refresh method

Future<OAuthSession> refresh(
  1. OAuthSession session
)

Refreshes session using the DPoP-bound refresh token flow.

The authorization server is re-discovered from OAuthSession.issuer. The DPoP key pair from the session is reused. The given session is never mutated; a brand-new OAuthSession is returned and stored.

If the server rejects the refresh token with invalid_grant, the session is deleted from the OAuthSessionStore and an OAuthSessionRevokedException is thrown so callers can route the user back through authorize.

Throws:

Implementation

Future<OAuthSession> refresh(final OAuthSession session) async {
  final refreshToken = session.refreshToken;
  if (refreshToken == null || refreshToken.isEmpty) {
    throw OAuthException('No refresh token available');
  }

  // Single-flight: coalesce concurrent refreshes of the same account onto
  // one shared future so the rotating refresh token is POSTed exactly once.
  final inFlight = _inFlightRefreshes[session.sub];
  if (inFlight != null) return inFlight;

  final future = _refresh(session, refreshToken);
  _inFlightRefreshes[session.sub] = future;
  try {
    return await future;
  } finally {
    _inFlightRefreshes.remove(session.sub);
  }
}