@onderling/oidc-session
v0.1.0
Published
Solid OIDC session manager for Node — SolidVault. Peer of @onderling/oidc-session-rn (the React Native variant). Extracted from @onderling/core/storage 2026-05-11 as part of the standardisation P1 work (Phase 50.1).
Readme
@onderling/oidc-session
Layer: substrate. Solid OIDC session manager for Node / desktop. Peer of
@onderling/oidc-session-rn(the React Native variant). Extracted from@onderling/core2026-05-11 as part of the standardisation P1 work (Phase 50.1 — seeProject Files/SDK/core-v2-coding-plan-2026-05-11.md).
npm install @onderling/oidc-sessionWhat's in here
SolidVault— Node-side Solid OIDC session manager. Delegates the actual OIDC dance to@inrupt/solid-client-authn-node; persists tokens into a caller-supplied Vault-shaped store; exposes agetAuthenticatedFetch()suitable forSolidPodSource. Used byagent-provisioning. Lower-level: takes directclientId / clientSecret / refreshToken— no browser dance.createSolidAuthNode({vault, clientName})— Phase 52.15.2 (2026-05-14). The browser-redirect Solid OIDC flow (start→ authorize URL → user OAuths →handleCallback) as aSolidAuth-shaped factory. Lifted from the byte-identical wrappers Folio + Stoop previously copy-pasted (apps/folio/src/auth/OidcSession.js+apps/stoop/src/lib/OidcSession.js, both deleted in 52.15.3). The rule-of-two substrate promotion.KNOWN_ISSUERS,DEFAULT_ISSUER_ID,resolveIssuer(idOrUrl)— Phase 52.15.1 (2026-05-14). Curated Solid pod provider list (Inrupt, SolidCommunity, SolidWeb) + helper for converting between issuer ids, URLs, and synthesised custom entries.getIssuerPickerHtml({selectedId?, customAllowed?, ...})— Phase 52.15.4 (2026-05-14). Server-rendered HTML fragment for the issuer picker. Apps embed it into their sign-in template; client-side JS reads the form's selected radio.OIDC_VAULT_KEYS— frozen object of the vault key names thatcreateSolidAuthNodeuses for refresh-token / issuer / clientId / clientSecret persistence._setSessionFactory/_setSolidAuthNodeSessionFactory— test-only seams to inject a fake InruptSession(one each forSolidVaultandcreateSolidAuthNode).
Public API
import { SolidVault } from '@onderling/oidc-session';
const sv = new SolidVault({
webid: 'https://alice.example/profile/card#me',
oidcIssuer: 'https://login.inrupt.com',
redirectUrl: 'https://app.example/callback', // browser only; unused in Node
vault, // any Vault-shaped store; optional (defaults to in-memory)
});
await sv.login({ clientId, clientSecret });
sv.isAuthenticated(); // boolean
const fetchFn = sv.getAuthenticatedFetch(); // pass to SolidPodSource
await sv.refresh(); // emits 'auth-state' ('refreshed' or 'expired')
sv.podRoot; // synchronous getter
await sv.getPodRoot(); // async; reads pim:storage from the WebID profile
await sv.logout(); // clears tokens + vault entriesSolidVault is an EventEmitter. Listen for 'auth-state' to observe
'authenticated' | 'unauthenticated' | 'refreshed' | 'expired'.
Token storage
Tokens are written into the supplied vault under namespace
solid-oidc:<webid>:*:
| Key | Value |
|---|---|
| solid-oidc:<webid>:access_token | The current Bearer token. |
| solid-oidc:<webid>:refresh_token | The most recent refresh token. |
| solid-oidc:<webid>:expires_at | Access-token expiry as unix-ms (string). |
| solid-oidc:<webid>:id_token | The most recent ID token. |
| solid-oidc:<webid>:client_id | Client ID (for fresh-process re-login). |
| solid-oidc:<webid>:client_secret | Client secret. |
| solid-oidc:<webid>:oidc_issuer | OIDC issuer URL. |
| solid-oidc:<webid>:pod_root | Cached pod root after first lookup. |
| inrupt:* | Inrupt session-internal state. |
logout() removes every solid-oidc:<webid>:* and inrupt:* key.
Vault shape
Any object with these methods works:
interface VaultLike {
get(key: string): Promise<string|null>;
set(key: string, value: string): Promise<void>;
delete(key: string): Promise<void>;
list?(): Promise<string[]>; // used by logout()
}@onderling/core's VaultMemory / VaultNodeFs / VaultIndexedDB /
VaultLocalStorage all satisfy this. The substrate ships a minimal
in-memory default for the no-vault-supplied case (test ergonomics);
production callers should pass their own.
Relationship with the RN peer
@onderling/oidc-session-rn and this package share the consumer-facing
contract (isAuthenticated(), getAuthenticatedFetch(), logout(),
webid getter) but differ in how the OIDC dance happens:
- Node (this package): delegates to
@inrupt/solid-client-authn-nodefor the client-credentials / refresh-token flow. - RN (
oidc-session-rn): the OIDC dance runs viaexpo-auth-sessionseparately; this package just adopts the resulting tokens viaadoptTokens().
Apps that want a unified surface across platforms use the consumer contract (which is identical) and pick the package by platform at import time.
Bring it up
cd packages/oidc-session
npm install
npm test # unit tests pass; CSS integration tests skip without env varsTo run the Community Solid Server integration tests, set the env vars
documented in test/SolidVault.css.test.js.
Tests
test/SolidVault.unit.test.js— unit tests with a mocked Inrupt Session. No network. Always runs.test/SolidVault.css.test.js— integration tests against a real Community Solid Server. Skipped unlessCSS_URL,CSS_WEBID,CSS_CLIENT_ID,CSS_CLIENT_SECRETare set.
Deprecation re-export
The 2026-07-05 de-fat removed @onderling/core's re-export of SolidVault — import
it from @onderling/oidc-session directly:
import { SolidVault } from '@onderling/oidc-session';Solid-auth consolidation status (Phase 52.15)
Scoped + (largely) shipped 2026-05-14. Three docs in
Project Files/Inrupt-migration/
capture the inventory, the substrate design, and the phase plan.
- 52.15.1 / 52.15.2 / 52.15.3 shipped 2026-05-14 — multi-issuer
exports,
createSolidAuthNodefactory, Folio + Stoop wrappers retired. - 52.15.4 / 52.15.5 shipped 2026-05-14 — web HTML picker +
React Native
<IssuerPicker>(@onderling/oidc-session-rn/picker)- adoption in all 5 apps.
- 52.15.6 / 52.15.7 / 52.15.8 shipped 2026-05-14 — terminology
contract locked in
localisation.md; audit script atscripts/audit-locales.mjs.
Phase 52.16 (ACP/WAC sharing via pod-client.sharing.*) is scoped
but not yet implemented.
See also
@onderling/oidc-session-rn— RN peer.@onderling/pod-client—SolidOidcAuthwraps aSolidVaultsession and adapts it to thePodClientauth contract.Project Files/SDK/core-v2-functional-design-2026-05-11.md— design context.Project Files/Inrupt-migration/— Solid-auth consolidation (Phase 52.15 + 52.16).
Status
0.x — pre-1.0; the API may move between minor versions. Versioned with
changesets. Source: github.com/Onderling/basis
(packages/oidc-session).
