Sign inSign up

nightcruisetech/passit-frontend

By nightcruisetech

•Updated almost 8 years ago

Image
0

215

nightcruisetech/passit-frontend repository overview

⁠Passit Front

passit-frontend is the angular client for Passit⁠.

We use smart and dumb components with ngrx/store. Read about it here⁠

API and crypto interaction are handled by passit-sdk-js which itself uses libsodium.js.

⁠Install Extensions

⁠Start developing

  1. Install docker and docker-compose
  2. Run docker-compose up

The front end is now running on localhost:4200 and the backend docker image is running on localhost:8000

Run any one off commands like docker-compose run --rm web ng to execute them inside the docker container.

You may want to run the client without docker. This is helpful when writing unit tests or for quickly adding packages. If you'd like to do this:

  1. Start the backend in docker docker-compose up api
  2. Ensure yarn and node 8 are installed
  3. Install node packages yarn
  4. Run the frontend yarn start or use any yarn ng command from angular-cli.
⁠Rebuilding when changing package.json

If you need to run yarn install you'll want to instead run docker-compose build and docker-compose rm -v app to remove the old container. This is because node_modules are kept in a docker volume. This is not ideal - if you know how to build node_modules into the container itself instead of a volume please let us know.

⁠Running unit tests

Run yarn test to execute the unit tests via Karma⁠.

⁠Running end-to-end tests

End-to-end tests are run via Protractor⁠.

We'll run the backend in docker and the frontend without for simplicity. Ensure you run yarn first to install local node modules.

  1. Start backend docker-compose up api
  2. Start dev server yarn start
  3. Run test yarn run e2e

The e2e script will use the existing dev server (so you don't have to wait for it to rebuild each time)

We can also run the e2e tests against firefox, by setting the FIREFOX environmental variable to something and we can run them against the web extension by setting EXTENSION env variable to be something (before testing against the extension you have to build it with build:ext.

We can also run the tests in docker:

docker-compose up -d app selenium-<chrome/firefox>
[docker-compose run app build:ext]
docker-compose run [-e FIREFOX=true] [-e EXTENSION=true] app e2e:docker
⁠end-to-end test structure and how to

We ensure that each describe block can be run in any order. However each it step inside a block actually must run in order - as to minimize set up time which is time consuming due to expensive crypto functions being used when logging in.

  • The describe blocks do not need to run in order.
  • Each describe block creates a new user.
  • Some it statements within a describe block depend on state from previous tests and need to run in order.

New users are created in the docker backend with random user names to prevent collisions. This means we don't have to wipe the backend between tests which also saves time (at the expense of this being slightly ugly).

⁠Coding Style and Linting

Follow style and design patterns as seen on the ngrx example-app⁠ and from angular-cli.

yarn lint
⁠Error handling

Error and validation can get complex. We have the backend API, js SDK, services, and effects as potential sources of errors. Here are some guidelines:

  • Do use ngrx-forms's client side validation
  • Only use ngrx-forms async validation for "as you type" server side validation. Do not use it for server errors.
  • The SDK should always throw IPassitSDKError type errors.
  • Services should not handle errors, services are just very thin wrappers around the SDK
  • Effects should handle errors by deciding what action to return.
    • If the user is submitting a form - handle the error in the effect and show a nice message (Ex: "Server Error"). Let the component display the error as seen fit (instead of a global method of notification)
    • If the error is authentication related, do return the HandleAPIErrorAction instead of handling the auth error yourself.
    • When not working with a form (ex: refresh groups from server) return the HandleAPIErrorAction. This is a generic error that will run some common checks on the server response (is the user logged in? Email Validated?) and handle those. If the error does not match any way to handle it - it will simply log to the console.

⁠Development for web extension

The web extension works in Firefox and Chrome. It reuses the same angular code but we need to build it differently.

For development:

We'll run this time without docker (though you could use docker). We want to build the app with aot and watch enabled for auto reload. Then we'll run web-ext to launch the code as an extension in Firefox.

  1. Run backend either in docker (docker-compose up -d api) or hosted service
  2. yarn install (if not done already)
  3. yarn run build:ext --watch
  4. (new term) yarn web-ext run -s dist/ -a dist/

This process can be a little slow. You are encouraged to use test driven development or working on the web front end when possible. Because the app shares the same code, going to routes like /popup actually work fine in the web version. However note when not running as an extension you won't have access to web extension api's like the browser object.

If you'd like to try the extension in Chrome:

  1. Do steps 1-4 above
  2. Open up Chrome and go to Extensions
  3. Check the "Developer Mode" box up top if you haven't already done so.
  4. Click "Load unpacked extension..." and select the dist/ folder.
⁠Autofill development

Autofill code is injected into the page. It must be compiled but the process is currently very awkward.

  1. Remove export from extension/form-fill/form-fill.ts
  2. Compile with yarn build:autofill
  3. Copy and paste the resulting js file into autofill-compiled.ts as a string.

Open an issue if you know a better way. Only plain js strings and js files can be inserted directly into a web page. Ideally webpack should do all this but I'm not sure how to get webpack to output a plain js file (without the module bootstraping) or how to force it to strip out exports. Note the exports must exist so that it can be used in tests.

⁠Deploying new extension

We don't distribute the firefox extension on the store, because they won't accept angular code - see #15. So instead we self host, signing it with the web-ext command in CI and creating an update manifest Firefox knows when to update⁠.

  1. Change version in src/manifest.json
  2. Commit those changes
  3. Add a git tag in the format vX.X.X
  4. Push the changes and git tag to Gitlab
  5. Once all build steps finish, download the passit.zip to upload to the chrome webstore. It is available as an artifact under the build-ext-assets job in the test stage.
  6. Create a new release on the Chrome web store⁠

⁠Mobile app

We use NativeScript for the mobile app⁠. At this time it's not ready to use.

⁠Technologies used

Tag summary

Content type

Image

Digest

Size

207.7 MB

Last updated

almost 8 years ago

docker pull nightcruisetech/passit-frontend