Uecko_ERP/modules/identity/src/api/infrastructure/express/middlewares/authenticate-user.middleware.ts

75 lines
2.5 KiB
TypeScript

import {
ExpressController,
type RequestWithAuth,
UnauthorizedApiError,
} from "@erp/core/api";
import { EmailAddress, UniqueID } from "@repo/rdx-ddd";
import type { NextFunction, Request, Response } from "express";
import type { IAccessTokenVerifier, IAccountRepository } from "../../../application";
function parseBearerToken(authorization?: string): string | undefined {
if (!authorization) {
return undefined;
}
const [scheme, token] = authorization.split(" ");
if (scheme?.toLowerCase() !== "bearer") {
return undefined;
}
return token?.trim() || undefined;
}
export function authenticateUser(params: {
accessTokenVerifier: IAccessTokenVerifier;
accountRepository: IAccountRepository;
}) {
return async (req: Request, res: Response, next: NextFunction) => {
try {
const authorization = req.get("authorization");
const token = parseBearerToken(authorization);
if (!token) {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
const verifiedTokenResult = await params.accessTokenVerifier.verify(token);
if (verifiedTokenResult.isFailure) {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
const accountIdResult = UniqueID.create(verifiedTokenResult.data.accountId);
if (accountIdResult.isFailure) {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
const accountResult = await params.accountRepository.findById(accountIdResult.data);
if (accountResult.isFailure || accountResult.data.isNone()) {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
const account = accountResult.data.unwrap();
const canAuthenticateResult = account.canAuthenticate();
if (canAuthenticateResult.isFailure) {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
const emailResult = EmailAddress.create(verifiedTokenResult.data.email);
if (emailResult.isFailure) {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
(req as RequestWithAuth).user = {
userId: account.id,
email: emailResult.data,
roles: [],
};
return next();
} catch {
return ExpressController.errorResponse(new UnauthorizedApiError("Unauthorized"), req, res);
}
};
}