async function verifySession()

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);
      }
    }
  }