Added linkToken and linkContext to OTP

This commit is contained in:
SepehrYahyaee
2026-05-13 09:23:45 +03:30
parent e26c533a52
commit 5b6409fc2e
9 changed files with 344 additions and 28 deletions

View File

@@ -1,20 +1,22 @@
import {
BadRequestException,
HttpException,
HttpStatus,
Injectable,
Logger,
NotAcceptableException,
NotFoundException,
} from "@nestjs/common";
import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { Types } from "mongoose";
import {
UserAuthErrorCode,
throwUserAuthError,
} from "src/auth/auth-services/user-auth-error";
import { UserLinkAccessService } from "src/auth/auth-services/user-link-access.service";
import { LoginDtoRs } from "src/auth/dto/user/login.dto";
import { OtpGeneratorService } from "src/sms-orchestration/otp-generator.service";
import { UserDbService } from "src/users/entities/db-service/user.db.service";
import { SmsOrchestrationService } from "src/sms-orchestration/sms-orchestration.service";
import { HashService } from "src/utils/hash/hash.service";
export interface LinkBinding {
linkToken?: string;
linkContext?: string;
}
// TODO FIX REGISTER TO USER.SERVICE AND AUTH IN THIS MODULE
@Injectable()
export class UserAuthService {
@@ -26,16 +28,27 @@ export class UserAuthService {
private readonly hashService: HashService,
private readonly otpCreator: OtpGeneratorService,
private readonly smsOrchestrationService: SmsOrchestrationService,
private readonly userLinkAccessService: UserLinkAccessService,
) {}
async validateUser(username: string, pass: string): Promise<any> {
async validateUser(
username: string,
pass: string,
binding: LinkBinding = {},
): Promise<any> {
await this.userLinkAccessService.assertMobileAllowed({
mobile: username,
linkToken: binding.linkToken,
linkContext: binding.linkContext,
});
const user = await this.userDbService.findOne({ username });
if (!user) throw new NotFoundException("user not found");
if (!user) throwUserAuthError(UserAuthErrorCode.USER_NOT_FOUND);
const now = new Date().getTime();
if (user.otp == null) throw new NotAcceptableException("please get otp");
if (user.otp == null) throwUserAuthError(UserAuthErrorCode.OTP_REQUIRED);
if (user.otpExpire < now) {
throw new NotAcceptableException("expire otp");
throwUserAuthError(UserAuthErrorCode.OTP_EXPIRED);
}
if (await this.hashService.compare(pass, user.otp)) {
return user;
@@ -65,7 +78,16 @@ export class UserAuthService {
};
}
async sendOtpRequest(mobile: string): Promise<LoginDtoRs> {
async sendOtpRequest(
mobile: string,
binding: LinkBinding = {},
): Promise<LoginDtoRs> {
await this.userLinkAccessService.assertMobileAllowed({
mobile,
linkToken: binding.linkToken,
linkContext: binding.linkContext,
});
const userExist = await this.userDbService.findOne({
mobile,
});
@@ -101,7 +123,9 @@ export class UserAuthService {
return new LoginDtoRs(newUser);
}
if (userExist) {
if (userExist.otpExpire > new Date(new Date().getTime()).getTime()) throw new BadRequestException("Wait for expiry time to finish");
if (userExist.otpExpire > new Date(new Date().getTime()).getTime()) {
throwUserAuthError(UserAuthErrorCode.OTP_REQUEST_TOO_SOON);
}
await this.smsSender(otp, mobile);
const updateTokens = await this.userDbService.findOneAndUpdate(
{