/*!
 * Copyright 2017 - 2020 by ChartIQ, Inc.
 * All rights reserved.
 */
/**
 * The Authentication Client supports three distinct areas of functionality:
 *
 * 1. The client API provides hooks for plugging in a custom sign-on component at the beginning of Finsemble start-up (before application-level components are started).
 * 2. The client API provides hooks for running authentication processes dynamically via "authentication profiles."
 * 3. The client API provides automatic login capabilities for Finsemble components (password auto-fill).
 *
 * See the [Authentication tutorial](/docs/productivity/API-tutorials-and-refs/authentication/) for an overview of using the Authentication Client.
 *
 * @module AuthenticationClient
 */
/**
This is how we want our API to work going foward, the way the world does it: import { processAndSet } from "configClient"
```
export const processAndSet = () => { ... }
```

This module's single exported object gives us backward compatibility when our core code does this: import { ConfigClient } from "configClient"
and provides the object that is attached to FSBL.Clients. This export should be kept as clean and simple as possible.
```
export const ConfigClient = {
   processAndSet
}
```

The default export gives us backward compatibility where our core code does this: import ConfigClient from "configClient"
This can be eliminated when our core core is converted to normal imports as in the first example.
```
export default ConfigClient;
```
*/
import { FinsembleWindow } from "../common/FinsembleWindow";
import { RouterClient } from "./routerClient";
import { Logger } from "./logger";
import { Startup } from "./Startup/Startup";
/**
 * @language javascript, java, dotnet
 * During Finsemble's start-up process, this function must be invoked before Finsemble will start the application.
 * Once invoked, the authenticated user name and authorization credentials are received by the Authentication Service and published on the "AuthenticationService.authorization" channel.
 * Any component can revive the credentials by subscribing to that channel or by calling <a href="/docs/productivity/API-tutorials-and-refs/authentication/#getCurrentCredentials">getCurrentCredentials</a>.
 *
 * Note that all calls to Storage Client are keyed to the authenticated user. See <a href="/docs/reference/typedocs/modules/StorageClient#setUser">StorageClient#setUser</a>.
 * If authentication is not enabled, then "defaultUser" is used instead.
 *
 * ```javascript
 * FSBL.Clients.AuthenticationClient.publishAuthorization(username, credentials);
 * ```
 * @param user The name of the authenticated user
 * @param credentials The authorization credentials (or token) for the current user, as specified by the application's authentication component.
 */
export const publishAuthorization = (user, credentials) => {
    RouterClient.transmit("AuthenticationService.authorization", {
        user,
        credentials,
    });
};
/**
 * @language javascript, java, dotnet
 * Returns the current global credentials (as published through <a href="/docs/productivity/API-tutorials-and-refs/authentication#publishAuthorization">publishAuthorization</a>) or null if no credentials are set yet.
 * @param cb A function that returns the current credentials. Will return null/undefined if no credentials have yet been established.
 */
export const getCurrentCredentials = async (cb) => {
    const { err, response } = await RouterClient.query("authentication.currentCredentials", null);
    const { data } = response;
    const credentials = err ? null : response.data;
    cb === null || cb === void 0 ? void 0 : cb(err, credentials);
    return { err, data };
};
/**
 * @language javascript, java
 * @deprecated
 * Sends the provided data to the authentication service for a sign-on attempt.
 */
export const transmitSignOnToAuthService = (signOnData) => {
    Logger.system.deprecated("AuthenticationClient.transmitSignOnToAuthService() is deprecated.");
    Logger.system.debug("AUTHORIZATION: Transmitting SignOn To AuthService");
    RouterClient.transmit("authentication.dialogSignOnToAuthService", signOnData);
};
/**
 * @language javascript
 * @deprecated
 *
 * ALPHA Automatic sign-on Function. Returns the sign on data after either prompting user or getting a cached version.
 *
 * @param signOnKey component-defined unique identifier string representing the sign-on data (the same string must be used for each unique sign on).
 * @param params
 * @param params.icon a URL to an icon that displaces the Finsemble icon for the sign-on dialog.
 * @param params.prompt A string to display in the sign on dialog.
 * @param params.force Whether the sign-on dialog should be used even if accepted sign-on data is available in the encrypted store.
 * @param params.userMsg Optional parameter to be displayed for the user in the sign-on dialog.
 * @param cb callback (err,response) with the response being an object: { signOnKey, username, password, validationRequired }
 */
export const appSignOn = async (signOnKey, params, cb) => {
    Logger.system.deprecated("AuthenticationClient.appSignOn() is deprecated.");
    Logger.system.debug(`AUTHORIZATION: Signing on to app ${signOnKey}`);
    const { err, response } = await RouterClient.query("authentication.appSignOn", { signOnKey, params }, { timeout: -1 });
    if (err || !response) {
        const error = err !== null && err !== void 0 ? err : `Internal error: appSignOn(): No data returned from service for "authentication.appSignOn"`;
        if (cb)
            cb(error);
        return { err: error };
    }
    else {
        if (cb)
            cb(null, response.data);
        return { data: response.data };
    }
};
/**
 * @language javascript
 * @deprecated
 *
 * ALPHA Automatic sign-on Function. Rejects previous sign-on data and restarts sign on. Returns the sign-on data after either prompting user or getting a cached version. Should only be called when `validationRequired` is `true` in sign-on response.
 *
 * @param signOnKey
 * @param params object
 * @param params.userMsg An optional message to be displayed for the user in the sign-on dialog
 * @param cb
 */
export const appRejectAndRetrySignOn = (signOnKey, params, cb) => {
    Logger.system.deprecated("AuthenticationClient.appRejectAndRetrySignOn() is deprecated.");
    Logger.system.warn("AUTHORIZATION: appRejectAndRetrySignOn", signOnKey);
    RouterClient.query("authentication.appRejectAndRetrySignOn", { signOnKey, params }, { timeout: -1 }, (err, response) => {
        if (cb) {
            cb(err, response.data);
        }
    });
};
/**
 * @deprecated
 *
 * ALPHA Automatic sign-on Function. Accepts the data returned by `appSignOn`, causing the data to be saved for future use. Should only be called when `validationRequired` is `true` in sign-on response.
 *
 * @param signOnKey
 */
const appAcceptSignOn = (signOnKey) => {
    Logger.system.deprecated("AuthenticationClient.appAcceptSignOn() is deprecated.");
    Logger.system.info("AUTHORIZATION: Accepted application sign on.", signOnKey);
    RouterClient.transmit("authentication.appAcceptSignOn", { signOnKey });
};
/**
 * @deprecated
 *
 * ALPHA Automatic sign-on Function. Rejects the data returned by previous sign on. Should only be called when validationRequired is true in sign-on response.
 *
 * @param signOnKey
 */
const appRejectSignOn = (signOnKey) => {
    Logger.system.deprecated("AuthenticationClient.appRejectSignOn() is deprecated.");
    Logger.system.error("AUTHORIZATION: Rejected application sign on.", signOnKey);
    RouterClient.transmit("authentication.appRejectSignOn", { signOnKey });
};
/**
 * @language javascript, java
 * Completes an OAuth2 authentication that was begun with <a href="/docs/productivity/API-tutorials-and-refs/authentication#beginAuthentication">beginAuthentication</a>.
 * This function is called when an OAuth2 response is completed.
 * You should call this function from within the page that you specified in "redirect_uri" in your Authentication Profile config.
 * @param err The error to be returned if the method fails.
 * @param params Optionally pass the OAuth2 query string parameters from your response page. Set to null and the query string will automatically be parsed based on the OAuth2 specification.
 * @param cb Returns the result (err, data). Data will contain the results of the authentication process, such as the access_token and other values provided by your Identify Provider.
 */
export const completeOAUTH = async (err, params, cb) => {
    var _a, _b;
    Logger.system.log("completeOAUTH", params);
    // Get parameters from the query string by default
    if (!params) {
        params = {};
        const queryString = new URLSearchParams(window.location.search);
        // Convert URLSearchParams into POJO
        for (const pair of queryString.entries()) {
            params[pair[0]] = pair[1];
        }
    }
    // Normally, we should have the "state" back by now, but sometimes oauth can get stuck in limbo, for instance
    // if the identity provider's redirect page doesn't return properly. In this case, we revert to looking
    // for our original "state" in the window's options (customData) where we had previously stashed it away for
    // just such a circumstance.
    if (!params.state) {
        const windowName = Startup.getInstance().getStartupData();
        const { wrap } = await FinsembleWindow.getInstance({ name: windowName });
        const { data } = await wrap.getOptions();
        if (data)
            params.state = (_b = (_a = data === null || data === void 0 ? void 0 : data.customData) === null || _a === void 0 ? void 0 : _a.OAuthState) !== null && _b !== void 0 ? _b : {};
    }
    const { err: queryError, response } = await RouterClient.query("authentication.completeOAUTH", { err, params });
    const { data } = response;
    cb === null || cb === void 0 ? void 0 : cb(queryError, data);
    return { err: queryError, data };
};
/**
 * @language javascript, java
 * Starts an authentication process. The callback will be triggered when the authentication is totally complete.
 * Use this method if you have a component that needs to complete an authentication process, such as OAuth2.
 *
 * You must set up an "authentication profile" in your Finsemble config. Reference the name of that profile
 * in params.profile.
 *
 * @param params Parameters
 * @param params.profile The name of the authentication profile from the authentication config section. See [startup](/docs/reference/ConfigReference) for instance.
 * @param params.spawnParams Optionally specify parameters to send to spawn for spawning an authentication window. These parameters are the same as those found in <a href="/docs/reference/typedocs/modules/LauncherClient#spawn">LauncherClient#spawn</a>.
 * @param cb Returns an object containing the authentication response, i.e., OAuth credentials, etc
 */
export const beginAuthentication = async (params, cb) => {
    const { err, response } = await RouterClient.query("authentication.beginAuthentication", params);
    const { data } = response;
    cb === null || cb === void 0 ? void 0 : cb(err, data);
    return { err, data };
};
/**
 * @ignore
 */
export const AuthenticationClient = {
    /**
     * For backward compatibility
     * @private
     * @deprecated
     */
    initialize: () => {
        Logger.system.deprecated("It is no longer necessary to call AuthenticationClient.initialize()");
    },
    /**
     * For backward compatibility
     * @private
     * @deprecated
     */
    onReady: (cb) => {
        Logger.system.deprecated("It is no longer necessary to call AuthenticationClient.onReady()");
        cb === null || cb === void 0 ? void 0 : cb();
    },
    beginAuthentication,
    completeOAUTH,
    transmitSignOnToAuthService,
    getCurrentCredentials,
    publishAuthorization,
    appRejectAndRetrySignOn,
    appRejectSignOn,
    appAcceptSignOn,
    appSignOn,
};
/**
 * @ignore
 */
export default AuthenticationClient;
//# sourceMappingURL=authenticationClient.js.map