/// <reference types="node" />
import { IncomingMessage, ServerResponse } from 'http';
import { WebClientOptions } from '@slack/web-api';
import { CodedError } from './errors';
import { Logger, LogLevel } from './logger';
/**
 * InstallProvider Class.
 * @param clientId - Your apps client ID
 * @param clientSecret - Your apps client Secret
 * @param stateSecret - Used to sign and verify the generated state when using the built-in `stateStore`
 * @param stateStore - Replacement function for the built-in `stateStore`
 * @param installationStore - Interface to store and retrieve installation data from the database
 * @param authVersion - Can be either `v1` or `v2`. Determines which slack Oauth URL and method to use
 * @param logger - Pass in your own Logger if you don't want to use the built-in one
 * @param logLevel - Pass in the log level you want (ERROR, WARN, INFO, DEBUG). Default is INFO
 */
export declare class InstallProvider {
    stateStore: StateStore;
    installationStore: InstallationStore;
    private clientId;
    private clientSecret;
    private authVersion;
    private logger;
    private clientOptions;
    private authorizationUrl;
    constructor({ clientId, clientSecret, stateSecret, stateStore, installationStore, authVersion, logger, logLevel, clientOptions, authorizationUrl, }: InstallProviderOptions);
    /**
     * Fetches data from the installationStore for non Org Installations.
     */
    authorize(source: InstallationQuery<boolean>): Promise<AuthorizeResult>;
    /**
     * Returns a URL that is suitable for including in an Add to Slack button
     * Uses stateStore to generate a value for the state query param.
     */
    generateInstallUrl(options: InstallURLOptions): Promise<string>;
    /**
     * This method handles the incoming request to the callback URL.
     * It can be used as a RequestListener in almost any HTTP server
     * framework.
     *
     * Verifies the state using the stateStore, exchanges the grant in the
     * query params for an access token, and stores token and associated data
     * in the installationStore.
     */
    handleCallback(req: IncomingMessage, res: ServerResponse, options?: CallbackOptions): Promise<void>;
}
export interface InstallProviderOptions {
    clientId: string;
    clientSecret: string;
    stateStore?: StateStore;
    stateSecret?: string;
    installationStore?: InstallationStore;
    authVersion?: 'v1' | 'v2';
    logger?: Logger;
    logLevel?: LogLevel;
    clientOptions?: Omit<WebClientOptions, 'logLevel' | 'logger'>;
    authorizationUrl?: string;
}
export interface InstallURLOptions {
    scopes: string | string[];
    teamId?: string;
    redirectUri?: string;
    userScopes?: string | string[];
    metadata?: string;
}
export interface CallbackOptions {
    success?: (installation: Installation | OrgInstallation, options: InstallURLOptions, callbackReq: IncomingMessage, callbackRes: ServerResponse) => void;
    failure?: (error: CodedError, options: InstallURLOptions, callbackReq: IncomingMessage, callbackRes: ServerResponse) => void;
}
export interface StateStore {
    generateStateParam: (installOptions: InstallURLOptions, now: Date) => Promise<string>;
    verifyStateParam: (now: Date, state: string) => Promise<InstallURLOptions>;
}
export interface InstallationStore {
    storeInstallation<AuthVersion extends 'v1' | 'v2'>(installation: Installation<AuthVersion, boolean>, logger?: Logger): Promise<void>;
    fetchInstallation: (query: InstallationQuery<boolean>, logger?: Logger) => Promise<Installation<'v1' | 'v2', boolean>>;
}
/**
 * An individual installation of the Slack app.
 *
 * This interface creates a representation for installations that normalizes the responses from OAuth grant exchanges
 * across auth versions (responses from the Web API methods `oauth.v2.access` and `oauth.access`). It describes some of
 * these differences using the `AuthVersion` generic placeholder type.
 *
 * This interface also represents both installations which occur on individual Slack workspaces and on Slack enterprise
 * organizations. The `IsEnterpriseInstall` generic placeholder type is used to describe some of those differences.
 *
 * This representation is designed to be used both when producing data that should be stored by an InstallationStore,
 * and when consuming data that is fetched from an InstallationStore. Most often, InstallationStore implementations
 * are a database. If you are going to implement an InstallationStore, it's advised that you **store as much of the
 * data in these objects as possible so that you can return as much as possible inside `fetchInstallation()`**.
 *
 * A few properties are synthesized with a default value if they are not present when returned from
 * `fetchInstallation()`. These properties are optional in the interface so that stored installations from previous
 * versions of this library (from before those properties were introduced) continue to work without requiring a breaking
 * change. However the synthesized default values are not always perfect and are based on some assumptions, so this is
 * why it's recommended to store as much of that data as possible in any InstallationStore.
 *
 * Some of the properties (e.g. `team.name`) can change between when the installation occurred and when it is fetched
 * from the InstallationStore. This can be seen as a reason not to store those properties. In most workspaces these
 * properties rarely change, and for most Slack apps having a slightly out of date value has no impact. However if your
 * app uses these values in a way where it must be up to date, it's recommended to implement a caching strategy in the
 * InstallationStore to fetch the latest data from the Web API (using methods such as `auth.test`, `teams.info`, etc.)
 * as often as it makes sense for your Slack app.
 *
 * TODO: IsEnterpriseInstall is always false when AuthVersion is v1
 */
export interface Installation<AuthVersion extends ('v1' | 'v2') = ('v1' | 'v2'), IsEnterpriseInstall extends boolean = boolean> {
    /**
     * TODO: when performing a “single workspace” install with the admin scope on the enterprise,
     * is the team property returned from oauth.access?
     */
    team: IsEnterpriseInstall extends true ? undefined : {
        id: string;
        /** Left as undefined when not returned from fetch. */
        name?: string;
    };
    /**
     * When the installation is an enterprise install or when the installation occurs on the org to acquire `admin` scope,
     * the name and ID of the enterprise org.
     */
    enterprise: IsEnterpriseInstall extends true ? EnterpriseInfo : (EnterpriseInfo | undefined);
    user: {
        token: AuthVersion extends 'v1' ? string : (string | undefined);
        scopes: AuthVersion extends 'v1' ? string[] : (string[] | undefined);
        id: string;
    };
    bot?: {
        token: string;
        scopes: string[];
        id: string;
        userId: string;
    };
    incomingWebhook?: {
        url: string;
        /** Left as undefined when not returned from fetch. */
        channel?: string;
        /** Left as undefined when not returned from fetch. */
        channelId?: string;
        /** Left as undefined when not returned from fetch. */
        configurationUrl?: string;
    };
    /** The App ID, which does not vary per installation. Left as undefined when not returned from fetch. */
    appId?: AuthVersion extends 'v2' ? string : undefined;
    /** When the installation contains a bot user, the token type. Left as undefined when not returned from fetch. */
    tokenType?: 'bot';
    /**
     * When the installation is an enterprise org install, the URL of the landing page for all workspaces in the org.
     * Left as undefined when not returned from fetch.
     */
    enterpriseUrl?: AuthVersion extends 'v2' ? string : undefined;
    /** Whether the installation was performed on an enterprise org. Synthesized as `false` when not present. */
    isEnterpriseInstall?: IsEnterpriseInstall;
    /** The version of Slack's auth flow that produced this installation. Synthesized as `v2` when not present. */
    authVersion?: AuthVersion;
}
/**
 * A type to describe enterprise organization installations.
 */
export declare type OrgInstallation = Installation<'v2', true>;
interface EnterpriseInfo {
    id: string;
    name?: string;
}
export interface InstallationQuery<isEnterpriseInstall extends boolean> {
    teamId: isEnterpriseInstall extends false ? string : undefined;
    enterpriseId: isEnterpriseInstall extends true ? string : (string | undefined);
    userId?: string;
    conversationId?: string;
    isEnterpriseInstall: isEnterpriseInstall;
}
export declare type OrgInstallationQuery = InstallationQuery<true>;
export interface AuthorizeResult {
    botToken?: string;
    userToken?: string;
    botId?: string;
    botUserId?: string;
    teamId?: string;
    enterpriseId?: string;
}
export { Logger, LogLevel } from './logger';
//# sourceMappingURL=index.d.ts.map