Documentation for a newer release is available. View Latest

Operational Dashboard - Changes & Fixes

This page covers the changes and fixes provided to Operational Dashboard for IPF Release 2025.1.0

New

Strict Transport Security Header Sent With Each HTTP Response

  • The Strict Transport Security header is configured to apply to all requests and all subdomains, ensuring that all traffic is securely served over HTTPS.

  • The preload directive is enabled, allowing the domain to be added to the HSTS preload list for enhanced security. (Note: This attribute has no effect unless the domain is successfully added to the preload list.)

  • The max-age attribute is configurable via the hsts-max-age setting.

The hsts-max-age Value Must Be Increased

  • By default, max-age is set to 300 seconds (5 minutes). The recommended minimum is 31536000 seconds (1 year), but it is advisable to increase this value incrementally during deployment.

  • A lower default value provides a grace period for testing. Once a browser enforces HSTS for a domain, it remembers the policy until the max-age expires. Increasing the max-age is simple, but reducing it can be challenging due to browser enforcement.

  • Best practice is to start with a low value, test thoroughly, and gradually increase to a long-term secure value. More information can be found here: hstspreload.org/

Functionality to cancel future dated payments

  • The functionality to cancel future dated payments has been added to the ODS Payment summary screen. This allows users to cancel payments that have a global status in SCHEDULED or PENDING categories.

  • To access this new feature you need to have the following permission: ROLE_PAYMENT_CANCEL

  • The repair button will only be enabled if the payment global status is in one of the two categories mentioned above. The repair button will not be enabled if the payment global status is in any other category or on the Recall and Bulk summary pages.

  • Changes to the global status config and introduction of categories has been explained in the Changed section below.

    NOTE: The cancel functionality has only been added on the frontend, there needs to be a backend implementation added in order for this to work which will be avaliable in the near future.
  • The duration of how long a JSON Web Token as well as cookie is valid for from the moment of log in can be configured via ipf.business-operations.auth.jwt.expiry.

  • The user can provide this value given in seconds, minutes, hours and days. The value of the set duration has to fall between 1 minute and 7 days. If this value is misconfigured, the application will not start up.

  • The default configuration for this property is 1 hour.

Configurable Signature Algorithm for JSON Web Token

  • Signature Algorithm can be configured via setting ipf.business-operations.auth.jwt.signature-algorithm along with further required properties for the chosen algorithm to correctly work.

  • Supported algorithms are HS512 and ES512.

  • ipf.business-operations.auth.jwt.secret has to be defined when HS512 is chosen as signature algorithm.

  • ipf.business-operations.auth.jwt.path-private-key and ipf.business-operations.auth.jwt.path-public-key have to be defined when ES512 is chosen as signature algorithm.

Granular Permissions Protocol introduced and leveraged by GUI HTM Module

  • Granular Permissions Protocol has been created, which is used by the HTM endpoints in the Dashboard.

  • The present, role-based permissions remain in use for the endpoints of the rest of the GUI modules.

  • ipf.authorisation.conf has to be overriden with custom groups, roles and HTM specific contexts to leverage granular authorisation for selected users for access to HTM tasks.

  • Default config included in ipf.authorisation.conf reuses legacy roles, such as ROLE_HTM_VIEWER, ROLE_HTM_EXECUTE, etc. with permission scopes respectively which replicate authorisation scope as they were used in roles-based protocol.

  • The new protocol comes with its own terminology and in order to set up authorisation scopes correctly for HTM GUI module, it is recommended to study the published docs in detail: Granular Authorisation

Changed

Basic Auth Now Disabled by Default

  • Basic auth should not be used in production and is disabled by default. It is intended only for development and testing purposes. Enable it with:

    • ipf.business-operations.auth.basic-auth.enabled = true

Changes to Global Status Config

  • The global status config has been changed from an array of strings to an array of objects. Here is an example of what it should look like now:

global-statuses = [
    {
        name: "Pending",
        category: "PENDING"
    },
    {
        name: "Accepted",
        category: "ACCEPTED"
    },
    {
        name: "Completed",
        category: "ACCEPTED"
    },
    {
        name: "Rejected",
        category: "REJECTED"
    },
    {
        name: "Manual Action Required",
        category: "MANUAL_ACTION_REQUIRED"
    },
    {
        name: "Scheduled",
        category: "SCHEDULED"
    },
    {
        name: "Cancelled",
        category: "CANCELLED"
    }
  ]

This is a breaking change. If you have a custom global status config, you will need to update it to match the new format. The name value should be set as whatever you would like the global status to be, and this is the value that will show up on the UI. Each status should be assigned one of 6 categories that has the closest meaning to the global status name. There are only 6 status categories available, and you should not assign a category that does not exist in the following list: PENDING, ACCEPTED, REJECTED, MANUAL_ACTION_REQUIRED, SCHEDULED, CANCELLED. There can be more than one status in each category. Categories have been introduced because they drive certain screen behaviours in the UI, therefore the UI will not work as expected if the category is left null.

Removal of Active User Service

  • Following changes from PAY-12897 and PAY-12894, the active user service has been removed.

  • Any references to this service should now reference the ngrx store instead as the single source of truth as we no longer decode the JWT locally.

For example, if you used the activeUserService to get the logged in user:

this.loggedInUser = activeUserService.getActiveUserInfo();

This can be replaced with

 this.store.select(selectActiveUser).pipe(
    map((username: string) =>
        (this.loggedInUser = username)
    ));

This is not recommended as we should not be mapping from the selector

  • Rather we should handle the loggedInUser as this

 this.loggedInUser$ = this.store.select(selectActiveUser);

Where loggedInUser$ is now an Observable<string | undefined>

  • Typically, you don’t want to ever reference the logged in user outside of an effect unless it’s for display purposes.

Custom Translations Supplied At Release

  • Default translations for the IPF Operational Dashboard are supplied at build.

    • Each module has its own scoped translation file, e.g.: i18n/htm/en.json

    • In addition, a global translation file now exists for shared or frequently reused terms: i18n/en.json

    • At runtime, the global translations are merged into the scoped translations. All keys from the global file are accessible under the scoped namespace. If the same key exists in both the scoped and global files, the scoped translation takes precedence.

  • Custom translations can be supplied at release time by adding a HOCON file in the following location: config/bizops/i18n/{scope}/{lang}.conf (eg. config/bizops/i18n/htm/en.conf)

    • This file may include all or just some of the scoped translations. It is not mandatory to provide any custom translations - if the file is missing, the application will use the defaults.

To facilitate this functionality, all translations should be grouped into the following categories:

  • navigationItem

  • title

  • heading

  • text

  • columnHeader

  • rowHeader

  • formField

  • tooltip

  • tab

  • button

  • warning

  • error

  • metadataField

Additionally, certain best practices should be followed. Please refer to Translation Guidelines for more details.

  • The cookie is now httpOnly meaning we no longer have access to it in the FE

  • You will need to update the configuration of the providers for your application to handle the changes made on the module

This is a breaking change routerReducer has to be provided for the store module and StoreRouterConnectingModule must also be provided

For example, it should be changed from this:

 StoreModule.forRoot(
    {},
    {
        runtimeChecks: {
            strictStateImmutability: false,
            strictActionImmutability: false
            }
    }),

To this:

 StoreModule.forRoot(
    {
        router: routerReducer
    },
    {
        runtimeChecks: {
            strictStateImmutability: false,
            strictActionImmutability: false
            }
    }),
    StoreRouterConnectingModule.forRoot()

You will also need to update your routing for the root path so that we are actually checking the user is authenticated and has a valid Processing Entity

    {
        path: 'app',
        canActivate: [ProcessingEntityGuard],
        component: AppHomeComponent
    },