@aws-amplify/auth
Version:
Auth category of aws-amplify
120 lines (118 loc) • 5.31 kB
JavaScript
;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
Object.defineProperty(exports, "__esModule", { value: true });
exports.signInWithRedirect = void 0;
const core_1 = require("@aws-amplify/core");
const utils_1 = require("@aws-amplify/core/internals/utils");
require("../utils/oauth/enableOAuthListener");
const models_1 = require("../types/models");
const utils_2 = require("../../../utils");
const signInHelpers_1 = require("../utils/signInHelpers");
const oauth_1 = require("../utils/oauth");
const createOAuthError_1 = require("../utils/oauth/createOAuthError");
const cancelOAuthFlow_1 = require("../utils/oauth/cancelOAuthFlow");
/**
* Signs in a user with OAuth. Redirects the application to an Identity Provider.
*
* @param input - The SignInWithRedirectInput object, if empty it will redirect to Cognito HostedUI
*
* @throws AuthTokenConfigException - Thrown when the user pool config is invalid.
* @throws OAuthNotConfigureException - Thrown when the oauth config is invalid.
*/
async function signInWithRedirect(input) {
const authConfig = core_1.Amplify.getConfig().Auth?.Cognito;
(0, utils_1.assertTokenProviderConfig)(authConfig);
(0, utils_1.assertOAuthConfig)(authConfig);
oauth_1.oAuthStore.setAuthConfig(authConfig);
await (0, signInHelpers_1.assertUserNotAuthenticated)();
let provider = 'COGNITO'; // Default
if (typeof input?.provider === 'string') {
provider = models_1.cognitoHostedUIIdentityProviderMap[input.provider];
}
else if (input?.provider?.custom) {
provider = input.provider.custom;
}
return oauthSignIn({
oauthConfig: authConfig.loginWith.oauth,
clientId: authConfig.userPoolClientId,
provider,
customState: input?.customState,
preferPrivateSession: input?.options?.preferPrivateSession,
options: {
loginHint: input?.options?.loginHint,
lang: input?.options?.lang,
nonce: input?.options?.nonce,
},
});
}
exports.signInWithRedirect = signInWithRedirect;
const oauthSignIn = async ({ oauthConfig, provider, clientId, customState, preferPrivateSession, options, }) => {
const { domain, redirectSignIn, responseType, scopes } = oauthConfig;
const { loginHint, lang, nonce } = options ?? {};
const randomState = (0, oauth_1.generateState)();
/* encodeURIComponent is not URL safe, use urlSafeEncode instead. Cognito
single-encodes/decodes url on first sign in and double-encodes/decodes url
when user already signed in. Using encodeURIComponent, Base32, Base64 add
characters % or = which on further encoding becomes unsafe. '=' create issue
for parsing query params.
Refer: https://github.com/aws-amplify/amplify-js/issues/5218 */
const state = customState
? `${randomState}-${(0, utils_1.urlSafeEncode)(customState)}`
: randomState;
const { value, method, toCodeChallenge } = (0, oauth_1.generateCodeVerifier)(128);
const redirectUri = (0, oauth_1.getRedirectUrl)(oauthConfig.redirectSignIn);
if ((0, utils_1.isBrowser)())
oauth_1.oAuthStore.storeOAuthInFlight(true);
oauth_1.oAuthStore.storeOAuthState(state);
oauth_1.oAuthStore.storePKCE(value);
const queryString = Object.entries({
redirect_uri: redirectUri,
response_type: responseType,
client_id: clientId,
identity_provider: provider,
scope: scopes.join(' '),
// eslint-disable-next-line camelcase
...(loginHint && { login_hint: loginHint }),
...(lang && { lang }),
...(nonce && { nonce }),
state,
...(responseType === 'code' && {
code_challenge: toCodeChallenge(),
code_challenge_method: method,
}),
})
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&');
// TODO(v6): use URL object instead
const oAuthUrl = `https://${domain}/oauth2/authorize?${queryString}`;
// this will only take effect in the following scenarios:
// 1. the user cancels the OAuth flow on web via back button, and
// 2. when bfcache is enabled
(0, cancelOAuthFlow_1.listenForOAuthFlowCancellation)(oauth_1.oAuthStore);
// the following is effective only in react-native as openAuthSession resolves only in react-native
const { type, error, url } = (await (0, utils_2.openAuthSession)(oAuthUrl, redirectSignIn, preferPrivateSession)) ??
{};
try {
if (type === 'error') {
throw (0, createOAuthError_1.createOAuthError)(String(error));
}
if (type === 'success' && url) {
await (0, oauth_1.completeOAuthFlow)({
currentUrl: url,
clientId,
domain,
redirectUri,
responseType,
userAgentValue: (0, utils_2.getAuthUserAgentValue)(utils_1.AuthAction.SignInWithRedirect),
preferPrivateSession,
});
}
}
catch (err) {
await (0, oauth_1.handleFailure)(err);
// rethrow the error so it can be caught by `await signInWithRedirect()` in react-native
throw err;
}
};
//# sourceMappingURL=signInWithRedirect.js.map