onUnauthorisedResponseRecieved method

Future<_UnauthorisedResponse> onUnauthorisedResponseRecieved(
  1. String refreshEndpointURL,
  2. String preRequestIdRefreshToken,
  3. BaseRequest request
)

Implementation

Future<_UnauthorisedResponse> onUnauthorisedResponseRecieved(
    String refreshEndpointURL,
    String preRequestIdRefreshToken,
    http.BaseRequest request) async {
  // this is intentionally not put in a loop because the loop in other projects is because locking has a timeout
  http.Response refreshResponse;
  try {
    await _refreshAPILock.acquireWrite();
    String? postLockIdRefresh = await IdRefreshToken.getToken();

    if (postLockIdRefresh == null) {
      return _UnauthorisedResponse(
          status: _UnauthorisedStatus.SESSION_EXPIRED);
    }

    if (postLockIdRefresh != preRequestIdRefreshToken) {
      return _UnauthorisedResponse(status: _UnauthorisedStatus.RETRY);
    }

    Map<String, String> refreshHeaders = HashMap();
    String? antiCSRF = await AntiCSRF.getToken(preRequestIdRefreshToken);

    if (antiCSRF != null) {
      refreshHeaders[antiCSRFHeaderKey] = antiCSRF;
    }

    refreshHeaders[superTokensPlatformHeaderKey] = superTokensPlatformName;
    refreshHeaders[superTokensSDKVersionHeaderKey] = superTokensPluginVersion;
    refreshHeaders.addAll(SuperTokens.refreshAPICustomHeaders ?? HashMap());

    // Add cookies
    Uri refreshUri = Uri.parse(refreshEndpointURL);
    String? cookieHeader =
        await _cookieStore?.getCookieHeaderStringForRequest(refreshUri);
    refreshHeaders[HttpHeaders.cookieHeader] = cookieHeader ?? "";

    refreshResponse =
        await _innerClient.post(refreshUri, headers: refreshHeaders);

    // Save cookies from response
    String? setCookieFromResponse =
        refreshResponse.headers[HttpHeaders.setCookieHeader];
    await _cookieStore?.saveFromSetCookieHeader(
        refreshUri, setCookieFromResponse);

    bool removeIdRefreshToken = true;
    String? idRefreshTokenFromResponse =
        refreshResponse.headers[idRefreshHeaderKey];

    if (idRefreshTokenFromResponse != null) {
      await IdRefreshToken.setToken(idRefreshTokenFromResponse);
      removeIdRefreshToken = false;
    }

    if (refreshResponse.statusCode == SuperTokens.sessionExpiryStatusCode &&
        removeIdRefreshToken) {
      await IdRefreshToken.setToken("remove");
    }

    if (refreshResponse.statusCode != 200) {
      String message = refreshResponse.body;
      throw http.ClientException(message);
    }

    String? idRefreshAfterResponse = await IdRefreshToken.getToken();
    if (idRefreshAfterResponse == null) {
      return _UnauthorisedResponse(
          status: _UnauthorisedStatus.SESSION_EXPIRED);
    }

    String? antiCSRFFromResponse = refreshResponse.headers[antiCSRFHeaderKey];
    if (antiCSRFFromResponse != null) {
      String? idRefreshToken = await IdRefreshToken.getToken();
      await AntiCSRF.setToken(antiCSRFFromResponse, idRefreshToken);
    }

    return _UnauthorisedResponse(status: _UnauthorisedStatus.RETRY);
  } catch (e) {
    http.ClientException exception = http.ClientException(
        "$e"); // Need to do it this way to capture the error message since catch returns a generic object not a class
    String? idRefreshToken = await IdRefreshToken.getToken();
    if (idRefreshToken == null) {
      return _UnauthorisedResponse(
          status: _UnauthorisedStatus.SESSION_EXPIRED);
    }

    return _UnauthorisedResponse(
        status: _UnauthorisedStatus.API_ERROR, exception: exception);
  } finally {
    _refreshAPILock.release();
  }
}