Skip to content

Commit

Permalink
try to do the two factor auth google authentificator
Browse files Browse the repository at this point in the history
  • Loading branch information
VallienneDiane committed Feb 24, 2023
1 parent a0240c1 commit dfc4205
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 18 deletions.
1 change: 1 addition & 0 deletions .env
Expand Up @@ -10,3 +10,4 @@ POSTGRES_DB=users
USER=${USER}

SECRET=Zc8JM4VDQD6IZngLfns1OEdjjcmkXbUJ
TWOFACTOR_APP_NAME=transcendence
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@ postgres/
nodes_modules/
docker-compose.yml
Makefile
.env
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -186,6 +186,8 @@ After the user is successfully saved, you can return a response to the front-end

https://medium.com/att-israel/authentication-authorization-using-react-nestjs-jwt-token-55f52070a3f2

https://dev.to/hahnmatthieu/2fa-with-nestjs-passeport-using-google-authenticator-1l32


## OAuth

Expand Down
26 changes: 26 additions & 0 deletions back/nest_project/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions back/nest_project/package.json
Expand Up @@ -29,6 +29,7 @@
"@nestjs/typeorm": "^9.0.1",
"@types/passport-jwt": "^3.0.8",
"@types/passport-local": "^1.0.35",
"@types/speakeasy": "^2.0.7",
"bcrypt": "^5.1.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
Expand All @@ -38,6 +39,7 @@
"postgres": "^3.3.3",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0",
"speakeasy": "^2.0.0",
"typeorm": "^0.3.12"
},
"devDependencies": {
Expand Down
12 changes: 9 additions & 3 deletions back/nest_project/src/auth/auth.controller.ts
@@ -1,17 +1,23 @@
import { Controller, Body, Request, Post, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { UserDto } from 'src/user/user.dto';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './local-auth.guard';

// SIGN IN, LOGIN AND PASSWORD VERIFICATION, NEW TOKEN
@Controller()
export class AuthController {
constructor(private authService: AuthService) {}

//check login and password and generate token
@UseGuards(AuthGuard('local'))
//check login and password with stratgey local of passport and generate token
@UseGuards(LocalAuthGuard)
@Post('auth/login')
async genToken(@Body() user: UserDto) {
return this.authService.login(user);
}

@Post('auth/otp/generate')
async generateTwoFactorSecretCode() {
const secretCode = await this.authService.genTwoFactorSecretCode();
return secretCode;
}
}
2 changes: 1 addition & 1 deletion back/nest_project/src/auth/auth.module.ts
Expand Up @@ -4,7 +4,7 @@ import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { PassportModule } from "@nestjs/passport";
import { JwtModule } from "@nestjs/jwt";
import { JwtStrategy } from "./jwt.strategy";
import { JwtStrategy } from "../user/jwt.strategy";
import { LocalStrategy } from "./local.strategy";

@Module({
Expand Down
16 changes: 14 additions & 2 deletions back/nest_project/src/auth/auth.service.ts
@@ -1,8 +1,9 @@

import { HttpException, HttpStatus, Injectable, Res } from '@nestjs/common';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { UserService } from 'src/user/user.service';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
import * as speakeasy from "speakeasy";

@Injectable()
export class AuthService {
Expand All @@ -28,4 +29,15 @@ export class AuthService {
access_token: this.jwtService.sign(payload)
}
}

//otp = one time password
async genTwoFactorSecretCode() {
const secretCode = speakeasy.generateSecret({
name: process.env.TWOFACTOR_APP_NAME,
});
return {
otpauthUrl: secretCode.otpauth_url,
base32: secretCode.base32,
}
}
}
5 changes: 5 additions & 0 deletions back/nest_project/src/auth/local-auth.guard.ts
@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
5 changes: 5 additions & 0 deletions back/nest_project/src/user/jwt-auth.guard.ts
@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Expand Up @@ -5,7 +5,6 @@ import { Injectable } from "@nestjs/common";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
console.log('SECRET', process.env.SECRET);
super({
usernameField: 'login',
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
Expand Down
19 changes: 11 additions & 8 deletions back/nest_project/src/user/user.controller.ts
Expand Up @@ -3,8 +3,8 @@ import { UserService } from "./user.service";
import { UserDto } from "./user.dto";
import { UserEntity } from "./user.entity";
import * as bcrypt from 'bcrypt';
import { AuthGuard } from "@nestjs/passport";
import { JwtService } from "@nestjs/jwt";
import { JwtAuthGuard } from "./jwt-auth.guard";

// SIGN UP, REGISTER NEW USER IN DATABASE, NEW TOKEN
@Controller()
Expand All @@ -14,7 +14,7 @@ export class UserController {
private jwtService: JwtService)
{}

//create user account in db and generate token
//Create user account in db, hash password with bcrypt and generate token with jwtservice
@Post('user/signup')
async create(@Body() newUser: UserDto) {
const saltOrRounds = 10;
Expand All @@ -26,26 +26,29 @@ export class UserController {
access_token: this.jwtService.sign(payload)
}
}
//get all users
@UseGuards(AuthGuard('jwt'))

//Requests to database, access ok for validate user only !
//use jwt strategy to check if token is valid before send back the user infos
//get all users (login and id) of the db if valid token (use in chat for exemple)
@UseGuards(JwtAuthGuard)
@Get('users')
async findAll(): Promise<UserEntity[]> {
async findAll(): Promise<any> {
return await this.userService.findAll();
}
//get profile
@UseGuards(AuthGuard('jwt'))
@UseGuards(JwtAuthGuard)
@Get('user/:login')
async displayUserByLogin(@Param('login') login: string): Promise<UserEntity> {
return await this.userService.findByLogin(login);
}
//update account params
@UseGuards(AuthGuard('jwt'))
@UseGuards(JwtAuthGuard)
@Patch('user/:login')
async update(@Param('login') login: string, @Body() user: UserDto): Promise<void> {
return await this.userService.update(login, user);
}
//delete user account
@UseGuards(AuthGuard('jwt'))
@UseGuards(JwtAuthGuard)
@Delete('user/:login')
async delete(@Param('login') login: string) {
return this.userService.delete(login);
Expand Down
2 changes: 1 addition & 1 deletion back/nest_project/src/user/user.module.ts
Expand Up @@ -2,7 +2,7 @@ import { Module } from "@nestjs/common";
import { JwtModule } from "@nestjs/jwt";
import { PassportModule } from "@nestjs/passport";
import { TypeOrmModule } from "@nestjs/typeorm";
import { JwtStrategy } from "src/auth/jwt.strategy";
import { JwtStrategy } from "./jwt.strategy";
import { UserController } from "./user.controller";
import { UserEntity } from "./user.entity";
import { UserService } from "./user.service";
Expand Down
9 changes: 7 additions & 2 deletions back/nest_project/src/user/user.service.ts
Expand Up @@ -19,9 +19,14 @@ export class UserService {
return this.usersRepository.findOneBy({login});
}
// DISPLAY ALL USERS
public findAll(): Promise<UserEntity[]> {
return this.usersRepository.find();
async findAll(): Promise<{ id: number, login: string }[]> {
return await this.usersRepository.createQueryBuilder('user')
.select(['user.id', 'user.login'])
.getMany();
}
// public findAll(): Promise<UserEntity[]> {
// return this.usersRepository.find();
// }
// UPDATE USER INFOS
async update(login: string, User: UserEntity): Promise<void> {
this.usersRepository.update(login, User);
Expand Down
1 change: 1 addition & 0 deletions front/react_project/src/components/ProtectedRoutes.tsx
Expand Up @@ -2,6 +2,7 @@ import { Navigate, Outlet } from "react-router-dom";
import { accountService } from "../services/account.service";

const ProtectedRoutes = () => {
console.log(accountService.isLogged())
return accountService.isLogged() ? <Outlet/> : <Navigate to="/login"/>;
}

Expand Down

0 comments on commit dfc4205

Please sign in to comment.