src/auth/auth.service.ts
Properties |
|
Methods |
|
constructor()
|
|
Defined in src/auth/auth.service.ts:83
|
| Async associateAuthToken | |||||
associateAuthToken(undefined: IAssociateAuthToken)
|
|||||
|
Defined in src/auth/auth.service.ts:742
|
|||||
|
Parameters :
Returns :
unknown
|
| Async authenticateUserAndChangeTempPswd | ||||||
authenticateUserAndChangeTempPswd(authChangePasswordUserDto: AuthChangePasswordUserDto)
|
||||||
|
Defined in src/auth/auth.service.ts:343
|
||||||
|
Admin receive email from cognito with temp password to join. The new admin need to login with a new password to change the temp password.
Parameters :
Returns :
unknown
|
| Async authenticateUserWithMfa | ||||||
authenticateUserWithMfa(authLoginUserDto: AuthLoginUserDto)
|
||||||
|
Defined in src/auth/auth.service.ts:259
|
||||||
|
Parameters :
Returns :
Promise<ICognitoUserSession | >
|
| Async changeUserPassword | ||||||
changeUserPassword(authChangePasswordUserDto: AuthChangePasswordUserDto)
|
||||||
|
Defined in src/auth/auth.service.ts:507
|
||||||
|
Parameters :
Returns :
any
|
| Async confirmUserPassword | ||||||
confirmUserPassword(authConfirmPasswordUserDto: AuthConfirmPasswordUserDto)
|
||||||
|
Defined in src/auth/auth.service.ts:606
|
||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async createPlatformAdmin | ||||||
createPlatformAdmin(authChangePasswordUserDto: Omit
|
||||||
|
Defined in src/auth/auth.service.ts:413
|
||||||
|
Parameters :
Returns :
unknown
|
| Async deleteCognitoUser | ||||||
deleteCognitoUser(email: string)
|
||||||
|
Defined in src/auth/auth.service.ts:775
|
||||||
|
Parameters :
Returns :
Promise<void>
|
| Async disableEnableUser | |||||
disableEnableUser(undefined: AllowDisallowDto)
|
|||||
|
Defined in src/auth/auth.service.ts:755
|
|||||
|
Parameters :
Returns :
unknown
|
| Async enableMFA | ||||||
enableMFA(email: string)
|
||||||
|
Defined in src/auth/auth.service.ts:702
|
||||||
|
Parameters :
Returns :
unknown
|
| Async forgotUserPassword | ||||||
forgotUserPassword(authForgotPasswordUserDto: AuthForgotPasswordUserDto)
|
||||||
|
Defined in src/auth/auth.service.ts:582
|
||||||
|
Parameters :
Returns :
Promise<string>
|
| Async getCognitoUser | ||||||
getCognitoUser(email: string)
|
||||||
|
Defined in src/auth/auth.service.ts:630
|
||||||
|
Parameters :
Returns :
Promise<CognitoUserSession>
|
| Async registerCognitoUser | ||||||
registerCognitoUser(authRegisterUserDto: AuthRegisterUserDto)
|
||||||
|
Defined in src/auth/auth.service.ts:232
|
||||||
|
Parameters :
Returns :
Promise<CognitoUser>
|
| Async registerUser | |||||||||
registerUser(authRegisterUserDto: AuthRegisterUserDto, onBoardedUser: UserJwtPayload)
|
|||||||||
|
Defined in src/auth/auth.service.ts:95
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async setUpPlatformAdminWeb3Roles | ||||||
setUpPlatformAdminWeb3Roles(address: string)
|
||||||
|
Defined in src/auth/auth.service.ts:469
|
||||||
|
Parameters :
Returns :
Promise<ContractTransactionResponse[]>
|
| Async signIn |
signIn(email: string, password: string)
|
|
Defined in src/auth/auth.service.ts:647
|
|
Returns :
unknown
|
| Async totpChallenge | |||||
totpChallenge(undefined: ITotpChallenge)
|
|||||
|
Defined in src/auth/auth.service.ts:674
|
|||||
|
Parameters :
Returns :
unknown
|
| Async validateAndGetSubscribedFunds | |||||||||
validateAndGetSubscribedFunds(authRegisterUserDto: AuthRegisterUserDto, onBoardedUser: UserJwtPayload)
|
|||||||||
|
Defined in src/auth/auth.service.ts:207
|
|||||||||
|
Parameters :
Returns :
Promise<Fund[]>
|
| Async validateMFA |
validateMFA(UserCode: string, AccessTokenOrSession: string)
|
|
Defined in src/auth/auth.service.ts:724
|
|
Returns :
unknown
|
| Private Readonly adminService |
Type : AdminService
|
Decorators :
@Inject(AdminService)
|
|
Defined in src/auth/auth.service.ts:59
|
| Private Readonly authWeb3 |
Type : AuthWeb3Service
|
Decorators :
@Inject(AuthWeb3Service)
|
|
Defined in src/auth/auth.service.ts:74
|
| Private cognitoIdentityServiceProvider |
Type : CognitoIdentityServiceProvider
|
|
Defined in src/auth/auth.service.ts:83
|
| Private Readonly emailService |
Type : EmailService
|
Decorators :
@Inject(EmailService)
|
|
Defined in src/auth/auth.service.ts:68
|
| Private Readonly fundService |
Type : FundService
|
Decorators :
@Inject(FundService)
|
|
Defined in src/auth/auth.service.ts:62
|
| Private Readonly internalInternalCustodialService |
Type : InternalCustodialService
|
Decorators :
@Inject(InternalCustodialService)
|
|
Defined in src/auth/auth.service.ts:71
|
| Private Readonly revertOperationService |
Type : RevertOperationService
|
Decorators :
@Inject(RevertOperationService)
|
|
Defined in src/auth/auth.service.ts:80
|
| Private Readonly userCmsService |
Type : UserCmsService
|
Decorators :
@Inject(UserCmsService)
|
|
Defined in src/auth/auth.service.ts:77
|
| Private userPool |
Type : CognitoUserPool
|
|
Defined in src/auth/auth.service.ts:82
|
| Private Readonly userService |
Type : UserService
|
Decorators :
@Inject(UserService)
|
|
Defined in src/auth/auth.service.ts:56
|
| Private Readonly walletService |
Type : WalletService
|
Decorators :
@Inject(WalletService)
|
|
Defined in src/auth/auth.service.ts:65
|
import {
BadRequestException,
Inject,
Injectable,
ServiceUnavailableException,
UnauthorizedException,
} from "@nestjs/common";
import {
AuthenticationDetails,
CognitoUser,
CognitoUserAttribute,
CognitoUserPool,
} from "amazon-cognito-identity-js";
import QR from "qrcode";
import type {
CognitoUserSession,
ICognitoUserData,
} from "amazon-cognito-identity-js";
import type { IAssociateAuthToken } from "./interfaces/auth.interface";
import type { AuthChangePasswordUserDto } from "./dtos/auth-change-password-user.dto";
import type { AuthLoginUserDto } from "./dtos/auth-login-user.dto";
import type { AuthRegisterUserDto } from "./dtos/auth-register-user.dto";
import type { AuthConfirmPasswordUserDto } from "./dtos/auth-confirm-password-user.dto";
import type { AuthForgotPasswordUserDto } from "./dtos/auth-forgot-password-user.dto";
import {
ContractName,
EndUserRoles,
TransactionNames,
UserJwtPayload,
} from "src/common/interfaces";
import { UserService } from "src/user/user.service";
import { FundService } from "src/security/fund.service";
import { WalletService } from "src/wallet/wallet.service";
import { AdminService } from "src/admin/admin.service";
import { ICognitoUserSession, ITotpChallenge } from "./interfaces";
import { EmailService } from "src/common/provider/mail/email.service";
import { InternalCustodialService } from "src/shared/custodial/internalCustodial.service";
import { AuthWeb3Service } from "./auth.web3.service";
import { UserCmsService } from "src/user/user.cms.service";
import { Fund } from "src/security/schemas/fund.schema";
import { RevertOperationService } from "src/revertOperation/revertOperation.service";
import { ContractTransactionResponse, parseEther } from "ethers";
import { transactionSubmitter } from "src/common/provider";
import { PaymentToken, Roles } from "src/common/constants";
import { CognitoIdentityServiceProvider } from "aws-sdk";
import { RoleRegistry } from "src/shared/artifacts/RoleRegistry";
import { AllowDisallowDto } from "./dtos/auth-status-user.dto";
@Injectable()
export class AuthService {
@Inject(UserService)
private readonly userService: UserService;
@Inject(AdminService)
private readonly adminService: AdminService;
@Inject(FundService)
private readonly fundService: FundService;
@Inject(WalletService)
private readonly walletService: WalletService;
@Inject(EmailService)
private readonly emailService: EmailService;
@Inject(InternalCustodialService)
private readonly internalInternalCustodialService: InternalCustodialService;
@Inject(AuthWeb3Service)
private readonly authWeb3: AuthWeb3Service;
@Inject(UserCmsService)
private readonly userCmsService: UserCmsService;
@Inject(RevertOperationService)
private readonly revertOperationService: RevertOperationService;
private userPool: CognitoUserPool;
private cognitoIdentityServiceProvider: CognitoIdentityServiceProvider;
constructor() {
this.userPool = new CognitoUserPool({
UserPoolId: process.env.AWS_COGNITO_USER_POOL_ID,
ClientId: process.env.AWS_COGNITO_CLIENT_ID,
});
this.cognitoIdentityServiceProvider = new CognitoIdentityServiceProvider({
region: process.env.AWS_COGNITO_REGION,
endpoint: process.env.AWS_COGNITO_AUTHORITY,
});
}
async registerUser(
authRegisterUserDto: AuthRegisterUserDto,
onBoardedUser: UserJwtPayload,
) {
const operationId = RevertOperationService.getOperationId();
const subscribedFunds = await this.validateAndGetSubscribedFunds(
authRegisterUserDto,
onBoardedUser,
);
try {
const [defaultWallet, , dealer] = await Promise.all([
this.walletService.create({
walletLabel: "default wallet",
}),
this.registerCognitoUser(authRegisterUserDto),
onBoardedUser.role === EndUserRoles.dealer &&
this.userService.findUserByProperty({ email: onBoardedUser.email }),
]);
this.revertOperationService.pushRevertOperation(operationId, [
{
revertFunction: this.deleteCognitoUser,
args: [authRegisterUserDto.email],
rFunctionId: RevertOperationService.getRevertFunctionId(),
},
]);
const newUser = await this.userService.create({
...authRegisterUserDto,
onboardByEmail: onBoardedUser.email,
wallets: [defaultWallet],
subscribedFunds,
bankDetails: {
bankName: authRegisterUserDto.bankName,
bankAddress: authRegisterUserDto.bankAddress,
bankChaps: authRegisterUserDto.bankChaps,
bankBic: authRegisterUserDto.bankBic,
accountBic: authRegisterUserDto.accountBic,
accountName: authRegisterUserDto.accountName,
accountNo: authRegisterUserDto.accountNo,
ibanNo: authRegisterUserDto.ibanNo,
ultimateName: authRegisterUserDto.ultimateName,
ultimateAccountNo: authRegisterUserDto.ultimateAccountNo,
currency: authRegisterUserDto.currency,
abaCode: authRegisterUserDto.abaCode,
},
});
this.revertOperationService.pushRevertOperation(operationId, [
{
revertFunction: this.userService.deleteByEmail,
args: [authRegisterUserDto.email],
rFunctionId: RevertOperationService.getRevertFunctionId(),
},
]);
let txs: ContractTransactionResponse[] = [];
if (
authRegisterUserDto.endUserRole === EndUserRoles.dealer ||
authRegisterUserDto.endUserRole === EndUserRoles.investor
) {
txs = await this.authWeb3.onboardUser({
onBoardedByRole: onBoardedUser.role as "admin" | EndUserRoles.dealer,
userJwtPayload: onBoardedUser,
newUserRole: authRegisterUserDto.endUserRole,
newUser,
internalCustodialService: this.internalInternalCustodialService,
onChainFields: authRegisterUserDto.onChainFields,
dealerAddressSubmitter: dealer ? dealer.wallets[0].address : null,
dealerId: dealer
? dealer._id.toString()
: authRegisterUserDto.dealerId,
});
if (authRegisterUserDto.endUserRole === EndUserRoles.dealer) {
await this.userCmsService.addUserInCms(newUser.email);
this.revertOperationService.pushRevertOperation(operationId, [
{
revertFunction: this.userCmsService.removeUserFromCms,
args: [newUser.email],
rFunctionId: RevertOperationService.getRevertFunctionId(),
},
]);
}
}
if (authRegisterUserDto.endUserRole === EndUserRoles.fundAdmin) {
const tx = await transactionSubmitter({
signerKey: process.env.RELAYER_KEY,
contractAddress: RoleRegistry.address,
transactionName: TransactionNames.grantRole,
contractName: ContractName.RoleRegistry,
args: [Roles.FundAdmin, newUser.wallets[0].address],
});
await tx.wait();
txs.push(tx);
txs.push(
await transactionSubmitter({
signerKey: process.env.RELAYER_KEY,
contractAddress: PaymentToken,
contractName: ContractName.erc20,
transactionName: TransactionNames.mint,
args: [newUser.wallets[0].address, parseEther("1000000")],
}),
);
}
return { newUser, txs };
} catch (error) {
console.error(error);
await this.revertOperationService.runRevertOperation(operationId);
throw new ServiceUnavailableException(error);
}
}
async validateAndGetSubscribedFunds(
authRegisterUserDto: AuthRegisterUserDto,
onBoardedUser: UserJwtPayload,
): Promise<Fund[]> {
if (
onBoardedUser.role === EndUserRoles.dealer &&
authRegisterUserDto.endUserRole !== EndUserRoles.investor
) {
throw new UnauthorizedException(
`Only admin is allowed to create ${authRegisterUserDto.endUserRole}`,
);
}
const subscribedFunds = await this.fundService.findByIds({
ids: authRegisterUserDto.subscribedFunds,
});
if (
subscribedFunds.length === 0 &&
authRegisterUserDto.subscribedFunds.length > 0
) {
throw new BadRequestException("Wrong fund Id");
}
return subscribedFunds;
}
async registerCognitoUser(
authRegisterUserDto: AuthRegisterUserDto,
): Promise<CognitoUser> {
const { endUserRole, email, password } = authRegisterUserDto;
return new Promise((resolve, reject) => {
this.userPool.signUp(
email,
password,
[
new CognitoUserAttribute({
Name: "custom:role",
Value: endUserRole,
}),
],
null,
(err, result) => {
if (!result) {
reject(err);
} else {
resolve(result.user);
}
},
);
});
}
async authenticateUserWithMfa(authLoginUserDto: AuthLoginUserDto): Promise<
| ICognitoUserSession // If didn't setup the mfa
| (CognitoIdentityServiceProvider.AuthenticationResultType & {
payload: {
email: string;
role: string;
};
}) // if setup the mfa
> {
const { email, password, session, mfaCode } = authLoginUserDto;
const userData = {
Username: email,
Pool: this.userPool,
};
const authenticationDetails = new AuthenticationDetails({
Username: email,
Password: password,
});
const cognitoIdentityServiceProvider = this.cognitoIdentityServiceProvider;
const userCognito = new CognitoUser(userData);
return new Promise((resolve, reject) => {
userCognito.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
resolve({
accessToken: result.getIdToken().getJwtToken(),
refreshToken: result.getRefreshToken().getToken(),
payload: {
email: result.getIdToken().payload.email,
role: result.getIdToken().payload["custom:role"],
},
});
},
onFailure: (err) => {
reject(err);
},
mfaSetup: () => {
throw new UnauthorizedException("Please setup your authenticator");
},
totpRequired: async (challengeName) => {
if (challengeName !== "SOFTWARE_TOKEN_MFA") {
reject("Soft token is the only supported Challenge");
}
try {
const [authInfo, userInfo] = await Promise.all([
this.totpChallenge({
email,
mfaCode,
session,
cognitoIdentityServiceProvider,
}),
cognitoIdentityServiceProvider
.adminGetUser({
Username: email,
UserPoolId: this.userPool.getUserPoolId(),
})
.promise(),
]);
const payload: Record<string, string> = {};
userInfo.UserAttributes.forEach((attribute) => {
if (attribute.Name === "custom:role")
payload.role = attribute.Value;
else payload[attribute.Name] = attribute.Value;
});
resolve({
...authInfo.AuthenticationResult,
payload: { email: payload.email, role: payload.role },
});
} catch (totpChallengeError) {
reject(totpChallengeError);
}
},
});
});
}
/**
Admin receive email from cognito with temp password to join.
The new admin need to login with a new password to change the temp password.
*/
async authenticateUserAndChangeTempPswd(
authChangePasswordUserDto: AuthChangePasswordUserDto,
) {
const { email, currentPassword, newPassword, mfaCode, session } =
authChangePasswordUserDto;
const userData = {
Username: email,
Pool: this.userPool,
};
const authenticationDetails = new AuthenticationDetails({
Username: email,
Password: currentPassword,
});
const userCognito = new CognitoUser(userData);
const cognitoIdentityServiceProvider = this.cognitoIdentityServiceProvider;
return new Promise((resolve, reject) => {
userCognito.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
resolve({
accessToken: result.getIdToken().getJwtToken(),
refreshToken: result.getRefreshToken().getToken(),
payload: {
email: result.getIdToken().payload.email,
role: result.getIdToken().payload["custom:role"],
},
});
},
onFailure: (err) => {
reject(err);
},
newPasswordRequired: function () {
userCognito.completeNewPasswordChallenge(newPassword, null, this);
},
mfaSetup: () => {
resolve(true);
},
totpRequired: async (challengeName) => {
if (challengeName !== "SOFTWARE_TOKEN_MFA") {
reject("Soft token is the only supported Challenge");
}
try {
const authInfo = await this.totpChallenge({
email,
mfaCode,
session,
cognitoIdentityServiceProvider,
});
await cognitoIdentityServiceProvider
.changePassword({
PreviousPassword: currentPassword,
ProposedPassword: newPassword,
AccessToken: authInfo.AuthenticationResult.AccessToken,
})
.promise();
resolve(authInfo.AuthenticationResult);
} catch (totpChallengeError) {
reject(totpChallengeError);
}
},
});
});
}
async createPlatformAdmin(
authChangePasswordUserDto: Omit<
AuthChangePasswordUserDto,
"mfaCode" | "session"
>,
) {
const { email, currentPassword, newPassword } = authChangePasswordUserDto;
const userData = {
Username: email,
Pool: this.userPool,
};
const authenticationDetails = new AuthenticationDetails({
Username: email,
Password: currentPassword,
});
const userCognito = new CognitoUser(userData);
const cognitoIdentityServiceProvider = this.cognitoIdentityServiceProvider;
const adminService = this.adminService;
const setUpPlatformAdminWeb3Roles = this.setUpPlatformAdminWeb3Roles;
const user = await cognitoIdentityServiceProvider
.adminGetUser({
Username: email,
UserPoolId: this.userPool.getUserPoolId(),
})
.promise();
const roleAttribute = user.UserAttributes.find(
(attribute) => attribute.Name === "custom:role",
);
if (!roleAttribute || roleAttribute.Value !== "admin") {
throw new UnauthorizedException("Only admins are allowed for this call");
}
return new Promise((resolve, reject) => {
userCognito.authenticateUser(authenticationDetails, {
newPasswordRequired: async function () {
const admin = await adminService.create(email);
userCognito.completeNewPasswordChallenge(newPassword, null, this);
resolve(setUpPlatformAdminWeb3Roles(admin.wallets[0].address));
},
mfaSetup: () => {
reject("This call used on `newPasswordRequired` challenge only.");
},
totpRequired: () => {
reject("This call used on `newPasswordRequired` challenge only.");
},
onFailure: (err) => {
console.log("hnaa");
reject(err);
},
onSuccess: () => {
reject("This call used on `newPasswordRequired` challenge only");
},
});
});
}
async setUpPlatformAdminWeb3Roles(
address: string,
): Promise<ContractTransactionResponse[]> {
const txs: ContractTransactionResponse[] = [];
txs.push(
await transactionSubmitter({
signerKey: process.env.RELAYER_KEY,
contractAddress: RoleRegistry.address,
transactionName: TransactionNames.grantRole,
contractName: ContractName.RoleRegistry,
args: [Roles.Admin, address],
}),
);
await txs[0].wait();
txs.push(
await transactionSubmitter({
signerKey: process.env.RELAYER_KEY,
contractAddress: RoleRegistry.address,
transactionName: TransactionNames.grantRole,
contractName: ContractName.RoleRegistry,
args: [Roles.FundAdmin, address],
}),
);
await txs[1].wait();
txs.push(
await transactionSubmitter({
signerKey: process.env.RELAYER_KEY,
contractAddress: PaymentToken,
contractName: ContractName.erc20,
transactionName: TransactionNames.mint,
args: [address, parseEther("1000000000")],
}),
);
return txs;
}
async changeUserPassword(
authChangePasswordUserDto: AuthChangePasswordUserDto,
) {
const { email, currentPassword, newPassword, mfaCode, session } =
authChangePasswordUserDto;
const userData = {
Username: email,
Pool: this.userPool,
};
const authenticationDetails = new AuthenticationDetails({
Username: email,
Password: currentPassword,
});
const userCognito = new CognitoUser(userData);
const cognitoIdentityServiceProvider = this.cognitoIdentityServiceProvider;
try {
await new Promise((resolve, reject) => {
userCognito.authenticateUser(authenticationDetails, {
onSuccess: function (session) {
try {
userCognito.changePassword(
currentPassword,
newPassword,
(err) => {
if (err) {
reject(err);
}
},
);
resolve(session);
} catch (passwordChangeError) {
reject(passwordChangeError);
}
},
onFailure: function (authenticationError) {
reject(authenticationError);
},
totpRequired: async (challengeName) => {
if (challengeName !== "SOFTWARE_TOKEN_MFA") {
reject("Soft token is the only supported Challenge");
}
try {
const authInfo = await this.totpChallenge({
email,
mfaCode,
session,
cognitoIdentityServiceProvider,
});
await cognitoIdentityServiceProvider
.changePassword({
PreviousPassword: currentPassword,
ProposedPassword: newPassword,
AccessToken: authInfo.AuthenticationResult.AccessToken,
})
.promise();
resolve(authInfo.AuthenticationResult);
} catch (totpChallengeError) {
reject(totpChallengeError);
}
},
});
});
} catch (error) {
console.error("An error occurred:", error);
throw new ServiceUnavailableException(error);
}
}
async forgotUserPassword(
authForgotPasswordUserDto: AuthForgotPasswordUserDto,
): Promise<string> {
const { email } = authForgotPasswordUserDto;
const userData = {
Username: email,
Pool: this.userPool,
};
const userCognito = new CognitoUser(userData);
return new Promise((resolve, reject) => {
userCognito.forgotPassword({
onSuccess: (result) => {
resolve(result);
},
onFailure: (err) => {
reject(err);
},
});
});
}
async confirmUserPassword(
authConfirmPasswordUserDto: AuthConfirmPasswordUserDto,
): Promise<{ status: string }> {
const { email, confirmationCode, newPassword } = authConfirmPasswordUserDto;
const userData = {
Username: email,
Pool: this.userPool,
};
const userCognito = new CognitoUser(userData);
return new Promise((resolve, reject) => {
userCognito.confirmPassword(confirmationCode, newPassword, {
onSuccess: () => {
resolve({ status: "success" });
},
onFailure: (err) => {
reject(err);
},
});
});
}
async getCognitoUser(email: string): Promise<CognitoUserSession> {
const userData: ICognitoUserData = {
Username: email,
Pool: this.userPool,
};
const userCognito = new CognitoUser(userData);
return new Promise((resolve, reject) => {
userCognito.getSession((error, session) => {
if (error) {
reject(error);
}
resolve(session);
});
});
}
async signIn(email: string, password: string) {
const signInParams: AWS.CognitoIdentityServiceProvider.InitiateAuthRequest =
{
AuthFlow: "USER_PASSWORD_AUTH",
ClientId: process.env.AWS_COGNITO_CLIENT_ID, // Replace with your Cognito User Pool App Client ID
AuthParameters: {
USERNAME: email,
PASSWORD: password,
},
};
const authResponse = await this.cognitoIdentityServiceProvider
.initiateAuth(signInParams)
.promise();
if (authResponse.ChallengeName === "MFA_SETUP") {
const authenticatorData = await this.associateAuthToken({
userSession: authResponse.Session,
email,
});
return {
...authenticatorData,
ChallengeName: authResponse.ChallengeName,
};
}
return authResponse;
}
async totpChallenge({
email,
mfaCode,
session,
cognitoIdentityServiceProvider,
}: ITotpChallenge) {
try {
const params: CognitoIdentityServiceProvider.Types.AdminRespondToAuthChallengeRequest =
{
ChallengeName: "SOFTWARE_TOKEN_MFA",
ClientId: process.env.AWS_COGNITO_CLIENT_ID,
ChallengeResponses: {
USERNAME: email,
SOFTWARE_TOKEN_MFA_CODE: mfaCode,
},
Session: session,
UserPoolId: process.env.AWS_COGNITO_USER_POOL_ID,
};
return await cognitoIdentityServiceProvider
.adminRespondToAuthChallenge(params)
.promise();
} catch (error) {
console.error("Verification failed:", error);
throw new ServiceUnavailableException(error);
}
}
async enableMFA(email: string) {
try {
const enableMFAParams: AWS.CognitoIdentityServiceProvider.AdminSetUserMFAPreferenceRequest =
{
SoftwareTokenMfaSettings: {
Enabled: true,
PreferredMfa: true,
},
UserPoolId: this.userPool.getUserPoolId(),
Username: email,
};
await this.cognitoIdentityServiceProvider
.adminSetUserMFAPreference(enableMFAParams)
.promise();
return { message: "MFA enabled successfully!" };
} catch (error) {
console.error("Verification failed:", error);
throw new ServiceUnavailableException(error);
}
}
async validateMFA(UserCode: string, AccessTokenOrSession: string) {
try {
const params: AWS.CognitoIdentityServiceProvider.VerifySoftwareTokenRequest =
{
Session: AccessTokenOrSession,
UserCode,
};
await this.cognitoIdentityServiceProvider
.verifySoftwareToken(params)
.promise();
return { message: "Verification successful!" };
} catch (error) {
console.error("Verification failed:", error);
throw new UnauthorizedException(error);
}
}
async associateAuthToken({ userSession, email }: IAssociateAuthToken) {
const { SecretCode, Session } = await this.cognitoIdentityServiceProvider
.associateSoftwareToken({ Session: userSession })
.promise();
const name = `Libre Capital: ${email}`;
const uri = `otpauth://totp/${decodeURI(name)}?secret=${SecretCode}`;
const qrCode = await QR.toDataURL(uri);
return {
qrCode,
secretCode: SecretCode,
session: Session,
};
}
async disableEnableUser({ email, isDisabled }: AllowDisallowDto) {
const params = {
UserPoolId: this.userPool.getUserPoolId(),
Username: email, // Username of the user you want to disable
};
if (isDisabled)
await this.cognitoIdentityServiceProvider
.adminDisableUser(params)
.promise();
else
await this.cognitoIdentityServiceProvider
.adminEnableUser(params)
.promise();
return {
message: `User with email ${email} is ${
isDisabled ? "disabled" : "enabled"
} successfully.`,
};
}
async deleteCognitoUser(email: string): Promise<void> {
const userData: ICognitoUserData = {
Username: email,
Pool: this.userPool,
};
const userCognito = new CognitoUser(userData);
return new Promise((resolve, reject) => {
userCognito.deleteUser((error) => {
if (error) {
reject(error);
}
resolve();
});
});
}
}