125 lines
3.7 KiB
TypeScript
125 lines
3.7 KiB
TypeScript
import { type ModuleParams, buildTransactionManager } from "@erp/core/api";
|
|
|
|
import {
|
|
AccountAuthenticator,
|
|
type IAccessTokenVerifier,
|
|
type GetCurrentSessionUseCase,
|
|
GetCurrentSessionUseCase as GetCurrentSessionUseCaseImpl,
|
|
type LoginWithPasswordUseCase,
|
|
LoginWithPasswordUseCase as LoginWithPasswordUseCaseImpl,
|
|
type LogoutUseCase,
|
|
LogoutUseCase as LogoutUseCaseImpl,
|
|
type RefreshSessionUseCase,
|
|
RefreshSessionUseCase as RefreshSessionUseCaseImpl,
|
|
SessionIssuer,
|
|
} from "../../application/authentication";
|
|
import type { IAccountRepository } from "../../application/accounts";
|
|
import { identityAuthenticateRequest } from "../express/middlewares";
|
|
import {
|
|
SequelizeAccountDomainMapper,
|
|
SequelizeAccountRepository,
|
|
SequelizeRefreshTokenDomainMapper,
|
|
SequelizeRefreshTokenRepository,
|
|
} from "../persistence";
|
|
import {
|
|
BcryptPasswordHasher,
|
|
CryptoRefreshTokenGenerator,
|
|
JsonWebTokenAccessTokenIssuer,
|
|
JsonWebTokenAccessTokenVerifier,
|
|
Sha256RefreshTokenHasher,
|
|
} from "../security";
|
|
|
|
export type IdentityInternalDeps = {
|
|
auth: {
|
|
refreshTokenExpiration: string;
|
|
authenticateUserDependencies: {
|
|
accessTokenVerifier: IAccessTokenVerifier;
|
|
accountRepository: IAccountRepository;
|
|
};
|
|
authenticateRequest: ReturnType<typeof identityAuthenticateRequest>;
|
|
useCases: {
|
|
loginWithPassword: () => LoginWithPasswordUseCase;
|
|
refreshSession: () => RefreshSessionUseCase;
|
|
logout: () => LogoutUseCase;
|
|
getCurrentSession: () => GetCurrentSessionUseCase;
|
|
};
|
|
};
|
|
};
|
|
|
|
export const buildIdentityDependencies = (params: ModuleParams): IdentityInternalDeps => {
|
|
const { database, config } = params;
|
|
|
|
const transactionManager = buildTransactionManager(database);
|
|
|
|
const accountRepository = new SequelizeAccountRepository(
|
|
new SequelizeAccountDomainMapper(),
|
|
database
|
|
);
|
|
const refreshTokenRepository = new SequelizeRefreshTokenRepository(
|
|
new SequelizeRefreshTokenDomainMapper(),
|
|
database
|
|
);
|
|
|
|
const passwordHasher = new BcryptPasswordHasher({ rounds: 10 });
|
|
const accessTokenIssuer = new JsonWebTokenAccessTokenIssuer({
|
|
secret: config.auth.jwt.secret,
|
|
expiresIn: config.auth.jwt.accessExpiration,
|
|
});
|
|
const accessTokenVerifier = new JsonWebTokenAccessTokenVerifier({
|
|
secret: config.auth.jwt.secret,
|
|
});
|
|
const refreshTokenGenerator = new CryptoRefreshTokenGenerator({ sizeInBytes: 32 });
|
|
const refreshTokenHasher = new Sha256RefreshTokenHasher();
|
|
|
|
const accountAuthenticator = new AccountAuthenticator({
|
|
accountRepository,
|
|
passwordHasher,
|
|
});
|
|
const sessionIssuer = new SessionIssuer({
|
|
accessTokenIssuer,
|
|
refreshTokenGenerator,
|
|
refreshTokenHasher,
|
|
refreshTokenRepository,
|
|
});
|
|
|
|
return {
|
|
auth: {
|
|
refreshTokenExpiration: config.auth.jwt.refreshExpiration,
|
|
authenticateUserDependencies: {
|
|
accessTokenVerifier,
|
|
accountRepository,
|
|
},
|
|
authenticateRequest: identityAuthenticateRequest({
|
|
accessTokenVerifier,
|
|
accountRepository,
|
|
}),
|
|
useCases: {
|
|
loginWithPassword: () =>
|
|
new LoginWithPasswordUseCaseImpl({
|
|
accountAuthenticator,
|
|
sessionIssuer,
|
|
transactionManager,
|
|
}),
|
|
refreshSession: () =>
|
|
new RefreshSessionUseCaseImpl({
|
|
refreshTokenHasher,
|
|
refreshTokenRepository,
|
|
accountRepository,
|
|
sessionIssuer,
|
|
transactionManager,
|
|
}),
|
|
logout: () =>
|
|
new LogoutUseCaseImpl({
|
|
refreshTokenHasher,
|
|
refreshTokenRepository,
|
|
transactionManager,
|
|
}),
|
|
getCurrentSession: () =>
|
|
new GetCurrentSessionUseCaseImpl({
|
|
accountRepository,
|
|
}),
|
|
},
|
|
},
|
|
};
|
|
};
|