@anythink-cloud/sdk 0.2.1 → 0.3.0
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/dist/index.d.mts +137 -1
- package/dist/index.d.ts +137 -1
- package/dist/index.js +251 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +250 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as zustand_middleware from 'zustand/middleware';
|
|
2
2
|
import * as zustand from 'zustand';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
3
5
|
import { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -120,9 +122,11 @@ interface CookieStorageOptions {
|
|
|
120
122
|
|
|
121
123
|
interface AuthState {
|
|
122
124
|
session: Session | null;
|
|
125
|
+
user: User | null;
|
|
123
126
|
isLoading: boolean;
|
|
124
127
|
error: Error | null;
|
|
125
128
|
setSession: (session: Session | null) => void;
|
|
129
|
+
setUser: (user: User | null) => void;
|
|
126
130
|
signOut: () => void;
|
|
127
131
|
clearError: () => void;
|
|
128
132
|
setLoading: (isLoading: boolean) => void;
|
|
@@ -231,12 +235,144 @@ declare class AuthClient {
|
|
|
231
235
|
* Check if user is authenticated
|
|
232
236
|
*/
|
|
233
237
|
isAuthenticated(): boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Fetch user information from the API
|
|
240
|
+
* @returns User object or null if failed
|
|
241
|
+
*/
|
|
242
|
+
fetchUserInfo(): Promise<{
|
|
243
|
+
data: {
|
|
244
|
+
user: User | null;
|
|
245
|
+
};
|
|
246
|
+
error: Error | null;
|
|
247
|
+
}>;
|
|
248
|
+
/**
|
|
249
|
+
* Get the current user
|
|
250
|
+
* @returns User object or null if not available
|
|
251
|
+
*/
|
|
252
|
+
getUser(): User | null;
|
|
234
253
|
/**
|
|
235
254
|
* Get the Zustand store (for React hooks)
|
|
236
255
|
*/
|
|
237
256
|
getStore(): ReturnType<typeof createAuthStore>;
|
|
238
257
|
}
|
|
239
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Callback functions for auth events
|
|
261
|
+
*/
|
|
262
|
+
interface AuthCallbacks {
|
|
263
|
+
/**
|
|
264
|
+
* Called after successful sign in
|
|
265
|
+
*/
|
|
266
|
+
onSignIn?: (session: Session) => void | Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Called after sign out
|
|
269
|
+
*/
|
|
270
|
+
onSignOut?: () => void | Promise<void>;
|
|
271
|
+
/**
|
|
272
|
+
* Called when token refresh fails and user is signed out
|
|
273
|
+
*/
|
|
274
|
+
onTokenRefreshFailed?: () => void | Promise<void>;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Auth context value
|
|
278
|
+
*/
|
|
279
|
+
interface AuthContextValue {
|
|
280
|
+
/**
|
|
281
|
+
* Current session
|
|
282
|
+
*/
|
|
283
|
+
session: Session | null;
|
|
284
|
+
/**
|
|
285
|
+
* Current user information
|
|
286
|
+
*/
|
|
287
|
+
user: User | null;
|
|
288
|
+
/**
|
|
289
|
+
* Whether auth operations are in progress
|
|
290
|
+
*/
|
|
291
|
+
isLoading: boolean;
|
|
292
|
+
/**
|
|
293
|
+
* Current error, if any
|
|
294
|
+
*/
|
|
295
|
+
error: Error | null;
|
|
296
|
+
/**
|
|
297
|
+
* Whether user is authenticated
|
|
298
|
+
*/
|
|
299
|
+
isAuthenticated: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Sign in with email and password
|
|
302
|
+
*/
|
|
303
|
+
signIn: (email: string, password: string, orgId?: number) => Promise<SignInResponse>;
|
|
304
|
+
/**
|
|
305
|
+
* Sign out and clear session
|
|
306
|
+
*/
|
|
307
|
+
signOut: () => Promise<{
|
|
308
|
+
error: Error | null;
|
|
309
|
+
}>;
|
|
310
|
+
/**
|
|
311
|
+
* Register a new user
|
|
312
|
+
*/
|
|
313
|
+
register: (firstName: string, lastName: string, email: string, password: string) => Promise<{
|
|
314
|
+
error: Error | null;
|
|
315
|
+
}>;
|
|
316
|
+
/**
|
|
317
|
+
* Change password
|
|
318
|
+
*/
|
|
319
|
+
changePassword: (currentPassword: string, newPassword: string) => Promise<{
|
|
320
|
+
error: Error | null;
|
|
321
|
+
}>;
|
|
322
|
+
/**
|
|
323
|
+
* Refresh the session token
|
|
324
|
+
*/
|
|
325
|
+
refreshSession: () => Promise<RefreshResponse>;
|
|
326
|
+
/**
|
|
327
|
+
* Get the current access token
|
|
328
|
+
*/
|
|
329
|
+
getAccessToken: () => string | null;
|
|
330
|
+
/**
|
|
331
|
+
* Get the current refresh token
|
|
332
|
+
*/
|
|
333
|
+
getRefreshToken: () => string | null;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Props for AuthProvider
|
|
337
|
+
*/
|
|
338
|
+
interface AuthProviderProps {
|
|
339
|
+
/**
|
|
340
|
+
* AuthClient instance
|
|
341
|
+
*/
|
|
342
|
+
authClient: AuthClient;
|
|
343
|
+
/**
|
|
344
|
+
* Optional callbacks for auth events
|
|
345
|
+
*/
|
|
346
|
+
callbacks?: AuthCallbacks;
|
|
347
|
+
/**
|
|
348
|
+
* Whether to automatically refresh tokens before they expire
|
|
349
|
+
* @default true
|
|
350
|
+
*/
|
|
351
|
+
autoRefresh?: boolean;
|
|
352
|
+
/**
|
|
353
|
+
* How many seconds before expiration to refresh the token
|
|
354
|
+
* @default 60
|
|
355
|
+
*/
|
|
356
|
+
refreshThreshold?: number;
|
|
357
|
+
/**
|
|
358
|
+
* URL to redirect to when user is not authenticated or token refresh fails
|
|
359
|
+
*/
|
|
360
|
+
loginUrl?: string;
|
|
361
|
+
/**
|
|
362
|
+
* Child components
|
|
363
|
+
*/
|
|
364
|
+
children: ReactNode;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* AuthProvider component that wraps your app and provides auth state
|
|
368
|
+
*/
|
|
369
|
+
declare function AuthProvider({ authClient, callbacks, autoRefresh, refreshThreshold, loginUrl, children, }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
370
|
+
/**
|
|
371
|
+
* Hook to access auth context
|
|
372
|
+
* @throws Error if used outside AuthProvider
|
|
373
|
+
*/
|
|
374
|
+
declare function useAuth(): AuthContextValue;
|
|
375
|
+
|
|
240
376
|
/**
|
|
241
377
|
* Base service class with automatic token injection and refresh handling
|
|
242
378
|
*/
|
|
@@ -279,4 +415,4 @@ declare class AuthenticatedBaseService {
|
|
|
279
415
|
getClient(): AxiosInstance;
|
|
280
416
|
}
|
|
281
417
|
|
|
282
|
-
export { AuthClient, type AuthConfig, AuthenticatedBaseService, type CookieStorageConfig, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore };
|
|
418
|
+
export { type AuthCallbacks, AuthClient, type AuthConfig, type AuthContextValue, AuthProvider, type AuthProviderProps, AuthenticatedBaseService, type CookieStorageConfig, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore, useAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as zustand_middleware from 'zustand/middleware';
|
|
2
2
|
import * as zustand from 'zustand';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
3
5
|
import { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -120,9 +122,11 @@ interface CookieStorageOptions {
|
|
|
120
122
|
|
|
121
123
|
interface AuthState {
|
|
122
124
|
session: Session | null;
|
|
125
|
+
user: User | null;
|
|
123
126
|
isLoading: boolean;
|
|
124
127
|
error: Error | null;
|
|
125
128
|
setSession: (session: Session | null) => void;
|
|
129
|
+
setUser: (user: User | null) => void;
|
|
126
130
|
signOut: () => void;
|
|
127
131
|
clearError: () => void;
|
|
128
132
|
setLoading: (isLoading: boolean) => void;
|
|
@@ -231,12 +235,144 @@ declare class AuthClient {
|
|
|
231
235
|
* Check if user is authenticated
|
|
232
236
|
*/
|
|
233
237
|
isAuthenticated(): boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Fetch user information from the API
|
|
240
|
+
* @returns User object or null if failed
|
|
241
|
+
*/
|
|
242
|
+
fetchUserInfo(): Promise<{
|
|
243
|
+
data: {
|
|
244
|
+
user: User | null;
|
|
245
|
+
};
|
|
246
|
+
error: Error | null;
|
|
247
|
+
}>;
|
|
248
|
+
/**
|
|
249
|
+
* Get the current user
|
|
250
|
+
* @returns User object or null if not available
|
|
251
|
+
*/
|
|
252
|
+
getUser(): User | null;
|
|
234
253
|
/**
|
|
235
254
|
* Get the Zustand store (for React hooks)
|
|
236
255
|
*/
|
|
237
256
|
getStore(): ReturnType<typeof createAuthStore>;
|
|
238
257
|
}
|
|
239
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Callback functions for auth events
|
|
261
|
+
*/
|
|
262
|
+
interface AuthCallbacks {
|
|
263
|
+
/**
|
|
264
|
+
* Called after successful sign in
|
|
265
|
+
*/
|
|
266
|
+
onSignIn?: (session: Session) => void | Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Called after sign out
|
|
269
|
+
*/
|
|
270
|
+
onSignOut?: () => void | Promise<void>;
|
|
271
|
+
/**
|
|
272
|
+
* Called when token refresh fails and user is signed out
|
|
273
|
+
*/
|
|
274
|
+
onTokenRefreshFailed?: () => void | Promise<void>;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Auth context value
|
|
278
|
+
*/
|
|
279
|
+
interface AuthContextValue {
|
|
280
|
+
/**
|
|
281
|
+
* Current session
|
|
282
|
+
*/
|
|
283
|
+
session: Session | null;
|
|
284
|
+
/**
|
|
285
|
+
* Current user information
|
|
286
|
+
*/
|
|
287
|
+
user: User | null;
|
|
288
|
+
/**
|
|
289
|
+
* Whether auth operations are in progress
|
|
290
|
+
*/
|
|
291
|
+
isLoading: boolean;
|
|
292
|
+
/**
|
|
293
|
+
* Current error, if any
|
|
294
|
+
*/
|
|
295
|
+
error: Error | null;
|
|
296
|
+
/**
|
|
297
|
+
* Whether user is authenticated
|
|
298
|
+
*/
|
|
299
|
+
isAuthenticated: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Sign in with email and password
|
|
302
|
+
*/
|
|
303
|
+
signIn: (email: string, password: string, orgId?: number) => Promise<SignInResponse>;
|
|
304
|
+
/**
|
|
305
|
+
* Sign out and clear session
|
|
306
|
+
*/
|
|
307
|
+
signOut: () => Promise<{
|
|
308
|
+
error: Error | null;
|
|
309
|
+
}>;
|
|
310
|
+
/**
|
|
311
|
+
* Register a new user
|
|
312
|
+
*/
|
|
313
|
+
register: (firstName: string, lastName: string, email: string, password: string) => Promise<{
|
|
314
|
+
error: Error | null;
|
|
315
|
+
}>;
|
|
316
|
+
/**
|
|
317
|
+
* Change password
|
|
318
|
+
*/
|
|
319
|
+
changePassword: (currentPassword: string, newPassword: string) => Promise<{
|
|
320
|
+
error: Error | null;
|
|
321
|
+
}>;
|
|
322
|
+
/**
|
|
323
|
+
* Refresh the session token
|
|
324
|
+
*/
|
|
325
|
+
refreshSession: () => Promise<RefreshResponse>;
|
|
326
|
+
/**
|
|
327
|
+
* Get the current access token
|
|
328
|
+
*/
|
|
329
|
+
getAccessToken: () => string | null;
|
|
330
|
+
/**
|
|
331
|
+
* Get the current refresh token
|
|
332
|
+
*/
|
|
333
|
+
getRefreshToken: () => string | null;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Props for AuthProvider
|
|
337
|
+
*/
|
|
338
|
+
interface AuthProviderProps {
|
|
339
|
+
/**
|
|
340
|
+
* AuthClient instance
|
|
341
|
+
*/
|
|
342
|
+
authClient: AuthClient;
|
|
343
|
+
/**
|
|
344
|
+
* Optional callbacks for auth events
|
|
345
|
+
*/
|
|
346
|
+
callbacks?: AuthCallbacks;
|
|
347
|
+
/**
|
|
348
|
+
* Whether to automatically refresh tokens before they expire
|
|
349
|
+
* @default true
|
|
350
|
+
*/
|
|
351
|
+
autoRefresh?: boolean;
|
|
352
|
+
/**
|
|
353
|
+
* How many seconds before expiration to refresh the token
|
|
354
|
+
* @default 60
|
|
355
|
+
*/
|
|
356
|
+
refreshThreshold?: number;
|
|
357
|
+
/**
|
|
358
|
+
* URL to redirect to when user is not authenticated or token refresh fails
|
|
359
|
+
*/
|
|
360
|
+
loginUrl?: string;
|
|
361
|
+
/**
|
|
362
|
+
* Child components
|
|
363
|
+
*/
|
|
364
|
+
children: ReactNode;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* AuthProvider component that wraps your app and provides auth state
|
|
368
|
+
*/
|
|
369
|
+
declare function AuthProvider({ authClient, callbacks, autoRefresh, refreshThreshold, loginUrl, children, }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
370
|
+
/**
|
|
371
|
+
* Hook to access auth context
|
|
372
|
+
* @throws Error if used outside AuthProvider
|
|
373
|
+
*/
|
|
374
|
+
declare function useAuth(): AuthContextValue;
|
|
375
|
+
|
|
240
376
|
/**
|
|
241
377
|
* Base service class with automatic token injection and refresh handling
|
|
242
378
|
*/
|
|
@@ -279,4 +415,4 @@ declare class AuthenticatedBaseService {
|
|
|
279
415
|
getClient(): AxiosInstance;
|
|
280
416
|
}
|
|
281
417
|
|
|
282
|
-
export { AuthClient, type AuthConfig, AuthenticatedBaseService, type CookieStorageConfig, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore };
|
|
418
|
+
export { type AuthCallbacks, AuthClient, type AuthConfig, type AuthContextValue, AuthProvider, type AuthProviderProps, AuthenticatedBaseService, type CookieStorageConfig, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore, useAuth };
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var axios = require('axios');
|
|
4
4
|
var zustand = require('zustand');
|
|
5
5
|
var middleware = require('zustand/middleware');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
8
|
|
|
7
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
10
|
|
|
@@ -113,13 +115,17 @@ var createAuthStore = (cookieOptions) => {
|
|
|
113
115
|
middleware.persist(
|
|
114
116
|
(set) => ({
|
|
115
117
|
session: null,
|
|
118
|
+
user: null,
|
|
116
119
|
isLoading: false,
|
|
117
120
|
error: null,
|
|
118
121
|
setSession: (session) => {
|
|
119
122
|
set({ session, error: null });
|
|
120
123
|
},
|
|
124
|
+
setUser: (user) => {
|
|
125
|
+
set({ user });
|
|
126
|
+
},
|
|
121
127
|
signOut: () => {
|
|
122
|
-
set({ session: null, error: null });
|
|
128
|
+
set({ session: null, user: null, error: null });
|
|
123
129
|
},
|
|
124
130
|
clearError: () => {
|
|
125
131
|
set({ error: null });
|
|
@@ -143,8 +149,11 @@ var createAuthStore = (cookieOptions) => {
|
|
|
143
149
|
// User-provided options override defaults
|
|
144
150
|
});
|
|
145
151
|
}),
|
|
146
|
-
// Only persist the session, not loading/error states
|
|
147
|
-
partialize: (state) => ({
|
|
152
|
+
// Only persist the session and user, not loading/error states
|
|
153
|
+
partialize: (state) => ({
|
|
154
|
+
session: state.session,
|
|
155
|
+
user: state.user
|
|
156
|
+
})
|
|
148
157
|
}
|
|
149
158
|
)
|
|
150
159
|
);
|
|
@@ -181,7 +190,7 @@ var AuthClient = class {
|
|
|
181
190
|
this.store.getState().clearError();
|
|
182
191
|
const params = orgId ? { org_id: orgId.toString() } : void 0;
|
|
183
192
|
const response = await this.axiosClient.post(
|
|
184
|
-
this.config.tokenEndpoint ??
|
|
193
|
+
this.config.tokenEndpoint ?? `/org/${this.config.orgId}/auth/v1/token`,
|
|
185
194
|
{ email, password },
|
|
186
195
|
{ params }
|
|
187
196
|
);
|
|
@@ -194,6 +203,7 @@ var AuthClient = class {
|
|
|
194
203
|
};
|
|
195
204
|
this.store.getState().setSession(session);
|
|
196
205
|
this.store.getState().setLoading(false);
|
|
206
|
+
await this.fetchUserInfo();
|
|
197
207
|
return { data: { session }, error: null };
|
|
198
208
|
} catch (error) {
|
|
199
209
|
let authError;
|
|
@@ -223,7 +233,7 @@ var AuthClient = class {
|
|
|
223
233
|
async register(firstName, lastName, email, password) {
|
|
224
234
|
try {
|
|
225
235
|
await this.axiosClient.post(
|
|
226
|
-
this.config.registerEndpoint ??
|
|
236
|
+
this.config.registerEndpoint ?? `/org/${this.config.orgId}/auth/v1/register`,
|
|
227
237
|
{
|
|
228
238
|
first_name: firstName,
|
|
229
239
|
last_name: lastName,
|
|
@@ -264,7 +274,7 @@ var AuthClient = class {
|
|
|
264
274
|
this.store.getState().setLoading(true);
|
|
265
275
|
this.store.getState().clearError();
|
|
266
276
|
const response = await this.axiosClient.post(
|
|
267
|
-
this.config.refreshEndpoint ??
|
|
277
|
+
this.config.refreshEndpoint ?? `/org/${this.config.orgId}/auth/v1/refresh`,
|
|
268
278
|
{ token: session.refresh_token }
|
|
269
279
|
);
|
|
270
280
|
const tokenPair = response.data;
|
|
@@ -276,6 +286,7 @@ var AuthClient = class {
|
|
|
276
286
|
};
|
|
277
287
|
this.store.getState().setSession(newSession);
|
|
278
288
|
this.store.getState().setLoading(false);
|
|
289
|
+
await this.fetchUserInfo();
|
|
279
290
|
return { data: { session: newSession }, error: null };
|
|
280
291
|
} catch (error) {
|
|
281
292
|
this.store.getState().setSession(null);
|
|
@@ -324,6 +335,7 @@ var AuthClient = class {
|
|
|
324
335
|
expires_at: Math.floor(Date.now() / 1e3) + expires_in
|
|
325
336
|
};
|
|
326
337
|
this.store.getState().setSession(session);
|
|
338
|
+
await this.fetchUserInfo();
|
|
327
339
|
return { error: null };
|
|
328
340
|
} catch (error) {
|
|
329
341
|
return {
|
|
@@ -344,7 +356,7 @@ var AuthClient = class {
|
|
|
344
356
|
throw new Error("No access token found");
|
|
345
357
|
}
|
|
346
358
|
await this.axiosClient.post(
|
|
347
|
-
this.config.changePasswordEndpoint ??
|
|
359
|
+
this.config.changePasswordEndpoint ?? `/org/${this.config.orgId}/users/me/password`,
|
|
348
360
|
{
|
|
349
361
|
current_password: currentPassword,
|
|
350
362
|
new_password: newPassword
|
|
@@ -380,7 +392,7 @@ var AuthClient = class {
|
|
|
380
392
|
if (refreshToken) {
|
|
381
393
|
try {
|
|
382
394
|
await this.axiosClient.post(
|
|
383
|
-
this.config.logoutEndpoint ??
|
|
395
|
+
this.config.logoutEndpoint ?? `/org/${this.config.orgId}/auth/v1/logout`,
|
|
384
396
|
{
|
|
385
397
|
token: refreshToken
|
|
386
398
|
}
|
|
@@ -427,6 +439,51 @@ var AuthClient = class {
|
|
|
427
439
|
}
|
|
428
440
|
return true;
|
|
429
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Fetch user information from the API
|
|
444
|
+
* @returns User object or null if failed
|
|
445
|
+
*/
|
|
446
|
+
async fetchUserInfo() {
|
|
447
|
+
const token = this.getAccessToken();
|
|
448
|
+
if (!token) {
|
|
449
|
+
return {
|
|
450
|
+
data: { user: null },
|
|
451
|
+
error: new Error("No access token found")
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
const response = await this.axiosClient.get(
|
|
456
|
+
`/org/${this.config.orgId}/users/me`,
|
|
457
|
+
{
|
|
458
|
+
headers: {
|
|
459
|
+
Authorization: `Bearer ${token}`
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
);
|
|
463
|
+
const user = response.data;
|
|
464
|
+
this.store.getState().setUser(user);
|
|
465
|
+
return { data: { user }, error: null };
|
|
466
|
+
} catch (error) {
|
|
467
|
+
let authError;
|
|
468
|
+
if (error instanceof axios.AxiosError) {
|
|
469
|
+
const errorMessage = typeof error.response?.data === "string" ? error.response.data : error.response?.data?.message || error.message || "Failed to fetch user information";
|
|
470
|
+
authError = new Error(errorMessage);
|
|
471
|
+
} else {
|
|
472
|
+
authError = error instanceof Error ? error : new Error("Failed to fetch user information");
|
|
473
|
+
}
|
|
474
|
+
return {
|
|
475
|
+
data: { user: null },
|
|
476
|
+
error: authError
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get the current user
|
|
482
|
+
* @returns User object or null if not available
|
|
483
|
+
*/
|
|
484
|
+
getUser() {
|
|
485
|
+
return this.store.getState().user;
|
|
486
|
+
}
|
|
430
487
|
/**
|
|
431
488
|
* Get the Zustand store (for React hooks)
|
|
432
489
|
*/
|
|
@@ -434,6 +491,190 @@ var AuthClient = class {
|
|
|
434
491
|
return this.store;
|
|
435
492
|
}
|
|
436
493
|
};
|
|
494
|
+
var AuthContext = react.createContext(null);
|
|
495
|
+
function AuthProvider({
|
|
496
|
+
authClient,
|
|
497
|
+
callbacks,
|
|
498
|
+
autoRefresh = true,
|
|
499
|
+
refreshThreshold = 60,
|
|
500
|
+
loginUrl,
|
|
501
|
+
children
|
|
502
|
+
}) {
|
|
503
|
+
const store = authClient.getStore();
|
|
504
|
+
const session = store((state) => state.session);
|
|
505
|
+
const user = store((state) => state.user);
|
|
506
|
+
const isLoading = store((state) => state.isLoading);
|
|
507
|
+
const error = store((state) => state.error);
|
|
508
|
+
const refreshTimerRef = react.useRef(null);
|
|
509
|
+
const isRefreshingRef = react.useRef(false);
|
|
510
|
+
const hasInitializedRef = react.useRef(false);
|
|
511
|
+
const isAuthenticated = react.useMemo(() => {
|
|
512
|
+
if (!session) return false;
|
|
513
|
+
if (session.expires_at && Date.now() >= session.expires_at * 1e3) {
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
return true;
|
|
517
|
+
}, [session]);
|
|
518
|
+
const redirectToLogin = react.useCallback(() => {
|
|
519
|
+
if (loginUrl && typeof window !== "undefined") {
|
|
520
|
+
window.location.href = loginUrl;
|
|
521
|
+
}
|
|
522
|
+
}, [loginUrl]);
|
|
523
|
+
const refreshTokenIfNeeded = react.useCallback(async () => {
|
|
524
|
+
if (isRefreshingRef.current) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
const currentSession = authClient.getSession().data.session;
|
|
528
|
+
if (!currentSession || !currentSession.expires_at) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
532
|
+
const timeUntilExpiry = currentSession.expires_at - now;
|
|
533
|
+
if (timeUntilExpiry <= refreshThreshold) {
|
|
534
|
+
isRefreshingRef.current = true;
|
|
535
|
+
try {
|
|
536
|
+
const { data, error: refreshError } = await authClient.refreshSession();
|
|
537
|
+
if (refreshError || !data.session) {
|
|
538
|
+
if (callbacks?.onTokenRefreshFailed) {
|
|
539
|
+
await callbacks.onTokenRefreshFailed();
|
|
540
|
+
}
|
|
541
|
+
redirectToLogin();
|
|
542
|
+
}
|
|
543
|
+
} catch (err) {
|
|
544
|
+
if (callbacks?.onTokenRefreshFailed) {
|
|
545
|
+
await callbacks.onTokenRefreshFailed();
|
|
546
|
+
}
|
|
547
|
+
redirectToLogin();
|
|
548
|
+
} finally {
|
|
549
|
+
isRefreshingRef.current = false;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}, [authClient, refreshThreshold, callbacks, redirectToLogin]);
|
|
553
|
+
react.useEffect(() => {
|
|
554
|
+
if (hasInitializedRef.current) {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
hasInitializedRef.current = true;
|
|
558
|
+
let isMounted = true;
|
|
559
|
+
const initializeAuth = async () => {
|
|
560
|
+
try {
|
|
561
|
+
const currentSession = authClient.getSession().data.session;
|
|
562
|
+
if (!currentSession || !currentSession.expires_at) {
|
|
563
|
+
if (loginUrl && isMounted) {
|
|
564
|
+
redirectToLogin();
|
|
565
|
+
}
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
569
|
+
if (currentSession.expires_at <= now) {
|
|
570
|
+
const { data, error: refreshError } = await authClient.refreshSession();
|
|
571
|
+
if (!isMounted) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
if (refreshError || !data.session) {
|
|
575
|
+
if (loginUrl) {
|
|
576
|
+
redirectToLogin();
|
|
577
|
+
}
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
const { error: userError } = await authClient.fetchUserInfo();
|
|
582
|
+
if (!isMounted) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
if (userError) {
|
|
586
|
+
const { data, error: refreshError } = await authClient.refreshSession();
|
|
587
|
+
if (!isMounted) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
if (refreshError || !data.session) {
|
|
591
|
+
if (loginUrl) {
|
|
592
|
+
redirectToLogin();
|
|
593
|
+
}
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const { error: retryError } = await authClient.fetchUserInfo();
|
|
597
|
+
if (!isMounted) {
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (retryError && loginUrl) {
|
|
601
|
+
redirectToLogin();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
} catch (error2) {
|
|
605
|
+
if (isMounted && loginUrl) {
|
|
606
|
+
redirectToLogin();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
initializeAuth();
|
|
611
|
+
return () => {
|
|
612
|
+
isMounted = false;
|
|
613
|
+
};
|
|
614
|
+
}, [authClient, loginUrl, redirectToLogin]);
|
|
615
|
+
react.useEffect(() => {
|
|
616
|
+
if (!autoRefresh || !session || !session.expires_at) {
|
|
617
|
+
if (refreshTimerRef.current) {
|
|
618
|
+
clearInterval(refreshTimerRef.current);
|
|
619
|
+
refreshTimerRef.current = null;
|
|
620
|
+
}
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if (refreshTimerRef.current) {
|
|
624
|
+
clearInterval(refreshTimerRef.current);
|
|
625
|
+
}
|
|
626
|
+
const checkAndRefresh = () => {
|
|
627
|
+
refreshTokenIfNeeded();
|
|
628
|
+
};
|
|
629
|
+
checkAndRefresh();
|
|
630
|
+
refreshTimerRef.current = setInterval(checkAndRefresh, 3e4);
|
|
631
|
+
return () => {
|
|
632
|
+
if (refreshTimerRef.current) {
|
|
633
|
+
clearInterval(refreshTimerRef.current);
|
|
634
|
+
refreshTimerRef.current = null;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
}, [session, autoRefresh, refreshThreshold, refreshTokenIfNeeded]);
|
|
638
|
+
const signIn = react.useCallback(
|
|
639
|
+
async (email, password, orgId) => {
|
|
640
|
+
const result = await authClient.signIn(email, password, orgId);
|
|
641
|
+
if (result.data.session && !result.error && callbacks?.onSignIn) {
|
|
642
|
+
await callbacks.onSignIn(result.data.session);
|
|
643
|
+
}
|
|
644
|
+
return result;
|
|
645
|
+
},
|
|
646
|
+
[authClient, callbacks]
|
|
647
|
+
);
|
|
648
|
+
const signOut = react.useCallback(async () => {
|
|
649
|
+
const result = await authClient.signOut();
|
|
650
|
+
if (!result.error && callbacks?.onSignOut) {
|
|
651
|
+
await callbacks.onSignOut();
|
|
652
|
+
}
|
|
653
|
+
return result;
|
|
654
|
+
}, [authClient, callbacks]);
|
|
655
|
+
const contextValue = {
|
|
656
|
+
session,
|
|
657
|
+
user,
|
|
658
|
+
isLoading,
|
|
659
|
+
error,
|
|
660
|
+
isAuthenticated,
|
|
661
|
+
signIn,
|
|
662
|
+
signOut,
|
|
663
|
+
register: authClient.register.bind(authClient),
|
|
664
|
+
changePassword: authClient.changePassword.bind(authClient),
|
|
665
|
+
refreshSession: authClient.refreshSession.bind(authClient),
|
|
666
|
+
getAccessToken: authClient.getAccessToken.bind(authClient),
|
|
667
|
+
getRefreshToken: authClient.getRefreshToken.bind(authClient)
|
|
668
|
+
};
|
|
669
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value: contextValue, children });
|
|
670
|
+
}
|
|
671
|
+
function useAuth() {
|
|
672
|
+
const context = react.useContext(AuthContext);
|
|
673
|
+
if (!context) {
|
|
674
|
+
throw new Error("useAuth must be used within an AuthProvider");
|
|
675
|
+
}
|
|
676
|
+
return context;
|
|
677
|
+
}
|
|
437
678
|
var AuthenticatedBaseService = class {
|
|
438
679
|
constructor(authClient, instanceUrl) {
|
|
439
680
|
this.authClient = authClient;
|
|
@@ -559,7 +800,9 @@ var AuthenticatedBaseService = class {
|
|
|
559
800
|
};
|
|
560
801
|
|
|
561
802
|
exports.AuthClient = AuthClient;
|
|
803
|
+
exports.AuthProvider = AuthProvider;
|
|
562
804
|
exports.AuthenticatedBaseService = AuthenticatedBaseService;
|
|
563
805
|
exports.createAuthStore = createAuthStore;
|
|
806
|
+
exports.useAuth = useAuth;
|
|
564
807
|
//# sourceMappingURL=index.js.map
|
|
565
808
|
//# sourceMappingURL=index.js.map
|