onUnauthorisedResponse static method

Future<UnauthorisedResponse> onUnauthorisedResponse(
  1. dynamic preRequestLocalSessionState
)

Implementation

static Future<UnauthorisedResponse> onUnauthorisedResponse(
    LocalSessionState preRequestLocalSessionState) async {
  try {
    await _refreshAPILock.acquireWrite();

    LocalSessionState postLockLocalSessionState =
        await SuperTokensUtils.getLocalSessionState();
    if (postLockLocalSessionState.status ==
        LocalSessionStateStatus.NOT_EXISTS) {
      logDebugMessage('Client.onUnauthorisedResponse: local session state does not exist, throwing unauthorised error');
      SuperTokens.config.eventHandler(Eventype.UNAUTHORISED);
      return UnauthorisedResponse(status: UnauthorisedStatus.SESSION_EXPIRED);
    }
    if (postLockLocalSessionState.status !=
            preRequestLocalSessionState.status ||
        (postLockLocalSessionState.status == LocalSessionStateStatus.EXISTS &&
            preRequestLocalSessionState.status ==
                LocalSessionStateStatus.EXISTS &&
            postLockLocalSessionState.lastAccessTokenUpdate !=
                preRequestLocalSessionState.lastAccessTokenUpdate)) {
      logDebugMessage('Client.onUnauthorisedResponse: Retry required, throwing retry error');
      return UnauthorisedResponse(status: UnauthorisedStatus.RETRY);
    }
    Uri refreshUrl = Uri.parse(SuperTokens.refreshTokenUrl);
    http.Request refreshReq = http.Request('POST', refreshUrl);
    refreshReq = await Utils.setAuthorizationHeaderIfRequiredForRequestObject(
        refreshReq,
        addRefreshToken: true);

    if (preRequestLocalSessionState.status ==
        LocalSessionStateStatus.EXISTS) {
      logDebugMessage('Client.onUnauthorisedResponse: preRequestLocalSessionState exists');
      String? antiCSRFToken = await AntiCSRF.getToken(
          preRequestLocalSessionState.lastAccessTokenUpdate);
      if (antiCSRFToken != null) {
        logDebugMessage('Client.onUnauthorisedResponse: Setting antiCSRF token');
        refreshReq.headers[antiCSRFHeaderKey] = antiCSRFToken;
      }
    }

    logDebugMessage('Client.onUnauthorisedResponse: Setting rid and fdi-version headers');
    refreshReq.headers['rid'] = SuperTokens.rid;
    refreshReq.headers['fdi-version'] = Version.supported_fdi.join(',');
    // Add cookies to request headers
    logDebugMessage('Client.onUnauthorisedResponse: Adding cookies to headers');
    String? newCookiesToAdd =
        await Client.cookieStore?.getCookieHeaderStringForRequest(refreshUrl);
    refreshReq.headers[HttpHeaders.cookieHeader] = newCookiesToAdd ?? "";
    SuperTokensTokenTransferMethod tokenTransferMethod =
        SuperTokens.config.tokenTransferMethod;
    logDebugMessage('Client.onUnauthorisedResponse: Setting st-auth-mode');
    refreshReq.headers
        .addAll({'st-auth-mode': tokenTransferMethod.getValue()});
    refreshReq =
        SuperTokens.config.preAPIHook(APIAction.REFRESH_TOKEN, refreshReq);
    var resp = await refreshReq.send();
    await Utils.saveTokenFromHeaders(resp);
    http.Response response = await http.Response.fromStream(resp);

    // Save cookies from the response
    String? setCookieFromResponse =
        response.headers[HttpHeaders.setCookieHeader];
    await Client.cookieStore
        ?.saveFromSetCookieHeader(refreshReq.url, setCookieFromResponse);

    bool isUnauthorised =
        response.statusCode == SuperTokens.config.sessionExpiredStatusCode;
    logDebugMessage('Client.onUnauthorisedResponse: isUnauthorised: ${isUnauthorised}');

    String? frontTokenInHeaders = response.headers[frontTokenHeaderKey];
    if (isUnauthorised && frontTokenInHeaders == null) {
      logDebugMessage('Client.onUnauthorisedResponse: Removing frontToken by setting remove');
      await FrontToken.setItem("remove");
    }

    SuperTokensUtils.fireSessionUpdateEventsIfNecessary(
      wasLoggedIn: preRequestLocalSessionState.status ==
          LocalSessionStateStatus.EXISTS,
      status: response.statusCode,
      frontTokenFromResponse: frontTokenInHeaders,
    );

    if (response.statusCode >= 300) {
      return UnauthorisedResponse(
          status: UnauthorisedStatus.API_ERROR,
          error: SuperTokensException(
              "Refresh API returned with status code: ${response.statusCode}"));
    }

    SuperTokens.config
        .postAPIHook(APIAction.REFRESH_TOKEN, refreshReq, response);

    if ((await SuperTokensUtils.getLocalSessionState()).status ==
        LocalSessionStateStatus.NOT_EXISTS) {
      // The execution should never come here.. but just in case.
      // removed by server. So we logout
      // we do not send "UNAUTHORISED" event here because
      // this is a result of the refresh API returning a session expiry, which
      // means that the frontend did not know for sure that the session existed
      // in the first place.
      logDebugMessage('Client.onUnauthorisedResponse: local session state does not exist');
      return UnauthorisedResponse(status: UnauthorisedStatus.SESSION_EXPIRED);
    }

    SuperTokens.config.eventHandler(Eventype.REFRESH_SESSION);
    return UnauthorisedResponse(status: UnauthorisedStatus.RETRY);
  } catch (e) {
    return UnauthorisedResponse(
        status: UnauthorisedStatus.API_ERROR,
        error: SuperTokensException("Some unknown error occured"));
  } finally {
    _refreshAPILock.release();
  }
}