import { Context, HttpResponseRedirect, HttpResponseOK } from '@foal/core';
/**
 * Tokens returned by an OAuth2 authorization server.
 *
 * @export
 * @interface SocialTokens
 */
export interface SocialTokens {
    access_token: string;
    token_type: string;
    [name: string]: any;
}
/**
 * Objects returned by the method AbstractProvider.getUserInfo.
 *
 * @export
 * @interface UserInfoAndTokens
 * @template UserInfo
 */
export interface UserInfoAndTokens<UserInfo = any> {
    userInfo: UserInfo;
    tokens: SocialTokens;
}
/**
 * Error thrown if the state does not match.
 *
 * @export
 * @class InvalidStateError
 * @extends {Error}
 */
export declare class InvalidStateError extends Error {
    readonly name = "InvalidStateError";
    constructor();
}
/**
 * Error thrown if the (encrypted) code verifier is not found in cookie.
 *
 * @export
 * @class CodeVerifierNotFound
 * @extends {Error}
 */
export declare class CodeVerifierNotFound extends Error {
    readonly name = "CodeVerifierNotFound";
    constructor();
}
/**
 * Error thrown if the authorization server returns an error.
 *
 * @export
 * @class AuthorizationError
 * @extends {Error}
 */
export declare class AuthorizationError extends Error {
    readonly error: string;
    readonly errorDescription?: string | undefined;
    readonly errorUri?: string | undefined;
    readonly name = "AuthorizationError";
    constructor(error: string, errorDescription?: string | undefined, errorUri?: string | undefined);
}
/**
 * Error thrown if the token endpoint does not return a 2xx response.
 *
 * @export
 * @class TokenError
 * @extends {Error}
 */
export declare class TokenError extends Error {
    readonly error: any;
    readonly name = "TokenError";
    constructor(error: any);
}
export interface ObjectType {
    [name: string]: any;
}
/**
 * Abstract class that any social provider must inherit from.
 *
 * @export
 * @abstract
 * @class AbstractProvider
 * @template AuthParameters - Additional parameters to pass to the auth endpoint.
 * @template UserInfoParameters - Additional parameters to pass when retrieving user information.
 * @template UserInfo - Type of the user information.
 */
export declare abstract class AbstractProvider<AuthParameters extends ObjectType, UserInfoParameters extends ObjectType, UserInfo = any> {
    /**
     * Configuration paths from which the client ID, client secret and redirect URI must be retrieved.
     *
     * @protected
     * @abstract
     * @type {{
     *     clientId: string;
     *     clientSecret: string;
     *     redirectUri: string;
     *   }}
     * @memberof AbstractProvider
     */
    protected readonly abstract configPaths: {
        clientId: string;
        clientSecret: string;
        redirectUri: string;
    };
    /**
     * URL of the authorization endpoint from which we retrieve an authorization code.
     *
     * @protected
     * @abstract
     * @type {string}
     * @memberof AbstractProvider
     */
    protected readonly abstract authEndpoint: string;
    /**
     * URL of the token endpoint from which we retrieve an access token.
     *
     * @protected
     * @abstract
     * @type {string}
     * @memberof AbstractProvider
     */
    protected readonly abstract tokenEndpoint: string;
    /**
     * Default scopes requested by the social provider.
     *
     * @protected
     * @type {string[]}
     * @memberof AbstractProvider
     */
    protected readonly defaultScopes: string[];
    /**
     * Character used to separate the scopes in the URL.
     *
     * @protected
     * @type {string}
     * @memberof AbstractProvider
     */
    protected readonly scopeSeparator: string;
    /**
     * Enables code flow with PKCE.
     *
     * @protected
     * @type {boolean}
     * @memberof AbstractProvider
     */
    protected readonly usePKCE: boolean;
    /**
     * Specifies whether to use the plain code verifier string as PKCE code challenge.
     *
     * @protected
     * @type {boolean}
     * @memberof AbstractProvider
     */
    protected readonly useCodeVerifierAsCodeChallenge: boolean;
    /**
     * Configuration path from which the code verifier secret must be retrieved.
     *
     * @protected
     * @type {boolean}
     * @memberof AbstractProvider
     */
    protected readonly codeVerifierSecretPath: string;
    /**
     * Specifies whether the client ID and client secret must be sent in a Authorization header using Basic scheme.
     *
     * @protected
     * @memberof AbstractProvider
     */
    protected readonly useAuthorizationHeaderForTokenEndpoint: boolean;
    /**
     * Algorithm used for the code verifier encryption.
     *
     * @protected
     * @type {string}
     * @memberof AbstractProvider
     */
    private readonly cryptAlgorithm;
    private get config();
    /**
     * Retrieve user information from the tokens returned by the authorization server.
     *
     * This method may be synchronous or asynchronous.
     *
     * @abstract
     * @param {SocialTokens} tokens - Tokens returned by the authorization server. It contains at least an access token.
     * @param {UserInfoParameters} [params] - Additional parameters to pass to the function.
     * @returns {UserInfo | Promise<UserInfo>} The user information.
     * @memberof AbstractProvider
     */
    abstract getUserInfoFromTokens(tokens: SocialTokens, params?: UserInfoParameters): UserInfo | Promise<UserInfo>;
    /**
     * Returns an HttpResponseOK or HttpResponseRedirect object to redirect the user to the social provider's authorization page.
     *
     * If the isRedirection parameter is undefined or set to false, the function returns an HttpResponseOK object. Its body contains the URL of the consent page.
     *
     * If the isRedirection parameter is set to true, the function returns an HttpResponseRedirect object.
     *
     * @param {{ scopes?: string[] }} [{ scopes }={}] - Custom scopes to override the default ones used by the provider.
     * @param {{ isRedirection?: boolean }} [{ isRedirection }={}] - If true, the function returns an HttpResponseRedirect object. Otherwise, it returns an HttpResponseOK object.
     * @param {AuthParameters} [params] - Additional parameters (specific to the social provider).
     * @returns {Promise<HttpResponseOK | HttpResponseRedirect>} The HttpResponseOK or HttpResponseRedirect object.
     * @memberof AbstractProvider
     */
    createHttpResponseWithConsentPageUrl({ scopes, isRedirection }?: {
        scopes?: string[];
        isRedirection?: boolean;
    }, params?: AuthParameters): Promise<HttpResponseOK | HttpResponseRedirect>;
    /**
     * Function to use in the controller method that handles the provider redirection.
     *
     * It returns an access token.
     *
     * @param {Context} ctx - The request context.
     * @returns {Promise<SocialTokens>} The tokens (it contains at least an access token).
     * @memberof AbstractProvider
     */
    getTokens(ctx: Context): Promise<SocialTokens>;
    /**
     * Function to use in the controller method that handles the provider redirection.
     *
     * It retrieves the access token as well as the user information.
     *
     * @param {Context} ctx - The request context.
     * @param {UserInfoParameters} [params] - Additional parameters to pass to the function.
     * @returns {Promise<UserInfoAndTokens<UserInfo>>} The access token and the user information
     * @memberof AbstractProvider
     */
    getUserInfo(ctx: Context, params?: UserInfoParameters): Promise<UserInfoAndTokens<UserInfo>>;
    private getState;
    /**
     * This function is for encrypt a string using aes-256 and codeVerifierSecret.
     * Notice that init vector base64-encoded is concatenated at start of encrypted message.
     * We'll need init vector to decrypt message.
     * Init vector is 16 bytes length and it base64-encoded is 24 bytes length.
     *
     * @param {string} message - String to encrypt
     */
    private encryptString;
    /**
     * This function is for decrypt a string using aes-256 and codeVerifierSecret
     * encryptedMessage is {iv}{encrypted data}
     *
     * @param {string} encryptedMessage - String to decrypt
     */
    private decryptString;
    private getCodeVerifierSecretBuffer;
}
