Rayfin

Sessions

How Rayfin's opaque session object works — subscribe with onSessionChange, gate UI on isAuthenticated, and let Rayfin manage tokens for you.

Every Rayfin session comes from signing in with Fabric SSO — the popup and embedded flows both produce the same opaque session object. Once you know how to read it, it doesn't matter which flow completed it.

Sessions are opaque

client.auth.getSession() returns an OpaqueSession. Treat it as opaque: read the fields below, but don't infer meaning from anything else it might contain internally.

interface OpaqueSession {
  user: User | null;
  role?: string;
  expiresAt?: Date;
  isAuthenticated: boolean;
  isAnonymous: boolean;
}
FieldDescription
userThe signed-in user, or null if there isn't one.
isAuthenticatedtrue once a user has a valid session.
isAnonymoustrue for an anonymous/unauthenticated session.
roleThe user's role, if your project assigns one.
expiresAtWhen the current access token expires.

Warning

Gate UI logic on isAuthenticated or the presence of user — not on internal session fields. Rayfin's session shape is intentionally opaque so it can change without breaking your app, as long as you only depend on the documented fields above.

const session = client.auth.getSession();

if (session.isAuthenticated && session.user) {
  showApp(session.user);
} else {
  showSignInPage();
}

Subscribing to session changes: onSessionChange

Warning

The method is onSessionChange. onAuthStateChange does not exist on the Rayfin auth client — code that calls it will throw at runtime, not just fail a type check.

onSessionChange fires whenever the session changes — sign-in, sign-out, token refresh, user update, or expiration — and returns an unsubscribe function:

const unsubscribe = client.auth.onSessionChange((session) => {
  if (session?.isAuthenticated) {
    console.log('Signed in as', session.user?.email);
  } else {
    console.log('Signed out');
  }
});

// Later, e.g. on component unmount:
unsubscribe();

See React integration for wiring this into a useAuth() hook.

Reading the current session once

getSession() returns synchronously and reflects whatever Rayfin currently has in memory — call it once on startup, then rely on onSessionChange for updates:

const session = client.auth.getSession();

Token handling

In normal use, Rayfin manages access tokens internally and attaches them to client.data.* and client.functions.* calls automatically — your code never reads, stores, or forwards a token itself.

  • hasRefreshToken() reports whether the session has a refresh token available.
  • refreshSession() refreshes the session using the stored refresh token and resolves with the new token response; it rejects with an AuthError if there's no refresh token or the refresh fails. This exists to satisfy the refresh contract, not as a supported way to extract a token for reuse elsewhere — it still requires an existing browser session with a stored refresh token, which is exactly what a Node.js script never has. See Seeding data for what a script can do without one.
  • Rayfin schedules a refresh automatically as the access token approaches expiry when a refresh token is available, so you generally don't need to call refreshSession() yourself.
if (client.auth.hasRefreshToken()) {
  try {
    await client.auth.refreshSession();
  } catch {
    // Refresh failed — the user needs to sign in again.
  }
}

Signing out

await client.auth.signOut();       // End the current session.
await client.auth.signOutAll();    // Revoke every session for this user across every
                                    // device, returning the number revoked.

Auth events

onSessionChange covers most UI needs. For finer-grained handling, subscribe to individual events with on(event, handler):

EventFires when
AUTH_LOGINA session is established via Fabric SSO.
AUTH_LOGOUTThe user signs out.
AUTH_REFRESHThe session is refreshed.
AUTH_SESSION_EXPIREDThe access token expires with no refresh token available.
const unsubscribe = client.auth.on('AUTH_SESSION_EXPIRED', () => {
  redirectToSignIn();
});
PromptGate a page behind authentication
In my Rayfin React app, gate the main app route behind authentication: - On mount, read client.auth.getSession() once, then subscribe with client.auth.onSessionChange(...) to keep it in sync. Do not use onAuthStateChange — it does not exist on the Rayfin auth client. - Show a loading state until the first session check completes, then render the app if session.isAuthenticated and session.user are both present, or redirect to a sign-in page otherwise. - Do not introspect any session fields beyond isAuthenticated, isAnonymous, user, role, and expiresAt — treat the session object as opaque. Show me the resulting component.
Something wrong on this page?Report an issueEdit this page

On this page