in packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/index.tsx [125:277]
async function verifySession(code: string) {
clearErrorMessages();
logViewEvent(`flow.${viewName}`, 'submit', REACT_ENTRYPOINT);
GleanMetrics.signupConfirmation.submit();
try {
const hasSelectedNewsletters = newsletters && newsletters.length > 0;
const service = integration.getService();
const clientId = integration.getClientId();
const options = {
...(hasSelectedNewsletters && { ...{ newsletters } }),
...(isOAuthIntegration(integration) && {
scopes: integration.getPermissions(),
}),
// See oauth_client_info in the auth-server for details on service/clientId
// Sending up the clientId when the user is not signing in to the browser
// is used to show the correct service name in emails
...(isFirefoxService(service) ? { service } : { service: clientId }),
};
await session.verifySession(code, options);
logViewEvent(
`flow.${viewName}`,
'verification.success',
REACT_ENTRYPOINT
);
GleanMetrics.registration.complete();
// since many of the branches below lead to a redirect, we'll wait for
// the Glean requests
await GleanMetrics.isDone();
storeAccountData({
sessionToken,
email,
uid,
// Update verification status of stored current account
verified: true,
});
if (hasSelectedNewsletters) {
logViewEvent(`flow`, 'newsletter.subscribed', REACT_ENTRYPOINT);
}
if (isSyncDesktopV3Integration(integration)) {
const { to } = getSyncNavigate(location.search);
// will navigate to pair route which is still in backbone
hardNavigate(to);
} else if (isOAuthIntegration(integration)) {
// Check to see if the relier wants TOTP.
// Newly created accounts wouldn't have this so lets redirect them to signin.
// Certain reliers may require users to set up 2FA / TOTP
// before they can be redirected back to the RP.
// Notes in content-server indicate that a message should be displayed on the signin page
// to explain why totp setup is required, but this does not currently
// appear to be implemented.
// Params are included to eventually allow for redirect to RP after 2FA setup
if (integration.wantsTwoStepAuthentication()) {
navigateWithQuery('oauth/signin');
return;
} else {
const { redirect, code, state, error } = await finishOAuthFlowHandler(
uid,
sessionToken,
keyFetchToken,
unwrapBKey
);
if (error) {
setLocalizedErrorBannerHeading(
getLocalizedErrorMessage(ftlMsgResolver, error)
);
return;
}
if (integration.isSync()) {
firefox.fxaOAuthLogin({
// OAuth desktop looks at the sync engine list in fxaLogin. Oauth
// mobile currently looks at the engines provided here, but should
// eventually move to look at fxaLogin as well to prevent FXA-10596.
declinedSyncEngines,
offeredSyncEngines,
action: 'signup',
code,
redirect,
state,
});
// Mobile sync will close the web view, OAuth Desktop mimics DesktopV3 behavior
const { to } = getSyncNavigate(location.search);
hardNavigate(to);
return;
} else if (isDesktopRelay) {
firefox.fxaOAuthLogin({
action: 'signup',
code,
redirect,
state,
});
goToSettingsWithAlertSuccess();
} else {
// Navigate to relying party
hardNavigate(redirect);
return;
}
}
} else if (isWebIntegration(integration)) {
// SubPlat redirect
if (integration.data.redirectTo) {
if (webRedirectCheck.isValid) {
hardNavigate(integration.data.redirectTo);
} else if (webRedirectCheck?.localizedInvalidRedirectError) {
// Even if the code submission is successful, show the user this error
// message if the redirect is invalid to match parity with content-server.
// This may but may be revisited when we look at our signup flows as a whole.
setLocalizedErrorBannerHeading(
webRedirectCheck.localizedInvalidRedirectError
);
}
} else {
goToSettingsWithAlertSuccess();
}
}
} catch (error) {
let localizedErrorMessage: string;
// Intercept invalid parameter error and set the error message to INVALID_EXPIRED_OTP_CODE
// This error occurs when the submitted code does not pass validation for the code param
// e.g., if the submitted code contains spaces or characters other than numbers
if (error.errno === 107) {
localizedErrorMessage = ftlMsgResolver.getMsg(
getErrorFtlId(AuthUiErrors.INVALID_EXPIRED_OTP_CODE),
AuthUiErrors.INVALID_EXPIRED_OTP_CODE.message
);
} else {
localizedErrorMessage = getLocalizedErrorMessage(ftlMsgResolver, error);
}
// In any case where the submitted code is invalid/expired, show the error message in a tooltip
if (
error.errno === AuthUiErrors.INVALID_EXPIRED_OTP_CODE.errno ||
error.errno === AuthUiErrors.OTP_CODE_REQUIRED.errno ||
error.errno === AuthUiErrors.INVALID_OTP_CODE.errno ||
error.errno === 107
) {
setCodeErrorMessage(localizedErrorMessage);
} else {
// Clear resend link success banner (if displayed) before rendering an error banner
setResendStatus(ResendStatus.none);
// Any other error messages should be displayed in an error banner
setLocalizedErrorBannerHeading(localizedErrorMessage);
}
}
}