Hw 3 - Managing Users in the Web Gallery

The objective of these assignments is to build an application called The Web Gallery where users can share pictures and comments. This application is similar to existing web applications such as Facebook, Instagram or Google Photos.

In this last assignment, you will concentrate on

Submission and Grading

Important: This homework has some starter code that is available on Classroom 50. If you do not have access to Classroom 50, please send a private message to the instructor on Piazza.

There are two things to do when submitting your work:

  1. Push your final version of your code to the main branch of your hw3 Github repository created through Classroom 50. The timestamp of that latest commit will be used to calculate the number of late days used.

  2. Deploy your application on the provided VM and make sure that everything works. You work should be accessible through the following URL (replace repository_name with your Github repository):

http://repository_name.amazingcloud.space

When comes the time for the course staff to grade your work, keep in mind the following:

Deployment

The starter code that is working and deployable. We recommend to deploy the starter code first to get familiar with the deployment process using the instructions below.

Once you have deployed the starter code, you should access your app on the browser http://repository_name.amazingcloud.space (replace repository_name with your repository). You should see the message Welcome to HW3!

Then, as you build your web application, we recommend to deploy your application on the VM as often as possible.

Accessing and configuring the VM

  1. Setup the SSH key following these instructions here
  2. SSH into the VM:
 ssh root@repository_name.amazingcloud.space
  1. Install Docker on your VM following these instructions here.

  2. Make sure that docker is working:

  docker run --rm hello-world
  1. You can learn more about how to use Docker here

Deploying your Application

To deploy your application:

  1. From your computer first, copy your code into the VM rsync -avz --delete -e ssh . root@repository_name.amazingcloud.space:web-gallery (replace repository_name with your repository name).

  2. SSH to the VM ssh root@repository_name.amazingcloud.space and cd web-gallery

  3. Build the backend docker image (should be done the first time and every time the backend code has changed):

  docker compose build
  1. Run the Docker containers:
  docker compose up -d
  1. Check the logs:
  docker compose logs -f

FYI, the first time you run this setup, the acme-companion container will create a certificate for your domain repository_name.amazingcloud.space and ask Let’s Encrypt to sign it. This process takes couple of minutes.

  1. Access your app on the browser https://repository_name.amazingcloud.space.

  2. To stop all containers

  docker compose down

Understanding the Deployment Setup

There are 4 containers orchestrated by the docker-compose.yml file:

For this homework, we only have one domain repository_name.amazingcloud.space that we want to deploy in HTTPS. We want the reverse proxy to route all HTTPS requests to the frontend at first. If the request is for one of our static files, the frontend container returns that file. However, if the HTTP starts with /api/, the frontend reroute this request to the backend container (see the frontend/nginx.conf NGINX config file)

This deployment has several advantages:

  1. the same VM can host multiple applications running for multiple domains
  2. the frontend and the backend are on the same domain, meaning it does not require any cors setup

Working with the Code

Let’s look at the backend code in backend/src.

Starting the Development server

The file package.json contains two scripts: npm run dev to start the server in development mode and npm run prod to run the server in production mode. Depending on which mode is running, the environment variable NODE_ENV is either set to dev or prod respectively.

The file backend/src/app.mjs contains a minimal Express backend server. Open this file and review the code to see how the environment variable NODE_ENV is used:

  1. the secure flag on the session cookie is set to false in development mode but to true in production when the application is actually deployed in HTTPS
  2. The static files are served by the Express framework in development mode but not in production mode since they will be served more efficiently by our separate dockerized NGINX frontend server

Understanding the .env file

While inspecting the code, you have most likely noticed that there is another environment variable called SESSION_SECRET used for setting the session secret value. This environment variable is defined in the backend/src/.env file provided with the starter code . This file is supposed to store all kind of secrets such as session secrets, database login and passwords, API tokens to avoid having those sensitive data in the source code directly and being pushed to Github.

Indeed the .env file should not be pushed to Github but it was pushed there at first for convenience. Ideally, this file should be removed from Github and added to the gitignore file before changing all secret values. Indeed, you will need to recreate this file on the deployment VM before building the backend docker image.

Building the Features

For this assignment, you should use Node.js, the Express web framework and the embedded NoSQL database NeDB (@seald-io/nedb) to build your application. You should not need more than the packages that were introduced in the labs. Make sure that all of these required packages are recorded in the package.json file.

Important: It is recommended to push, deploy and test your application in production as you build new features. Deploying is hard and often requires some complex debugging. So do not wait for the last minute to deploy your code.

Authenticated Users and Multiple Galleries

In this part, you are going to extend your API to support authenticated users and multiple galleries. Each user will now have their own gallery. Users will be authenticated through the API (local authentication based on sessions). In addition, access to the API is ruled by the following authorization policy:

While refactoring your application, you might want to redesign your REST API to reflect the fact that image galleries are owned by users.

Integrating the Frontend

Update your current frontend to reflect all changes made above. The homepage should now be a paginated list of all galleries that can be browsed. Users should be able to sign-up, sign-in and sign-out into the application and do no longer need to enter their username when adding images and comments.