From fd61ea56d2f39bf783c7b1fc496e4dd662f14afa Mon Sep 17 00:00:00 2001 From: batche Date: Tue, 15 Nov 2022 17:57:21 +0100 Subject: [PATCH] double auth maintenant fonctionne correctement. Il y a un PoC avec svelte --- .../src/auth/42/authentication.controller.ts | 27 ++++-- .../api_back/src/auth/42/guards/42guards.ts | 12 ++- .../src/friendship/friendship.controller.ts | 10 ++- .../src/users/entities/user.entity.ts | 3 + .../api_back/src/users/users.controller.ts | 6 +- .../api_back/src/users/users.service.ts | 6 +- .../svelte/api_front/src/App.svelte | 15 +++- .../api_front/src/pages/auth/DoubleFa.svelte | 89 +++++++++++++++++++ 8 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 srcs/requirements/svelte/api_front/src/pages/auth/DoubleFa.svelte diff --git a/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts b/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts index f381466f..cbe76106 100644 --- a/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts @@ -1,5 +1,5 @@ -import { Controller, Get, Res, UseGuards, Req, Post, UnauthorizedException, Body, Options } from '@nestjs/common'; -import { AuthenticateGuard, FortyTwoAuthGuard } from './guards/42guards'; +import { Controller, Get, Res, UseGuards, Req, Post, UnauthorizedException, Body, Options, Next } from '@nestjs/common'; +import { AuthenticateGuard, FortyTwoAuthGuard, TwoFactorGuard } from './guards/42guards'; import { AuthenticationService } from './authentication.service'; import { Response } from 'express'; import { TwoFaDto } from './dto/2fa.dto'; @@ -31,19 +31,26 @@ export class AuthenticationController { @Get('redirect') @UseGuards(FortyTwoAuthGuard) async redirect(@Res() response : Response, @Req() request) { - console.log('ON EST DANS REDIRECT AUTH CONTROLLER' + request.user); + console.log('ON EST DANS REDIRECT AUTH CONTROLLER'); console.log('On redirige'); - return response.status(200).redirect('http://transcendance:8080'); + if (request.user.isEnabledTwoFactorAuth === false) + return response.status(200).redirect('http://transcendance:8080'); + return response.status(200).redirect('http://transcendance:8080/#/2fa'); } /** * GET /api/v2/auth/logout * Route pour déconnecter l'utilisateur */ - @Get('logout') - logout(@Req() request) { - console.log('ON EST DANS LOGOUT AUTH CONTROLLER') - request.session.destroy(); + @Post('logout') + @UseGuards(AuthenticateGuard) + logout(@Req() request, @Res() response, @Next() next) { + this.userService.setIsTwoFactorAuthenticatedWhenLogout(request.user.id); + request.logout(function(err) { + if (err) { return next(err); } + response.redirect('/'); + }); + request.session.cookie.maxAge = 0; return {msg : 'You are now logged out'}; } @@ -57,7 +64,7 @@ export class AuthenticationController { @Post('2fa/turn-on') @UseGuards(AuthenticateGuard) - async verify(@Req() request, @Body() {twoFaCode} : TwoFaDto){ + async verify(@Req() request, @Body() {twoFaCode} : TwoFaDto, @Res() response){ console.log('ON EST DANS VERIFY POUR 2FA AUTH CONTROLLER') const isCodeIsValid = await this.authService.verify2FaCode(request.user, twoFaCode); if (isCodeIsValid === false) @@ -65,5 +72,7 @@ export class AuthenticationController { throw new UnauthorizedException('Wrong Code.'); } await this.userService.enableTwoFactorAuth(request.user.id); + console.log('ON REDIRIGE'); + return response.status(200); } } diff --git a/srcs/requirements/nestjs/api_back/src/auth/42/guards/42guards.ts b/srcs/requirements/nestjs/api_back/src/auth/42/guards/42guards.ts index ea5a93a9..82a39eea 100644 --- a/srcs/requirements/nestjs/api_back/src/auth/42/guards/42guards.ts +++ b/srcs/requirements/nestjs/api_back/src/auth/42/guards/42guards.ts @@ -15,8 +15,18 @@ export class FortyTwoAuthGuard extends AuthGuard('42') { export class AuthenticateGuard implements CanActivate { async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); - console.log("Is User authenticated : " + request.isAuthenticated()); + console.log("AuthenticateGuard : Is User authenticated : " + request.isAuthenticated()); return request.isAuthenticated(); } } +@Injectable() +export class TwoFactorGuard implements CanActivate { + async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest(); + console.log("TwoFactorGuard : Is User authenticated : " + request.isAuthenticated() + " and has 2FA enabled : " + request.user.isEnabledTwoFactorAuth + " and has 2FA verified : " + request.user.isTwoFactorAuthenticated); + return request.isAuthenticated() && (request.user.isEnabledTwoFactorAuth === false + || request.user.isTwoFactorAuthenticated === true); + } +} + diff --git a/srcs/requirements/nestjs/api_back/src/friendship/friendship.controller.ts b/srcs/requirements/nestjs/api_back/src/friendship/friendship.controller.ts index 58678bbf..4d85dfc8 100644 --- a/srcs/requirements/nestjs/api_back/src/friendship/friendship.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/friendship/friendship.controller.ts @@ -1,5 +1,5 @@ import { Body, Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Param, Patch, Post, Query, Req, UseGuards } from '@nestjs/common'; -import { AuthenticateGuard } from 'src/auth/42/guards/42guards'; +import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards'; import { User } from 'src/users/entities/user.entity'; import { CreateFriendshipDto } from './dto/create-friendship.dto'; import { FriendshipService } from './friendship.service'; @@ -11,6 +11,7 @@ export class FriendshipController { // GET http://127.0.0.1:3000/api/v2/network/myfriends @Get('myfriends') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) findEmpty(@Req() req) { const user = req.user; return this.friendshipService.findAllFriends(user.id); @@ -19,6 +20,7 @@ export class FriendshipController { // GET http://127.0.0.1:3000/api/v2/network/myfriends/relationshipId @Get('myfriends/:relationshipId') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) findOneFriend(@Param('relationshipId') relationshipId: string, @Req() req) { const user = req.user; return this.friendshipService.findOneFriend(relationshipId, user.id); @@ -28,6 +30,7 @@ export class FriendshipController { @Post('myfriends') @HttpCode(HttpStatus.CREATED) @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) create(@Body() createFriendshipDto: CreateFriendshipDto, @Req() req) { const user = req.user; console.log(`User id: ${user.id}\n Friend id: ${createFriendshipDto.requesterId}`); @@ -39,6 +42,7 @@ export class FriendshipController { // PATCH http://127.0.0.1:3000/api/v2/network/myfriends/relationshipId?status=A @Patch('myfriends/:relationshipId') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) update(@Param('relationshipId') relationshipId: string, @Query('status') status : string, @Req() req) { const user : User = req.user; @@ -48,6 +52,7 @@ export class FriendshipController { // DELETE http://127.0.0.1:3000/api/v2/network/myfriends/relationshipId @Delete('myfriends/:relationshipId') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) remove(@Param('relationshipId') relationshipId: string) { return this.friendshipService.removeFriendship(relationshipId); } @@ -56,6 +61,7 @@ export class FriendshipController { // GET http://127.0.0.1:3000/api/v2/network/blocked @Get('blocked') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) findAllBlocked(@Req() req) { const user = req.user; return this.friendshipService.findAllBlockedFriends(user.id); @@ -64,6 +70,7 @@ export class FriendshipController { // GET http://127.0.0.1:3000/api/v2/network/pending @Get('pending') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) findAllPendantFriendshipRequested(@Req() req) { const user = req.user; return this.friendshipService.findAllPendantRequestsForFriendship(user.id); @@ -72,6 +79,7 @@ export class FriendshipController { // GET http://127.0.0.1:3000/api/v2/network/received @Get('received') @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) findAllPendantFriendshipReceived(@Req() req) { const user = req.user; return this.friendshipService.findAllReceivedRequestsForFriendship(user.id); diff --git a/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts b/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts index 3394b5c8..714b5b15 100644 --- a/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts +++ b/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts @@ -36,6 +36,9 @@ export class User { @Column({ default: false, nullable: true }) isEnabledTwoFactorAuth: boolean; + @Column({ default:false, nullable: true }) + isTwoFactorAuthenticated: boolean; + @Column({ nullable: true }) secretTwoFactorAuth: string; diff --git a/srcs/requirements/nestjs/api_back/src/users/users.controller.ts b/srcs/requirements/nestjs/api_back/src/users/users.controller.ts index 333aae30..f1c00cf5 100644 --- a/srcs/requirements/nestjs/api_back/src/users/users.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/users/users.controller.ts @@ -2,7 +2,7 @@ import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Query, Req, UseGuards } from '@nestjs/common'; -import { AuthenticateGuard } from 'src/auth/42/guards/42guards'; +import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards'; import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto'; import { ValidationPipe } from 'src/common/validation/validation.pipe'; import { CreateUsersDto } from './dto/create-users.dto'; @@ -17,6 +17,7 @@ export class UsersController { // par exemple dans postamn ou insomnia http://localhost:3000/users?limit=10&offset=20 @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) @Get('all') findAll(@Query() paginationquery : PaginationQueryDto) { //const { limit, offset } = query; @@ -33,6 +34,7 @@ export class UsersController { */ @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) @Get() findOne(@Req() req) { return this.usersService.findOne(req.user.id); @@ -46,6 +48,7 @@ export class UsersController { // } @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) @Patch() update(@Req() req, @Body(new ValidationPipe()) usersUpdateDto: UpdateUsersDto) { console.log("DANS PATCH USERS"); @@ -53,6 +56,7 @@ export class UsersController { } @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) @Delete() remove(@Req() req) { return this.usersService.remove(req.user.id); diff --git a/srcs/requirements/nestjs/api_back/src/users/users.service.ts b/srcs/requirements/nestjs/api_back/src/users/users.service.ts index 24e1c4c0..a5cbcd59 100644 --- a/srcs/requirements/nestjs/api_back/src/users/users.service.ts +++ b/srcs/requirements/nestjs/api_back/src/users/users.service.ts @@ -82,7 +82,11 @@ export class UsersService { } async enableTwoFactorAuth(id: string) { - return this.userRepository.update(id, {isEnabledTwoFactorAuth: true}); + return this.userRepository.update(id, {isEnabledTwoFactorAuth: true, isTwoFactorAuthenticated: true}); + } + + async setIsTwoFactorAuthenticatedWhenLogout(id: number) { + return this.userRepository.update(id, {isTwoFactorAuthenticated: false}); } async setAuthenticatorSecret(id: number, secret: string) { diff --git a/srcs/requirements/svelte/api_front/src/App.svelte b/srcs/requirements/svelte/api_front/src/App.svelte index e02c1ce1..aaa05f48 100644 --- a/srcs/requirements/svelte/api_front/src/App.svelte +++ b/srcs/requirements/svelte/api_front/src/App.svelte @@ -1,17 +1,24 @@
@@ -27,7 +34,11 @@ Profil --> - +
+ +
diff --git a/srcs/requirements/svelte/api_front/src/pages/auth/DoubleFa.svelte b/srcs/requirements/svelte/api_front/src/pages/auth/DoubleFa.svelte new file mode 100644 index 00000000..b0b3479d --- /dev/null +++ b/srcs/requirements/svelte/api_front/src/pages/auth/DoubleFa.svelte @@ -0,0 +1,89 @@ + + + +
+ {#await fetchQrCodeImg} +

Please Wait...

+ {:then data} + {#if wrongCode} + + {/if} + A QRCodeImg you must scan with google authenticator +
+ + + +
+ {:catch} +

Unable to get QrCodeImg

+ {/await} +
+ + +