Files
sign/packages/api/v1/middleware/authenticated.ts

92 lines
2.3 KiB
TypeScript
Raw Normal View History

2025-03-03 14:49:28 +11:00
import type { Team, User } from '@prisma/client';
2025-01-02 15:33:37 +11:00
import type { TsRestRequest } from '@ts-rest/serverless';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
2024-02-22 13:39:34 +11:00
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
2025-01-02 15:33:37 +11:00
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
2025-01-02 15:33:37 +11:00
type B = {
// appRoute: any;
request: TsRestRequest;
responseHeaders: Headers;
};
export const authenticatedMiddleware = <
T extends {
2025-01-02 15:33:37 +11:00
headers: {
authorization: string;
};
},
R extends {
status: number;
body: unknown;
},
>(
handler: (
2025-01-02 15:33:37 +11:00
args: T & { req: TsRestRequest },
user: User,
team: Team | null | undefined,
options: { metadata: ApiRequestMetadata },
) => Promise<R>,
) => {
2025-01-02 15:33:37 +11:00
return async (args: T, { request }: B) => {
try {
2025-01-02 15:33:37 +11:00
const { authorization } = args.headers;
2024-02-20 19:46:18 +11:00
// Support for both "Authorization: Bearer api_xxx" and "Authorization: api_xxx"
const [token] = (authorization || '').split('Bearer ').filter((s) => s.length > 0);
if (!token) {
throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'API token was not provided',
});
}
2024-02-22 13:39:34 +11:00
const apiToken = await getApiTokenByToken({ token });
if (apiToken.user.disabled) {
throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'User is disabled',
});
}
const metadata: ApiRequestMetadata = {
2025-02-25 16:37:36 +11:00
requestMetadata: extractRequestMetadata(request),
source: 'apiV1',
auth: 'api',
auditUser: {
id: apiToken.team ? null : apiToken.user.id,
email: apiToken.team ? null : apiToken.user.email,
name: apiToken.team?.name ?? apiToken.user.name,
},
};
2025-01-02 15:33:37 +11:00
return await handler(
{
...args,
req: request,
},
apiToken.user,
apiToken.team,
{ metadata },
);
} catch (err) {
console.log({ err: err });
let message = 'Unauthorized';
if (err instanceof AppError) {
message = err.message;
}
return {
status: 401,
body: {
message,
},
} as const;
}
};
};