Skip to content

A backend express API for a small association in Denmark. Which in the long run, should help handle personal data and general association data, in a easy and GDPR compliant fashion.

Notifications You must be signed in to change notification settings

5-semesterprojekt/Backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Firebase JWT TypeScript Jest Express.js

πŸ“Œ Contents

  1. Setup
  2. Start
  3. Scripts
  4. Contribution
  5. API Documentation
  6. Error Handling
  7. Authentication / Authorization

πŸ› οΈ Setup

Using nvm is advised.

Using yarn is required. Install it with npm like this:

npm install -g yarn

Clone the project:

git clone https://github.com/5-semesterprojekt/Backend.git

Install packages:

cd backend
yarn install

it is advised to use our frontend which can get cloned from and follow the guide that is written.

git clone https://github.com/5-semesterprojekt/Frontend.git

After that it is also advised to change the example file and rename them without example at the end, at the moment there 3 files that has to change.

firebaseConfig-example.ts

This one is simple, go to the firebase console and create a new project. Then copy your own firestore config and paste it in the firebaseConfig-example.ts file and rename the file to firebaseConfig.ts

gmailSecrets-example.ts

If you already have a gmail then you should just follow the intructions in the file and afterwards rename it to gmailSecrets.ts. If you dont own an gmail then create one and follow the instructions in the gmailSecrets-example.ts.

jwtSecretKey-example.ts

Just rename the one that is called "SECRET_KEY" to something secure, since this line is used store the user's token and could be hacked if compromised.


πŸš€ Start

The backend can be started by running the start script:

yarn start

You can make your own website or use our frontend that we have developed along with this backend. You can get our frontend from here https://github.com/5-semesterprojekt/Frontend.git


πŸ“œ Scripts

yarn start

Starts the api, you would now be able to make calls, look at the api doc

yarn test

Runs all tests (see jest for more).

yarn prettier

Formats the code according to the .prettierrc.


πŸ—οΈ Contribution

  1. Make a branch from main using the suggested branch name from Shortcut. (i.e. feature/sc-{story number}/{feature-name})
  2. Commit until the feature is "complete"
  3. Run yarn prettier so code is formatted correctly
  4. Make pull request to main and request a review
  5. Squash and merge when all requirements are met

It is HIGHLY advisable, that you don't branch off secondary branches. Only branch off main.
Feel free to customize and expand upon this documentation based on your specific contributions.


πŸ“‹ API Documentation

Create Event

Create a new event by making a POST request to the following endpoint: Needs to be logged in/auth token

POST /events/:orgId/

Request Body: title (string, required): The title of the event.
start (date, required): The start date and time of the event in ISO format (e.g., "2019-12-17T03:24:00").
end (date, required): The end date and time of the event in ISO format.
description (string, optional): A description of the event.

Example:

{
  "title": "some title",
  "description": "some description",
  "start": "2019-12-17T03:24:00",
  "end": "2019-12-18T03:24:00"
}

Response:
Status Code: 201 Created
Response Body: The created event object with an additional id field.

Get All Events

Retrieve all events for a specific organization by making a GET request to the following endpoint:

GET /events/:orgId/

Response:
Status Code: 200 OK if the event is found.
Example

[
   {
        "title": "Event title",
        "description": "something...",
        "start": "2023-11-23T23:00:00.000Z",
        "end": "2023-11-23T23:00:00.000Z",
        "orgId": 123
   }, ...
]

Get Event by ID

Retrieve a specific event by its ID for a given organization by making a GET request to the following endpoint:

GET /events/:orgId/:id

Response:
Status Code: 200 OK if the event is found, 404 Not Found otherwise.

Update Event

Update an existing event by making a PUT request to the following endpoint:

PUT /events/:orgId/:id

Request Body:

{
  "title": "Updated Event Title",
  "start": "2023-12-01T15:00:00",
  "end": "2023-12-01T20:00:00",
  "description": "Updated Event Description"
}

Response:
Status Code: 200 OK
Response Body: The updated event object.

Delete Event

Delete a specific event by its ID for a given organization by making a DELETE request to the following endpoint:

DELETE /events/:orgId/:id

Response:
Status Code: 204 No Content if the event is deleted successfully, 404 Not Found otherwise.

Create User

Create a new user by making a POST request to the following endpoint:

POST /users/:orgId/

Request Body:

{
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@example.com",
  "password": "SecurePassword123!",
  "repeatPassword": "SecurePassword123!"
}

Response:
Status Code: 201 Created
Response Body: The created user object.

User Login

Authenticate a user by making a POST request to the following endpoint:

POST /users/:orgId/login

Request Body:

{
  "email": "john.doe@example.com",
  "password": "SecurePassword123!"
}

Response:
Status Code: 200 OK
Response Body: The authenticated user object.

Get All Users by Organization

Needs to be logged in/auth token

Retrieve all users for a specific organization by making a GET request to the following endpoint:

GET /users/:orgId/

Response:
Status Code: 200 OK
Response Body: An array of user objects for the specified organization.

Get User by Token/ID

Needs to be logged in/auth token A jwt token must be present in the Authorization header. This token is received by logging in. Retrieve the user associated with the provided token by making a GET request to the following endpoint:

GET /users/:orgId/me

Response:
Status Code: 200 OK
Response Body: The user object.

Get User by ID

Needs to be logged in/auth token

Retrieve a specific user by their ID for a given organization by making a GET request to the following endpoint:

GET /users/:orgId/:id

Response:
Status Code: 200 OK
Response Body: The user object.

Update User

Needs to be logged in/auth token

Update an existing user by making a PUT request to the following endpoint:

PUT /users/:orgId/:id

Request Body:

{
  "firstName": "Updated John"
}

Response:
Status Code: 200 OK
Response Body: The updated user object.

Delete User

Needs to be logged in/auth token
Delete a specific user by their ID for a given organization by making a DELETE request to the following endpoint:

DELETE /users/:orgId/:id

Response:
Status Code: 204 No Content

Forgot Password

Initiate the forgot password process by making a POST request to the following endpoint:

POST /users/:orgId/forgot-password

Request Body:

{
  "email": "john.doe@example.com"
}

Response:
Status Code: 200 OK
Response Body: An object with a message indicating that the email has been sent.


⚠️ Error Handling

Overview

The error handling module in this application is designed to manage and respond to errors that may occur during the execution of API endpoints. It includes middleware functions for logging errors, responding with appropriate error messages, and handling invalid paths.

Custom Errors

Custom errors, such as BaseError, are supported. They can be thrown with a specific status code and optional error details.

import { BaseError } from 'path-to-error-handler';

throw new BaseError('Custom error message', 404, { additionalInfo: 'details' });

A BaseError should generally be thrown when an error is expected. i.e. when an entry doesn't exist in a database, then throw new BaseError('Error', 404); immediately.


πŸ”‘ Authentication / Authorization

Overview

The authentication middleware is designed to secure specific routes by ensuring that requests contain a valid JWT token in the Authorization header. If the token is valid, the middleware decodes it, extracts the user ID, and attaches it to the request object for further use in downstream middleware or route handlers.

Usage

The auth middleware function should be applied to routes or groups of routes that require authentication.
If the token is missing or invalid, the middleware responds with a 401 Unauthorized status code and the message "Please authenticate."

Example

import { auth, CustomRequest } from 'path-to-authentication-middleware';

// ... Other middleware and route handling

// Apply authentication middleware to a route
app.get('/authenticated-route', auth, (req: CustomRequest, res) => {
  // Access user ID from the decoded token
  const userId = req.token;

  // ... Other route handling logic
});

About

A backend express API for a small association in Denmark. Which in the long run, should help handle personal data and general association data, in a easy and GDPR compliant fashion.

Resources

Stars

Watchers

Forks