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<AuthSecretDetails>;
}
export type AuthSecretDetails = {
    value: string;
    secretType: Exclude<AuthSecretType, AuthSecretType.EXTERNAL_AUTHENTICATION | AuthSecretType.DIGITAL_ID | AuthSecretType.ICURE_CLOUD>;
} | {
    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<SmartAuthProvider>;
    private constructor();
    getAuthService(): AuthService;
    switchGroup(newGroupId: string, matches: Array<UserGroup>): Promise<AuthenticationProvider>;
    getIcureTokens(): Promise<{
        token: string;
        refreshToken: string;
    } | undefined>;
}
