/// <reference types="@adonisjs/application/build/adonis-typings/application" />
declare module '@ioc:Adonis/Addons/Auth' {
    import { DateTime } from 'luxon';
    import { HashersList } from '@ioc:Adonis/Core/Hash';
    import { QueryClientContract } from '@ioc:Adonis/Lucid/Database';
    import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
    import { ApplicationContract } from '@ioc:Adonis/Core/Application';
    import { DatabaseQueryBuilderContract } from '@ioc:Adonis/Lucid/Database';
    import { LucidModel, LucidRow, ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
    /**
     * Unwraps user from the provider user
     */
    type UnWrapProviderUser<T> = T extends ProviderUserContract<any> ? Exclude<T['user'], null> : T;
    /**
     * Unwraps awaited type from Promise
     */
    type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
    /**
     * Returns the real user from the provider user
     */
    export type GetProviderRealUser<Provider extends keyof ProvidersList> = UnWrapProviderUser<Awaited<ReturnType<ProvidersList[Provider]['implementation']['getUserFor']>>>;
    /**
     * Provider user works as a bridge between the provider real user
     * and the guard. It is never exposed to the end-user.
     */
    export interface ProviderUserContract<User extends any> {
        user: User | null;
        getId(): string | number | null;
        verifyPassword: (plainPassword: string) => Promise<boolean>;
        getRememberMeToken(): string | null;
        setRememberMeToken(token: string): void;
    }
    /**
     * The interface that every provider must implement
     */
    export interface UserProviderContract<User extends any> {
        /**
         * Return an instance of the user wrapped inside the Provider user contract
         */
        getUserFor(user: User): Promise<ProviderUserContract<User>>;
        /**
         * Find a user using the primary key value
         */
        findById(id: string | number): Promise<ProviderUserContract<User>>;
        /**
         * Find a user by searching for their uids
         */
        findByUid(uid: string): Promise<ProviderUserContract<User>>;
        /**
         * Find a user using the remember me token
         */
        findByRememberMeToken(userId: string | number, token: string): Promise<ProviderUserContract<User>>;
        /**
         * Update remember token
         */
        updateRememberMeToken(authenticatable: ProviderUserContract<User>): Promise<void>;
    }
    /**
     * Shape of the token sent to/read from the tokens provider
     */
    export interface ProviderTokenContract {
        /**
         * Persisted token value. It is a sha256 hash
         */
        tokenHash: string;
        /**
         * Token name
         */
        name: string;
        /**
         * Token type
         */
        type: string;
        /**
         * UserId for which the token was saved
         */
        userId: string | number;
        /**
         * Expiry date
         */
        expiresAt?: DateTime;
        /**
         * All other token details
         */
        meta?: any;
    }
    /**
     * Token providers provides the API to create/fetch and delete tokens
     * for a given user. Any token based implementation can use token
     * providers, given they only store a single token.
     */
    export interface TokenProviderContract {
        /**
         * Define a custom connection for the driver in use
         */
        setConnection(connection: any): this;
        /**
         * Saves the token to some persistance storage and returns an lookup
         * id. We introduced the concept of lookup ids, since lookups by
         * cryptographic tokens can have performance impacts on certain
         * databases.
         *
         * Also note that the return lookup id is also prepended to the raw
         * token, so that we can later extract the id for reads. The
         * real message is to keep the lookup ids small.
         */
        write(token: ProviderTokenContract): Promise<string>;
        /**
         * Find token using the lookup id or the token value
         */
        read(lookupId: string, token: string, type: string): Promise<ProviderTokenContract | null>;
        /**
         * Delete token using the lookup id or the token value
         */
        destroy(lookupId: string, type: string): Promise<void>;
    }
    /**
     * Config for the database token provider
     */
    export type DatabaseTokenProviderConfig = {
        driver: 'database';
        table: string;
        foreignKey?: string;
        connection?: string;
        type?: string;
    };
    /**
     * Config for the redis token provider
     */
    export type RedisTokenProviderConfig = {
        driver: 'redis';
        redisConnection: string;
        foreignKey?: string;
        type?: string;
    };
    /**
     * The shape of the user model accepted by the Lucid provider. The model
     * must have `password` and `rememberMeToken` attributes.
     */
    export type LucidProviderModel = LucidModel & {
        findForAuth?: <T extends LucidModel>(this: T, uids: string[], value: any) => Promise<InstanceType<T>>;
    } & {
        new (): LucidRow & {
            password?: string | null;
            rememberMeToken?: string | null;
        };
    };
    /**
     * Shape of the lucid provider user builder. It must return [[ProviderUserContract]]
     */
    export interface LucidProviderUserBuilder<User extends LucidProviderModel> {
        new (user: InstanceType<User> | null, config: LucidProviderConfig<User>, ...args: any[]): ProviderUserContract<InstanceType<User>>;
    }
    /**
     * Lucid provider
     */
    export interface LucidProviderContract<User extends LucidProviderModel> extends UserProviderContract<InstanceType<User>> {
        /**
         * Define a custom connection for all the provider queries
         */
        setConnection(connection: string | QueryClientContract): this;
        /**
         * Before hooks
         */
        before(event: 'findUser', callback: (query: ModelQueryBuilderContract<User>) => Promise<void>): this;
        /**
         * After hooks
         */
        after(event: 'findUser', callback: (user: InstanceType<User>) => Promise<void>): this;
    }
    /**
     * The config accepted by the Lucid provider
     */
    export type LucidProviderConfig<User extends LucidProviderModel> = {
        driver: 'lucid';
        model: () => Promise<User> | Promise<{
            default: User;
        }>;
        uids: (keyof InstanceType<User>)[];
        identifierKey: string;
        connection?: string;
        hashDriver?: keyof HashersList;
        user?: () => Promise<LucidProviderUserBuilder<User>> | Promise<{
            default: LucidProviderUserBuilder<User>;
        }>;
    };
    /**
     * Shape of the row returned by the database provider. The table must have `password`
     * and `remember_me_token` columns.
     */
    export type DatabaseProviderRow = {
        password?: string;
        remember_me_token?: string;
        [key: string]: any;
    };
    /**
     * Shape of database provider user builder. It must always returns [[ProviderUserContract]]
     */
    export interface DatabaseProviderUserBuilder {
        new (user: DatabaseProviderRow | null, config: DatabaseProviderConfig, ...args: any[]): ProviderUserContract<DatabaseProviderRow>;
    }
    /**
     * Database provider
     */
    export interface DatabaseProviderContract<User extends DatabaseProviderRow> extends UserProviderContract<User> {
        /**
         * Define a custom connection for all the provider queries
         */
        setConnection(connection: string | QueryClientContract): this;
        /**
         * Before hooks
         */
        before(event: 'findUser', callback: (query: DatabaseQueryBuilderContract) => Promise<void>): this;
        /**
         * After hooks
         */
        after(event: 'findUser', callback: (user: DatabaseProviderRow) => Promise<void>): this;
    }
    /**
     * The config accepted by the Database provider
     */
    export type DatabaseProviderConfig = {
        driver: 'database';
        uids: string[];
        usersTable: string;
        identifierKey: string;
        connection?: string;
        hashDriver?: keyof HashersList;
        user?: () => Promise<DatabaseProviderUserBuilder> | Promise<{
            default: DatabaseProviderUserBuilder;
        }>;
    };
    /**
     * Request data a guard client can set when making the
     * testing request
     */
    export type ClientRequestData = {
        session?: Record<string, any>;
        headers?: Record<string, any>;
        cookies?: Record<string, any>;
    };
    /**
     * The authentication clients should follow this interface
     */
    export interface GuardClientContract<Provider extends keyof ProvidersList> {
        /**
         * Login a user
         */
        login(user: GetProviderRealUser<Provider>, ...args: any[]): Promise<ClientRequestData>;
        /**
         * Logout user
         */
        logout(user: GetProviderRealUser<Provider>): Promise<void>;
    }
    export interface GuardContract<Provider extends keyof ProvidersList, Guard extends keyof GuardsList> {
        name: Guard;
        /**
         * Reference to the guard config
         */
        config: GuardsList[Guard]['config'];
        /**
         * Reference to the logged in user.
         */
        user?: GetProviderRealUser<Provider>;
        /**
         * Find if the user has been logged out in the current request
         */
        isLoggedOut: boolean;
        /**
         * A boolean to know if user is a guest or not. It is
         * always opposite of [[isLoggedIn]]
         */
        isGuest: boolean;
        /**
         * A boolean to know if user is logged in or not
         */
        isLoggedIn: boolean;
        /**
         * A boolean to know if user is retrieved by authenticating
         * the current request or not.
         */
        isAuthenticated: boolean;
        /**
         * Whether or not the authentication has been attempted
         * for the current request
         */
        authenticationAttempted: boolean;
        /**
         * Reference to the provider for looking up the user
         */
        provider: ProvidersList[Provider]['implementation'];
        /**
         * Verify user credentials.
         */
        verifyCredentials(uid: string, password: string): Promise<GetProviderRealUser<Provider>>;
        /**
         * Attempt to verify user credentials and perform login
         */
        attempt(uid: string, password: string, ...args: any[]): Promise<any>;
        /**
         * Login a user without any verification
         */
        login(user: GetProviderRealUser<Provider>, ...args: any[]): Promise<any>;
        /**
         * Login a user using their id
         */
        loginViaId(id: string | number, ...args: any[]): Promise<any>;
        /**
         * Attempts to authenticate the user for the current HTTP request. An exception
         * is raised when unable to do so
         */
        authenticate(): Promise<GetProviderRealUser<Provider>>;
        /**
         * Attempts to authenticate the user for the current HTTP request and supresses
         * exceptions raised by the [[authenticate]] method and returns a boolean
         */
        check(): Promise<boolean>;
        /**
         * Logout user
         */
        logout(...args: any[]): Promise<void>;
        /**
         * Serialize guard to JSON
         */
        toJSON(): any;
    }
    /**
     * Shape of data emitted by the login event
     */
    export type SessionLoginEventData<Provider extends keyof ProvidersList> = {
        name: string;
        user: GetProviderRealUser<Provider>;
        ctx: HttpContextContract;
        token: string | null;
    };
    /**
     * Shape of data emitted by the authenticate event
     */
    export type SessionAuthenticateEventData<Provider extends keyof ProvidersList> = {
        name: string;
        user: GetProviderRealUser<Provider>;
        ctx: HttpContextContract;
        viaRemember: boolean;
    };
    /**
     * Shape of the session guard
     */
    export interface SessionGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends GuardContract<Provider, Name> {
        /**
         * A boolean to know if user is loggedin via remember me token or not.
         */
        viaRemember: boolean;
        /**
         * Attempt to verify user credentials and perform login
         */
        attempt(uid: string, password: string, remember?: boolean): Promise<any>;
        /**
         * Login a user without any verification
         */
        login(user: GetProviderRealUser<Provider>, remember?: boolean): Promise<any>;
        /**
         * Login a user using their id
         */
        loginViaId(id: string | number, remember?: boolean): Promise<any>;
        /**
         * Logout user
         */
        logout(renewRememberToken?: boolean): Promise<void>;
    }
    /**
     * Session client to login users during tests
     */
    export interface SessionClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
    }
    /**
     * Shape of session driver config.
     */
    export type SessionGuardConfig<Provider extends keyof ProvidersList> = {
        driver: 'session';
        provider: ProvidersList[Provider]['config'];
    };
    /**
     * Shape of data emitted by the authenticate event
     */
    export type BasicAuthAuthenticateEventData<Provider extends keyof ProvidersList> = {
        name: string;
        user: GetProviderRealUser<Provider>;
        ctx: HttpContextContract;
    };
    /**
     * Shape of the basic auth guard
     */
    export interface BasicAuthGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends Omit<GuardContract<Provider, Name>, 'attempt' | 'login' | 'loginViaId' | 'logout'> {
    }
    /**
     * Basic auth client to login users during tests
     */
    export interface BasicAuthClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
    }
    /**
     * Shape of basic auth guard config.
     */
    export type BasicAuthGuardConfig<Provider extends keyof ProvidersList> = {
        driver: 'basic';
        realm?: string;
        provider: ProvidersList[Provider]['config'];
    };
    /**
     * Opaque token is generated during the login call by the OpaqueTokensGuard
     */
    export interface OpaqueTokenContract<User extends any> {
        /**
         * Always a bearer token
         */
        type: 'bearer';
        /**
         * The user for which the token was generated
         */
        user: User;
        /**
         * Date/time when the token will be expired
         */
        expiresAt?: DateTime;
        /**
         * Time in seconds until the token is valid
         */
        expiresIn?: number;
        /**
         * Any meta-data attached with the token
         */
        meta: any;
        /**
         * Token name
         */
        name: string;
        /**
         * Token public value
         */
        token: string;
        /**
         * Token hash (persisted to the db as well)
         */
        tokenHash: string;
        /**
         * Serialize token
         */
        toJSON(): {
            type: 'bearer';
            token: string;
            expires_at?: string;
            expires_in?: number;
        };
    }
    /**
     * Login options
     */
    export type OATLoginOptions = {
        name?: string;
        expiresIn?: number | string;
    } & {
        [key: string]: any;
    };
    /**
     * Shape of data emitted by the login event
     */
    export type OATLoginEventData<Provider extends keyof ProvidersList> = {
        name: string;
        user: GetProviderRealUser<Provider>;
        ctx: HttpContextContract;
        token: OpaqueTokenContract<GetProviderRealUser<Provider>>;
    };
    /**
     * Shape of the data emitted by the authenticate event
     */
    export type OATAuthenticateEventData<Provider extends keyof ProvidersList> = {
        name: string;
        user: GetProviderRealUser<Provider>;
        ctx: HttpContextContract;
        token: ProviderTokenContract;
    };
    /**
     * Shape of the OAT guard
     */
    export interface OATGuardContract<Provider extends keyof ProvidersList, Name extends keyof GuardsList> extends GuardContract<Provider, Name> {
        token?: ProviderTokenContract;
        tokenProvider: TokenProviderContract;
        /**
         * Attempt to verify user credentials and perform login
         */
        attempt(uid: string, password: string, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
        /**
         * Login a user without any verification
         */
        login(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
        /**
         * Generate token for a user without any verification
         */
        generate(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
        /**
         * Alias for logout
         */
        revoke(): Promise<void>;
        /**
         * Login a user using their id
         */
        loginViaId(id: string | number, options?: OATLoginOptions): Promise<OpaqueTokenContract<GetProviderRealUser<Provider>>>;
    }
    /**
     * Oat guard to login users during tests
     */
    export interface OATClientContract<Provider extends keyof ProvidersList> extends GuardClientContract<Provider> {
        login(user: GetProviderRealUser<Provider>, options?: OATLoginOptions): Promise<ClientRequestData>;
    }
    /**
     * Shape of OAT guard config.
     */
    export type OATGuardConfig<Provider extends keyof ProvidersList> = {
        /**
         * Driver name is always constant
         */
        driver: 'oat';
        /**
         * Provider for managing tokens
         */
        tokenProvider: DatabaseTokenProviderConfig | RedisTokenProviderConfig;
        /**
         * User provider
         */
        provider: ProvidersList[Provider]['config'];
    };
    /**
     * List of providers mappings used by the app. Using declaration
     * merging, one must extend this interface.
     *
     * MUST BE SET IN THE USER LAND.
     *
     * Example:
     *
     * lucid: {
     *   config: LucidProviderConfig<any>,
     *   implementation: LucidProviderContract<any>,
     * }
     *
     */
    export interface ProvidersList {
    }
    /**
     * List of guards mappings used by the app. Using declaration
     * merging, one must extend this interface.
     *
     * MUST BE SET IN THE USER LAND.
     *
     * Example:
     *
     * session: {
     *   config: SessionGuardConfig<'lucid'>,
     *   implementation: SessionGuardContract<'lucid'>,
     *   client: SessionClientContract<'lucid'>,
     * }
     *
     */
    export interface GuardsList {
    }
    /**
     * Shape of config accepted by the Auth module. It relies on the
     * [[GuardsList]] interface
     */
    export type AuthConfig = {
        guard: keyof GuardsList;
        guards: {
            [P in keyof GuardsList]: GuardsList[P]['config'];
        };
    };
    /**
     * Instance of the auth contract. The `use` method can be used to obtain
     * an instance of a given guard mapping for a single HTTP request
     */
    export interface AuthContract extends GuardContract<keyof ProvidersList, keyof GuardsList> {
        /**
         * The default guard for the current request
         */
        defaultGuard: string;
        /**
         * Use a given guard
         */
        use(): GuardContract<keyof ProvidersList, keyof GuardsList>;
        use<K extends keyof GuardsList>(guard: K): GuardsList[K]['implementation'];
    }
    /**
     * Shape of the callback accepted to add new user providers
     */
    export type ExtendProviderCallback = (auth: AuthManagerContract, mapping: string, config: any) => UserProviderContract<any>;
    /**
     * Shape of the callback accepted to add new guards
     */
    export type ExtendGuardCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>, ctx: HttpContextContract) => GuardContract<keyof ProvidersList, keyof GuardsList>;
    /**
     * Shape of the callback accepted to add custom testing
     * clients
     */
    export type ExtendClientCallback = (auth: AuthManagerContract, mapping: string, config: any, provider: UserProviderContract<any>) => GuardClientContract<keyof ProvidersList>;
    /**
     * Shape of the auth manager to register custom drivers and providers and
     * make instances of them
     */
    export interface AuthManagerContract {
        application: ApplicationContract;
        /**
         * The default guard
         */
        defaultGuard: string;
        /**
         * Returns the instance of [[AuthContract]] for a given HTTP request
         */
        getAuthForRequest(ctx: HttpContextContract): AuthContract;
        /**
         * Make instance of a mapping
         */
        makeMapping(ctx: HttpContextContract, mapping: string): GuardContract<keyof ProvidersList, keyof GuardsList>;
        makeMapping<K extends keyof GuardsList>(ctx: HttpContextContract, mapping: K): GuardsList[K]['implementation'];
        /**
         * Returns an instance of the auth client for a given
         * mapping
         */
        client(mapping: string): GuardClientContract<keyof ProvidersList>;
        /**
         * Extend by adding custom providers, guards and client
         */
        extend(type: 'provider', provider: string, callback: ExtendProviderCallback): void;
        extend(type: 'guard', guard: string, callback: ExtendGuardCallback): void;
        extend(type: 'client', guard: string, callback: ExtendClientCallback): void;
    }
    const AuthManager: AuthManagerContract;
    export default AuthManager;
}
