Skip to content

Conversation

@github-classroom
Copy link

@github-classroom github-classroom bot commented Aug 25, 2022

👋! GitHub Classroom created this pull request as a place for your teacher to leave feedback on your work. It will update automatically. Don’t close or merge this pull request, unless you’re instructed to do so by your teacher.
In this pull request, your teacher can leave comments and feedback on your code. Click the Subscribe button to be notified if that happens.
Click the Files changed or Commits tab to see all of the changes pushed to main since the assignment started. Your teacher can see this too.

Notes for teachers Use this PR to leave feedback. Here are some tips: - Click the **Files changed** tab to see all of the changes pushed to `main` since the assignment started. To leave comments on specific lines of code, put your cursor over a line of code and click the blue **+** (plus sign). To learn more about comments, read “[Commenting on a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request)”. - Click the **Commits** tab to see the commits pushed to `main`. Click a commit to see specific changes. - If you turned on autograding, then click the **Checks** tab to see the results. - This page is an overview. It shows commits, line comments, and general comments. You can leave a general comment below. For more information about this pull request, read “[Leaving assignment feedback in GitHub](https://docs.github.com/education/manage-coursework-with-github-classroom/leave-feedback-with-pull-requests)”.

Subscribed: @ureshiiYing @fantablack @Punpun1643 @dionegoh

github-classroom bot and others added 30 commits August 25, 2022 13:31
The project adopt airbnb coding standard.
Some customization has been added such as
4 spaces indentation and limit lines to
120 characters.
Add eslint to identify coding standard violations
ESLint rules ignore file extensions.
This causes the file to fail the lint check.

Update ESLint check to ignore .js file extensions so as to 
pass check.
ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.
* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

Co-authored-by: dionegoh <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: dionegoh <[email protected]>
The following features has been implemented for Milestone 1

On frontend:
- Add a `/login` and `/logout` page UI
- Add placeholder `Home` for matchmaking service

On backend:
- Ensure duplicate username during account creation
- Allow users to login of their account
- Allow users to logout of their account
- Authentication is done using jwt tokens and cookies
- Allow users to change passwords
- Ensured authorisation of users before being able to use certain APIs
* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
* Setup frontend UI for code editor (#92)

* [#93] Implement collaborative functionality of code editor 

* Establish socket connection

* Add collaborative functionality to code editor using socketio

* add console log to check

* Set up yjs and bind it to editor (#100)

* set up yjs and bind it to editor

* Remove previous UI implementation

* UI related updates

* Clean up code

* remove unused dependencies and backend

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
* npm init

* Implement skeleton of question service (No Functionality)

* Implement Question Service - Retrieve Qn by difficulty API (#104)

* Add API to retrieve a question based on difficulty

- Correct Typo "Diffficulty"

* Add randomness to question retrieval

- Additionally, implemented API to generate a new question that is not the same as current question

* [#113] Reflect question on room page

**Summary**
- sent a `GET` request  the question-service api by using `axios`
- retrieved `response.data` and passed it to the room page

* (#105) FR3.1 The system contains questions with easy, medium and hard difficulty levels

* Add API to retrieve a question based on difficulty

* Add randomness to question retrieval

* Additionally, implemented API to generate a new question that is not the same as current question

* Add questions to mongodb using json files

* Add and update 20 easy, medium, hard questions

Co-authored-by: fantablack <[email protected]>

* FR3.X UI for displaying questions #110

Summary:
- Add a separate component for question display
- Fix new line ("\n") not showing on UI
- Todo: Add a button component and its related UX flow for generating new questions

Co-authored-by: fantablack <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

Co-authored-by: fantablack <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`
* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug
* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

* [#126] Revamp frontend UI for sign up/ log in

* Improve abstraction and OOP

* Revamp signup frontend

* Implement responsive design

* Complete singup

* Refactor code for better abstraction

* Fix login UI

* Fix snackbar for login

* Update severity

* Fix success and error alerts

* Finalize frontend for login signup

* Fix error message

* Handle initial empty password

* Resolve merge conflict

* Merge UI updates into main (#124)

* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Add Prod DB URL (#137)

- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`

* [#125] Milestone 3: chat service

* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug

Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: fantablack <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

* [#129] Enhance matching-service UI

Improved UI for match selection page, room page and navbar

* [#129] Enhance matching-service UI

Improved UI for match selection page, room page and navbar

Co-Authored-By: Papattarada Apithanangsiri <[email protected]>

Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
* Add chat service back to room

* Resolve button in room page

* Change back border radius navbar

* Cypress file removed

* Fix navbar

* Fix options margin

* Change color inconsistency

* Fix all dialog boxes

* Fix minor bug from sending empty text

* Make scrollbar transparent

* Implement adjustable split screen

* Complete resizable split screen

* Add logo

* Add logo to navbar

* Add icon to login page

* Fix css overwrite
* [#21] Cypress E2E frontend testing for CI

* Setup cypress for frontend testing

* Setup script for CI

* Update gitignore

* Fix gitignore

* Test workflow for CI

* Update workflow

* Update workflow

* Update working directory

* Try remove eslint

* Change test

* Edit

* Update json

* Localhost

* Port

* Update

* Update

* Finish and pass CI

* Update CI

* CI stuff

* Test

* Retry

* Try again

* Update README.md

* Test again

* Solve ci

* Try change package lock

* Resolve package

* Change package again

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
* Implement History Service (#133)

- Add new `HistoryModel` schema to mongodb
- Add PUT API to save attempted question into user's history - will create a new record if there is no existing record for the user, otherwise update the records for the user
- Add GET API to retrieve user's list of attempted question

* Implement Home UI Updates (#156)

* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

* [#126] Revamp frontend UI for sign up/ log in

* Improve abstraction and OOP

* Revamp signup frontend

* Implement responsive design

* Complete singup

* Refactor code for better abstraction

* Fix login UI

* Fix snackbar for login

* Update severity

* Fix success and error alerts

* Finalize frontend for login signup

* Fix error message

* Handle initial empty password

* Resolve merge conflict

* Merge UI updates into main (#124)

* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Add Prod DB URL (#137)

- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`

* [#125] Milestone 3: chat service

* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug

* [#138] Improve UI for change password page

- Add a paper background
- Align center the form
- Update password error messages to: `should contain at least one number and one alphabet, and must be at least 8 characters`
- Change text field to variant`outlined`

* Add unstyled link

* Update home to difficulty link to button

* Align grind button and label

* Add history service URI URL to configs.js

* Add getAttemptedQuestions()

* Update history service port no. and update cors

* Implement fetching and display of attempted qns

* Update UI

* Update package-lock.json

* Add circular progress bar

* Align right circular progress

* Update start grind button to use navigate

Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>

* Resolve merge conflict

* [#21] Cypress E2E frontend testing for CI (#162)

* [#21] Cypress E2E frontend testing for CI

* Setup cypress for frontend testing

* Setup script for CI

* Update gitignore

* Fix gitignore

* Test workflow for CI

* Update workflow

* Update workflow

* Update working directory

* Try remove eslint

* Change test

* Edit

* Update json

* Localhost

* Port

* Update

* Update

* Finish and pass CI

* Update CI

* CI stuff

* Test

* Retry

* Try again

* Update README.md

* Test again

* Solve ci

* Try change package lock

* Resolve package

* Change package again

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Resolve button

* Resolve progress and button

* Complete homepage

Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: fantablack <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

* [#126] Revamp frontend UI for sign up/ log in

* Improve abstraction and OOP

* Revamp signup frontend

* Implement responsive design

* Complete singup

* Refactor code for better abstraction

* Fix login UI

* Fix snackbar for login

* Update severity

* Fix success and error alerts

* Finalize frontend for login signup

* Fix error message

* Handle initial empty password

* Resolve merge conflict

* Merge UI updates into main (#124)

* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Add Prod DB URL (#137)

- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`

* [#125] Milestone 3: chat service

* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug

* [#138] Improve UI for change password page

- Add a paper background
- Align center the form
- Update password error messages to: `should contain at least one number and one alphabet, and must be at least 8 characters`
- Change text field to variant`outlined`

* [#164] Update FE / to point to home by default

* Change frontend to align with the rest

Co-authored-by: fantablack <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* npm init

* Implement skeleton of question service (No Functionality)

* Implement Question Service - Retrieve Qn by difficulty API (#104)

* Add API to retrieve a question based on difficulty

- Correct Typo "Diffficulty"

* Add randomness to question retrieval

- Additionally, implemented API to generate a new question that is not the same as current question

* [#113] Reflect question on room page

**Summary**
- sent a `GET` request  the question-service api by using `axios`
- retrieved `response.data` and passed it to the room page

* (#105) FR3.1 The system contains questions with easy, medium and hard difficulty levels

* Add API to retrieve a question based on difficulty

* Add randomness to question retrieval

* Additionally, implemented API to generate a new question that is not the same as current question

* Add questions to mongodb using json files

* Add and update 20 easy, medium, hard questions

Co-authored-by: fantablack <[email protected]>

* FR3.X UI for displaying questions #110

Summary:
- Add a separate component for question display
- Fix new line ("\n") not showing on UI
- Todo: Add a button component and its related UX flow for generating new questions

* Implement storing and displaying of pictures for questions (#131)

**Summary**
* Questions currently only consist of string data, which may not be sufficient as some questions require image examples to help the user better understand the question.
* Update Question Bank and Question Schema to support base64 encoded image data.
* Implement rendering of image data if it exists in `RoomPage.js` and `QuestionDisplay.js`.

* [#153] Update question bank with more images 

**Summary**
* Update questions across all easy, medium and hard questions with corresponding image if it exists

* [#142] refresh question


### Implemented functionality to refresh question in the room page 
- Frontend: added refresh icon and modal check for confirmation 
- Backend: handled socket.io logic (client emits `refresh-question` to indicate a refresh event and server emits `update-question` with the new question as an argument)

* [#142] refresh question

### Implemented functionality to refresh question in the room page 
- Frontend: added refresh icon and modal check for confirmation 
- Backend: handled socket.io logic (client emits `refresh-question` to indicate a refresh event and server emits `update-question` with the new question as an argument)

* Update UI to align with the rest

Co-authored-by: fantablack <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
* Implement History Service (#133)

- Add new `HistoryModel` schema to mongodb
- Add PUT API to save attempted question into user's history - will create a new record if there is no existing record for the user, otherwise update the records for the user
- Add GET API to retrieve user's list of attempted question

* Implement Home UI Updates (#156)

* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

* [#126] Revamp frontend UI for sign up/ log in

* Improve abstraction and OOP

* Revamp signup frontend

* Implement responsive design

* Complete singup

* Refactor code for better abstraction

* Fix login UI

* Fix snackbar for login

* Update severity

* Fix success and error alerts

* Finalize frontend for login signup

* Fix error message

* Handle initial empty password

* Resolve merge conflict

* Merge UI updates into main (#124)

* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Add Prod DB URL (#137)

- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`

* [#125] Milestone 3: chat service

* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug

* [#138] Improve UI for change password page

- Add a paper background
- Align center the form
- Update password error messages to: `should contain at least one number and one alphabet, and must be at least 8 characters`
- Change text field to variant`outlined`

* Add unstyled link

* Update home to difficulty link to button

* Align grind button and label

* Add history service URI URL to configs.js

* Add getAttemptedQuestions()

* Update history service port no. and update cors

* Implement fetching and display of attempted qns

* Update UI

* Update package-lock.json

* Add circular progress bar

* Align right circular progress

* Update start grind button to use navigate

Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>

* Resolve merge conflict

* [#21] Cypress E2E frontend testing for CI (#162)

* [#21] Cypress E2E frontend testing for CI

* Setup cypress for frontend testing

* Setup script for CI

* Update gitignore

* Fix gitignore

* Test workflow for CI

* Update workflow

* Update workflow

* Update working directory

* Try remove eslint

* Change test

* Edit

* Update json

* Localhost

* Port

* Update

* Update

* Finish and pass CI

* Update CI

* CI stuff

* Test

* Retry

* Try again

* Update README.md

* Test again

* Solve ci

* Try change package lock

* Resolve package

* Change package again

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Resolve button

* Resolve progress and button

* Complete homepage

* Implement population of attempted questions (#173)

Closes #157, Closes #172

**Summary**
* Implement population of attempted questions, namely 
   * On new match
   * On refresh question
* Fix edge case in the history API for getting a user record that doesn't exist yet

* [#168] Re-inject Attempted Difficulty cards with live data

* Re-inject Attempted Difficulty cards with live data

Co-authored-by: fantablack <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

* [#126] Revamp frontend UI for sign up/ log in

* Improve abstraction and OOP

* Revamp signup frontend

* Implement responsive design

* Complete singup

* Refactor code for better abstraction

* Fix login UI

* Fix snackbar for login

* Update severity

* Fix success and error alerts

* Finalize frontend for login signup

* Fix error message

* Handle initial empty password

* Resolve merge conflict

* Merge UI updates into main (#124)

* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Add Prod DB URL (#137)

- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`

* [#125] Milestone 3: chat service

* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug

* [#138] Improve UI for change password page

- Add a paper background
- Align center the form
- Update password error messages to: `should contain at least one number and one alphabet, and must be at least 8 characters`
- Change text field to variant`outlined`

* [#164] Update FE / to point to home by default

* Change frontend to align with the rest

* (#170) Fix multiple firings of auth endpoint

* Update each FE protected page to only fire ensureLoggedIn() once

Co-authored-by: fantablack <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
* Implement History Service (#133)

- Add new `HistoryModel` schema to mongodb
- Add PUT API to save attempted question into user's history - will create a new record if there is no existing record for the user, otherwise update the records for the user
- Add GET API to retrieve user's list of attempted question

* Implement Home UI Updates (#156)

* [#8] Password Hashing and Salting

Currently, passwords are stored in plain text.
This is an insecure way of storing passwords.
Password can be stored more securely by hashing it.

Implemented using bcrypt package.
This makes it more difficult for hackers to brute force users' passwords should the database be compromised.

Created services.js file to handle logic processing of users.
Implemented function to verify password when logging in.

Let's salt and hash passwords before storing in the database.

* Implement logic to ensure unique usernames during account creation (#34)

Currently, there is no mechanism to catch duplicate usernames, other than in the UserModel schema.
- Usernames should be unique to be able to identify the user, and users should be informed when account creation failed due to duplicate usernames
- Implement logic to check whether the username already exists in DB, and prevent account creation if it exists

* Implement Login and Logout (#23)

Fixes #22 

Summary
* Implement JWT creation upon successful login
* Add login route `/api/user/login`
* ~~This version of authentication is in development before the merge of PR #8 , hence authentication involves comparison of plaintext passwords~~
* Implement password comparison using bcrypt,  Closes #24 
* Fix bcrypt import typo in services.js
* Update invalid login error messages to be more specific. Closes #28 
* Implement refresh of tokens after expiry
* Implement logout of token. Closes #29 
* Abstract orm functions into _user-orm.js_ Closes #27 
* Add check for user existence in orm. Closes #31 

Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* [#58] Improve error handling for JWT verification functions

**Summary**
* Remove logging of handled error stacktrace
* Add error handling for failed refreshToken verification

Closes #58

* FR1.3 Create frontend UI for login #40

Summary:
- Created a login page component with similar UI as sign up page
- Linked login page to route at `/login`
- Connect to backend login with axios
- Errors are displayed using a snackbar positioned on top center
- Successful login are redirected to `/home` page temporary placeholder

* Implement storage of returned JWT in cookie for successful logins (#63)

**Summary**
* Successful logins return jwt tokens but they are not saved in a cookie
* Storage of jwt as a cookie is necessary for authorization requests
* In this PR, jwt token is stored as a _httpOnly_ cookie to prevent javascript from accessing it
* Additional notes: `app.use(cors())` in user-service/index.js has to be disabled for this feature to work. When we do `app.use(cors())`, all of the requests are allowed by default and because of which, the 'Access-Control-Allow-Origin' header is set to '*'. This leads to CORS issues as the front-end and user-service are on different origins. The conflict arising from '*' usage is due to the browser requiring additional credential arguments in the axios.post() call, otherwise it would not save cookies, and these additional credential arguments do not accept '*' in the 'Access-Control-Allow-Origin' header.

Co-authored-by: ureshiiYing <[email protected]>

* [#66] Implement UI and update backend for cookies for logout 

**Summary**
* Current logout operations in the backend do not interact with our token cookies that we set in the user's browser when they log in, and thus updates are needed to do so.
* Implement removal of our token cookies from the user's browser upon logout.
* Update logout function in backend to read target token from cookies instead of request body.
* Add skeleton UI destination page after logout is successful.
* Add home page UI as placeholder for matching-service.
* Implement logout button and logic to home page

Co-authored-by: ureshiiYing <[email protected]>

* FR 1.6 Change Password #38

Fixes #38 

Summary
- Users might want to change their password
- Implemented ability for users to change password through `POST /api/user/changePassword`
- Users need to provide their username, their current password, and the new password they would like to change to

* [#69] Implement Authorizations to backend and frontend API with cookies

**Summary**
* Implement protection of /logout route, both in frontend and backend
* Update protection to use cookies instead of authorization bearer token
* Sync cookie expiration time to that of their jwt token counterparts
* Implement redirection to login if token/cookie expired

Co-authored-by: ureshiiYing <[email protected]>

* Refactor to avoid param reassignment

* FR1.5 Account Deletion #20

Summary:
* Add feature that allows user to delete their account
* Through the API - `DELETE /api/user/`, requiring `username` to be provided in the json body
* User will be authenticated and authorised first before account deletion is allowed
* User is automatically logged out after account deletion
* Block deletion of other user's account, if you are not logged in as that user

Co-authored-by: fantablack <[email protected]>

* [#72] Implement refreshing of tokens if refreshToken is still valid 

**Summary**
* Add token refresh logic to authentication call
* If token is expired but refresh token is not expired and not blacklisted, a new access token cookie will be issued

Co-authored-by: ureshiiYing <[email protected]>

* [#74] Add protection to changePassword endpoint 

**Summary**
* Reject changePassword attempts in backend if user is not logged in
* Fix bug in error handling caused by res object return type

Co-authored-by: ureshiiYing <[email protected]>

* Fix bug where verifiedUser is not updated when token expires

* Revert "Fix bug where verifiedUser is not updated when token expires"

This reverts commit 542ad44.

* [#78] Fix bug where expired token fails to update

**Summary**
* Fix bug where expired token fails to refresh

* (#64) FR1.6-FE Implement UI for changing passwords

Summary:
- Users might want to change their passwords
- Create a button component that redirects to change password page
- Change password page contains 3 text field inputs - username, old password, new password
- custom hook - `setSessionStorage` is created to make use of session storage to persist username information
- `username` field is taken from session storage, and set to disabled
- Linked to backend `changePassword` API using axios
- Display error using `error` prop in `textfield` and `snackbar`
- Add client-side validation for password strength

* [#79] NFR1.3 - Password strength

Summary:
- Adds API validation for password strength: At least 8 characters, and is alphanumeric.
- Further style error and success snackbars by using MUI alerts

* (#90) FE for user-service - Nav Bar

Summary:
- Current UI does not have a navbar, users may find it difficult to navigate user-related features
- Adds a navbar containing title, settings icon and logout icon
- Adds tooltip to icon buttons to improve usability
- Configured navbar to show only after logging in - i.e main pages of the application
- Move original logout and change password related code into `NavBar.js`
- Remove unnecessary code

* (#102) Sign up page password requirement error not showing

- Previously, generic error shows when a weak password was used.
- Shows specific error message for weak password

* [#94] Update username handling from using Session to Cookies

**Summary**
* ~~Update useSessionStorage() to use a default string value rather than navigate() params~~
* Update username read/write to use cookies instead of storage
* Pages updated with this new functionality in this PR: `Home`, `ChangePassword`, `NavBar`

* [#65] Implement UI for Delete Account

**Summary**
* Implement UI elements for delete account in the NavBar
* Add dialog to prevent accidental deletion of account
* Update delete account route from DELETE to POST, as axios currently do not support `withCredentials` for a `axios.delete`, and the cookie data will never be sent to the backend.

* [#116] Implement standalone endpoint for authentication

**Summary**
* Currently, authentication is built-in in user-service endpoints that require it. (E.g. changePassword, logout etc)
* Implement standalone endpoint for authentication at `POST /auth`
* This can be used for checks when the desired outcome after authentication is outside of user-service responsibilities.

* [#115] Implement FE route protections 

**Summary**
Add protections (redirection to `/login` if not logged in) to the following pages:
* `selectquestiondifficulty`
* `roompage`
* `home`
* `logout`
* `changePassword`
* `deleteAccount`

* [#122] Fix FE from kicking out logged in users

**Summary**
* Fix FE from kicking out logged in users
* Update auth standalone endpoint to GET instead of POST since there is no request body
* Update axios call from POST to GET in the frontend for calling auth endpoint

* update room page to prevent null pointer for fe protection

* [#126] Revamp frontend UI for sign up/ log in

* Improve abstraction and OOP

* Revamp signup frontend

* Implement responsive design

* Complete singup

* Refactor code for better abstraction

* Fix login UI

* Fix snackbar for login

* Update severity

* Fix success and error alerts

* Finalize frontend for login signup

* Fix error message

* Handle initial empty password

* Resolve merge conflict

* Merge UI updates into main (#124)

* Add frontend view to select question difficulty

* Initialize socket server instance

* Add log for user disconnection

* Fix alignment bug and add console logs on button click

* Remove fullWidth attribute for card

* [#6] Add round countdown timer UI 

There is no countdown timer for matching services.

30 seconds countdown timer is required to match users.

Let's implement a UI for the countdown timer so that the users
can visually see how long the matching service has in order 
to find a match before it times out.

* [#13, #15] Implement pending match model and ORM layer

Implementations:
* Create database connection with nodejs
* Implement the pending match model
* Implement the ORM layer. This layer will serve as an 'intermediary' between the controller and the database.

Additionally, Implemented CRUD features + useful features:
- Add new pending match (`POST` request to `localhost:8001/pendingMatches` with the *JSON* object)
- Delete existing pending match (`DELETE` request to `localhost:8001/pendingMatches/:username`)
- Update difficulty level for pending match (`PUT` request to `localhost:8001/pendingMatches/:username`)
- Retrieve all pending match (`GET` request to `localhost:8001/pendingMatches`)
- Find pending match by username (`GET` request to `localhost:8001/pendingMatches/:username`)

* [#48] Update eslint to match main

Update ESLint from main branch. Sync matching-service with main.

* Revert "[#48] Update eslint to match main" (#50)

This reverts commit 9164fea.

* [#33] Update ESLint check to align with Express 

ESLint check fails due to some check that
does not align with Express.

An update is required to ignore these checks.

Include object-shorthand:0 to ignore necessary
declarations for Express module exports.

Include no-use-before-define to ignore functions
as these need to be `used` before declarations
following Express.

Let's update ESLint to align with these requirements.

* [#25] UI Layout for room page view 

* Add package-lock.json

* Add structural layout for room page

* Add leave button

* Edit dimensions

* Edit dimensions

* Modify layout according to feedback

* Adjust border and margin

* Remove comments

* Fix eslint warnings

* [#4, #37] Create socket.io client instance when find match button is clicked

* Create socket.io client instance upon clicking match button

* Fix style check

* Edit event emitted to include difficulty

* Added event listeners on server side

* Add routing from matching page to countdown timer

* Change capitalisation of events emitted

* Change capitalisation of events emitted

* Implement countdown timer as modal

* Add emit cancel-match events

* Align emit event names

* Align emit event names

* Aign emit event names

* Fix bug where event is emitted thrice and align event names

* [44-46] Implement matching related events (#53)

* Refactoring and add pending match upon match event

* Change and add primary key to auto-incremented id

* Implement no-match-found event

* Match pending match by difficulty level

* Minor abstraction

* Abstract out repository

* Fix match-hard pending match creation bug

* Send match-success to matched users

* Resolve bug for match-success hard

* Update

* Add no-match-found handler

* [57] Merge frontend and backend (#59)

* All rooms and events related implementation supporting many socket instances (#81)

* Support CRUD from different socket instances

* Implement room joining and creation through socket

* Implement room joining on matched

* Implement no-match-found event

* Implement match-cancel event

* Implement leave-room event

* [#76] Match frontend events to backend 

* Modify match-cancel and no-match-found events to not pass data

* Modify match-cancel and no-match-found events to not pass data

* Add join-room event

* add leave-room event

* Pass socket to room

* remove match-fail

* Prevent both no-match-found and match-cancel events to be emitted

* Merge with backend

* create socket context

* Add socket context to other views

* Fix bug cannot leave room after refresh

* Clean up source code (#86)

* 108 update UI for matching and room (#112)

* fix alignment issue for selection page

* prevent leave room button from overflowing to code editor

* add check modal for leave room

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Add Prod DB URL (#137)

- Microservices using mongodb were found to be using the same database
- Separate DB for user and question microservices in `PROD` - /users and /questions
- Use `/test` database in `DEV`
- changed `ENV` to `DEV`

* [#125] Milestone 3: chat service

* Implement chat frontend

* Make chat work

User in the same room are able to receive chat
from each other in real-time.

Chat are only sent to user in the same room.

* Refresh input box on submit

* Implement auto-scroll

* Complete chat service

* Enhance ux to allow enter without clicking send

* Clean up code

* Fix minor css bug

* [#138] Improve UI for change password page

- Add a paper background
- Align center the form
- Update password error messages to: `should contain at least one number and one alphabet, and must be at least 8 characters`
- Change text field to variant`outlined`

* Add unstyled link

* Update home to difficulty link to button

* Align grind button and label

* Add history service URI URL to configs.js

* Add getAttemptedQuestions()

* Update history service port no. and update cors

* Implement fetching and display of attempted qns

* Update UI

* Update package-lock.json

* Add circular progress bar

* Align right circular progress

* Update start grind button to use navigate

Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: ureshiiYing <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>

* Resolve merge conflict

* [#21] Cypress E2E frontend testing for CI (#162)

* [#21] Cypress E2E frontend testing for CI

* Setup cypress for frontend testing

* Setup script for CI

* Update gitignore

* Fix gitignore

* Test workflow for CI

* Update workflow

* Update workflow

* Update working directory

* Try remove eslint

* Change test

* Edit

* Update json

* Localhost

* Port

* Update

* Update

* Finish and pass CI

* Update CI

* CI stuff

* Test

* Retry

* Try again

* Update README.md

* Test again

* Solve ci

* Try change package lock

* Resolve package

* Change package again

Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>

* Resolve button

* Resolve progress and button

* Complete homepage

* Implement population of attempted questions (#173)

Closes #157, Closes #172

**Summary**
* Implement population of attempted questions, namely 
   * On new match
   * On refresh question
* Fix edge case in the history API for getting a user record that doesn't exist yet

* [#168] Re-inject Attempted Difficulty cards with live data

* Re-inject Attempted Difficulty cards with live data

* Update question progress calculation

* Update question Progress

Co-authored-by: fantablack <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
Co-authored-by: Papattarada Apithanangsiri <[email protected]>
Co-authored-by: dionegoh <[email protected]>
# Summary of changes made:
- Added a Dockerfile (and `.dockerignore` where applicable) for each microservice
- Added a `docker-compose.yml` file to build the docker containers 
- Updated URLs (specifically, api call from `matching-service` to `question-service`) to be recognisable by Docker 
- Updated README.md with instructions on how to deploy the application locally using Docker
* Resolve merge conflict

* Add test

* Remove screenshot

* Add test
* Upload Final Report

* Correct typo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants