fix idp on started
This commit is contained in:
@@ -3,12 +3,16 @@ import * as bcrypt from 'bcryptjs';
|
||||
import { randomInt } from 'node:crypto';
|
||||
import { PrismaService } from '../infra/prisma.service';
|
||||
import { SettingsService } from './settings.service';
|
||||
import { MessagingService } from '../infra/messaging.service';
|
||||
import { RedisService } from '../infra/redis.service';
|
||||
|
||||
@Injectable()
|
||||
export class OtpService {
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly settings: SettingsService
|
||||
private readonly settings: SettingsService,
|
||||
private readonly messaging: MessagingService,
|
||||
private readonly redis: RedisService
|
||||
) {}
|
||||
|
||||
async send(command: { target: string; channel: string; purpose: string; userId?: string }) {
|
||||
@@ -25,7 +29,14 @@ export class OtpService {
|
||||
expiresAt
|
||||
}
|
||||
});
|
||||
console.log(`OTP ${command.channel} для ${command.target}: ${code}`);
|
||||
const channel = command.channel === 'sms' ? 'sms' : 'email';
|
||||
await this.messaging.sendVerificationCode({
|
||||
channel,
|
||||
target: command.target,
|
||||
code,
|
||||
expiryMinutes
|
||||
});
|
||||
await this.redis.client.del(this.attemptKey(command.target, command.purpose));
|
||||
return { sent: true, expiresAt: expiresAt.toISOString() };
|
||||
}
|
||||
|
||||
@@ -41,9 +52,25 @@ export class OtpService {
|
||||
});
|
||||
|
||||
if (!authCode) throw new BadRequestException('Код подтверждения не найден или истек');
|
||||
|
||||
const attemptKey = this.attemptKey(command.target, command.purpose);
|
||||
const maxAttempts = await this.settings.getNumber('OTP_MAX_ATTEMPTS', 5);
|
||||
const attempts = Number((await this.redis.client.get(attemptKey)) ?? 0);
|
||||
if (attempts >= maxAttempts) {
|
||||
throw new UnauthorizedException('Превышено число попыток ввода кода');
|
||||
}
|
||||
|
||||
const matches = await bcrypt.compare(command.code, authCode.codeHash);
|
||||
if (!matches) throw new UnauthorizedException('Неверный код подтверждения');
|
||||
if (!matches) {
|
||||
await this.redis.client.set(attemptKey, String(attempts + 1), 'EX', 15 * 60);
|
||||
throw new UnauthorizedException('Неверный код подтверждения');
|
||||
}
|
||||
await this.redis.client.del(attemptKey);
|
||||
await this.prisma.authCode.update({ where: { id: authCode.id }, data: { usedAt: new Date() } });
|
||||
return { verified: true };
|
||||
}
|
||||
|
||||
private attemptKey(target: string, purpose: string) {
|
||||
return `otp:attempts:${purpose}:${target.toLowerCase()}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user