feat(api): improve errors and error handling

This commit is contained in:
Daniel Hougaard
2024-09-27 20:02:43 +04:00
parent 02c51b05b6
commit 2d51ed317f
99 changed files with 922 additions and 847 deletions
@@ -6,7 +6,7 @@ import bcrypt from "bcrypt";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { TAccessTokenQueueServiceFactory } from "../access-token-queue/access-token-queue";
import { ActorType } from "../auth/auth-type";
@@ -75,7 +75,7 @@ export const serviceTokenServiceFactory = ({
// validates env
const scopeEnvs = [...new Set(scopes.map(({ environment }) => environment))];
const inputEnvs = await projectEnvDAL.findBySlugs(projectId, scopeEnvs);
if (inputEnvs.length !== scopeEnvs.length) throw new BadRequestError({ message: "Environment not found" });
if (inputEnvs.length !== scopeEnvs.length) throw new NotFoundError({ message: "Environment not found" });
const secret = crypto.randomBytes(16).toString("hex");
const secretHash = await bcrypt.hash(secret, appCfg.SALT_ROUNDS);
@@ -106,7 +106,7 @@ export const serviceTokenServiceFactory = ({
const deleteServiceToken = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteServiceTokenDTO) => {
const serviceToken = await serviceTokenDAL.findById(id);
if (!serviceToken) throw new BadRequestError({ message: "Token not found" });
if (!serviceToken) throw new NotFoundError({ message: "Token not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
@@ -122,13 +122,13 @@ export const serviceTokenServiceFactory = ({
};
const getServiceToken = async ({ actor, actorId }: TGetServiceTokenInfoDTO) => {
if (actor !== ActorType.SERVICE) throw new BadRequestError({ message: "Service token not found" });
if (actor !== ActorType.SERVICE) throw new NotFoundError({ message: "Service token not found" });
const serviceToken = await serviceTokenDAL.findById(actorId);
if (!serviceToken) throw new BadRequestError({ message: "Token not found" });
if (!serviceToken) throw new NotFoundError({ message: "Token not found" });
const serviceTokenUser = await userDAL.findById(serviceToken.createdBy);
if (!serviceTokenUser) throw new BadRequestError({ message: "Service token user not found" });
if (!serviceTokenUser) throw new NotFoundError({ message: "Service token user not found" });
return { serviceToken, user: serviceTokenUser };
};
@@ -154,21 +154,21 @@ export const serviceTokenServiceFactory = ({
};
const fnValidateServiceToken = async (token: string) => {
const [, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>token.split(".", 3);
const serviceToken = await serviceTokenDAL.findById(TOKEN_IDENTIFIER);
const [, tokenIdentifier, tokenSecret] = <[string, string, string]>token.split(".", 3);
const serviceToken = await serviceTokenDAL.findById(tokenIdentifier);
if (!serviceToken) throw new UnauthorizedError();
if (!serviceToken) throw new NotFoundError({ message: "Service token not found" });
const project = await projectDAL.findById(serviceToken.projectId);
if (!project) throw new UnauthorizedError({ message: "Service token project not found" });
if (!project) throw new NotFoundError({ message: "Service token project not found" });
if (serviceToken.expiresAt && new Date(serviceToken.expiresAt) < new Date()) {
await serviceTokenDAL.deleteById(serviceToken.id);
throw new UnauthorizedError({ message: "failed to authenticate expired service token" });
throw new ForbiddenRequestError({ message: "Service token has expired" });
}
const isMatch = await bcrypt.compare(TOKEN_SECRET, serviceToken.secretHash);
if (!isMatch) throw new UnauthorizedError();
const isMatch = await bcrypt.compare(tokenSecret, serviceToken.secretHash);
if (!isMatch) throw new ForbiddenRequestError();
await accessTokenQueue.updateServiceTokenStatus(serviceToken.id);
return { ...serviceToken, lastUsed: new Date(), orgId: project.orgId };