Skip to content

API Reference

Christoph Braun edited this page Nov 5, 2025 · 8 revisions

Version: 0.2.1

The Session class provides the functionality for handling authentication in browser-based applications that interact with Solid Pods using Solid OpenID Connect (Solid-OIDC) with DPoP-bound tokens.

Overview

The Session class manages the entire authentication lifecycle:

  • User login via their Identity Provider (IDP)
  • Token management (access, refresh)
  • Session state tracking
  • (Un-)Authenticated HTTP requests
  • Automatic token refresh
  • Session expiration handling
  • Session restoration

Library Versions: web vs. core

This library is published with two entry points to suit different needs. Understanding the difference is key to choosing the right one for your project.

  • Default (web) Version: This is the "batteries-included" version, recommended for most Single-Page Applications (SPAs) and Multi-Page Applications (MPAs). It includes a background Web Worker that automatically and reliably handles token refreshes, even in inactive browser tabs. When you import { Session } from '@uvdsl/solid-oidc-client-browser', this is the version you get.

  • core Version: This is the foundational "engine" of the library. It contains all the core authentication logic but does not include any automatic token refreshing. This version is intended for advanced use cases where you need full control over the refresh lifecycle, such as building a browser extension. You access it via a specific import path.


API Reference (web version)

Constructor

new Session(clientDetails?: DereferencableIdClientDetails | DynamicRegistrationClientDetails, sessionOptions?: SessionOptions)

Creates a new session instance.

Parameters:

  • clientDetails: (Optional) Configuration for the client application
  • sessionOptions: (Optional) Options for session behavior

Example:

// Using dereferencable client ID
const session = new Session({
  client_id: 'https://app.example/profile#app', // client_id that can be dereferenced to a client profile document
}, {
  onSessionStateChange: () => {
    console.log('Session state changed');
    // Update UI or trigger reactivity
  }
});

// OR using dynamic registration
const session = new Session({
  redirect_uris: ['https://app.example/callback'], // mandatory for dynamic registration
  client_name: 'My Application' // optional
}, {
  onSessionStateChange: () => {
    console.log('Session state changed');
    // Update UI or trigger reactivity
  }
});

Methods

login(idp: string, redirect_uri: string): Promise<void>

Initiates the login process by redirecting the user to their Identity Provider.

Parameters:

  • idp: URL of the user's Identity Provider
  • redirect_uri: URL where the user should be redirected after authentication

Example:

// Redirect user to their IdP for authentication
await session.login('https://idp.example', 'https://app.example/callback');

Note:
The idp paramter needs to match issuer attribute of the IDP's configuration.
This is the same as the solid:oidcIssuer value in WebId profiles.

handleRedirectFromLogin(): Promise<void>

Processes the authentication response after redirect from the identity provider. If there's no valid session after redirect, the session remains unauthenticated.

Example:

// On your callback/redirect page:
await session.handleRedirectFromLogin();
if (session.isActive) {
  // Authentication successful, 
} else {
  // unauthentication session
}

restore(): Promise<void>

Attempts to restore a previous session using stored refresh tokens without requiring user interaction. Silently fails if the session cannot be restored (e.g., if there was no previous session or the refresh token is invalid).

Example:

// Try to restore a previous session on application start
await session.restore();
if (session.isActive) {
  // Session successfully restored
  console.log(`Welcome back, ${session.webId}`);
} else {
  // No session could be restored, user needs to log in
  // Show login UI
}

logout(): Promise<void>

Terminates the current session, clearing all tokens and session data.

Example:

// Log the user out
await session.logout();

authFetch(input: string | URL | Request, init?: RequestInit, dpopPayload?: any): Promise<Response>

Makes an authenticated HTTP request with DPoP-bound tokens. If the session is unauthenticated, a regular HTTP request is dispatched.

Parameters:

  • input: URL or Request object to fetch
  • init: Standard fetch RequestInit options
  • dpopPayload: (Optional) Custom payload for the DPoP token

Example:

// Basic authenticated GET request
const response = await session.authFetch('https://pod.example/private-resource');

// POST request with custom options
const postResponse = await session.authFetch('https://pod.example/resource', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
});

See also Solid Requests for get, post, put, delete on resources, and even to create resources with the correct LDP link header, and to create containers with the correct link header - for your convenience.

Properties

isActive: boolean (readonly)

Indicates whether the session is currently active (authenticated).

Example:

if (session.isActive) {
  // User is logged in
} else {
  // User is not logged in
}

webId: string | undefined (readonly)

Returns the WebID of the authenticated user, or undefined if not authenticated.

Example:

console.log(`Logged in as: ${session.webId}`);

Reacting to Session Changes

The Session class extends EventTarget and provides two ways to react to session lifecycle events.

Session Lifecycle and Auto-Refresh

The Session class automatically handles token refreshing and session timeout:

  1. When a session is established, a timer is set for token refresh (at 80% of token expiration time).

  2. The token refresh process attempts to use the refresh token to obtain new tokens without user interaction.

  3. If token refresh fails, the sessionExpirationWarning event is fired, allowing you to notify the user.

  4. When the session expires, the sessionExpiration event is fired and the session is automatically deactivated.

  5. When state changes (login, logout, refresh), the sessionStateChange event is fired.

Option 1: Callbacks (in Constructor)

Pass callback functions directly in SessionOptions. This is convenient for simple use cases where one handler is sufficient.

import { Session, SessionStateChangeDetail, SessionExpirationWarningDetail } from '@uvdsl/solid-oidc-client-browser';

const session = new Session(clientDetails, {
  onSessionStateChange: (event) => {
    if (event instanceof CustomEvent) {
      const { isActive, webId } = event.detail as SessionStateChangeDetail;
      console.log(`Session changed: ${isActive ? 'active' : 'inactive'}`, webId);
    }
  },
  onSessionExpirationWarning: (event) => {
    if (event instanceof CustomEvent) {
      const { expires_in } = event.detail as SessionExpirationWarningDetail;
      console.warn(`Session expiring in ${expires_in} seconds!`);
    }
  },
  onSessionExpiration: () => {
    console.log('Session expired');
  }
});

Option 2: Event Listeners (Recommended for flexibility)

Use addEventListener to attach multiple handlers or to dynamically add/remove handlers (e.g., inside React/Vue components).

import { Session, SessionEvents, SessionStateChangeDetail } from '@uvdsl/solid-oidc-client-browser';

// Using the SessionEvents enum for type safety
session.addEventListener(SessionEvents.STATE_CHANGE, (event: Event) => {
  if (event instanceof CustomEvent) {
    const { isActive, webId } = event.detail as SessionStateChangeDetail;
    console.log(`Session is now ${isActive ? 'active' : 'inactive'}`);
  }
});

Available Events

Event Name SessionEvents Enum Detail Interface SessionOptions
sessionStateChange STATE_CHANGE SessionStateChangeDetail onSessionStateChange
sessionExpirationWarning EXPIRATION_WARNING SessionExpirationWarningDetail onSessionExpirationWarning
sessionExpiration EXPIRATION null onSessionExpiration

SessionEvents Enum

export enum SessionEvents {
  STATE_CHANGE = 'sessionStateChange',
  EXPIRATION_WARNING = 'sessionExpirationWarning',
  EXPIRATION = 'sessionExpiration',
}

Event Detail Interfaces

export interface SessionStateChangeDetail {
  isActive: boolean;
  webId?: string;
}

export interface SessionExpirationWarningDetail {
  expires_in: number; // seconds until expiration
}

Interfaces

ClientDetails

The client details can be provided in one of two formats:

DereferencableIdClientDetails

export interface DereferencableIdClientDetails {
  client_id: string // A dereferencable client_id URI
}

DynamicRegistrationClientDetails

export interface DynamicRegistrationClientDetails {
  redirect_uris: string[]; // mandatory
  client_name?: string;
  client_uri?: string;
  logo_uri?: string;
  contacts?: string[];
  tos_uri?: string;
  policy_uri?: string;
  software_id?: string; // not the `client id`!
  software_version?: string;
}

SessionOptions

export interface SessionOptions {
  onSessionStateChange?: (event?: Event) => void;
  onSessionExpirationWarning?: (event?: Event) => void;
  onSessionExpiration?: (event?: Event) => void;
  workerUrl?: string | URL;
}
  • onSessionStateChange: Callback triggered whenever the session state changes (login, logout, token refresh, etc.). This is particularly useful for reactivity frameworks like React or Vue where automatic reactivity on the session object may not work reliably after state changes.
  • onSessionExpirationWarning: Callback triggered when the session is about to expire, allowing you to notify the user or take preventive action.
  • onSessionExpiration: Callback triggered when the session has expired.
  • workerUrl: (Optional) Custom URL or path to the Web Worker script used for background token refresh. By default, the library uses its bundled worker, but you can provide a custom worker URL if needed for your deployment setup.

Advanced Usage

Session Restoration Pattern

The recommended pattern for session management:

const session = new Session(clientDetails, sessionOptions);

// Try to restore previous session on application start
await session.restore();
if (session.isActive) {
  // Session was restored successfully
  console.log(`Welcome back, ${session.webId}`);
  // Continue with authenticated state
} else {
  // No session to restore, user needs to log in
  // Show login UI
}
// alternatively, remember that you can use the onSessionStateChange callback

// Later, when user clicks login button:
async function loginUser() {
  await session.login('https://idp.example', 'https://app.example/callback');
}

// And on your callback/redirect page:
async function handleCallback() {
  await session.handleRedirectFromLogin();
  if (session.isActive) {
    // Authentication successful
    // Redirect to application or update UI
  } else {
    // Authentication failed
    // Show error or login form
  }
}

Using with Reactivity Frameworks (React, Vue, etc.)

See here.

Custom DPoP Payload

const response = await session.authFetch('https://pod.example/resource', {
  method: 'POST',
  body: data
}, {
  // Custom DPoP payload
  htu: 'https://custom-uri.example',
  htm: 'PATCH',
  extraClaim: 'custom-value'
});

Handling Session Expiration

import { Session, SessionExpirationWarningDetail } from '@uvdsl/solid-oidc-client-browser';

const session = new Session(clientDetails, {
  onSessionExpirationWarning: (event) => {
    if (event instanceof CustomEvent) {
      const { expires_in } = event.detail as SessionExpirationWarningDetail;
      // Show modal to user
      console.warn(`Session expiring in ${expires_in} seconds.`);
      // e.g., showModal(`Your session is about to expire in ${expires_in} seconds. Stay logged in?`);
      // if (userWantsToStay) {
      //   performLogin();
      // }
    }
  },
  onSessionExpiration: () => {
    // Session has expired
    console.log('Your session has expired');
    // Redirect to login page or show login modal
  }
});

Custom Worker URL

If you need to serve the Web Worker from a custom location:

const session = new Session(clientDetails, {
  workerUrl: '/custom-path/solid-oidc-worker.js'
});

Using the Core Library (for Extensions and Custom Setups)

For advanced scenarios like building a browser extension, you can import the core version of the library. The SessionCore class provides the same API as the default Session but does not perform automatic token refreshes. You are responsible for scheduling and calling session.restore() to refresh the token.

Import:

import { 
Session,         // the session interface
SessionDatabase, // the session database interface to implement
SessionOptions,  // the session options to provide a database to the session
SessionCore      // the core session implementation that you'd extend or use
} from '@uvdsl/solid-oidc-client-browser/core';