feat: add logs for successful registration, successful login and failed login
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user