import { AuthenticationProvider } from './AuthenticationProvider'; import { UserGroup } from '../../icc-api/model/UserGroup'; import { AuthService } from './AuthService'; import { DigitalIdProvider, IccAuthApi, OAuthThirdParty } from '../../icc-api'; /** * Needed by a {@link SmartAuthProvider} to get the secrets (password, token, etc.) for authentication to the iCure SDK as needed. */ export interface AuthSecretProvider { /** * Provides a secret for authentication to the iCure SDK. * * ## Accepted secrets * * The method will be provided with an array of the secrets types that are acceptable (`acceptedSecrets`). Usually this array will contain multiple * elements, but this depends on the group configuration, the user (if he has 2fa setup or not), or the operation being performed. For groups using * default configurations and for patients without 2fa enabled for example the array will always contain the {@link AuthSecretType.PASSWORD} element. * Usually the array contain also the {@link AuthSecretType.LONG_LIVED_TOKEN} element, but if the user is attempting to perform a sensitive operations * such as changing his password the default group configuration does not allow for the user to authenticate using a JWT obtained from a long-lived * token for this operation, meaning the array will not contain the {@link AuthSecretType.LONG_LIVED_TOKEN} element. * * Regardless of the number of elements in the array only one secret of the accepted types is sufficient for the operation to succeed. * * ## TWO_FACTOR_AUTHENTICATION_TOKEN secret type * * The {@link AuthSecretType.TWO_FACTOR_AUTHENTICATION_TOKEN} secret type is only used when the user has 2fa enabled. In this case the SDK will call * this method twice, once containing the {@link AuthSecretType.PASSWORD} element in the `acceptedSecrets` array, and if the provided secret is a * valid password the SDK will immediately call this method again, this time containing the {@link AuthSecretType.TWO_FACTOR_AUTHENTICATION_TOKEN} * instead of the {@link AuthSecretType.PASSWORD} element. * * Any future call to this method from the same provider instance will not contain the {@link AuthSecretType.PASSWORD} element anymore, as it is * cached, but it may contain the {@link AuthSecretType.TWO_FACTOR_AUTHENTICATION_TOKEN} element instead. * * Note that the 2fa token is not needed for logging in through a long-lived or short-lived token, it is only used in combination with a password. * If the user is using 2fa, and you get in input as `acceptedSecrets` an array `[PASSWORD, LONG_LIVED_TOKEN, SHORT_LIVED_TOKEN]`, and you pass to * authenticate a long-lived token, the SDK will not call this method again to ask for the 2fa token. * * @param acceptedSecrets the types of secrets that are acceptable for the operation being performed. * @param previousAttempts the secrets that were previously attempted by the SDK for this operation. This array will be empty the first time this * method is called for a given operation, but it may contain multiple elements if the SDK has already called this method multiple times because the * previously returned secrets were not valid. The first element is the first secret that was attempted, and the last element is the most recently * attempted. * @param isUpgradeRequest specifies if the secret was requested to upgrade an existing and valid jwt. * @return a promise that resolves with the secret and the secret type to use for authentication. If the promise rejects then the ongoing SDK * operation will fail without being re-attempted. */ getSecret(acceptedSecrets: AuthSecretType[], previousAttempts: AuthSecretDetails[], isUpgradeRequest: boolean): Promise; } export type AuthSecretDetails = { value: string; secretType: Exclude; } | { value: string; secretType: AuthSecretType.EXTERNAL_AUTHENTICATION; oauthType: OAuthThirdParty; } | { value: string; secretType: AuthSecretType.DIGITAL_ID; provider: DigitalIdProvider; } | { value: string; secretType: AuthSecretType.ICURE_CLOUD; issuer: string; }; /** * Represents a type of secret that can be used for authentication with iCure. */ export declare enum AuthSecretType { /** * Password chosen by the user. */ PASSWORD = "PASSWORD",// pragma: allowlist secret /** * Time based one time password provided by authenticator applications, generated on the basis of a timestamp and a shared secret between the iCure * server and the authenticator application. */ TWO_FACTOR_AUTHENTICATION_TOKEN = "TWO_FACTOR_AUTHENTICATION_TOKEN", /** * A short-lived iCure token, an internal authentication token that lasts 5 minutes or less. Unlike passwords these tokens usually are generated by * some component of iCure, and are not chosen by the user. */ SHORT_LIVED_TOKEN = "SHORT_LIVED_TOKEN", /** * A long-lived iCure token, an internal authentication token that lasts longer than 5 minutes. Unlike passwords these tokens usually are generated * by some component of iCure, and are not chosen by the user. */ LONG_LIVED_TOKEN = "LONG_LIVED_TOKEN", /** * A token provided by an external authentication provider (e.g. Oauth/Google). * Not yet in use. */ EXTERNAL_AUTHENTICATION = "EXTERNAL_AUTHENTICATION", /** * A special case of external authentication where the provider is a digital identity provider. */ DIGITAL_ID = "DIGITAL_ID", /** * The secret is an authentication token for a cloud instance of icure (kraken-cloud). * Supported only on lite instances. */ ICURE_CLOUD = "ICURE_CLOUD" } export type SmartAuthProviderInitialSecret = { password: string; } | { longToken: string; } | { oauthToken: string; oauthType: OAuthThirdParty; } | { digitalIdToken: string; provider: DigitalIdProvider; } | { cloudToken: string; issuer: string; }; /** * @internal this class is meant for internal use only and may be changed without notice. The SmartAuthProvider will be initialised automatically * by the iCure api depending on the authentication options you provide. * * An authentication provider that automatically requests secrets for authentication as needed. * * This authentication provider can be initialised already with some secrets or tokens, and the provider will cache them and use them as needed for * as long as they remain valid. If at any point however the provider needs an updated secret or a secret of a different kind it will automatically * request this to the {@link SmartAuthProvider} to get the secret. * * An advantage of using this provider over others is that in case all the cached tokens and secrets were to expire while performing a request, * instead of having the request fail the provider will ask for new secrets from the {@link SmartAuthProvider} and the request will automatically * be retried with the new secret. Additionally, the provider may request updated secrets also for performing some sensitive operations (e.g. changing * password of the user) even if the cached tokens and/or did not expire. This could be the case for example if the cached secret is a long-lived * token, but in order to change the password the user needs to provide his current password. * * Note that in this context the cache of secrets and token is in memory only, and is not persisted in any way. Different instances of this provider * will not share the same cache. * */ export declare class SmartAuthProvider implements AuthenticationProvider { private readonly tokenProvider; private readonly groupId; /** * Initialises a {@link SmartAuthProvider}. * @param authApi an "anonymous" {@link IccAuthApi} to use for authentication. * @param login * @param secretProvider * @param props optional initialisation properties. */ static initialise(authApi: IccAuthApi, login: string | undefined, secretProvider: AuthSecretProvider, props?: { initialSecret?: SmartAuthProviderInitialSecret; initialAuthToken?: string; initialRefreshToken?: string; loginGroupId?: string; debugLog?: boolean; }): Promise; private constructor(); getAuthService(): AuthService; switchGroup(newGroupId: string, matches: Array): Promise; getIcureTokens(): Promise<{ token: string; refreshToken: string; } | undefined>; }