Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
✨ Support logging in backup code
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Oct 30, 2020
1 parent 63bac41 commit 9857fbc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
45 changes: 44 additions & 1 deletion src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ export class AuthService {
const user = await this.prisma.users.findOne({
where: { id },
select: {
name: true,
prefersEmail: true,
twoFactorSecret: true,
twoFactorEnabled: true,
checkLocationOnLogin: true,
Expand All @@ -381,7 +383,48 @@ export class AuthService {
if (!user) throw new NotFoundException();
if (!user.twoFactorEnabled)
throw new BadRequestException('Two-factor authentication is not enabled');
if (!this.authenticator.check(code, user.twoFactorSecret))
if (this.authenticator.check(code, user.twoFactorSecret))
return this.loginResponse(ipAddress, userAgent, id);
const backupCodes = await this.prisma.backupCodes.findMany({
where: { user: { id } },
});
let usedBackupCode = false;
for await (const backupCode of backupCodes) {
if (await compare(code, backupCode.code)) {
if (!usedBackupCode) {
if (backupCode.isUsed)
throw new UnauthorizedException(
'This backup code has previously been used',
);
usedBackupCode = true;
await this.prisma.backupCodes.update({
where: { id: backupCode.id },
data: { isUsed: true },
});
const location = await this.geolocationService.getLocation(ipAddress);
const locationName =
[
location?.city?.names?.en,
location?.subdivisions[0]?.names?.en,
location?.country?.names?.en,
]
.filter(i => i)
.join(', ') || 'Unknown location';
this.email.send({
to: `"${user.name}" <${user.prefersEmail.emailSafe}>`,
template: 'auth/used-backup-code',
data: {
name: user.name,
locationName,
link: `${this.configService.get<string>(
'frontendUrl',
)}/users/${id}/sessions`,
},
});
}
}
}
if (!usedBackupCode)
throw new UnauthorizedException(
'Two-factor authentication code is invalid',
);
Expand Down
9 changes: 9 additions & 0 deletions src/templates/auth/used-backup-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Login with a backup code

Hi {{name}},

Someone (hopefully you) logged in to your account from **{{ locationName }}**, and they used a backup code when asked for a two-factor authentication code.

<a href="{{ link }}" class="btn btn-primary">Check recent activity</a>

If you didn't login to your account, you should immediately change your password and regenerate your backup codes. You can do that by logging in to your account.

0 comments on commit 9857fbc

Please sign in to comment.