import { type SetCookieInit } from "@mjackson/headers";
import { CodeChallengeMethod, OAuth2Client, OAuth2RequestError, type OAuth2Tokens, UnexpectedErrorResponseBodyError, UnexpectedResponseError } from "arctic";
import { Strategy } from "remix-auth/strategy";
type URLConstructor = ConstructorParameters<typeof URL>[0];
export { OAuth2RequestError, CodeChallengeMethod, UnexpectedResponseError, UnexpectedErrorResponseBodyError, };
export declare class OAuth2Strategy<User> extends Strategy<User, OAuth2Strategy.VerifyOptions> {
    protected options: OAuth2Strategy.ConstructorOptions;
    name: string;
    protected client: OAuth2Client;
    constructor(options: OAuth2Strategy.ConstructorOptions, verify: Strategy.VerifyFunction<User, OAuth2Strategy.VerifyOptions>);
    private get cookieName();
    private get cookieOptions();
    authenticate(request: Request): Promise<User>;
    protected createAuthorizationURL(): {
        state: string;
        codeVerifier: string;
        url: URL;
    };
    protected validateAuthorizationCode(code: string, codeVerifier: string): Promise<OAuth2Tokens>;
    /**
     * Return extra parameters to be included in the authorization request.
     *
     * Some OAuth 2.0 providers allow additional, non-standard parameters to be
     * included when requesting authorization.  Since these parameters are not
     * standardized by the OAuth 2.0 specification, OAuth 2.0-based authentication
     * strategies can override this function in order to populate these
     * parameters as required by the provider.
     */
    protected authorizationParams(params: URLSearchParams, request: Request): URLSearchParams;
    /**
     * Get a new OAuth2 Tokens object using the refresh token once the previous
     * access token has expired.
     * @param refreshToken The refresh token to use to get a new access token
     * @returns The new OAuth2 tokens object
     * @example
     * ```ts
     * let tokens = await strategy.refreshToken(refreshToken);
     * console.log(tokens.accessToken());
     * ```
     */
    refreshToken(refreshToken: string): Promise<OAuth2Tokens>;
    /**
     * Users the token revocation endpoint of the identity provider to revoke the
     * access token and make it invalid.
     *
     * @param token The access token to revoke
     * @example
     * ```ts
     * // Get it from where you stored it
     * let accessToken = await getAccessToken();
     * await strategy.revokeToken(tokens.access_token);
     * ```
     */
    revokeToken(token: string): Promise<void>;
    /**
     * Discover the OAuth2 issuer and create a new OAuth2Strategy instance from
     * the OIDC configuration that is returned.
     *
     * This method will fetch the OIDC configuration from the issuer and create a
     * new OAuth2Strategy instance with the provided options and verify function.
     *
     * @param uri The URI of the issuer, this can be a full URL or just the domain
     * @param options The rest of the options to pass to the OAuth2Strategy constructor, clientId, clientSecret, redirectURI, and scopes are required.
     * @param verify The verify function to use with the OAuth2Strategy instance
     * @returns A new OAuth2Strategy instance
     * @example
     * ```ts
     * let strategy = await OAuth2Strategy.discover(
     *   "https://accounts.google.com",
     *   {
     *     clientId: "your-client-id",
     *     clientSecret: "your-client-secret",
     *     redirectURI: "https://your-app.com/auth/callback",
     *     scopes: ["openid", "email", "profile"],
     *   },
     *   async ({ tokens }) => {
     *     return getUserProfile(tokens.access_token);
     *   },
     * );
     */
    static discover<U, M extends OAuth2Strategy<U> = OAuth2Strategy<U>>(this: new (options: OAuth2Strategy.ConstructorOptions, verify: Strategy.VerifyFunction<U, OAuth2Strategy.VerifyOptions>) => M, uri: string | URL, options: Pick<OAuth2Strategy.ConstructorOptions, "clientId" | "clientSecret" | "cookie" | "redirectURI" | "scopes"> & Partial<Omit<OAuth2Strategy.ConstructorOptions, "clientId" | "clientSecret" | "cookie" | "redirectURI" | "scopes">>, verify: Strategy.VerifyFunction<U, OAuth2Strategy.VerifyOptions>): Promise<M>;
}
export declare namespace OAuth2Strategy {
    interface VerifyOptions {
        /** The request that triggered the verification flow */
        request: Request;
        /** The OAuth2 tokens retrivied from the identity provider */
        tokens: OAuth2Tokens;
    }
    interface ConstructorOptions {
        /**
         * The name of the cookie used to keep state and code verifier around.
         *
         * The OAuth2 flow requires generating a random state and code verifier, and
         * then checking that the state matches when the user is redirected back to
         * the application. This is done to prevent CSRF attacks.
         *
         * The state and code verifier are stored in a cookie, and this option
         * allows you to customize the name of that cookie if needed.
         * @default "oauth2"
         */
        cookie?: string | (Omit<SetCookieInit, "value"> & {
            name: string;
        });
        /**
         * This is the Client ID of your application, provided to you by the Identity
         * Provider you're using to authenticate users.
         */
        clientId: string;
        /**
         * This is the Client Secret of your application, provided to you by the
         * Identity Provider you're using to authenticate users.
         */
        clientSecret: string | null;
        /**
         * The endpoint the Identity Provider asks you to send users to log in, or
         * authorize your application.
         */
        authorizationEndpoint: URLConstructor;
        /**
         * The endpoint the Identity Provider uses to let's you exchange an access
         * code for an access and refresh token.
         */
        tokenEndpoint: URLConstructor;
        /**
         * The URL of your application where the Identity Provider will redirect the
         * user after they've logged in or authorized your application.
         */
        redirectURI: URLConstructor | null;
        /**
         * The endpoint the Identity Provider uses to revoke an access or refresh
         * token, this can be useful to log out the user.
         */
        tokenRevocationEndpoint?: URLConstructor;
        /**
         * The scopes you want to request from the Identity Provider, this is a list
         * of strings that represent the permissions you want to request from the
         * user.
         */
        scopes?: string[];
        /**
         * The code challenge method to use when sending the authorization request.
         * This is used when the Identity Provider requires a code challenge to be
         * sent with the authorization request.
         * @default "CodeChallengeMethod.S256"
         */
        codeChallengeMethod?: CodeChallengeMethod;
        /**
         * The audience of the token to request from the Identity Provider. This is
         * used when the Identity Provider requires a specific audience to be set on
         * the token.
         *
         * This can be a string or an array of strings.
         */
        audience?: string | string[];
    }
}
