**POR FAVOR MUDEM DIRETAMENTE NO BRANCH**
# Zona auxiliar para os diagramas




## Features
- Login
- Password and email validation
- Register
- Logout
- Update Password
- Password Recovery
- Delete account
## Endpoints
### GET `/authentication`
This example route was created in order to test the authentication. It will return a json response with a message field whose value will depend on the status code. On success, the id of the authenticated user is returned, otherwise an error message is returned.
The following responses may be returned:
- 200 if the request was made with a valid token
- The message returns the id of the authenticated user (i.e: 1 )
- 403 if no token was provided
- Access token is required for authentication
- 401 if the token or session is not valid:
- Invalid Token
- Invalid session
- The user does not exist
- 500 if an internal error occurs
- Get user failed with error: ${err}
- Could not process session
### POST `/authentication/login`
The login route requires two parameters for the account creation:
- `email`
- `password`
It verifies the validity of the email and password and returns a response with a status code of:
- 200 if the user was successfully logged in
- 400 if something went wrong, such as:
- Not passing one of the parameters
- Passing an e-mail that is not registered
- Using a wrong password
- 500 if an internal error occurs
- Get user failed with error
- Error creating session
All of the responses will also include a message describing the success or failure of the request.
If the login is successful, a json response is returned with a success message, the id of the user and the JWT, for example:
```json
{
"message": "Login with success",
"id": 11,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTEsImlhdCI6MTY1NTQ2NDMwOCwiZXhwIjoxNjU1NzIzNTA4fQ.Is_sAEggVqkcox_XTZAKia9fsOe_AhSaC655ikEES3E"
}
```
This token should be included in all subsequent requests that require the user to be authenticated. It can be sent in the Authorization Header through the Bearer Schema or using cookies, given that our implementation supports both approaches.
### POST `/authentication/logout`
This is the logout route, it requires no parameters, but there must be a logged in user, in which case the cookies related to the login will be deleted, otherwise the same error codes as in the authentication testing route will appear in the response.
authentication - 200
- 200 if the logout was successful
- 'Logout with success'
### POST `/authentication/register`
This is the register route, it requires two parameters for the account creation:
- `email`
- `password`
It will return a response with a status code of:
- 201
- Registered with success
- 400
- Email and password are required
- The email '${email}' is not valid
- The password is not strong enough: ${passwordErrors}
- 409
- This user already exists. Please Login
- 500
- Get user failed with error: ${err}
- Insert user failed
- Insert user failed with error: ${err}
All of the responses will also include a message with their description.
### DELETE `/user/:id`
This is the route for account deletion, it requires one parameter for the account deletion:
- `password`
But there must be a logged in user, otherwise the same error codes as in the authentication testing route will appear in the response. Other status codes for responses that can be returned are:
authorization errors - 200 +
- 401
- Unauthorized action
- 400
- Password is required
- The user does not exist
- Invalid password
- 500
- Get user failed with error: ${err}
- Account deletion failed
- 204
- Account deleted with success
All of the responses will also include a message with their description.
### PUT `/user/update-password/:id`
This is the route for password changes, it requires two parameters for the password update:
- `oldPassword`
- `newPassword`
But there must be a logged in user, otherwise the same error codes as in the authentication testing route will appear in the response. Other status codes for responses that can be returned are:
authorization errors - 200 +
- 200
- Update password with success
- 400
- New and old passwords are required
- Invalid current password
- The new password is not strong enough: ${passwordErrors}
- 401
- Unauthorized action
- The user does not exist
- 500
- Get user failed with error: ${err}
- Update password failed
### `POST /user/forgot-password`
Send a token via email that can be used to change the password when a user forgets it
- 200
- Email sent with success
- 400
- Email is required
- 401
- The user does not exist
- 500
- Get user failed with error: ${err}
- ||Algum erro de envio do email, não faço ideia de como ele pode aparacer||
### `POST /user/reset-password`
Update an user's password without knowing the previous password using a token
- 200
- Update password with success
- 400
- New password is required
- The password is not strong enough: ${passwordErrors}
- 401
- Invalid Token
- The user does not exist
- 403
- A token is required for authentication
- 500
- Get user failed with error: ${err}
- Update password failed
# Report
**Todo**
- [x] General problems: corrigir no Multiple Authentication emthods
- [x] Design and architecture patterns: João sent them
- [ ] Technologies: nodemailer, redis, postgres, javascript, node, express
- [X] Usage (SwaggerHub link)
- [X] Contributing (explain middleware for internal use)
**Todo bonus**
- [ ] Graphical diagram of usage (UML)
## Technologies
Authentication & Authorization:
- nodemailer: to send the password recover email
- redis: for session storage
- postgres: to store the credentials (email and password) of the user
## Architecture and Design Decisions
### Access Token
- https://learning.oreilly.com/library/view/architectural-patterns/9781787287495/2f3c5677-2687-4338-bf23-72dbb77828f8.xhtml
- https://microservices.io/patterns/security/access-token.html
#### Context
Our application makes use of a Microservices architecture and therefore, there are multiple services that must authenticate the User to verify his identity and authorize the access to specific resources. In order to provide a single interface that can be reused by each of the services, the Access Token pattern is used to authenticate the user.
#### Mapping

Based on this diagram, the Flutter App would be the client, which would send an Access Token to the API endpoints that require authentication or authorization. Our Authentication service, in particular the middleware, intercepts the requests to verify if the user is authenticated and authorized to access the resource.
#### Consequences
##### Pros
- Higher scalability and efficiency: access tokens are not stored on the server;
- Flexibility: offers authentication and authorization for several applications or services;
- Robust security: a secret key is required to generate and validate the token;
- Usability: the user doesn't need to authenticate at every request, he just needs to send the access token.
##### Cons
- Compromised access token: if the secret key or token are not stored correctly, security can be compromised;
- Data overhead: the access token is usually bigger than a normal session token;
- Shorter lifespan: access tokens have a short lifespan which could lead to a worse UX.
### API Key
https://microservice-api-patterns.org/patterns/quality/qualityManagementAndGovernance/APIKey
#### Context
Some of the services offered by our API will return different data depending on the user trying to access it, therefore we need a way to identify and authenticate users.
#### Mapping

Based on this diagram, the client is the Flutter App, which requires authentication to obtain certain information. Our backend offers the API that receives the token.
#### Consequences
##### Pros
- Security: The token makes the service more secure by allowing us to identify the user.
##### Cons
- Sending the token in every request increases the network traffic.
### Error Report
#### Context
Our app services need to handle errors generated at runtime. To achieve this, our error messages have to follow a specific design that everyone agreed on.
#### Mapping

The image represents what an error message would be like in the context of our application.
#### Consequences
##### Pros
- Error messages allow the end user to understand what generated the error in a simplistic way;
- Having a detailed report of the error may help achieve a solution.
##### Cons
- Having a very detailed explanation may expose sensitive data and other details related to provider side implementation.
### Client Session State
#### Context
The session state is stored in the client, in order to keep the session alive without having to reinsert the authentication credentials. In this case, in particular, the token can be stored inside a cookie, for praticality purposes or in other types of storage (i.e. Flutter's SecureStorage) and then sent to the server in the Authorization Header.
#### Mapping

#### Consequences
##### Pros
- Low Latency: validating and creating sessions is faster as it doesn't need to consult the database;
- Increases usability for the user;
- Supports stateless server objects with maximal clustering and failover resiliency.
##### Cons
- Sessions cannot be terminated (even though there are workarounds);
- Logout is not possible: the session token can be dropped from the browser (in case of a cookie) or from storage, but it would still work if resubmitted, unless other workarounds are used to avoid that (which is the case).
- Any data sent to the client is vulnerable to being looked at and altered, so the session may be stolen. Encryption is the only way to stop this, but encrypting and decrypting with each request are a performance burden.
### Saving User Login Information
#### Context
Jwt tokens are sent as a response to login requests, but these tokens have a specified lifetime. A priori, we have no way to invalidate it before it expires, which is necessary when the user wants to logout.
#### Mapping
We can save the session information in a database when the user logs in and remove it on logout. However, this implies a verification of each request containing tokens, and that's why a cache database like Redis is better for this purpose.
#### Consequences
##### Pros
- We have a way to check if the tokens are active
- We can invalidate tokens, so that people cannot use them anymore, which is needed for the logout functionality
##### Cons
- We need to establish connections to the database in every authenticated request, to validate the token
- The overhead can be mitigated by using a cache database, but it is still there either way
## Contributing
### Authentication Middleware
#### Context - How are we authenticating the user?
In order to authenticate the user we use JWT tokens. This tokens are sent to the user upon a successful login both in the response and in a cookie. The JWT token must then be sent in every request that requires authentication and authorization. For that, the request may send the **cookie** or it can set the **Bearer Token in the Authorization header**.
#### Usage of the Authentication Middleware
If a service needs to authenticate the user before providing access to a resource, it can use the **authentication middleware** to do so, particularly the `verifySessionToken` middleware function.
You just need to define your route like the one below, setting the first and third parameters with the appropriate path and handler:
```typescript=
import auth from '@/middleware/auth'
router.get(PATH, auth.verifySessionToken, HANDLER)`
```
If you need to know who is accessing your endpoint, you can access the id of the user, which will be set by our middleware in the request body (`req.body.id`).
In the file that contains the authentication routes, you can find an example route (`testAuth`), which returns as a response the id of the user if a valid access token is provided. Otherwise, an error message will be returned.
-->

