Skip to content

API reference

Configures OIDC authentication. Call once in app.config.ts.

interface AuthConfig {
issuerUrl: string; // Required: auth server base URL
clientId: string; // Required: OIDC client ID
scopes?: string[]; // Default: openid profile email offline_access phone address pl:extended_profile
redirectUri?: string; // Default: ${origin}/auth/callback
postLogoutRedirectUri?: string; // Default: ${origin}/auth/logged-out
silentRefresh?: boolean; // Default: true
refreshBeforeExpiry?: number; // Default: 30 (seconds before expiry to refresh)
secureRoutes?: string[]; // URL prefixes that receive the Authorization header (default: [])
impersonation?: boolean; // Default: true — enables impersonation support
}

secureRoutes defaults to [], which the interceptor treats as match-all. Once you set it to a non-empty list, matching is origin-exact plus pathname-prefix, and relative request URLs receive no token at all. impersonation gates the interceptor’s 401 recovery path for impersonated sessions.

Pass to provideHttpClient(). Attaches the Bearer token to requests matching secureRoutes. Triggers logout on 401.

provideHttpClient(withAuthInterceptor());
class AuthService {
readonly isAuthenticated: Signal<boolean>;
readonly currentUser: Signal<User | null>;
readonly accessToken: Signal<string | null>;
readonly isImpersonating: Signal<boolean>;
readonly originalUser: Signal<User | null>;
login(returnUrl?: string): void;
logout(localOnly?: boolean): void;
handleCallback(): Promise<void>;
checkAuth(): Promise<boolean>;
refreshToken(): Promise<string | null>;
isTokenExpired(thresholdSeconds?: number): boolean; // Default threshold: 30
getAccessTokenForUrl(url?: string): string | null;
startImpersonation(targetUserId: string, redirectPath?: string): Promise<void>;
stopImpersonation(): void;
}

See Impersonation for the impersonation members in context.

Returns a pre-configured Route for the OAuth callback. A dedicated internal callback guard (not authGuard) processes the callback and navigates to the stored return URL, or /. That guard always returns false after processing, so any extra canActivate you pass through overrides runs for its side effects only and cannot block navigation.

// Default path: auth/callback
createAuthCallbackRoute();
// Custom path or additional guards
createAuthCallbackRoute({ path: 'callback' });

Pre-built guard using defaults: saves the return URL and triggers auto-login.

{ path: 'dashboard', canActivate: [authGuard], component: DashboardComponent }
interface AuthGuardConfig {
redirectUrl?: string; // Default: '/auth/logged-out' (when autoLogin is false)
saveReturnUrl?: boolean; // Default: true
autoLogin?: boolean; // Default: true
}
createAuthGuard({ autoLogin: false, redirectUrl: '/login' });
interface GroupsGuardConfig {
groups: string | string[];
mode?: 'any' | 'all'; // Default: 'any'
redirectUrl?: string; // Default: '/403'
}
canActivate: [authGuard, createGroupsGuard({ groups: ['admin', 'superuser'] })];
import { hasGroup, hasAnyGroups, hasAllGroups } from '@presencelearning/auth';
hasGroup(user, 'admin');
hasAnyGroups(user, ['admin', 'superuser']);
hasAllGroups(user, ['editor', 'publisher']);
import {
parseToken,
isTokenExpired,
validateToken,
getTokenExpiry,
getTokenExpiryMs,
isImpersonationToken,
getRealUserId,
} from '@presencelearning/auth';
parseToken(token); // → TokenClaims | null
isTokenExpired(token, thresholdSeconds?); // → boolean (threshold defaults to 0)
validateToken(token); // → { valid: boolean; claims?: TokenClaims; error?: string }
getTokenExpiry(token); // → number | null (seconds since epoch)
getTokenExpiryMs(token); // → number | null (milliseconds since epoch)
isImpersonationToken(token); // → boolean
getRealUserId(token); // → string | null (the impersonator, when impersonating)

The standalone isTokenExpired(token, thresholdSeconds = 0) and the AuthService.isTokenExpired(thresholdSeconds = 30) method have different default thresholds.

import { getAuthEndpoints } from '@presencelearning/auth';
getAuthEndpoints(issuerUrl); // → AuthEndpoints — resolved OIDC endpoint URLs

withAuthInterceptor() is the provider form. The underlying functions are also exported directly for apps that build their own interceptor chain:

import { authInterceptor, createAuthInterceptor } from '@presencelearning/auth';

AuthFeature is the type of the optional ...features arguments to provideAuth(); withAuthInterceptor() is currently the only feature.

SSR-safe wrappers for localStorage and sessionStorage with JSON helpers, typed as SafeStorage.

import { localStorage, sessionStorage, AUTH_STORAGE_KEYS } from '@presencelearning/auth';
localStorage.setItem('key', 'value');
localStorage.setJSON('key', { foo: 'bar' });
localStorage.getJSON<{ foo: string }>('key'); // → { foo: 'bar' } | null

AUTH_STORAGE_KEYS holds the keys the library itself writes, so consumers can avoid collisions.

AuthConfig, User, TokenClaims, AuthGuardConfig, GroupsGuardConfig, AuthFeature, AuthEndpoints, and SafeStorage are all exported.