@jasperoosthoek/zustand-auth-registry 0.0.1 → 0.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,24 +1,17 @@
1
1
  # zustand-auth-registry
2
2
 
3
- OAuth 2.0 compliant authentication state management library using Zustand and Axios with a type-safe registry pattern.
4
-
5
- ## Overview
6
-
7
- `zustand-auth-registry` provides a simple, type-safe way to manage authentication state in React applications using Zustand. It supports both modern OAuth 2.0 standards and legacy authentication patterns, with automatic token refresh, Bearer token support, and comprehensive backward compatibility.
3
+ Authentication state management library using Zustand and Axios with a type-safe registry pattern.
8
4
 
9
5
  ## Features
10
6
 
11
- - **OAuth 2.0 Compliance** - Industry-standard Bearer tokens, automatic refresh, token lifecycle management
12
7
  - **Authentication State Management** - User, token, and authentication status with reactive updates
13
8
  - **Registry Pattern** - Type-safe multiple auth stores per application
14
- - **Axios Integration** - Automatic authentication header management with configurable formats
15
- - **Token Lifecycle** - Automatic expiration detection, refresh workflows, and cleanup
16
- - **Auto-Refresh** - Configurable threshold-based token renewal (default: 5 minutes before expiry)
17
- - **Persistence** - Flexible storage options (localStorage, sessionStorage, custom) with OAuth token support
9
+ - **Axios Integration** - Automatic authentication header management
10
+ - **Token Lifecycle** - Automatic expiration detection and refresh workflows
11
+ - **Cookie Authentication** - httpOnly cookie support with CSRF protection
12
+ - **Typed Errors** - `AuthError` class with error codes for better error handling
13
+ - **Persistence** - Flexible storage options (localStorage, sessionStorage, custom)
18
14
  - **Type-Safe** - Full TypeScript support with generics for user models
19
- - **Backward Compatible** - Seamless support for Django REST Framework and legacy APIs
20
- - **Flexible** - Support for multiple APIs with different authentication strategies
21
- - **Lightweight** - Simple API, no unnecessary complexity
22
15
 
23
16
  ## Installation
24
17
 
@@ -28,15 +21,13 @@ npm install @jasperoosthoek/zustand-auth-registry zustand axios react
28
21
 
29
22
  ## Quick Start
30
23
 
31
- ### OAuth 2.0 Setup (Recommended)
32
-
33
24
  ```typescript
34
25
  import axios from 'axios';
35
26
  import { createAuthRegistry, useAuth } from '@jasperoosthoek/zustand-auth-registry';
36
27
 
37
28
  // 1. Define your user type
38
29
  type User = {
39
- id: string;
30
+ id: number;
40
31
  email: string;
41
32
  name: string;
42
33
  };
@@ -49,350 +40,177 @@ const getAuthStore = createAuthRegistry<{
49
40
  // 3. Create axios instance
50
41
  const api = axios.create({ baseURL: 'https://api.example.com' });
51
42
 
52
- // 4. Create OAuth 2.0 compliant auth store
43
+ // 4. Create auth store
53
44
  export const authStore = getAuthStore('main', {
54
45
  axios: api,
55
- tokenUrl: '/oauth/token',
56
- userInfoUrl: '/oauth/userinfo',
57
- // Automatic OAuth token extraction (access_token, refresh_token, expires_in)
58
- // Automatic Bearer header format
59
- // Auto-refresh enabled by default
46
+ loginUrl: '/auth/login',
47
+ logoutUrl: '/auth/logout',
48
+ getUserUrl: '/users/me',
49
+ extractUser: 'user', // Extract user from response.data.user
60
50
  });
61
51
 
62
52
  // 5. Use in components
63
53
  function LoginForm() {
64
54
  const { login } = useAuth(authStore);
65
55
  const { user, isAuthenticated } = authStore((s) => s);
66
-
56
+
67
57
  const handleLogin = async () => {
68
- await login({
69
- username: 'user@example.com',
70
- password: 'password'
71
- });
58
+ await login({ username: 'user@example.com', password: 'password' });
72
59
  };
73
-
60
+
74
61
  if (isAuthenticated) {
75
62
  return <div>Welcome {user?.name}!</div>;
76
63
  }
77
-
64
+
78
65
  return <button onClick={handleLogin}>Login</button>;
79
66
  }
80
67
  ```
81
68
 
82
- ### Legacy/Django Setup (Backward Compatible)
83
-
84
- ```typescript
85
- // Works with existing Django REST Framework patterns
86
- export const authStore = getAuthStore('main', {
87
- axios: api,
88
- loginUrl: '/api/token/login/', // Legacy endpoint
89
- logoutUrl: '/api/token/logout/',
90
- getUserUrl: '/api/users/me/',
91
- extractToken: (data) => data.auth_token, // Django field name
92
- formatAuthHeader: (token) => `Token ${token}`, // Django format
93
- });
94
- ```
95
-
96
- ## Use Cases
97
-
98
- ### OAuth 2.0 Provider Integration
99
-
100
- ```typescript
101
- // Works with Auth0, Google, GitHub, or any OAuth 2.0 provider
102
- const auth0Store = getAuthStore('auth0', {
103
- axios: api,
104
- tokenUrl: 'https://your-domain.auth0.com/oauth/token',
105
- userInfoUrl: 'https://your-domain.auth0.com/userinfo',
106
- autoRefresh: true,
107
- refreshThreshold: 300000, // Refresh 5 minutes before expiry
108
- onTokenRefresh: (tokens) => {
109
- console.log('Token refreshed, expires at:', new Date(tokens.expiresAt));
110
- }
111
- });
112
- ```
113
-
114
- ### JWT Token Support
115
-
116
- ```typescript
117
- // Automatic JWT expiration detection
118
- const jwtStore = getAuthStore('jwt', {
119
- axios: api,
120
- tokenUrl: '/api/auth/login',
121
- extractTokens: (data) => {
122
- const payload = JSON.parse(atob(data.access_token.split('.')[1]));
123
- return {
124
- accessToken: data.access_token,
125
- expiresAt: payload.exp * 1000, // JWT exp is in seconds
126
- tokenType: 'Bearer'
127
- };
128
- }
129
- });
130
- ```
131
-
132
- ### Multiple APIs with Different Authentication
69
+ ## Cookie Authentication
133
70
 
134
- ```typescript
135
- const internalApi = axios.create({ baseURL: 'https://internal.app.com' });
136
- const partnerApi = axios.create({ baseURL: 'https://partner.api.com' });
137
-
138
- // Internal API uses legacy Token authentication
139
- const internalAuth = getAuthStore('internal', {
140
- axios: internalApi,
141
- loginUrl: '/api/token/login/',
142
- extractToken: (data) => data.auth_token,
143
- formatAuthHeader: (token) => `Token ${token}`,
144
- });
145
-
146
- // Partner API uses OAuth 2.0 Bearer authentication
147
- const partnerAuth = getAuthStore('partner', {
148
- axios: partnerApi,
149
- tokenUrl: '/oauth/token',
150
- userInfoUrl: '/oauth/userinfo',
151
- // Uses Bearer tokens and auto-refresh by default
152
- });
153
- ```
154
-
155
- ### Custom Storage Configuration
71
+ For httpOnly cookie-based authentication (more secure against XSS):
156
72
 
157
73
  ```typescript
158
74
  const authStore = getAuthStore('main', {
159
75
  axios: api,
160
- tokenUrl: '/oauth/token',
161
- persistence: {
76
+ loginUrl: '/auth/login',
77
+ logoutUrl: '/auth/logout',
78
+ authCheckUrl: '/auth/check', // Required for cookie auth
79
+
80
+ cookieAuth: {
162
81
  enabled: true,
163
- storage: sessionStorage, // Use sessionStorage instead of localStorage
164
- tokenKey: 'access_token', // OAuth standard (default)
165
- refreshTokenKey: 'refresh_token',
166
- userKey: 'user_profile',
167
- expiryKey: 'token_expires_at',
82
+ csrf: {
83
+ enabled: true,
84
+ headerName: 'X-CSRFToken',
85
+ cookieName: 'csrftoken',
86
+ },
168
87
  },
169
88
  });
170
- ```
171
-
172
- ### SSR/No Persistence
173
89
 
174
- ```typescript
175
- const authStore = getAuthStore('main', {
176
- axios: api,
177
- tokenUrl: '/oauth/token',
178
- persistence: {
179
- enabled: false, // Disable persistence for SSR
180
- },
181
- });
90
+ // Check authentication status (reads httpOnly cookie server-side)
91
+ const { checkAuth } = useAuth(authStore);
92
+ const isAuthenticated = await checkAuth();
182
93
  ```
183
94
 
184
- ## Integration with zustand-crud-registry
185
-
186
- Works seamlessly with [@jasperoosthoek/zustand-crud-registry](https://github.com/jasperoosthoek/zustand-crud-registry):
95
+ ## Error Handling
187
96
 
188
97
  ```typescript
189
- import { createStoreRegistry } from '@jasperoosthoek/zustand-crud-registry';
190
- import { createAuthRegistry } from '@jasperoosthoek/zustand-auth-registry';
191
-
192
- // Shared axios instance
193
- const api = axios.create({ baseURL: 'https://api.example.com' });
98
+ import { AuthError, AuthErrorCode } from '@jasperoosthoek/zustand-auth-registry';
194
99
 
195
- // Auth manages authentication with auto-refresh
196
- const auth = getAuthStore('main', {
197
- axios: api,
198
- tokenUrl: '/oauth/token',
199
- autoRefresh: true
100
+ const authStore = getAuthStore('main', {
101
+ // ...
102
+ onError: (error) => {
103
+ if (AuthError.isAuthError(error)) {
104
+ switch (error.code) {
105
+ case AuthErrorCode.INVALID_CREDENTIALS:
106
+ alert('Invalid username or password');
107
+ break;
108
+ case AuthErrorCode.TOKEN_EXPIRED:
109
+ // Token expired, user needs to login again
110
+ break;
111
+ case AuthErrorCode.NETWORK_ERROR:
112
+ alert('Network error, please try again');
113
+ break;
114
+ }
115
+ }
116
+ },
200
117
  });
201
-
202
- // CRUD uses the same authenticated axios
203
- const getCrudStore = createStoreRegistry<{ user: User; post: Post }>();
204
- const users = getCrudStore('user', { axios: api, route: '/users' });
205
-
206
- // Login first, then use CRUD
207
- const { login } = useAuth(auth);
208
- const { list, getList } = useCrud(users);
209
-
210
- await login({ username: '...', password: '...' });
211
- await getList(); // Authenticated request with auto-refreshed tokens
212
118
  ```
213
119
 
214
120
  ## API Reference
215
121
 
216
- ### `createAuthRegistry<Models>()`
217
-
218
- Creates a registry function for type-safe auth stores.
122
+ ### `AuthConfig<U>`
219
123
 
220
124
  ```typescript
221
- type Models = {
222
- main: MainUser;
223
- admin: AdminUser;
224
- };
225
-
226
- const getAuthStore = createAuthRegistry<Models>();
227
- ```
228
-
229
- ### `getAuthStore(key, config)`
125
+ type AuthConfig<U> = {
126
+ axios: AxiosInstance;
230
127
 
231
- Creates or retrieves an auth store.
128
+ // Endpoints
129
+ loginUrl: string;
130
+ logoutUrl?: string;
131
+ refreshUrl?: string;
132
+ getUserUrl?: string;
133
+ authCheckUrl?: string; // For cookie auth
232
134
 
233
- **Parameters:**
234
- - `key`: Unique identifier for the store
235
- - `config`: Authentication configuration
135
+ // Token extraction from login response
136
+ extractTokens?: (data: any) => TokenData;
236
137
 
237
- **Returns:** Auth store with Zustand state and config metadata
138
+ // User extraction (function or string key)
139
+ extractUser?: ((data: any) => U | null) | string;
238
140
 
239
- ### `AuthConfig<U>`
141
+ // Auth header format (default: "Bearer {token}")
142
+ formatAuthHeader?: (token: string, tokenType?: string) => string;
240
143
 
241
- Configuration object for authentication.
144
+ // Auto-refresh
145
+ autoRefresh?: boolean; // Default: true
146
+ refreshThreshold?: number; // Default: 300000 (5 minutes)
147
+
148
+ // Cookie auth
149
+ cookieAuth?: {
150
+ enabled: boolean;
151
+ csrf?: {
152
+ enabled: boolean;
153
+ headerName?: string; // Default: 'X-CSRFToken'
154
+ cookieName?: string; // Default: 'csrftoken'
155
+ };
156
+ };
242
157
 
243
- ```typescript
244
- type AuthConfig<U> = {
245
- // Required
246
- axios: AxiosInstance;
247
-
248
- // OAuth 2.0 endpoints (recommended)
249
- tokenUrl?: string; // POST /oauth/token
250
- revokeUrl?: string; // POST /oauth/revoke
251
- userInfoUrl?: string; // GET /oauth/userinfo
252
-
253
- // Legacy endpoints (backward compatibility)
254
- loginUrl?: string; // POST /api/token/login/
255
- logoutUrl?: string; // POST /api/token/logout/
256
- getUserUrl?: string; // GET /api/users/me/
257
-
258
- // OAuth 2.0 token extraction (automatic if not specified)
259
- extractTokens?: (data: any) => TokenData;
260
-
261
- // Legacy token extraction (backward compatibility)
262
- extractToken?: (data: any) => string;
263
-
264
- // Token formatting (defaults to Bearer)
265
- formatAuthHeader?: (token: string, tokenType?: string) => string;
266
-
267
- // OAuth 2.0 features
268
- autoRefresh?: boolean; // Default: true
269
- refreshThreshold?: number; // Default: 300000ms (5 minutes)
270
-
271
- // Storage configuration
158
+ // Persistence
272
159
  persistence?: {
273
- enabled?: boolean; // Default: true
274
- storage?: Storage; // Default: localStorage
275
- tokenKey?: string; // Default: 'token'
276
- refreshTokenKey?: string; // Default: 'refresh_token'
277
- userKey?: string; // Default: 'user'
278
- expiryKey?: string; // Default: 'expires_at'
160
+ enabled: boolean; // Default: false
161
+ storage?: Storage; // Default: localStorage
162
+ tokenKey?: string;
163
+ refreshTokenKey?: string;
164
+ userKey?: string;
165
+ expiryKey?: string;
279
166
  };
280
-
281
- // Event callbacks
167
+
168
+ // Callbacks
282
169
  onError?: (error: any) => void;
283
170
  onLogin?: (user: U) => void;
284
171
  onLogout?: () => void;
285
- onTokenRefresh?: (tokens: TokenData) => void;
286
172
  };
287
173
  ```
288
174
 
289
175
  ### `TokenData`
290
176
 
291
- OAuth 2.0 compliant token structure.
292
-
293
177
  ```typescript
294
178
  type TokenData = {
295
- accessToken: string; // OAuth 2.0 standard
296
- refreshToken?: string; // For token renewal
297
- expiresAt?: number; // Timestamp for expiration
298
- tokenType: string; // 'Bearer' (default) or custom
299
- scope?: string[]; // OAuth scope support
179
+ accessToken: string;
180
+ refreshToken?: string;
181
+ expiresAt?: number;
182
+ tokenType: string; // Default: 'Bearer'
300
183
  };
301
184
  ```
302
185
 
303
186
  ### `useAuth(store)`
304
187
 
305
- React hook for authentication actions.
306
-
307
- **Returns:**
308
188
  ```typescript
309
- {
310
- login: (credentials: Record<string, string>, callback?: () => void) => Promise<void>;
311
- logout: () => Promise<void>;
312
- getCurrentUser: () => Promise<void>;
313
- refreshTokens: () => Promise<boolean>; // OAuth 2.0 token refresh
314
- }
189
+ const { login, logout, getCurrentUser, refreshTokens, checkAuth } = useAuth(authStore);
315
190
  ```
316
191
 
317
- ### Auth Store State
192
+ - `login(credentials, callback?)` - Login with credentials
193
+ - `logout()` - Logout and clear tokens
194
+ - `getCurrentUser()` - Fetch current user
195
+ - `refreshTokens()` - Refresh access token
196
+ - `checkAuth()` - Check cookie authentication status
318
197
 
319
- Access auth state using the store:
198
+ ### Auth Store State
320
199
 
321
200
  ```typescript
322
- const { user, token, tokens, isAuthenticated } = authStore((s) => s);
201
+ const { user, tokens, isAuthenticated, setBearerToken, setTokens } = authStore((s) => s);
323
202
  ```
324
203
 
325
204
  **State:**
326
- - `user: U | null` - Current user object
327
- - `token: string` - Authentication token (backward compatibility)
328
- - `tokens: TokenData | null` - OAuth 2.0 token structure
329
- - `isAuthenticated: boolean` - Whether user is authenticated (based on valid token)
330
-
331
- **Actions:**
332
- - `setToken(token: string)` - Set authentication token (backward compatibility)
333
- - `setTokens(tokens: TokenData)` - Set OAuth 2.0 tokens
334
- - `setUser(user: U)` - Set user object
335
- - `unsetUser()` - Clear user and tokens (logout)
336
- - `isTokenExpired(): boolean` - Check if current token is expired
337
-
338
- ## Migration Guide
339
-
340
- ### From Legacy to OAuth 2.0
205
+ - `user: U | null` - Current user
206
+ - `tokens: TokenData | null` - Token data (access token, refresh token, etc.)
207
+ - `isAuthenticated: boolean` - Authentication status
341
208
 
342
- **Step 1: No changes required (existing code continues to work)**
343
- ```typescript
344
- // Existing configurations work unchanged
345
- const authStore = getAuthStore('main', {
346
- loginUrl: '/api/token/login/',
347
- extractToken: (data) => data.auth_token,
348
- formatAuthHeader: (token) => `Token ${token}`
349
- });
350
- ```
351
-
352
- **Step 2: Gradual OAuth adoption**
353
- ```typescript
354
- // Start using OAuth endpoints while keeping legacy token extraction
355
- const authStore = getAuthStore('main', {
356
- tokenUrl: '/oauth/token', // OAuth endpoint
357
- extractToken: (data) => data.auth_token, // Legacy extraction
358
- formatAuthHeader: (token) => `Token ${token}` // Legacy headers
359
- });
360
- ```
361
-
362
- **Step 3: Full OAuth 2.0**
363
- ```typescript
364
- // Complete OAuth 2.0 implementation
365
- const authStore = getAuthStore('main', {
366
- tokenUrl: '/oauth/token',
367
- revokeUrl: '/oauth/revoke',
368
- userInfoUrl: '/oauth/userinfo',
369
- // OAuth token extraction and Bearer headers are automatic
370
- autoRefresh: true,
371
- refreshThreshold: 300000 // 5 minutes
372
- });
373
- ```
374
-
375
- ## Development
376
-
377
- See [SETUP.md](./SETUP.md) for detailed setup and development instructions.
378
-
379
- ```bash
380
- # Install dependencies
381
- npm install
382
-
383
- # Build
384
- npm run build
385
-
386
- # Test (67 tests, 100% pass rate)
387
- npm test
388
-
389
- # Coverage
390
- npm run test:coverage
391
- ```
392
-
393
- ## OAuth 2.0 Compliance
394
-
395
- This library implements OAuth 2.0 (RFC 6749) standards with Bearer Token Authentication (RFC 6750), token refresh flows, proper token lifecycle management, and standard field names. For detailed implementation information and future roadmap, see [docs/OAUTH_ROADMAP.md](./docs/OAUTH_ROADMAP.md).
209
+ **Methods:**
210
+ - `setBearerToken(token)` - Convenience method for simple Bearer token auth
211
+ - `setTokens(tokenData)` - Set full token data (access, refresh, expiry)
212
+ - `setUser(user)` - Set user
213
+ - `unsetUser()` - Clear user and tokens
396
214
 
397
215
  ## Related Projects
398
216
 
@@ -401,7 +219,3 @@ This library implements OAuth 2.0 (RFC 6749) standards with Bearer Token Authent
401
219
  ## License
402
220
 
403
221
  MIT
404
-
405
- ## Author
406
-
407
- Jasper Oosthoek
@@ -4,29 +4,30 @@ export type TokenData = {
4
4
  refreshToken?: string;
5
5
  expiresAt?: number;
6
6
  tokenType: string;
7
- scope?: string[];
8
7
  };
9
- export type TokenExtractor = (data: any) => string | TokenData;
10
8
  export type AuthConfig<U> = {
11
9
  axios: AxiosInstance;
12
- tokenUrl?: string;
13
- revokeUrl?: string;
14
- userInfoUrl?: string;
15
- loginUrl?: string;
10
+ loginUrl: string;
16
11
  logoutUrl?: string;
12
+ refreshUrl?: string;
17
13
  getUserUrl?: string;
14
+ authCheckUrl?: string;
18
15
  extractTokens?: (data: any) => TokenData;
19
- extractAccessToken?: (data: any) => string;
20
- extractRefreshToken?: (data: any) => string | undefined;
21
- extractExpiresIn?: (data: any) => number | undefined;
22
- extractTokenType?: (data: any) => string;
23
- extractScope?: (data: any) => string[] | undefined;
24
- extractToken?: (data: any) => string;
16
+ extractUser?: ((data: any) => U | null) | string;
25
17
  formatAuthHeader?: (token: string, tokenType?: string) => string;
26
18
  autoRefresh?: boolean;
27
19
  refreshThreshold?: number;
20
+ cookieAuth?: {
21
+ enabled: boolean;
22
+ csrf?: {
23
+ enabled: boolean;
24
+ headerName?: string;
25
+ cookieName?: string;
26
+ getToken?: () => string | null;
27
+ };
28
+ };
28
29
  persistence?: {
29
- enabled?: boolean;
30
+ enabled: boolean;
30
31
  storage?: Storage;
31
32
  tokenKey?: string;
32
33
  refreshTokenKey?: string;
@@ -36,21 +37,27 @@ export type AuthConfig<U> = {
36
37
  onError?: (error: any) => void;
37
38
  onLogin?: (user: U) => void;
38
39
  onLogout?: () => void;
39
- onTokenRefresh?: (tokens: TokenData) => void;
40
40
  };
41
41
  export type ValidatedAuthConfig<U> = {
42
42
  axios: AxiosInstance;
43
- tokenUrl: string;
44
- revokeUrl?: string;
45
- userInfoUrl?: string;
46
- loginUrl?: string;
43
+ loginUrl: string;
47
44
  logoutUrl?: string;
45
+ refreshUrl?: string;
48
46
  getUserUrl?: string;
47
+ authCheckUrl?: string;
49
48
  extractTokens: (data: any) => TokenData;
50
- extractToken?: (data: any) => string;
49
+ extractUser?: (data: any) => U | null;
51
50
  formatAuthHeader: (token: string, tokenType?: string) => string;
52
51
  autoRefresh: boolean;
53
52
  refreshThreshold: number;
53
+ cookieAuth?: {
54
+ enabled: boolean;
55
+ csrf: {
56
+ enabled: boolean;
57
+ headerName: string;
58
+ getToken: () => string | null;
59
+ };
60
+ };
54
61
  persistence: {
55
62
  enabled: boolean;
56
63
  storage: Storage;
@@ -62,6 +69,5 @@ export type ValidatedAuthConfig<U> = {
62
69
  onError?: (error: any) => void;
63
70
  onLogin?: (user: U) => void;
64
71
  onLogout?: () => void;
65
- onTokenRefresh?: (tokens: TokenData) => void;
66
72
  };
67
73
  export declare const validateAuthConfig: <U>(config: AuthConfig<U>) => ValidatedAuthConfig<U>;
@@ -1,15 +1,15 @@
1
1
  import { StoreApi, UseBoundStore } from 'zustand';
2
2
  import { ValidatedAuthConfig, TokenData } from './authConfig';
3
3
  export type AuthState<U> = {
4
- isAuthenticated: boolean;
4
+ isAuthenticated: boolean | null;
5
5
  user: U | null;
6
6
  tokens: TokenData | null;
7
7
  setTokens: (tokens: TokenData) => void;
8
+ setBearerToken: (token: string) => void;
9
+ setAuthenticated: (authenticated: boolean) => void;
8
10
  setUser: (user: U) => void;
9
11
  unsetUser: () => void;
10
12
  isTokenExpired: () => boolean;
11
- token: string;
12
- setToken: (token: string) => void;
13
13
  };
14
14
  export type AuthStore<U> = UseBoundStore<StoreApi<AuthState<U>>> & {
15
15
  config: ValidatedAuthConfig<U>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Authentication error codes
3
+ */
4
+ export declare enum AuthErrorCode {
5
+ INVALID_CREDENTIALS = "INVALID_CREDENTIALS",
6
+ TOKEN_EXPIRED = "TOKEN_EXPIRED",
7
+ TOKEN_INVALID = "TOKEN_INVALID",
8
+ REFRESH_FAILED = "REFRESH_FAILED",
9
+ NETWORK_ERROR = "NETWORK_ERROR",
10
+ USER_NOT_FOUND = "USER_NOT_FOUND",
11
+ UNAUTHORIZED = "UNAUTHORIZED",
12
+ CSRF_TOKEN_MISSING = "CSRF_TOKEN_MISSING",
13
+ FORBIDDEN = "FORBIDDEN",
14
+ UNKNOWN = "UNKNOWN"
15
+ }
16
+ /**
17
+ * Typed authentication error
18
+ */
19
+ export declare class AuthError extends Error {
20
+ code: AuthErrorCode;
21
+ originalError?: any;
22
+ constructor(code: AuthErrorCode, originalError?: any, message?: string);
23
+ /**
24
+ * Convert error to JSON (excludes originalError in production)
25
+ */
26
+ toJSON(): {
27
+ code: AuthErrorCode;
28
+ message: string;
29
+ name: string;
30
+ };
31
+ /**
32
+ * Check if error is an AuthError
33
+ */
34
+ static isAuthError(error: any): error is AuthError;
35
+ }
36
+ /**
37
+ * Create typed AuthError from any error
38
+ */
39
+ export declare function createAuthError(error: any): AuthError;
package/dist/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export * from './authConfig';
2
2
  export * from './authStore';
3
3
  export * from './createAuthRegistry';
4
4
  export * from './useAuth';
5
+ export * from './errors';