UNPKG

aws-amplify

Version:

AWS Amplify is a JavaScript library for Frontend and mobile developers building cloud-enabled applications.

179 lines (177 loc) • 8.72 kB
'use strict'; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 Object.defineProperty(exports, "__esModule", { value: true }); exports.Amplify = void 0; const core_1 = require("@aws-amplify/core"); const utils_1 = require("@aws-amplify/core/internals/utils"); const cognito_1 = require("./auth/cognito"); /** * The `Amplify` singleton facade provides the v6-compatible, global-state * `configure()` / `getConfig()` API. It builds a branded, frozen * {@link AmplifyContext}, publishes it as the global context (so category APIs * can be called without an explicit context argument), and dispatches the * `configure` Hub event that side effects such as auth's OAuth listener depend * on. * * @example * ```ts * import { Amplify } from 'aws-amplify'; * import config from './amplifyconfiguration.json'; * * Amplify.configure(config); * ``` */ exports.Amplify = { /** * Configures Amplify with the {@link resourceConfig} and {@link libraryOptions}, * publishing the resulting branded context as the global {@link AmplifyContext}. * * If `libraryOptions` is omitted on a reconfigure, the previously configured * non-Auth `libraryOptions` are preserved (mirroring the previous singleton * merge behavior); when provided they replace the previous ones. When * `resourceConfig.Auth` is present and the caller does not supply * `libraryOptions.Auth`, the default Cognito token/credentials providers are * wired using cookie storage (`ssr: true`) or `localStorage` (default), and * the singleton token provider's auth config is re-synced on every call so a * reconfigure with a new `userPoolId` retargets token refresh. * * @param resourceConfig The {@link ResourcesConfig} object that is typically imported from the * `amplifyconfiguration.json` / `amplify_outputs.json` file. It can also be an object literal * created inline when calling `Amplify.configure`. * @param libraryOptions The {@link LibraryOptions} additional options for the library. * * @example * import config from './amplifyconfiguration.json'; * * Amplify.configure(config); */ configure(resourceConfig, libraryOptions) { const resolvedResourceConfig = (0, utils_1.parseAmplifyConfig)(resourceConfig); const previousLibraryOptions = (0, core_1.hasGlobalContext)() ? (0, core_1.getGlobalContext)().libraryOptions : undefined; const resolvedLibraryOptions = resolveLibraryOptions(resolvedResourceConfig, libraryOptions, previousLibraryOptions); // Build a branded + frozen context (with a fresh per-context AuthClass) // via the core factory, then publish it as the global context. const ctx = (0, core_1.createAmplifyContext)(resolvedResourceConfig, resolvedLibraryOptions); (0, utils_1.setGlobalContext)(ctx); // Notify listeners (e.g. auth's OAuth completion side effect) that the // library has been (re)configured. The payload `data` carries the parsed // ResourcesConfig so listeners can read `data.Auth.Cognito`. core_1.Hub.dispatch('core', { event: 'configure', data: resolvedResourceConfig, }, 'Configure', utils_1.AMPLIFY_SYMBOL); }, /** * Returns the {@link ResourcesConfig} object passed in as the `resourceConfig` parameter when * calling `Amplify.configure`. * * If `configure()` has not been called yet, this warns and returns an empty * config object (`{}`) rather than throwing, preserving the historical * pre-context singleton behavior that callers (and release-gating e2e tests) * depend on. * * @returns An {@link ResourcesConfig} object. */ getConfig() { if (!(0, core_1.hasGlobalContext)()) { // Preserve the historical unconfigured UX from the core singleton: // warn and return an empty config instead of throwing. // eslint-disable-next-line no-console console.warn(`Amplify has not been configured. Please call Amplify.configure() before using this service.`); return {}; } return (0, core_1.getGlobalContext)().resourcesConfig; }, /** * Fetches the current auth session from the global context. * * @throws If `configure()` has not been called yet. */ fetchAuthSession(options) { return (0, core_1.getGlobalContext)().fetchAuthSession(options); }, /** * Clears cached credentials in the global context. * * @throws If `configure()` has not been called yet. */ clearCredentials() { return (0, core_1.getGlobalContext)().clearCredentials(); }, /** * Fetches auth tokens from the global context. * * @throws If `configure()` has not been called yet. */ getTokens(options) { return (0, core_1.getGlobalContext)().getTokens(options); }, }; /** * Resolves the effective {@link LibraryOptions} for the global singleton, * preserving the previous `DefaultAmplify`-style default-provider * behavior (process-wide **singleton** Cognito providers, `setAuthConfig` / * `setKeyValueStorage` refresh). * * - No `Auth` in the resource config → pass options through unchanged * (preserving previously-resolved options when the caller supplies none). * - Caller-provided `libraryOptions.Auth` → take precedence (no defaults). * - Otherwise (Auth present, no caller-supplied Auth providers) → on **every** * call, including reconfigures with or without other `libraryOptions`, refresh * the singleton token provider's auth config + storage and inject the * singleton token/credentials providers. Non-Auth library options are still * carried forward from the previous configuration when the caller passes none. */ function resolveLibraryOptions(resourceConfig, libraryOptions, previousLibraryOptions) { // Pass-through: with no Auth in the resource config the singleton token // provider is never involved, so simply preserve the previously configured // libraryOptions when the caller supplies none (the core AmplifyClass // singleton used to perform this merge), otherwise use what was given. if (!resourceConfig.Auth) { if (!libraryOptions && previousLibraryOptions) { return previousLibraryOptions; } return libraryOptions ?? {}; } // Caller-provided Auth providers always take precedence; never touch the // singleton token provider in that case. if (libraryOptions?.Auth) { return libraryOptions; } // Auth is present and the caller did NOT supply their own Auth providers. // Carry non-Auth library options forward from the previous configuration // when the caller passes none (preserving prior behavior across // reconfigure), but ALWAYS re-sync the // singleton token provider below so the Auth providers never go stale. const baseLibraryOptions = libraryOptions ?? previousLibraryOptions ?? {}; // Select the storage backing the default providers via core's shared // helper (ssr → fresh cookie storage, else the localStorage-backed // singleton). When ssr is set, reuse the SAME cookie storage instance for // the identity-id store so tokens and identity ids share one cookie jar. const resolvedKeyValueStorage = (0, utils_1.selectSsrKeyValueStorage)(baseLibraryOptions.ssr); const resolvedCredentialsProvider = baseLibraryOptions.ssr ? new cognito_1.CognitoAWSCredentialsAndIdentityIdProvider(new cognito_1.DefaultIdentityIdStore(resolvedKeyValueStorage)) : cognito_1.cognitoCredentialsProvider; // Re-push the resolved auth config + key-value storage into the process-wide // singleton token provider on EVERY configure call. AuthClass.getTokens // delegates to this provider's own authConfig, which is only ever updated // here; skipping this on a reconfigure (e.g. a new userPoolId with no // libraryOptions) would leave token refresh pinned to the previous pool // while getConfig()/credentials reflect the new one. Restores the #14819 // contract. cognito_1.cognitoUserPoolsTokenProvider.setAuthConfig(resourceConfig.Auth); cognito_1.cognitoUserPoolsTokenProvider.setKeyValueStorage( // TODO: allow configure with a public interface resolvedKeyValueStorage); return { ...baseLibraryOptions, Auth: { tokenProvider: cognito_1.cognitoUserPoolsTokenProvider, credentialsProvider: resolvedCredentialsProvider, }, }; } //# sourceMappingURL=Amplify.js.map