Skip to content

Commit

Permalink
Add given user service
Browse files Browse the repository at this point in the history
  • Loading branch information
nknguyenhc committed Sep 24, 2024
1 parent 7f07f5d commit 83972fd
Show file tree
Hide file tree
Showing 14 changed files with 2,657 additions and 0 deletions.
9 changes: 9 additions & 0 deletions user-service/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DB_CLOUD_URI=<CONNECTION_STRING>
DB_LOCAL_URI=mongodb://127.0.0.1:27017/peerprepUserServiceDB
PORT=3001

# Will use cloud MongoDB Atlas database
ENV=PROD

# Secret for creating JWT signature
JWT_SECRET=you-can-replace-this-with-your-own-secret
3 changes: 3 additions & 0 deletions user-service/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/node_modules
**/.env
**/.idea
248 changes: 248 additions & 0 deletions user-service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# User Service Guide

## Running User Service

1. Open Command Line/Terminal and navigate into the `user-service` directory.

2. Run the command: `npm install`. This will install all the necessary dependencies.

3. Run the command `npm start` to start the User Service in production mode, or use `npm run dev` for development mode, which includes features like automatic server restart when you make code changes.

4. Using applications like Postman, you can interact with the User Service on port 3001. If you wish to change this, please update the `.env` file.

## User Service API Guide

### Create User

- This endpoint allows adding a new user to the database (i.e., user registration).

- HTTP Method: `POST`

- Endpoint: http://localhost:3001/users

- Body
- Required: `username` (string), `email` (string), `password` (string)

```json
{
"username": "SampleUserName",
"email": "[email protected]",
"password": "SecurePassword"
}
```

- Responses:

| Response Code | Explanation |
|-----------------------------|-------------------------------------------------------|
| 201 (Created) | User created successfully, created user data returned |
| 400 (Bad Request) | Missing fields |
| 409 (Conflict) | Duplicate username or email encountered |
| 500 (Internal Server Error) | Database or server error |

### Get User

- This endpoint allows retrieval of a single user's data from the database using the user's ID.

> :bulb: The user ID refers to the MongoDB Object ID, a unique identifier automatically generated by MongoDB for each document in a collection.

- HTTP Method: `GET`

- Endpoint: http://localhost:3001/users/{userId}

- Parameters
- Required: `userId` path parameter
- Example: `http://localhost:3001/users/60c72b2f9b1d4c3a2e5f8b4c`

- <a name="auth-header">Headers</a>

- Required: `Authorization: Bearer <JWT_ACCESS_TOKEN>`

- Explanation: This endpoint requires the client to include a JWT (JSON Web Token) in the HTTP request header for authentication and authorization. This token is generated during the authentication process (i.e., login) and contains information about the user's identity. The server verifies this token to ensure that the client is authorized to access the data.

- Auth Rules:

- Admin users: Can retrieve any user's data. The server verifies the user associated with the JWT token is an admin user and allows access to the requested user's data.

- Non-admin users: Can only retrieve their own data. The server checks if the user ID in the request URL matches the ID of the user associated with the JWT token. If it matches, the server returns the user's own data.

- Responses:

| Response Code | Explanation |
|-----------------------------|----------------------------------------------------------|
| 200 (OK) | Success, user data returned |
| 401 (Unauthorized) | Access denied due to missing/invalid/expired JWT |
| 403 (Forbidden) | Access denied for non-admin users accessing others' data |
| 404 (Not Found) | User with the specified ID not found |
| 500 (Internal Server Error) | Database or server error |

### Get All Users

- This endpoint allows retrieval of all users' data from the database.
- HTTP Method: `GET`
- Endpoint: http://localhost:3001/users
- Headers
- Required: `Authorization: Bearer <JWT_ACCESS_TOKEN>`
- Auth Rules:

- Admin users: Can retrieve all users' data. The server verifies the user associated with the JWT token is an admin user and allows access to all users' data.

- Non-admin users: Not allowed access.

- Responses:

| Response Code | Explanation |
|-----------------------------|--------------------------------------------------|
| 200 (OK) | Success, all user data returned |
| 401 (Unauthorized) | Access denied due to missing/invalid/expired JWT |
| 403 (Forbidden) | Access denied for non-admin users |
| 500 (Internal Server Error) | Database or server error |

### Update User

- This endpoint allows updating a user and their related data in the database using the user's ID.

- HTTP Method: `PATCH`

- Endpoint: http://localhost:3001/users/{userId}

- Parameters
- Required: `userId` path parameter

- Body
- At least one of the following fields is required: `username` (string), `email` (string), `password` (string)

```json
{
"username": "SampleUserName",
"email": "[email protected]",
"password": "SecurePassword"
}
```

- Headers
- Required: `Authorization: Bearer <JWT_ACCESS_TOKEN>`
- Auth Rules:

- Admin users: Can update any user's data. The server verifies the user associated with the JWT token is an admin user and allows the update of requested user's data.

- Non-admin users: Can only update their own data. The server checks if the user ID in the request URL matches the ID of the user associated with the JWT token. If it matches, the server updates the user's own data.

- Responses:

| Response Code | Explanation |
|-----------------------------|---------------------------------------------------------|
| 200 (OK) | User updated successfully, updated user data returned |
| 400 (Bad Request) | Missing fields |
| 401 (Unauthorized) | Access denied due to missing/invalid/expired JWT |
| 403 (Forbidden) | Access denied for non-admin users updating others' data |
| 404 (Not Found) | User with the specified ID not found |
| 409 (Conflict) | Duplicate username or email encountered |
| 500 (Internal Server Error) | Database or server error |

### Update User Privilege

- This endpoint allows updating a user’s privilege, i.e., promoting or demoting them from admin status.

- HTTP Method: `PATCH`

- Endpoint: http://localhost:3001/users/{userId}

- Parameters
- Required: `userId` path parameter

- Body
- Required: `isAdmin` (boolean)

```json
{
"isAdmin": true
}
```

- Headers
- Required: `Authorization: Bearer <JWT_ACCESS_TOKEN>`
- Auth Rules:

- Admin users: Can update any user's privilege. The server verifies the user associated with the JWT token is an admin user and allows the privilege update.
- Non-admin users: Not allowed access.

> :bulb: You may need to manually assign admin status to the first user by directly editing the database document before using this endpoint.

- Responses:

| Response Code | Explanation |
|-----------------------------|-----------------------------------------------------------------|
| 200 (OK) | User privilege updated successfully, updated user data returned |
| 400 (Bad Request) | Missing fields |
| 401 (Unauthorized) | Access denied due to missing/invalid/expired JWT |
| 403 (Forbidden) | Access denied for non-admin users |
| 404 (Not Found) | User with the specified ID not found |
| 500 (Internal Server Error) | Database or server error |

### Delete User

- This endpoint allows deletion of a user and their related data from the database using the user's ID.
- HTTP Method: `DELETE`
- Endpoint: http://localhost:3001/users/{userId}
- Parameters

- Required: `userId` path parameter
- Headers

- Required: `Authorization: Bearer <JWT_ACCESS_TOKEN>`

- Auth Rules:

- Admin users: Can delete any user's data. The server verifies the user associated with the JWT token is an admin user and allows the deletion of requested user's data.

- Non-admin users: Can only delete their own data. The server checks if the user ID in the request URL matches the ID of the user associated with the JWT token. If it matches, the server deletes the user's own data.
- Responses:

| Response Code | Explanation |
|-----------------------------|---------------------------------------------------------|
| 200 (OK) | User deleted successfully |
| 401 (Unauthorized) | Access denied due to missing/invalid/expired JWT |
| 403 (Forbidden) | Access denied for non-admin users deleting others' data |
| 404 (Not Found) | User with the specified ID not found |
| 500 (Internal Server Error) | Database or server error |

### Login

- This endpoint allows a user to authenticate with an email and password and returns a JWT access token. The token is valid for 1 day and can be used subsequently to access protected resources. For example usage, refer to the [Authorization header section in the Get User endpoint](#auth-header).
- HTTP Method: `POST`
- Endpoint: http://localhost:3001/auth/login
- Body
- Required: `email` (string), `password` (string)

```json
{
"email": "[email protected]",
"password": "SecurePassword"
}
```

- Responses:

| Response Code | Explanation |
|-----------------------------|----------------------------------------------------|
| 200 (OK) | Login successful, JWT token and user data returned |
| 400 (Bad Request) | Missing fields |
| 401 (Unauthorized) | Incorrect email or password |
| 500 (Internal Server Error) | Database or server error |

### Verify Token

- This endpoint allows one to verify a JWT access token to authenticate and retrieve the user's data associated with the token.
- HTTP Method: `GET`
- Endpoint: http://localhost:3001/auth/verify-token
- Headers
- Required: `Authorization: Bearer <JWT_ACCESS_TOKEN>`

- Responses:

| Response Code | Explanation |
|-----------------------------|----------------------------------------------------|
| 200 (OK) | Token verified, authenticated user's data returned |
| 401 (Unauthorized) | Missing/invalid/expired JWT |
| 500 (Internal Server Error) | Database or server error |
41 changes: 41 additions & 0 deletions user-service/controller/auth-controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { findUserByEmail as _findUserByEmail } from "../model/repository.js";
import { formatUserResponse } from "./user-controller.js";

export async function handleLogin(req, res) {
const { email, password } = req.body;
if (email && password) {
try {
const user = await _findUserByEmail(email);
if (!user) {
return res.status(401).json({ message: "Wrong email and/or password" });
}

const match = await bcrypt.compare(password, user.password);
if (!match) {
return res.status(401).json({ message: "Wrong email and/or password" });
}

const accessToken = jwt.sign({
id: user.id,
}, process.env.JWT_SECRET, {
expiresIn: "1d",
});
return res.status(200).json({ message: "User logged in", data: { accessToken, ...formatUserResponse(user) } });
} catch (err) {
return res.status(500).json({ message: err.message });
}
} else {
return res.status(400).json({ message: "Missing email and/or password" });
}
}

export async function handleVerifyToken(req, res) {
try {
const verifiedUser = req.user;
return res.status(200).json({ message: "Token verified", data: verifiedUser });
} catch (err) {
return res.status(500).json({ message: err.message });
}
}
Loading

0 comments on commit 83972fd

Please sign in to comment.