-
Notifications
You must be signed in to change notification settings - Fork 4
API Reference
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.
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
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 youimport { Session } from '@uvdsl/solid-oidc-client-browser', this is the version you get. -
coreVersion: 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.
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
}
});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.
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
}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
}Terminates the current session, clearing all tokens and session data.
Example:
// Log the user out
await session.logout();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.
Indicates whether the session is currently active (authenticated).
Example:
if (session.isActive) {
// User is logged in
} else {
// User is not logged in
}Returns the WebID of the authenticated user, or undefined if not authenticated.
Example:
console.log(`Logged in as: ${session.webId}`);The Session class extends EventTarget and provides two ways to react to session lifecycle events.
The Session class automatically handles token refreshing and session timeout:
-
When a session is established, a timer is set for token refresh (at 80% of token expiration time).
-
The token refresh process attempts to use the refresh token to obtain new tokens without user interaction.
-
If token refresh fails, the
sessionExpirationWarningevent is fired, allowing you to notify the user. -
When the session expires, the
sessionExpirationevent is fired and the session is automatically deactivated. -
When state changes (login, logout, refresh), the
sessionStateChangeevent is fired.
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');
}
});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'}`);
}
});| Event Name |
SessionEvents Enum |
Detail Interface | SessionOptions |
|---|---|---|---|
sessionStateChange |
STATE_CHANGE |
SessionStateChangeDetail |
onSessionStateChange |
sessionExpirationWarning |
EXPIRATION_WARNING |
SessionExpirationWarningDetail |
onSessionExpirationWarning |
sessionExpiration |
EXPIRATION |
null |
onSessionExpiration |
export enum SessionEvents {
STATE_CHANGE = 'sessionStateChange',
EXPIRATION_WARNING = 'sessionExpirationWarning',
EXPIRATION = 'sessionExpiration',
}export interface SessionStateChangeDetail {
isActive: boolean;
webId?: string;
}
export interface SessionExpirationWarningDetail {
expires_in: number; // seconds until expiration
}The client details can be provided in one of two formats:
export interface DereferencableIdClientDetails {
client_id: string // A dereferencable client_id URI
}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;
}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.
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
}
}See here.
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'
});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
}
});If you need to serve the Web Worker from a custom location:
const session = new Session(clientDetails, {
workerUrl: '/custom-path/solid-oidc-worker.js'
});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';