parent
5777f9f85e
commit
1ad73af848
9 changed files with 390 additions and 9 deletions
@ -0,0 +1,20 @@ |
|||||||
|
import { Controller, Post, Body, Request, UseGuards } from '@nestjs/common'; |
||||||
|
import { AuthService } from './auth.service'; |
||||||
|
import { CreateUserDto } from '../users/dto'; |
||||||
|
import { AuthGuard } from '@nestjs/passport'; |
||||||
|
|
||||||
|
@Controller('auth') |
||||||
|
export class AuthController { |
||||||
|
constructor(private authService: AuthService) {} |
||||||
|
|
||||||
|
@UseGuards(AuthGuard('local')) |
||||||
|
@Post('login') |
||||||
|
async login(@Request() req) { |
||||||
|
return await this.authService.login(req.user); |
||||||
|
} |
||||||
|
|
||||||
|
@Post('signup') |
||||||
|
async signUp(@Body() createUserDto: CreateUserDto) { |
||||||
|
return await this.authService.create(createUserDto); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
import { Module } from '@nestjs/common'; |
||||||
|
import { AuthService } from './auth.service'; |
||||||
|
import { AuthController } from './auth.controller'; |
||||||
|
import { PassportModule } from '@nestjs/passport'; |
||||||
|
import { LocalStrategy } from './local.strategy'; |
||||||
|
import { UsersModule } from '../users/users.module'; |
||||||
|
import { JwtModule } from '@nestjs/jwt'; |
||||||
|
import { JwtStrategy } from './jwt.strategy'; |
||||||
|
|
||||||
|
@Module({ |
||||||
|
imports: [ |
||||||
|
PassportModule, |
||||||
|
UsersModule, |
||||||
|
JwtModule.register({ |
||||||
|
secret: process.env.JWTKEY, |
||||||
|
signOptions: { expiresIn: process.env.TOKEN_EXPIRATION }, |
||||||
|
}), |
||||||
|
], |
||||||
|
controllers: [AuthController], |
||||||
|
providers: [AuthService, LocalStrategy, JwtStrategy], |
||||||
|
}) |
||||||
|
export class AuthModule {} |
@ -0,0 +1,55 @@ |
|||||||
|
import { Injectable } from '@nestjs/common'; |
||||||
|
import { UsersService } from '../users/users.service'; |
||||||
|
import * as argon from 'argon2'; |
||||||
|
import { JwtService } from '@nestjs/jwt'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class AuthService { |
||||||
|
constructor( |
||||||
|
private readonly userService: UsersService, |
||||||
|
private readonly jwtService: JwtService, |
||||||
|
) {} |
||||||
|
|
||||||
|
async validateUser(username: string, pass: string) { |
||||||
|
// find if user exist with this email
|
||||||
|
const user = await this.userService.findOneByEmail(username); |
||||||
|
if (!user) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
const match = await this.comparePassword(pass, user.password); |
||||||
|
if (!match) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
const { password, ...result } = user['dataValues']; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public async login(user) { |
||||||
|
const token = await this.generateToken(user); |
||||||
|
return { user, token }; |
||||||
|
} |
||||||
|
|
||||||
|
public async create(user) { |
||||||
|
const createdUser = await this.userService.create(user); |
||||||
|
const token = await this.generateToken(createdUser); |
||||||
|
|
||||||
|
return { user: createdUser, token }; |
||||||
|
} |
||||||
|
|
||||||
|
private async generateToken(user) { |
||||||
|
const token = await this.jwtService.signAsync(user); |
||||||
|
return token; |
||||||
|
} |
||||||
|
|
||||||
|
private async hashPassword(password) { |
||||||
|
const hash = await argon.hash(password); |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
private async comparePassword(enteredPassword, dbPassword) { |
||||||
|
const match = await argon.verify(dbPassword, enteredPassword); |
||||||
|
return match; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
import { ExtractJwt, Strategy } from 'passport-jwt'; |
||||||
|
import { PassportStrategy } from '@nestjs/passport'; |
||||||
|
import { Injectable, UnauthorizedException } from '@nestjs/common'; |
||||||
|
import { UsersService } from '../users/users.service'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class JwtStrategy extends PassportStrategy(Strategy) { |
||||||
|
constructor(private readonly userService: UsersService) { |
||||||
|
super({ |
||||||
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), |
||||||
|
ignoreExpiration: false, |
||||||
|
secretOrKey: process.env.JWTKEY, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async validate(payload: any) { |
||||||
|
const user = await this.userService.findOne(payload.id); |
||||||
|
if (!user) { |
||||||
|
throw new UnauthorizedException( |
||||||
|
'You are not authorized to perform the operation', |
||||||
|
); |
||||||
|
} |
||||||
|
return payload; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
import { Strategy } from 'passport-local'; |
||||||
|
import { PassportStrategy } from '@nestjs/passport'; |
||||||
|
import { Injectable, UnauthorizedException } from '@nestjs/common'; |
||||||
|
import { AuthService } from './auth.service'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class LocalStrategy extends PassportStrategy(Strategy) { |
||||||
|
constructor(private readonly authService: AuthService) { |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
async validate(username: string, password: string): Promise<any> { |
||||||
|
const user = await this.authService.validateUser(username, password); |
||||||
|
|
||||||
|
if (!user) { |
||||||
|
throw new UnauthorizedException('Invalid user credentials'); |
||||||
|
} |
||||||
|
return user; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue