mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: better api errors
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import fastifyPlugin from "fastify-plugin";
|
||||
import { JsonWebTokenError } from "jsonwebtoken";
|
||||
import { ZodError } from "zod";
|
||||
|
||||
import { UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import {
|
||||
BadRequestError,
|
||||
DatabaseError,
|
||||
@@ -11,6 +13,12 @@ import {
|
||||
UnauthorizedError
|
||||
} from "@app/lib/errors";
|
||||
|
||||
enum JWTErrors {
|
||||
JwtExpired = "jwt expired",
|
||||
JwtMalformed = "jwt malformed",
|
||||
InvalidAlgorithm = "invalid algorithm"
|
||||
}
|
||||
|
||||
export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider) => {
|
||||
server.setErrorHandler((error, req, res) => {
|
||||
req.log.error(error);
|
||||
@@ -36,6 +44,35 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider
|
||||
status: error.status,
|
||||
detail: error.detail
|
||||
});
|
||||
// Handle JWT errors and make them more human-readable for the end-user.
|
||||
} else if (error instanceof JsonWebTokenError) {
|
||||
const isCliRequest = req.headers["user-agent"] === UserAgentType.CLI;
|
||||
|
||||
const message = (() => {
|
||||
if (error.message === JWTErrors.JwtExpired) {
|
||||
return "Your token has expired. Please re-authenticate.";
|
||||
}
|
||||
if (error.message === JWTErrors.JwtMalformed) {
|
||||
if (isCliRequest) {
|
||||
return "The access token is malformed. Are you sure the token you are using is correct? Check the INFISICAL_TOKEN environment variable, or the --token flag. If you are using user-login, please run [infisical login] to re-authenticate.";
|
||||
}
|
||||
return "The access token is malformed. Please ensure that the token is in the correct format and try again.";
|
||||
}
|
||||
if (error.message === JWTErrors.InvalidAlgorithm) {
|
||||
if (isCliRequest) {
|
||||
return "Invalid algorithm. Are you sure you are using the correct authentication method? Make sure to check that you don't have the INFISICAL_TOKEN variable set in your environment variables. If you are intentionally using the INFISICAL_TOKEN variable, make sure you are using the correct token." as const;
|
||||
}
|
||||
return "The access token is signed with an invalid algorithm. Please ensure that the token is in the correct format and try again. We recommend obtaining a new token.";
|
||||
}
|
||||
|
||||
return error.message;
|
||||
})();
|
||||
|
||||
void res.status(401).send({
|
||||
statusCode: 401,
|
||||
error: "TokenError",
|
||||
message
|
||||
});
|
||||
} else {
|
||||
void res.send(error);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ export const getBotKeyFnFactory = (
|
||||
) => {
|
||||
const getBotKeyFn = async (projectId: string) => {
|
||||
const project = await projectDAL.findById(projectId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found during bot lookup." });
|
||||
if (!project)
|
||||
throw new BadRequestError({
|
||||
message: "Project not found during bot lookup. Are you sure you are using the correct project ID?"
|
||||
});
|
||||
|
||||
if (project.version === 3) {
|
||||
return { project, shouldUseSecretV2Bridge: true };
|
||||
|
||||
@@ -512,7 +512,11 @@ export const secretImportServiceFactory = ({
|
||||
return importedSecrets;
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
|
||||
const importedSecrets = await fnSecretsFromImports({ allowedImports, folderDAL, secretDAL, secretImportDAL });
|
||||
return importedSecrets.map((el) => ({
|
||||
|
||||
@@ -832,7 +832,11 @@ export const createManySecretsRawFnFactory = ({
|
||||
secretDAL
|
||||
});
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
const inputSecrets = secrets.map((secret) => {
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretName, botKey);
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretValue || "", botKey);
|
||||
@@ -993,7 +997,11 @@ export const updateManySecretsRawFnFactory = ({
|
||||
return updatedSecrets;
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
|
||||
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
|
||||
|
||||
|
||||
@@ -985,7 +985,11 @@ export const secretServiceFactory = ({
|
||||
return { secrets, imports };
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
|
||||
const { secrets, imports } = await getSecrets({
|
||||
actorId,
|
||||
@@ -1146,7 +1150,10 @@ export const secretServiceFactory = ({
|
||||
});
|
||||
|
||||
if (!botKey)
|
||||
throw new BadRequestError({ message: "Please upgrade your project first", name: "bot_not_found_error" });
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
const decryptedSecret = decryptSecretRaw(encryptedSecret, botKey);
|
||||
|
||||
if (expandSecretReferences) {
|
||||
@@ -1238,7 +1245,11 @@ export const secretServiceFactory = ({
|
||||
return { secret, type: SecretProtectionType.Direct as const };
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretName, botKey);
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
@@ -1376,7 +1387,11 @@ export const secretServiceFactory = ({
|
||||
return { type: SecretProtectionType.Direct as const, secret };
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
@@ -1498,7 +1513,11 @@ export const secretServiceFactory = ({
|
||||
});
|
||||
return { type: SecretProtectionType.Direct as const, secret };
|
||||
}
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
if (policy) {
|
||||
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||
policy,
|
||||
@@ -1598,7 +1617,11 @@ export const secretServiceFactory = ({
|
||||
return { secrets, type: SecretProtectionType.Direct as const };
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
const sanitizedSecrets = inputSecrets.map(
|
||||
({ secretComment, secretKey, metadata, tagIds, secretValue, skipMultilineEncoding }) => {
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretKey, botKey);
|
||||
@@ -1720,7 +1743,11 @@ export const secretServiceFactory = ({
|
||||
return { type: SecretProtectionType.Direct as const, secrets };
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
const sanitizedSecrets = inputSecrets.map(
|
||||
({
|
||||
secretComment,
|
||||
@@ -1848,7 +1875,11 @@ export const secretServiceFactory = ({
|
||||
return { type: SecretProtectionType.Direct as const, secrets };
|
||||
}
|
||||
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
if (!botKey)
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
|
||||
if (policy) {
|
||||
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||
@@ -2182,7 +2213,10 @@ export const secretServiceFactory = ({
|
||||
}
|
||||
|
||||
if (!botKey)
|
||||
throw new BadRequestError({ message: "Please upgrade your project first", name: "bot_not_found_error" });
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
|
||||
await secretDAL.transaction(async (tx) => {
|
||||
const secrets = await secretDAL.findAllProjectSecretValues(projectId, tx);
|
||||
@@ -2265,7 +2299,10 @@ export const secretServiceFactory = ({
|
||||
|
||||
const { botKey } = await projectBotService.getBotKey(project.id);
|
||||
if (!botKey) {
|
||||
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
throw new BadRequestError({
|
||||
message: "Project bot not found. Please upgrade your project.",
|
||||
name: "bot_not_found_error"
|
||||
});
|
||||
}
|
||||
|
||||
const sourceFolder = await folderDAL.findBySecretPath(project.id, sourceEnvironment, sourceSecretPath);
|
||||
|
||||
Reference in New Issue
Block a user