swissoid-front
v0.1.7
Published
SwissOID frontend helpers for relying-party applications
Readme
swissoid-front
SwissOID frontend helpers for relying-party applications. The package bundles the wiring we introduced in clockize-react so any React app can plug into the SwissOID session managed by a backend that exposes the swissoid-back implementation.
Building a SwissOID-consuming app inside the meow workspace? Start with
../RP_INTEGRATION.md— the canonical end-to-end recipe covering auth backend + data API + SPA + infra together. This package is one piece of the picture; the doc is workspace-internal and is not shipped in any published npm package.
Features
SwissOIDAuthProvider– context provider that keeps track of the SwissOID session, polls/auth/status, and exposes helpers to login, logout, refresh the session, and re-check status.useSwissOIDAuth()– hook that returns the current authentication state and helpers.AuthGuard– simple component that protects a subtree, optionally auto-redirecting to the backend login endpoint when the session has expired.AuthDebugPanel– drop-in diagnostics panel useful during integration to inspect cookies, raw payloads, and trigger session actions.createSwissOIDBackendClient()– utility that mimics theutils/oidc.tshelpers fromclockize-react(initiateLogin,checkAuthStatus,logout) but works with any backend URL and endpoint configuration.
Quick start
import React from 'react';
import { SwissOIDAuthProvider, AuthGuard } from 'swissoid-front';
const App = () => (
<SwissOIDAuthProvider
config={{
backendUrl: import.meta.env.VITE_BACKEND_URL,
pollIntervalMs: 30_000,
}}
>
<AuthGuard loadingFallback={<span>Loading session…</span>}>
{/* protected routes */}
</AuthGuard>
</SwissOIDAuthProvider>
);Inside your components you can access the session data:
import { useSwissOIDAuth } from 'swissoid-front';
const UserMenu = () => {
const { user, logout } = useSwissOIDAuth();
return (
<button onClick={() => logout({ redirectTo: '/' })}>
Sign out {user && (user as any).email}
</button>
);
};To reproduce the clockize-react helpers:
import { createSwissOIDBackendClient } from 'swissoid-front';
const backend = createSwissOIDBackendClient({ backendUrl: import.meta.env.VITE_BACKEND_URL });
export const initiateLogin = backend.initiateLogin;
export const checkAuthStatus = () => backend.checkAuthStatus().then((res) => res.json());
export const logout = () => backend.logout({ redirectTo: '/' });Configuration options
The provider accepts the following configuration:
| Option | Description | Default |
| ------ | ----------- | ------- |
| backendUrl | Base URL of the relying-party backend that mounted swissoid-back routes. | Required |
| endpoints | Override paths for status, login, logout, refresh. | /auth/status, /login, /auth/logout, /auth/refresh |
| pollIntervalMs | Interval for background /auth/status checks. | 30000 (30s) |
| fetchImplementation | Custom fetch (useful in SSR/tests). | globalThis.fetch |
| transformUser | Map the response payload to the user object stored in context. | identity |
| loginRedirectParam | Query parameter name for continue URLs. | continue |
| logoutRedirectTo | URL or callback invoked after logout. | none |
| sessionExpiredRedirectTo | URL or callback invoked when a previously authenticated session later expires. | none |
| initialUser | Seed user (useful for SSR). | null |
| defaultHeaders | Headers sent with backend requests. | none |
When a session ends (0.1.7)
- Refresh first. When a check reports that a session in use has ended, the
provider asks
/auth/refreshonce. Only a refused refresh (401/403) ends the session and callssessionExpiredRedirectTo. When the refresh cannot be reached, the session stays and the next check tries again. - One login at a time.
login()marks the start of a login in the app'slocalStorage. Another tab of the same app that needs a login waits up to 30 seconds and checks the session every second, because the first tab's session cookie serves every tab. Only then does it start its own login. SwissOID keeps one login binding per browser, so logins started in parallel collide and end on "Session expired" (binding_expired).
With swissoid-back 2.4.0 or later, a session also lives while it is used,
instead of ending with the ID token after one hour.
Building
npm install
npm run buildInstalling dependencies can take a moment – if it times out, re-run the command locally.
The build emits dual CJS/ESM bundles with TypeScript declarations under dist/.
