diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 48e341a0..00000000 --- a/package-lock.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "lockfileVersion": 1 -} diff --git a/srcs/requirements/nestjs/api_back/src/chat/chat.controller.ts b/srcs/requirements/nestjs/api_back/src/chat/chat.controller.ts index a2570d8d..d3a4eedb 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/chat.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/chat.controller.ts @@ -1,15 +1,14 @@ import { Controller, UseGuards, HttpException, HttpStatus, Get, Post, Delete, 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 { roomDto } from './dto/room.dto'; -import { setCurrentRoomDto } from './dto/setCurrentRoom.dto'; import { ChatGateway } from './chat.gateway'; -import { socketDto } from './dto/socket.dto'; import { Chatroom } from './entities/chatroom.entity'; +import { socketDto } from './dto/socket.dto'; +import { roomDto } from './dto/room.dto'; import { printCaller } from './dev/dev_utils'; +import { setCurrentRoomDto } from './dto/setCurrentRoom.dto'; +import { muteDto } from './dto/mute.dto'; @Controller('chat') export class ChatController { @@ -32,6 +31,7 @@ export class ChatController { new_room.users = room.users; if (room.allowed) new_room.allowed = room.allowed; + return new_room; } @@ -52,18 +52,34 @@ export class ChatController { let fields = ["name", "type", "users", "protection", "allowed_users"]; const rooms = await this.chatService.getMyRooms(req.user.username, fields); + const blocked = await this.chatService.getListBlockUser(req.user.username); - rooms.forEach(room => { + let filtered_rooms = rooms.filter(room => + { + if (room.type === 'direct') + { + let roomname = room.users[0]; + if (roomname === req.user.username) + roomname = room.users[1]; + if (blocked.includes(roomname)) + return false; + } + return true; + }); + + const ret_rooms = filtered_rooms.map(room => + { + let new_room = this.format_room(room); if (room.protection) { if (room.allowed_users.includes(req.user.username)) - room.allowed = true; + new_room.allowed = true; else - room.allowed = false; + new_room.allowed = false; } + return new_room; }); - const ret_rooms = rooms.map(room => this.format_room(room)); res.status(HttpStatus.OK).json({ rooms: ret_rooms }); printCaller("- out "); } @@ -76,12 +92,59 @@ export class ChatController { printCaller("- in "); const rooms: roomDto[] = await this.chatService.getAllOtherRoomsAndUsers(req.user.username) + const blocked = await this.chatService.getListBlockUser(req.user.username); - const ret_rooms = rooms.map(room => this.format_room(room)); + let filtered_rooms = rooms.filter(room => + { + if (room.type === 'user') + { + if (blocked.includes(room.name)) + return false; + } + return true; + }); + + const ret_rooms = filtered_rooms.map(room => this.format_room(room)); res.status(HttpStatus.OK).json({ rooms: ret_rooms }); printCaller("- out "); } + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Post('setadmin') + async setAdmin(@Body('username') username: string, @Req() req, @Res() res): Promise + { + printCaller("- in "); + + const current_room_name = await this.chatService.getCurrentRoomName(req.user.username); + await this.chatService.setAdmin(req.user.username, username, current_room_name); + + let message = `${username} is now admin`; + await this.chatService.addMessageToRoom(current_room_name, "SERVER", message); + let socket: socketDto = this.chatGateway.sockets.get(req.user.username); + let server = this.chatGateway.server; + await server.in(socket.room).emit('message', "SERVER", message); + + res.status(HttpStatus.OK).json({ message: `${username} is now admin in room ${current_room_name}` }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Get('isadmin') + async isAdmin(@Req() req, @Res() res): Promise + { + printCaller("- in "); + + const room_name = await this.chatService.getCurrentRoomName(req.user.username); + const fields = ["admins"]; + const room_db = await this.chatService.getRoomByName(room_name, fields); + const is_admin = room_db.admins.includes(req.user.username); + + res.status(HttpStatus.OK).json({ condition: is_admin }); + printCaller("- out "); + } + @UseGuards(AuthenticateGuard) @UseGuards(TwoFactorGuard) @Get('current') @@ -162,6 +225,19 @@ export class ChatController { let response = ""; if (room.type === 'user') { + const blocked = await this.chatService.getListBlockUser(req.user.username); + if (blocked.includes(room.name)) + { + console.log("throw error: error: true, code: 'BLOCKED_USER', message: 'you cannot enter this room, you blocked this user'"); + throw new HttpException({ error: true, code: 'BLOCKED_USER', message: `you cannot enter this room, you blocked this user` }, HttpStatus.UNAUTHORIZED); + } + + const find_room = await this.chatService.getRoomByName(`${req.user.username} + ${room.name}`); + if (find_room) + { + console.log("throw error: error: true, code: 'ROOM_CONFLICT', message: 'This room name already exist'"); + throw new HttpException({ error: true, code: 'ROOM_CONFLICT', message: `This room name already exist` }, HttpStatus.CONFLICT); + } room.type = 'direct'; room.users = [room.name, req.user.username]; room.name += ` + ${req.user.username}`; @@ -205,7 +281,7 @@ export class ChatController { { printCaller("- in "); - let fields = ["protection", "allowed_users"]; + let fields = ["protection", "allowed_users", "type", "users"]; const room_db = await this.chatService.getRoomByName(room.name, fields); if (room_db.protection === true) @@ -217,6 +293,19 @@ export class ChatController { } } + const blocked = await this.chatService.getListBlockUser(req.user.username); + if (room_db.type === 'direct') + { + let roomname = room_db.users[0]; + if (roomname === req.user.username) + roomname = room.users[1]; + if (blocked.includes(roomname)) + { + console.log("throw error: error: true, code: 'BLOCKED_USER', message: 'you cannot enter this room, you blocked this user'"); + throw new HttpException({ error: true, code: 'BLOCKED_USER', message: `you cannot enter this room, you blocked this user` }, HttpStatus.UNAUTHORIZED); + } + } + await this.chatService.setCurrentRoom(req.user.username, room.name); let socket: socketDto = this.chatGateway.sockets.get(req.user.username); await this.chatService.socketChangeRoom(socket, room.name); @@ -266,6 +355,7 @@ export class ChatController { // inform other connected users let socket: socketDto = this.chatGateway.sockets.get(req.user.username); await socket.to(socket.room).emit('message', "SERVER", message); + await socket.to(socket.room).emit('new_password'); const ret_room = this.format_room(room); res.status(HttpStatus.OK).json({ room: ret_room }); @@ -287,6 +377,7 @@ export class ChatController { // inform other connected users let socket: socketDto = this.chatGateway.sockets.get(req.user.username); await socket.to(socket.room).emit('message', "SERVER", message); + await socket.to(socket.room).emit('new_password'); const ret_room = this.format_room(room); res.status(HttpStatus.OK).json({ room: ret_room }); @@ -321,6 +412,14 @@ export class ChatController { { printCaller("- in "); + + const blocked = await this.chatService.getListBlockUser(req.user.username); + if (blocked.includes(username)) + { + console.log("throw error: error: true, code: 'BLOCKED_USER', message: 'you cannot invite this user, you have blocked it'"); + throw new HttpException({ error: true, code: 'BLOCKED_USER', message: `you cannot invite this user, you have blocked it` }, HttpStatus.UNAUTHORIZED); + } + let current_room_name = await this.chatService.getCurrentRoomName(req.user.username); let room = await this.chatService.addUserToRoom(username, current_room_name); let message = `${username} joined the room`; @@ -363,7 +462,17 @@ export class ChatController { printCaller("- in "); const messages = await this.chatService.getMessagesFromCurrentRoom(req.user.username); - res.status(HttpStatus.OK).json({ messages: messages }); + + console.log("messages:", messages); + const blocked = await this.chatService.getListBlockUser(req.user.username); + let filtered_messages = messages.filter(message => + { + if (blocked.includes(message.name)) + return false; + return true; + }); + + res.status(HttpStatus.OK).json({ messages: filtered_messages }); printCaller("- out "); } @@ -377,14 +486,32 @@ export class ChatController { const room_name = await this.chatService.getCurrentRoomName(req.user.username); const room = await this.chatService.getRoomByName(room_name); const users = room.users; + const admins = room.admins; + const blocked = await this.chatService.getListBlockUser(req.user.username); let index = users.indexOf(req.user.username); if (index > -1) - { users.splice(index, 1); - } - res.status(HttpStatus.OK).json({ users: users }); + let ret_users = users.map(username => + { + let new_user = + { + name: username, + isadmin: false, + isblocked: false, + }; + if (admins.includes(username)) + new_user.isadmin = true; + if (blocked.includes(username)) + new_user.isblocked = true; + console.log("new_user:", new_user); + + return new_user; + }); + console.log("ret_user:", ret_users); + + res.status(HttpStatus.OK).json({ users: ret_users }); printCaller("- out "); } @@ -397,6 +524,137 @@ export class ChatController { const room_name = await this.chatService.getCurrentRoomName(req.user.username); const users = await this.chatService.getAllUsersNotInRoom(room_name); + + const blocked = await this.chatService.getListBlockUser(req.user.username); + let filtered_users = users.filter(user => + { + if (blocked.includes(user.username)) + return false; + return true; + }); + + res.status(HttpStatus.OK).json({ users: filtered_users }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Post('setmute') + async setMuteUser(@Body('mute') mute: muteDto, @Body('time') time: string, @Req() req, @Res() res): Promise + { + printCaller("- in "); + + const room_name = await this.chatService.getCurrentRoomName(req.user.username); + await this.chatService.addMute(req.user.username, room_name, mute); + + // inform other connected users + let message = `${req.user.username} has muted ${mute.name} untill ${time}`; + let socket: socketDto = this.chatGateway.sockets.get(req.user.username); + let server = this.chatGateway.server; + await this.chatService.addMessageToRoom(room_name, "SERVER", message); + await server.in(socket.room).emit('message', "SERVER", message); + + const room = await this.chatService.getRoomByName(room_name); + + res.status(HttpStatus.OK).json({ message: message }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Post('ismute') + async isuserMute(@Body('username') username: string, @Req() req, @Res() res): Promise + { + printCaller("- in "); + + const room_name = await this.chatService.getCurrentRoomName(req.user.username); + const current_room = await this.chatService.getRoomByName(room_name); + let mute = current_room.mutes.find(mute => mute.name === username); + console.log("mute:", mute); + console.log("username:", username); + + res.status(HttpStatus.OK).json({ mute: mute }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Post('unmute') + async unMute(@Body('username') username: string, @Req() req, @Res() res): Promise + { + printCaller("- in "); + + const room_name = await this.chatService.getCurrentRoomName(req.user.username); + + const fields = ["admins"]; + const room_db = await this.chatService.getRoomByName(room_name, fields); + const is_admin = room_db.admins.includes(req.user.username); + if (!is_admin) + { + console.log("throw error: error: true, code: 'UNMUTE_NEED_ADMIN', message: 'you cannot unmute a user if you are not admin in the room'"); + throw new HttpException({ error: true, code: 'UNMUTE_NEED_ADMIN', message: `you cannot unmute a user if you are not admin in the room` }, HttpStatus.UNAUTHORIZED); + } + + await this.chatService.removeMute(username, room_name); + + let message = `${req.user.username} has un-muted ${username}`; + let socket: socketDto = this.chatGateway.sockets.get(req.user.username); + let server = this.chatGateway.server; + await this.chatService.addMessageToRoom(room_name, "SERVER", message); + await server.in(socket.room).emit('message', "SERVER", message); + + res.status(HttpStatus.OK).json({ message: "successfull unmute" }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Post('block') + async blockUser(@Body('username') username: string, @Req() req, @Res() res): Promise + { + printCaller("- in "); + + await this.chatService.addBlockUser(req.user.username, username); + + let user_socket: socketDto = this.chatGateway.sockets.get(req.user.username); + user_socket.join(`${username}_not_emit`); + + res.status(HttpStatus.OK).json({ message: "successfull block" }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Post('unblock') + async unBlockUser(@Body('username') username: string, @Req() req, @Res() res): Promise + { + printCaller("- in "); + + await this.chatService.removeBlockUser(req.user.username, username); + let user_socket: socketDto = this.chatGateway.sockets.get(req.user.username); + user_socket.leave(`${username}_not_emit`); + + res.status(HttpStatus.OK).json({ message: "successfull unblock" }); + printCaller("- out "); + } + + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + @Get('listblock') + async listBlockUser(@Req() req, @Res() res): Promise + { + printCaller("- in "); + + let block_users = await this.chatService.getListBlockUser(req.user.username); + let users = block_users.map(user => + { + return { + name: user, + isadmin: false, + isblocked: true, + } + }); + res.status(HttpStatus.OK).json({ users: users }); printCaller("- out "); } diff --git a/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts b/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts index 1892ce4d..554366f5 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts @@ -2,6 +2,7 @@ import { WebSocketGateway, SubscribeMessage, WebSocketServer, MessageBody, Conne import { UsersService } from 'src/users/users.service'; import { ChatService } from './chat.service'; import { socketDto } from './dto/socket.dto'; +import { printCaller } from './dev/dev_utils'; @WebSocketGateway(5000, { path: '/chat', @@ -22,9 +23,24 @@ implements OnGatewayConnection, OnGatewayDisconnect server; async handleConnection(socket: socketDto) { - console.log('- socket connected :', socket.id, socket.handshake.query.username); + printCaller('- socket connected :', socket.id, socket.handshake.query.username); + socket.username = socket.handshake.query.username.toString(); this.sockets.set(socket.username, socket); + + printCaller("--- socket.username:", socket.username); + + let not_emit: string = `${socket.username}_not_emit`; + socket.join(not_emit); + let blocked = await this.chatService.getListBlockUser(socket.username); + blocked.forEach(user => + { + not_emit = `${user}_not_emit`; + socket.join(not_emit); + }); + + let current_room = await this.chatService.getCurrentRoomName(socket.username); + socket.join(current_room); } async handleDisconnect(socket: socketDto) { this.sockets.delete(socket.username); diff --git a/srcs/requirements/nestjs/api_back/src/chat/chat.module.ts b/srcs/requirements/nestjs/api_back/src/chat/chat.module.ts index 1ab18c9d..a35d3f0e 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/chat.module.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/chat.module.ts @@ -3,14 +3,17 @@ import { ChatController } from './chat.controller'; import { ChatService } from './chat.service'; import { ChatGateway } from './chat.gateway'; import { UsersModule } from 'src/users/users.module'; +import { FriendshipsModule } from 'src/friendship/friendships.module'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Chatroom } from './entities/chatroom.entity'; import { User } from 'src/users/entities/user.entity'; +import { Friendship } from 'src/friendship/entities/friendship.entity'; @Module({ imports: [ - TypeOrmModule.forFeature([Chatroom, User]), + TypeOrmModule.forFeature([Chatroom, User, Friendship]), UsersModule, + FriendshipsModule, ], controllers: [ ChatController, diff --git a/srcs/requirements/nestjs/api_back/src/chat/chat.service.ts b/srcs/requirements/nestjs/api_back/src/chat/chat.service.ts index e094920f..a97d9004 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/chat.service.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/chat.service.ts @@ -1,14 +1,18 @@ import { HttpException, HttpStatus, Injectable, Res } from '@nestjs/common'; import { User } from 'src/users/entities/user.entity'; -import { UsersService } from 'src/users/users.service'; +import { Friendship, FriendshipStatus } from 'src/friendship/entities/friendship.entity'; import { Chatroom } from './entities/chatroom.entity'; -import { Repository } from 'typeorm'; +import { UsersService } from 'src/users/users.service'; +import { FriendshipService } from 'src/friendship/friendship.service'; +import { SendableFriendship } from 'src/friendship/sendableFriendship'; +import { Repository, Brackets } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; import { roomDto } from './dto/room.dto'; import { messagesDto } from './dto/messages.dto'; import { socketDto } from './dto/socket.dto'; import * as bcrypt from 'bcrypt'; import { printCaller } from './dev/dev_utils'; +import { muteDto } from './dto/mute.dto'; @Injectable() @@ -16,10 +20,13 @@ export class ChatService { constructor( private usersService: UsersService, + private friendshipService: FriendshipService, @InjectRepository(User) private readonly userRepository: Repository, @InjectRepository(Chatroom) private readonly chatroomRepository: Repository, + @InjectRepository(Friendship) + private readonly friendshipRepository: Repository, ) {} // temp for test @@ -35,6 +42,8 @@ export class ChatService { { printCaller("-- in "); + //await this.sleep(1000); + const queryBuilder = this.chatroomRepository .createQueryBuilder('chatroom') .where('chatroom.users LIKE :user_name', { user_name: `%${username}%` }); @@ -202,8 +211,9 @@ export class ChatService { } room_db.allowed_users.push(username); - printCaller("-- out "); await this.chatroomRepository.save(room_db); + + printCaller("-- out "); } async setPassword(username: string, message: string, room: roomDto, old_password?: string): Promise @@ -216,14 +226,20 @@ export class ChatService { throw new HttpException({ error: true, code: 'DIRECT_PASSWORD_FORBIDDEN', message: `you cannot set a password in a direct message room` }, HttpStatus.FORBIDDEN); } - const current_room = await this.getRoomByName(room.name); + const room_db = await this.getRoomByName(room.name); + + if (!room_db.admins.includes(username)) + { + console.log("throw error: error: true, code: 'NO_ADMIN', message: 'only admins are allowed to set or modify password'"); + throw new HttpException({ error: true, code: 'NO_ADMIN', message: `only admins are allowed to set or modify password` }, HttpStatus.FORBIDDEN); + } if (!room.password) { console.log("throw error: error: true, code: 'NO_PASSWORD', message: 'this room has no password protection'"); throw new HttpException({ error: true, code: 'NO_PASSWORD', message: `this room has no password protection` }, HttpStatus.FORBIDDEN); } - if (current_room.protection) + if (room_db.protection) { if (room.protection && !old_password) { @@ -232,7 +248,13 @@ export class ChatService { } if (old_password) { - const is_match = await bcrypt.compare(old_password, current_room.hash); + const is_old_match = await bcrypt.compare(room.password, room_db.hash); + if (is_old_match) + { + printCaller(`throw error: error: true, code: 'SAME_PASSWORD', message: 'you provided the same password'`); + throw new HttpException({ error: true, code: 'SAME_PASSWORD', message: `you provided the same password` }, HttpStatus.BAD_REQUEST); + } + const is_match = await bcrypt.compare(old_password, room_db.hash); if (!is_match) { printCaller(`throw error: error: true, code: 'BAD_PASSWORD', message: 'you provided a bad password'`); @@ -248,18 +270,117 @@ export class ChatService { hash = await bcrypt.hash(password, saltOrRounds); // add password to chatroom - current_room.allowed_users = room.allowed_users; - current_room.protection = room.protection; + room_db.allowed_users = room.allowed_users; + room_db.protection = room.protection; if (room.protection) - current_room.hash = hash; + room_db.hash = hash; else - delete current_room.hash; - current_room.messages.push({ name: "SERVER", message: message }); - await this.chatroomRepository.save(current_room); + delete room_db.hash; + room_db.messages.push({ name: "SERVER", message: message }); + await this.chatroomRepository.save(room_db); printCaller("-- out "); } + async setAdmin(current_username: string, user_username: string, room_name: string): Promise + { + printCaller("-- in "); + + const room_db = await this.getRoomByName(room_name); + if (room_db.type === "direct") + { + printCaller(`throw error: error: true, code: 'NO_DIRECT_ADMIN', message: 'there are no admins in direct messages'`); + throw new HttpException({ error: true, code: 'NO_DIRECT_ADMIN', message: `there are no admins in direct messages` }, HttpStatus.UNAUTHORIZED); + } + if (!room_db.admins.includes(current_username)) + { + printCaller(`throw error: error: true, code: 'NOT_ADMIN', message: 'you cannot set someone else as admin, since you are not admin yourself'`); + throw new HttpException({ error: true, code: 'NOT_ADMIN', message: `you cannot set someone else as admin, since you are not admin yourself` }, HttpStatus.UNAUTHORIZED); + } + + room_db.admins.push(user_username); + await this.chatroomRepository.save(room_db); + + printCaller("-- out "); + } + + async findOneRelationshipByUsername(friendUsername : string, username : string) + { + printCaller("-- in "); + + const friendship = await this.friendshipRepository + .createQueryBuilder('friendship') + .leftJoinAndSelect('friendship.sender', 'sender') + .leftJoinAndSelect('friendship.receiver', 'receiver') + .where ( + new Brackets((qb) => { + qb.where ( + new Brackets((subAQb) => { + subAQb.where('sender.username = :username', {username : username}) + .andWhere('receiver.username = :friendUsername', {friendUsername : friendUsername}) + }) + ) + .orWhere ( + new Brackets((subBQb) => { + subBQb.where('sender.username = :friendUsername2', {friendUsername2 : friendUsername}) + .andWhere('receiver.username = :username2', {username2 : username}) + .andWhere('friendship.status != :status', {status : FriendshipStatus.BLOCKED}) + }) + ) + }), + ) + .getOne(); + + console.log("friendship:", friendship); + if (!friendship) + return null; + return new SendableFriendship(friendship); + + printCaller("-- out "); + } + + async addBlockUser(username: string, to_block_username: string): Promise + { + printCaller("-- in "); + + let user = await this.getUserByName(username); + let relation = await this.findOneRelationshipByUsername(to_block_username, username); + if (relation) + { + let blocked_friendship = await this.friendshipService.blockFriendship(relation.id, user); + } + else + { + const newFriendshipDto = {"receiverUsername": to_block_username, "status": FriendshipStatus.BLOCKED}; + await this.friendshipService.create(newFriendshipDto, user); + } + + printCaller("-- out "); + } + + async removeBlockUser(username: string, to_unblock_username: string): Promise + { + printCaller("-- in "); + + let user = await this.getUserByName(username); + let relation = await this.findOneRelationshipByUsername(to_unblock_username, username); + await this.friendshipService.removeFriendship(relation.id, user); + + printCaller("-- out "); + } + + async getListBlockUser(username: string): Promise + { + printCaller("-- in "); + + let user = await this.getUserByName(username); + let friends_users = await this.friendshipService.findAllBlockedFriends(user.id); + let users = friends_users.map(user => user.receiverUsername); + + printCaller("-- out "); + return users; + } + /* ADDERS ************************************************* */ @@ -280,6 +401,7 @@ export class ChatService { newChatroom.name = room.name; newChatroom.type = room.type; newChatroom.owner = username; + newChatroom.admins = [username]; newChatroom.users = room.users; newChatroom.allowed_users = []; newChatroom.protection = false; @@ -316,9 +438,42 @@ export class ChatService { message: message, }; my_room.messages.push(chat_message); + await this.chatroomRepository.save(my_room); + + printCaller("-- out "); + } + + async addMute(username: string, room_name: string, mute: muteDto): Promise + { + printCaller("-- in "); + + const room_db = await this.getRoomByName(room_name); + + if (!room_db.admins.includes(username)) + { + console.log("throw error: error: true, code: 'NO_ADMIN', message: 'only admins are allowed to set or modify mute time'"); + throw new HttpException({ error: true, code: 'NO_ADMIN', message: `only admins are allowed to set or modify mute time` }, HttpStatus.FORBIDDEN); + } + + if (!room_db.mutes) + room_db.mutes = [mute]; + else + { + let already_here = false; + room_db.mutes.forEach(mute_elem => + { + if (mute_elem.name === mute.name) + { + already_here = true; + mute_elem.date = mute.date; + } + }); + if (!already_here) + room_db.mutes.push(mute); + } + await this.chatroomRepository.save(room_db); printCaller("-- out "); - await this.chatroomRepository.save(my_room); } @@ -350,6 +505,21 @@ export class ChatService { return "successfully leaving room"; } + async removeMute(username: string, room_name: string): Promise + { + printCaller("-- in "); + + const room_db = await this.getRoomByName(room_name); + + let index = room_db.mutes.findIndex(mute => mute.name === username); + if (index > -1) + room_db.mutes.splice(index, 1); + + await this.chatroomRepository.save(room_db); + + printCaller("-- out "); + } + /* SEARCH IN USER ***************************************** */ @@ -416,8 +586,44 @@ export class ChatService { { printCaller("-- in "); - socket.to(socket.room).emit('message', socket.username, message); let room_name = await this.getCurrentRoomName(socket.username); + + const current_room = await this.getRoomByName(room_name); + + if (current_room.protection) + { + if (!current_room.allowed_users.includes(socket.username)) + { + socket.emit('message', "SERVER", "your message was not sent because you need to validate the password"); + return; + } + } + if (current_room.mutes) + { + let current_mute = current_room.mutes.find(mute => mute.name === socket.username); + if (current_mute) + { + let date_diff = 1; + if (current_mute.date) + { + const date_now = new Date(); + const date_mute = new Date(current_mute.date); + date_diff = date_mute.getTime() - date_now.getTime(); + } + if (date_diff > 0) + { + socket.emit('message', "SERVER", "your message was not sent because you are muted"); + return; + } + else + await this.removeMute(current_mute.name, room_name); + } + } + + console.log("socket rooms:", socket.rooms); + let socket_name = `${socket.username}_not_emit`; + console.log("socket_name:", socket_name); + await socket.to(socket.room).except(socket_name).emit('message', socket.username, message); await this.addMessageToRoom(room_name, socket.username, message); printCaller("-- out "); diff --git a/srcs/requirements/nestjs/api_back/src/chat/dev/dev_utils.ts b/srcs/requirements/nestjs/api_back/src/chat/dev/dev_utils.ts index 309c1e34..e3dc8ae0 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/dev/dev_utils.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/dev/dev_utils.ts @@ -1,4 +1,5 @@ -export function printCaller(prefix: string = "") { +export function printCaller(...prefix) +{ try { throw new Error(); @@ -8,6 +9,6 @@ export function printCaller(prefix: string = "") { Error.captureStackTrace(e); let stack = e.stack.split('\n'); let caller = stack[2].trim(); - console.log(prefix + ' ' + caller); + console.log(...prefix, caller); } } diff --git a/srcs/requirements/nestjs/api_back/src/chat/dto/mute.dto.ts b/srcs/requirements/nestjs/api_back/src/chat/dto/mute.dto.ts new file mode 100644 index 00000000..0dc917c4 --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/chat/dto/mute.dto.ts @@ -0,0 +1,14 @@ +import { IsNotEmpty, IsString, IsDate, IsOptional } from "class-validator"; + +export class muteDto +{ + @IsString() + @IsNotEmpty() + name: string; + + @IsDate() + @IsOptional() + date?: Date; +} + + diff --git a/srcs/requirements/nestjs/api_back/src/chat/dto/room.dto.ts b/srcs/requirements/nestjs/api_back/src/chat/dto/room.dto.ts index e3451468..61c6b174 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/dto/room.dto.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/dto/room.dto.ts @@ -31,6 +31,11 @@ export class roomDto @IsOptional() owner?: string; + @IsArray() + @IsString({ each: true }) + @IsOptional() + admins?: string[]; + @IsString() @IsOptional() client_name?: string; diff --git a/srcs/requirements/nestjs/api_back/src/chat/dto/socket.dto.ts b/srcs/requirements/nestjs/api_back/src/chat/dto/socket.dto.ts index abc5350e..089c02a0 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/dto/socket.dto.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/dto/socket.dto.ts @@ -8,6 +8,10 @@ export class socketDto extends Socket @IsString() room: string; + + @IsBoolean() + @IsOptional() + new_password?: boolean; } diff --git a/srcs/requirements/nestjs/api_back/src/chat/entities/chatroom.entity.ts b/srcs/requirements/nestjs/api_back/src/chat/entities/chatroom.entity.ts index 82522e1a..aaf8592f 100644 --- a/srcs/requirements/nestjs/api_back/src/chat/entities/chatroom.entity.ts +++ b/srcs/requirements/nestjs/api_back/src/chat/entities/chatroom.entity.ts @@ -1,8 +1,9 @@ -import { Entity, Column, ManyToOne, ManyToMany, JoinTable, PrimaryGeneratedColumn } from "typeorm"; +import { Entity, Column, CreateDateColumn, ManyToOne, ManyToMany, JoinTable, PrimaryGeneratedColumn } from "typeorm"; import { IsBoolean, IsEmpty, IsInt, IsIn, IsNotEmpty, IsNumber, IsArray, IsString, IsOptional, IsEnum } from "class-validator"; import { Exclude, Expose } from 'class-transformer'; import { User } from 'src/users/entities/user.entity'; import { messagesDto } from 'src/chat/dto/messages.dto'; +import { muteDto } from 'src/chat/dto/mute.dto'; @Entity('chatroom') export class Chatroom @@ -25,11 +26,6 @@ export class Chatroom @IsBoolean() protection: boolean = false; - @Column({ nullable: true }) - @IsBoolean() - @IsOptional() - allowed?: boolean; - @Column({ nullable: true }) @IsString() @IsOptional() @@ -38,6 +34,11 @@ export class Chatroom @Column() owner: string; // username + @Column("simple-array") + @IsArray() + @IsString({ each: true }) + admins: string[]; // username + @Column("simple-array") @IsArray() @IsString({ each: true }) @@ -50,5 +51,9 @@ export class Chatroom @Column("json") messages: messagesDto[]; + + @Column("json", { nullable: true }) + @IsOptional() + mutes?: muteDto[]; } diff --git a/srcs/requirements/nestjs/api_back/src/friendship/friendship.service.ts b/srcs/requirements/nestjs/api_back/src/friendship/friendship.service.ts index 1219c2ba..2a325e0b 100644 --- a/srcs/requirements/nestjs/api_back/src/friendship/friendship.service.ts +++ b/srcs/requirements/nestjs/api_back/src/friendship/friendship.service.ts @@ -310,7 +310,7 @@ export class FriendshipService { if (relation.receiver && relation.receiver.id === user.id) { // console.log('friendship.service blockFriendship trying to delete and recreate a friendship with block') // console.log({...relation}) - const newFriendshipDto = {"receiverUsername": relation.sender.username, "receiverId": relation.sender.id, "status": FriendshipStatus.BLOCKED}; + const newFriendshipDto = {"receiverUsername": relation.sender.username, "status": FriendshipStatus.BLOCKED}; await this.removeFriendship(relationshipId, user); return await this.create(newFriendshipDto, user); } else { 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 798b5253..9b2bc897 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 @@ -23,7 +23,7 @@ export class User { email: string; @Column() - image_url : string; + image_url: string; @Column({ nullable: true }) phone: string; diff --git a/srcs/requirements/svelte/api_front/public/global.css b/srcs/requirements/svelte/api_front/public/global.css index ef988c0e..151d0d36 100644 --- a/srcs/requirements/svelte/api_front/public/global.css +++ b/srcs/requirements/svelte/api_front/public/global.css @@ -13,8 +13,6 @@ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; /* tmp? */ background-color: #333; - display: flex; - flex-direction: column; } @font-face { diff --git a/srcs/requirements/svelte/api_front/src/App.svelte b/srcs/requirements/svelte/api_front/src/App.svelte index 01902ed6..dddbb5ac 100644 --- a/srcs/requirements/svelte/api_front/src/App.svelte +++ b/srcs/requirements/svelte/api_front/src/App.svelte @@ -2,6 +2,7 @@ import Router, { replace } from "svelte-spa-router"; import { primaryRoutes } from "./routes/primaryRoutes.js"; import { location } from 'svelte-spa-router'; + import Chat from './pieces/chat/Chat.svelte'; import Header from './pieces/Header.svelte'; const conditionsFailed = (event) => { @@ -17,6 +18,7 @@ {#if ($location !== '/')}
{/if} + diff --git a/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte b/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte index 9d538c88..337cb4a4 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte @@ -190,6 +190,7 @@ position: relative; width: 100%; height: 100%; + box-sizing: border-box; } #canvas_container { margin-top: 20px; diff --git a/srcs/requirements/svelte/api_front/src/pages/profile/ProfileDisplay.svelte b/srcs/requirements/svelte/api_front/src/pages/profile/ProfileDisplay.svelte index 0b537349..8553e32b 100644 --- a/srcs/requirements/svelte/api_front/src/pages/profile/ProfileDisplay.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/profile/ProfileDisplay.svelte @@ -15,19 +15,18 @@ - -
-
- {#if user} - - - {:else} -

Sorry

-
Failed to load current
- {/if} -
+
+ {#if user !== undefined} + + + {:else} +

Sorry

+
Failed to load current
+ {/if} +
+ diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_box_css.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_box_css.svelte index 95d575fc..625d6b1d 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_box_css.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_box_css.svelte @@ -6,7 +6,10 @@ + +
@@ -22,7 +25,8 @@ padding: 0px; width: auto; height: auto; - border: 1px solid black; + border: var(--lines_width) solid var(--lines_color); + background-color: var(--bg_color); z-index: 1; } @@ -34,6 +38,10 @@ */ + /* gobal variables styles + */ + + /* Hide scrollbar */ .chat_box :global(*) { @@ -67,6 +75,7 @@ .chat_box :global(.grid_box p) { padding: 10px; font-size: 15px; + color: var(--lines_color); } @@ -95,7 +104,7 @@ } .chat_box :global(.__show_if_only_child:only-child) { display: flex; - color: rgb(100, 100, 100); + color: var(--lines_light_color); } @@ -110,7 +119,7 @@ /* __border_top */ .chat_box :global(.__border_top) { - border-top: 1px solid black; + border-top: var(--lines_width) solid var(--lines_color); } @@ -122,7 +131,7 @@ .chat_box :global(.__check_change_next:checked ~ .__to_block), .chat_box :global(.__check_change_next:checked ~ .__to_block *) { pointer-events: none; - color: rgb(100, 100, 100); + color: var(--lines_light_color); } .chat_box :global(.__to_show) { display: none; diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_layouts.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_layouts.svelte index 55ae3216..bb8cbcd2 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_layouts.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Chat_layouts.svelte @@ -19,7 +19,6 @@ /* global variables */ - export let color; let room = ""; let admin = false; let layouts = ["home", "home"]; @@ -28,8 +27,6 @@ */ function set_layouts($layout) { - //console.log("layouts:", layouts); - //console.log("layout:", $layout); if ($layout.length === 0) layout.set(layouts[0]); else if ($layout === "close") @@ -40,13 +37,12 @@ layouts = [$layout, "home"]; else layouts = [$layout, layouts[0]]; - //console.log("- layouts:", layouts); } $: set_layouts($layout); - + {#if $layout === "home"} diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Element_button.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Element_button.svelte index bd5148b4..2e4d3173 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Element_button.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Element_button.svelte @@ -29,17 +29,6 @@ diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_create.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_create.svelte index 99030f01..51482f05 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_create.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_create.svelte @@ -3,7 +3,7 @@ import { msgs, layout, allowed_chars } from './Store_chat'; import { change_room, create_room } from './Request_rooms'; import { onMount } from 'svelte'; - import { FetchResponse } from './Types_chat'; + import type { FetchResponse } from './Types_chat'; import Button from './Element_button.svelte'; import Warning from './Element_warning.svelte'; diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_home.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_home.svelte index d2d2d6d4..eeb992fa 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_home.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_home.svelte @@ -2,6 +2,7 @@ import { layout, msgs, user, current_room } from './Store_chat'; import { change_room, get_room_messages, get_my_rooms } from './Request_rooms'; + import { to_print } from './Utils_chat'; import { onMount } from 'svelte'; import Button from './Element_button.svelte'; @@ -10,9 +11,9 @@ // go to clicked room async function go_to_room(room) { - console.log("inside go_to_room"); + to_print("inside go_to_room"); - console.log("room:", room); + to_print("room:", room); if (room.protection && !room.allowed) { await current_room.set(room); @@ -55,7 +56,7 @@

rooms are loading...

{:then rooms} {#each rooms as room} - {/each} diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_invite.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_invite.svelte index 10b86d4b..21e8e0f0 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_invite.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_invite.svelte @@ -2,6 +2,7 @@ import { layout, user, current_room } from './Store_chat'; import { get_all_users, invite_user } from './Request_rooms'; + import { to_print } from './Utils_chat'; import Button from './Element_button.svelte'; export let back = ""; @@ -11,7 +12,7 @@ // invite user in this room async function invite_this_user(username: string) { - console.log("inside invite_this_user"); + to_print("inside invite_this_user"); invite_user(username); layout.set("room"); diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_mute.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_mute.svelte index f9e7f31b..e83a13ae 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_mute.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_mute.svelte @@ -1,10 +1,80 @@ -
@@ -16,7 +86,7 @@ @@ -25,160 +95,168 @@ - -
-

mute this user for a time :

-
- - - -
- - - - - - -
- -
+ {#if show_error} + + {/if} + {#if is_mute === true } +

this user is mute untill {date_string}

+ + {:else} +
+

mute this user for a time :

+ + + +
+ + + + + + +
+ +
+ {/if}
diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_new.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_new.svelte index 8a845b5d..e44a4867 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_new.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_new.svelte @@ -2,6 +2,7 @@ import { layout, msgs, user, socket, current_room } from './Store_chat'; import { join_room, change_room, get_room_messages, get_all_rooms } from './Request_rooms'; + import { to_print } from './Utils_chat'; import Button from './Element_button.svelte'; export let back = ""; @@ -11,7 +12,7 @@ // join the room async function join_rooms(room) { - console.log("inside join_room"); + to_print("inside join_room"); const updated_room = await join_room(room); if (updated_room.protection) diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_password.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_password.svelte index d2d87f92..9848e7b2 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_password.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_password.svelte @@ -2,7 +2,8 @@ import { layout, current_room } from './Store_chat'; import { change_room, validate_password, change_password, add_password, remove_password } from './Request_rooms'; - import { FetchResponse } from './Types_chat'; + import type { FetchResponse } from './Types_chat'; + import { to_print } from './Utils_chat'; import Button from './Element_button.svelte'; import Warning from './Element_warning.svelte'; @@ -22,7 +23,7 @@ async function handleSubmit(evt) { - console.log("in handleSubmit"); + to_print("in handleSubmit"); let formIsValid = evt.target.checkValidity(); diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room.svelte index 49de63a7..caf1ef54 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room.svelte @@ -15,7 +15,6 @@ if (msg.length > 0) { socket.emit('message', msg); add_msg("me", msg); - console.log(msgs); } msg = ""; @@ -42,7 +41,7 @@ @@ -112,8 +111,11 @@ overflow-x: hidden; overflow-y: scroll; - background-color: white; - border: 1px solid black; + background-color: var(--chat_msg_bg_color); + border: var(--lines_width) solid var(--lines_color); + } + .grid_box .text_area { + color: var(--lines_color); } .grid_box .text_area:focus { height: auto; @@ -129,7 +131,8 @@ */ .grid_box .panel_msg { flex-direction: column-reverse; - border: 1px solid black; + border: var(--lines_width) solid var(--lines_color); + background-color: var(--chat_conv_bg_color); } .grid_box .msg_thread { width: 100%; diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room_set.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room_set.svelte index 07f1c1ae..7223478f 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room_set.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_room_set.svelte @@ -1,23 +1,30 @@ -
@@ -31,21 +43,15 @@

/ you have blocked no one /

- - + {#await users} +

list of users is loading...

+ {:then users} + {#each users as user} + + {/each} + {/await}
diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_user.svelte b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_user.svelte index b5abf6f3..4afc34aa 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_user.svelte +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Layout_user.svelte @@ -1,21 +1,60 @@ - @@ -28,7 +67,7 @@ @@ -39,29 +78,38 @@ {#if back === "room_set"} {/if}
+ {#if show_error} + + {/if}

user options :

- - - + {#if $settings_user.isblocked} + + {:else} + + {/if} - {#if back === "room_set"} - - {/if} diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Request_rooms.ts b/srcs/requirements/svelte/api_front/src/pieces/chat/Request_rooms.ts index 36b98d4c..2153c306 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Request_rooms.ts +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Request_rooms.ts @@ -1,15 +1,16 @@ import { msgs, user, layout, socket, current_room } from './Store_chat'; -import { Room, FetchResponse, FetchMethod } from './Types_chat'; +import type { Room, FetchResponse } from './Types_chat'; +import { FetchMethod, Mute, User } from './Types_chat'; +import { to_print } from './Utils_chat'; import { fetch_chat_request, set_client_name_on_room, fill_fetch_response } from './Request_utils'; export async function get_room_messages() { - console.log("in get_room_messages"); + to_print("in get_room_messages"); let response: FetchResponse = await fetch_chat_request('messages', FetchMethod.GET); const messages = response.messages; - if (messages === null) return; @@ -24,33 +25,33 @@ export async function get_room_messages() export async function create_room(room: Room) { - console.log("in create_room"); + to_print("in create_room"); -console.log("room sent to create:", room); + to_print("room sent to create:", room); let response: FetchResponse = await fetch_chat_request('create', FetchMethod.POST, room); -console.log("room returned from create:", response.room); + to_print("room returned from create:", response.room); return response; } export async function join_room(room: Room) { - console.log("in join_room"); + to_print("in join_room"); -console.log("room sent to join:", room); + to_print("room sent to join:", room); let response: FetchResponse = await fetch_chat_request('join', FetchMethod.POST, room); -console.log("room returned from join:", response.room); + to_print("room returned from join:", response.room); return response.room; } export async function change_room(room: Room) { - console.log("in change_room"); + to_print("in change_room"); -console.log("room sent to change:", room); + to_print("room sent to change:", room); let response: FetchResponse = await fetch_chat_request('change', FetchMethod.POST, room); -console.log("room returned from change:", response.room); + to_print("room returned from change:", response.room); await get_room_messages(); @@ -62,29 +63,29 @@ console.log("room returned from change:", response.room); export async function validate_password(room: Room) { - console.log("in validate_password"); + to_print("in validate_password"); -console.log("room sent to validate password:", room); + to_print("room sent to validate password:", room); let response: FetchResponse = await fetch_chat_request('passwordauth', FetchMethod.POST, room); -console.log("room returned from validate password:", response.room); + to_print("room returned from validate password:", response.room); return response; } export async function add_password(room: Room) { - console.log("in add_password"); + to_print("in add_password"); -console.log("room sent to add password:", room); + to_print("room sent to add password:", room); let response: FetchResponse = await fetch_chat_request('addpassword', FetchMethod.POST, room); -console.log("room returned from add password:", response.room); + to_print("room returned from add password:", response.room); return response; } export async function change_password(room: Room, old_password: string) { - console.log("in send_password"); + to_print("in send_password"); let request_body = { @@ -92,27 +93,27 @@ export async function change_password(room: Room, old_password: string) old_password: old_password, } -console.log("room sent to change password:", room); + to_print("room sent to change password:", room); let response: FetchResponse = await fetch_chat_request('changepassword', FetchMethod.POST, request_body); -console.log("room returned from change password:", response.room); + to_print("room returned from change password:", response.room); return response; } export async function remove_password(room: Room) { - console.log("in send_password"); + to_print("in send_password"); -console.log("room sent to remove password:", room); + to_print("room sent to remove password:", room); let response: FetchResponse = await fetch_chat_request('removepassword', FetchMethod.DELETE, room); -console.log("room returned from remove password:", response.room); + to_print("room returned from remove password:", response.room); return response; } export async function invite_user(user_name: string) { - console.log("in invite_user"); + to_print("in invite_user"); let response: FetchResponse = await fetch_chat_request('invite', FetchMethod.POST, {username: user_name}); @@ -121,7 +122,7 @@ export async function invite_user(user_name: string) export async function get_my_rooms() { - console.log("in get_my_rooms"); + to_print("in get_my_rooms"); let response: FetchResponse = await fetch_chat_request('myrooms', FetchMethod.GET); @@ -132,35 +133,119 @@ export async function get_my_rooms() export async function get_all_rooms() { - console.log("in get_all_rooms"); + to_print("in get_all_rooms"); let response: FetchResponse = await fetch_chat_request('allrooms', FetchMethod.GET); return response.rooms; } -export async function get_room_users() +export async function get_room_users(): Promise { - console.log("in get_room_users"); + to_print("in get_room_users"); let response: FetchResponse = await fetch_chat_request('roomusers', FetchMethod.GET); + to_print("response from get_room_users:", response); return response.users; } export async function get_all_users() { - console.log("in get_all_users"); + to_print("in get_all_users"); let response: FetchResponse = await fetch_chat_request('users', FetchMethod.GET); return response.users; } -export async function leave_room() +export async function leave_room(): Promise { - console.log("in leave_room"); + to_print("in leave_room"); let response: FetchResponse = await fetch_chat_request('leave', FetchMethod.DELETE); } +export async function make_admin(username): Promise +{ + to_print("in is_admin"); + + to_print("username sent to setadmin:", username); + let response: FetchResponse = await fetch_chat_request('setadmin', FetchMethod.POST, {username: username} ); + to_print("response from setadmin:", response); + + return response; +} + +export async function get_is_admin(): Promise +{ + to_print("in is_admin"); + + let response: FetchResponse = await fetch_chat_request('isadmin', FetchMethod.GET); + to_print("is_admin return:", response.condition); + + return response.condition; +} + +export async function set_mute(date_limit: Date, username: string, time: string): Promise +{ + to_print("in set_mute"); + + let body = + { + mute: + { + name: username, + date: date_limit, + }, + time: time, + } + + to_print("setmute send body:", body); + let response: FetchResponse = await fetch_chat_request('setmute', FetchMethod.POST, body ); + to_print("setmute return:", response); + + return response; +} + +export async function get_is_mute(username: string): Promise +{ + to_print("in get_is_mute"); + + let response: FetchResponse = await fetch_chat_request('ismute', FetchMethod.POST, {username: username} ); + to_print("ismute return:", response); + + return response.mute; +} + +export async function get_unmute(username: string): Promise +{ + to_print("in get_unmute"); + + await fetch_chat_request('unmute', FetchMethod.POST, {username: username} ); +} + +export async function set_block_user(username: string): Promise +{ + to_print("in set_block_user"); + + await fetch_chat_request('block', FetchMethod.POST, {username: username} ); +} + +export async function remove_block_user(username: string): Promise +{ + to_print("in set_block_user"); + + await fetch_chat_request('unblock', FetchMethod.POST, {username: username} ); +} + +export async function list_block_user(username: string): Promise +{ + to_print("in list_block_user"); + + let response = await fetch_chat_request('listblock', FetchMethod.GET); + to_print("response.users:", response.users); + + return response.users; +} + diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Request_utils.ts b/srcs/requirements/svelte/api_front/src/pieces/chat/Request_utils.ts index 4ef90b5b..b0d23986 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Request_utils.ts +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Request_utils.ts @@ -1,9 +1,10 @@ import { user } from './Store_chat'; -import { Room, FetchResponse, FetchInit, FetchMethod } from './Types_chat'; +import type { Room, FetchResponse, FetchInit, FetchMethod } from './Types_chat'; +import { to_print } from './Utils_chat'; export async function fetch_chat_request(route: string, fetchMethod: FetchMethod, param?: any) { - console.log("in fetch_chat_request"); + to_print("in fetch_chat_request"); let response: FetchResponse = { status: 0 }; @@ -35,7 +36,7 @@ export async function fetch_chat_request(route: string, fetchMethod: FetchMethod export function set_client_name_on_room(room: Room) { - console.log("in set_client_name_on_room"); + to_print("in set_client_name_on_room"); if (room.type === 'direct') { @@ -50,7 +51,7 @@ export function set_client_name_on_room(room: Room) export function fill_fetch_response(response: FetchResponse, data: any) { - console.log("in fill_fetch_response"); + to_print("in fill_fetch_response"); Object.keys(data).forEach(key => { diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Socket_chat.ts b/srcs/requirements/svelte/api_front/src/pieces/chat/Socket_chat.ts index 18d0a322..f658d1b5 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Socket_chat.ts +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Socket_chat.ts @@ -1,13 +1,16 @@ import io from 'socket.io-client'; -import { set_socket, set_user } from './Store_chat'; -import { user, msgs } from './Store_chat'; +import { user, msgs, layout, set_socket, set_user } from './Store_chat'; +import { to_print } from './Utils_chat'; const address = `http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}`; export async function init_socket() { + to_print("in init_socket"); + console.log("here"); const response = await fetch(`${address}/api/v2/user`); const response_data = await response.json(); + to_print("-- response_data:", response_data); set_user(response_data); @@ -19,6 +22,7 @@ export async function init_socket() username: response_data.username, }, }); + console.log("horo"); set_socket(socket); socket_states(socket); @@ -29,11 +33,17 @@ function socket_events(socket) { socket.on('message', function(from, message) { - console.log("received msg:", message, from); + to_print("received msg:", message, from); if (from === user.username) from = "me"; msgs.update(msgs => [...msgs, { name: from, message: message }]); }); + + socket.on('new_password', function() + { + to_print("notification new password"); + layout.set("password"); + }); } function socket_states(socket) diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Store_chat.ts b/srcs/requirements/svelte/api_front/src/pieces/chat/Store_chat.ts index 2b74f87c..4a653e54 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Store_chat.ts +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Store_chat.ts @@ -1,13 +1,12 @@ import { writable } from 'svelte/store'; -import { Room } from './Types_chat'; +import type { Room, Message, User } from './Types_chat'; -export let msgs = writable([]); +export let msgs = writable(); +export let my_rooms = writable(); +export let all_rooms = writable(); +export let current_room = writable(); +export let settings_user = writable(); export let layout = writable("close"); -export let current_room: Room = writable({ - name: "", - type: "", - protection: false, -}); export let user; export let socket; diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Types_chat.ts b/srcs/requirements/svelte/api_front/src/pieces/chat/Types_chat.ts index 82f5c419..a142fa64 100644 --- a/srcs/requirements/svelte/api_front/src/pieces/chat/Types_chat.ts +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Types_chat.ts @@ -8,13 +8,37 @@ export interface Room allowed?: boolean; } +export interface Mute +{ + name: string; + date: Date; +} + +export interface Message +{ + name: string; + message: string; +} + +export interface User +{ + name: string; + isadmin: boolean; + isblocked: boolean; +} + export interface FetchResponse { status: number; error?: boolean; code?: string; message?: string; + messages?: Message[]; + users?: User[]; room?: Room; + rooms?: Room[]; + condition?: boolean; + mute?: Mute; } export interface FetchInit diff --git a/srcs/requirements/svelte/api_front/src/pieces/chat/Utils_chat.ts b/srcs/requirements/svelte/api_front/src/pieces/chat/Utils_chat.ts new file mode 100644 index 00000000..986fdb9b --- /dev/null +++ b/srcs/requirements/svelte/api_front/src/pieces/chat/Utils_chat.ts @@ -0,0 +1,4 @@ +export function to_print(...args) +{ + console.log(...args); +}