From 9f813d72f261e3797aa9db50e4d03dda89ead59d Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Mon, 15 Jan 2024 14:10:54 +0530 Subject: [PATCH] feat(infisical-pg): resolved multi integration auth and ip v6 support in ua --- backend-pg/src/lib/knex/index.ts | 4 ++- backend-pg/src/server/routes/index.ts | 3 +- .../src/server/routes/v1/identity-ua.ts | 4 +-- .../services/auth-token/auth-token-service.ts | 2 +- .../identity-ua/identity-ua-service.ts | 26 ++++++++++++--- .../integration-auth-service.ts | 8 +---- .../integration/integration-service.ts | 11 +++++-- .../src/services/secret/secret-queue.ts | 33 ++++++++++--------- 8 files changed, 57 insertions(+), 34 deletions(-) diff --git a/backend-pg/src/lib/knex/index.ts b/backend-pg/src/lib/knex/index.ts index be7dab042..c8e81541f 100644 --- a/backend-pg/src/lib/knex/index.ts +++ b/backend-pg/src/lib/knex/index.ts @@ -88,7 +88,9 @@ export const ormify = ( }, create: async (data: Tables[Tname]["insert"], tx?: Knex) => { try { - const [res] = await (tx || db)(tableName).insert(data).returning("*"); + const [res] = await (tx || db)(tableName) + .insert(data as any) + .returning("*"); return res; } catch (error) { throw new DatabaseError({ error, name: "Create" }); diff --git a/backend-pg/src/server/routes/index.ts b/backend-pg/src/server/routes/index.ts index a862f5b62..d7a5f1e98 100644 --- a/backend-pg/src/server/routes/index.ts +++ b/backend-pg/src/server/routes/index.ts @@ -392,7 +392,8 @@ export const registerRoutes = async ( permissionService, folderDal, integrationDal, - integrationAuthDal + integrationAuthDal, + secretQueueService }); const serviceTokenService = serviceTokenServiceFactory({ projectEnvDal, diff --git a/backend-pg/src/server/routes/v1/identity-ua.ts b/backend-pg/src/server/routes/v1/identity-ua.ts index 09b086bac..a6def6d73 100644 --- a/backend-pg/src/server/routes/v1/identity-ua.ts +++ b/backend-pg/src/server/routes/v1/identity-ua.ts @@ -81,14 +81,14 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }) .array() .min(1) - .default([{ ipAddress: "0.0.0.0/0" }]), + .default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]), accessTokenTrustedIps: z .object({ ipAddress: z.string().trim() }) .array() .min(1) - .default([{ ipAddress: "0.0.0.0/0" }]), + .default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]), accessTokenTTL: z .number() .int() diff --git a/backend-pg/src/services/auth-token/auth-token-service.ts b/backend-pg/src/services/auth-token/auth-token-service.ts index fb69ffad3..475738bbc 100644 --- a/backend-pg/src/services/auth-token/auth-token-service.ts +++ b/backend-pg/src/services/auth-token/auth-token-service.ts @@ -69,7 +69,7 @@ export const tokenServiceFactory = ({ tokenDal, userDal }: TAuthTokenServiceFact const newToken = await tokenDal.create( { tokenHash, - expiresAt: tkCfg.expiresAt.toUTCString(), + expiresAt: tkCfg.expiresAt, type, userId, orgId, diff --git a/backend-pg/src/services/identity-ua/identity-ua-service.ts b/backend-pg/src/services/identity-ua/identity-ua-service.ts index e311a5b6a..4c195d394 100644 --- a/backend-pg/src/services/identity-ua/identity-ua-service.ts +++ b/backend-pg/src/services/identity-ua/identity-ua-service.ts @@ -14,7 +14,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors"; -import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr,TIp } from "@app/lib/ip"; +import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr, TIp } from "@app/lib/ip"; import { ActorType, AuthTokenType } from "../auth/auth-type"; import { TIdentityDalFactory } from "../identity/identity-dal"; @@ -176,7 +176,11 @@ export const identityUaServiceFactory = ({ const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map( (clientSecretTrustedIp) => { - if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0") + if ( + !plan.ipAllowlisting && + clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && + clientSecretTrustedIp.ipAddress !== "::/0" + ) throw new BadRequestError({ message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." @@ -189,7 +193,11 @@ export const identityUaServiceFactory = ({ } ); const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { - if (!plan.ipAllowlisting && accessTokenTrustedIp.ipAddress !== "0.0.0.0/0") + if ( + !plan.ipAllowlisting && + accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" && + accessTokenTrustedIp.ipAddress !== "::/0" + ) throw new BadRequestError({ message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." @@ -266,7 +274,11 @@ export const identityUaServiceFactory = ({ const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map( (clientSecretTrustedIp) => { - if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0") + if ( + !plan.ipAllowlisting && + clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && + clientSecretTrustedIp.ipAddress !== "::/0" + ) throw new BadRequestError({ message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." @@ -279,7 +291,11 @@ export const identityUaServiceFactory = ({ } ); const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { - if (!plan.ipAllowlisting && accessTokenTrustedIp.ipAddress !== "0.0.0.0/0") + if ( + !plan.ipAllowlisting && + accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" && + accessTokenTrustedIp.ipAddress !== "::/0" + ) throw new BadRequestError({ message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." diff --git a/backend-pg/src/services/integration-auth/integration-auth-service.ts b/backend-pg/src/services/integration-auth/integration-auth-service.ts index d9e9205c1..41d2434c5 100644 --- a/backend-pg/src/services/integration-auth/integration-auth-service.ts +++ b/backend-pg/src/services/integration-auth/integration-auth-service.ts @@ -234,13 +234,7 @@ export const integrationAuthServiceFactory = ({ updateDoc.accessIdCiphertext = accessEncToken.ciphertext; } } - return integrationAuthDal.transaction(async (tx) => { - const doc = await integrationAuthDal.findOne({ projectId, integration }, tx); - if (!doc) { - return integrationAuthDal.create(updateDoc, tx); - } - return integrationAuthDal.updateById(doc.id, updateDoc, tx); - }); + return integrationAuthDal.create(updateDoc); }; // helper function diff --git a/backend-pg/src/services/integration/integration-service.ts b/backend-pg/src/services/integration/integration-service.ts index 2fe117142..65853c7b6 100644 --- a/backend-pg/src/services/integration/integration-service.ts +++ b/backend-pg/src/services/integration/integration-service.ts @@ -16,12 +16,14 @@ import { TDeleteIntegrationDTO, TUpdateIntegrationDTO } from "./integration-types"; +import { TSecretQueueFactory } from "../secret/secret-queue"; type TIntegrationServiceFactoryDep = { integrationDal: TIntegrationDalFactory; integrationAuthDal: TIntegrationAuthDalFactory; folderDal: Pick; permissionService: Pick; + secretQueueService: Pick; }; export type TIntegrationServiceFactory = ReturnType; @@ -30,7 +32,8 @@ export const integrationServiceFactory = ({ integrationDal, integrationAuthDal, folderDal, - permissionService + permissionService, + secretQueueService }: TIntegrationServiceFactoryDep) => { const createIntegration = async ({ app, @@ -90,7 +93,11 @@ export const integrationServiceFactory = ({ integration: integrationAuth.integration }); - + await secretQueueService.syncIntegrations({ + environment: sourceEnvironment, + secretPath, + projectId: integrationAuth.projectId + }); return { integration, integrationAuth }; }; diff --git a/backend-pg/src/services/secret/secret-queue.ts b/backend-pg/src/services/secret/secret-queue.ts index fdebd3708..b239bd8b2 100644 --- a/backend-pg/src/services/secret/secret-queue.ts +++ b/backend-pg/src/services/secret/secret-queue.ts @@ -48,20 +48,8 @@ export const secretQueueFactory = ({ webhookDal, projectEnvDal }: TSecretQueueFactoryDep) => { - const syncSecrets = async (dto: TGetSecrets) => { - queueService.queue(QueueName.SecretWebhook, QueueJobs.SecWebhook, dto, { - jobId: `secret-webhook-${dto.environment}-${dto.projectId}-${dto.secretPath}`, - removeOnFail: { count: 5 }, - removeOnComplete: true, - delay: 1000, - attempts: 5, - backoff: { - type: "exponential", - delay: 3000 - } - }); - - queueService.queue(QueueName.IntegrationSync, QueueJobs.IntegrationSync, dto, { + const syncIntegrations = async (dto: TGetSecrets) => { + await queueService.queue(QueueName.IntegrationSync, QueueJobs.IntegrationSync, dto, { attempts: 5, delay: 1000, backoff: { @@ -75,6 +63,21 @@ export const secretQueueFactory = ({ }); }; + const syncSecrets = async (dto: TGetSecrets) => { + await queueService.queue(QueueName.SecretWebhook, QueueJobs.SecWebhook, dto, { + jobId: `secret-webhook-${dto.environment}-${dto.projectId}-${dto.secretPath}`, + removeOnFail: { count: 5 }, + removeOnComplete: true, + delay: 1000, + attempts: 5, + backoff: { + type: "exponential", + delay: 3000 + } + }); + await syncIntegrations(dto); + }; + const getIntegrationSecrets = async (dto: TGetSecrets & { folderId: string }, key: string) => { const secrets = await secretDal.findByFolderId(dto.folderId); if (!secrets.length) return {}; @@ -226,5 +229,5 @@ export const secretQueueFactory = ({ await fnTriggerWebhook({ ...job.data, projectEnvDal, webhookDal }); }); - return { syncSecrets }; + return { syncSecrets, syncIntegrations }; };