Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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