import { Auth } from '@genesislcap/foundation-comms'; import { Binding } from '@microsoft/fast-element'; import { Connect } from '@genesislcap/foundation-comms'; import { Container } from '@microsoft/fast-foundation'; import { CredentialManager } from '@genesislcap/foundation-comms'; import { DefineFunction } from '@genesislcap/foundation-ui'; import { ElementStyles } from '@microsoft/fast-element'; import { FASTElement } from '@microsoft/fast-element'; import { FoundationRouterConfiguration } from '@genesislcap/foundation-ui'; import { I18next } from '@genesislcap/foundation-i18n'; import { I18nextConfig } from '@genesislcap/foundation-i18n'; import { InterfaceSymbol } from '@microsoft/fast-foundation'; import { Message } from '@genesislcap/foundation-comms'; import { MessageBuilder } from '@genesislcap/foundation-comms'; import { PartialFASTElementDefinition } from '@microsoft/fast-element'; import { Session } from '@genesislcap/foundation-comms'; import { SyntheticViewTemplate } from '@microsoft/fast-element'; import { TemplateElementDependency } from '@genesislcap/foundation-ui'; import { ViewTemplate } from '@microsoft/fast-element'; import { ZeroButtonAppearance } from '@genesislcap/foundation-zero'; /** * @internal */ export declare const backButton: (binding: Binding, label: string) => ViewTemplate; /** * @internal * @privateRemarks * Temp optimisation. How we handle images like this needs a broader review. */ export declare class BackgroundElement extends ConfigHostElement { connectedCallback(): void; } /** * @internal */ export declare class BaseRoute extends ConfigHostElement { auth: Auth; connect: Connect; session: Session; messageBuilder: MessageBuilder; credentialManager: CredentialManager; host: string; organisation: string; username: string; email: string; password: string; password2: string; showPassword: boolean; message: string; hasErrors: boolean; isSubmitting: boolean; connectedCallback(): void; onSubmit(): Promise; ensureConnection(): Promise; setError(message: string): void; clearError(): void; get orgUsername(): string; onBack: () => void; onNavigate: (routeName: Routes, params?: object, trigger?: boolean) => void; queueOnBack(delay?: number): void; autofill(): Promise; storeCredentials(password?: string): void; sendMessage(message: Message, successFeedback?: string, successCallback?: (result: any) => void, delayBack?: number): Promise; toLocalisedText(text: string): string; } /** * @internal */ export declare type ConfigHost = { config: LoginConfig; }; /** * @internal * @privateRemarks * For services / constructor injection, using `@optional(LoginConfig) config = defaultLoginConfig;` works as expected. * However, for elements, the `@optional` decorator isn't viable. This base element provides an alternative approach. */ export declare class ConfigHostElement extends FASTElement implements ConfigHost { container: Container; config: LoginConfig; /** * i18next instance for managing internationalization. * @internal */ i18next: I18next; connectedCallback(): void; } /** * @internal * @privateRemarks * Potential optimisation ahead of workflow / statemachine based smart forms integration, but needs tagFor. * Feels a bit at odds with the declarative nature we're aiming for, but will await review. */ export declare const configurableTextField: (name: keyof FieldConfigMap | [name: keyof FieldConfigMap, valueKey: string], type: string, autofocus?: boolean, autocomplete?: string, className?: string, labelOverride?: string, testIdOverride?: string, required?: boolean) => ViewTemplate; /** * Configure the login micro frontend settings. * * @remarks * This is primarily for general settings, rather than re-defining the element, static templating / style changes. * * @param container - DI container. * @param config - A partial LoginConfig. * * @example Configuring login on lazy load * ```ts * name: 'login', * path: 'login', * title: 'Login', * element: async () => { * const { configure, define, defaultLoginConfig } = await import('@genesislcap/foundation-login'); * configure(this.container, { * autoConnect: true, * omitRoutes: ['request-account'], * fields: { * ...defaultLoginConfig.fields, * organisation: { * label: 'CompID', * }, * }, * hostPath: 'login', * defaultRedirectUrl: 'dashboard', * logo: loginLogo, * background: loginBG, * }); * // You can import and return `Login` directly here or re-define it completely via `define`. * return define({ * name: `nexus-login`, * }); * }, * layout: loginLayout, * settings: { public: true }, * childRouters: true, * ``` * * @public * @privateRemarks * We can tailor the spreading logic after we put it to use. Keeping it simple for now. * * @deprecated - Please use foundation-auth instead. */ export declare function configure(container: Container, config: Partial): void; /** * @public */ export declare const defaultApiHost: string; /** * Default LoginConfig DI implementation. * @public */ export declare const defaultLoginConfig: LoginConfig; /** * Default LoginRouting. * * @public */ export declare class DefaultLoginRouting implements LoginRouting { /** @internal */ private config; /** {@inheritDoc LoginRouting.getRoutePath} */ getRoutePath(route: string): string; /** {@inheritDoc LoginRouting.navigateTo} */ navigateTo(route: string): void; } /** * @internal */ export declare const defaultOnBackMS = 3000; /** * @public */ export declare const defaultOrganisation: string; /** * @public */ export declare const defaultPassword: string; /** * @public */ export declare const defaultSocketExt: string; /** * The default template options this MF has been created with. * @beta * @privateRemarks * This will likely evolve into the shell style PWA + FDC3 manifest setup, but that needs more work to evolve into MVP. * Hosts should be able to figure out everything they will need to do to fully customise a MF. Currently, they * import these `defaultTemplateOptions` and the host dev overrides. Each TemplateComponents key must be a mandatory * override, given in hosted mode the MFs won't be registering fallbacks as this would be wasteful, bloat etc. * I've added the components list to the package.json \> config block for now, but I'm not using it here. */ export declare const defaultTemplateOptions: TemplateOptions; /** * @public */ export declare const defaultUser: string; /** * Re-define the login micro frontend. * * @example * ```ts * import { define, styles, template, defaultTemplateOptions } from '@genesislcap/foundation-login'; * const customTemplateOptions = { * ...defaultTemplateOptions, * ...customOptions, * } * export const AppLogin = define({ * name: `nexus-login`, * template: template(customTemplateOptions), * styles: css` * ${styles(customTemplateOptions)} * some-element { * background-color: #ff00b4; * } * `, * }); * ``` * * @beta * @privateRemarks * TODO: Use LoginHosted instead of Login when elements manifest stuff lands, which will drive tagFor etc. */ export declare const define: DefineFunction; /** * @beta * @remarks * This is the main definition of this micro frontend which is exposed for user reconfiguration. */ export declare const definition: PartialFASTElementDefinition; /** * @internal */ export declare const emailField: () => ViewTemplate; /** * Request SSO identity provider list * * @public */ export declare const fetchIDPs: (path?: string, host?: string) => Promise; /** * @public * Could be expanded to allow field ViewTemplates. */ export declare type FieldConfig = { label: string; /** * @privateRemarks * Added for now to apply defaults, but I'm not convinced we should do this. Could be made reactive after upgrade. */ value?: any; /** * @remarks * We expect fields to be required by default, but you can override to make them optional. Organisation for example. */ required?: boolean; /** * @remarks * A regular expression the control's value should match. Please note the email field has its own built in pattern. */ pattern?: string; /** * @remarks * Used in conjunction with the pattern to explain the conditions. */ title?: string; }; /** * @public * @privateRemarks * Using null to exclude the organisation field rather than boolean, as it affords cleaner value lookups in the templates. */ export declare type FieldConfigMap = { organisation: FieldConfig | null; username: FieldConfig; email: FieldConfig; password: FieldConfig; }; /** * Gets LoginRouting from the DI container. * * @remarks * A utility method for host applications that are not using decorators or the DI container. * * @example * ```ts * import { getloginRouting } from '@genesislcap/foundation-login'; * ... * private loginRouting = getLoginRouting(); * ... * this.loginRouting.navigateTo('logout'); * ``` * * @public */ export declare function getLoginRouting(): LoginRouting; /** * A utility to get a sub route path taking the host path into account. * * @param route - A login route. * @param hostPath - The host path. * * @public */ declare function getRoutePath(route: string, hostPath?: string): string; /** * Get SSO identity provider login URL * * @public */ export declare const getSSOLoginURL: (idp: any, path?: string, host?: string) => string; /** * @public */ export declare const hostEnv: string; /** * @public */ export declare const hostUrl: string; /** * @public */ export declare interface IDP { id: string; type: string; } /** * @public */ export declare interface IDPResponse { ID: string; TYPE: string; } /** * A utility to check if a pathname is a route of this micro frontend. * * @param pathname - A pathname string to check, typically location.pathname, which is used when a value is omitted. * * @public * @privateRemarks * I've just put this util in for now given there's some app level direction code in place which needs review. */ export declare function isMFRoute(pathname?: string): boolean; /** * Defines the login class which handles account authentication from the front-end * * @remarks * * Add the Login class as a router element, and it will handle the account authentication for you. * Requires use of `@genesislcap/foundation-comms` for the {@link @genesislcap/foundation-comms#Auth | Auth} and * {@link @genesislcap/foundation#Session | Session} classes. * * There are a lot of configuration options available, and different authentication types (such as login via SSO). Use * the modules exported `configure` and `define` functions for more power. * * @example * The following is an example of using it in your app, setting it up in the router configuration. This isn't a complete * routes confutation, but it contains all required configuration in regard to adding Login functionality. * ```ts * // Import required dependencies from the foundation-login package * import { Login } from '@genesislcap/foundation-login'; * // Import required dependencies from the foundation-comms package * // You could also import analytics events and set them up in the NavigationContributor * import { Auth, Session } from '@genesislcap/foundation-comms'; * * type RouterSettings = { * public?: boolean; * autoAuth?: boolean; * } * * // Define your router config * export class MainRouterConfig extends RouterConfiguration { * // Ensure you inject in required dependencies * constructor( * @Auth private auth: Auth, * @Session private session: Session * ) { * super(); * } * * // Add Login as a route * public configure() { * ... * this.routes.map( * { path: '', redirect: 'login' }, * { * path: 'login', * element: Login, * title: 'Login', * name: 'login', * layout: loginLayout, * settings: { public: true }, * childRouters: true, * }, * ... // Other routes config here * ); * * const session = this.session; * const auth = this.auth; * * // Example of a FallbackRouteDefinition * this.routes.fallback(() => * auth.isLoggedIn ? { redirect: 'not-found' } : { redirect: 'login' } * ); * * // Example of a NavigationContributor * this.contributors.push({ * navigate: async (phase) => { * const settings = phase.route.settings; * * // Could add in processes such as analytics here * * // If public route don't block * if (settings && settings.public) { * return; * } * * // If logged in don't block * if (auth.isLoggedIn) { * return; * } * * // If autoAuth and session is valid try to connect+auto-login * if (settings && settings.autoAuth && (await auth.reAuthFromSession())) { * return; * } * * // Otherwise route them to login * phase.cancel(() => { * session.captureReturnUrl(); * FoundationRouteNav.name.replace(phase.router, 'login'); * }); * }, * }); * } * * ... // Other configuration/methods * * } * ``` * * @deprecated - Use '\@genesislcap/pbc-auth' instead. * 'https://www.npmjs.com/package/\@genesislcap/pbc-auth' * * @public */ export declare class Login extends FASTElement { /** * Configuration for the routes and their associated settings. * The client would override this in their app with their own settings to set * their routes up as desired * @internal */ config: MainRouterConfig; /** * The DI container used to register required components in {@link Login.registerDIDependencies} * @internal */ container: Container; /** * Session controller used to manage the user's session * @internal */ session: Session; /** * i18next instance for managing internationalization. * @internal */ i18next: I18next; /** * Marked true when remote components are loaded, currently unused. * @internal */ ready: boolean; /** * DS provider / root level template. * @internal */ provider: FASTElement; /** * @internal */ connectedCallback(): Promise; /** * Used to forward the user onto a logged-in session during an SSO journey * * @remarks * * Called when loading the login page via the connectedCallback() method. * During normal flows there will be no SSO tokens set and hence this function * will quit execution. * During an SSO journey the SSO provider will set the SSO token as a URLSearchParams * parameter and redirect back to us. In this case we will take this and forward the * user on, with their logged in session. * * There are two paths the user can take here - if they are in a popup * (window.opener exists) then we need to set the session and get the parent window * (the one which the user wants their session on) to refresh, and close the popup. * * Or if they are not in a popup then we simply set the ssoToken in the session. * When this component is loaded with the ssoToken then it will redirect the * user to their app (the `defaultRedirectUrl`). * * @internal */ checkForSSOToken(): void; /** * Called from the connectedCallback * @internal */ registerCommonComponents(): Promise; /** * @internal */ protected registerDIDependencies(): void; } /** * LoginConfig DI interface. * * @public */ export declare interface LoginConfig { /** * Connect automatically or require user to click a connect button. */ autoConnect: boolean; /** * Login automatically or require user to click a login button after a connection is established. * * @remarks * Needs to manually be enabled in the NavigationContributor (see [2] in the example in the {@link Login} class). */ autoAuth: boolean; /** * Logo styles. * * @remarks * Providing `null` will hide the logo. Use content: url(...); to set source. * * @example Setting a custom logo * ```ts * logo: css` * content: url(${customLogoImport}); * `, * ``` */ logo: ElementStyles | null; /** * Logo alt text. */ logoAltText: string; /** * Background styles. * * @remarks * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/background} for more information. * * @example Setting a custom background image * ```ts * background: css` * :host { * background-image: url(${customBGImport}); * } * `, * ``` */ background: ElementStyles; /** * Omit any of the internal routes except 'login' and 'not-found'. * * @remarks * Routes specified here will not be configured nor will any internal cross-links to them be displayed. * * @example * ```ts * omitRoutes: ['request-account'], * ``` */ omitRoutes: Exclude[]; /** * Map of configuration for each of the primary form fields. * * @remarks * Use to drive inclusion / exclusion, tailor labels etc. */ fields: FieldConfigMap; /** * Show or hide the connection status indicator. */ showConnectionIndicator: boolean; /** * The `path` of the micro frontend as defined in the parent / host route. * * @remarks * Used to help resolve internal route links. Defaults to an empty string. */ hostPath: string; /** * The default URL to route the user to after a successful login. * * @remarks * Session.returnUrl set via Session.captureReturnUrl() trumps this value. */ defaultRedirectUrl: string; /** * Handler that allows external apps own router to navigate after successful login * */ redirectHandler?: (url: string) => void; /** * Omit certain return urls which the session service may have captured. * * @example * ```ts * omitRedirectUrls: ['/not-found'], * ``` */ omitRedirectUrls: string[]; /** * SSO configuration. * * @remarks * Providing `null` excludes the SSO journey option completely. */ sso: SSOConfig | null; /** * Display arbitrary version information. * * @remarks * Applications may choose to set this to display their Application release version on the login form. * * @example * ```ts * versionInformation: 'Version 3.0.0', * ``` */ versionInformation?: string; /** * I18n resources. * * @remarks * This property holds the localization resources needed for internationalization of the application. * It should follow the structure defined by the I18nextConfig interface, which includes * translations grouped by locale and namespace. Each locale can contain multiple namespaces, and each * namespace includes key-value pairs for translation strings. * * @example * ```ts * resources: { * en: { * translation: { * key: 'Hello World' * } * }, * es: { * translation: { * key: 'Hola Mundo' * } * } * } * ``` */ localizationResources?: I18nextConfig['resources']; /** * Delay configurations for various message-related actions. * * @remarks * This property holds numeric values representing delays (in milliseconds) for specific message-related actions * within the application. Each key in this object corresponds to a particular message action. * * @example * ```ts * messageDelays: { * forgotPassword: 1000, // Delay of 1000ms before processing forgot password action * resetPassword: 2000, // Delay of 2000ms for reset password action * base: 500 // Base delay used for generic message processing * } * ``` */ messageDelays?: MessageDelays; /** * Custom appearance for submit buttons in `foundation-login`. * * @remarks * This property holds a string representing the desired appearance for submit buttons in `foundation-login`. * The value should be a valid `appearance` attribute of a Foundation button component. * * @example * ```ts * submitButtonAppearance: 'stealth' * ``` */ submitButtonAppearance?: ZeroButtonAppearance; /** * Show or hide the environment indicator. */ showEnvironmentIndicator?: boolean; } /** * LoginConfig DI key. * * @internal * @privateRemarks * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name. */ export declare const LoginConfig: InterfaceSymbol; /** * @beta * @privateRemarks * A hosted version of the MF that doesn't set up a design system or components. This is what apps would use to truly * customise the MF for their needs via define.ts. * * @deprecated - Please use foundation-auth instead. */ export declare class LoginHosted extends Login { registerCommonComponents(): Promise; } /** * LoginRouting interface. * * @remarks * A utility to navigate to a sub route of the login micro frontend without needing to know the full path in advance. * * @example Import the utility into any component or logic you wish to invoke from. * ```ts * import { LoginRouting } from '@genesislcap/foundation-login'; * ... * @LoginRouting private loginRouting: LoginRouting; * ... * this.loginRouting.navigateTo('logout'); * ``` * * @public */ export declare interface LoginRouting { /** {@inheritDoc getRoutePath} */ getRoutePath: typeof getRoutePath; /** {@inheritDoc navigateTo} */ navigateTo: typeof navigateTo; } /** * LoginRouting DI key. * * @privateRemarks * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name. * * @internal */ export declare const LoginRouting: InterfaceSymbol; /** * @internal */ export declare class LogoElement extends ConfigHostElement { } /** * Base implementation of a routing used with the Login class * * @remarks * * Could be used when using the Login class as a standalone authentication method * with your app * * @internal */ export declare class MainRouterConfig extends FoundationRouterConfiguration { private auth; private loginConfig; constructor(auth: Auth, loginConfig?: LoginConfig); configure(): void; } /** * @public */ export declare type MessageDelayKey = 'forgotPassword' | 'resetPassword' | 'base'; /** * @public */ export declare type MessageDelays = Partial>; /** * @internal * @privateRemarks * Temp optimisation. How we handle images like this needs a broader review. */ export declare class MessageElement extends FASTElement { classNames: string; message: string; nonError: boolean; nonErrorChanged(): void; } /** * @remarks * Uses the `FASTRouter`. * * @param route - An auth route including query params if required, ie. `reset-password?expired`. * * @internal */ declare function navigateTo(route: string): void; /** * @internal */ export declare const organisationField: () => ViewTemplate; /** * @internal */ export declare const password2Field: (type: "new" | "confirmation") => ViewTemplate; /** * @internal */ export declare const passwordField: (label?: string) => ViewTemplate; /** * @public */ export declare const Routes: { readonly login: "login"; readonly 'request-account': "request-account"; readonly 'reset-password': "reset-password"; readonly 'forgot-password': "forgot-password"; readonly verify: "verify"; readonly 'mfa-mail-sent': "mfa-mail-sent"; readonly protected: "protected"; readonly 'not-found': "not-found"; }; /** * @public */ export declare type Routes = (typeof Routes)[keyof typeof Routes]; /** * Defines the parameters you may set on the routes. * * @remarks * See the example in the {@link Login} class in the router's `configure` method for usage. All parameters are Optional. * * @public */ export declare type Settings = { /** * Controls whether the user has to be logged in to view. */ public?: boolean; }; /** * @internal */ export declare const showEnvironmentIndicator: () => ViewTemplate; /** * @internal */ export declare const showPasswordCheckbox: () => ViewTemplate; /** * @public * * If you don't provide SSOConfig on the login config then SSO is disabled completely. * * @remarks * `toggled` - Optionally toggle the SSO journey on/off by default. * If `toggled` is set to `true`, the SSO option is presented as enabled to the user (e.g., the SSO checkbox is checked, or SSO providers are immediately displayed). * If `toggled` is set to `false` (or if the parameter is omitted entirely), the SSO option starts as disabled. The user would then need to explicitly enable it (e.g., by checking a checkbox) to initiate the SSO flow. * * `identityProvidersPath` - The identity providers path under the current host. This is a *required* string parameter. * It specifies the URL path where the application can fetch the list of available Identity Providers (IDPs) for SSO. This path is relative to the `API_HOST` or the `host` you are setting in the parent component. * The login component will make a request to this endpoint to retrieve the IDPs. The response from this endpoint is expected to be in a format that the component can understand (as defined by the `IDP` and `IDPResponse` types in your code). The response is expected to be a JSON object containing an array of identity providers. * Example: If your `API_HOST` is `https://example.com/gwf` and `identityProvidersPath` is set to `'sso/list'`, the component will fetch the IDP list from `https://example.com/gwf/sso/list`. This endpoint should be implemented on your backend to return the available SSO providers. * * @example * ```ts * const config: SSOConfig = { * toggled: true, * identityProvidersPath: 'sso/list', * } * ``` */ export declare type SSOConfig = { toggled?: boolean; identityProvidersPath: string; }; /** * @internal * @privateRemarks * This is used during development of this micro frontend. */ export declare const standaloneDefinition: PartialFASTElementDefinition; /** * @public * @privateRemarks * Options can be used to target unknown component tags in the css, such as: * @example unknown target * ``` * const buttonTag = tagFor(options.button); * ... * ${buttonTag} { * width: 200px; * } * ``` */ export declare const styles: (options: TemplateOptions) => ElementStyles; /** * @internal */ export declare const submitButton: (label: string, dataTestId?: string, disabled?: boolean) => ViewTemplate; /** * @internal */ export declare class SubmittingIndicator extends FASTElement { isSubmitting: boolean; } /** * @public */ export declare const template: (options: TemplateOptions) => ViewTemplate; /** * @beta * @privateRemarks * The CLI can be used to monitor what is in use and needs a mapping. */ export declare type TemplateComponents = { anchor: TemplateElementDependency; button: TemplateElementDependency; card: TemplateElementDependency; checkbox: TemplateElementDependency; listboxOption: TemplateElementDependency; provider: TemplateElementDependency; router: TemplateElementDependency; select: TemplateElementDependency; textField: TemplateElementDependency; }; /** * @beta */ export declare type TemplateOptions = TemplateComponents & { somePartial?: string | SyntheticViewTemplate; }; /** * @internal */ export declare const usernameField: () => ViewTemplate; export { }