myhealthpass-auth
TypeScript icon, indicating that this package has built-in type declarations

2.0.1 • Public • Published

Case Study Exercise - MyHealthPass Authentication and Authorization Library

This package is the authentication and authorization library to be used by the MyHealthPass health system.
The package was written in TypeScript and npm packages have been created for the two releases.
An example of how it can be used within a Node.js web application is shown below.

Installation

npm

npm install myhealthpass-auth

Getting Started

To use the package the auth object must be instantiated as seen below:

import { AuthApp } from 'myhealthpass-auth';

// ...

const config = {
    authSecret: 'my-secret',
    accountsStore: new YourAccountStore(),
};
  
const authApp = new AuthApp();
const auth = authApp.configure(config);

The YourAccountStore object would be your concrete implementation of the provided IAcccountStore interface, to handle the retrieval and storage of accounts to an actual data store.

The auth object can then be used to call the various methods.

// register
const details = new AccountDetails('username');
const registerResult: Account = auth.register(details, 'password');

// login
const loginResult: Account = auth.login('username', 'password');

// authenticate token
const valid: boolean = auth.authenticate(loginResult.token!);

// upload a profile picture
auth.accountHandler.saveProfileImage('username', 'base64-profile-picture');

Configuration

The configuration object used above comes with default values described in the case study. However, for extensibility, these configuration values can be overridden.

const config = {
    authSecret: 'my-secret',
    accountsStore: new YourAccountStore(),
    imageFolderLocation: "C:\\Users\\userprofile\\Downloads",
    bruteDetection: {
      failedCount: 10, // for 10 failed attempts
      requestTimePeriod: 10, // within 10 secs
      lockedPeriod: 5 // lock requests for 5 secs
    }
};

Data Models

The following are the data models used within the package:

  • Account: This is used as a representation of the registered or logged in user. It is used to track the user token and whether or not the user account is locked.
  • AccountDetails: This is used as a representation of data passed to the library during registration.

Assumption: The consumer should make use of the Account and AccountDetails models to map to data in their backing database/storage. It is also used to track the profile picture and region the user belongs to.

  • Region: This is used to track what region the user belongs to and therefore what policies should be applied to them.

Assumption: All regions would have the default lockout policy, as described by the 3 failed login attempts, in the case study.

  • Request: This is used to track the login request made to the library.

Assumption: The consumer's web API is responsible for the population of this object when calling the login method. Any calls to the login method without the populated Request object will fail.

  • RequestTrace: This is used to track additional data about the Request and therefore detect possible brute force attacks.

Regions & Policies

Assumption: Regions are representations of time zones.

Therefore a list of possible regions is created by the package for use to add to an account. The consumer will not be creating their own regions.

As stated in the case study, different authentication rules such as session length, password policies and user lockout policies are configured by region. As such, interfaces were created for the possible password and user lockout policies, called IPasswordPolicy and ILockoutPolicy, respectively.

Assumption: The locking of a user's account after 3 failed login attempts, is a type of user lockout policy. Each region has therefore been given a default ILockoutPolicy of FailedLoginPolicy.

There are also helper methods available to add and remove policies from regions in the RegionHandler class.
These are:

- addPasswordPolicy(regionIdentifer: string, policy: IPasswordPolicy)  
- removePasswordPolicy(regionIdentifer: string, policyIdentifer: string)  
- addLockoutPolicy(regionIdentifer: string, policy: ILockoutPolicy)  
- removeLockoutPolicy(regionIdentifer: string, policyIdentifer: string)  

Interfaces

The following are the interfaces available for use in the package:

  • IAccountStore: The inheriting class should be a concrete implementation that uses the backing database/storage to:
    • getAccount(username: string)
    • addNewAccount(account: Account)
    • recordProfilePhoto(username: string, base64ImageStr: string)
  • ILockoutPolicy: This is a type of user lockout policy that can be added to a region.
    The implementations would determine the conditions for the lock with:
    • shouldLock(obj: any): boolean
      And set the lock period with:
    • lockPeriod: number
  • IPasswordPolicy: This is a type of password policy that can be added to a region.
    The implementations would determine the conditions for the password policy with:
    • validate(password: string): boolean

Tests

Unit tests have been created for the case study and can be run by using a terminal in the solution directory to run:

npm install

To ensure that the required packages are installed.
Then run:

npm run test

Assumptions

The following are some assumptions made while developing the solution:

  • Both the login and register methods return an Account object that includes a token which the user can use to authenticate.
  • This package does not handle the actual storage of data. The consumer should make use of the Account and AccountDetails models to map to data in their backing database/storage after login and registration.
  • The consumer should implement the IAcccountStore to handle the actual retrieval and storage of accounts.
  • The login method was expanded to include a Request object parameter for brute force prevention.
    • This object must contain the properties of user agent, client IP address and request signature.
    • A brute force attack would come from a malicious person calling the consumer's web API. Therefore the consumer must ensure that the user agent, client IP address and request signature are captured for each call to their web API and passed along to the library to validate against.
    • Any calls to the login method without the populated Request object will fail.
  • Regions are representations of time zones.
  • An account can only belong to one region, therefore the region will get set at the time of registration, either through a timezone property passed with accountDetails during registration or set by the user's current timezone, if one is not provided.
  • The locking of a user's account after 3 failed login attempts, is a type of user lockout policy.
  • All regions would therefore have this default lockout policy, as described by the 3 failed login attempts, in the case study.
  • The ability to upload a profile picture is handled by the saveProfileImage method in the AccountHandler class.
    • This method is called during the registration process, as well as can be called by the consumer within their application.
    • The consumer should provide a folder path to store the profile image through the configuration setting. This will be used to store the image on the file system.
    • Additionally, the consumer should implement the recordProfilePhoto method in the IAcccountStore interface, to do any additional storing or processing of the image, as it is also called by the saveProfileImage method.
  • UTC dates are used for all date calculations to avoid timezone conflicts.
  • All time period configuration options represent seconds.

Diagrams

The diagrams describing the architecture can be seen here.


Usage

The provided Node.js web application under examples > node-app, can use used to test the implementation of the package.

Installation

  1. Download the node-app folder
  2. Open a terminal in the folder and run npm install
  3. Run the node app by running npm run start
  4. Using a tool for testing API requests, make a request to the endpoint of the running node application, likely http://localhost:3000.

Making Requests

Register

POST http://localhost:3000/register

Example Body:

{
    "accountDetails": {
        "username": "bob", 
        "fullName": "Bob Smith",
        "timezone": "America/La_Paz",
        "profilePicture": "base64string"
    },
    "password": "password1"
}

Login

POST http://localhost:3000/login

Example Body:

{
    "username": "bob", 
    "password": "password1"
}

Authenticate

POST http://localhost:3000/authenticate

Example Body:

{
    "token": "token-received-after-login-or-register",
}

Package Sidebar

Install

npm i myhealthpass-auth

Weekly Downloads

0

Version

2.0.1

License

ISC

Unpacked Size

39.1 kB

Total Files

42

Last publish

Collaborators

  • keisha.waithe