Skip to content

Commit

Permalink
#389 - Moved verification code to Domain level (#412)
Browse files Browse the repository at this point in the history
  • Loading branch information
petruki authored May 14, 2023
1 parent ef5d0b4 commit 269c23b
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 72 deletions.
28 changes: 0 additions & 28 deletions src/api-docs/paths/path-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,34 +274,6 @@ export default {
}
}
},
'/config/relay/verificationCode/{id}': {
patch: {
tags: ['Config'],
description: 'Config Relay generates verification code',
security: [{ bearerAuth: [] }],
parameters: [
pathParameter('id', 'Config ID', true)
],
responses: {
'200': {
description: 'Config Relay verification code generated',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Verification code'
}
}
}
}
}
}
}
}
},
'/config/relay/verify/{id}/{env}': {
patch: {
tags: ['Config'],
Expand Down
30 changes: 29 additions & 1 deletion src/api-docs/paths/path-domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,5 +231,33 @@ export default {
}
}
}
}
},
'/domain/relay/verificationCode/{id}': {
patch: {
tags: ['Domain'],
description: 'Generates verification code for Relay integration',
security: [{ bearerAuth: [] }],
parameters: [
pathParameter('id', 'Domain ID', true)
],
responses: {
'200': {
description: 'Relay verification code generated',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Verification code'
}
}
}
}
}
}
}
}
},
};
4 changes: 0 additions & 4 deletions src/api-docs/schemas/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ export const relay = {
type: 'string'
}
},
verification_code: {
type: 'string',
description: 'Generated string used to verify Relay endpoint ownership'
},
verified: {
type: 'object',
additionalProperties: {
Expand Down
9 changes: 9 additions & 0 deletions src/api-docs/schemas/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ export const domain = {
slack: {
type: 'string',
description: 'The slack integration id'
},
relay: {
type: 'object',
properties: {
verification_code: {
type: 'string',
description: 'Generated string used to verify Relay ownership'
}
}
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/client/relay/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function resolveVerification(relay, environment) {
const endpoint = relay.endpoint.get(environment)?.replace(/\/$/, '');
const url = `${endpoint?.substring(0, endpoint.lastIndexOf('/'))}/verify`;
const header = createHeader(relay.auth_prefix, relay.auth_token.get(environment));
const response = await get(url, `?code=${relay.verification_code}`, header);
const response = await get(url, '', header);

return response.data?.code;
}
Expand Down
3 changes: 0 additions & 3 deletions src/models/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ const configSchema = new mongoose.Schema({
type: Map,
of: String
},
verification_code: {
type: String
},
verified: {
type: Map,
of: Boolean,
Expand Down
5 changes: 5 additions & 0 deletions src/models/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const domainSchema = new mongoose.Schema({
slack: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Slack'
},
relay: {
verification_code: {
type: String
}
}
},
lastUpdate: {
Expand Down
11 changes: 0 additions & 11 deletions src/routers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,6 @@ router.patch('/config/removeRelay/:id/:env', auth, [
}
});

router.patch('/config/relay/verificationCode/:id', auth, [
check('id').isMongoId()
], validate, async (req, res) => {
try {
const config = await Services.getRelayVerificationCode(req.params.id, req.admin);
res.send({ code: config.relay.verification_code });
} catch (e) {
responseException(res, e, 500);
}
});

router.patch('/config/relay/verify/:id/:env', auth, [
check('id').isMongoId(),
check('env').isLength({ min: 1 })
Expand Down
11 changes: 11 additions & 0 deletions src/routers/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,15 @@ router.patch('/domain/removeStatus/:id', auth, [
}
});

router.patch('/domain/relay/verificationCode/:id', auth, [
check('id').isMongoId()
], validate, async (req, res) => {
try {
const code = await Services.getRelayVerificationCode(req.params.id, req.admin);
res.send({ code });
} catch (e) {
responseException(res, e, 500);
}
});

export default router;
16 changes: 3 additions & 13 deletions src/services/config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import mongoose from 'mongoose';
import { randomUUID } from 'crypto';
import { response } from './common';
import { Config } from '../models/config';
import { formatInput, verifyOwnership, checkEnvironmentStatusRemoval } from '../helpers';
import { ActionTypes, RouterTypes } from '../models/permission';
import { updateDomainVersion } from './domain';
import { getDomainById, updateDomainVersion } from './domain';
import { getGroupConfigById } from './group-config';
import { checkSwitcher } from '../external/switcher-api-facade';
import { BadRequestError, NotFoundError } from '../exceptions';
Expand Down Expand Up @@ -264,22 +263,13 @@ export async function removeRelay(id, env, admin) {
return config;
}

export async function getRelayVerificationCode(id, admin) {
let config = await getConfigById(id);
config = await verifyOwnership(admin, config, config.domain, ActionTypes.UPDATE, RouterTypes.CONFIG);

config.updatedBy = admin.email;
config.relay.verification_code = randomUUID();

return config.save();
}

export async function verifyRelay(id, env, admin) {
let config = await getConfigById(id);
let domain = await getDomainById(config.domain);
config = await verifyOwnership(admin, config, config.domain, ActionTypes.UPDATE, RouterTypes.CONFIG);

const code = await resolveVerification(config.relay, env);
if (!config.relay.verified?.get(env) && Object.is(config.relay.verification_code, code)) {
if (!config.relay.verified?.get(env) && Object.is(domain.integrations.relay.verification_code, code)) {
config.relay.verified.set(env, true);
await config.save();
return 'verified';
Expand Down
15 changes: 15 additions & 0 deletions src/services/domain.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { randomUUID } from 'crypto';
import { checkEnvironmentStatusChange_v2 } from '../middleware/validators';
import Component from '../models/component';
import { Config } from '../models/config';
Expand Down Expand Up @@ -133,4 +134,18 @@ export async function updateDomainVersion(domainId) {
const domain = await getDomainById(domainId);
domain.lastUpdate = Date.now();
domain.save();
}

export async function getRelayVerificationCode(id, admin) {
let domain = await getDomainById(id);
domain = await verifyOwnership(admin, domain, domain._id, ActionTypes.UPDATE, RouterTypes.DOMAIN);

domain.updatedBy = admin.email;

if (!domain.integrations.relay.verification_code) {
domain.integrations.relay.verification_code = randomUUID();
await domain.save();
}

return domain.integrations.relay.verification_code;
}
65 changes: 55 additions & 10 deletions tests/config-relay.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
adminMasterAccountToken,
domainId,
configId1,
configId2,
} from './fixtures/db_api';
import { EnvType } from '../src/models/environment';

Expand Down Expand Up @@ -87,7 +88,6 @@ describe('Testing relay verification', () => {
// Config has a verified Relay
let config = await Config.findById(configId1).exec();
config.relay.verified.set(EnvType.DEFAULT, true);
config.relay.verification_code = '123';
await config.save();
expect(config.relay.verified.get(EnvType.DEFAULT)).toBe(true);

Expand All @@ -102,7 +102,6 @@ describe('Testing relay verification', () => {

config = await Config.findById(configId1).exec();
expect(config.relay.verified.get(EnvType.DEFAULT)).toBe(false);
expect(config.relay.verification_code).toBe('123');
});

test('CONFIG_RELAY_SUITE - Should NOT reset Relay verified flag when changing anything but endpoint', async () => {
Expand All @@ -119,7 +118,6 @@ describe('Testing relay verification', () => {
// Config has a verified Relay
let config = await Config.findById(configId1).exec();
config.relay.verified.set(EnvType.DEFAULT, true);
config.relay.verification_code = '123';
await config.save();
expect(config.relay.verified.get(EnvType.DEFAULT)).toBe(true);

Expand All @@ -134,7 +132,6 @@ describe('Testing relay verification', () => {

config = await Config.findById(configId1).exec();
expect(config.relay.verified.get(EnvType.DEFAULT)).toBe(true);
expect(config.relay.verification_code).toBe('123');
});

});
Expand Down Expand Up @@ -167,7 +164,6 @@ describe('Testing relay association', () => {
// DB validation - document updated
const config = await Config.findById(configId1).lean().exec();
expect(config.relay.verified[EnvType.DEFAULT]).toEqual(false);
expect(config.relay.verification_code).toEqual(undefined);
expect(config.relay.activated[EnvType.DEFAULT]).toEqual(true);
expect(config.relay.endpoint[EnvType.DEFAULT]).toBe('http://localhost:3001');
expect(config.relay.auth_token[EnvType.DEFAULT]).toEqual('123');
Expand Down Expand Up @@ -365,7 +361,7 @@ describe('Testing relay association', () => {

test('CONFIG_RELAY_SUITE - Should generate verification code', async () => {
const response = await request(app)
.patch(`/config/relay/verificationCode/${configId1}`)
.patch(`/domain/relay/verificationCode/${domainId}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send().expect(200);

Expand All @@ -374,14 +370,14 @@ describe('Testing relay association', () => {

test('CONFIG_RELAY_SUITE - Should NOT generate verification code - Config not found', async () => {
await request(app)
.patch(`/config/relay/verificationCode/${new mongoose.Types.ObjectId()}`)
.patch(`/domain/relay/verificationCode/${new mongoose.Types.ObjectId()}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send(bodyRelayProd).expect(404);
});

test('CONFIG_RELAY_SUITE - Should verify code', async () => {
// Given
// Adding relay
// Adding Relay
await request(app)
.patch(`/config/updateRelay/${configId1}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
Expand All @@ -394,7 +390,7 @@ describe('Testing relay association', () => {

// Request verification code
let response = await request(app)
.patch(`/config/relay/verificationCode/${configId1}`)
.patch(`/domain/relay/verificationCode/${domainId}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send().expect(200);

Expand All @@ -417,7 +413,7 @@ describe('Testing relay association', () => {
// Given
// Request verification code
await request(app)
.patch(`/config/relay/verificationCode/${configId1}`)
.patch(`/domain/relay/verificationCode/${domainId}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send().expect(200);

Expand Down Expand Up @@ -455,4 +451,53 @@ describe('Testing relay association', () => {
expect(response.body.status).toBe('failed');
});

});

describe('Testing relay verification - Existing verified Relays', () => {
beforeAll(async () => {
await setupDatabase();
});

const bodyRelay = {
type: 'VALIDATION',
activated: { default: true },
endpoint: { default: {} },
method: 'POST'
};

test('CONFIG_RELAY_SUITE - Should NOT generate a new verification code - Existing Relay has it', async () => {
// Given
// Add Relay 1
bodyRelay.endpoint.default = 'https://localhost:3001/validate';
await request(app)
.patch(`/config/updateRelay/${configId1}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send(bodyRelay).expect(200);

// Request verification code for Relay 1
let response = await request(app)
.patch(`/domain/relay/verificationCode/${domainId}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send().expect(200);

const code1 = response.body.code;
expect(code1).not.toBe(undefined);

// Add Relay 2
bodyRelay.endpoint.default = 'https://localhost:3001/v2/validate';
await request(app)
.patch(`/config/updateRelay/${configId2}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send(bodyRelay).expect(200);

// Request verification code for Relay 2
response = await request(app)
.patch(`/domain/relay/verificationCode/${domainId}`)
.set('Authorization', `Bearer ${adminMasterAccountToken}`)
.send().expect(200);

const code2 = response.body.code;
expect(code1).toBe(code2);
});

});
1 change: 0 additions & 1 deletion tests/relay.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,6 @@ describe('Testing Switcher Relay Verification', () => {
// Config has a verified Relay
const config = await Config.findById(configId).exec();
config.relay.verified.set(EnvType.DEFAULT, true);
config.relay.verification_code = '123';
await config.save();
expect(config.relay.verified.get(EnvType.DEFAULT)).toBe(true);

Expand Down

0 comments on commit 269c23b

Please sign in to comment.