tenneo-auth-gateway-plugin 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,422 @@
1
+ # tenneo-auth-plugin
2
+
3
+ Production-ready React authentication plugin with OAuth 2.0 PKCE support for enterprise applications.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/tenneo-auth-plugin)](https://www.npmjs.com/package/tenneo-auth-plugin)
6
+ [![npm downloads](https://img.shields.io/npm/dm/tenneo-auth-plugin)](https://www.npmjs.com/package/tenneo-auth-plugin)
7
+ [![license](https://img.shields.io/npm/l/tenneo-auth-plugin)](https://www.npmjs.com/package/tenneo-auth-plugin)
8
+
9
+ ## Overview
10
+
11
+ tenneo-auth-plugin is a comprehensive authentication solution designed for modern React applications. It implements the OAuth 2.0 Authorization Code flow with PKCE (Proof Key for Code Exchange), providing secure authentication without exposing client secrets in browser-based applications.
12
+
13
+ The plugin features a robust multi-tenant architecture that automatically resolves tenant configuration based on tenant codes. This makes it ideal for SaaS platforms and enterprise applications where multiple tenants share the same codebase but require isolated authentication contexts.
14
+
15
+ Built with TypeScript and following clean architecture principles, the plugin handles the complete token lifecycle including automatic refresh, secure storage, and session management. The React Context API integration provides a seamless developer experience with hooks-based access to authentication state and methods.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install tenneo-auth-plugin
21
+ ```
22
+
23
+ ### Requirements
24
+
25
+ - React 18 or higher
26
+ - React DOM 18 or higher
27
+ - React Router (recommended for callback handling)
28
+
29
+ ## Quick Start
30
+
31
+ ### 1. Wrap your application with AuthProvider
32
+
33
+ ```tsx
34
+ import { AuthProvider } from 'tenneo-auth-plugin';
35
+
36
+ function App() {
37
+ return (
38
+ <AuthProvider tenantCode="your-tenant-code">
39
+ <YourApplication />
40
+ </AuthProvider>
41
+ );
42
+ }
43
+ ```
44
+
45
+ ### 2. Access authentication state with useAuth
46
+
47
+ ```tsx
48
+ import { useAuth } from 'tenneo-auth-plugin';
49
+
50
+ function Dashboard() {
51
+ const { isAuthenticated, isLoading, accessToken, logout } = useAuth();
52
+
53
+ if (isLoading) {
54
+ return <div>Loading...</div>;
55
+ }
56
+
57
+ if (!isAuthenticated) {
58
+ return <div>Please log in to continue.</div>;
59
+ }
60
+
61
+ return (
62
+ <div>
63
+ <h1>Welcome to Dashboard</h1>
64
+ <button onClick={logout}>Sign Out</button>
65
+ </div>
66
+ );
67
+ }
68
+ ```
69
+
70
+ ### 3. Handle OAuth callback
71
+
72
+ ```tsx
73
+ import { AuthCallback } from 'tenneo-auth-plugin';
74
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
75
+
76
+ function App() {
77
+ return (
78
+ <AuthProvider tenantCode="your-tenant-code">
79
+ <BrowserRouter>
80
+ <Routes>
81
+ <Route
82
+ path="/callback"
83
+ element={
84
+ <AuthCallback
85
+ successPath="/dashboard"
86
+ loginPath="/login"
87
+ />
88
+ }
89
+ />
90
+ <Route path="/dashboard" element={<Dashboard />} />
91
+ </Routes>
92
+ </BrowserRouter>
93
+ </AuthProvider>
94
+ );
95
+ }
96
+ ```
97
+
98
+ ### 4. Protect routes
99
+
100
+ ```tsx
101
+ import { ProtectedRoute } from 'tenneo-auth-plugin';
102
+
103
+ function App() {
104
+ return (
105
+ <AuthProvider tenantCode="your-tenant-code">
106
+ <BrowserRouter>
107
+ <Routes>
108
+ <Route path="/callback" element={<AuthCallback />} />
109
+ <Route
110
+ path="/dashboard"
111
+ element={
112
+ <ProtectedRoute fallback={<div>Authenticating...</div>}>
113
+ <Dashboard />
114
+ </ProtectedRoute>
115
+ }
116
+ />
117
+ </Routes>
118
+ </BrowserRouter>
119
+ </AuthProvider>
120
+ );
121
+ }
122
+ ```
123
+
124
+ ## Features
125
+
126
+ - OAuth 2.0 PKCE flow for secure browser-based authentication
127
+ - Automatic token refresh before expiration
128
+ - Multi-tenant support with automatic tenant resolution
129
+ - Pluggable storage adapters (session, cookie, memory)
130
+ - Authentication event system for observability
131
+ - Strict TypeScript definitions throughout
132
+ - Host-driven configuration (props / `setConfig()`)
133
+ - Clean layered architecture
134
+ - Tree-shakeable ESM and CJS builds
135
+ - React 18+ compatibility
136
+
137
+ ## AuthProvider Props
138
+
139
+ | Prop | Type | Required | Default | Description |
140
+ |------|------|----------|---------|-------------|
141
+ | `config` | `SDKConfig` | No | - | Pass all configuration as a single object (alternative to individual props) |
142
+ | `tenantCode` | `string` | No | - | Tenant code for configuration resolution |
143
+ | `apiBaseUrl` | `string` | Yes | - | Tenant resolution service base URL |
144
+ | `authServerUrl` | `string` | Yes | - | Authorization server base URL (OIDC authorize) |
145
+ | `callbackUrl` | `string` | Yes | - | Full callback/redirect URL |
146
+ | `appId` | `string` | No | `''` | Application identifier for storage namespacing |
147
+ | `autoInit` | `boolean` | No | `true` | Automatically initialize authentication on mount |
148
+ | `storageAdapter` | `StorageAdapter` | No | `null` | Custom storage adapter instance |
149
+
150
+ ## Hooks API
151
+
152
+ ### useAuth()
153
+
154
+ Primary hook for accessing authentication state and methods.
155
+
156
+ ```tsx
157
+ import { useAuth } from 'tenneo-auth-plugin';
158
+
159
+ function Component() {
160
+ const {
161
+ isAuthenticated, // boolean - Current authentication status
162
+ accessToken, // string | null - Current access token
163
+ isLoading, // boolean - Loading state during auth operations
164
+ error, // string | null - Error message if any
165
+ login, // () => Promise<void> - Trigger login flow
166
+ logout, // () => Promise<void> - Sign out and clear session
167
+ refreshToken, // () => Promise<string> - Manually refresh token
168
+ getAccessToken, // () => Promise<string> - Get valid token (auto-refresh)
169
+ } = useAuth();
170
+ }
171
+ ```
172
+
173
+ ### useAuthInit()
174
+
175
+ Hook for manual authentication initialization.
176
+
177
+ ```tsx
178
+ import { useAuthInit } from 'tenneo-auth-plugin';
179
+
180
+ function Component() {
181
+ const {
182
+ isLoading, // boolean - Initialization in progress
183
+ error, // string | null - Initialization error
184
+ init, // () => Promise<void> - Trigger initialization
185
+ } = useAuthInit();
186
+
187
+ useEffect(() => {
188
+ init();
189
+ }, [init]);
190
+ }
191
+ ```
192
+
193
+ ## Components
194
+
195
+ ### AuthCallback
196
+
197
+ Handles OAuth authorization callback and token exchange.
198
+
199
+ ```tsx
200
+ import { AuthCallback } from 'tenneo-auth-plugin';
201
+
202
+ <AuthCallback
203
+ loginPath="/login" // Redirect on error (default: '/login')
204
+ successPath="/dashboard" // Redirect on success (default: '/dashboard')
205
+ homePath="/" // Fallback path (default: '/')
206
+ />
207
+ ```
208
+
209
+ ### ProtectedRoute
210
+
211
+ Wrapper component that ensures authentication before rendering children.
212
+
213
+ ```tsx
214
+ import { ProtectedRoute } from 'tenneo-auth-plugin';
215
+
216
+ <ProtectedRoute
217
+ fallback={<LoadingSpinner />} // Shown while checking auth
218
+ autoLogin={true} // Auto-redirect to login (default: true)
219
+ >
220
+ <ProtectedContent />
221
+ </ProtectedRoute>
222
+ ```
223
+
224
+ ## Core API
225
+
226
+ ### bootstrap()
227
+
228
+ Initializes the authentication flow. Called automatically by AuthProvider when `autoInit` is true.
229
+
230
+ ```tsx
231
+ import { bootstrap } from 'tenneo-auth-plugin';
232
+
233
+ await bootstrap();
234
+ ```
235
+
236
+ ### getAccessToken()
237
+
238
+ Retrieves a valid access token, automatically refreshing if expired.
239
+
240
+ ```tsx
241
+ import { getAccessToken } from 'tenneo-auth-plugin';
242
+
243
+ const token = await getAccessToken();
244
+ ```
245
+
246
+ ### logout()
247
+
248
+ Signs out the user and clears all authentication data.
249
+
250
+ ```tsx
251
+ import { logout } from 'tenneo-auth-plugin';
252
+
253
+ await logout();
254
+ ```
255
+
256
+ ### createAuthEngine()
257
+
258
+ Creates an authentication engine instance for advanced use cases.
259
+
260
+ ```tsx
261
+ import { createAuthEngine } from 'tenneo-auth-plugin';
262
+
263
+ const engine = createAuthEngine(runtime);
264
+
265
+ // Subscribe to state changes
266
+ const unsubscribe = engine.subscribe((state) => {
267
+ console.log('Status:', state.status);
268
+ console.log('Token:', state.accessToken);
269
+ });
270
+
271
+ // Initialize
272
+ await engine.init();
273
+
274
+ // Operations
275
+ await engine.login();
276
+ await engine.logout();
277
+ const token = await engine.getAccessToken();
278
+ ```
279
+
280
+ ## Configuration
281
+
282
+ ### Host app configuration (required)
283
+
284
+ This SDK does **not** read `.env` or `window.__AUTH_CONFIG__`. Provide configuration from your host app:
285
+
286
+ ```tsx
287
+ import { AuthProvider } from 'tenneo-auth-plugin';
288
+
289
+ <AuthProvider
290
+ tenantCode="your-tenant-code"
291
+ apiBaseUrl="https://tenant-service.example.com"
292
+ authServerUrl="https://auth.example.com"
293
+ callbackUrl="https://app.example.com/callback"
294
+ appId="myapp"
295
+ >
296
+ <App />
297
+ </AuthProvider>
298
+ ```
299
+
300
+ ### Programmatic Configuration
301
+
302
+ ```tsx
303
+ import { setConfig, Config } from 'tenneo-auth-plugin';
304
+
305
+ // Override configuration (host-driven)
306
+ setConfig({
307
+ tenantCode: 'your-tenant-code',
308
+ apiBaseUrl: 'https://tenant-service.example.com',
309
+ authServerUrl: 'https://auth.example.com',
310
+ callbackUrl: 'https://app.example.com/callback',
311
+ });
312
+
313
+ // Access resolved configuration
314
+ const authServerUrl = Config.getAuthServerUrl();
315
+ const allConfig = Config.getAll();
316
+ ```
317
+
318
+
319
+ ## Security
320
+
321
+ ### PKCE Protection
322
+
323
+ The plugin implements PKCE (Proof Key for Code Exchange) to prevent authorization code interception attacks. A cryptographically random code verifier is generated for each authentication request and never transmitted to the authorization server.
324
+
325
+ ### CSRF Protection
326
+
327
+ OAuth state parameter validation prevents cross-site request forgery attacks. Each authentication request includes a unique state value that is verified during the callback.
328
+
329
+ ### Token Isolation
330
+
331
+ Authentication tokens are stored with tenant-specific namespacing, ensuring complete isolation between different tenants in multi-tenant deployments.
332
+
333
+ ### HTTPS Enforcement
334
+
335
+ Production environments automatically enforce HTTPS for all authentication-related requests and redirects.
336
+
337
+ ### Session Security
338
+
339
+ Tokens are stored in sessionStorage by default, ensuring they are cleared when the browser tab is closed. For enhanced security requirements, custom storage adapters can be configured.
340
+
341
+ ## Storage Adapters
342
+
343
+ ```tsx
344
+ import {
345
+ createSecureSessionStorageAdapter,
346
+ createCookieStorageAdapter,
347
+ createMemoryStorageAdapter,
348
+ } from 'tenneo-auth-plugin';
349
+
350
+ // Session storage (default, cleared on tab close)
351
+ const sessionAdapter = createSecureSessionStorageAdapter({
352
+ tenantId: 'tenant-123',
353
+ appId: 'my-app'
354
+ });
355
+
356
+ // Cookie storage (persistent)
357
+ const cookieAdapter = createCookieStorageAdapter({
358
+ tenantId: 'tenant-123',
359
+ appId: 'my-app'
360
+ });
361
+
362
+ // Memory storage (testing)
363
+ const memoryAdapter = createMemoryStorageAdapter({
364
+ tenantId: 'tenant-123',
365
+ appId: 'my-app'
366
+ });
367
+
368
+ // Use custom adapter
369
+ <AuthProvider tenantCode="abc" storageAdapter={sessionAdapter}>
370
+ <App />
371
+ </AuthProvider>
372
+ ```
373
+
374
+ ## Events
375
+
376
+ Subscribe to authentication events for logging, analytics, or custom behavior.
377
+
378
+ ```tsx
379
+ import { subscribeAuthEvent, AuthEventNames } from 'tenneo-auth-plugin';
380
+
381
+ // Subscribe to login events
382
+ const unsubscribe = subscribeAuthEvent(AuthEventNames.LOGIN, (payload) => {
383
+ console.log('User authenticated');
384
+ });
385
+
386
+ // Available events
387
+ AuthEventNames.LOGIN // User successfully authenticated
388
+ AuthEventNames.LOGOUT // User signed out
389
+ AuthEventNames.REFRESH // Token refreshed
390
+ AuthEventNames.ERROR // Authentication error occurred
391
+ ```
392
+
393
+ ## TypeScript Support
394
+
395
+ All types are exported for use in TypeScript applications.
396
+
397
+ ```tsx
398
+ import type {
399
+ TenantConfig,
400
+ TokenResponse,
401
+ AuthState,
402
+ AuthContextValue,
403
+ AuthTokens,
404
+ StorageAdapter,
405
+ AuthEngine,
406
+ AuthEngineState,
407
+ SDKConfig,
408
+ } from 'tenneo-auth-plugin';
409
+ ```
410
+
411
+ ## Versioning
412
+
413
+ This package follows Semantic Versioning (SemVer):
414
+
415
+ - **Major versions** contain breaking changes
416
+ - **Minor versions** add backward-compatible features
417
+ - **Patch versions** include backward-compatible bug fixes
418
+ - **Beta versions** are pre-release versions for testing
419
+
420
+ ## License
421
+
422
+ MIT