common-session-management
v1.0.0
Published
Simple, lightweight session management library for Angular 17+. Handles auth tokens, session timeout, route guards, and HTTP interceptors.
Maintainers
Readme
Common Session Management
A complete session management library for Angular 17+. Includes auth tokens, session timeout, conflict detection, session locking, and cross-tab sync.
Installation
npm install common-session-managementQuick Start
1. Configure in app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideSessionWithInterceptor } from 'common-session-management';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideSessionWithInterceptor({
sessionTimeoutMs: 600000, // 10 minutes
warningSeconds: 60,
loginRoute: '/login',
homeRoute: '/home',
debug: true,
}),
],
};2. Login Component
import { Component, inject } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { SessionService } from 'common-session-management';
@Component({ ... })
export class LoginComponent {
private http = inject(HttpClient);
private session = inject(SessionService);
login(email: string, password: string) {
this.http.post('https://api.example.com/login',
{ email, password },
{ observe: 'response' }
).subscribe((response: HttpResponse<any>) => {
const authToken = response.headers.get('AuthToken');
const userData = response.body.result.get_gmdt_login_id[0];
this.session.login(authToken!, userData);
});
}
}3. Add UI Components (app.component.ts)
import { Component, inject } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import {
SessionService,
TimeoutDialogComponent,
ConflictModalComponent,
LockScreenComponent,
} from 'common-session-management';
@Component({
selector: 'app-root',
standalone: true,
imports: [
AsyncPipe,
TimeoutDialogComponent,
ConflictModalComponent,
LockScreenComponent,
],
template: `
<router-outlet></router-outlet>
<!-- Timeout Warning Dialog -->
<session-timeout-dialog
[visible]="(session.showTimeout$ | async) ?? false"
[remainingSeconds]="(session.timeoutCountdown$ | async) ?? 0"
(extend)="session.extendSession()"
(logout)="session.logout()">
</session-timeout-dialog>
<!-- Session Conflict Modal -->
@if (conflict$ | async; as conflict) {
<session-conflict-modal
[visible]="conflict.hasConflict"
[sessions]="conflict.sessions"
[countdown]="conflict.countdown"
[forceEnabled]="conflict.forceEnabled"
(continue)="session.forceLogoutOtherSessions()"
(wait)="session.dismissConflict()"
(cancel)="session.cancelAndLogout()">
</session-conflict-modal>
}
<!-- Lock Screen -->
<session-lock-screen
[visible]="session.isLocked()"
[userName]="session.currentUser()?.user_name"
(unlock)="onUnlock($event)"
(logout)="session.logout()">
</session-lock-screen>
`,
})
export class AppComponent {
session = inject(SessionService);
conflict$ = this.session.conflictState;
onUnlock(password: string) {
// Verify password with your API, then:
this.session.unlockSession();
}
}4. Protect Routes
import { Routes } from '@angular/router';
import { sessionGuard, guestGuard, roleGuard } from 'common-session-management';
export const routes: Routes = [
{ path: 'login', component: LoginComponent, canActivate: [guestGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate: [sessionGuard] },
{ path: 'admin', component: AdminComponent, canActivate: [sessionGuard, roleGuard(['Admin'])] },
];Features
Session Timeout
- Automatic warning dialog before session expires
- User can extend session or logout
- Cross-tab synchronization
Session Conflict Detection
- Detect multiple active sessions
- Force logout other sessions
- Wait or cancel options
Session Locking
- Lock session manually
- Password unlock
- Cross-tab sync
Cross-Tab Sync
- Logout syncs across all tabs
- Session extension syncs across tabs
- Lock/unlock syncs across tabs
API Reference
SessionService
| Method | Description |
|--------|-------------|
| login(authToken, userData, sessionId?) | Initialize session |
| logout() | Clear session and redirect |
| extendSession() | Reset timer, hide dialog |
| lockSession() | Lock the session |
| unlockSession() | Unlock the session |
| forceLogoutOtherSessions() | Revoke other sessions |
| dismissConflict() | Hide conflict modal |
| cancelAndLogout() | Logout current session |
Observables
| Observable | Description |
|------------|-------------|
| showTimeout$ | Show timeout dialog |
| timeoutCountdown$ | Seconds remaining |
| conflictState | Conflict state object |
| onLogin$ | Login event |
| onLogout$ | Logout event |
| onLocked$ | Session locked |
| onUnlocked$ | Session unlocked |
Signals
| Signal | Description |
|--------|-------------|
| isAuthenticated | Auth status |
| currentUser | User data |
| isLocked | Lock status |
Configuration
interface SessionConfig {
sessionTimeoutMs?: number; // Default: 600000 (10 min)
warningSeconds?: number; // Default: 60
cookieName?: string; // Default: 'Authtoken'
loginRoute?: string; // Default: '/login'
homeRoute?: string; // Default: '/home'
debug?: boolean; // Default: false
enableConflictDetection?: boolean; // Default: true
forceLogoutDelaySeconds?: number; // Default: 300
activeSessionsEndpoint?: string; // API to get active sessions
revokeSessionEndpoint?: string; // API to revoke session
// Callbacks
onSessionExpired?: () => void;
onSessionWarning?: (seconds: number) => void;
onLogout?: () => void;
onConflictDetected?: (sessions: ActiveSession[]) => void;
onSessionLocked?: () => void;
onSessionUnlocked?: () => void;
}License
MIT
