Skip to content

sendahug/send-hug-frontend

Repository files navigation

Send A Hug

CircleCI CI codecov Known Vulnerabilities Depfu Depfu

Version

Version 1 (currently in development).

Built using the gulp-site-template repo.

For full project information, check the main README file.

Code Usage and Contribution

If you want to contribute to the project, you should start by reading the contribution guidelines and the code of conduct.

The project is open source, so feel free to use parts of the code. However, the full project itself is not meant to be reused. The design, the concept and the project itself are personal and belong to the Send A Hug group.

Installation and Usage

Requirements

  • Node.js LTS
  • The back-end of the project (which you can clone here).

Developers

  1. Download or clone the repo.
  2. cd into the project directory.
  3. Run git config core.hooksPath .githooks to install the pre-commit hook, which runs prettier.
  4. Run npm install to install dependencies.
  5. Set the following environment variables (either as environment variables or within the development .env file):
    • FIREBASE_API_KEY - the Firebase API key for your project.
    • FIREBASE_PROJECT_ID - your Firebase project ID.
    • FIREBASE_AUTH_DOMAIN - the Firebase auth domain for your project.
    • FIREBASE_STORAGE_BUCKET - the Firebase storage bucket for your project.
    • FIREBASE_MESSAGING_SENDER_ID - the Firebase messaging sender ID.
    • FIREBASE_APP_ID - your Firebase App ID.
    • FIREBASE_MEASUREMENT_ID - the Firebase measurement ID (for analytics).
  6. Run npm run localdev to compile the whole project for local development.
  7. Run gulp serve to start the local server.
  8. Open localhost:3000.

For your convenience, this project utilises Gulp's 'watch' functionality. In order to activate it while developing, run gulp watch. For more information about Gulp watch, check the Gulp documentation.

Users

Not yet ready for users!

Contents

The app (located in src/app) contains several modules:

  • The root module (AppModule), defined in app.module.ts. Contains mainly the components that are available to all users, whether or not they're logged in.
  • A routing module, defined in app-routing.module.ts. Contains the app's routing.
  • An Admin module, defined in admin/admin.module.ts. Contains the components that handle admin actions.
  • A Common module, defined in common/common.module.ts. Contains components and services which are used throughout the whole app.
  • A User module, defined in user/user.module.ts. Contians the components that handle authenticated users' actions.

Each component folder contains both the HTML template and the component TypeScript file.

The components (both view-defining components and smaller components) are located in eac module's components folder (for example: src/app/components). The interfaces, used to define the types of objects in the app, are located in src/app/interfaces. The injectable services, which perform a various array of tasks, are located in each module's services folder (for example: src/app/services).

Dependencies

Gulp

The site uses several tools to maximise compatibility:

  1. Gulp - Gulp enables running tasks automatically. You can read more on the Gulp website. Gulp is a Node.js tool, so it requires installing Node.
  2. Gulp-Postcss with Autoprefixer Plugin - A Gulp plugin which adds the necessary browser prefixes to the CSS file. For more info check the Gulp-postcss page and the Autoprefixer page on NPM.
  3. Rollup - A module bundler for JS. Rollup bundles up the main module (AppModule) and converts it from TypeScript to ES6. For more info, check the Rollup repo.
  4. Gulp-Rename - A gulp plugin used to rename files. Used to rename the main module JS and to change the directory name of all HTML files. For more info check the Gulp-rename page on NPM.
  5. Gulp-replace - A string replace plugin for Gulp. Used to change the templateUrls in the final JS file. For more info, check the Gulp-replace page on NPM.
  6. Gulp-less - A gulp plugin for Less compilation. Used to compile the app's main styles, written in Less, to the CSS used in deployment. For more info, check the gulp-less page on NPM.

Angular

  1. @angular/animations - Angular's animations library.
  2. @angular/common - Angular's commonly needed services, pipes and directives.
  3. @angular/compiler - Angular's template compiler.
  4. @angular/compiler-cli - Command-line interface to invoke Angular's compiler.
  5. @angular/core - Critical runtime parts of the Angular framework.
  6. @angular/forms - Support for template-driven and reactive forms.
  7. @angular/platform-browser - Everything DOM and browser-related.
  8. @angular/platform-browser-dynamic - Providers and methods for compiling and running the app.
  9. @angular/router - Angular's router module.
  10. @angular/service-worker - Angular's ServiceWorker module.
  11. rxjs - Contains an implementation of observables, which many Angular APIs use.
  12. typescript - TypeScript language server, which Angular uses.
  13. zone.js - Implementation of zones for JavaScript (used by Angular).
  14. core-js - Modular standard library for JavaScript. Contains polyfills. For more information, check the GitHub repo.

For more information about Angular's required NPM packages, check the Angular docs.

Other

  1. IDB (formerly IDBPromised) - An improved version of IndexedDB, which is Promise-based and includes various enhancements to improve the API's usability. For more information, check the IDBP repo.
  2. Firebase - Firebase's JS SDK, used for user authentication. For more information, check the Firebase SDK's repo.

Testing Dependencies

This project's tests are run using the Jasmine framework and the Karma runner. Thus, testing requires several packages:

  1. Jasmine - An open-source behaviour-driven testing framework. For more information, check Jasmine's official site. Included packages:
    • jasmine-core
    • jasmine-spec-reporter
    • @types/jasmine - A typed version, required in order to write TypeScript tests.
  2. Karma - An open-source test-runner, used to run the tests on various devices with a test server. For more information, check Karma's official site. Included packages:
    • karma
    • karma-jasmine - A Karma adapter for the Jasmine framework. Project repo.
    • karma-jasmine-html-reporter - A reporter that shows test results in HTML. NPM page..
    • karma-chrome-launcher - A launcher for Chrome, Chrome Canary and Chromuim. Project repo..
    • karma-coverage - Code coverage generator. Project repo.
    • karma-coverage-istanbul-reporter - Code coverage generator reporter. NPM page.
    • karma-sourcemap-loader - A preprocessor that loads existing source maps. NPM page.
    • karma-rollup-preprocessor - A rollup preprocessor for karma, used to bundle up the tests. NPM page.
    • karma-viewport - A karma framework used to gain access to the viewport in tests. NPM page.
  3. Cypress - An open-source end-to-end test framework. For more information, check Cypress's official site.

Production Dependencies

  1. Express - This project uses Express in order to run a basic server in deployment. This server is used to send the static files and script to the user. For more information, check the Express website.
  2. Compression - A Node extension used to compress production files when sending them from the Express server to the client. For more information, check the compression NPM page.
  3. dotenv - A Node extension for accessing environment variables. Used by the frontend while in production mode. For more information, check the dotenv NPM page.

Authentication

The project uses Firebase as a third-party authentication provider. Authentication is done by Firebase, which in turn sets its internal currentUser property to the logged in user's data. This allows us to fetch a JWT for the given user for each of their requests.

While the frontend uses the JWT, it doesn't verify the given token. This is done by the backend. Upon login, a request is made to the server to fetch the user's data. Since getting user's data requires authentication, if the server's response contains the user's data, the frontend can treat the token as valid. Once the token is verified, the user is marked as 'authenticated'.

On top of fetching the user's data, the frontend also deals with login, logout and sign-up. These are done using Firebase's JS SDK, Firebase's client-side library. All authentication handling in the frontend is done by the AuthService.

The frontend Authentication Process:

  1. The user logs in via the login page. This passes the login details to the Auth Service, which passes them to Firebase to handle the actual login process.

  2. Once a successful response is received from Firebase, the Auth Service uses Firebase's getIdToken method to get a JWT for the current user.

  3. An attempt is made to fetch the user's data from the backend, where the token is verified. If successful, the fetched data is used as the user's data and the user is marked as authenticated.

  4. Token refresh and handling is done by Firebase whenever it's needed. In order to always have the most recent valid token, the API client fetches the current ID token (using the getIdToken method) before making each request.

  5. Upon logout, the frontend clears all user data.

Notes:

  • If the user doesn't exist in the database (the request was rejected because of something other than an AuthError), that means it's a new user. The user is then redirected to the sign up page to complete registration. Using the details provided by the user there, the AuthService makes a request to the server to add the new user to the database.

Testing

Writing Tests

Tests are written in TypeScript and each component's tests are located in the same directory as the component. Test files' names follow this format: <component_name>.spec.ts. This format is the way tests are picked up by the main testing file, and so it's important to keep to it.

Running Tests

Running tests is done through the dedicated Gulp task. All you need to do is run gulp test or npm run test in the terminal; this will start Karma and trigger Webpack's compilation of tests and project files.

End-to-End Tests

End to end tests are similarly written in TypeScript and named in the following format: <component_name>.spec.ts. They're all located in e2e/src.

Since this is a full-stack application, running end-to-end tests requires running the backend prior to running the tests. Once the backend is up and running, run gulp e2e in another terminal tab. This will compile all files, run the frontend server and then run Cypress.

Note that you will need the username and password of an admin set to two environment variables in order to run some of the tests (CYPRESS_ADMIN_USERNAME and CYPRESS_ADMIN_PASSWORD).

Hosting

The project was hosted live on Heroku (we're currently looking at alternatives, due to Heroku removing their free tier). If you want to clone and host your own version, you can do so by using the following guide (the following commands are for Heroku, but they can be adjusted depending on your host):

  1. Create a Heroku account (skip this step if you already have an account).
  2. Install the Heroku command line interface.
  3. In your Terminal, enter heroku login. This triggers logging in via the CLI.
  4. Enter heroku create <APP_NAME> (with your own app name). If successful, Heroku returns the live version's URL (will be referred to as <LIVE_URL>) and the Git repo link (will be referred to as <GIT_URL>).
  5. In your terminal, enter git remote add heroku-client <GIT_URL>.
  6. Update the live environment file with the correct variable values:
    • LOGIN_REDIRECT - set to your <LIVE_URL> (or wherever in the app you want the user to be redirected to) to ensure after login the user will be redirected to your app
    • LOGOUT_REDIRECT - set to your <LIVE_URL> (or wherever in the app you want the user to be redirected to) to ensure after login the user will be redirected to your app
    • BACKEND_URL - set with your own backend URL (necessary for making requests to the backend!)
  7. Enter git push heroku-client master. This triggers the app build. If successful, you'll get a 'Verifying deploy... done.' message.
  8. Add the following environment variables (via CLI or via the Heroku website):
    • PRODUCTION - set to true
    • FIREBASE_API_KEY - the Firebase API key for your project.
    • FIREBASE_PROJECT_ID - your Firebase project ID.
    • FIREBASE_AUTH_DOMAIN - the Firebase auth domain for your project.
    • FIREBASE_STORAGE_BUCKET - the Firebase storage bucket for your project.
    • FIREBASE_MESSAGING_SENDER_ID - the Firebase messaging sender ID.
    • FIREBASE_APP_ID - your Firebase App ID.
    • FIREBASE_MEASUREMENT_ID - the Firebase measurement ID (for analytics).
  9. All done! Now you can visit your <GIT_URL> to see the live app.

Known Issues

There are no current issues at the time.