Merge branch 'master' into luke

This commit is contained in:
LuckyLaszlo
2023-01-11 13:14:25 +01:00
48 changed files with 25430 additions and 435 deletions

View File

@@ -9,6 +9,7 @@ import { AuthenticationModule } from './auth/42/authentication.module';
import { PassportModule } from '@nestjs/passport';
import { GameModule } from './game/game.module';
import { ChatGateway } from './chat/chat.gateway';
import { ChatModule } from './chat/chat.module';
@Module({
imports: [
@@ -30,12 +31,10 @@ import { ChatGateway } from './chat/chat.gateway';
//avec une classe pour le module
synchronize: true,
}),
ChatModule,
// GameModule,
],
controllers: [AppController],
providers: [
AppService,
ChatGateway,
],
providers: [AppService],
})
export class AppModule {}

View File

@@ -0,0 +1,105 @@
import { Controller, UseGuards, HttpException, HttpStatus, Get, Post, Body, Req, Res } from '@nestjs/common';
import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards';
import { ConnectedSocket } from '@nestjs/websockets';
import { ChatService } from './chat.service';
import { User } from 'src/users/entities/user.entity';
import { PartialUsersDto } from 'src/users/dto/partial-users.dto';
import { createRoomDto } from './dto/createRoom.dto';
import { joinRoomDto } from './dto/joinRoom.dto';
import { setCurrentRoomDto } from './dto/setCurrentRoom.dto';
@Controller('chat')
export class ChatController {
constructor(
private chatService: ChatService,
) {}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Get('myrooms')
async getMyRooms(@Req() req, @Res() res): Promise<object>
{
console.log("- in getMyRooms controller");
const rooms = await this.chatService.getMyRooms(req.user);
console.log("- out getMyRooms controller");
return res.status(HttpStatus.OK).json({ rooms: rooms });
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Get('allrooms')
async getAllRooms(@Req() req, @Res() res): Promise<object>
{
console.log("- in getAllRooms controller");
const rooms = await this.chatService.getAllNotMyRooms(req.user);
console.log("- out getAllRooms controller");
return res.status(HttpStatus.OK).json({ rooms: rooms });
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Get('current')
async setCurrentRoom(@Body() setCurrentRoomDto: setCurrentRoomDto, @Req() req, @Res() res): Promise<object>
{
console.log("- in setCurrentRoom controller");
const response = await this.chatService.setCurrentRoom(req.user, setCurrentRoomDto.name);
console.log("- out setCurrentRoom controller");
return res.status(HttpStatus.OK).json({ message: response });
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Post('create')
async createRoom(@Body() createRoomDto: createRoomDto, @Req() req, @Res() res): Promise<object>
{
console.log("- in createRoom controller");
const response = await this.chatService.addUserToNewRoom(req.user, createRoomDto);
console.log("- out createRoom controller");
return res.status(HttpStatus.OK).json({ room_name: createRoomDto.room_name, message: response });
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Post('join')
async joinRoom(@Body() joinRoomDto: joinRoomDto, @Req() req, @Res() res): Promise<object>
{
console.log("- in joinRoom controller");
const response = await this.chatService.addUserToRoom(req.user, joinRoomDto);
console.log("- out joinRoom controller");
return res.status(HttpStatus.OK).json({ room_name: joinRoomDto.room_name, message: response });
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Post('change')
async changeRoom(@Body() joinRoomDto: joinRoomDto, @Req() req, @Res() res): Promise<object>
{
console.log("- in changeRoom controller");
const response = await this.chatService.setCurrentRoom(req.user, joinRoomDto.room_name);
console.log("- out changeRoom controller");
return res.status(HttpStatus.OK).json({ room_name: joinRoomDto.room_name, message: response });
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Post('leave')
async leaveRoom(@Body() body)
{
console.log("- in leaveRoom controller");
console.log("- out leaveRoom controller");
}
@UseGuards(AuthenticateGuard)
@UseGuards(TwoFactorGuard)
@Get('messages')
async getMessages(@Req() req, @Res() res): Promise<object>
{
console.log("- in getMessages controller");
const messages = await this.chatService.getMessagesFromCurrentRoom(req.user);
console.log("- out getMessages controller");
return res.status(HttpStatus.OK).json({ messages: messages });
}
}

View File

@@ -1,13 +1,7 @@
import {
WebSocketGateway,
SubscribeMessage,
WebSocketServer,
MessageBody,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { WebSocketGateway, SubscribeMessage, WebSocketServer, MessageBody, ConnectedSocket, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { UsersService } from 'src/users/users.service';
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
import { ChatService } from './chat.service';
@WebSocketGateway(5000, {
path: '/chat',
@@ -19,26 +13,43 @@ export class ChatGateway
constructor
(
private usersService: UsersService,
private chatService: ChatService,
) {}
@WebSocketServer()
server;
// how to guard the handleConnection ?
// https://github.com/nestjs/nest/issues/882
async handleConnection(client) {
// const paginationQuery = new PaginationQueryDto();
// const users = await this.usersService.findAll(paginationQuery);
console.log('- Client connected :', client.id, client.handshake.query.username);
client.username = client.handshake.query.username;
}
async handleDisconnect(client) {
console.log('- Client disconnected :', client.id, client.username);
}
// const users = await this.usersService.findAll(client);
// const users = await this.usersService.findAll(client);
console.log('---- Client connected :', client.id);
// console.log('users :', users);
@SubscribeMessage('join')
async joinRoom(@ConnectedSocket() socket, @MessageBody() room_name: string): Promise<void>
{
console.log('- in joinRoom gateway');
socket.leave(socket.room);
socket.join(room_name);
socket.room = room_name;
console.log('- out joinRoom gateway');
}
handleDisconnect(client) {
console.log('---- client disconnected :', client.id);
@SubscribeMessage('message')
async handleMessage(@ConnectedSocket() socket, @MessageBody() message: string): Promise<void>
{
console.log('- in handleMessage gateway');
//let room_name = await this.chatService.getCurrentRoom(socket.username);
socket.to(socket.room).emit('message', socket.username, message);
this.chatService.addMessageToCurrentRoom(socket.username, message);
console.log('- out handleMessage gateway');
}
/*
*/
}

View File

@@ -0,0 +1,28 @@
import { Module } from '@nestjs/common';
import { ChatController } from './chat.controller';
import { ChatService } from './chat.service';
import { ChatGateway } from './chat.gateway';
import { UsersModule } from 'src/users/users.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Chatroom } from './entities/chatroom.entity';
import { User } from 'src/users/entities/user.entity';
@Module({
imports: [
TypeOrmModule.forFeature([Chatroom, User]),
UsersModule,
],
controllers: [
ChatController,
],
exports: [
],
providers: [
ChatService,
ChatGateway,
],
})
export class ChatModule {}

View File

@@ -0,0 +1,219 @@
import { HttpException, HttpStatus, Injectable, Res } from '@nestjs/common';
import { User } from 'src/users/entities/user.entity';
import { UsersService } from 'src/users/users.service';
import { Chatroom } from './entities/chatroom.entity';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { createRoomDto } from './dto/createRoom.dto';
import { joinRoomDto } from './dto/joinRoom.dto';
import { messagesDto } from './dto/messages.dto';
@Injectable()
export class ChatService {
constructor(
private usersService: UsersService,
@InjectRepository(User)
private readonly userRepository: Repository<User>,
@InjectRepository(Chatroom)
private readonly chatroomRepository: Repository<Chatroom>,
) { }
// temp for test
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/* GETTERS ************************************************
*/
async getMyRooms(user: User)
{
console.log("-- in getMyRooms service");
const rooms = await this.chatroomRepository
.createQueryBuilder('chatroom')
.where('chatroom.users LIKE :user_name', { user_name: `%${user.username}%` })
.getMany();
console.log("-- out getMyRooms service");
return rooms;
}
async getAllRooms()
{
console.log("-- in getAllRooms service");
const rooms = await this.chatroomRepository
.createQueryBuilder('chatroom')
.getMany();
console.log("-- out getAllRooms service");
return rooms;
}
async getAllNotMyRooms(user: User)
{
console.log("-- in getAllNotMyRooms service");
const user_db = await this.getUserByName(user.username);
//const user_db = await this.usersService.findOne(user.username);
const rooms = await this.chatroomRepository
.createQueryBuilder('chatroom')
.where('chatroom.type != :type', { type: 'private' })
.andWhere('chatroom.users NOT LIKE :user_name', { user_name: `%${user.username}%` })
.getMany();
//const users = await this.getAllUsers();
//let allRooms = [...rooms, ...users];
console.log("-- out getAllNotMyRooms service");
return rooms;
}
async getMessagesFromCurrentRoom(user: User)
{
console.log("-- in getMessagesFromCurrentRoom service");
const user_db = await this.getUserByName(user.username);
//const user_db = await this.usersService.findOne(user.username);
const currentRoom = await this.getRoomByName(user_db.currentRoom);
console.log("-- out getMessagesFromCurrentRoom service");
return currentRoom.messages;
}
async getCurrentRoom(username: string)
{
console.log("-- in getCurrentRoom service");
const user_db = await this.getUserByName(username);
//const user_db = await this.usersService.findOne(username);
console.log("-- out getCurrentRoom service");
return user_db.currentRoom;
}
async getRoomByName(name: string)
{
console.log("-- in getRoomByName service");
const room = await this.chatroomRepository
.createQueryBuilder('chatroom')
.where('chatroom.name = :name', { name: name })
.getOne();
console.log("-- out getRoomByName service");
return room;
}
async getRoomById(id: number)
{
console.log("-- in getRoomById service");
const room = await this.chatroomRepository
.createQueryBuilder('chatroom')
.where('chatroom.id = :id', { id: id })
.getOne();
console.log("-- out getRoomById service");
return room;
}
/* SETTERS ************************************************
*/
async setCurrentRoom(user: User, name: string)
{
console.log("-- in setCurrentRoom service");
const user_db = await this.getUserByName(user.username);
//const user_db = await this.usersService.findOne(user.username);
user_db.currentRoom = name;
this.userRepository.save(user_db);
console.log("-- out setCurrentRoom service");
return `room "${name}" is now current room`;
}
/* ADDERS *************************************************
*/
async addUserToNewRoom(user: User, createRoomDto: createRoomDto)
{
console.log("-- in addUserToRoom service");
const room = await this.getRoomByName(createRoomDto.room_name);
if (room)
throw new HttpException(`This room already exist`, HttpStatus.CONFLICT);
// create chatroom
const newChatroom = new Chatroom();
newChatroom.name = createRoomDto.room_name;
newChatroom.type = createRoomDto.room_type;
newChatroom.owner = user.username;
newChatroom.users = [user.username];
newChatroom.messages = [{ name: "SERVER", message: `creation of room ${createRoomDto.room_name}` }];
this.chatroomRepository.save(newChatroom);
console.log("-- out addUserToRoom service");
return "successfull room creation";
}
async addUserToRoom(user: User, joinRoomDto: joinRoomDto)
{
console.log("-- in addUserToRoom service");
const room = await this.getRoomByName(joinRoomDto.room_name);
if (room.users.includes(user.username))
throw new HttpException(`your have already join this room`, HttpStatus.CONFLICT);
// update room with new user
room.users.push(user.username);
this.chatroomRepository.save(room);
const rooms = await this.getMyRooms(user);
const allRooms = await this.getAllRooms();
console.log("-- out addUserToRoom service");
return "successfull joining room";
}
async addMessageToCurrentRoom(username: string, message: string)
{
console.log("-- in addMessageToCurrentRoom service");
const user_db = await this.getUserByName(username);
//const user_db = await this.usersService.findOne(username);
const currentRoom = await this.getRoomByName(user_db.currentRoom);
let chat_message = {
name: username,
message: message,
};
currentRoom.messages.push(chat_message);
this.chatroomRepository.save(currentRoom);
console.log("-- out addMessageToCurrentRoom service");
}
/* REMOVERS ***********************************************
*/
async removeUserFromRoom(user: User, room_name: string)
{
console.log("-- in removeUserFromRoom service");
// get room
// remove user
}
/* SEARCH IN USER *****************************************
*/
async getUserByName(name: string)
{
console.log("-- in getUserByName service");
const user = await this.userRepository
.createQueryBuilder('user')
.where('user.username = :name', { name: name })
.getOne();
console.log("-- out getUserByName service");
return user;
}
}

View File

@@ -0,0 +1,18 @@
import { IsBoolean, IsEmpty, IsInt, IsNotEmpty, IsNumber, IsString, IsOptional } from "class-validator";
import { IsNull } from "typeorm";
export class createRoomDto
{
@IsString()
@IsNotEmpty()
room_name: string;
@IsString()
@IsNotEmpty()
room_type: 'public' | 'private' | 'direct';
@IsString()
@IsOptional()
room_password: string;
}

View File

@@ -0,0 +1,10 @@
import { IsBoolean, IsEmpty, IsInt, IsNotEmpty, IsNumber, IsString, IsOptional } from "class-validator";
import { IsNull } from "typeorm";
export class joinRoomDto
{
@IsString()
@IsNotEmpty()
room_name: string;
}

View File

@@ -0,0 +1,9 @@
import { IsBoolean, IsEmpty, IsInt, IsNotEmpty, IsNumber, IsString, IsOptional, IsArray } from "class-validator";
import { IsNull } from "typeorm";
export class messagesDto
{
@IsArray()
messages: { name: string; message: string }[];
}

View File

@@ -0,0 +1,10 @@
import { IsBoolean, IsEmpty, IsInt, IsNotEmpty, IsNumber, IsString, IsOptional } from "class-validator";
import { IsNull } from "typeorm";
export class setCurrentRoomDto
{
@IsString()
@IsNotEmpty()
name: string;
}

View File

@@ -0,0 +1,38 @@
import {
Entity,
Column,
ManyToOne,
ManyToMany,
JoinTable,
PrimaryGeneratedColumn
} from "typeorm";
import { User } from 'src/users/entities/user.entity';
@Entity('chatroom')
export class Chatroom {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
type: string;
// @ManyToOne(type => User, user => user.ownedRooms)
// owner: User;
//
// @ManyToMany(type => User)
// @JoinTable()
// users: User[];
@Column()
owner: string; // name
@Column("simple-array")
users: string[]; // names
@Column("json")
messages: { name: string, message: string }[];
}

View File

@@ -254,7 +254,6 @@ export class FriendshipService {
// const friendship = await this.friendshipRepository.findOneBy({ sender: creator, receiver: receiver });
const friendship = await this.friendshipRepository
.createQueryBuilder('friendship')
.leftJoinAndSelect('friendship.sender', 'sender')
@@ -459,4 +458,4 @@ export class FriendshipService {
console.log('we are not blocked in friendship service')
return false;
}
}
}

View File

@@ -52,4 +52,9 @@ export class User {
@JoinColumn()
@OneToOne(() => UserStats, { cascade: true })
stats: UserStats;
// ROOMS :
@Column({ nullable: true })
currentRoom: string; // chatroom name
}

View File

@@ -45,6 +45,7 @@ export class UsersService {
isEnabledTwoFactorAuth: user.isEnabledTwoFactorAuth,
status: user.status,
stats: user.stats,
currentRoom: user.currentRoom,
};
console.log(`Returned Partial User.` + partialUser.username + user.username);
return partialUser;