# ft_trandandad ## SIMPLE BUGS - [ ] COOKIES-SET are on 127.0.0.1:3000 not 127.0.0.1:4200 After logon - [x] docker network === backend front database || simple - all ports are exposed ??? - [x] ~~Front-End with .env (Avoid hardcoding)~~ - [x] unique name ## IDs ```yaml lmj : 53993 dollar : 62532 ``` ## Notes - Chat log notes - Create a Room `/room` - add member to a room, `/room/{room_id}/add` - give admin right to a member `room/{room_id}/addadmin/` - send message (create a message and associate it with a room id) `/room/{room_id}/addmessage` - get last 20 messages (optional - persitancy) `room/{room_id}/messages` - mute a member `room/{room_id}/mutemember` - Create a message, (associated with a room) - ... ## Progress - [ ] User Account - [x] The user should be able to choose a unique name that will be displayed on the website. - [x] The user should be able to upload an avatar. If the user doesn’t upload an avatar, a default one must be set. - [x] The user should be able to enable two-factor authentication. For instance, Google Authenticator or sending a text message to their phone. - [x] The user should be able to add other users as friends and see their current status (online, offline, in a game, and so forth). - [x] add other users as friends - [ ] see their current status - [ ] Stats (such as: wins and losses, ladder level, achievements, and so forth) have to be displayed on the user profile. - [ ] Each user should have a Match History including 1v1 games, ladder, and any-thing else useful. Anyone who is logged in should be able to consult it. - [ ] Chat - [x] The user should be able to create channels (chat rooms) that can be either public, or private, or protected by a password. - [x] The user should be able to send direct messages to other users. - [x] The user should be able to block other users. This way, they will see no more messages from the account they blocked. - [x] The user who has created a new channel is automatically set as the channel owner until they leave it. - [ ] The channel owner can set a password required to access the channel, change it, and also remove it. - [ ] The channel owner is a channel administrator. They can set other users as administrators. - [ ] The administrators of a channel can ban or mute users for a limited time. - [x] The user should be able to invite other users to play a Pong game through the chat interface. - [x] The user should be able to access other players profiles through the chat interface. <!-- - [ ] Game - [ ] users should be able to play a live Pong game versus another player directly on the website. - [ ] There must be a matchmaking system: the user can join a queue until they get automatically matched with someone else. - [ ] You must offer some customization options (for example, power-ups or different maps). However, the user should be able to select a default version of the game without any extra features if they want to. - [ ] The game must be responsive! - [ ] The user should be able to watch a live play between other users without interfering with it. --> - game history - entity/user.entity -- model - /{userid}/history -- controller - /me - user.service / service - status - user.service, updateStatus(enum <...>) - ~~achievments~~ ### Bugs: - ui: - ~~global chat layout does not scroll horizontally when overflown, to reproduce send large paragraphs from [lipsum.com](https://lipsum.com/)~~ - ~~ditto for: room chat/friends-chat~~ - ~~global menu should show current active friends requests, currently it shows a place holder value == 2~~ - ~~room creation form should close on success~~ - ~~in the global chat, write a short message, notice the shape of the scrollbar~~ - the user menu in the global chat, has the same contrast with the background text - ~~add a spectate option the game menu~~ - add a spectate button the main page - ~~[global-chat] scroll to end when a new message is sent~~ - [global-chat] ignore empty messages - ~~apply game-ui patch~~ - api: - /api/chat/room/{id}/join : does not check if user is already a member - from the chat, long press (left click) a user avatar, then choose profile, clicking that button should open a modal with the info of that player, info = {username, match history, achievement, status} - ~~display a placeholder user profile in the meantime~~ - from the chat, long press (left click) a user avatar, then choose match history, clicking that button should open a modal with the match history for that player - design match history layout - display a placeholder for the player match history - render notification for a 1vs1 invite, with an actionable button to switch to that game - If a user first registers using github, then attempts to login using 42Intra, a 500 is thrown due to: ``` trans_db | 2022-12-24 14:07:49.750 UTC [36] ERROR: duplicate key value violates unique constraint "UQ_065d4d8f3b5adb4a08841eae3c8" trans_db | 2022-12-24 14:07:49.750 UTC [36] DETAIL: Key (name)=(hchandad) already exists. trans_db | 2022-12-24 14:07:49.750 UTC [36] STATEMENT: INSERT INTO "user"("id", "name", "email", "avatar", "wins", "losses", "lvl", "status", "twoFactor", "twoFactorAuthenticationSecret", "Pcolor") VALUES ($1, $2, $3, $4, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT) RETURNING "wins", "losses", "lvl", "status", "twoFactor", "Pcolor" trans | trans | /usr/src/app/src/driver/postgres/PostgresQueryRunner.ts:299 trans | throw new QueryFailedError(query, parameters, err) trans | ^ trans | QueryFailedError: duplicate key value violates unique constraint "UQ_065d4d8f3b5adb4a08841eae3c8" trans | at PostgresQueryRunner.query (/usr/src/app/src/driver/postgres/PostgresQueryRunner.ts:299:19) trans | at processTicksAndRejections (node:internal/process/task_queues:95:5) trans | at InsertQueryBuilder.execute (/usr/src/app/src/query-builder/InsertQueryBuilder.ts:163:33) trans | at SubjectExecutor.executeInsertOperations (/usr/src/app/src/persistence/SubjectExecutor.ts:428:42) trans | at SubjectExecutor.execute (/usr/src/app/src/persistence/SubjectExecutor.ts:137:9) trans | at EntityPersistExecutor.execute (/usr/src/app/src/persistence/EntityPersistExecutor.ts:197:21) trans | at UserService.addUserToDB (/usr/src/app/src/api/user/user.service.ts:110:5) trans | at UserService.createaccess (/usr/src/app/src/api/user/user.service.ts:58:32) ``` - solution: query by user email instead of id. - after applying the fix, this also creates a conflict, in which in multiple places the same user exists, querying by id cause's errors since then the user will not be found. ``` trans | /usr/src/app/src/api/user/user.service.ts:63 trans | const id = (await this.getUserByid(d.id)).id trans | ^ trans | TypeError: Cannot read properties of null (reading 'id') trans | at UserService.createaccess (/usr/src/app/src/api/user/user.service.ts:63:48) trans | at processTicksAndRejections (node:internal/process/task_queues:95:5) ``` - even then it still creates a conflict, since one may have a different emails, thus things that could raise a conflict are id's, usernames, and emails, which all need to be checked. (disable other providers) ### Security Issue ```javascript= async updateavatar(user: User, file: any): Promise<Boolean> { if(!user)throw new NotFoundException(`user not found`); console.log(file); const type = file.mimetype.split("/")[1]; console.log(type); fs.rename( file.path, file.destination + "/" + user.name + "." + type, (Error) => { //callback if error if (Error) throw Error; } ); user.avatar = process.env.UPLOAD_PATH + "/" + user.name + "." + type; this.repository.save(user); return true; } ``` - the line where you take `user.name` (fs.rename and user.avatar); it can lead to a LFI if the username was for example `../../../../../../../../../../../../etc/passwd%00`; so it will ignore the dot and the variable type. ### WIP - chat - leave channel (room) - invite for 1vs1 - roles actions - 1vs1 vs other players - watch live games - ui - 2fa check - center content - ui - friends-list hide -add friend/send message- - (minor) ui - add ui hint in friends-list of to indicate friends status - double check server side validation of all forms one last time - ensure rooms data persistance - global http error handler in client - ~~use a single docker compose file at project room~~