Loginapp Design Kit navigation menu configuration

  • By default, the Loginapp Design Kit provides a navigation menu that consists of:
  • All pages that exist in the Loginapp UI.
  • Example custom pages.

Overview of the Loginapp Design Kit navigation menu structure

The Design Kit provides a configuration for navigation to alter the navigation menu:

Show moreShow less
navigation: { 
    authentication: { 
         ... 
    }, 
    registration: { 
         ... 
    }, 
    publicSelfServices: { 
         ... 
    }, 
    protectedSelfServices: { 
         ... 
    }, 
    error: { 
         ... 
    } 
}
  • The navigation is structured as a two-tier hierarchy:
  • The top-tier navigation is modeled after the main functions of the Loginapp UI.
  • The second-tier navigation structures the menu into functional or technical groups.
  • Each group provides links to individual pages of the UI.

Path placeholders with flow IDs and step IDs

Every entry in the navigation structure contains the path pointing to the UI page. A path may contain a placeholder FLOW that is replaced with the configuration of config.flows.defaultFlowId.

Using the FLOW placeholder allows viewing the same page in different flows. However, its use is optional and it is possible to hardcode the flow ID in the path.

The password reset pages use a fixed 'default' flow ID and do not use the FLOW placeholder.

It is possible to add a step ID to a path definition. This supports different customizations of the same page with distinct step IDs. Note that the flow ID and the step ID may only consist of lowercase letters, numbers, hyphens and underscores.

  • The example below demonstrates:
  • The first two paths uses the FLOW placeholder.
  • The third path uses fixed-flow-id as flow ID.
  • The second path adds a step ID.

Example:

navigation: { 
    authentication: { 
        customUi: [ 
            {path: '/auth/flow/{{FLOW}}/password'}, 
            {path: '/auth/flow/{{FLOW}}/password', stepId: 'another-step-id'}, 
            {path: '/auth/flow/fixed-flow-id/password'} 
        ] 
    } 
}

FLOW and stepId only apply to pages representing flow steps.

Adding pages using custom UI

Airlock IAM allows certain pages to be configured via server-side configuration or to be written in JavaScript.

  • The URLs of those pages are characterized by either having "data" or "ext" in their paths:
  • data pages are provided by IAM and are included in the standard navigation menu.
  • ext pages can be added to the navigation menu using the customUi block.

Example:

navigation: { 
    authentication: { 
        customUi: [ {path: '/auth/flow/{{FLOW}}/ext/example-one'}, 
                    {path: '/auth/flow/{{FLOW}}/ext/example-two'} 
        ] 
    } 
}

data and ext are always included in the step ID as part of the path. In the above example, example-one and example-two are both step IDs. Configuring a step ID using stepId will therefore not have any effect.

Modifying the Loginapp Design Kit navigation

  • The Design Kit navigation behaves differently when adding pages:
  • customUi pages will be added to the standard navigation menu.
  • The configuration of product pages will remove the entire standard navigation menu and replace it with the configured pages.
  • Error pages will not be removed unless an empty error block is configured.

Example:

navigation: { 
    authentication: { 
        password: [ 
            {path: '/auth/flow/{{FLOW}}/password'}, 
            {path: '/auth/flow/{{FLOW}}/password/change'} 
        ] 
    } 
}

The above example configuration would result in a navigation menu that only consist of the entries for username password authentication, password change and the standard error pages.

Full navigation configuration

To help you with customizing the navigation menu, the full configuration is as follows:

copy
navigation: {
    authentication: {
        password: [
            {path: '/auth/flow/{{FLOW}}/password'},
            {path: '/auth/flow/{{FLOW}}/password-only'},
            {path: '/auth/flow/{{FLOW}}/password/change'}
        ],
        airlock2fa: [
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/additional-activation'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/challenge'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/challenge-only'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/device/edit'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/device/selection'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/migration'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/passcode'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/qrcode-only'},
            {path: '/auth/flow/{{FLOW}}/airlock-2fa/usernameless'}
        ],
        mtan: [
            {path: '/auth/flow/{{FLOW}}/mtan'},
            {path: '/auth/flow/{{FLOW}}/mtan/registration/verification/iak'},
            {path: '/auth/flow/{{FLOW}}/mtan/registration/verification/otp'},
            {path: '/auth/flow/{{FLOW}}/mtan/selection'}
        ],
        fido: [
            {path: '/auth/flow/{{FLOW}}/fido'},
            {path: '/auth/flow/{{FLOW}}/fido/passwordless'},
            {path: '/auth/flow/{{FLOW}}/fido/registration'}
        ],
        cronto: [
            {path: '/auth/flow/{{FLOW}}/cronto/activation'},
            {path: '/auth/flow/{{FLOW}}/cronto/activation/complete'},
            {path: '/auth/flow/{{FLOW}}/cronto/activation/on-screen'},
            {path: '/auth/flow/{{FLOW}}/cronto/challenge'},
            {path: '/auth/flow/{{FLOW}}/cronto/push-activation'},
            {path: '/auth/flow/{{FLOW}}/cronto/selection'}
        ],
        email: [
            {path: '/auth/flow/{{FLOW}}/email/otp'},
            {path: '/auth/flow/{{FLOW}}/email/verification/otp/check'}
        ],
        otp: [
            {path: '/auth/flow/{{FLOW}}/oath-otp'},
            {path: '/auth/flow/{{FLOW}}/otp'},
            {path: '/auth/flow/{{FLOW}}/vasco-otp'}
        ],
        oauth2: [
            {path: '/auth/flow/{{FLOW}}/oauth2/consent'}
        ],
        secretQuestions: [
            {path: '/auth/flow/{{FLOW}}/secret-questions'}
        ],
        ssi: [
            {path: '/auth/flow/{{FLOW}}/ssi/invitation', incubating: true},
            {path: '/auth/flow/{{FLOW}}/ssi/issuance', incubating: true},
            {path: '/auth/flow/{{FLOW}}/ssi/verification', incubating: true}
        ],
        identification: [
            {path: '/auth/flow/{{FLOW}}/identification'},
            {path: '/auth/flow/{{FLOW}}/username'}
        ],
        varia: [
            {path: '/auth/flow/{{FLOW}}/data/example'},
            {path: '/auth/flow/{{FLOW}}/matrix'},
            {path: '/auth/flow/{{FLOW}}/message'},
            {path: '/auth/flow/{{FLOW}}/migration-selection'},
            {path: '/auth/flow/{{FLOW}}/selection'},
            {path: '/auth/flow/{{FLOW}}/terms-of-service'},
            {path: '/auth/logout/disclaimer'}
        ],
        customUi: [
            {path: '/auth/flow/{{FLOW}}/ext/example'}
        ]
    },
    registration: {
        selfRegistration: [
            {path: '/registration/flow/{{FLOW}}/confirmation'},
            {path: '/registration/flow/{{FLOW}}/data/example'},
            {path: '/registration/flow/{{FLOW}}/message'},
            {path: '/registration/flow/{{FLOW}}/selection'},
            {path: '/registration/flow/{{FLOW}}/ssi/invitation', incubating: true},
            {path: '/registration/flow/{{FLOW}}/ssi/verification', incubating: true},
            {path: '/registration/flow/{{FLOW}}/terms-of-service'},
            {path: '/registration/flow/{{FLOW}}/verification/email'},
            {path: '/registration/flow/{{FLOW}}/verification/phone-number'}
        ],
        tokens: [
            {path: '/registration/flow/{{FLOW}}/airlock-2fa/device/add'}
        ],
        customUi: [
            {path: '/registration/flow/{{FLOW}}/ext/example'}
        ]
    },
    publicSelfServices: {
        selfServices: [
            {path: '/self-service/flow/{{FLOW}}/approval/airlock-2fa/challenge'},
            {path: '/self-service/flow/{{FLOW}}/approval/airlock-2fa/challenge-only'},
            {path: '/self-service/flow/{{FLOW}}/approval/airlock-2fa/qrcode'},
            {path: '/self-service/flow/{{FLOW}}/approval/airlock-2fa/selection'},
            {path: '/self-service/flow/{{FLOW}}/approval/cronto/challenge'},
            {path: '/self-service/flow/{{FLOW}}/approval/cronto/selection'},
            {path: '/self-service/flow/{{FLOW}}/approval/fido'},
            {path: '/self-service/flow/{{FLOW}}/approval/matrix'},
            {path: '/self-service/flow/{{FLOW}}/approval/mtan'},
            {path: '/self-service/flow/{{FLOW}}/approval/mtan/selection'},
            {path: '/self-service/flow/{{FLOW}}/approval/vasco-otp'},
            {path: '/self-service/flow/{{FLOW}}/confirmation'},
            {path: '/self-service/flow/{{FLOW}}/email'},
            {path: '/self-service/flow/{{FLOW}}/identification'},
            {path: '/self-service/flow/{{FLOW}}/message'},
            {path: '/self-service/flow/{{FLOW}}/mtan'},
            {path: '/self-service/flow/{{FLOW}}/password'},
            {path: '/self-service/flow/{{FLOW}}/secret-questions'},
            {path: '/self-service/flow/{{FLOW}}/selection'},
            {path: '/self-service/flow/{{FLOW}}/ssi/invitation', incubating: true},
            {path: '/self-service/flow/{{FLOW}}/ssi/verification', incubating: true},
            {path: '/self-service/flow/{{FLOW}}/username'}
        ],
        customUi: [
            {path: '/self-service/flow/{{FLOW}}/ext/example'}
        ]
    },
    protectedSelfServices: {
        selfServices: [
            {path: '/protected/account-links'},
            {path: '/protected/flow/{{FLOW}}/approval/airlock-2fa/challenge'},
            {path: '/protected/flow/{{FLOW}}/approval/airlock-2fa/challenge-only'},
            {path: '/protected/flow/{{FLOW}}/approval/airlock-2fa/qrcode'},
            {path: '/protected/flow/{{FLOW}}/approval/airlock-2fa/selection'},
            {path: '/protected/flow/{{FLOW}}/approval/cronto/challenge'},
            {path: '/protected/flow/{{FLOW}}/approval/cronto/selection'},
            {path: '/protected/flow/{{FLOW}}/approval/fido'},
            {path: '/protected/flow/{{FLOW}}/approval/matrix'},
            {path: '/protected/flow/{{FLOW}}/approval/mtan'},
            {path: '/protected/flow/{{FLOW}}/approval/mtan/selection'},
            {path: '/protected/flow/{{FLOW}}/approval/vasco-otp'},
            {path: '/protected/flow/{{FLOW}}/confirmation'},
            {path: '/protected/flow/{{FLOW}}/data/example'},
            {path: '/protected/flow/{{FLOW}}/email/verification/otp/check'},
            {path: '/protected/flow/{{FLOW}}/message'},
            {path: '/protected/flow/{{FLOW}}/mtan/registration/verification/iak'},
            {path: '/protected/flow/{{FLOW}}/mtan/registration/verification/otp'},
            {path: '/protected/flow/{{FLOW}}/password/change'},
            {path: '/protected/flow/{{FLOW}}/selection'},
            {path: '/protected/flow/{{FLOW}}/ssi/invitation', incubating: true},
            {path: '/protected/flow/{{FLOW}}/ssi/issuance', incubating: true},
            {path: '/protected/flow/{{FLOW}}/vasco/device/activation'},
            {path: '/protected/oauth2/consents'},
            {path: '/protected/oauth2/sessions'},
            {path: '/protected/portal'},
            {path: '/protected/remember-me/devices'}
        ],
        tokens: [
            {path: '/protected/flow/{{FLOW}}/airlock-2fa/device/add'},
            {path: '/protected/flow/{{FLOW}}/airlock-2fa/device/edit'},
            {path: '/protected/flow/{{FLOW}}/cronto/activation'},
            {path: '/protected/flow/{{FLOW}}/cronto/activation/complete'},
            {path: '/protected/flow/{{FLOW}}/cronto/activation/on-screen'},
            {path: '/protected/flow/{{FLOW}}/cronto/device/edit'},
            {path: '/protected/flow/{{FLOW}}/cronto/push-activation'},
            {path: '/protected/flow/{{FLOW}}/fido/credential/edit'},
            {path: '/protected/flow/{{FLOW}}/fido/registration'},
            {path: '/protected/tokens/airlock-2fa/devices'},
            {path: '/protected/tokens/cronto/devices'},
            {path: '/protected/tokens/device-token'},
            {path: '/protected/tokens/fido/credentials'},
            {path: '/protected/tokens/mtan'}
        ],
        customUi: [
            {path: '/protected/flow/{{FLOW}}/ext/example'}
        ]
    },
    error: {
        error: [
            {path: '/error'},
            {path: '/error/message'},
            {path: '/error/no-access'},
            {path: '/error/not-available'},
            {path: '/error/not-found'}
        ]
    }
},