diff --git a/src/routes/auth/auth.controller.spec.ts b/src/routes/auth/auth.controller.spec.ts new file mode 100644 index 0000000..27a31e6 --- /dev/null +++ b/src/routes/auth/auth.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthController } from './auth.controller'; + +describe('AuthController', () => { + let controller: AuthController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AuthController], + }).compile(); + + controller = module.get(AuthController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/routes/auth/auth.controller.ts b/src/routes/auth/auth.controller.ts new file mode 100644 index 0000000..4395073 --- /dev/null +++ b/src/routes/auth/auth.controller.ts @@ -0,0 +1,22 @@ +import { Body, Controller, Post } from '@nestjs/common'; +import { LoginDto } from './dto/login.dto'; +import { AuthService } from './auth.service'; +import { CreateUserDto } from '../user/dto/create_user.dto'; +import { Public } from 'src/common/decorators/public.decorator'; + +@Controller('auth') +export class AuthController { + constructor(private readonly authService: AuthService) {} + + @Public() + @Post('login') + async login(@Body() dto: LoginDto) { + return this.authService.login(dto); + } + + @Public() + @Post('bootstrap-super-admin') + async bootstrapSuperAdmin(@Body() dto: CreateUserDto) { + return this.authService.bootstrapSuperAdmin(dto); + } +} diff --git a/src/routes/auth/auth.module.ts b/src/routes/auth/auth.module.ts new file mode 100644 index 0000000..d7a59fa --- /dev/null +++ b/src/routes/auth/auth.module.ts @@ -0,0 +1,23 @@ +import { Module } from '@nestjs/common'; +import { AuthController } from './auth.controller'; +import { AuthService } from './auth.service'; +import { UserModule } from '../user/user.module'; +import { JwtModule } from '@nestjs/jwt'; +import { ConfigModule, ConfigService } from '@nestjs/config'; + +@Module({ + imports: [ + UserModule, + JwtModule.registerAsync({ + imports: [ConfigModule], + useFactory: (config: ConfigService) => ({ + secret: config.get('jwt.secret'), + signOptions: { expiresIn: config.get('jwt.expirationTime') }, + }), + inject: [ConfigService], + }) + ], + controllers: [AuthController], + providers: [AuthService] +}) +export class AuthModule {} diff --git a/src/routes/auth/auth.service.spec.ts b/src/routes/auth/auth.service.spec.ts new file mode 100644 index 0000000..800ab66 --- /dev/null +++ b/src/routes/auth/auth.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AuthService], + }).compile(); + + service = module.get(AuthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/routes/auth/auth.service.ts b/src/routes/auth/auth.service.ts new file mode 100644 index 0000000..4408f72 --- /dev/null +++ b/src/routes/auth/auth.service.ts @@ -0,0 +1,33 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { UserService } from '../user/user.service'; +import { JwtService } from '@nestjs/jwt'; +import { RoleType } from 'src/entities/users.entity'; +import * as bcrypt from 'bcrypt'; + +@Injectable() +export class AuthService { + constructor( + private readonly userService: UserService, + private readonly jwtService: JwtService, + ) { } + + async bootstrapSuperAdmin(dto: any) { + const user = await this.userService.create({ + ...dto, + role: RoleType.SUPER_ADMIN, + }, undefined); + return { message: 'Super admin cree avec succes !', user }; + } + + async login({ email, password }: { email: string, password: string }) { + const user = await this.userService.findByEmail(email) + if (!user) throw new UnauthorizedException('Identifiants invalides !'); + + const isMatch = await bcrypt.compare(password, user.password_hash); + if (!isMatch) throw new UnauthorizedException('Identifiants invalides !'); + const payload = { id: user.id, email: user.email, role: user.role }; + return { + access_token: this.jwtService.sign(payload), + }; + } +} diff --git a/src/routes/auth/dto/login.dto.ts b/src/routes/auth/dto/login.dto.ts new file mode 100644 index 0000000..a36da97 --- /dev/null +++ b/src/routes/auth/dto/login.dto.ts @@ -0,0 +1,10 @@ +import { IsEmail, IsString, MinLength } from "class-validator"; + +export class LoginDto { + @IsEmail() + email: string; + + @IsString() + @MinLength(6) + password: string; +} \ No newline at end of file