feat: add logs for successful registration, successful login and failed login

This commit is contained in:
Elias Schneider
2024-07-10 18:39:47 +02:00
parent 9d9cc7b4ab
commit d2bfb9a55f
4 changed files with 30 additions and 15 deletions

View File

@@ -45,12 +45,13 @@ export class AuthController {
}) })
async signUp( async signUp(
@Body() dto: AuthRegisterDTO, @Body() dto: AuthRegisterDTO,
@Req() { ip }: Request,
@Res({ passthrough: true }) response: Response, @Res({ passthrough: true }) response: Response,
) { ) {
if (!this.config.get("share.allowRegistration")) if (!this.config.get("share.allowRegistration"))
throw new ForbiddenException("Registration is not allowed"); throw new ForbiddenException("Registration is not allowed");
const result = await this.authService.signUp(dto); const result = await this.authService.signUp(dto, ip);
this.authService.addTokensToResponse( this.authService.addTokensToResponse(
response, response,
@@ -71,9 +72,10 @@ export class AuthController {
@HttpCode(200) @HttpCode(200)
async signIn( async signIn(
@Body() dto: AuthSignInDTO, @Body() dto: AuthSignInDTO,
@Req() { ip }: Request,
@Res({ passthrough: true }) response: Response, @Res({ passthrough: true }) response: Response,
) { ) {
const result = await this.authService.signIn(dto); const result = await this.authService.signIn(dto, ip);
if (result.accessToken && result.refreshToken) { if (result.accessToken && result.refreshToken) {
this.authService.addTokensToResponse( this.authService.addTokensToResponse(

View File

@@ -2,6 +2,7 @@ import {
BadRequestException, BadRequestException,
ForbiddenException, ForbiddenException,
Injectable, Injectable,
Logger,
UnauthorizedException, UnauthorizedException,
} from "@nestjs/common"; } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt"; import { JwtService } from "@nestjs/jwt";
@@ -24,8 +25,9 @@ export class AuthService {
private config: ConfigService, private config: ConfigService,
private emailService: EmailService, private emailService: EmailService,
) {} ) {}
private readonly logger = new Logger(AuthService.name);
async signUp(dto: AuthRegisterDTO) { async signUp(dto: AuthRegisterDTO, ip: string) {
const isFirstUser = (await this.prisma.user.count()) == 0; const isFirstUser = (await this.prisma.user.count()) == 0;
const hash = dto.password ? await argon.hash(dto.password) : null; const hash = dto.password ? await argon.hash(dto.password) : null;
@@ -44,6 +46,7 @@ export class AuthService {
); );
const accessToken = await this.createAccessToken(user, refreshTokenId); const accessToken = await this.createAccessToken(user, refreshTokenId);
this.logger.log(`User ${user.email} signed up from IP ${ip}`);
return { accessToken, refreshToken, user }; return { accessToken, refreshToken, user };
} catch (e) { } catch (e) {
if (e instanceof PrismaClientKnownRequestError) { if (e instanceof PrismaClientKnownRequestError) {
@@ -57,7 +60,7 @@ export class AuthService {
} }
} }
async signIn(dto: AuthSignInDTO) { async signIn(dto: AuthSignInDTO, ip: string) {
if (!dto.email && !dto.username) if (!dto.email && !dto.username)
throw new BadRequestException("Email or username is required"); throw new BadRequestException("Email or username is required");
@@ -67,9 +70,14 @@ export class AuthService {
}, },
}); });
if (!user || !(await argon.verify(user.password, dto.password))) if (!user || !(await argon.verify(user.password, dto.password))) {
this.logger.log(
`Failed login attempt for user ${dto.email} from IP ${ip}`,
);
throw new UnauthorizedException("Wrong email or password"); throw new UnauthorizedException("Wrong email or password");
}
this.logger.log(`Successful login for user ${dto.email} from IP ${ip}`);
return this.generateToken(user); return this.generateToken(user);
} }

View File

@@ -85,7 +85,7 @@ export class OAuthController {
accessToken?: string; accessToken?: string;
refreshToken?: string; refreshToken?: string;
loginToken?: string; loginToken?: string;
} = await this.oauthService.signIn(user); } = await this.oauthService.signIn(user, request.ip);
if (token.accessToken) { if (token.accessToken) {
this.authService.addTokensToResponse( this.authService.addTokensToResponse(
response, response,

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from "@nestjs/common"; import { Inject, Injectable, Logger } from "@nestjs/common";
import { User } from "@prisma/client"; import { User } from "@prisma/client";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { AuthService } from "../auth/auth.service"; import { AuthService } from "../auth/auth.service";
@@ -15,6 +15,7 @@ export class OAuthService {
private auth: AuthService, private auth: AuthService,
@Inject("OAUTH_PLATFORMS") private platforms: string[], @Inject("OAUTH_PLATFORMS") private platforms: string[],
) {} ) {}
private readonly logger = new Logger(OAuthService.name);
available(): string[] { available(): string[] {
return this.platforms return this.platforms
@@ -39,7 +40,7 @@ export class OAuthService {
return Object.fromEntries(oauthUsers.map((u) => [u.provider, u])); return Object.fromEntries(oauthUsers.map((u) => [u.provider, u]));
} }
async signIn(user: OAuthSignInDto) { async signIn(user: OAuthSignInDto, ip: string) {
const oauthUser = await this.prisma.oAuthUser.findFirst({ const oauthUser = await this.prisma.oAuthUser.findFirst({
where: { where: {
provider: user.provider, provider: user.provider,
@@ -50,10 +51,11 @@ export class OAuthService {
}, },
}); });
if (oauthUser) { if (oauthUser) {
this.logger.log(`Successful login for user ${user.email} from IP ${ip}`);
return this.auth.generateToken(oauthUser.user, true); return this.auth.generateToken(oauthUser.user, true);
} }
return this.signUp(user); return this.signUp(user, ip);
} }
async link( async link(
@@ -119,7 +121,7 @@ export class OAuthService {
} }
} }
private async signUp(user: OAuthSignInDto) { private async signUp(user: OAuthSignInDto, ip: string) {
// register // register
if (!this.config.get("oauth.allowRegistration")) { if (!this.config.get("oauth.allowRegistration")) {
throw new ErrorPageException("no_user", "/auth/signIn", [ throw new ErrorPageException("no_user", "/auth/signIn", [
@@ -151,11 +153,14 @@ export class OAuthService {
return this.auth.generateToken(existingUser, true); return this.auth.generateToken(existingUser, true);
} }
const result = await this.auth.signUp({ const result = await this.auth.signUp(
email: user.email, {
username: await this.getAvailableUsername(user.providerUsername), email: user.email,
password: null, username: await this.getAvailableUsername(user.providerUsername),
}); password: null,
},
ip,
);
await this.prisma.oAuthUser.create({ await this.prisma.oAuthUser.create({
data: { data: {