feat: add otp and hashing modules
This commit is contained in:
@@ -33,13 +33,13 @@ export class OTP {
|
||||
|
||||
@Index()
|
||||
@Column({ type: 'timestamptz' })
|
||||
expiredAt: Date;
|
||||
expiresAt: Date;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
used: boolean;
|
||||
|
||||
@BeforeInsert()
|
||||
setExpiry() {
|
||||
this.expiredAt = new Date(Date.now() + 2 * 60 * 1000);
|
||||
this.expiresAt = new Date(Date.now() + 2 * 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@ import { OTP } from './otp.entity';
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([OTP])],
|
||||
providers: [OtpService],
|
||||
exports: [OtpService],
|
||||
})
|
||||
export class OtpModule {}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Repository } from 'typeorm';
|
||||
import {
|
||||
HttpException,
|
||||
HttpStatus,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { LessThan, Repository } from 'typeorm';
|
||||
import { OTP } from '../otp.entity';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Cron } from '@nestjs/schedule';
|
||||
|
||||
@Injectable()
|
||||
export class OtpService {
|
||||
@@ -31,9 +37,52 @@ export class OtpService {
|
||||
});
|
||||
|
||||
if (lastOTP && Date.now() - lastOTP.createdAt.getTime() < 60_000) {
|
||||
// throw new TooMany();
|
||||
throw new HttpException(
|
||||
'Too many requests! Try again after 1 min.',
|
||||
HttpStatus.TOO_MANY_REQUESTS,
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
const code = this.generateOTPCode();
|
||||
// TODO: Hash the code
|
||||
|
||||
const otp = this.otpRepository.create({ phone, code });
|
||||
|
||||
await this.otpRepository.save(otp);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify OTP
|
||||
*/
|
||||
public async verifyOTP(phone: string, code: string): Promise<OTP> {
|
||||
const otp = await this.otpRepository.findOne({
|
||||
where: { phone, used: false },
|
||||
order: { createdAt: 'DESC' },
|
||||
});
|
||||
|
||||
if (!otp) throw new UnauthorizedException('Invalid OTP');
|
||||
|
||||
if (otp.expiresAt < new Date()) {
|
||||
throw new UnauthorizedException('OTP expired');
|
||||
}
|
||||
|
||||
// TODO: Compared hashed otp
|
||||
if (otp.code !== code) {
|
||||
throw new UnauthorizedException('Invalid OTP');
|
||||
}
|
||||
|
||||
otp.used = true;
|
||||
await this.otpRepository.save(otp);
|
||||
|
||||
return otp;
|
||||
}
|
||||
|
||||
@Cron('0 */10 * * * *')
|
||||
public async cleanupExpired(): Promise<void> {
|
||||
await this.otpRepository.delete({
|
||||
expiresAt: LessThan(new Date()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user