Skip to content

Ending a session ​

session.end() ends this session in this application. It never signs out every device and never ends the identity provider's own session behind your back, and it answers what it proved.

ts
const handleSignOutPress = async () => {
  const result = await session.end();

  if (result.navigation !== null) {
    location.assign(result.navigation.url);
  }
};

The result ​

ts
import type { EndResult } from "@priemskiyyy/anchor";

const describeEnding = ({ local, remote }: EndResult) =>
  `This device: ${local}. The provider: ${remote}.`;
FieldValuesMeaning
localcompleted, not-applicable, unknownWhether the session was ended in this application, on this device.
remotecompleted, not-applicable, unknownWhether the provider's server ended it too. not-applicable when the provider has no such step.
navigation{ url } or nullA page the application must open to finish, such as Auth0's logout endpoint. Anchor never opens it itself.

A partial success is an answer, not an error: an adapter that cleared the local session but could not tell whether the server revoked it answers local: "completed", remote: "unknown".

What happens ​

  1. After dispose(), end() rejects with DISPOSED. On a session that is no longer current it resolves { local: "not-applicable", remote: "not-applicable", navigation: null } without calling the adapter. A second end() while one runs joins it, and an adapter without end rejects with UNSUPPORTED.
  2. The session becomes ending: its pending token requests reject with SESSION_CHANGED, and new ones are refused.
  3. The adapter ends the session through its SDK's narrowest sign-out, and only while the SDK still holds this session's identity: when it holds someone else, it signs nobody out and answers not-applicable. Its signal aborts if the session is replaced or Anchor is disposed meanwhile.
  4. When local is completed and the session is still current, Anchor publishes signed-out itself: the adapter's answer is the evidence. Otherwise the session becomes usable again and Anchor reads the provider to reconcile.
  5. An adapter that throws rejects end() with END_FAILED and the SDK's error as its cause, and the session becomes usable again until a read says otherwise.
  6. An answer that arrives after the session was replaced resolves its caller and changes nothing.

dispose() never ends a session.

What each adapter answers ​

AdapterSigns out withlocalremotenavigation
Firebase, on React Native toosignOut()completednot-applicablenull
Supabaseauth.signOut({ scope: "local" }), never the global defaultcompletedcompletednull
Auth0logout({ openUrl }), capturing the URLcompletedunknownAuth0's /v2/logout page
Auth0 on React NativeclearApiCredentials() per audience, then clearCredentials()completedunknownnull
Better AuthsignOut()completedcompleted, or unknown offline on React Nativenull
ClerksignOut(callback, { sessionId }), without navigatingcompletedcompleted, or unknown offlinenull
Microsoft Entra IDclearCache({ account }), that account alonecompletedunknownnull
Amazon CognitosignOut({ global: false })completed once Amplify said signedOut, else unknownunknownnull
WorkOS AuthKitsignOut({ navigate: false })completedunknownnull
Auth.jssignOut({ redirect: false }), then reads the session againcompletedunknownnull
OpenID ConnectremoveUser()completedunknownthe provider's end-session page
KeycloakclearToken(), never logout(), which navigatescompletedunknownKeycloak's logout page
Oktarevokes the refresh and access tokens, then tokenManager.clear()completedunknownOkta's sign-out page
Your own backendyour end({ session, signal })completedcompletednull

Each adapter's page says what it answers in the edge cases, such as a provider with no end-session endpoint.

What stays with your SDK ​

Signing the user out everywhere, revoking every session and ending a federated login are provider operations with their own consequences, so Anchor leaves them to you, through anchor.native:

  • Supabase: anchor.native.auth.signOut({ scope: "global" }) signs the user out on every device.
  • Amazon Cognito: anchor.native.auth.signOut({ global: true }).
  • Clerk: anchor.native.signOut() ends every signed-in session of a multi-session application.
  • Better Auth: anchor.native.revokeOtherSessions() ends the user's other sessions.
  • Firebase: revoke a user's refresh tokens on your server with the Admin SDK's revokeRefreshTokens.
  • Auth0 on React Native: anchor.native.webAuth.clearSession() ends Auth0's session in the browser the login used.
  • Microsoft Entra ID: anchor.native.logoutRedirect() signs out of Microsoft Entra ID as well.

A session ended through anchor.native reaches Anchor like any other change: by push where the adapter observes, and after anchor.sync() where it does not.

Released under the MIT License.