Clone this repo to your local machine
git@github.com:alphagov/di-authentication-frontend.gitClones the repository to the <your_folder_name> directory.
There are three different ways to run the app on a local machine:
- Full stack running locally in Docker
- The frontend and stubs running in Docker, with AWS connections
- The frontend app running in a local node instance, with supporting services running in Docker and AWS connections
- The frontend app running in a local node instance against a local running api in Docker
To run the full stack locally in Docker, see local-running in the authentication-api repo.
If not using full local running then the frontend must connect to the internal api running in a dev account. Now that the internal api is private tunneling is required to access the api from a local machine. See how to configure tunneling to the api.
Before you can run the frontend app against the backend you will need to configure some environment variables.
You will need a .env file. this can be generated by:
- Log into the VPN
- Run
scripts/create-env-file.sh ${target_environment}, where${target_environment}is the environment you wish to use for OIDC etc.dev|authdev1|authdev2are supported.
If things stop working in future, this script can be rerun to update the variables sourced from AWS. All non-generated variables may be updated, and changes will persist through reruns.
UI_LOCALES can be used be the stub to request specific locales when authorising. Only 'en' and 'cy' are supported.
Run one of the following:
docker compose up
./startup.shIn this case supporting services (redis and stubs) run in Docker but the frontend itself runs outside. Development can be quicker and more responsive if done in this way.
The startup script will do this for you so just run this command:
./startup.sh -lIn this case the backend (and it's supporting services) are run in Docker locally but the frontend itself runs outside. Development can be quicker and more responsive if done in this way and we don't need to rely on having correct AWS roles
- You can follow the instructions here to run the api locally
- The
authentication-apiand theauthentication-frontendhave to live in the same directory as siblings
- As this is locally running, it is not hooked up to Notify so you will not receive email or SMS OTPs. Check the environment configuration for the local backend to see the email and phone number OTPs.
- The orchstub will be on
localhost:4400so visit here to start your journeys - You can see the db in IntelliJ by:
- Run
aws configure- Access key ID =
test - Access key =
test - Set default region to
eu-west-2 - Default output format can remain as
None
- Access key ID =
- In IntelliJ
- Select Database -> New -> Data Source -> DynamoDb
- Host =
localhost - Port =
8000 - Region =
eu-west-2 - Authentication =
No auth
- You should then be able to see the database inside IntelliJ
- Run
The startup script will do this for you so just run this command:
./startup.sh -LThis application will normally be started on port 3000 locally.
However, you cannot hit this directly to run through a local journey since we require an OIDC client in order to use the application.
We have an orchestration stub client for local use that is spun up via the startup script that you should use - normally running on port 3002.
You must use this if running against dev, authdev1 or authdev2 backends.
Hitting this stub will perform the relevant OIDC flows in the background and redirect you to the frontend running at localhost:3000.
When starting for the first time, or after a clean, the frontend will take a few minutes to start as node needs to install all the dependencies.
To find out if the application has started, open a console window on the frontend docker container and view the logs. If the server has started successfully you will see this message Server listening on port 3000. If this does not appear try forcing node to restart by updating one of the .njk files.
If things do not appear to be working it can be a good idea to start with a clean deployment:
npm run cleanAdditionaly delete the Docker images for all the frontend services in docker-compose.yml.
Changes made locally will automatically be deployed after a few seconds. You should check the docker console to check that your changes have been picked up by the restart.
You can tweak the vector of trust (VTR) requested by the stub client on port 3002 (or $DOCKER_STUB_DEFAULT_PORT if modified in .env) by editing the VTR environment variable in the .env file.
Set it to "Cl.Cm" for a service needing 2FA, and to "Cl" for a service requiring password only.
You may need to restart all services for the change to take effect.
# Local stub client options
VTR="Cl.Cm"
The service down page starts up automatically when the startup script is run. It can be tested by going to http://localhost:3005.
The unit tests have been written with Mocha and Supertest.
If the app is run in a container then the tests are run there too:
docker exec -it di-authentication-frontend_di-auth-frontend /bin/sh
npm run test:unitYou can restart the app by re-running the startup.sh script, or restarting docker-compose.
For a clean start run ./startup.sh -c
Before committing or creating a PR it is a good idea to run all checks and tests. The pre-commit script can be used to do this. It runs:
- All pre-commit checks defined in
.pre-commit-config.yaml - The app in Docker
- Unit tests
- Integration tests
Pre-commit checks include applying formatting, so after the script has run you may see files updated with formatting changes. Running pre-commit before every PR ensures that all files in the repo are formatted correctly.
./pre-commit.shYou may need to install pre-commit for the script to work.
brew install pre-commitIf you're having problems running locally, try these steps first:
- Connect to the VPN
- Run
./shutdown.sh - Delete your Docker Images (you can do this via Docker Desktop or with
docker system prune --all) - Run
./startup.sh -lcto do a cleanup before a local run - Because things sometimes don't work first time round, a
touch src/server.tswhile the server is running might help
`Error: secret option required for sessions`
- stop the server with
./shutdown.sh - run
./startup.sh -l(there's no need for the -c flag)
Remember to run these commands in the docker container itself.
Generate and view documentation of the user journey state machine
npm run dev:render-user-journey-documentationTo run the app in development mode with nodemon watching the files
npm run devStarts a nodemon server serving the files from the dist/
directory.
To build the app
npm run buildTo run the built app
npm run startStarts a node server pointing to the entry point found in the build directory.
To run the unit tests
npm run test:unitRuns all unit tests found in the tests/unit/ directory
using mocha.
To run all the tests in the project: Select the "Unit Tests" run configuration in the top-right and click the play button.
To run some of the tests (e.g. within a file): Click the play button next to the tests, or by right-clicking the file.
The application stack must be started before the integration tests can be run, either with frontend running in a docker container or on the local machine (./startup -l).
In either case the command to run the integration tests is the same, but the tests usually run faster when frontend is started outside of docker.
In both cases frontend must have started successfully with the message 'Server listening on port 3000' before the tests can be run. If running frontend in a container check the actual container logs in docker desktop to make sure that frontend has started correctly, otherwise the test run will be invalid.
To run the integration tests
REDIS_PORT=6379 REDIS_HOST=localhost npm run test:integrationTo run all the tests in the project: Select the "Integration Tests" run configuration in the top-right and click the play button.
To run some of the tests (e.g. within a file): Click the play button next to the tests, or by right-clicking the file.
Extra Mocha configuration is required to make the integration tests run. This is set up in the project already within the .run/Template Mocha.run.xml file.
To install dependencies, run npm run install
npm run installInstalls the dependencies required to run the application.
To get a coverage report
npm run test:coverageTo run lint checks
npm run lintChecks if the code conforms the linting standards.
We use Playwright to do our snapshot tests.
All snapshot test files are suffixed .snapshot.test.ts
This will run the tests in the same way as in the build pipeline. From the root of the project
- Build the docker containers
docker compose -f docker-compose.snapshots.yml build - Run the tests
docker compose -f docker-compose.snapshots.yml up --exit-code-from playwright - NOTE: Do not run the Playwright tests outside of Docker. There are subtle differences between running them in the container and locally and because of the pipeline we want to make sure we only run them in Docker.
- If there are failing tests you can look in test-results to see the actual, expected and diff.
- Remember, if you have run the tests locally there will likely be failures. Check the instructions above to run them in docker.
If you make a change that affects the appearance of a page then you will need to update the saved snapshot file.
docker compose -f docker-compose.snapshots.yml buildCOMMAND=--update-snapshots docker compose -f docker-compose.snapshots.yml up --exit-code-from playwright
When you want to add an environment variable, make sure to modify the following places:
template.yaml- The Cloudformation template. It configured environment variables for hosted containers.
- You may need to make changes to these areas of the file:
Mappings / EnvironmentConfiguration- the settings for an individual environmentConditions- how the EnvironmentConfiguration is extracted into a Cloudformation variableResources / TaskDefinition / Properties / ContainerDefinitions- how the Cloudformation variable is mapped into an environment variable in the container
config.ts- This file contains functions to read in environment variables.
- Create a function for every environment variable used.
_create_env_file.py- This script generates your
.envfile. - Add each new environment variable to the generator function.
- Make sure to re-run the script after modifying the file.
- This script generates your
.env.local- This file is used by test runners.
- Add each new environment variable to the file.
This guide explains how to set up the nginx-based reverse proxy for accessing private API Gateway endpoints during development. The proxy setup creates a secure tunnel to private API Gateway endpoints:
Frontend App → localhost:8888 → Session Manager → nginx → VPC Endpoint → API Gateway
- AWS CLI configured
- Session Manager plugin:
brew install session-manager-plugin - Node.js installed
- Access to
di-authentication-development-AdministratorAccessPermissionanddi-auth-development-AdministratorAccessPermissionAWS profiles - Connected to the VPN
./scripts/deploy-bastion.shYou will need a .env file. this can be generated by:
./scripts/create-env-file.sh ${target_environment}where ${target_environment} is the environment you wish to use authdev1|authdev2|dev# are only supported for proxy frontend.
./scripts/setup-api-gateway-proxy.sh./start-frontend-with-proxy.shKey configuration in .env file:
FRONTEND_API_BASE_URL=http://localhost:8888Proxy tunnel not working:
# Check if tunnel is running
lsof -i :8888
# Restart proxy
pkill -f 'session-manager-plugin'
./scripts/setup-api-gateway-proxy.sh