@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 +183 -15
- package/dist/{api-key-storage-web-J3W8nQi2.d.cts → api-key-storage-web-DUyiN9mC.d.cts} +11 -5
- package/dist/{api-key-storage-web-J3W8nQi2.d.ts → api-key-storage-web-DUyiN9mC.d.ts} +11 -5
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/constants-BZPTHasL.d.cts +110 -0
- package/dist/constants-BZPTHasL.d.ts +110 -0
- package/dist/index.cjs +79 -40
- package/dist/index.d.cts +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.mjs +79 -40
- package/dist/react/index.cjs +261 -0
- package/dist/react/index.d.cts +95 -0
- package/dist/react/index.d.ts +95 -0
- package/dist/react/index.mjs +238 -0
- package/dist/server/index.cjs +169 -0
- package/dist/server/index.d.cts +184 -0
- package/dist/server/index.d.ts +184 -0
- package/dist/server/index.mjs +146 -0
- package/package.json +57 -15
package/README.md
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
# @lanonasis/oauth-client
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
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
|
|
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)
|
|
120
|
-
2)
|
|
121
|
-
3)
|
|
122
|
-
4)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
239
|
-
*
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
239
|
-
*
|
|
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 {
|
|
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 };
|
package/dist/browser.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as OAuthConfig, T as TokenStorageAdapter } from './api-key-storage-web-
|
|
2
|
-
export {
|
|
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-
|
|
2
|
-
export {
|
|
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 };
|