mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-11 00:17:59 -05:00
feat: fips inside (checkpoint)
This commit is contained in:
@@ -26,15 +26,18 @@ export default {
|
||||
transformMode: "ssr",
|
||||
async setup() {
|
||||
const logger = initLogger();
|
||||
const envConfig = initEnvConfig(logger);
|
||||
const { envCfg, updateRootEncryptionKey } = initEnvConfig(logger);
|
||||
const db = initDbConnection({
|
||||
dbConnectionUri: envConfig.DB_CONNECTION_URI,
|
||||
dbRootCert: envConfig.DB_ROOT_CERT
|
||||
dbConnectionUri: envCfg.DB_CONNECTION_URI,
|
||||
dbRootCert: envCfg.DB_ROOT_CERT
|
||||
});
|
||||
const superAdminDAL = superAdminDALFactory(db);
|
||||
await crypto.initialize(superAdminDAL);
|
||||
const fipsEnabled = await crypto.initialize(superAdminDAL);
|
||||
if (fipsEnabled) {
|
||||
updateRootEncryptionKey(envCfg.ENCRYPTION_KEY);
|
||||
}
|
||||
|
||||
const redis = buildRedisFromConfig(envConfig);
|
||||
const redis = buildRedisFromConfig(envCfg);
|
||||
await redis.flushdb("SYNC");
|
||||
|
||||
try {
|
||||
@@ -59,10 +62,10 @@ export default {
|
||||
});
|
||||
|
||||
const smtp = mockSmtpServer();
|
||||
const queue = queueServiceFactory(envConfig, { dbConnectionUrl: envConfig.DB_CONNECTION_URI });
|
||||
const keyStore = keyStoreFactory(envConfig);
|
||||
const queue = queueServiceFactory(envCfg, { dbConnectionUrl: envCfg.DB_CONNECTION_URI });
|
||||
const keyStore = keyStoreFactory(envCfg);
|
||||
|
||||
const hsmModule = initializeHsmModule(envConfig);
|
||||
const hsmModule = initializeHsmModule(envCfg);
|
||||
hsmModule.initialize();
|
||||
|
||||
const server = await main({
|
||||
@@ -74,7 +77,7 @@ export default {
|
||||
hsmModule: hsmModule.getModule(),
|
||||
superAdminDAL,
|
||||
redis,
|
||||
envConfig
|
||||
envConfig: envCfg
|
||||
});
|
||||
|
||||
// @ts-expect-error type
|
||||
@@ -91,8 +94,8 @@ export default {
|
||||
organizationId: seedData1.organization.id,
|
||||
accessVersion: 1
|
||||
},
|
||||
envConfig.AUTH_SECRET,
|
||||
{ expiresIn: envConfig.JWT_AUTH_LIFETIME }
|
||||
envCfg.AUTH_SECRET,
|
||||
{ expiresIn: envCfg.JWT_AUTH_LIFETIME }
|
||||
);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line
|
||||
|
||||
@@ -353,8 +353,23 @@ export const initEnvConfig = (logger?: CustomLogger) => {
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
envCfg = Object.freeze(parsedEnv.data);
|
||||
return envCfg;
|
||||
const updateRootEncryptionKey = (key?: string) => {
|
||||
if (!key) {
|
||||
throw new Error("Failed to update root encryption key. Key is unset.");
|
||||
}
|
||||
|
||||
const newEnvCfg = {
|
||||
...envCfg
|
||||
};
|
||||
|
||||
newEnvCfg.ROOT_ENCRYPTION_KEY = key;
|
||||
delete newEnvCfg.ENCRYPTION_KEY;
|
||||
|
||||
envCfg = Object.freeze(newEnvCfg);
|
||||
return envCfg;
|
||||
};
|
||||
|
||||
return { envCfg, updateRootEncryptionKey };
|
||||
};
|
||||
|
||||
export const formatSmtpConfig = () => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { SymmetricKeyAlgorithm, TSymmetricEncryptionFns } from "./types";
|
||||
const IV_LENGTH = 12;
|
||||
const TAG_LENGTH = 16;
|
||||
|
||||
// todo(daniel): Decide if we should move this into the cryptography module
|
||||
export const symmetricCipherService = (
|
||||
type: SymmetricKeyAlgorithm.AES_GCM_128 | SymmetricKeyAlgorithm.AES_GCM_256
|
||||
): TSymmetricEncryptionFns => {
|
||||
|
||||
@@ -11,7 +11,9 @@ import { SecretEncryptionAlgo, SecretKeyEncoding } from "@app/db/schemas";
|
||||
import { TSuperAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
|
||||
import { ADMIN_CONFIG_DB_UUID } from "@app/services/super-admin/super-admin-service";
|
||||
|
||||
import { isBase64 } from "../base64";
|
||||
import { getConfig } from "../config/env";
|
||||
import { CryptographyError } from "../errors";
|
||||
import { logger } from "../logger";
|
||||
|
||||
enum DigestType {
|
||||
@@ -59,6 +61,8 @@ type TDecryptAsymmetricInput = {
|
||||
privateKey: string;
|
||||
};
|
||||
|
||||
const bytesToBits = (bytes: number) => bytes * 8;
|
||||
|
||||
const IV_BYTES_SIZE = 12;
|
||||
const BLOCK_SIZE_BYTES_16 = 16;
|
||||
|
||||
@@ -294,6 +298,33 @@ const cryptographyFactory = () => {
|
||||
return $fipsEnabled;
|
||||
};
|
||||
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) {
|
||||
const appCfg = getConfig();
|
||||
|
||||
if (appCfg.ENCRYPTION_KEY) {
|
||||
// we need to validate that the ENCRYPTION_KEY is a base64 encoded 256-bit key
|
||||
|
||||
if (!isBase64(appCfg.ENCRYPTION_KEY)) {
|
||||
throw new CryptographyError({
|
||||
message:
|
||||
"FIPS mode is enabled, but the ENCRYPTION_KEY environment variable is not a base64 encoded 256-bit key.\nYou can generate a 256-bit key using the following command: `openssl rand -base64 32`"
|
||||
});
|
||||
}
|
||||
|
||||
if (bytesToBits(Buffer.from(appCfg.ENCRYPTION_KEY, "base64").length) !== 256) {
|
||||
throw new CryptographyError({
|
||||
message:
|
||||
"FIPS mode is enabled, but the ENCRYPTION_KEY environment variable is not a 256-bit key.\nYou can generate a 256-bit key using the following command: `openssl rand -base64 32`"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw new CryptographyError({
|
||||
message:
|
||||
"FIPS mode is enabled, but the ENCRYPTION_KEY environment variable is not set.\nYou can generate a 256-bit key using the following command: `openssl rand -base64 32`"
|
||||
});
|
||||
}
|
||||
}
|
||||
$fipsEnabled = enabled;
|
||||
$isInitialized = true;
|
||||
};
|
||||
@@ -337,52 +368,22 @@ const cryptographyFactory = () => {
|
||||
const asymmetric = () => {
|
||||
const generateKeyPair = () => {
|
||||
if (isFipsModeEnabled()) {
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is enabled.");
|
||||
return generateAsymmetricKeyPairFipsValidated();
|
||||
}
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Generating asymmetric key pair. FIPS mode is DISABLED.");
|
||||
return generateAsymmetricKeyPairNoFipsValidation();
|
||||
};
|
||||
|
||||
const encrypt = (data: string, publicKey: string, privateKey: string) => {
|
||||
if (isFipsModeEnabled()) {
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is enabled.");
|
||||
return encryptAsymmetricFipsValidated(data, publicKey, privateKey);
|
||||
}
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Encrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
return encryptAsymmetricNoFipsValidation(data, publicKey, privateKey);
|
||||
};
|
||||
|
||||
const decrypt = ({ ciphertext, nonce, publicKey, privateKey }: TDecryptAsymmetricInput) => {
|
||||
if (isFipsModeEnabled()) {
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is enabled.");
|
||||
return decryptAsymmetricFipsValidated({ ciphertext, nonce, publicKey, privateKey });
|
||||
}
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
logger.info("[FIPS]: Decrypting asymmetric data. FIPS mode is DISABLED.");
|
||||
return decryptAsymmetricNoFipsValidation({ ciphertext, nonce, publicKey, privateKey });
|
||||
};
|
||||
|
||||
@@ -397,6 +398,12 @@ const cryptographyFactory = () => {
|
||||
let decipher;
|
||||
|
||||
if (keySize === SymmetricKeySize.Bits128) {
|
||||
if (isFipsModeEnabled()) {
|
||||
throw new CryptographyError({
|
||||
message: "128-bit symmetric key is not supported in FIPS mode of operation."
|
||||
});
|
||||
}
|
||||
|
||||
// Not ideal: 128-bit hex key (32 chars) gets interpreted as 32 UTF-8 bytes (256 bits)
|
||||
// This works but reduces effective key entropy from 256 to 128 bits
|
||||
// Note: Never use this for FIPS mode of operation.
|
||||
@@ -418,6 +425,12 @@ const cryptographyFactory = () => {
|
||||
let cipher;
|
||||
|
||||
if (keySize === SymmetricKeySize.Bits128) {
|
||||
if (isFipsModeEnabled()) {
|
||||
throw new CryptographyError({
|
||||
message: "128-bit symmetric key is not supported in FIPS mode of operation."
|
||||
});
|
||||
}
|
||||
|
||||
iv = crypto.randomBytes(BLOCK_SIZE_BYTES_16);
|
||||
cipher = crypto.createCipheriv(SecretEncryptionAlgo.AES_256_GCM, key, iv);
|
||||
} else {
|
||||
@@ -478,21 +491,6 @@ const cryptographyFactory = () => {
|
||||
}: Omit<TDecryptSymmetricInput, "key" | "keySize"> & {
|
||||
keyEncoding: SecretKeyEncoding;
|
||||
}) => {
|
||||
logger.info(
|
||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
||||
);
|
||||
logger.info(
|
||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
||||
);
|
||||
logger.info(
|
||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
||||
);
|
||||
logger.info(
|
||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
||||
);
|
||||
logger.info(
|
||||
`[FIPS]: decryptWithRootEncryptionKey -> Decrypting symmetric data. FIPS mode is: ${isFipsModeEnabled()}`
|
||||
);
|
||||
const appCfg = getConfig();
|
||||
// the or gate is used used in migration
|
||||
const rootEncryptionKey = appCfg?.ROOT_ENCRYPTION_KEY || process.env.ROOT_ENCRYPTION_KEY;
|
||||
@@ -530,11 +528,6 @@ const cryptographyFactory = () => {
|
||||
* @deprecated Do not use MD5 unless you absolutely have to. It is considered an unsafe hashing algorithm, and should only be used if absolutely necessary.
|
||||
*/
|
||||
const md5 = (message: string, digest: DigestType = DigestType.Hex) => {
|
||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: md5 -> Hashing message. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
// If FIPS is enabled and we need MD5, we use the crypto-js implementation.
|
||||
// Avoid this at all costs unless strictly necessary, like for mongo atlas digest auth.
|
||||
if (isFipsModeEnabled()) {
|
||||
@@ -544,12 +537,6 @@ const cryptographyFactory = () => {
|
||||
};
|
||||
|
||||
const createHash = async (password: string, saltRounds: number) => {
|
||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: createHash -> Hashing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
if (isFipsModeEnabled()) {
|
||||
const hasher = hasherFipsValidated();
|
||||
|
||||
@@ -566,12 +553,6 @@ const cryptographyFactory = () => {
|
||||
};
|
||||
|
||||
const compareHash = async (password: string, hash: string) => {
|
||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
logger.info(`[FIPS]: compareHash -> Comparing password. FIPS mode is: ${isFipsModeEnabled()}`);
|
||||
if (isFipsModeEnabled()) {
|
||||
const isValid = await hasherFipsValidated().compare(password, hash);
|
||||
return isValid;
|
||||
|
||||
@@ -171,3 +171,15 @@ export class OidcAuthError extends Error {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
export class CryptographyError extends Error {
|
||||
name: string;
|
||||
|
||||
error: unknown;
|
||||
|
||||
constructor({ name, error, message }: { message?: string; name?: string; error?: unknown }) {
|
||||
super(message || "Cryptographic operation failed");
|
||||
this.name = name || "CryptographyError";
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,27 +75,29 @@ const initTelemetryInstrumentation = ({
|
||||
};
|
||||
|
||||
const setupTelemetry = () => {
|
||||
const appCfg = initEnvConfig();
|
||||
const { envCfg } = initEnvConfig();
|
||||
|
||||
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
|
||||
console.log("envCfg", envCfg);
|
||||
|
||||
if (envCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
|
||||
console.log("Initializing telemetry instrumentation");
|
||||
initTelemetryInstrumentation({
|
||||
otlpURL: appCfg.OTEL_EXPORT_OTLP_ENDPOINT,
|
||||
otlpUser: appCfg.OTEL_COLLECTOR_BASIC_AUTH_USERNAME,
|
||||
otlpPassword: appCfg.OTEL_COLLECTOR_BASIC_AUTH_PASSWORD,
|
||||
otlpPushInterval: appCfg.OTEL_OTLP_PUSH_INTERVAL,
|
||||
exportType: appCfg.OTEL_EXPORT_TYPE
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
if (appCfg.SHOULD_USE_DATADOG_TRACER) {
|
||||
if (envCfg.SHOULD_USE_DATADOG_TRACER) {
|
||||
console.log("Initializing Datadog tracer");
|
||||
tracer.init({
|
||||
profiling: appCfg.DATADOG_PROFILING_ENABLED,
|
||||
version: appCfg.INFISICAL_PLATFORM_VERSION,
|
||||
env: appCfg.DATADOG_ENV,
|
||||
service: appCfg.DATADOG_SERVICE,
|
||||
hostname: appCfg.DATADOG_HOSTNAME
|
||||
profiling: envCfg.DATADOG_PROFILING_ENABLED,
|
||||
version: envCfg.INFISICAL_PLATFORM_VERSION,
|
||||
env: envCfg.DATADOG_ENV,
|
||||
service: envCfg.DATADOG_SERVICE,
|
||||
hostname: envCfg.DATADOG_HOSTNAME
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,26 +22,29 @@ dotenv.config();
|
||||
|
||||
const run = async () => {
|
||||
const logger = initLogger();
|
||||
const envConfig = initEnvConfig(logger);
|
||||
const { envCfg, updateRootEncryptionKey } = initEnvConfig(logger);
|
||||
|
||||
await removeTemporaryBaseDirectory();
|
||||
|
||||
const db = initDbConnection({
|
||||
dbConnectionUri: envConfig.DB_CONNECTION_URI,
|
||||
dbRootCert: envConfig.DB_ROOT_CERT,
|
||||
readReplicas: envConfig.DB_READ_REPLICAS?.map((el) => ({
|
||||
dbConnectionUri: envCfg.DB_CONNECTION_URI,
|
||||
dbRootCert: envCfg.DB_ROOT_CERT,
|
||||
readReplicas: envCfg.DB_READ_REPLICAS?.map((el) => ({
|
||||
dbRootCert: el.DB_ROOT_CERT,
|
||||
dbConnectionUri: el.DB_CONNECTION_URI
|
||||
}))
|
||||
});
|
||||
|
||||
const superAdminDAL = superAdminDALFactory(db);
|
||||
await crypto.initialize(superAdminDAL);
|
||||
const fipsEnabled = await crypto.initialize(superAdminDAL);
|
||||
if (fipsEnabled) {
|
||||
updateRootEncryptionKey(envCfg.ENCRYPTION_KEY);
|
||||
}
|
||||
|
||||
const auditLogDb = envConfig.AUDIT_LOGS_DB_CONNECTION_URI
|
||||
const auditLogDb = envCfg.AUDIT_LOGS_DB_CONNECTION_URI
|
||||
? initAuditLogDbConnection({
|
||||
dbConnectionUri: envConfig.AUDIT_LOGS_DB_CONNECTION_URI,
|
||||
dbRootCert: envConfig.AUDIT_LOGS_DB_ROOT_CERT
|
||||
dbConnectionUri: envCfg.AUDIT_LOGS_DB_CONNECTION_URI,
|
||||
dbRootCert: envCfg.AUDIT_LOGS_DB_ROOT_CERT
|
||||
})
|
||||
: undefined;
|
||||
|
||||
@@ -49,17 +52,17 @@ const run = async () => {
|
||||
|
||||
const smtp = smtpServiceFactory(formatSmtpConfig());
|
||||
|
||||
const queue = queueServiceFactory(envConfig, {
|
||||
dbConnectionUrl: envConfig.DB_CONNECTION_URI,
|
||||
dbRootCert: envConfig.DB_ROOT_CERT
|
||||
const queue = queueServiceFactory(envCfg, {
|
||||
dbConnectionUrl: envCfg.DB_CONNECTION_URI,
|
||||
dbRootCert: envCfg.DB_ROOT_CERT
|
||||
});
|
||||
|
||||
await queue.initialize();
|
||||
|
||||
const keyStore = keyStoreFactory(envConfig);
|
||||
const redis = buildRedisFromConfig(envConfig);
|
||||
const keyStore = keyStoreFactory(envCfg);
|
||||
const redis = buildRedisFromConfig(envCfg);
|
||||
|
||||
const hsmModule = initializeHsmModule(envConfig);
|
||||
const hsmModule = initializeHsmModule(envCfg);
|
||||
hsmModule.initialize();
|
||||
|
||||
const server = await main({
|
||||
@@ -72,7 +75,7 @@ const run = async () => {
|
||||
queue,
|
||||
keyStore,
|
||||
redis,
|
||||
envConfig
|
||||
envConfig: envCfg
|
||||
});
|
||||
const bootstrap = await bootstrapCheck({ db });
|
||||
|
||||
@@ -96,7 +99,7 @@ const run = async () => {
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
if (!envConfig.isDevelopmentMode) {
|
||||
if (!envCfg.isDevelopmentMode) {
|
||||
process.on("uncaughtException", (error) => {
|
||||
logger.error(error, "CRITICAL ERROR: Uncaught Exception");
|
||||
});
|
||||
@@ -107,8 +110,8 @@ const run = async () => {
|
||||
}
|
||||
|
||||
await server.listen({
|
||||
port: envConfig.PORT,
|
||||
host: envConfig.HOST,
|
||||
port: envCfg.PORT,
|
||||
host: envCfg.HOST,
|
||||
listenTextResolver: (address) => {
|
||||
void bootstrap();
|
||||
return address;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ZodError } from "zod";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import {
|
||||
BadRequestError,
|
||||
CryptographyError,
|
||||
DatabaseError,
|
||||
ForbiddenRequestError,
|
||||
GatewayTimeoutError,
|
||||
@@ -147,6 +148,13 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider
|
||||
message: error.message,
|
||||
error: error.name
|
||||
});
|
||||
} else if (error instanceof CryptographyError) {
|
||||
void res.status(HttpStatusCodes.BadRequest).send({
|
||||
reqId: req.id,
|
||||
statusCode: HttpStatusCodes.BadRequest,
|
||||
message: error.message,
|
||||
error: error.name
|
||||
});
|
||||
} else if (error instanceof jwt.JsonWebTokenError) {
|
||||
let errorMessage = error.message;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user