diff --git a/apps/backend/src/app/auth/auth.controller.ts b/apps/backend/src/app/auth/auth.controller.ts index f59e49e..c33f1fa 100644 --- a/apps/backend/src/app/auth/auth.controller.ts +++ b/apps/backend/src/app/auth/auth.controller.ts @@ -1,14 +1,14 @@ import { - Body, - Controller, - Delete, - Get, - HttpCode, - HttpStatus, - Patch, - Post, - UnauthorizedException, - UseGuards, + Body, + Controller, + Delete, + Get, + HttpCode, + HttpStatus, + Patch, + Post, + UnauthorizedException, + UseGuards, } from "@nestjs/common"; import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto"; import { AuthService } from "apps/backend/src/app/auth/auth.service"; @@ -16,50 +16,50 @@ import { UserGuard } from "./auth.guard"; @Controller("auth") export class AuthController { - constructor(private readonly authService: AuthService) { } + constructor(private readonly authService: AuthService) {} - //TODO Initial account validation for admin privileges - //POST signup - @HttpCode(HttpStatus.CREATED) - @Post("signup") - async signUp(@Body() dto: SignUpDto) { - return this.authService.doRegister(dto); - } + //TODO Initial account validation for admin privileges + //POST signup + @HttpCode(HttpStatus.CREATED) + @Post("signup") + async signUp(@Body() dto: SignUpDto) { + return this.authService.doRegister(dto); + } - //POST signin - @HttpCode(HttpStatus.OK) - @Post("signin") - async signIn(@Body() dto: SignInDto) { - return this.authService.doLogin(dto); - } - //GET me -- Get current user data via jwt - @HttpCode(HttpStatus.OK) - @Get("me") - @UseGuards(UserGuard) - async getMe(@Body() body: object) { - // @ts-ignore - const targetId = body.sourceUserId; - const userData = await this.authService.fetchUserById(targetId); - if (!userData) { - throw new UnauthorizedException(); - } - return userData; - } - //DELETE me - @HttpCode(HttpStatus.FOUND) - @Delete("me") - @UseGuards(UserGuard) - async deleteMe(@Body() body: object) { - // @ts-ignore - const targetId = body.sourceUserId; - try { - await this.authService.deleteUser(targetId); - } catch (err) { - throw new UnauthorizedException(); - } - } + //POST signin + @HttpCode(HttpStatus.OK) + @Post("signin") + async signIn(@Body() dto: SignInDto) { + return this.authService.doLogin(dto); + } + //GET me -- Get current user data via jwt + @HttpCode(HttpStatus.OK) + @Get("me") + @UseGuards(UserGuard) + async getMe(@Body() body: object) { + // @ts-ignore + const targetId = body.sourceUserId; + const userData = await this.authService.fetchUserById(targetId); + if (!userData) { + throw new UnauthorizedException(); + } + return userData; + } + //DELETE me + @HttpCode(HttpStatus.FOUND) + @Delete("me") + @UseGuards(UserGuard) + async deleteMe(@Body() body: object) { + // @ts-ignore + const targetId = body.sourceUserId; + try { + await this.authService.deleteUser(targetId); + } catch (err) { + throw new UnauthorizedException(); + } + } - /* + /* //PATCH me @HttpCode(HttpStatus.OK) @Patch("me") diff --git a/apps/backend/src/app/auth/auth.service.ts b/apps/backend/src/app/auth/auth.service.ts index 429beed..83c6926 100644 --- a/apps/backend/src/app/auth/auth.service.ts +++ b/apps/backend/src/app/auth/auth.service.ts @@ -1,7 +1,7 @@ import { - Injectable, - OnModuleInit, - UnauthorizedException, + Injectable, + OnModuleInit, + UnauthorizedException, } from "@nestjs/common"; import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto"; import { CredentialsService } from "apps/backend/src/app/credentials/credentials.service"; @@ -11,102 +11,102 @@ import { eq } from "drizzle-orm"; @Injectable() export class AuthService implements OnModuleInit { - constructor( - private db: DbService, - private credentials: CredentialsService, - ) { } + constructor( + private db: DbService, + private credentials: CredentialsService, + ) {} - //TODO Initial account validation for admin privileges - async doRegister(data: SignUpDto) { - const existingUser = await this.db - .use() - .select() - .from(UsersTable) - .where(eq(UsersTable.email, data.email)) - .prepare("userByEmail") - .execute(); - if (existingUser.length !== 0) - throw new UnauthorizedException("Already exist"); - const query = await this.db - .use() - .insert(UsersTable) - .values({ - //firstName: data.firstName, - //lastName: data.lastName, - email: data.email, - hash: await this.credentials.hash(data.password), - }) - .returning() - .prepare("insertUser") - .execute() - .catch((err) => { - console.error(err); - throw new UnauthorizedException( - "Error occurred while inserting user", - err, - ); - }); - return { - message: "User created, check your email for validation.", - token: await this.credentials.signAuthToken({ sub: query[0].uuid }), - }; - } + //TODO Initial account validation for admin privileges + async doRegister(data: SignUpDto) { + const existingUser = await this.db + .use() + .select() + .from(UsersTable) + .where(eq(UsersTable.email, data.email)) + .prepare("userByEmail") + .execute(); + if (existingUser.length !== 0) + throw new UnauthorizedException("Already exist"); + const query = await this.db + .use() + .insert(UsersTable) + .values({ + //firstName: data.firstName, + //lastName: data.lastName, + email: data.email, + hash: await this.credentials.hash(data.password), + }) + .returning() + .prepare("insertUser") + .execute() + .catch((err) => { + console.error(err); + throw new UnauthorizedException( + "Error occurred while inserting user", + err, + ); + }); + return { + message: "User created, check your email for validation.", + token: await this.credentials.signAuthToken({ sub: query[0].uuid }), + }; + } - async doLogin(data: SignInDto) { - const user = await this.db - .use() - .select() - .from(UsersTable) - .where(eq(UsersTable.email, data.email)) - .prepare("userByEmail") - .execute(); - if (user.length !== 1) - throw new UnauthorizedException("Invalid credentials"); - const passwordMatch = await this.credentials.check( - data.password, - user[0].hash, - ); - if (!passwordMatch) throw new UnauthorizedException("Invalid credentials"); - const token = await this.credentials.signAuthToken({ sub: user[0].uuid }); - return { - message: "Login successful", - token: token, - }; - } + async doLogin(data: SignInDto) { + const user = await this.db + .use() + .select() + .from(UsersTable) + .where(eq(UsersTable.email, data.email)) + .prepare("userByEmail") + .execute(); + if (user.length !== 1) + throw new UnauthorizedException("Invalid credentials"); + const passwordMatch = await this.credentials.check( + data.password, + user[0].hash, + ); + if (!passwordMatch) throw new UnauthorizedException("Invalid credentials"); + const token = await this.credentials.signAuthToken({ sub: user[0].uuid }); + return { + message: "Login successful", + token: token, + }; + } - async fetchUserById(userId: string) { - const user = await this.db - .use() - .select() - .from(UsersTable) - .where(eq(UsersTable.uuid, userId)) - .prepare("userById") - .execute(); - if (user.length !== 1) { - throw new UnauthorizedException("User not found"); - } - delete user[0].hash; - //delete user[0].emailCode; - return user[0]; - } + async fetchUserById(userId: string) { + const user = await this.db + .use() + .select() + .from(UsersTable) + .where(eq(UsersTable.uuid, userId)) + .prepare("userById") + .execute(); + if (user.length !== 1) { + throw new UnauthorizedException("User not found"); + } + delete user[0].hash; + //delete user[0].emailCode; + return user[0]; + } - async fetchUsers() { - //TODO Pagination - const usersInDb = await this.db.use().select().from(UsersTable); - const result = { - total: usersInDb.length, - users: usersInDb.map((user) => { - delete user.hash; - return { - ...user, - }; - }), - }; - console.log(result); - return result; - } + async fetchUsers() { + //TODO Pagination + const usersInDb = await this.db.use().select().from(UsersTable); + const result = { + total: usersInDb.length, + users: usersInDb.map((user) => { + delete user.hash; + return { + ...user, + }; + }), + }; + console.log(result); + return result; + } - /* + /* async updateUser(targetId: string, userData: IUserUpdateData) { const validationResult = UserUpdateSchema.safeParse(userData); if (!validationResult.success) { @@ -132,26 +132,26 @@ export class AuthService implements OnModuleInit { } */ - async deleteUser(targetId: string) { - await this.db - .use() - .delete(UsersTable) - .where(eq(UsersTable.uuid, targetId)) - .prepare("deleteUserById") - .execute() - .catch((err) => { - console.error(err); - throw new UnauthorizedException( - "Error occurred while deleting user", - err, - ); - }); - return true; - } + async deleteUser(targetId: string) { + await this.db + .use() + .delete(UsersTable) + .where(eq(UsersTable.uuid, targetId)) + .prepare("deleteUserById") + .execute() + .catch((err) => { + console.error(err); + throw new UnauthorizedException( + "Error occurred while deleting user", + err, + ); + }); + return true; + } - async onModuleInit() { - setTimeout(() => { - this.fetchUsers(); - }, 2000); - } + async onModuleInit() { + setTimeout(() => { + this.fetchUsers(); + }, 2000); + } } diff --git a/apps/backend/src/app/credentials/credentials.service.ts b/apps/backend/src/app/credentials/credentials.service.ts index 899c3a9..a16c9f9 100644 --- a/apps/backend/src/app/credentials/credentials.service.ts +++ b/apps/backend/src/app/credentials/credentials.service.ts @@ -6,51 +6,51 @@ import { JWTPayload, generateSecret } from "jose"; @Injectable() export class CredentialsService { - constructor(private readonly configService: ConfigService) { } + constructor(private readonly configService: ConfigService) {} - async hash(plaintextPassword: string) { - if (plaintextPassword.length < 6) - throw new BadRequestException("Password is not strong enough !"); - return argon.hash(plaintextPassword, { - secret: Buffer.from(this.configService.get("APP_HASH_SECRET")), - }); - } + async hash(plaintextPassword: string) { + if (plaintextPassword.length < 6) + throw new BadRequestException("Password is not strong enough !"); + return argon.hash(plaintextPassword, { + secret: Buffer.from(this.configService.get("APP_HASH_SECRET")), + }); + } - async check(plaintextPassword: string, hashedPassword: string) { - return argon.verify(hashedPassword, plaintextPassword, { - secret: Buffer.from(this.configService.get("APP_HASH_SECRET")), - }); - } + async check(plaintextPassword: string, hashedPassword: string) { + return argon.verify(hashedPassword, plaintextPassword, { + secret: Buffer.from(this.configService.get("APP_HASH_SECRET")), + }); + } - async verifyAuthToken(token: string) { - try { - const result = await jose.jwtVerify( - token, - Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")), - { - audience: "auth:user", - issuer: "FabLab", - }, - ); - console.log(result); - return result; - } catch (error) { - console.log(error); - throw new BadRequestException("Invalid token"); - } - } + async verifyAuthToken(token: string) { + try { + const result = await jose.jwtVerify( + token, + Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")), + { + audience: "auth:user", + issuer: "FabLab", + }, + ); + console.log(result); + return result; + } catch (error) { + console.log(error); + throw new BadRequestException("Invalid token"); + } + } - async signAuthToken(payload: JWTPayload) { - console.log(this.configService.get("APP_TOKEN_SECRET")); - const token = new jose.SignJWT(payload) - .setProtectedHeader({ alg: "HS512", enc: "A128CBC-HS512" }) - .setIssuedAt() - .setExpirationTime("5 day") - .setIssuer("FabLab") - .setAudience("auth:user"); - console.log(token); - return await token.sign( - Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")), - ); - } + async signAuthToken(payload: JWTPayload) { + console.log(this.configService.get("APP_TOKEN_SECRET")); + const token = new jose.SignJWT(payload) + .setProtectedHeader({ alg: "HS512", enc: "A128CBC-HS512" }) + .setIssuedAt() + .setExpirationTime("5 day") + .setIssuer("FabLab") + .setAudience("auth:user"); + console.log(token); + return await token.sign( + Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")), + ); + } } diff --git a/apps/backend/src/main.ts b/apps/backend/src/main.ts index c8bd9f1..98cbe8d 100644 --- a/apps/backend/src/main.ts +++ b/apps/backend/src/main.ts @@ -1,17 +1,15 @@ import { Logger } from "@nestjs/common"; import { NestFactory } from "@nestjs/core"; -import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; - +import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; import helmet from "helmet"; import { AppModule } from "./app/app.module"; async function bootstrap() { - const config = new DocumentBuilder() - .setTitle('Fab Explorer') + .setTitle("Fab Explorer") .setDescription("Définition de l'api du FabLab Explorer") - .setVersion('1.0') + .setVersion("1.0") .build(); const app = await NestFactory.create(AppModule); @@ -21,7 +19,7 @@ async function bootstrap() { const port = process.env.PORT || 3000; const document = SwaggerModule.createDocument(app, config); - SwaggerModule.setup('api', app, document); + SwaggerModule.setup("api", app, document); await app.listen(port); Logger.log(