private async _handleAuthResponse()

in packages/auth/src/Auth.ts [2086:2225]


	private async _handleAuthResponse(URL?: string) {
		if (this.oAuthFlowInProgress) {
			logger.debug(`Skipping URL ${URL} current flow in progress`);
			return;
		}

		try {
			this.oAuthFlowInProgress = true;
			if (!this._config.userPoolId) {
				throw new Error(
					`OAuth responses require a User Pool defined in config`
				);
			}

			dispatchAuthEvent(
				'parsingCallbackUrl',
				{ url: URL },
				`The callback url is being parsed`
			);

			const currentUrl =
				URL || (JS.browserOrNode().isBrowser ? window.location.href : '');

			const hasCodeOrError = !!(parse(currentUrl).query || '')
				.split('&')
				.map(entry => entry.split('='))
				.find(([k]) => k === 'code' || k === 'error');

			const hasTokenOrError = !!(parse(currentUrl).hash || '#')
				.substr(1)
				.split('&')
				.map(entry => entry.split('='))
				.find(([k]) => k === 'access_token' || k === 'error');

			if (hasCodeOrError || hasTokenOrError) {
				this._storage.setItem('amplify-redirected-from-hosted-ui', 'true');
				try {
					const { accessToken, idToken, refreshToken, state } =
						await this._oAuthHandler.handleAuthResponse(currentUrl);
					const session = new CognitoUserSession({
						IdToken: new CognitoIdToken({ IdToken: idToken }),
						RefreshToken: new CognitoRefreshToken({
							RefreshToken: refreshToken,
						}),
						AccessToken: new CognitoAccessToken({
							AccessToken: accessToken,
						}),
					});

					let credentials;
					// Get AWS Credentials & store if Identity Pool is defined
					if (this._config.identityPoolId) {
						credentials = await this.Credentials.set(session, 'session');
						logger.debug('AWS credentials', credentials);
					}

					/* 
				Prior to the request we do sign the custom state along with the state we set. This check will verify
				if there is a dash indicated when setting custom state from the request. If a dash is contained
				then there is custom state present on the state string.
				*/
					const isCustomStateIncluded = /-/.test(state);

					/*
				The following is to create a user for the Cognito Identity SDK to store the tokens
				When we remove this SDK later that logic will have to be centralized in our new version
				*/
					//#region
					const currentUser = this.createCognitoUser(
						session.getIdToken().decodePayload()['cognito:username']
					);

					// This calls cacheTokens() in Cognito SDK
					currentUser.setSignInUserSession(session);

					if (window && typeof window.history !== 'undefined') {
						window.history.replaceState(
							{},
							null,
							(this._config.oauth as AwsCognitoOAuthOpts).redirectSignIn
						);
					}

					dispatchAuthEvent(
						'signIn',
						currentUser,
						`A user ${currentUser.getUsername()} has been signed in`
					);
					dispatchAuthEvent(
						'cognitoHostedUI',
						currentUser,
						`A user ${currentUser.getUsername()} has been signed in via Cognito Hosted UI`
					);

					if (isCustomStateIncluded) {
						const customState = state.split('-').splice(1).join('-');

						dispatchAuthEvent(
							'customOAuthState',
							urlSafeDecode(customState),
							`State for user ${currentUser.getUsername()}`
						);
					}
					//#endregion

					return credentials;
				} catch (err) {
					logger.debug('Error in cognito hosted auth response', err);

					// Just like a successful handling of `?code`, replace the window history to "dispose" of the `code`.
					// Otherwise, reloading the page will throw errors as the `code` has already been spent.
					if (window && typeof window.history !== 'undefined') {
						window.history.replaceState(
							{},
							null,
							(this._config.oauth as AwsCognitoOAuthOpts).redirectSignIn
						);
					}

					dispatchAuthEvent(
						'signIn_failure',
						err,
						`The OAuth response flow failed`
					);
					dispatchAuthEvent(
						'cognitoHostedUI_failure',
						err,
						`A failure occurred when returning to the Cognito Hosted UI`
					);
					dispatchAuthEvent(
						'customState_failure',
						err,
						`A failure occurred when returning state`
					);
				}
			}
		} finally {
			this.oAuthFlowInProgress = false;
		}
	}