npm package: @flexdemo/utils
Description: This Package contains serveral Utilities that are designed to make Backend Development more efficient.
Author: FlexDeMo
Latest version: 0.0.21

# FlexDeMo-Module-Utils
This Package contains serveral Utilities that are designed to make Backend Development more efficient.

## Content
 - Logging
 - Configuration
 - Messaging Utils
 - Password Validator
 - JWT Utils
 - Exceptions
 
 ## Logging
 The Logging utility can be accessed via the ``logger`` object. To use it, simply call on of the following:
  - ``logger.error(message:string)``
  - ``logger.warning(message:string)``
  - ``logger.info(message:string)``
  - ``logger.debug(message:string)``
  
  ## Configuration
  This Module provides a way to easily provide a hot-swappable Configuration to another module. To use the 
  Configuration, first one needs to create the Configuration File ``appconfig.json`` in the Root of the NodeJS Project. 
  Then it can be loaded via the ``Configuration`` Class. To initialize the ``Configuration`` Class one needs to 
  initialize a new Object of the class an call ``initialize``. After the returned Promise is resolved, the 
  Configuration can be accessed via ``Configuration.Configuration``.
  
  ### File Watcher
  ``initialize`` will also start a File watcher on the Configuration file. When the File is Changed, the Configuration
  Object is reloaded from the Configuration File. To stop the file watcher, for example to end Tests one can use 
  ``Configuration.dispose()``. ``dispose`` is an async function that will resolved once the File Watcher is completely 
  disabled.
  
  ## Messaging Utils
  ### Error Message Utils
  The Class ``ErrorMessageUtils`` contains Utils that can be used to check and create ``ErrorMessage`` Objects that can
  be used in the Communication Middleware.
  The static Method ``IsErrorMessage(message)`` can be used to determine if the `message` is a ErrorMessage.
  The Methods: 
  - `GetNotAllowedError(message)`
  - `GetNotAuthorized(message)`
  - `BadRequest(message)`
  - `GetNotImplemented()`
  
  can be used to create ErrorMessages of the specified Type (please refer to the Communication Protocol Documentation).
  
  ## Password Validator
  The Password Validator is an easy Tool to handle Password Validation. It is mostly composed out of the auth0 ``password-sheriff`` and ``dumb-passwords`` npm Packages. It can be easaly configured via the Configuration Utils.
  The Password Validator can be created by using the `new PasswordValidator()` construktor.
  ### Pasword Validation
  To Validate a Password first create a new Instance of the PasswordValidator. Then call the `ValidatePassword(password, passwordRules)` Method, where `password` is the Password that should be validated, and `passwordRules` is the Configuration Object.
  The Method will return (void) when the Password is accepted, and throw a `PasswordInvalidException` with a message and a German `displayMessage` to show the User.
  ### Password Rules
  The Configuration Object can be assembled out of all options. All Options are Optional.
  ```javascript
  {
     minLength: number, //The minimal Length of the Password
     maxLength: number, //The Maximal Length of the Password (should not be set, unless for Attack Protektion of long strings)
     requiresSpecial: boolean, //Passwords need a Special Char (see https://owasp.org/www-community/password-special-characters)
     requireUpper: boolean, //Passwords needs a Upper Case Letter
     requireLower: boolean, //Password needs a Lower Case Letter
     requiresNumbers: boolean, //Password needs a Numerical Charecter
     checkIfCommon: boolean //Checks the password against a table of the 10000 most common Passwords
  }
  ```

  ## JWTUtils
  This Modules Provides Utils (in form of a small Wrapper) to Provide JWT Token Generation and Validation functionality
  ### Generate
  The ``async JwtUtils.Generate(data, secrets, options)`` function can be used to Generate a JWT Token.
  
  The Parameter ``data`` can be used to supply the Data that will be send to the client. **This Data ist not Encrypted!**
  
  The Parameter ``secrets`` is a Dictionary of Keys. A Random supplied Key is used and encoded in the kid header field. Example:
  ```javascript
    let secrets = {
        "112eab91-6226-4000-a698-bb11f613dd74": "vkmZJW4%1%y1GXt*",
        "7dfc20a0-313a-4a3f-91e9-583f4f844e7c": "#%5qz3P!QZ@YrT6T"
    };
  ```

  The Parameter ``options`` contains multiple parameters that should be set!
  ``options.expiresIn`` contains a number with seconds or a string with a timeframe in witch the Token will be valid.
  Examples: ``60``, ``"1h"``, ``"2 days"``
  ``options.audience`` is a String to set the audience the token was generated for.
  ``options.issuer`` is the name of the issuing Service (For example "FlexDeMo - Auth")
  ``options.subject`` is the Subject this Token was created for. This will be the tenantId.
  
  The function Returns a Promise that can resolve to a String, null or Error.
  
  ### Validate
  The function ``JwtUtils.Validate(token, secrets, audience)`` validates a JWT Token.
  
  The Parameter ``token`` is a String that contains the JwtToken.
  
  The Parameter ``secrets`` is a Dictionary of Keys. The Key will be determined by the kid claim of the Token. Example:
  ```javascript
    let secrets = {
        "112eab91-6226-4000-a698-bb11f613dd74": "vkmZJW4%1%y1GXt*",
        "7dfc20a0-313a-4a3f-91e9-583f4f844e7c": "#%5qz3P!QZ@YrT6T"
    };
  ```


The Parameter ``audience`` is an array of Strings. These contain the allowed audiences of the Service. If the ``aud`` claim of the Token does not match one of the Audiences, the Token will not be verified.

If the Token is Validated it will return a Object with a ``header``, ``payload`` and ``signature`` field. Where the Payload is the encoded data.
If the Token is not Validated, it will throw a ``NotAuthenticatedException``;

By default, the token validation is heavily logged. The Log Level can be changed by setting the ``AUTH_LOGGER_LEVEL`` ENV var to one of the default levels of [winston](https://github.com/winstonjs/winston#logging).

Validation Logging can be completely turned off by setting the ``AUTH_LOGGER_SLIENT`` Env var to ``true``.

## JwtAuthData
JwtAuthData is a Class that capsules the currently send data in neat and tidy way. To use it, the Token first needs to 
be validated. This can be archived by usage of the ``JwtUtils``. Then the validated resultes can be passed to the 
constructor of JwtAuthData to create the wrapper object
```javascript
let authData = new JwtAuthData(JwtUtils.Validate(token, secrets, audience));
```

The instance has the following attributes that can be read:
- ``AuthType`` The Type of Authentification used. Should be "jwt"
- ``Algorithm`` The Hashing Algorithem used
- ``TokenKeyId`` The Key Id that was used while creating this Token. Primarely Used to retrive the correct Password
- ``User`` The User Object
- ``User.id`` UUID v4 that identifies the User
- ``User.roles`` Array of UUID v4 that identifies all Roles this user has for this Application
- ``User.tenantRoles`` Array of UUID v4 that identifies all Roles this user has for the Tenantdata
- ``IssuedAt`` The Time this auth token was created at
- ``Expires`` The Time this token expires
- ``Audience`` The Aufience this token was created for
- ``Issuer`` The Issuer of the Token
- ``TenantId`` The UUIDv4 of the Tenant that this User belongs to
  
  ## Exceptions
  ### AlreadyExistsException
  This Exception can be thrown if an Element could not be created or changed, because an other Element already exists.
  #### Usage
  ``new AlreadyExcistsException(message, innerException)``
  ``alreadyExistsException.toString()`` can be used to create a readable String of the exception
  ### ArgumentException
  This Exception can be thrown if some Argument was Missing, or if an Argument had the wrong Type or Format.
  #### Usage
  ``new ArgumentException(parameterName, parameterValue)``
  ``argumentException.toString()`` can be used to create a readable String of the exception;
  
  ### BadRequestException
  This Exception can be thrown if a Communication Middleware returns a Bad Request Event.
  #### Usage
  ``new BadRequestException("Cold not call Auth Middleware", error)``
  ``exception.toString()`` can be used to create a readable String of the exception;
  
  ### ConfigurationException
  This Exception can be thrown if the ApplicationConfiguration is malformed or Contains errors.
  #### Usage
  ``new ConfigurationException("Missing Configuration for Data Provider URL", innerException)``
  ``exception.toString()`` can be used to create a readable String of the exception;
  
  ### NotAuthenticatedException
  This Exception can be thrown if the user could not be authenticated. Ether as a LoginError, or because the 
  Session Token was wrong or missing
  #### Usage
  ``new NotAuthenticatedException("Session Token Hash not valid", innerException)``
  ``exception.toString()`` can be used to create a readable String of the exception;
  
  ### NotAuthorizedException
  This Exception can be thrown if the user accessed a Function or Resource for witch he is not Authorized. 
  #### Usage
  ``new NotAuthorizedException("User is not allowed to view Admin Area", innerException)``
  ``exception.toString()`` can be used to create a readable String of the exception;
  
  ### NotImplementedException
  This Exception can be thrown, if a Function is called, witch currently is not Implemented.
  #### Usage
  ``new NotImplementedException("GetUsers() not Implemented jet", innerException)``
  ``exception.toString()`` can be used to create a readable String of the exception;
  
  ### PasswordInvalidException
  This Exception is thrown, if the PasswordValidator can not Validate the supplied Password. Has the Attribute `displayMessage` in wich a German string is saved, witch can be shown to the User.
  
  
  ### TimeoutException
  This Exception can be thrown if some Timeout was met, for example if a Response from a Request to via the 
  ConnectionService takes to long.
  #### Usage
  ``new TimeoutException(message, innerException?)`` will create a new Timeout Exception.
  ``timeoutException.toString()`` will create a proper error String that can be displayed.