diff --git a/Dockerfile.fips.standalone-infisical b/Dockerfile.fips.standalone-infisical index c06347c7a0..d2b2a2d87d 100644 --- a/Dockerfile.fips.standalone-infisical +++ b/Dockerfile.fips.standalone-infisical @@ -200,9 +200,12 @@ WORKDIR /backend ENV TELEMETRY_ENABLED true EXPOSE 8080 -EXPOSE 80 EXPOSE 443 +# Remove telemetry. dd-trace uses BullMQ with MD5 hashing, which breaks when FIPS mode is enabled. +RUN grep -v 'import "./lib/telemetry/instrumentation.mjs";' dist/main.mjs > dist/main.mjs.tmp && \ + mv dist/main.mjs.tmp dist/main.mjs + USER non-root-user CMD ["./standalone-entrypoint.sh"] \ No newline at end of file diff --git a/backend/Dockerfile.dev.fips b/backend/Dockerfile.dev.fips index 23f9db2956..977362e031 100644 --- a/backend/Dockerfile.dev.fips +++ b/backend/Dockerfile.dev.fips @@ -80,7 +80,7 @@ COPY . . ENV HOST=0.0.0.0 ENV OPENSSL_CONF=/app/nodejs.fips.cnf ENV OPENSSL_MODULES=/usr/local/lib/ossl-modules -ENV NODE_OPTIONS=--force-fips +# ENV NODE_OPTIONS=--force-fips # Note(Daniel): We can't set this on the node options because it may break for existing folks using the infisical/infisical-fips image. Instead we call crypto.setFips(true) at runtime. ENV FIPS_ENABLED=true CMD ["npm", "run", "dev:docker"] diff --git a/backend/src/db/seed-data.ts b/backend/src/db/seed-data.ts index 2822a785b2..d923e45f11 100644 --- a/backend/src/db/seed-data.ts +++ b/backend/src/db/seed-data.ts @@ -52,7 +52,7 @@ export const seedData1 = { }; export const generateUserSrpKeys = async (password: string) => { - const { publicKey, privateKey } = crypto.encryption().asymmetric().generateKeyPair(); + const { publicKey, privateKey } = await crypto.encryption().asymmetric().generateKeyPair(); // eslint-disable-next-line const client = new jsrp.client(); diff --git a/backend/src/ee/services/kmip/kmip-service.ts b/backend/src/ee/services/kmip/kmip-service.ts index 44d970fa3f..c098431202 100644 --- a/backend/src/ee/services/kmip/kmip-service.ts +++ b/backend/src/ee/services/kmip/kmip-service.ts @@ -67,6 +67,12 @@ export const kmipServiceFactory = ({ description, permissions }: TCreateKmipClientDTO) => { + if (crypto.isFipsModeEnabled()) { + throw new BadRequestError({ + message: "KMIP is currently not supported in FIPS mode of operation." + }); + } + const { permission } = await permissionService.getProjectPermission({ actor, actorId, diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index d052f089a9..d7a9347636 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -386,6 +386,34 @@ export const initEnvConfig = async (superAdminDAL?: TSuperAdminDALFactory, logge return envCfg; }; +export const getTelemetryConfig = () => { + const parsedEnv = envSchema.safeParse(process.env); + if (!parsedEnv.success) { + console.error("Invalid environment variables. Check the error below"); + console.error(parsedEnv.error.issues); + process.exit(-1); + } + + return { + useOtel: parsedEnv.data.OTEL_TELEMETRY_COLLECTION_ENABLED, + useDataDogTracer: parsedEnv.data.SHOULD_USE_DATADOG_TRACER, + OTEL: { + otlpURL: parsedEnv.data.OTEL_EXPORT_OTLP_ENDPOINT, + otlpUser: parsedEnv.data.OTEL_COLLECTOR_BASIC_AUTH_USERNAME, + otlpPassword: parsedEnv.data.OTEL_COLLECTOR_BASIC_AUTH_PASSWORD, + otlpPushInterval: parsedEnv.data.OTEL_OTLP_PUSH_INTERVAL, + exportType: parsedEnv.data.OTEL_EXPORT_TYPE + }, + TRACER: { + profiling: parsedEnv.data.DATADOG_PROFILING_ENABLED, + version: parsedEnv.data.INFISICAL_PLATFORM_VERSION, + env: parsedEnv.data.DATADOG_ENV, + service: parsedEnv.data.DATADOG_SERVICE, + hostname: parsedEnv.data.DATADOG_HOSTNAME + } + }; +}; + export const getDatabaseCredentials = (logger?: CustomLogger) => { const parsedEnv = envSchema.safeParse(process.env); if (!parsedEnv.success) { diff --git a/backend/src/lib/crypto/cache.ts b/backend/src/lib/crypto/cache.ts index e74a01d8c2..6a050c8a72 100644 --- a/backend/src/lib/crypto/cache.ts +++ b/backend/src/lib/crypto/cache.ts @@ -1,4 +1,10 @@ import { crypto } from "@app/lib/crypto/cryptography"; export const generateCacheKeyFromData = (data: unknown) => - crypto.rawCrypto.createHash("sha256").update(JSON.stringify(data)).digest("base64"); + crypto.rawCrypto. + .createHash("sha256") + .update(JSON.stringify(data)) + .digest("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=/g, ""); diff --git a/backend/src/lib/crypto/cryptography/asymmetric-fips.ts b/backend/src/lib/crypto/cryptography/asymmetric-fips.ts index 9e1e124599..da49f99fc5 100644 --- a/backend/src/lib/crypto/cryptography/asymmetric-fips.ts +++ b/backend/src/lib/crypto/cryptography/asymmetric-fips.ts @@ -1,11 +1,25 @@ -import crypto from "crypto"; +import crypto, { KeyObject } from "crypto"; import { SecretEncryptionAlgo } from "@app/db/schemas"; import { CryptographyError } from "@app/lib/errors"; +import { logger } from "@app/lib/logger"; export const asymmetricFipsValidated = () => { - const generateKeyPair = () => { - const { publicKey, privateKey } = crypto.generateKeyPairSync("x25519"); + const generateKeyPair = async () => { + const { publicKey, privateKey } = await new Promise<{ publicKey: KeyObject; privateKey: KeyObject }>((resolve) => { + crypto.generateKeyPair("x25519", undefined, (err, pubKey, privKey) => { + if (err) { + logger.error(err, "FIPS generateKeyPair: Failed to generate key pair"); + throw new CryptographyError({ + message: "Failed to generate key pair" + }); + } + resolve({ + publicKey: pubKey, + privateKey: privKey + }); + }); + }); return { publicKey: publicKey.export({ type: "spki", format: "der" }).toString("base64"), diff --git a/backend/src/lib/crypto/cryptography/crypto.ts b/backend/src/lib/crypto/cryptography/crypto.ts index 2fd747dedb..df525e7088 100644 --- a/backend/src/lib/crypto/cryptography/crypto.ts +++ b/backend/src/lib/crypto/cryptography/crypto.ts @@ -19,9 +19,8 @@ import { CryptographyError } from "../../errors"; import { logger } from "../../logger"; import { asymmetricFipsValidated } from "./asymmetric-fips"; import { hasherFipsValidated } from "./hash-fips"; -import { jwtFipsValidated } from "./jwt-fips"; import type { TDecryptAsymmetricInput, TDecryptSymmetricInput, TEncryptSymmetricInput } from "./types"; -import { DigestType, JWTPayload, JWTSecretOrKey, JWTSignOptions, JWTVerifyOptions, SymmetricKeySize } from "./types"; +import { DigestType, SymmetricKeySize } from "./types"; const bytesToBits = (bytes: number) => bytes * 8; @@ -122,6 +121,8 @@ const cryptographyFactory = () => { const $setFipsModeEnabled = (enabled: boolean) => { // If FIPS is enabled, we need to validate that the ENCRYPTION_KEY is in a base64 format, and is a 256-bit key. if (enabled) { + crypto.setFips(true); + const appCfg = getConfig(); if (appCfg.ENCRYPTION_KEY) { @@ -190,9 +191,10 @@ const cryptographyFactory = () => { $checkIsInitialized(); const asymmetric = () => { - const generateKeyPair = () => { + const generateKeyPair = async () => { if (isFipsModeEnabled()) { - return asymmetricFipsValidated().generateKeyPair(); + const keyPair = await asymmetricFipsValidated().generateKeyPair(); + return keyPair; } return generateAsymmetricKeyPairNoFipsValidation(); }; @@ -381,31 +383,10 @@ const cryptographyFactory = () => { const jwt = () => { $checkIsInitialized(); - const sign = (payload: JWTPayload, secretOrKey: JWTSecretOrKey, options: JWTSignOptions = {}) => { - if (isFipsModeEnabled()) { - return jwtFipsValidated().sign(payload, secretOrKey, options); - } - return jwtDep.sign(payload, secretOrKey, options); - }; - - const verify = (token: string, secretOrKey: JWTSecretOrKey, options: JWTVerifyOptions = {}) => { - if (isFipsModeEnabled()) { - return jwtFipsValidated().verify(token, secretOrKey, options); - } - return jwtDep.verify(token, secretOrKey, options); - }; - - const decode = (token: string, options: { complete?: boolean } = {}) => { - if (isFipsModeEnabled()) { - return jwtFipsValidated().decode(token, options); - } - return jwtDep.decode(token, options); - }; - return { - sign, - verify, - decode + sign: jwtDep.sign, + verify: jwtDep.verify, + decode: jwtDep.decode }; }; diff --git a/backend/src/lib/crypto/cryptography/jwt-fips.ts b/backend/src/lib/crypto/cryptography/jwt-fips.ts deleted file mode 100644 index 1b7ee3367b..0000000000 --- a/backend/src/lib/crypto/cryptography/jwt-fips.ts +++ /dev/null @@ -1,327 +0,0 @@ -import crypto from "crypto"; -import RE2 from "re2"; - -import { CryptographyError } from "@app/lib/errors"; - -import { Algorithm, CompleteJWTPayload, JWTPayload, JWTSecretOrKey, JWTSignOptions, JWTVerifyOptions } from "./types"; - -export const jwtFipsValidated = () => { - const $base64urlEncode = (str: string) => Buffer.from(str).toString("base64url"); - const $isRSAAlgorithm = (algorithm: string) => algorithm.startsWith("RS"); - - const $parseTimeToSeconds = (timeStr: string | number) => { - if (typeof timeStr === "number") { - return timeStr; - } - - const match = new RE2(/^(\d+)([smhd])$/).exec(timeStr); - if (!match) { - throw new CryptographyError({ - message: `Invalid JWT time format: ${timeStr}` - }); - } - - const value = parseInt(match[1], 10); - const unit = match[2]; - - switch (unit) { - case "s": - return value; - case "m": - return value * 60; - case "h": - return value * 60 * 60; - case "d": - return value * 60 * 60 * 24; - default: - throw new CryptographyError({ - message: `Unknown JWT time unit: ${unit}` - }); - } - }; - - const $getHashAlgorithm = (algorithm: string) => { - switch (algorithm) { - case "HS256": - case "RS256": - return "sha256"; - case "HS384": - case "RS384": - return "sha384"; - case "HS512": - case "RS512": - return "sha512"; - default: - throw new CryptographyError({ - message: `Unsupported JWT algorithm: ${algorithm}` - }); - } - }; - - /** - * Sign a JWT token - */ - const sign = (payload: JWTPayload, secretOrPrivateKey: JWTSecretOrKey, options: JWTSignOptions = {}) => { - const algorithm = options.algorithm || "HS256"; - - const now = Math.floor(Date.now() / 1000); - // Create header - const header = { - alg: algorithm, - typ: "JWT", - ...(options.keyid && { kid: options.keyid }) - }; - - // Create payload with timestamps - const finalPayload = { - ...payload, - iat: now, - ...(options.expiresIn !== undefined && { exp: now + $parseTimeToSeconds(options.expiresIn) }) - }; - - // Encode header and payload - const encodedHeader = $base64urlEncode(JSON.stringify(header)); - const encodedPayload = $base64urlEncode(JSON.stringify(finalPayload)); - - // Create signature - const data = `${encodedHeader}.${encodedPayload}`; - const hashAlgorithm = $getHashAlgorithm(algorithm); - let signature: string; - - if ($isRSAAlgorithm(algorithm)) { - let privateKey: crypto.KeyLike | { key: string | Buffer }; - - if (typeof secretOrPrivateKey === "string") { - try { - // Try to create a proper private key object - privateKey = crypto.createPrivateKey(secretOrPrivateKey); - } catch (error) { - throw new CryptographyError({ - message: "Invalid JWT private key" - }); - } - } else { - privateKey = secretOrPrivateKey; - } - - const signatureBuffer = crypto.sign(hashAlgorithm, Buffer.from(data), privateKey); - signature = signatureBuffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); - } else { - // HMAC signing - if (typeof secretOrPrivateKey !== "string") { - throw new CryptographyError({ - message: "HMAC algorithms require a string secret" - }); - } - signature = crypto - .createHmac(hashAlgorithm, secretOrPrivateKey) - .update(data) - .digest("base64") - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=/g, ""); - } - - return `${data}.${signature}`; - }; - - const verify = (token: string, secretOrKey: JWTSecretOrKey, options: JWTVerifyOptions = {}) => { - const parts = token.split("."); - if (parts.length !== 3) { - throw new CryptographyError({ - message: "Invalid JWT format" - }); - } - - const [encodedHeader, encodedPayload, signature] = parts; - - // Decode header - const headerJson = Buffer.from(encodedHeader, "base64").toString(); - const header = JSON.parse(headerJson) as { alg: string; typ: string; kid?: string }; - - if (!header.alg || header.typ !== "JWT") { - throw new CryptographyError({ - message: "Invalid JWT header" - }); - } - - // Extract the actual key from different input types - let keyString: string; - if (Buffer.isBuffer(secretOrKey)) { - keyString = secretOrKey.toString(); - } else if (typeof secretOrKey === "object" && "key" in secretOrKey) { - keyString = Buffer.isBuffer(secretOrKey.key) ? secretOrKey.key.toString() : secretOrKey.key; - } else { - keyString = secretOrKey as string; - } - - // Verify signature - const data = `${encodedHeader}.${encodedPayload}`; - const hashAlgorithm = $getHashAlgorithm(header.alg); - let isValidSignature: boolean; - - if ($isRSAAlgorithm(header.alg)) { - // For RSA, handle both private and public keys - let verificationKey: crypto.KeyLike; - - // Clean up the key format - const cleanKey = keyString.replace(/\\n/g, "\n"); - - try { - // If it's a private key, extract the public key for verification - if (cleanKey.includes("PRIVATE KEY")) { - const privateKeyObj = crypto.createPrivateKey(cleanKey); - verificationKey = crypto.createPublicKey(privateKeyObj); - } else { - // It's already a public key - verificationKey = crypto.createPublicKey(cleanKey); - } - } catch (error) { - throw new CryptographyError({ - message: "Invalid JWT signature" - }); - } - - // Convert base64url signature back to buffer - const signatureBuffer = Buffer.from( - signature.replace(/-/g, "+").replace(/_/g, "/") + "==".slice(0, (4 - (signature.length % 4)) % 4), - "base64" - ); - isValidSignature = crypto.verify(hashAlgorithm, Buffer.from(data), verificationKey, signatureBuffer); - } else { - // HMAC verification - const expectedSignature = crypto - .createHmac(hashAlgorithm, keyString) - .update(data) - .digest("base64") - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=/g, ""); - isValidSignature = signature === expectedSignature; - } - - if (!isValidSignature) { - throw new CryptographyError({ - message: "Invalid JWT signature" - }); - } - - // Decode payload - const payloadJson = Buffer.from(encodedPayload, "base64").toString(); - const payload = JSON.parse(payloadJson) as JWTPayload & { - aud?: string | string[]; - iss?: string; - sub?: string; - nbf?: number; - jti?: string; - }; - - const now = Math.floor(Date.now() / 1000); - const clockTolerance = options.clockTolerance || 0; - - // Check expiration - if (!options.ignoreExpiration && payload.exp && now - clockTolerance > payload.exp) { - throw new CryptographyError({ - message: "JWT token has expired" - }); - } - - // Check not before - if (!options.ignoreNotBefore && payload.nbf && now + clockTolerance < payload.nbf) { - throw new CryptographyError({ - message: "JWT not active" - }); - } - - // Check audience - if (options.audience) { - const audiences = Array.isArray(options.audience) ? options.audience : [options.audience]; - const tokenAudiences = Array.isArray(payload.aud) ? payload.aud : [payload.aud]; - const hasValidAudience = audiences.some((aud) => tokenAudiences.includes(aud)); - if (!hasValidAudience) { - throw new CryptographyError({ - message: "JWT audience invalid" - }); - } - } - - // Check issuer - if (options.issuer) { - const issuers = Array.isArray(options.issuer) ? options.issuer : [options.issuer]; - if (!payload.iss || !issuers.includes(payload.iss)) { - throw new CryptographyError({ - message: "JWT issuer invalid" - }); - } - } - - // Check subject - if (options.subject && payload.sub !== options.subject) { - throw new CryptographyError({ - message: "JWT subject invalid" - }); - } - - // Check JWT ID - if (options.jwtid && payload.jti !== options.jwtid) { - throw new CryptographyError({ - message: "JWT ID invalid" - }); - } - - // Check max age - if (options.maxAge && payload.iat) { - const maxAgeSeconds = typeof options.maxAge === "string" ? $parseTimeToSeconds(options.maxAge) : options.maxAge; - if (now - payload.iat > maxAgeSeconds) { - throw new CryptographyError({ - message: "JWT max age exceeded" - }); - } - } - - // Check algorithms - if (options.algorithms && !options.algorithms.includes(header.alg as Algorithm)) { - throw new CryptographyError({ - message: `Algorithm not allowed: ${header.alg}` - }); - } - - return payload; - }; - - const decode = (token: string, options: { complete?: boolean } = {}): JWTPayload | CompleteJWTPayload => { - const parts = token.split("."); - if (parts.length !== 3) { - throw new CryptographyError({ - message: "Invalid JWT format" - }); - } - - const [encodedHeader, encodedPayload] = parts; - - // Decode header - const headerJson = Buffer.from(encodedHeader, "base64").toString(); - const header = JSON.parse(headerJson) as Record; - - // Decode payload - const payloadJson = Buffer.from(encodedPayload, "base64").toString(); - const payload = JSON.parse(payloadJson) as Record; - - // Return complete token info or just payload - if (options.complete) { - return { - header, - payload, - signature: parts[2] - }; - } - - return payload as JWTPayload; - }; - - return { - sign, - verify, - decode - }; -}; diff --git a/backend/src/lib/crypto/cryptography/types.ts b/backend/src/lib/crypto/cryptography/types.ts index e9622575e8..eb2f6dd7e2 100644 --- a/backend/src/lib/crypto/cryptography/types.ts +++ b/backend/src/lib/crypto/cryptography/types.ts @@ -1,5 +1,3 @@ -import { KeyObject } from "crypto"; - import { SecretEncryptionAlgo, SecretKeyEncoding } from "@app/db/schemas"; export enum DigestType { @@ -54,39 +52,3 @@ export type TEncryptedWithRootEncryptionKey = { algorithm: SecretEncryptionAlgo; encoding: SecretKeyEncoding; }; - -export interface JWTPayload { - iat?: number; - exp?: number; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any; -} - -export interface CompleteJWTPayload { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - header: any; - payload: JWTPayload; - signature: string; -} - -export type Algorithm = "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512"; - -export interface JWTSignOptions { - algorithm?: Algorithm | undefined; - keyid?: string | undefined; - expiresIn?: string | number; -} - -export type JWTSecretOrKey = string | Buffer | KeyObject | { key: string | Buffer; passphrase: string }; - -export interface JWTVerifyOptions { - algorithms?: Algorithm[] | undefined; - audience?: string | string[]; - issuer?: string | string[]; - subject?: string; - ignoreExpiration?: boolean; - ignoreNotBefore?: boolean; - clockTolerance?: number; - maxAge?: string | number; - jwtid?: string; -} diff --git a/backend/src/lib/crypto/srp.ts b/backend/src/lib/crypto/srp.ts index 5c204c0338..6c4dbc5aad 100644 --- a/backend/src/lib/crypto/srp.ts +++ b/backend/src/lib/crypto/srp.ts @@ -39,7 +39,7 @@ export const generateUserSrpKeys = async ( password: string, customKeys?: { publicKey: string; privateKey: string } ) => { - const pair = crypto.encryption().asymmetric().generateKeyPair(); + const pair = await crypto.encryption().asymmetric().generateKeyPair(); const privateKey = customKeys?.privateKey || pair.privateKey; const publicKey = customKeys?.publicKey || pair.publicKey; diff --git a/backend/src/lib/telemetry/instrumentation.ts b/backend/src/lib/telemetry/instrumentation.ts index 1c9b29cc7c..3bc6ea7fb4 100644 --- a/backend/src/lib/telemetry/instrumentation.ts +++ b/backend/src/lib/telemetry/instrumentation.ts @@ -6,9 +6,10 @@ import { HttpInstrumentation } from "@opentelemetry/instrumentation-http"; import { Resource } from "@opentelemetry/resources"; import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics"; import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions"; +import tracer from "dd-trace"; import dotenv from "dotenv"; -import { initEnvConfig } from "../config/env"; +import { getTelemetryConfig } from "../config/env"; dotenv.config(); @@ -73,31 +74,17 @@ const initTelemetryInstrumentation = ({ }); }; -const setupTelemetry = async () => { - const envCfg = await initEnvConfig(); +const setupTelemetry = () => { + const appCfg = getTelemetryConfig(); - if (envCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) { + if (appCfg.useOtel) { console.log("Initializing telemetry instrumentation"); - initTelemetryInstrumentation({ - otlpURL: envCfg.OTEL_EXPORT_OTLP_ENDPOINT, - otlpUser: envCfg.OTEL_COLLECTOR_BASIC_AUTH_USERNAME, - otlpPassword: envCfg.OTEL_COLLECTOR_BASIC_AUTH_PASSWORD, - otlpPushInterval: envCfg.OTEL_OTLP_PUSH_INTERVAL, - exportType: envCfg.OTEL_EXPORT_TYPE - }); + initTelemetryInstrumentation({ ...appCfg.OTEL }); } - if (envCfg.SHOULD_USE_DATADOG_TRACER) { - const tracer = await import("dd-trace"); - + if (appCfg.useDataDogTracer) { console.log("Initializing Datadog tracer"); - tracer.init({ - profiling: envCfg.DATADOG_PROFILING_ENABLED, - version: envCfg.INFISICAL_PLATFORM_VERSION, - env: envCfg.DATADOG_ENV, - service: envCfg.DATADOG_SERVICE, - hostname: envCfg.DATADOG_HOSTNAME - }); + tracer.init({ ...appCfg.TRACER }); } }; diff --git a/backend/src/main.ts b/backend/src/main.ts index 1f62f5a767..8af47eb0b3 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -1,3 +1,5 @@ +// Note(Daniel): Do not rename this import, as it is strictly removed from FIPS standalone builds to avoid FIPS mode issues. +// If you rename the import, update the Dockerfile.fips.standalone-infisical file as well. import "./lib/telemetry/instrumentation"; import dotenv from "dotenv"; diff --git a/backend/src/server/plugins/auth/inject-identity.ts b/backend/src/server/plugins/auth/inject-identity.ts index 98982e969f..7b4f5d90c5 100644 --- a/backend/src/server/plugins/auth/inject-identity.ts +++ b/backend/src/server/plugins/auth/inject-identity.ts @@ -1,12 +1,12 @@ import { requestContext } from "@fastify/request-context"; import { FastifyRequest } from "fastify"; import fp from "fastify-plugin"; +import type { JwtPayload } from "jsonwebtoken"; import { TServiceTokens, TUsers } from "@app/db/schemas"; import { TScimTokenJwtPayload } from "@app/ee/services/scim/scim-types"; import { getConfig } from "@app/lib/config/env"; import { crypto } from "@app/lib/crypto"; -import { JWTPayload } from "@app/lib/crypto/cryptography/types"; import { BadRequestError } from "@app/lib/errors"; import { ActorType, AuthMethod, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types"; @@ -73,7 +73,7 @@ const extractAuth = async (req: FastifyRequest, jwtSecret: string) => { } as const; } - const decodedToken = crypto.jwt().verify(authTokenValue, jwtSecret) as JWTPayload; + const decodedToken = crypto.jwt().verify(authTokenValue, jwtSecret) as JwtPayload; switch (decodedToken.authTokenType) { case AuthTokenType.ACCESS_TOKEN: diff --git a/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts b/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts index 546980f41e..35063ae708 100644 --- a/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts +++ b/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts @@ -13,7 +13,6 @@ import { import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { crypto } from "@app/lib/crypto"; -import { CompleteJWTPayload } from "@app/lib/crypto/cryptography/types"; import { BadRequestError, ForbiddenRequestError, @@ -81,7 +80,7 @@ export const identityJwtAuthServiceFactory = ({ orgId: identityMembershipOrg.orgId }); - const decodedToken = crypto.jwt().decode(jwtValue, { complete: true }) as CompleteJWTPayload; + const decodedToken = crypto.jwt().decode(jwtValue, { complete: true }); if (!decodedToken) { throw new UnauthorizedError({ message: "Invalid JWT" diff --git a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts index 997ed6dfdd..08d53a344a 100644 --- a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts +++ b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts @@ -14,7 +14,6 @@ import { import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { crypto } from "@app/lib/crypto"; -import { CompleteJWTPayload } from "@app/lib/crypto/cryptography/types"; import { BadRequestError, ForbiddenRequestError, @@ -95,7 +94,7 @@ export const identityOidcAuthServiceFactory = ({ ); const jwksUri = discoveryDoc.jwks_uri; - const decodedToken = crypto.jwt().decode(oidcJwt, { complete: true }) as CompleteJWTPayload; + const decodedToken = crypto.jwt().decode(oidcJwt, { complete: true }); if (!decodedToken) { throw new UnauthorizedError({ message: "Invalid JWT" diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index eb712843af..94bf4aa4e7 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -497,7 +497,7 @@ export const orgServiceFactory = ({ orgName: string; userEmail?: string | null; }) => { - const { privateKey, publicKey } = crypto.encryption().asymmetric().generateKeyPair(); + const { privateKey, publicKey } = await crypto.encryption().asymmetric().generateKeyPair(); const key = crypto.randomBytes(32).toString("base64"); const { ciphertext: encryptedPrivateKey, diff --git a/backend/src/services/project-bot/project-bot-fns.ts b/backend/src/services/project-bot/project-bot-fns.ts index 42db24d5b2..daf6fa33ed 100644 --- a/backend/src/services/project-bot/project-bot-fns.ts +++ b/backend/src/services/project-bot/project-bot-fns.ts @@ -59,7 +59,7 @@ export const getBotKeyFnFactory = ( publicKey: projectV1Keys.senderPublicKey, privateKey: userPrivateKey }); - const botKey = crypto.encryption().asymmetric().generateKeyPair(); + const botKey = await crypto.encryption().asymmetric().generateKeyPair(); const { iv, tag, ciphertext, encoding, algorithm } = crypto .encryption() .encryptWithRootEncryptionKey(botKey.privateKey); diff --git a/backend/src/services/project-bot/project-bot-service.ts b/backend/src/services/project-bot/project-bot-service.ts index 12e4ecbdcc..ab2eb7b527 100644 --- a/backend/src/services/project-bot/project-bot-service.ts +++ b/backend/src/services/project-bot/project-bot-service.ts @@ -54,7 +54,7 @@ export const projectBotServiceFactory = ({ if (doc) return doc; const keys = - privateKey && publicKey ? { privateKey, publicKey } : crypto.encryption().asymmetric().generateKeyPair(); + privateKey && publicKey ? { privateKey, publicKey } : await crypto.encryption().asymmetric().generateKeyPair(); const { iv, tag, ciphertext, encoding, algorithm } = crypto .encryption()