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

Commit

Permalink
♻️ Approve new subnets in auth
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Oct 30, 2020
1 parent d989922 commit 24afea0
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
21 changes: 20 additions & 1 deletion src/modules/approved-subnets/approved-subnets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { Expose } from 'src/modules/prisma/prisma.interface';
import { PrismaService } from '../prisma/prisma.service';
import anonymize from 'ip-anonymize';
import { hash } from 'bcrypt';
import { compare, hash } from 'bcrypt';
import { ConfigService } from '@nestjs/config';
import { GeolocationService } from '../geolocation/geolocation.service';

Expand Down Expand Up @@ -98,4 +98,23 @@ export class ApprovedSubnetsService {
});
return this.prisma.expose<approvedSubnets>(approved);
}

/**
* Upsert a new subnet
* If this subnet already exists, skip; otherwise add it
*/
async upsertNewSubnet(
userId: number,
ipAddress: string,
): Promise<Expose<approvedSubnets>> {
const subnet = anonymize(ipAddress);
const previousSubnets = await this.prisma.approvedSubnets.findMany({
where: { user: { id: userId } },
});
for await (const item of previousSubnets) {
if (await compare(subnet, item.subnet))
return this.prisma.expose<approvedSubnets>(item);
}
return this.approveNewSubnet(userId, ipAddress);
}
}
7 changes: 5 additions & 2 deletions src/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ export class AuthController {
duration: 60,
errorMessage: 'Wait for 60 seconds before trying to create an account',
})
async register(@Body() data: RegisterDto): Promise<Expose<users>> {
return this.authService.register(data);
async register(
@Ip() ip: string,
@Body() data: RegisterDto,
): Promise<Expose<users>> {
return this.authService.register(ip, data);
}

@Post('refresh')
Expand Down
2 changes: 2 additions & 0 deletions src/modules/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { ApprovedSubnetsModule } from '../approved-subnets/approved-subnets.module';
import { EmailModule } from '../email/email.module';
import { GeolocationModule } from '../geolocation/geolocation.module';
import { PrismaModule } from '../prisma/prisma.module';
Expand All @@ -20,6 +21,7 @@ import { JwtStrategy } from './jwt.strategy';
ConfigModule,
PwnedModule,
GeolocationModule,
ApprovedSubnetsModule,
JwtModule.register({
secret: process.env.JWT_SECRET ?? 'staart',
}),
Expand Down
40 changes: 32 additions & 8 deletions src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { RegisterDto } from './auth.dto';
import { AccessTokenClaims } from './auth.interface';
import anonymize from 'ip-anonymize';
import { GeolocationService } from '../geolocation/geolocation.service';
import { ApprovedSubnetsService } from '../approved-subnets/approved-subnets.service';

@Injectable()
export class AuthService {
Expand All @@ -44,6 +45,7 @@ export class AuthService {
private pwnedService: PwnedService,
private tokensService: TokensService,
private geolocationService: GeolocationService,
private approvedSubnetsService: ApprovedSubnetsService,
) {
this.authenticator = authenticator.create({
window: [
Expand All @@ -53,11 +55,17 @@ export class AuthService {
});
}

async validateUser(email: string, password?: string): Promise<number> {
async validateUser(email: string, password?: string) {
const emailSafe = safeEmail(email);
const user = await this.prisma.users.findFirst({
where: { emails: { some: { emailSafe } } },
select: { id: true, password: true, emails: true },
select: {
id: true,
password: true,
emails: true,
twoFactorEnabled: true,
checkLocationOnLogin: true,
},
});
if (!user) throw new HttpException('User not found', HttpStatus.NOT_FOUND);
if (!user.emails.find(i => i.emailSafe === emailSafe)?.isVerified)
Expand All @@ -67,7 +75,12 @@ export class AuthService {
'Logging in without passwords is not supported',
HttpStatus.NOT_IMPLEMENTED,
);
if (await compare(password, user.password)) return user.id;
if (await compare(password, user.password))
return {
id: user.id,
twoFactorEnabled: user.twoFactorEnabled,
checkLocationOnLogin: user.checkLocationOnLogin,
};
return null;
}

Expand All @@ -78,13 +91,22 @@ export class AuthService {
password?: string,
code?: string,
) {
const id = await this.validateUser(email, password);
if (!id) throw new UnauthorizedException();
if (code) return this.loginUserWithTotpCode(ipAddress, userAgent, id, code);
return this.loginResponse(ipAddress, userAgent, id);
const user = await this.validateUser(email, password);
if (!user) throw new UnauthorizedException();
if (code)
return this.loginUserWithTotpCode(ipAddress, userAgent, user.id, code);
if (user.twoFactorEnabled) {
}
await this.checkLoginSubnet(
ipAddress,
userAgent,
user.checkLocationOnLogin,
user.id,
);
return this.loginResponse(ipAddress, userAgent, user.id);
}

async register(data: RegisterDto): Promise<Expose<users>> {
async register(ipAddress: string, data: RegisterDto): Promise<Expose<users>> {
const email = data.email;
data.name = data.name
.split(' ')
Expand Down Expand Up @@ -122,6 +144,7 @@ export class AuthService {
},
});
await this.sendEmailVerification(email);
await this.approvedSubnetsService.approveNewSubnet(user.id, ipAddress);
return this.prisma.expose(user);
}

Expand Down Expand Up @@ -284,6 +307,7 @@ export class AuthService {
!!ignorePwnedPassword,
);
await this.prisma.users.update({ where: { id }, data: { password } });
await this.approvedSubnetsService.upsertNewSubnet(id, ipAddress);
return this.loginResponse(ipAddress, userAgent, id);
}

Expand Down

0 comments on commit 24afea0

Please sign in to comment.