From 2e523a60b6b77e25e348e0bda2eee1a58413cd91 Mon Sep 17 00:00:00 2001 From: Nithin Shekar Kuruba Date: Mon, 3 Feb 2025 16:27:05 -0800 Subject: [PATCH 1/2] feat: disable jswk_uri and update bcsc api conditionally --- lambda/app/src/bcsc/client.ts | 10 ++++++---- lambda/app/src/controllers/requests.ts | 26 +++++++++++++++++++++----- lambda/app/src/queries/request.ts | 6 +++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lambda/app/src/bcsc/client.ts b/lambda/app/src/bcsc/client.ts index 54152b0a..93ba953b 100644 --- a/lambda/app/src/bcsc/client.ts +++ b/lambda/app/src/bcsc/client.ts @@ -46,7 +46,7 @@ const getPrivacyZoneURI = async (env: string, privacyZoneDisplayName: string) => export const createBCSCClient = async (data: BCSCClientParameters, integration: IntegrationData, userId: number) => { const contacts = await getBCSCContacts(integration); const { bcscBaseUrl, kcBaseUrl, accessToken } = getBCSCEnvVars(data.environment); - const jwksUri = `${kcBaseUrl}/auth/realms/standard/protocol/openid-connect/certs`; + //const jwksUri = `${kcBaseUrl}/auth/realms/standard/protocol/openid-connect/certs`; const requiredScopes = await getRequiredBCSCScopes(integration.bcscAttributes); let bcscPrivacyZoneURI = await getPrivacyZoneURI(data.environment, integration.bcscPrivacyZone); @@ -64,7 +64,8 @@ export const createBCSCClient = async (data: BCSCClientParameters, integration: // Sub must be requested. Otherwise id token will have a randomized identifier. claims: [...integration.bcscAttributes, 'sub'], privacy_zone_uri: bcscPrivacyZoneURI, - jwks_uri: jwksUri, + // TODO: Keep it commented until encryption is allowed + //jwks_uri: jwksUri, }, { headers: { @@ -79,7 +80,7 @@ export const createBCSCClient = async (data: BCSCClientParameters, integration: export const updateBCSCClient = async (bcscClient: BCSCClientParameters, integration: IntegrationData) => { const { kcBaseUrl, bcscBaseUrl } = getBCSCEnvVars(bcscClient.environment); const contacts = await getBCSCContacts(integration); - const jwksUri = `${kcBaseUrl}/auth/realms/standard/protocol/openid-connect/certs`; + //const jwksUri = `${kcBaseUrl}/auth/realms/standard/protocol/openid-connect/certs`; const requiredScopes = await getRequiredBCSCScopes(integration.bcscAttributes); const result = await axios.put( @@ -94,7 +95,8 @@ export const updateBCSCClient = async (bcscClient: BCSCClientParameters, integra id_token_signed_response_alg: 'RS256', userinfo_signed_response_alg: 'RS256', claims: [...integration.bcscAttributes, 'sub'], - jwks_uri: jwksUri, + // TODO: Keep it commented until encryption is allowed + //jwks_uri: jwksUri, client_id: bcscClient.clientId, registration_access_token: bcscClient.registrationAccessToken, privacy_zone_uri: await getPrivacyZoneURI(bcscClient.environment, integration.bcscPrivacyZone), diff --git a/lambda/app/src/controllers/requests.ts b/lambda/app/src/controllers/requests.ts index e01d8fe4..ea8b006d 100644 --- a/lambda/app/src/controllers/requests.ts +++ b/lambda/app/src/controllers/requests.ts @@ -31,6 +31,7 @@ import { getIntegrationsByUserTeam, getIntegrationByClientId, canUpdateRequestByUserId, + getIntegrationById, } from '@lambda-app/queries/request'; import { fetchClient } from '@lambda-app/keycloak/client'; import { getUserTeamRole } from '@lambda-app/queries/literals'; @@ -271,14 +272,29 @@ export const createBCSCIntegration = async (env: string, integration: Integratio bcscClientId = clientResponse.data.client_id; } else { if (bcscClient.archived) { - // TODO: currently need to have the BCSC team manually re-enable client when restoring (as of July 2024). Once api route for enabling is available should be added here. bcscClient.archived = false; } - //TODO: update client name after BCSC team provides a way to update client name - //bcscClient.clientName = bcscClientName; + bcscClient.clientName = bcscClientName; bcscClient.save(); - await updateBCSCClient(bcscClient, integration); + + const integrationLastChanges = await getIntegrationById(integration.id).then((data) => data.lastChanges); + + if ( + integrationLastChanges !== null && + integrationLastChanges.find((change: any) => + [ + 'projectName', + 'bcscPrivacyZone', + 'bcscAttributes', + 'devHomePageUri', + 'testHomePageUri', + 'prodHomePageUri', + ].includes(change?.path[0]), + ) + ) { + await updateBCSCClient(bcscClient, integration); + } } const requiredScopes = await getRequiredBCSCScopes(integration.bcscAttributes); const idpCreated = await getIdp(env, integration.clientId); @@ -658,7 +674,7 @@ export const updateRequest = async ( } const changes = getDifferences(finalData, originalData); - current.lastChanges = changes; + current.lastChanges = changes || null; let updated = await current.save(); if (!updated) { diff --git a/lambda/app/src/queries/request.ts b/lambda/app/src/queries/request.ts index 5dbaa4f6..18312932 100644 --- a/lambda/app/src/queries/request.ts +++ b/lambda/app/src/queries/request.ts @@ -168,12 +168,12 @@ export const getIntegrationsByUserTeam = async ( }); }; -export const getIntegrationById = ( +export const getIntegrationById = async ( integrationId: number, - attributes: string[] = ['id', 'clientId', 'environments', 'teamId', 'devIdps'], + attributes: string[] = ['id', 'clientId', 'environments', 'teamId', 'devIdps', 'lastChanges'], options = { raw: true }, ) => { - return models.request.findOne({ + return await models.request.findOne({ where: { id: integrationId, apiServiceAccount: false, archived: false }, attributes, ...options, From 50a4beedc732ddf16f84420b15c66f7d56127554 Mon Sep 17 00:00:00 2001 From: Nithin Shekar Kuruba Date: Tue, 4 Feb 2025 08:10:43 -0800 Subject: [PATCH 2/2] fix: unit tests --- lambda/__tests__/20.bcsc.test.ts | 8 ++++++++ lambda/app/src/controllers/requests.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lambda/__tests__/20.bcsc.test.ts b/lambda/__tests__/20.bcsc.test.ts index 6bf712f0..91dcb82c 100644 --- a/lambda/__tests__/20.bcsc.test.ts +++ b/lambda/__tests__/20.bcsc.test.ts @@ -57,6 +57,14 @@ jest.mock('@lambda-app/bcsc/client', () => { }; }); +jest.mock('@lambda-app/queries/request', () => { + const original = jest.requireActual('@lambda-app/queries/request'); + return { + ...original, + getIntegrationById: jest.fn(() => Promise.resolve({ lastChanges: [] })), + }; +}); + const OLD_ENV = process.env; beforeEach(() => { jest.resetModules(); diff --git a/lambda/app/src/controllers/requests.ts b/lambda/app/src/controllers/requests.ts index ea8b006d..0ebfefe6 100644 --- a/lambda/app/src/controllers/requests.ts +++ b/lambda/app/src/controllers/requests.ts @@ -278,7 +278,7 @@ export const createBCSCIntegration = async (env: string, integration: Integratio bcscClient.clientName = bcscClientName; bcscClient.save(); - const integrationLastChanges = await getIntegrationById(integration.id).then((data) => data.lastChanges); + const integrationLastChanges = await getIntegrationById(integration.id).then((data) => data?.lastChanges); if ( integrationLastChanges !== null &&