@lanonasis/oauth-client 1.2.8 → 2.0.3

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 CHANGED
@@ -1,16 +1,32 @@
1
1
  # @lanonasis/oauth-client
2
2
 
3
- Drop-in OAuth + API Key authentication client for the Lanonasis ecosystem. Supports dual authentication modes: OAuth2 PKCE flow for pre-registered clients and direct API key authentication for dashboard users. Handles browser/desktop/terminal flows, token lifecycle, secure storage, and MCP WebSocket/SSE connections.
3
+ **THE single authentication package** for the Lanonasis ecosystem. Consolidates all auth patterns: OAuth2 PKCE, API keys, magic links, React hooks, and Express middleware.
4
+
5
+ > **v2.0**: Now includes `/react` and `/server` exports! Migrating from `@lanonasis/shared-auth`? See [Migration Guide](#migration-from-lanonasisshared-auth).
4
6
 
5
7
  ## Features
6
- - **Dual Authentication**: OAuth2 PKCE flow OR direct API key authentication
7
- - OAuth flows for terminal and desktop (Electron-friendly) environments
8
- - API key authentication for new users with dashboard-generated keys
9
- - Token storage with secure backends (Keytar, encrypted files, Electron secure store, mobile secure storage, WebCrypto in browsers); browser builds auto-use web storage
10
- - API key storage that normalizes to SHA-256 digests before persisting
11
- - MCP client that connects over WebSocket (`/ws`) or SSE (`/sse`) with auto-refreshing tokens
12
- - Automatic auth mode detection based on configuration
13
- - ESM + CJS bundles with a dedicated browser export to avoid Node-only deps
8
+
9
+ ### Core Authentication
10
+ - **OAuth2 PKCE Flow**: Terminal and desktop (Electron) environments
11
+ - **API Key Authentication**: Dashboard-generated keys for instant access
12
+ - **Magic Link / OTP Flow**: Passwordless email authentication
13
+ - **Token Storage**: Secure backends (Keytar, encrypted files, WebCrypto)
14
+
15
+ ### React Integration (`/react`)
16
+ - **`useSSO()`**: React hook for SSO authentication state
17
+ - **`useSSOSync()`**: Cross-subdomain session synchronization
18
+ - **Cookie utilities**: `parseUserCookie`, `hasSessionCookie`, `clearUserCookie`
19
+
20
+ ### Server Integration (`/server`)
21
+ - **`requireAuth()`**: Express middleware enforcing authentication
22
+ - **`optionalAuth()`**: Attach user if authenticated, allow anonymous
23
+ - **`requireRole(role)`**: Role-based access control middleware
24
+ - **Cookie parsing**: `getSSOUserFromRequest`, `getSessionTokenFromRequest`
25
+
26
+ ### Additional Features
27
+ - MCP client (WebSocket/SSE) with auto-refreshing tokens
28
+ - ESM + CJS bundles with dedicated browser export
29
+ - TypeScript types included
14
30
 
15
31
  ## Installation
16
32
  ```bash
@@ -76,6 +92,82 @@ const flow = new DesktopOAuthFlow({
76
92
  const tokens = await flow.authenticate();
77
93
  ```
78
94
 
95
+ ### Magic Link / OTP Flow (Passwordless)
96
+ ```ts
97
+ import { MagicLinkFlow } from '@lanonasis/oauth-client';
98
+
99
+ const flow = new MagicLinkFlow({
100
+ authBaseUrl: 'https://auth.lanonasis.com'
101
+ });
102
+
103
+ // Send OTP to user's email
104
+ await flow.sendOTP('user@example.com');
105
+
106
+ // User enters the code they received
107
+ const tokens = await flow.verifyOTP('user@example.com', '123456');
108
+ ```
109
+
110
+ ### React Hooks (`/react`)
111
+ ```tsx
112
+ import { useSSO, useSSOSync } from '@lanonasis/oauth-client/react';
113
+
114
+ function MyComponent() {
115
+ const { user, isAuthenticated, isLoading, error } = useSSO({
116
+ authGatewayUrl: 'https://auth.lanonasis.com',
117
+ projectScope: 'my-app'
118
+ });
119
+
120
+ if (isLoading) return <div>Loading...</div>;
121
+ if (!isAuthenticated) return <div>Please log in</div>;
122
+
123
+ return <div>Hello, {user.email}!</div>;
124
+ }
125
+
126
+ // For cross-subdomain session sync
127
+ function App() {
128
+ useSSOSync({ pollInterval: 30000 });
129
+ return <MyComponent />;
130
+ }
131
+ ```
132
+
133
+ ### Server Middleware (`/server`)
134
+ ```ts
135
+ import express from 'express';
136
+ import {
137
+ requireAuth,
138
+ optionalAuth,
139
+ requireRole,
140
+ getSSOUserFromRequest
141
+ } from '@lanonasis/oauth-client/server';
142
+
143
+ const app = express();
144
+
145
+ // Require authentication
146
+ app.get('/api/profile', requireAuth(), (req, res) => {
147
+ res.json({ user: req.user });
148
+ });
149
+
150
+ // Optional authentication (attach user if present)
151
+ app.get('/api/public', optionalAuth(), (req, res) => {
152
+ if (req.user) {
153
+ res.json({ message: `Hello ${req.user.email}` });
154
+ } else {
155
+ res.json({ message: 'Hello guest' });
156
+ }
157
+ });
158
+
159
+ // Role-based access control
160
+ app.delete('/api/admin/users/:id', requireAuth(), requireRole('admin'), (req, res) => {
161
+ // Only admins can reach here
162
+ });
163
+
164
+ // Manual user extraction
165
+ app.get('/api/check', (req, res) => {
166
+ const user = getSSOUserFromRequest(req);
167
+ res.json({ authenticated: !!user });
168
+ });
169
+ ```
170
+
79
171
  ### Token storage
80
172
  ```ts
81
173
  import { TokenStorage } from '@lanonasis/oauth-client';
@@ -85,15 +177,20 @@ await storage.store(tokens);
85
177
  const restored = await storage.retrieve();
86
178
  ```
87
179
 
88
- ### API key storage (hashes to SHA-256)
180
+ In Node and Electron environments, secure storage now lazy-loads `keytar` so the ESM bundle can still use the native OS keychain when available. If native keychain access is unavailable, storage falls back to the encrypted local file backend automatically.
181
+
182
+ ### API key storage
89
183
  ```ts
90
184
  import { ApiKeyStorage } from '@lanonasis/oauth-client';
91
185
 
92
186
  const apiKeys = new ApiKeyStorage();
93
187
  await apiKeys.store({ apiKey: 'lns_abc123', environment: 'production' });
94
- const hashed = await apiKeys.getApiKey(); // returns sha256 hex digest
188
+ const apiKey = await apiKeys.getApiKey(); // returns the original key for outbound auth headers
95
189
  ```
96
190
 
191
+ Node/Electron secure storage preserves the original secret value so clients can send it back
192
+ in `X-API-Key` or `Authorization` headers when talking to remote services.
193
+
97
194
  ## Configuration
98
195
 
99
196
  ### API Key Mode
@@ -116,15 +213,86 @@ const hashed = await apiKeys.getApiKey(); // returns sha256 hex digest
116
213
  - The terminal/device code flow remains Node-only; in browser previews use API key or desktop flow.
117
214
 
118
215
  ## Publishing (maintainers)
119
- 1) Build artifacts: `npm install && npm run build`
120
- 2) Verify contents: ensure `dist`, `README.md`, `LICENSE` are present.
121
- 3) Publish: `npm publish --access public` (registry must have 2FA as configured).
122
- 4) Tag in git (optional): `git tag oauth-client-v1.0.0 && git push --tags`
216
+ 1) Install and verify: `npm install && npm test && npm run build`
217
+ 2) Audit release deps: `bun audit`
218
+ 3) Verify contents: ensure `dist`, `README.md`, and `LICENSE` are present.
219
+ 4) Publish: `npm publish --access public` (registry must have 2FA as configured).
220
+ 5) Tag in git (optional): `git tag oauth-client-v2.0.3 && git push --tags`
123
221
 
124
222
  ## Files shipped
125
223
  - `dist/*` compiled CJS/ESM bundles + types
126
224
  - `README.md`
127
225
  - `LICENSE`
128
226
 
227
+ ## Auth-Gateway Compatibility
228
+
229
+ This SDK implements client-side equivalents of the auth-gateway's authentication methods:
230
+
231
+ | Auth-Gateway Endpoint | SDK Class | Use Case |
232
+ |-----------------------|-----------|----------|
233
+ | `POST /oauth/device` | `TerminalOAuthFlow` | CLI/terminal apps |
234
+ | `GET /oauth/authorize` | `DesktopOAuthFlow` | Desktop apps (Electron) |
235
+ | `POST /v1/auth/otp/*` | `MagicLinkFlow` | Mobile/passwordless |
236
+ | `X-API-Key` header | `APIKeyFlow` | Server-to-server |
237
+ | `MCPClient` | Combined | Auto-detects best method |
238
+
239
+ ### Methods NOT Exposed (Security)
240
+ - Email/Password: Server-rendered form only
241
+ - Admin Bypass: Internal emergency access
242
+ - Supabase OAuth 2.1: Internal Supabase integration
243
+
244
+ See [auth-gateway/AUTHENTICATION-METHODS.md](../../apps/onasis-core/services/auth-gateway/AUTHENTICATION-METHODS.md) for complete server-side documentation.
245
+
246
+ ## Exports
247
+
248
+ | Export | Description | Use Case |
249
+ |--------|-------------|----------|
250
+ | `@lanonasis/oauth-client` | Main entry - OAuth flows, MCP client, storage | Node.js CLI, servers |
251
+ | `@lanonasis/oauth-client/browser` | Browser-safe bundle (no Node deps) | Web apps, SPAs |
252
+ | `@lanonasis/oauth-client/react` | React hooks + browser cookie utils | React/Next.js apps |
253
+ | `@lanonasis/oauth-client/server` | Express middleware + server cookie utils | Express/Node servers |
254
+
255
+ ## Migration from @lanonasis/shared-auth
256
+
257
+ `@lanonasis/shared-auth` is now **deprecated**. All functionality has been consolidated into `@lanonasis/oauth-client`.
258
+
259
+ ### Import Changes
260
+
261
+ ```typescript
262
+ // ❌ BEFORE (deprecated)
263
+ import { useSSO, useSSOSync } from '@lanonasis/shared-auth';
264
+ import { getSSOUserFromRequest } from '@lanonasis/shared-auth/server';
265
+
266
+ // ✅ AFTER (recommended)
267
+ import { useSSO, useSSOSync } from '@lanonasis/oauth-client/react';
268
+ import { getSSOUserFromRequest, requireAuth } from '@lanonasis/oauth-client/server';
269
+ ```
270
+
271
+ ### Package.json Changes
272
+
273
+ ```json
274
+ {
275
+ "dependencies": {
276
+ // ❌ Remove
277
+ "@lanonasis/shared-auth": "^1.x.x",
278
+
279
+ // ✅ Add/Update
280
+ "@lanonasis/oauth-client": "^2.0.0"
281
+ }
282
+ }
283
+ ```
284
+
285
+ ### New Middleware (Bonus!)
286
+
287
+ The migration gives you access to new middleware that wasn't in shared-auth:
288
+
289
+ ```ts
290
+ import { requireAuth, optionalAuth, requireRole } from '@lanonasis/oauth-client/server';
291
+
292
+ // These are new! Replace manual auth checks
293
+ app.get('/api/protected', requireAuth(), handler);
294
+ app.delete('/api/admin/*', requireAuth(), requireRole('admin'), handler);
295
+ ```
296
+
129
297
  ## License
130
298
  MIT © Lan Onasis
@@ -106,7 +106,8 @@ declare class TokenStorage implements TokenStorageAdapter {
106
106
  private readonly storageKey;
107
107
  private readonly webEncryptionKeyStorage;
108
108
  private keytar;
109
- constructor();
109
+ private keytarLoadAttempted;
110
+ private getKeytar;
110
111
  store(tokens: TokenResponse): Promise<void>;
111
112
  retrieve(): Promise<TokenResponse | null>;
112
113
  clear(): Promise<void>;
@@ -182,8 +183,9 @@ declare class ApiKeyStorage {
182
183
  private readonly legacyConfigKey;
183
184
  private readonly webEncryptionKeyStorage;
184
185
  private keytar;
186
+ private keytarLoadAttempted;
185
187
  private migrationCompleted;
186
- constructor();
188
+ private getKeytar;
187
189
  /**
188
190
  * Initialize and migrate from legacy storage if needed
189
191
  */
@@ -235,8 +237,12 @@ declare class ApiKeyStorage {
235
237
  private base64Encode;
236
238
  private base64Decode;
237
239
  /**
238
- * Normalize API keys to a SHA-256 hex digest.
239
- * Accepts pre-hashed input and lowercases it to prevent double hashing.
240
+ * Normalize stored credentials without transforming their value.
241
+ *
242
+ * These secrets are stored in encrypted local storage/keychains and must remain
243
+ * usable for outbound authentication headers (for example X-API-Key or Bearer).
244
+ * Hashing here would make the original credential unrecoverable and break
245
+ * clients that need to send the raw key/token back to a remote service.
240
246
  */
241
247
  private normalizeApiKey;
242
248
  }
@@ -257,4 +263,4 @@ declare class ApiKeyStorageWeb {
257
263
  private base64Decode;
258
264
  }
259
265
 
260
- export { AuthGatewayClient as A, BaseOAuthFlow as B, DesktopOAuthFlow as D, type GrantType as G, type OAuthConfig as O, type PKCEChallenge as P, type TokenStorageAdapter as T, TokenStorageWeb as a, ApiKeyStorageWeb as b, type TokenResponse as c, type DeviceCodeResponse as d, type AuthError as e, type AuthTokenType as f, type AuthValidationResult as g, type AuthGatewayClientConfig as h, type TokenExchangeOptions as i, type TokenExchangeResponse as j, TokenStorage as k, type ApiKeyData as l, ApiKeyStorage as m };
266
+ export { ApiKeyStorageWeb as A, BaseOAuthFlow as B, DesktopOAuthFlow as D, type GrantType as G, type OAuthConfig as O, type PKCEChallenge as P, type TokenStorageAdapter as T, type AuthError as a, AuthGatewayClient as b, type AuthGatewayClientConfig as c, type AuthTokenType as d, type AuthValidationResult as e, type DeviceCodeResponse as f, type TokenExchangeOptions as g, type TokenExchangeResponse as h, type TokenResponse as i, TokenStorageWeb as j, type ApiKeyData as k, ApiKeyStorage as l, TokenStorage as m };
@@ -106,7 +106,8 @@ declare class TokenStorage implements TokenStorageAdapter {
106
106
  private readonly storageKey;
107
107
  private readonly webEncryptionKeyStorage;
108
108
  private keytar;
109
- constructor();
109
+ private keytarLoadAttempted;
110
+ private getKeytar;
110
111
  store(tokens: TokenResponse): Promise<void>;
111
112
  retrieve(): Promise<TokenResponse | null>;
112
113
  clear(): Promise<void>;
@@ -182,8 +183,9 @@ declare class ApiKeyStorage {
182
183
  private readonly legacyConfigKey;
183
184
  private readonly webEncryptionKeyStorage;
184
185
  private keytar;
186
+ private keytarLoadAttempted;
185
187
  private migrationCompleted;
186
- constructor();
188
+ private getKeytar;
187
189
  /**
188
190
  * Initialize and migrate from legacy storage if needed
189
191
  */
@@ -235,8 +237,12 @@ declare class ApiKeyStorage {
235
237
  private base64Encode;
236
238
  private base64Decode;
237
239
  /**
238
- * Normalize API keys to a SHA-256 hex digest.
239
- * Accepts pre-hashed input and lowercases it to prevent double hashing.
240
+ * Normalize stored credentials without transforming their value.
241
+ *
242
+ * These secrets are stored in encrypted local storage/keychains and must remain
243
+ * usable for outbound authentication headers (for example X-API-Key or Bearer).
244
+ * Hashing here would make the original credential unrecoverable and break
245
+ * clients that need to send the raw key/token back to a remote service.
240
246
  */
241
247
  private normalizeApiKey;
242
248
  }
@@ -257,4 +263,4 @@ declare class ApiKeyStorageWeb {
257
263
  private base64Decode;
258
264
  }
259
265
 
260
- export { AuthGatewayClient as A, BaseOAuthFlow as B, DesktopOAuthFlow as D, type GrantType as G, type OAuthConfig as O, type PKCEChallenge as P, type TokenStorageAdapter as T, TokenStorageWeb as a, ApiKeyStorageWeb as b, type TokenResponse as c, type DeviceCodeResponse as d, type AuthError as e, type AuthTokenType as f, type AuthValidationResult as g, type AuthGatewayClientConfig as h, type TokenExchangeOptions as i, type TokenExchangeResponse as j, TokenStorage as k, type ApiKeyData as l, ApiKeyStorage as m };
266
+ export { ApiKeyStorageWeb as A, BaseOAuthFlow as B, DesktopOAuthFlow as D, type GrantType as G, type OAuthConfig as O, type PKCEChallenge as P, type TokenStorageAdapter as T, type AuthError as a, AuthGatewayClient as b, type AuthGatewayClientConfig as c, type AuthTokenType as d, type AuthValidationResult as e, type DeviceCodeResponse as f, type TokenExchangeOptions as g, type TokenExchangeResponse as h, type TokenResponse as i, TokenStorageWeb as j, type ApiKeyData as k, ApiKeyStorage as l, TokenStorage as m };
@@ -1,5 +1,5 @@
1
- import { O as OAuthConfig, T as TokenStorageAdapter } from './api-key-storage-web-J3W8nQi2.cjs';
2
- export { b as ApiKeyStorageWeb, e as AuthError, A as AuthGatewayClient, h as AuthGatewayClientConfig, f as AuthTokenType, g as AuthValidationResult, B as BaseOAuthFlow, D as DesktopOAuthFlow, d as DeviceCodeResponse, G as GrantType, P as PKCEChallenge, i as TokenExchangeOptions, j as TokenExchangeResponse, c as TokenResponse, a as TokenStorageWeb } from './api-key-storage-web-J3W8nQi2.cjs';
1
+ import { O as OAuthConfig, T as TokenStorageAdapter } from './api-key-storage-web-DUyiN9mC.cjs';
2
+ export { A as ApiKeyStorageWeb, a as AuthError, b as AuthGatewayClient, c as AuthGatewayClientConfig, d as AuthTokenType, e as AuthValidationResult, B as BaseOAuthFlow, D as DesktopOAuthFlow, f as DeviceCodeResponse, G as GrantType, P as PKCEChallenge, g as TokenExchangeOptions, h as TokenExchangeResponse, i as TokenResponse, j as TokenStorageWeb } from './api-key-storage-web-DUyiN9mC.cjs';
3
3
 
4
4
  interface MCPClientConfig extends Partial<OAuthConfig> {
5
5
  mcpEndpoint?: string;
package/dist/browser.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { O as OAuthConfig, T as TokenStorageAdapter } from './api-key-storage-web-J3W8nQi2.js';
2
- export { b as ApiKeyStorageWeb, e as AuthError, A as AuthGatewayClient, h as AuthGatewayClientConfig, f as AuthTokenType, g as AuthValidationResult, B as BaseOAuthFlow, D as DesktopOAuthFlow, d as DeviceCodeResponse, G as GrantType, P as PKCEChallenge, i as TokenExchangeOptions, j as TokenExchangeResponse, c as TokenResponse, a as TokenStorageWeb } from './api-key-storage-web-J3W8nQi2.js';
1
+ import { O as OAuthConfig, T as TokenStorageAdapter } from './api-key-storage-web-DUyiN9mC.js';
2
+ export { A as ApiKeyStorageWeb, a as AuthError, b as AuthGatewayClient, c as AuthGatewayClientConfig, d as AuthTokenType, e as AuthValidationResult, B as BaseOAuthFlow, D as DesktopOAuthFlow, f as DeviceCodeResponse, G as GrantType, P as PKCEChallenge, g as TokenExchangeOptions, h as TokenExchangeResponse, i as TokenResponse, j as TokenStorageWeb } from './api-key-storage-web-DUyiN9mC.js';
3
3
 
4
4
  interface MCPClientConfig extends Partial<OAuthConfig> {
5
5
  mcpEndpoint?: string;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * React-specific types for SSO authentication
3
+ * @module @lanonasis/oauth-client/react
4
+ */
5
+ /**
6
+ * SSO User information from the lanonasis_user cookie
7
+ */
8
+ interface SSOUser {
9
+ id: string;
10
+ email: string;
11
+ role: string;
12
+ name?: string;
13
+ avatar_url?: string;
14
+ }
15
+ /**
16
+ * SSO authentication state
17
+ */
18
+ interface SSOState {
19
+ /** Whether the user is authenticated */
20
+ isAuthenticated: boolean;
21
+ /** Whether the auth state is being determined */
22
+ isLoading: boolean;
23
+ /** User information if authenticated */
24
+ user: SSOUser | null;
25
+ /** Error message if auth check failed */
26
+ error: string | null;
27
+ }
28
+ /**
29
+ * Configuration for the SSO hook
30
+ */
31
+ interface SSOConfig {
32
+ /** Auth gateway URL (default: https://auth.lanonasis.com) */
33
+ authGatewayUrl?: string;
34
+ /** Cookie domain (default: .lanonasis.com) */
35
+ cookieDomain?: string;
36
+ /** Callback when auth state changes */
37
+ onAuthChange?: (state: SSOState) => void;
38
+ /** Polling interval in ms for cookie changes (default: 30000) */
39
+ pollInterval?: number;
40
+ }
41
+ /**
42
+ * Configuration for Supabase-to-cookie sync
43
+ */
44
+ interface SSOSyncConfig {
45
+ /** Auth gateway URL (default: https://auth.lanonasis.com) */
46
+ authGatewayUrl?: string;
47
+ /** Project scope for multi-tenant auth */
48
+ projectScope?: string;
49
+ /** Callback when sync completes */
50
+ onSyncComplete?: (success: boolean) => void;
51
+ }
52
+ /**
53
+ * Supabase session interface (minimal for what we need)
54
+ */
55
+ interface SupabaseSession {
56
+ access_token: string;
57
+ refresh_token?: string;
58
+ }
59
+ /**
60
+ * Return type for useSSO hook
61
+ */
62
+ interface UseSSOReturn extends SSOState {
63
+ /** Manually refresh auth state */
64
+ refresh: () => void;
65
+ /** Logout and redirect to auth gateway */
66
+ logout: (returnTo?: string) => void;
67
+ /** Get login URL with optional return URL */
68
+ getLoginUrl: (returnTo?: string) => string;
69
+ }
70
+ /**
71
+ * Return type for useSSOSync hook
72
+ */
73
+ interface UseSSOSyncReturn {
74
+ /** Manually trigger sync */
75
+ sync: () => Promise<boolean>;
76
+ /** Sync with gateway directly */
77
+ syncWithGateway: (session: SupabaseSession) => Promise<boolean>;
78
+ }
79
+
80
+ /**
81
+ * Cookie constants and utilities shared between browser and server
82
+ * @module @lanonasis/oauth-client/cookies
83
+ */
84
+ /**
85
+ * Cookie names used by Lan Onasis auth system
86
+ */
87
+ declare const COOKIE_NAMES: {
88
+ /** HttpOnly JWT session token */
89
+ readonly SESSION: "lanonasis_session";
90
+ /** Readable user metadata (JSON) */
91
+ readonly USER: "lanonasis_user";
92
+ };
93
+ /**
94
+ * Default cookie domain for cross-subdomain SSO
95
+ */
96
+ declare const DEFAULT_COOKIE_DOMAIN = ".lanonasis.com";
97
+ /**
98
+ * Default auth gateway URL
99
+ */
100
+ declare const DEFAULT_AUTH_GATEWAY = "https://auth.lanonasis.com";
101
+ /**
102
+ * Default polling interval for cookie changes (30 seconds)
103
+ */
104
+ declare const DEFAULT_POLL_INTERVAL = 30000;
105
+ /**
106
+ * Default project scope for multi-tenant auth
107
+ */
108
+ declare const DEFAULT_PROJECT_SCOPE = "lanonasis-maas";
109
+
110
+ export { COOKIE_NAMES as C, DEFAULT_AUTH_GATEWAY as D, type SSOConfig as S, type UseSSOReturn as U, type SupabaseSession as a, type SSOSyncConfig as b, type UseSSOSyncReturn as c, type SSOUser as d, DEFAULT_COOKIE_DOMAIN as e, DEFAULT_POLL_INTERVAL as f, DEFAULT_PROJECT_SCOPE as g, type SSOState as h };
@@ -0,0 +1,110 @@
1
+ /**
2
+ * React-specific types for SSO authentication
3
+ * @module @lanonasis/oauth-client/react
4
+ */
5
+ /**
6
+ * SSO User information from the lanonasis_user cookie
7
+ */
8
+ interface SSOUser {
9
+ id: string;
10
+ email: string;
11
+ role: string;
12
+ name?: string;
13
+ avatar_url?: string;
14
+ }
15
+ /**
16
+ * SSO authentication state
17
+ */
18
+ interface SSOState {
19
+ /** Whether the user is authenticated */
20
+ isAuthenticated: boolean;
21
+ /** Whether the auth state is being determined */
22
+ isLoading: boolean;
23
+ /** User information if authenticated */
24
+ user: SSOUser | null;
25
+ /** Error message if auth check failed */
26
+ error: string | null;
27
+ }
28
+ /**
29
+ * Configuration for the SSO hook
30
+ */
31
+ interface SSOConfig {
32
+ /** Auth gateway URL (default: https://auth.lanonasis.com) */
33
+ authGatewayUrl?: string;
34
+ /** Cookie domain (default: .lanonasis.com) */
35
+ cookieDomain?: string;
36
+ /** Callback when auth state changes */
37
+ onAuthChange?: (state: SSOState) => void;
38
+ /** Polling interval in ms for cookie changes (default: 30000) */
39
+ pollInterval?: number;
40
+ }
41
+ /**
42
+ * Configuration for Supabase-to-cookie sync
43
+ */
44
+ interface SSOSyncConfig {
45
+ /** Auth gateway URL (default: https://auth.lanonasis.com) */
46
+ authGatewayUrl?: string;
47
+ /** Project scope for multi-tenant auth */
48
+ projectScope?: string;
49
+ /** Callback when sync completes */
50
+ onSyncComplete?: (success: boolean) => void;
51
+ }
52
+ /**
53
+ * Supabase session interface (minimal for what we need)
54
+ */
55
+ interface SupabaseSession {
56
+ access_token: string;
57
+ refresh_token?: string;
58
+ }
59
+ /**
60
+ * Return type for useSSO hook
61
+ */
62
+ interface UseSSOReturn extends SSOState {
63
+ /** Manually refresh auth state */
64
+ refresh: () => void;
65
+ /** Logout and redirect to auth gateway */
66
+ logout: (returnTo?: string) => void;
67
+ /** Get login URL with optional return URL */
68
+ getLoginUrl: (returnTo?: string) => string;
69
+ }
70
+ /**
71
+ * Return type for useSSOSync hook
72
+ */
73
+ interface UseSSOSyncReturn {
74
+ /** Manually trigger sync */
75
+ sync: () => Promise<boolean>;
76
+ /** Sync with gateway directly */
77
+ syncWithGateway: (session: SupabaseSession) => Promise<boolean>;
78
+ }
79
+
80
+ /**
81
+ * Cookie constants and utilities shared between browser and server
82
+ * @module @lanonasis/oauth-client/cookies
83
+ */
84
+ /**
85
+ * Cookie names used by Lan Onasis auth system
86
+ */
87
+ declare const COOKIE_NAMES: {
88
+ /** HttpOnly JWT session token */
89
+ readonly SESSION: "lanonasis_session";
90
+ /** Readable user metadata (JSON) */
91
+ readonly USER: "lanonasis_user";
92
+ };
93
+ /**
94
+ * Default cookie domain for cross-subdomain SSO
95
+ */
96
+ declare const DEFAULT_COOKIE_DOMAIN = ".lanonasis.com";
97
+ /**
98
+ * Default auth gateway URL
99
+ */
100
+ declare const DEFAULT_AUTH_GATEWAY = "https://auth.lanonasis.com";
101
+ /**
102
+ * Default polling interval for cookie changes (30 seconds)
103
+ */
104
+ declare const DEFAULT_POLL_INTERVAL = 30000;
105
+ /**
106
+ * Default project scope for multi-tenant auth
107
+ */
108
+ declare const DEFAULT_PROJECT_SCOPE = "lanonasis-maas";
109
+
110
+ export { COOKIE_NAMES as C, DEFAULT_AUTH_GATEWAY as D, type SSOConfig as S, type UseSSOReturn as U, type SupabaseSession as a, type SSOSyncConfig as b, type UseSSOSyncReturn as c, type SSOUser as d, DEFAULT_COOKIE_DOMAIN as e, DEFAULT_POLL_INTERVAL as f, DEFAULT_PROJECT_SCOPE as g, type SSOState as h };