Oauth est fonctionnel. Le mécanisme de session est à terminer, probablement via un JWT ou autre méthode.
This commit is contained in:
@@ -6,10 +6,12 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { FriendshipsModule } from './friendship/friendships.module';
|
||||
import { AuthenticationModule } from './auth/42/authentication.module';
|
||||
import { PassportModule } from '@nestjs/passport';
|
||||
|
||||
@Module({
|
||||
imports: [UsersModule,
|
||||
AuthenticationModule,
|
||||
PassportModule.register({ session: true }),
|
||||
FriendshipsModule,
|
||||
ConfigModule.forRoot(),
|
||||
TypeOrmModule.forRoot({
|
||||
|
||||
@@ -8,20 +8,14 @@ export class AuthenticationController {
|
||||
|
||||
constructor(private readonly authService: AuthenticationService) {}
|
||||
|
||||
|
||||
@Get()
|
||||
hello() {
|
||||
console.log('AUTHENTICATION CONTROLLER');
|
||||
return 'hello';
|
||||
}
|
||||
/**
|
||||
* GET /api/v2/auth/login
|
||||
* Route pour l'autentification des utilisateurs
|
||||
*/
|
||||
@Get('login')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
login(@Res() res: Response) {
|
||||
return res.sendStatus(200);
|
||||
login() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,6 +24,7 @@ export class AuthenticationController {
|
||||
* L'api de 42 redirige vers cette route après l'autentification.
|
||||
*/
|
||||
@Get('redirect')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
redirect(@Res() res: Response) {
|
||||
console.log(`Redirection performed`);
|
||||
res.sendStatus(200);
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Friendship } from 'src/friendship/entities/friendship.entity';
|
||||
import { User } from 'src/users/entities/user.entity';
|
||||
import { UsersModule } from 'src/users/users.module';
|
||||
import { UsersService } from 'src/users/users.service';
|
||||
import { AuthenticationController } from './authentication.controller';
|
||||
import { AuthenticationService } from './authentication.service';
|
||||
import { FortyTwoStrategy } from './strategy/strategy';
|
||||
import { SessionSerializer } from './utils/serializer';
|
||||
|
||||
@Module({
|
||||
imports: [UsersModule],
|
||||
providers: [AuthenticationService, FortyTwoStrategy],
|
||||
imports: [TypeOrmModule.forFeature([User, Friendship]), UsersModule],
|
||||
providers: [AuthenticationService, FortyTwoStrategy, UsersService, SessionSerializer],
|
||||
exports: [AuthenticationService],
|
||||
controllers: [AuthenticationController],
|
||||
})
|
||||
|
||||
@@ -1,4 +1,26 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { CreateUsersDto } from 'src/users/dto/create-users.dto';
|
||||
import { User } from 'src/users/entities/user.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
import { UsersService } from 'src/users/users.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthenticationService {}
|
||||
export class AuthenticationService {
|
||||
constructor(
|
||||
private readonly userService: UsersService,
|
||||
) {}
|
||||
|
||||
async validateUser(createUsersDto :CreateUsersDto){
|
||||
console.log("Validate inside authentication.service.ts");
|
||||
const user = await this.userService.findOneByFourtyTwoId(createUsersDto.fourtyTwoId);
|
||||
if (user)
|
||||
return user;
|
||||
return this.userService.create(createUsersDto);
|
||||
}
|
||||
|
||||
async findUser(fourtytwo_id : string): Promise<User | undefined> {
|
||||
return await this.userService.findOneByFourtyTwoId(fourtytwo_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ export class FortyTwoAuthGuard extends AuthGuard('42') {
|
||||
async canActivate(context: ExecutionContext): Promise<any> {
|
||||
const activate = (await super.canActivate(context)) as boolean;
|
||||
const request = context.switchToHttp().getRequest();
|
||||
console.log(request.user);
|
||||
await super.logIn(request);
|
||||
return activate;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Strategy, Profile } from "passport-42/lib";
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { Injectable, UnauthorizedException } from "@nestjs/common";
|
||||
import { AuthenticationService } from "../authentication.service";
|
||||
import { CreateUsersDto } from "src/users/dto/create-users.dto";
|
||||
|
||||
@Injectable()
|
||||
export class FortyTwoStrategy extends PassportStrategy(Strategy, "42") {
|
||||
constructor(private readonly authenticationService: AuthenticationService) {
|
||||
constructor(private authenticationService: AuthenticationService) {
|
||||
super({
|
||||
clientID: process.env.FORTYTWO_CLIENT_ID,
|
||||
clientSecret: process.env.FORTYTWO_CLIENT_SECRET,
|
||||
@@ -15,7 +16,12 @@ export class FortyTwoStrategy extends PassportStrategy(Strategy, "42") {
|
||||
}
|
||||
|
||||
async validate(accessToken: string, refreshToken: string, profile: Profile, callbackURL: string) {
|
||||
const { id, username, displayName, photos } = profile;
|
||||
console.log(profile);
|
||||
console.log("Validate inside strategy.ts");
|
||||
console.log(profile.id, profile.username, profile.phoneNumbers[0].value, profile.emails[0].value, profile.photos[0].value);
|
||||
const userDTO: CreateUsersDto = { fourtyTwoId: profile.id, username: profile.username, email: profile.emails[0].value, image_url: profile.photos[0].value };
|
||||
const user = await this.authenticationService.validateUser(userDTO);
|
||||
if (!user)
|
||||
throw new UnauthorizedException();
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { PassportSerializer } from "@nestjs/passport";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { User } from "src/users/entities/user.entity";
|
||||
import { AuthenticationService } from "../authentication.service";
|
||||
|
||||
@Injectable()
|
||||
export class SessionSerializer extends PassportSerializer {
|
||||
constructor(private readonly authservice : AuthenticationService) {
|
||||
super();
|
||||
}
|
||||
|
||||
serializeUser(user : User, done : (err : Error, user : User) => void ){
|
||||
done(null, user);
|
||||
}
|
||||
|
||||
async deserializeUser(user : User, done : (err : Error, user : User) => void){
|
||||
const userDB = await this.authservice.findUser(user.fourtyTwoId);
|
||||
if (userDB)
|
||||
done(null, userDB);
|
||||
else
|
||||
done(null, null);
|
||||
}
|
||||
}
|
||||
3
srcs/requirements/nestjs/api_back/src/conf/constant.ts
Normal file
3
srcs/requirements/nestjs/api_back/src/conf/constant.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const constants = {
|
||||
secret: process.env.COOKIE_SECRET,
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Param, Patch, Post } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Param, Patch, Post, UseGuards } from '@nestjs/common';
|
||||
import { FortyTwoAuthGuard } from 'src/auth/42/guards/guards';
|
||||
import { CreateUsersDto } from 'src/users/dto/create-users.dto';
|
||||
import { CreateFriendshipDto } from './dto/create-friendship.dto';
|
||||
import { UpdateFriendshipDto } from './dto/update-friendship.dto';
|
||||
@@ -10,42 +11,50 @@ export class FriendshipController {
|
||||
constructor(private readonly friendshipService: FriendshipService) {}
|
||||
|
||||
@Get(':userId/friends')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findEmpty(@Param('userId') userId: string) {
|
||||
return this.friendshipService.findAllFriends(userId);
|
||||
}
|
||||
|
||||
@Get(':userId/blocked')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findAllBlocked(@Param('userId') userId: string) {
|
||||
return this.friendshipService.findAllBlockedFriends(userId);
|
||||
}
|
||||
|
||||
@Get(':userId/pending')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findAllPendantFriendshipRequested(@Param('userId') userId: string) {
|
||||
return this.friendshipService.findAllPendantRequestsForFriendship(userId);
|
||||
}
|
||||
|
||||
@Get(':userId/received')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findAllPendantFriendshipReceived(@Param('userId') userId: string) {
|
||||
return this.friendshipService.findAllReceivedRequestsForFriendship(userId);
|
||||
}
|
||||
|
||||
@Get(':userId/myfriends/:friendId')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findOneFriend(@Param('friendId') friendId: string) {
|
||||
return this.friendshipService.findOneFriend(friendId);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
create(@Body() createFriendshipDto: CreateFriendshipDto) {
|
||||
return this.friendshipService.create(createFriendshipDto);
|
||||
}
|
||||
|
||||
@Patch(':userId/received/:relationshipId')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
update(@Param('friendId') relationshipId: string, @Body() {status}: UpdateFriendshipDto) {
|
||||
return this.friendshipService.updateFriendship(relationshipId, {status});
|
||||
}
|
||||
|
||||
@Delete(':userId/:friendId')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
remove(@Param('friendId') friendId: string) {
|
||||
return this.friendshipService.removeFriendship(friendId);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { User } from 'src/users/entities/user.entity';
|
||||
import { Any, Repository } from 'typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { CreateFriendshipDto } from './dto/create-friendship.dto';
|
||||
import { UpdateFriendshipDto } from './dto/update-friendship.dto';
|
||||
import { Friendship, FriendshipStatus } from './entities/friendship.entity';
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
import * as session from 'express-session';
|
||||
import * as passport from 'passport';
|
||||
import { constants } from './conf/constant';
|
||||
async function bootstrap() {
|
||||
|
||||
const app = await NestFactory.create(AppModule);
|
||||
@@ -20,8 +22,20 @@ async function bootstrap() {
|
||||
},
|
||||
}),
|
||||
);
|
||||
const port = process.env.PORT || 3000;
|
||||
const port = process.env.PORT || 3001;
|
||||
app.setGlobalPrefix('api/v2');
|
||||
await app.listen(port, () => { console.log(`Listening on port ${port}`); });
|
||||
app.use(
|
||||
session({
|
||||
cookie: {
|
||||
maxAge: 3600000 * 24,
|
||||
},
|
||||
secret: constants.secret,
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
}),
|
||||
);
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
await app.listen(port, () => { console.log(`Listening on port ${port}`); });
|
||||
}
|
||||
bootstrap();
|
||||
|
||||
@@ -4,8 +4,10 @@ import { Unique } from 'typeorm';
|
||||
export class CreateUsersDto {
|
||||
@IsString()
|
||||
readonly username: string;
|
||||
@IsString()
|
||||
readonly fourtyTwoId: string;
|
||||
@IsEmail()
|
||||
readonly email: string;
|
||||
@IsString()
|
||||
readonly password: string;
|
||||
readonly image_url: string;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({ name: 'fourty_two_id' })
|
||||
@Column({unique: true})
|
||||
fourtyTwoId: string;
|
||||
|
||||
@Column()
|
||||
@@ -21,11 +21,11 @@ export class User {
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@Column()
|
||||
password: string;
|
||||
@Column({ nullable: true })
|
||||
image_url : string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
avatar: string;
|
||||
phone: string;
|
||||
|
||||
@Column('json', { nullable: true })
|
||||
status: [string];
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import {
|
||||
Body, Controller, Delete, Get, HttpCode,
|
||||
HttpStatus, Param, Patch, Post, Query
|
||||
HttpStatus, Param, Patch, Post, Query, UseGuards
|
||||
} from '@nestjs/common';
|
||||
import { FortyTwoAuthGuard } from 'src/auth/42/guards/guards';
|
||||
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
|
||||
import { CreateUsersDto } from './dto/create-users.dto';
|
||||
import { UpdateUsersDto } from './dto/update-users.dto';
|
||||
@@ -15,17 +16,20 @@ export class UsersController {
|
||||
// par exemple dans postamn ou insomnia http://localhost:3000/users?limit=10&offset=20
|
||||
|
||||
@Get('all')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findAll(@Query() paginationquery : PaginationQueryDto) {
|
||||
//const { limit, offset } = query;
|
||||
return this.usersService.findAll(paginationquery);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.usersService.findOne(id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
create(@Body() createUsersDto : CreateUsersDto ) {
|
||||
console.log(createUsersDto);
|
||||
@@ -33,11 +37,13 @@ export class UsersController {
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
update(@Param('id') id: string, @Body() usersUpdateDto: UpdateUsersDto) {
|
||||
return this.usersService.update(id, usersUpdateDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@UseGuards(FortyTwoAuthGuard)
|
||||
remove(@Param('id') id: string) {
|
||||
return this.usersService.remove(id);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,20 @@ export class UsersService {
|
||||
private readonly friendshipRepository: Repository<Friendship>,
|
||||
) {}
|
||||
|
||||
async findOneByFourtyTwoId(fourtytwo_id: string) {
|
||||
console.log(`Find user with fourtytwo_id ${fourtytwo_id}`);
|
||||
if (!isNumberString(fourtytwo_id))
|
||||
throw new HttpException(`The requested user not found.`,HttpStatus.NOT_FOUND);
|
||||
const user = await this.userRepository.findOneBy({fourtyTwoId: fourtytwo_id});
|
||||
if (!user)
|
||||
{
|
||||
console.log(`The requested user not found.`);
|
||||
return null;
|
||||
}
|
||||
console.log(`The requested user found.`);
|
||||
return user;
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
if (!isNumberString(id))
|
||||
throw new HttpException(`The requested user not found.`,HttpStatus.NOT_FOUND);
|
||||
@@ -40,7 +54,8 @@ export class UsersService {
|
||||
}
|
||||
|
||||
async create(createUserDto: CreateUsersDto) {
|
||||
if (await this.userRepository.findOneBy({email: createUserDto.email}))
|
||||
console.log(`Create user with ${createUserDto}`);
|
||||
if (await this.userRepository.findOneBy({fourtyTwoId: createUserDto.fourtyTwoId}))
|
||||
throw new HttpException(`The user already exists.`,HttpStatus.CONFLICT);
|
||||
const user = this.userRepository.create(createUserDto);
|
||||
if (!user)
|
||||
|
||||
Reference in New Issue
Block a user