These instructions will help you get the project up and running.
For more information about Universal 2nd Factor & One-Time Password see :
The u2f js api
requires the web client be served via https. This requirement creates a hurdle for developers to get up and running. For development, this project uses an NGINX proxy with https enabled.
The webserver resolves to domain names, so you'll have to add the domain (example.com
is the default) to your local system (/etc/hosts
or appropriate file)
0.0.0.0 api.example.com docs.example.com coverage.example.com example.com
make run
applies docker-compose.development.yml
which includes an environmental variable SITES
within the dev-ssl-proxy
definition. This variable is used by the development NGINX server to proxy the multiple services as HTTPS resources.
Before successfully running the project in development mode, you'll need to update the line below, replacing YOUR_LOCAL_IP_HERE
with your local ip 10.1.2.3
. Be sure to use an IP that the containers will resolve to your host. localhost
/0.0.0.0
/etc, will all resolve to inside the NGINX proxy container itself and will not work.
SITES: 'api.example.com=YOUR_LOCAL_IP_HERE:8881;docs.example.com=YOUR_LOCAL_IP_HERE:8882;coverage.example.com=YOUR_LOCAL_IP_HERE:8883;example.com=YOUR_LOCAL_IP_HERE:8884;'
Development doesn't require local installion of node or any of the project's dependencies. Instead, those dependencies are bundled within the docker container and nodemon
monitors changes to the app's source (which is mounted from your local system to the docker container) and reload the microservice.
This command starts the app, it's dependencies (database & cache), and additional development services (https proxy & more).
make run
API Endpoint
- API ServiceAPI Documentation
- Swagger UITest Coverage
- HTML Coverage ReportDemo Client
- Basic Client for Demo & Developmentchrome://inspect/#devices
- Node Inspector that consumes debugger listening on websockets
Chrome won't trust the https certs served by the development NGINX proxy. As such, you'll need to manually proceed past the security warnings before you can interact with the API or any of the development services.
To run production image:
make start
This process starts the database (with persistent data), cache server and the api microservice (and none of the development dependencies)
- Database | no port exposed
- Cache Server | no port exposed
- API Microservice | port 8443
NOTE: In Production, you'll want to make sure you're managing the db service correctly (backups, dumps, snapshots, redundancy, etc).
To build and tag a production image (u2f-server:latest
) with your local changes use:
make release
NOTE: Production images hosted on Docker Hub
Unit Tests can be run inside the container or locally. Running the tests inside the container eliminates your need to install node_modules locally.
The command mounts your local src
directory inside the container and runs the test suite.
make test
The command mounts your local src
directory inside the container and runs the test suite.
# install node packages
npm i
# run test suite
npm run test
# run test suite AND generate HTML Coverage Report
npm run test:coverage
This docker images (u2f-server:develop
& u2f-server:latest
) both generate the code coverage HTML when the container starts (this is done in the entrypoint script).
This HTML can be updated/overwritten by running npm run test:coverage
INSIDE or OUTSIDE the container.
Linting can be run inside the container or locally. Running the linting inside the container eliminates your need to install node_modules locally.
The command mounts your local src
directory inside the container and runs the linter.
make lint
The command mounts your local src
directory inside the container and runs the test suite.
# install node packages
npm i
npm run lint
Data migrations for the app are managed via knex migrate:latest
which is run in the container at runtime.
Below is a diagram of the schema for your reference.
u2f_key
, otp_device
, and backup_code
all hold records for configured MFA methods. The nickname field is only provided so the users can differentiate between their multiple devices (if they have them), as they're able to remove devices.
A backup_code
is single use and is deleted upon successful authentication.
auth_log
records all attempts to authenticate -- successful or failure. This could be useful in the future for rate-throttling or flagging activity.
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the MIT License - see the LICENSE.md file for details