From 2a3f136b68f64cbae3f665d034dfcf9ef889b645 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:31:55 +0400 Subject: [PATCH 1/9] Schemas --- backend/src/db/schemas/identity-access-tokens.ts | 2 +- backend/src/db/schemas/organizations.ts | 2 +- backend/src/db/schemas/secret-approval-requests-secrets.ts | 2 +- backend/src/db/schemas/user-encryption-keys.ts | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/db/schemas/identity-access-tokens.ts b/backend/src/db/schemas/identity-access-tokens.ts index 62f74f4aa..d36291ab9 100644 --- a/backend/src/db/schemas/identity-access-tokens.ts +++ b/backend/src/db/schemas/identity-access-tokens.ts @@ -8,7 +8,7 @@ import { z } from "zod"; import { TImmutableDBKeys } from "./models"; export const IdentityAccessTokensSchema = z.object({ - id: z.string().uuid(), + id: z.string(), accessTokenTTL: z.coerce.number().default(2592000), accessTokenMaxTTL: z.coerce.number().default(2592000), accessTokenNumUses: z.coerce.number().default(0), diff --git a/backend/src/db/schemas/organizations.ts b/backend/src/db/schemas/organizations.ts index e0f70d1c0..539217c00 100644 --- a/backend/src/db/schemas/organizations.ts +++ b/backend/src/db/schemas/organizations.ts @@ -13,7 +13,7 @@ export const OrganizationsSchema = z.object({ customerId: z.string().nullable().optional(), slug: z.string(), createdAt: z.date(), - updatedAt: z.date() + updatedAt: z.date(), }); export type TOrganizations = z.infer; diff --git a/backend/src/db/schemas/secret-approval-requests-secrets.ts b/backend/src/db/schemas/secret-approval-requests-secrets.ts index 2fe6c6692..db98bda17 100644 --- a/backend/src/db/schemas/secret-approval-requests-secrets.ts +++ b/backend/src/db/schemas/secret-approval-requests-secrets.ts @@ -10,7 +10,7 @@ import { TImmutableDBKeys } from "./models"; export const SecretApprovalRequestsSecretsSchema = z.object({ id: z.string().uuid(), version: z.number().default(1).nullable().optional(), - secretBlindIndex: z.string(), + secretBlindIndex: z.string().nullable().optional(), secretKeyCiphertext: z.string(), secretKeyIV: z.string(), secretKeyTag: z.string(), diff --git a/backend/src/db/schemas/user-encryption-keys.ts b/backend/src/db/schemas/user-encryption-keys.ts index 41a7ae57d..938b93aaf 100644 --- a/backend/src/db/schemas/user-encryption-keys.ts +++ b/backend/src/db/schemas/user-encryption-keys.ts @@ -12,9 +12,9 @@ export const UserEncryptionKeysSchema = z.object({ clientPublicKey: z.string().nullable().optional(), serverPrivateKey: z.string().nullable().optional(), encryptionVersion: z.number().default(2).nullable().optional(), - protectedKey: z.string().nullable(), - protectedKeyIV: z.string().nullable(), - protectedKeyTag: z.string().nullable(), + protectedKey: z.string().nullable().optional(), + protectedKeyIV: z.string().nullable().optional(), + protectedKeyTag: z.string().nullable().optional(), publicKey: z.string(), encryptedPrivateKey: z.string(), iv: z.string(), From abd3652910350018c2cd68eba64a02008dd6d0bf Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:33:35 +0400 Subject: [PATCH 2/9] Add user DAL --- backend/.eslintrc.js | 2 +- backend/src/server/routes/index.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/backend/.eslintrc.js b/backend/.eslintrc.js index e9e98bffe..7a3a8d802 100644 --- a/backend/.eslintrc.js +++ b/backend/.eslintrc.js @@ -13,7 +13,7 @@ module.exports = { tsconfigRootDir: __dirname }, rules: { - // "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-function": "off", "consistent-return": "off", // my style "import/order": "off", // for simple-import-order "import/prefer-default-export": "off", // why diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 19bf09727..16d32aada 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -92,7 +92,10 @@ import { serviceTokenDALFactory } from "@app/services/service-token/service-toke import { serviceTokenServiceFactory } from "@app/services/service-token/service-token-service"; import { TSmtpService } from "@app/services/smtp/smtp-service"; import { superAdminDALFactory } from "@app/services/super-admin/super-admin-dal"; -import { getServerCfg, superAdminServiceFactory } from "@app/services/super-admin/super-admin-service"; +import { + getServerCfg, + superAdminServiceFactory +} from "@app/services/super-admin/super-admin-service"; import { telemetryServiceFactory } from "@app/services/telemetry/telemetry-service"; import { userDALFactory } from "@app/services/user/user-dal"; import { userServiceFactory } from "@app/services/user/user-service"; @@ -420,6 +423,7 @@ export const registerRoutes = async ( const serviceTokenService = serviceTokenServiceFactory({ projectEnvDAL, serviceTokenDAL, + userDAL, permissionService }); @@ -516,14 +520,14 @@ export const registerRoutes = async ( }, handler: () => { const cfg = getConfig(); - const serverCfg = getServerCfg() + const serverCfg = getServerCfg(); return { date: new Date(), message: "Ok" as const, emailConfigured: cfg.isSmtpConfigured, inviteOnlySignup: Boolean(serverCfg.allowSignUp), redisConfigured: cfg.isRedisConfigured, - secretScanningConfigured: cfg.isSecretScanningConfigured, + secretScanningConfigured: cfg.isSecretScanningConfigured }; } }); From fbfe797547c418fb90a36814ee3593cdf45bec09 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:33:45 +0400 Subject: [PATCH 3/9] Update sanitizedSchemas.ts --- backend/src/server/routes/sanitizedSchemas.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/src/server/routes/sanitizedSchemas.ts b/backend/src/server/routes/sanitizedSchemas.ts index cc9dedd45..afc12c081 100644 --- a/backend/src/server/routes/sanitizedSchemas.ts +++ b/backend/src/server/routes/sanitizedSchemas.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { IntegrationAuthsSchema, SecretApprovalPoliciesSchema } from "@app/db/schemas"; +import { IntegrationAuthsSchema, SecretApprovalPoliciesSchema, UsersSchema } from "@app/db/schemas"; // sometimes the return data must be santizied to avoid leaking important values // always prefer pick over omit in zod @@ -28,6 +28,18 @@ export const sapPubSchema = SecretApprovalPoliciesSchema.merge( }) ); +export const sanitizedServiceTokenUserSchema = UsersSchema.pick({ + authMethods: true, + id: true, + createdAt: true, + updatedAt: true, + devices: true, + email: true, + firstName: true, + lastName: true, + mfaMethods: true +}); + export const secretRawSchema = z.object({ id: z.string(), _id: z.string(), From f335101369c525835a31a8f4679629ef5b0edee3 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:33:59 +0400 Subject: [PATCH 4/9] Add user --- .../src/server/routes/v2/service-token-router.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/src/server/routes/v2/service-token-router.ts b/backend/src/server/routes/v2/service-token-router.ts index 31f5c22d6..3ebce77dc 100644 --- a/backend/src/server/routes/v2/service-token-router.ts +++ b/backend/src/server/routes/v2/service-token-router.ts @@ -6,6 +6,8 @@ import { removeTrailingSlash } from "@app/lib/fn"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; +import { sanitizedServiceTokenUserSchema } from "../sanitizedSchemas"; + export const sanitizedServiceTokenSchema = ServiceTokensSchema.omit({ secretHash: true, encryptedKey: true, @@ -20,15 +22,21 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) => onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]), schema: { response: { - 200: ServiceTokensSchema.merge(z.object({ workspace: z.string() })) + 200: ServiceTokensSchema.merge( + z.object({ + workspace: z.string(), + user: sanitizedServiceTokenUserSchema + }) + ) } }, handler: async (req) => { - const serviceTokenData = await server.services.serviceToken.getServiceToken({ + const { serviceToken, user } = await server.services.serviceToken.getServiceToken({ actorId: req.permission.id, actor: req.permission.type }); - return { ...serviceTokenData, workspace: serviceTokenData.projectId }; + + return { ...serviceToken, workspace: serviceToken.projectId, user }; } }); From d5165e50860043b21cd62fbde3d8750f28381f82 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:34:13 +0400 Subject: [PATCH 5/9] Update secret-router.ts --- backend/src/server/routes/v3/secret-router.ts | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index cdb92fae6..99dc5ddfb 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -442,6 +442,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { secrets: SecretsSchema.omit({ secretBlindIndex: true }) .merge( z.object({ + workspace: z.string(), + environment: z.string(), tags: SecretTagsSchema.pick({ id: true, slug: true, @@ -529,7 +531,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }), response: { 200: z.object({ - secret: SecretsSchema.omit({ secretBlindIndex: true }) + secret: SecretsSchema.omit({ secretBlindIndex: true }).merge( + z.object({ + workspace: z.string(), + environment: z.string() + }) + ) }) } }, @@ -610,7 +617,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { response: { 200: z.union([ z.object({ - secret: SecretsSchema.omit({ secretBlindIndex: true }) + secret: SecretsSchema.omit({ secretBlindIndex: true }).merge( + z.object({ + workspace: z.string(), + environment: z.string() + }) + ) }), z .object({ approval: SecretApprovalRequestsSchema }) @@ -780,7 +792,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { response: { 200: z.union([ z.object({ - secret: SecretsSchema.omit({ secretBlindIndex: true }) + secret: SecretsSchema.omit({ secretBlindIndex: true }).merge( + z.object({ + workspace: z.string(), + environment: z.string() + }) + ) }), z .object({ approval: SecretApprovalRequestsSchema }) @@ -944,7 +961,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { response: { 200: z.union([ z.object({ - secret: SecretsSchema.omit({ secretBlindIndex: true }) + secret: SecretsSchema.omit({ secretBlindIndex: true }).merge( + z.object({ + workspace: z.string(), + environment: z.string() + }) + ) }), z .object({ approval: SecretApprovalRequestsSchema }) From fc8bd0470fe1d5f82c2dd129669cf48049f2866e Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:34:32 +0400 Subject: [PATCH 6/9] Update service-token-service.ts --- .../service-token/service-token-service.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index 48ead50e6..09f5e83a0 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -13,6 +13,7 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; import { ActorType } from "../auth/auth-type"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; +import { TUserDALFactory } from "../user/user-dal"; import { TServiceTokenDALFactory } from "./service-token-dal"; import { TCreateServiceTokenDTO, @@ -23,6 +24,7 @@ import { type TServiceTokenServiceFactoryDep = { serviceTokenDAL: TServiceTokenDALFactory; + userDAL: TUserDALFactory; permissionService: Pick; projectEnvDAL: Pick; }; @@ -31,6 +33,7 @@ export type TServiceTokenServiceFactory = ReturnType { @@ -51,14 +54,14 @@ export const serviceTokenServiceFactory = ({ ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens ); - + scopes.forEach(({ environment, secretPath }) => { ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); - }) - + }); + const appCfg = getConfig(); // validates env @@ -119,7 +122,10 @@ export const serviceTokenServiceFactory = ({ const serviceToken = await serviceTokenDAL.findById(actorId); if (!serviceToken) throw new BadRequestError({ message: "Token not found" }); - return serviceToken; + const serviceTokenUser = await userDAL.findById(serviceToken.createdBy); + if (!serviceTokenUser) throw new BadRequestError({ message: "Server token user not found" }); + + return { serviceToken, user: serviceTokenUser }; }; const getProjectServiceTokens = async ({ From 36a4bf73a608ea93469012ca381cdfcbd603e13a Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 15:10:55 +0400 Subject: [PATCH 7/9] Types --- .../secret-approval-request-service.ts | 38 +++++++++++++++---- backend/src/server/routes/v2/mfa-router.ts | 8 +++- backend/src/server/routes/v3/login-router.ts | 6 +-- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index 9680a6271..81be86304 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -269,7 +269,14 @@ export const secretApprovalRequestServiceFactory = ({ const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } = await secretService.fnSecretBlindIndexCheckV2({ folderId, - inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => ({ secretBlindIndex })) + inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => { + if (!secretBlindIndex) { + throw new BadRequestError({ + message: "Missing secret blind index" + }); + } + return { secretBlindIndex }; + }) }); secretCreationCommits .filter(({ secretBlindIndex }) => conflictGroupByBlindIndex[secretBlindIndex || ""]) @@ -291,7 +298,14 @@ export const secretApprovalRequestServiceFactory = ({ ({ secretBlindIndex, secret }) => secret && secret.secretBlindIndex !== secretBlindIndex ) - .map(({ secretBlindIndex }) => ({ secretBlindIndex })) + .map(({ secretBlindIndex }) => { + if (!secretBlindIndex) { + throw new BadRequestError({ + message: "Missing secret blind index" + }); + } + return { secretBlindIndex }; + }) }); secretUpdationCommits .filter( @@ -381,10 +395,14 @@ export const secretApprovalRequestServiceFactory = ({ folderId, tx, actorId: "", - inputSecrets: secretDeletionCommits.map(({ secretBlindIndex }) => ({ - secretBlindIndex, - type: SecretType.Shared - })) + inputSecrets: secretDeletionCommits.map(({ secretBlindIndex }) => { + if (!secretBlindIndex) { + throw new BadRequestError({ + message: "Missing secret blind index" + }); + } + return { secretBlindIndex, type: SecretType.Shared }; + }) }) : []; const updatedSecretApproval = await secretApprovalRequestDAL.updateById( @@ -638,7 +656,13 @@ export const secretApprovalRequestServiceFactory = ({ ), tx ); - const commitsGroupByBlindIndex = groupBy(approvalCommits, (i) => i.secretBlindIndex); + + const commitsGroupByBlindIndex = groupBy(approvalCommits, (i) => { + if (!i.secretBlindIndex) { + throw new BadRequestError({ message: "Missing secret blind index" }); + } + return i.secretBlindIndex; + }); if (tagIds.length) { await secretApprovalRequestSecretDAL.insertApprovalSecretTags( Object.keys(commitTagIds).flatMap((blindIndex) => diff --git a/backend/src/server/routes/v2/mfa-router.ts b/backend/src/server/routes/v2/mfa-router.ts index 6efda7221..02006a470 100644 --- a/backend/src/server/routes/v2/mfa-router.ts +++ b/backend/src/server/routes/v2/mfa-router.ts @@ -86,7 +86,13 @@ export const registerMfaRouter = async (server: FastifyZodProvider) => { secure: appCfg.HTTPS_ENABLED }); - return { token: token.access, ...user }; + return { + ...user, + token: token.access, + protectedKey: user.protectedKey || null, + protectedKeyIV: user.protectedKeyIV || null, + protectedKeyTag: user.protectedKeyTag || null + }; } }); }; diff --git a/backend/src/server/routes/v3/login-router.ts b/backend/src/server/routes/v3/login-router.ts index 22d7b8be7..1c513c183 100644 --- a/backend/src/server/routes/v3/login-router.ts +++ b/backend/src/server/routes/v3/login-router.ts @@ -96,9 +96,9 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => { encryptedPrivateKey: data.user.encryptedPrivateKey, iv: data.user.iv, tag: data.user.tag, - protectedKey: data.user.protectedKey, - protectedKeyIV: data.user.protectedKeyIV, - protectedKeyTag: data.user.protectedKeyTag + protectedKey: data.user.protectedKey || null, + protectedKeyIV: data.user.protectedKeyIV || null, + protectedKeyTag: data.user.protectedKeyTag || null } as const; } }); From 0d9ec7cd769fbb1c2fa2b0f831251ef8e0b64592 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 15:19:45 +0400 Subject: [PATCH 8/9] Update service-token-router.ts --- backend/src/server/routes/v2/service-token-router.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/server/routes/v2/service-token-router.ts b/backend/src/server/routes/v2/service-token-router.ts index 3ebce77dc..52e4d7334 100644 --- a/backend/src/server/routes/v2/service-token-router.ts +++ b/backend/src/server/routes/v2/service-token-router.ts @@ -36,6 +36,7 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) => actor: req.permission.type }); + // We return the user here because older versions of the deprecated Python SDK depend on it to properly parse the API response. return { ...serviceToken, workspace: serviceToken.projectId, user }; } }); From 62eacc712d4f3e1ca3a60a03dc26d6f9c6745268 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 29 Jan 2024 15:21:53 +0400 Subject: [PATCH 9/9] Update service-token-service.ts --- backend/src/services/service-token/service-token-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index 09f5e83a0..63d5f6aac 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -123,7 +123,7 @@ export const serviceTokenServiceFactory = ({ if (!serviceToken) throw new BadRequestError({ message: "Token not found" }); const serviceTokenUser = await userDAL.findById(serviceToken.createdBy); - if (!serviceTokenUser) throw new BadRequestError({ message: "Server token user not found" }); + if (!serviceTokenUser) throw new BadRequestError({ message: "Service token user not found" }); return { serviceToken, user: serviceTokenUser }; };