- Project Description
- Tech Stack
- Application architecture diagram
- Data Model
- Folder structure
- Setup
- HTTPS Certificates
- OWASP Dependency Check
- Security Measures by Web Application Security Risks according to OWASP
- Authors of the project
POOL project is a mobile application that aims to help the survivors of domestic violence. The main features of the app are: resources in forms of curated articles, videos & podcasts about intimate partner violence, finding shelters and hotlines. Signed up users can have additional access to emergency contact features.
The api uses Heroku for production
- Production URL: https://pool-api-mobile.herokuapp.com/api/
- Not protected endpoints: /shelters, /hotlines
- Node.js
- Express
- Mongoose
- Mongo DB
- Json Web Token
- Jest
- Heroku
The components implements the following functionalities:
- React Native: User registration, login, browse educational resources and add/delete bookmarks, search hotlines and shelters on map, show/create/edit/remove emergency contacts.
- Express/node.js server: Abstracts access to database for clients with RESTful API using Mongoose library: user management (login, register, delete, authorization of different roles), emergency contact management (read, add, edit, remove), articles (read, add, edit, remove), videos, shelters, hotlines.
- MongoDB database: stores the user related data (login credentials, emergency contacts), geospatial data for shelters, resources, hotlines, and T&C.
Why NoSQL ?
The main reasons for choosing MongoDB in POOL project are as below:
- Flexibility → Since the Pool project is in the development phase, it does not have fixed data models. Therefore, the database system may need to accommodate frequent design changes and new features.
- Prioritizing scalability over consistency→ The project needs to store dynamic structured data at large scale
- Performing Geolocation Operations → Map is one of the main features of the app which needs frequent and fast geospatial querying.
- Storing large volumes of data without relations → Some of the collections such as shelters, hotlines and resources do not have relations.
Basic users can perform CRUD operations on contacts and bookmarks. Authorized user with editor or admin role can perform CRUD operations on articles, videos, and podcasts.
Contacts document is embedded in the users collection for optimal querying. Since a user can have maximum 2 emergency contacts (one-to-few relationship), the document size would not exceed the limit.
Each article, video, podcast has one or few violence type tags. The number of violence types are limited, thus another collection is not needed.
http://pool-api-mobile.herokuapp.com/api-docs/
To run locally
- Clone this repo by running the following command:
git clone https://github.com/no-domestic-violence/backend.git
cd backend
- Install dependencies:
yarn install
- Create .env file and add following information:
mongoURI = mongodb atlas uri
JWT_ACCESS_TOKEN_SECRET = jwt access token secret string
JWT_REFRESH_TOKEN_SECRET = jwt refresh token secret string
SENTRY = team sentry link
- Start environment
yarn dev
-
Open http://localhost:3001/api to view it in the browser.
-
Before merging to master
- check lint and prettier rules
yarn lint
- run tests
yarn test
Load Balancing with NGINX and Docker
- Build dockerized image of the app
docker build -t load-balanced-app .
- Run the app instances
docker run -e "INSTANCE=First" -p 3002:3001 -d load-balanced-app
docker run -e "INSTANCE=Second" -p 3003:3001 -d load-balanced-app
docker run -e "INSTANCE=Third" -p 3004:3001 -d load-balanced-app
- cd to nginx directory, build and run the load balancer
docker build -t nginx-load-balancer .
docker run -p 3001:80 -d nginx-load-balancer
Then the NGINX load balancer on port 3001 distributes the requests to 3 server instances.
Caching
- Install Redis
- On Mac:
brew install redis
- Launch Redis before you run the server
brew services start redis
- Stop Redis
brew services stop redis
Testing
App uses Jest and supertest (HTTP assertions library)
- Run tests
yarn test
Application monitoring
App uses Sentry as application monitoring and error tracking.
To monitor docker containers on grafana:
docker-compose up
Aplication logging
Winston and morgan (HTTP logger) display logs on terminal and logs are collected on a separate log file.
To use Heroku for development
- Check that app is running
heroku local
- To check builds
heroku builds
- To cancel builds
heroku build:cancel
In order to run https with certificates (locally for one server in development mode):
- generate a private key
openssl genrsa -aes128 -out private.key 2048
- generate a public key from private key
openssl rsa -pubout -in private.key -out public.key
- generate request
openssl req -new -key private.key -out request.csr
- generate certificate
openssl x509 -req -days 3 -in request.csr -signkey private.key -out certificate.crt
-
Make sure you have OWASP dependency-check
-
Create directory for report
mkdir vulnerabilities
- Generate report
dependency-check --scan ./ -f JSON -f HTML -f XML -o vulnerabilities
- Detailed threats can be viewed on threat model file using OWASP Threat Dragon software.
- NoSQL Injection
- Use input sanitization
- Ensure that the database queries are not constructed directly from user-controlled data
- Broken Authentication
- Use JWT authentication token
- Use JWT refresh token
- Use standard Authorization: Bearer < access token >
- Limit failed login attempts
- Increase password length
- Increase password strength
- Implement weak password check
- Sensitive Data Exposure
- Store sensitive data in encrypted secure storage (client side)
- Store password using strong, salted hashing function with Bcrypt
- Enforce encryption using HTTP Strict Transport Security
- Encrypt all data in transit with secure TLS protocol
- Prevent using cache for sensitive data
- Use hpp express middleware to prevent HTTP parameter pollution
- Security Misconfiguration
- Keep error messages short
- Use eslint-plugin-security and Sonar Cloud to identify potential security hotspots
- Cross-Site Scripting XSS
- Use React JS and React Native that automatically escape XSS by design
- Enable and customise Content Security Policy (CSP)
- Validate all user inputs (client and server)
- Using Components with Known Vulnerabilities
- Use OWASP Dependency Check
- Reverse Engineering (mobile)
- Use an obfuscation tool
- Clickjacking
- Implement X-Frame-Options via Content Security Policy
- Code Tampering
- Detect rooted devices
- Brute Force Attacks
- Implement rate limiting on authentication routes
- Implement Google reCAPTCHA v3 on web-app authentication
- The project scored A+ grade on Mozilla Observatory scan
- Soyoon Choi : User(contacts) API, setup loggers and monitoring, NGINX load balancer for development, API documentation. role based access control, client/server side input validation, refresh token, setup custom error handler, authentication on web, database query sanitization, enforce https redirect, setup security header
- Irina Baeva : Setup production and development environment (yarn, babel, lint), API: Articles (Create, Edit, Delete), Hotlines (Get searching), Shelters, Video (including handling multipart/form-data for image), Caching with Redis on development mode, Setup logging and monitoring. client/server side input validation/sanitization, security headers including CSP, TLS encryption for development mode, implement weak password check, obfuscate bundle code, configure vulnerability check tools, authentication on mobile
- Behnaz Derakhshani : Implementing Google reCAPTCHA v3 on web-app authentication, Implementing rate limiting on authentication routes with Redis, Refresh token, Server side input validation, Authentication (signup, login, changepassword, deleting account) & error handling and expectation, API: Articles(Read), API documentation