@pubflow/react 0.2.1 → 0.3.1
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.cjs +271 -256
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +271 -257
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createStorageKey, initConfig, ApiClient, AuthService, BridgeApiService, validateWithSchema, FilterOperator } from '@pubflow/core';
|
|
2
2
|
export * from '@pubflow/core';
|
|
3
3
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
4
|
-
import React, { createContext, useState,
|
|
4
|
+
import React, { createContext, useState, useCallback, useEffect, useContext } from 'react';
|
|
5
5
|
import useSWR, { SWRConfig, useSWRConfig } from 'swr';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -208,67 +208,36 @@ const PubflowContext = createContext({
|
|
|
208
208
|
defaultInstance: 'default'
|
|
209
209
|
});
|
|
210
210
|
/**
|
|
211
|
-
* Pubflow
|
|
211
|
+
* Pubflow Provider Component
|
|
212
212
|
*/
|
|
213
|
-
function PubflowProvider({ children, config, instances, defaultInstance = 'default',
|
|
214
|
-
const [isInitialized, setIsInitialized] = useState(false);
|
|
213
|
+
function PubflowProvider({ children, config, instances, defaultInstance = 'default', enableDebugTools = false, showSessionAlerts = false, persistentCache = { enabled: false }, theme = {}, loginRedirectPath = '/login', publicPaths = [] }) {
|
|
215
214
|
const [contextValue, setContextValue] = useState({
|
|
216
215
|
instances: {},
|
|
217
216
|
defaultInstance
|
|
218
217
|
});
|
|
219
|
-
//
|
|
220
|
-
useEffect(() => {
|
|
221
|
-
if (enableDebugTools) {
|
|
222
|
-
console.log('Pubflow debug tools enabled');
|
|
223
|
-
// Add debug utilities to window object
|
|
224
|
-
if (typeof window !== 'undefined') {
|
|
225
|
-
window.pubflowDebug = {
|
|
226
|
-
getInstances: () => contextValue.instances,
|
|
227
|
-
getDefaultInstance: () => contextValue.defaultInstance,
|
|
228
|
-
clearStorage: async () => {
|
|
229
|
-
const storage = new BrowserStorageAdapter();
|
|
230
|
-
await storage.removeItem('pubflow_session_id');
|
|
231
|
-
await storage.removeItem('pubflow_user_data');
|
|
232
|
-
console.log('Pubflow storage cleared');
|
|
233
|
-
},
|
|
234
|
-
loginRedirectPath,
|
|
235
|
-
publicPaths,
|
|
236
|
-
theme
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}, [enableDebugTools]); // ✅ OPTIMIZED: Only enableDebugTools as dependency
|
|
241
|
-
// Handle session expiration
|
|
218
|
+
// Session handlers
|
|
242
219
|
const handleSessionExpired = useCallback(() => {
|
|
243
|
-
if (showSessionAlerts) {
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
if (onSessionExpired) {
|
|
247
|
-
onSessionExpired();
|
|
220
|
+
if (showSessionAlerts && typeof window !== 'undefined') {
|
|
221
|
+
console.warn('Session expired');
|
|
248
222
|
}
|
|
249
|
-
}, [
|
|
250
|
-
// Handle session refresh
|
|
223
|
+
}, [showSessionAlerts]);
|
|
251
224
|
const handleSessionRefreshed = useCallback(() => {
|
|
252
|
-
if (showSessionAlerts) {
|
|
253
|
-
|
|
225
|
+
if (showSessionAlerts && typeof window !== 'undefined') {
|
|
226
|
+
console.log('Session refreshed');
|
|
254
227
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
}, [onSessionRefreshed, showSessionAlerts]);
|
|
228
|
+
}, [showSessionAlerts]);
|
|
229
|
+
// Initialize instances
|
|
259
230
|
useEffect(() => {
|
|
260
231
|
let isMounted = true;
|
|
261
232
|
const initialize = async () => {
|
|
262
233
|
var _a, _b;
|
|
263
234
|
try {
|
|
264
|
-
// Initialize instances
|
|
265
235
|
const instancesMap = {};
|
|
266
236
|
if (instances && instances.length > 0) {
|
|
267
237
|
// Initialize multiple instances
|
|
268
238
|
for (const instanceConfig of instances) {
|
|
269
239
|
if (!isMounted)
|
|
270
|
-
return;
|
|
271
|
-
// Initialize configuration
|
|
240
|
+
return;
|
|
272
241
|
const fullConfig = initConfig({
|
|
273
242
|
...instanceConfig,
|
|
274
243
|
sessionConfig: {
|
|
@@ -277,38 +246,21 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
277
246
|
onSessionRefreshed: handleSessionRefreshed
|
|
278
247
|
}
|
|
279
248
|
}, instanceConfig.id);
|
|
280
|
-
// Create storage adapter
|
|
281
249
|
const storage = new BrowserStorageAdapter({
|
|
282
250
|
prefix: (_a = fullConfig.storageConfig) === null || _a === void 0 ? void 0 : _a.prefix
|
|
283
251
|
});
|
|
284
|
-
// Create API client
|
|
285
252
|
const apiClient = new ApiClient(fullConfig, storage);
|
|
286
|
-
// Create auth service
|
|
287
253
|
const authService = new AuthService(apiClient, storage, fullConfig);
|
|
288
|
-
// Get current user (
|
|
254
|
+
// Get current user (non-blocking)
|
|
289
255
|
let user = null;
|
|
290
256
|
let isAuthenticated = false;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
[instanceConfig.id]: {
|
|
299
|
-
...prev.instances[instanceConfig.id],
|
|
300
|
-
user: currentUser,
|
|
301
|
-
isAuthenticated: true,
|
|
302
|
-
isLoading: false
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}));
|
|
306
|
-
}
|
|
307
|
-
}).catch(error => {
|
|
308
|
-
console.error(`Error getting current user for instance ${instanceConfig.id}:`, error);
|
|
309
|
-
});
|
|
310
|
-
// Create instance with optimized functions
|
|
311
|
-
const createInstanceFunctions = (id) => ({
|
|
257
|
+
instancesMap[instanceConfig.id] = {
|
|
258
|
+
config: fullConfig,
|
|
259
|
+
apiClient,
|
|
260
|
+
authService,
|
|
261
|
+
user,
|
|
262
|
+
isAuthenticated,
|
|
263
|
+
isLoading: true,
|
|
312
264
|
login: async (credentials) => {
|
|
313
265
|
const result = await authService.login(credentials);
|
|
314
266
|
if (result.success && result.user && isMounted) {
|
|
@@ -316,10 +268,11 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
316
268
|
...prev,
|
|
317
269
|
instances: {
|
|
318
270
|
...prev.instances,
|
|
319
|
-
[id]: {
|
|
320
|
-
...prev.instances[id],
|
|
271
|
+
[instanceConfig.id]: {
|
|
272
|
+
...prev.instances[instanceConfig.id],
|
|
321
273
|
user: result.user,
|
|
322
|
-
isAuthenticated: true
|
|
274
|
+
isAuthenticated: true,
|
|
275
|
+
isLoading: false
|
|
323
276
|
}
|
|
324
277
|
}
|
|
325
278
|
}));
|
|
@@ -333,10 +286,11 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
333
286
|
...prev,
|
|
334
287
|
instances: {
|
|
335
288
|
...prev.instances,
|
|
336
|
-
[id]: {
|
|
337
|
-
...prev.instances[id],
|
|
289
|
+
[instanceConfig.id]: {
|
|
290
|
+
...prev.instances[instanceConfig.id],
|
|
338
291
|
user: null,
|
|
339
|
-
isAuthenticated: false
|
|
292
|
+
isAuthenticated: false,
|
|
293
|
+
isLoading: false
|
|
340
294
|
}
|
|
341
295
|
}
|
|
342
296
|
}));
|
|
@@ -349,31 +303,52 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
349
303
|
...prev,
|
|
350
304
|
instances: {
|
|
351
305
|
...prev.instances,
|
|
352
|
-
[id]: {
|
|
353
|
-
...prev.instances[id],
|
|
306
|
+
[instanceConfig.id]: {
|
|
307
|
+
...prev.instances[instanceConfig.id],
|
|
354
308
|
user: result.user || null,
|
|
355
|
-
isAuthenticated: result.isValid
|
|
309
|
+
isAuthenticated: result.isValid,
|
|
310
|
+
isLoading: false
|
|
356
311
|
}
|
|
357
312
|
}
|
|
358
313
|
}));
|
|
359
314
|
}
|
|
360
315
|
return result;
|
|
361
316
|
}
|
|
362
|
-
});
|
|
363
|
-
instancesMap[instanceConfig.id] = {
|
|
364
|
-
config: fullConfig,
|
|
365
|
-
apiClient,
|
|
366
|
-
authService,
|
|
367
|
-
user,
|
|
368
|
-
isAuthenticated,
|
|
369
|
-
isLoading: true, // Start as loading
|
|
370
|
-
...createInstanceFunctions(instanceConfig.id)
|
|
371
317
|
};
|
|
318
|
+
// Load user asynchronously
|
|
319
|
+
authService.getCurrentUser().then(currentUser => {
|
|
320
|
+
if (isMounted) {
|
|
321
|
+
setContextValue(prev => ({
|
|
322
|
+
...prev,
|
|
323
|
+
instances: {
|
|
324
|
+
...prev.instances,
|
|
325
|
+
[instanceConfig.id]: {
|
|
326
|
+
...prev.instances[instanceConfig.id],
|
|
327
|
+
user: currentUser,
|
|
328
|
+
isAuthenticated: !!currentUser,
|
|
329
|
+
isLoading: false
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}));
|
|
333
|
+
}
|
|
334
|
+
}).catch(() => {
|
|
335
|
+
if (isMounted) {
|
|
336
|
+
setContextValue(prev => ({
|
|
337
|
+
...prev,
|
|
338
|
+
instances: {
|
|
339
|
+
...prev.instances,
|
|
340
|
+
[instanceConfig.id]: {
|
|
341
|
+
...prev.instances[instanceConfig.id],
|
|
342
|
+
isLoading: false
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}));
|
|
346
|
+
}
|
|
347
|
+
});
|
|
372
348
|
}
|
|
373
349
|
}
|
|
374
350
|
else if (config) {
|
|
375
|
-
//
|
|
376
|
-
// Initialize configuration
|
|
351
|
+
// Single instance mode (simplified)
|
|
377
352
|
const fullConfig = initConfig({
|
|
378
353
|
...config,
|
|
379
354
|
sessionConfig: {
|
|
@@ -381,37 +356,22 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
381
356
|
onSessionExpired: handleSessionExpired,
|
|
382
357
|
onSessionRefreshed: handleSessionRefreshed
|
|
383
358
|
}
|
|
384
|
-
}, defaultInstance);
|
|
385
|
-
// Create storage adapter
|
|
359
|
+
}, config.id || defaultInstance);
|
|
386
360
|
const storage = new BrowserStorageAdapter({
|
|
387
361
|
prefix: (_b = fullConfig.storageConfig) === null || _b === void 0 ? void 0 : _b.prefix
|
|
388
362
|
});
|
|
389
|
-
// Create API client
|
|
390
363
|
const apiClient = new ApiClient(fullConfig, storage);
|
|
391
|
-
// Create auth service
|
|
392
364
|
const authService = new AuthService(apiClient, storage, fullConfig);
|
|
393
|
-
// Get current user
|
|
394
|
-
let user = null;
|
|
395
|
-
let isAuthenticated = false;
|
|
396
|
-
try {
|
|
397
|
-
user = await authService.getCurrentUser();
|
|
398
|
-
isAuthenticated = !!user;
|
|
399
|
-
}
|
|
400
|
-
catch (error) {
|
|
401
|
-
console.error('Error getting current user:', error);
|
|
402
|
-
}
|
|
403
|
-
// Create instance
|
|
404
365
|
instancesMap[defaultInstance] = {
|
|
405
366
|
config: fullConfig,
|
|
406
367
|
apiClient,
|
|
407
368
|
authService,
|
|
408
|
-
user,
|
|
409
|
-
isAuthenticated,
|
|
410
|
-
isLoading:
|
|
369
|
+
user: null,
|
|
370
|
+
isAuthenticated: false,
|
|
371
|
+
isLoading: true,
|
|
411
372
|
login: async (credentials) => {
|
|
412
373
|
const result = await authService.login(credentials);
|
|
413
|
-
if (result.success && result.user) {
|
|
414
|
-
// Update instance
|
|
374
|
+
if (result.success && result.user && isMounted) {
|
|
415
375
|
setContextValue(prev => ({
|
|
416
376
|
...prev,
|
|
417
377
|
instances: {
|
|
@@ -419,7 +379,8 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
419
379
|
[defaultInstance]: {
|
|
420
380
|
...prev.instances[defaultInstance],
|
|
421
381
|
user: result.user,
|
|
422
|
-
isAuthenticated: true
|
|
382
|
+
isAuthenticated: true,
|
|
383
|
+
isLoading: false
|
|
423
384
|
}
|
|
424
385
|
}
|
|
425
386
|
}));
|
|
@@ -428,65 +389,107 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
428
389
|
},
|
|
429
390
|
logout: async () => {
|
|
430
391
|
await authService.logout();
|
|
431
|
-
|
|
392
|
+
if (isMounted) {
|
|
393
|
+
setContextValue(prev => ({
|
|
394
|
+
...prev,
|
|
395
|
+
instances: {
|
|
396
|
+
...prev.instances,
|
|
397
|
+
[defaultInstance]: {
|
|
398
|
+
...prev.instances[defaultInstance],
|
|
399
|
+
user: null,
|
|
400
|
+
isAuthenticated: false,
|
|
401
|
+
isLoading: false
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
validateSession: async () => {
|
|
408
|
+
const result = await authService.validateSession();
|
|
409
|
+
if (isMounted) {
|
|
410
|
+
setContextValue(prev => ({
|
|
411
|
+
...prev,
|
|
412
|
+
instances: {
|
|
413
|
+
...prev.instances,
|
|
414
|
+
[defaultInstance]: {
|
|
415
|
+
...prev.instances[defaultInstance],
|
|
416
|
+
user: result.user || null,
|
|
417
|
+
isAuthenticated: result.isValid,
|
|
418
|
+
isLoading: false
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
return result;
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
// Load user asynchronously
|
|
427
|
+
authService.getCurrentUser().then(currentUser => {
|
|
428
|
+
if (isMounted) {
|
|
432
429
|
setContextValue(prev => ({
|
|
433
430
|
...prev,
|
|
434
431
|
instances: {
|
|
435
432
|
...prev.instances,
|
|
436
433
|
[defaultInstance]: {
|
|
437
434
|
...prev.instances[defaultInstance],
|
|
438
|
-
user:
|
|
439
|
-
isAuthenticated:
|
|
435
|
+
user: currentUser,
|
|
436
|
+
isAuthenticated: !!currentUser,
|
|
437
|
+
isLoading: false
|
|
440
438
|
}
|
|
441
439
|
}
|
|
442
440
|
}));
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
// Update instance
|
|
441
|
+
}
|
|
442
|
+
}).catch(() => {
|
|
443
|
+
if (isMounted) {
|
|
447
444
|
setContextValue(prev => ({
|
|
448
445
|
...prev,
|
|
449
446
|
instances: {
|
|
450
447
|
...prev.instances,
|
|
451
448
|
[defaultInstance]: {
|
|
452
449
|
...prev.instances[defaultInstance],
|
|
453
|
-
|
|
454
|
-
isAuthenticated: result.isValid
|
|
450
|
+
isLoading: false
|
|
455
451
|
}
|
|
456
452
|
}
|
|
457
453
|
}));
|
|
458
|
-
return result;
|
|
459
454
|
}
|
|
460
|
-
};
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
if (isMounted) {
|
|
458
|
+
setContextValue({
|
|
459
|
+
instances: instancesMap,
|
|
460
|
+
defaultInstance
|
|
461
|
+
});
|
|
461
462
|
}
|
|
462
|
-
// Set context value
|
|
463
|
-
setContextValue({
|
|
464
|
-
instances: instancesMap,
|
|
465
|
-
defaultInstance
|
|
466
|
-
});
|
|
467
|
-
// Set initialized
|
|
468
|
-
setIsInitialized(true);
|
|
469
463
|
}
|
|
470
464
|
catch (error) {
|
|
471
465
|
console.error('Error initializing Pubflow:', error);
|
|
472
466
|
}
|
|
473
467
|
};
|
|
474
468
|
initialize();
|
|
475
|
-
// Cleanup function
|
|
476
469
|
return () => {
|
|
477
470
|
isMounted = false;
|
|
478
471
|
};
|
|
479
472
|
}, [config, instances, defaultInstance, handleSessionExpired, handleSessionRefreshed]);
|
|
480
|
-
//
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
473
|
+
// Debug tools (simplified)
|
|
474
|
+
useEffect(() => {
|
|
475
|
+
if (enableDebugTools && typeof window !== 'undefined') {
|
|
476
|
+
window.pubflowDebug = {
|
|
477
|
+
getInstances: () => contextValue.instances,
|
|
478
|
+
getDefaultInstance: () => contextValue.defaultInstance
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
}, [enableDebugTools]);
|
|
482
|
+
// SWR configuration
|
|
483
|
+
const swrConfig = {
|
|
484
|
+
revalidateOnFocus: false,
|
|
485
|
+
revalidateOnReconnect: true,
|
|
486
|
+
...(persistentCache.enabled && {
|
|
487
|
+
provider: () => new Map(),
|
|
488
|
+
isOnline: () => true,
|
|
489
|
+
isVisible: () => true
|
|
490
|
+
})
|
|
491
|
+
};
|
|
492
|
+
return (jsx(PubflowContext.Provider, { value: contextValue, children: jsx(SWRConfig, { value: swrConfig, children: children }) }));
|
|
490
493
|
}
|
|
491
494
|
|
|
492
495
|
/**
|
|
@@ -502,7 +505,6 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
502
505
|
*/
|
|
503
506
|
function useAuth(instanceId) {
|
|
504
507
|
const context = useContext(PubflowContext);
|
|
505
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
506
508
|
if (!context) {
|
|
507
509
|
throw new Error('useAuth must be used within a PubflowProvider');
|
|
508
510
|
}
|
|
@@ -511,68 +513,14 @@ function useAuth(instanceId) {
|
|
|
511
513
|
if (!pubflowInstance) {
|
|
512
514
|
throw new Error(`Pubflow instance '${instance}' not found`);
|
|
513
515
|
}
|
|
514
|
-
// Wrap login to handle loading state
|
|
515
|
-
const login = useCallback(async (credentials) => {
|
|
516
|
-
setIsLoading(true);
|
|
517
|
-
try {
|
|
518
|
-
return await pubflowInstance.login(credentials);
|
|
519
|
-
}
|
|
520
|
-
finally {
|
|
521
|
-
setIsLoading(false);
|
|
522
|
-
}
|
|
523
|
-
}, [pubflowInstance]);
|
|
524
|
-
// Wrap logout to handle loading state
|
|
525
|
-
const logout = useCallback(async () => {
|
|
526
|
-
setIsLoading(true);
|
|
527
|
-
try {
|
|
528
|
-
await pubflowInstance.logout();
|
|
529
|
-
}
|
|
530
|
-
finally {
|
|
531
|
-
setIsLoading(false);
|
|
532
|
-
}
|
|
533
|
-
}, [pubflowInstance]);
|
|
534
|
-
// Wrap validateSession to handle loading state
|
|
535
|
-
const validateSession = useCallback(async () => {
|
|
536
|
-
setIsLoading(true);
|
|
537
|
-
try {
|
|
538
|
-
return await pubflowInstance.validateSession();
|
|
539
|
-
}
|
|
540
|
-
finally {
|
|
541
|
-
setIsLoading(false);
|
|
542
|
-
}
|
|
543
|
-
}, [pubflowInstance]);
|
|
544
|
-
// Add refreshUser function to manually refresh user data
|
|
545
|
-
const refreshUser = useCallback(async () => {
|
|
546
|
-
setIsLoading(true);
|
|
547
|
-
try {
|
|
548
|
-
const result = await pubflowInstance.validateSession();
|
|
549
|
-
return result.user || null;
|
|
550
|
-
}
|
|
551
|
-
finally {
|
|
552
|
-
setIsLoading(false);
|
|
553
|
-
}
|
|
554
|
-
}, [pubflowInstance]);
|
|
555
|
-
// Validate session on mount
|
|
556
|
-
useEffect(() => {
|
|
557
|
-
const validate = async () => {
|
|
558
|
-
try {
|
|
559
|
-
await validateSession();
|
|
560
|
-
}
|
|
561
|
-
catch (error) {
|
|
562
|
-
console.error('Error validating session:', error);
|
|
563
|
-
}
|
|
564
|
-
};
|
|
565
|
-
validate();
|
|
566
|
-
}, [validateSession]);
|
|
567
516
|
return {
|
|
568
517
|
// Ensure user is never undefined
|
|
569
518
|
user: pubflowInstance.user || null,
|
|
570
519
|
isAuthenticated: pubflowInstance.isAuthenticated,
|
|
571
|
-
isLoading,
|
|
572
|
-
login,
|
|
573
|
-
logout,
|
|
574
|
-
validateSession
|
|
575
|
-
refreshUser
|
|
520
|
+
isLoading: pubflowInstance.isLoading,
|
|
521
|
+
login: pubflowInstance.login,
|
|
522
|
+
logout: pubflowInstance.logout,
|
|
523
|
+
validateSession: pubflowInstance.validateSession
|
|
576
524
|
};
|
|
577
525
|
}
|
|
578
526
|
|
|
@@ -9582,6 +9530,131 @@ function createStyles(theme) {
|
|
|
9582
9530
|
};
|
|
9583
9531
|
}
|
|
9584
9532
|
|
|
9533
|
+
/**
|
|
9534
|
+
* Authentication Guard Hook for React
|
|
9535
|
+
*
|
|
9536
|
+
* Framework-agnostic hook for handling authentication validation and redirects
|
|
9537
|
+
*/
|
|
9538
|
+
/**
|
|
9539
|
+
* Hook for handling authentication validation and redirects
|
|
9540
|
+
*
|
|
9541
|
+
* This hook is framework-agnostic and requires the user to provide
|
|
9542
|
+
* their own redirect function (e.g., Next.js router, React Router, etc.)
|
|
9543
|
+
*
|
|
9544
|
+
* @param options Hook options
|
|
9545
|
+
* @returns Authentication guard result
|
|
9546
|
+
*/
|
|
9547
|
+
function useAuthGuard({ validateOnMount = true, allowedTypes = ['authenticated'], instanceId, onRedirect, onSessionExpired, loginRedirectPath = '/login', accessDeniedPath = '/access-denied', enableLogging = false } = {}) {
|
|
9548
|
+
const { user, isAuthenticated, isLoading, validateSession } = useAuth(instanceId);
|
|
9549
|
+
// Check if user is authorized based on user type
|
|
9550
|
+
const isAuthorized = useCallback(() => {
|
|
9551
|
+
if (!isAuthenticated || !user) {
|
|
9552
|
+
return false;
|
|
9553
|
+
}
|
|
9554
|
+
// If allowedTypes includes 'authenticated', any authenticated user is allowed
|
|
9555
|
+
if (allowedTypes.includes('authenticated')) {
|
|
9556
|
+
return true;
|
|
9557
|
+
}
|
|
9558
|
+
// Check specific user types
|
|
9559
|
+
const userType = user.userType || user.user_type || '';
|
|
9560
|
+
return allowedTypes.some(type => type.toLowerCase() === userType.toLowerCase());
|
|
9561
|
+
}, [isAuthenticated, user, allowedTypes]);
|
|
9562
|
+
const authorized = isAuthorized();
|
|
9563
|
+
// Determine redirect reason
|
|
9564
|
+
const getRedirectReason = useCallback(() => {
|
|
9565
|
+
if (isLoading) {
|
|
9566
|
+
return null;
|
|
9567
|
+
}
|
|
9568
|
+
if (!isAuthenticated) {
|
|
9569
|
+
return 'unauthenticated';
|
|
9570
|
+
}
|
|
9571
|
+
if (!authorized) {
|
|
9572
|
+
return 'unauthorized';
|
|
9573
|
+
}
|
|
9574
|
+
return null;
|
|
9575
|
+
}, [isLoading, isAuthenticated, authorized]);
|
|
9576
|
+
const redirectReason = getRedirectReason();
|
|
9577
|
+
// Validate session on mount
|
|
9578
|
+
useEffect(() => {
|
|
9579
|
+
if (validateOnMount && isAuthenticated) {
|
|
9580
|
+
validateSession().then(({ isValid }) => {
|
|
9581
|
+
if (!isValid) {
|
|
9582
|
+
if (enableLogging) {
|
|
9583
|
+
console.warn('useAuthGuard: Session validation failed');
|
|
9584
|
+
}
|
|
9585
|
+
// Call session expired handler
|
|
9586
|
+
if (onSessionExpired) {
|
|
9587
|
+
onSessionExpired();
|
|
9588
|
+
}
|
|
9589
|
+
// Redirect to login
|
|
9590
|
+
if (onRedirect) {
|
|
9591
|
+
onRedirect(loginRedirectPath, 'session-expired');
|
|
9592
|
+
}
|
|
9593
|
+
}
|
|
9594
|
+
}).catch(error => {
|
|
9595
|
+
if (enableLogging) {
|
|
9596
|
+
console.error('useAuthGuard: Session validation error:', error);
|
|
9597
|
+
}
|
|
9598
|
+
});
|
|
9599
|
+
}
|
|
9600
|
+
}, [validateOnMount, isAuthenticated, validateSession, onSessionExpired, onRedirect, loginRedirectPath, enableLogging]);
|
|
9601
|
+
// Handle authentication redirects
|
|
9602
|
+
useEffect(() => {
|
|
9603
|
+
if (isLoading || !onRedirect) {
|
|
9604
|
+
return;
|
|
9605
|
+
}
|
|
9606
|
+
if (!isAuthenticated) {
|
|
9607
|
+
if (enableLogging) {
|
|
9608
|
+
console.warn('useAuthGuard: User not authenticated, redirecting to login');
|
|
9609
|
+
}
|
|
9610
|
+
onRedirect(loginRedirectPath, 'unauthenticated');
|
|
9611
|
+
return;
|
|
9612
|
+
}
|
|
9613
|
+
if (!authorized) {
|
|
9614
|
+
if (enableLogging) {
|
|
9615
|
+
console.warn('useAuthGuard: User not authorized for this page, redirecting to access denied');
|
|
9616
|
+
}
|
|
9617
|
+
onRedirect(accessDeniedPath, 'unauthorized');
|
|
9618
|
+
return;
|
|
9619
|
+
}
|
|
9620
|
+
}, [isLoading, isAuthenticated, authorized, onRedirect, loginRedirectPath, accessDeniedPath, enableLogging]);
|
|
9621
|
+
return {
|
|
9622
|
+
user,
|
|
9623
|
+
isAuthenticated,
|
|
9624
|
+
isLoading,
|
|
9625
|
+
isAuthorized: authorized,
|
|
9626
|
+
validateSession,
|
|
9627
|
+
redirectReason
|
|
9628
|
+
};
|
|
9629
|
+
}
|
|
9630
|
+
/**
|
|
9631
|
+
* Simple authentication guard hook with automatic redirects
|
|
9632
|
+
*
|
|
9633
|
+
* This is a simplified version that uses window.location for redirects
|
|
9634
|
+
* Suitable for simple React apps without complex routing
|
|
9635
|
+
*
|
|
9636
|
+
* @param options Hook options
|
|
9637
|
+
* @returns Authentication guard result
|
|
9638
|
+
*/
|
|
9639
|
+
function useSimpleAuthGuard(options = {}) {
|
|
9640
|
+
var _a;
|
|
9641
|
+
const handleRedirect = useCallback((path, reason) => {
|
|
9642
|
+
if (typeof window !== 'undefined') {
|
|
9643
|
+
// Add current path as redirect parameter
|
|
9644
|
+
const currentPath = window.location.pathname + window.location.search;
|
|
9645
|
+
const redirectUrl = reason === 'unauthenticated'
|
|
9646
|
+
? `${path}?redirect=${encodeURIComponent(currentPath)}`
|
|
9647
|
+
: path;
|
|
9648
|
+
window.location.href = redirectUrl;
|
|
9649
|
+
}
|
|
9650
|
+
}, []);
|
|
9651
|
+
return useAuthGuard({
|
|
9652
|
+
...options,
|
|
9653
|
+
onRedirect: handleRedirect,
|
|
9654
|
+
enableLogging: (_a = options.enableLogging) !== null && _a !== void 0 ? _a : true
|
|
9655
|
+
});
|
|
9656
|
+
}
|
|
9657
|
+
|
|
9585
9658
|
/**
|
|
9586
9659
|
* Bridge API Raw Hook for React
|
|
9587
9660
|
*
|
|
@@ -9661,65 +9734,6 @@ function useBridgeApiRaw(instanceId) {
|
|
|
9661
9734
|
};
|
|
9662
9735
|
}
|
|
9663
9736
|
|
|
9664
|
-
/**
|
|
9665
|
-
* Server Authentication Hook for React
|
|
9666
|
-
*
|
|
9667
|
-
* Provides a hook for handling authentication with automatic redirects
|
|
9668
|
-
*/
|
|
9669
|
-
/**
|
|
9670
|
-
* Hook for handling authentication with automatic redirects
|
|
9671
|
-
*
|
|
9672
|
-
* @param options Hook options
|
|
9673
|
-
* @returns Authentication hook result
|
|
9674
|
-
*/
|
|
9675
|
-
function useServerAuth({ loginRedirectPath = '/login', allowedTypes = ['authenticated'], validateOnMount = true, instanceId, onRedirect } = {}) {
|
|
9676
|
-
const { user, isAuthenticated, isLoading, validateSession } = useAuth(instanceId);
|
|
9677
|
-
// Default redirect function
|
|
9678
|
-
const defaultRedirect = (path) => {
|
|
9679
|
-
if (typeof window !== 'undefined') {
|
|
9680
|
-
const currentPath = window.location.pathname;
|
|
9681
|
-
const redirectUrl = `${path}?redirect=${encodeURIComponent(currentPath)}`;
|
|
9682
|
-
window.location.href = redirectUrl;
|
|
9683
|
-
}
|
|
9684
|
-
};
|
|
9685
|
-
const redirect = onRedirect || defaultRedirect;
|
|
9686
|
-
useEffect(() => {
|
|
9687
|
-
// Validate session on mount if configured
|
|
9688
|
-
if (validateOnMount) {
|
|
9689
|
-
validateSession().then(({ isValid }) => {
|
|
9690
|
-
if (!isValid) {
|
|
9691
|
-
redirect(loginRedirectPath);
|
|
9692
|
-
}
|
|
9693
|
-
});
|
|
9694
|
-
}
|
|
9695
|
-
}, [validateOnMount, loginRedirectPath, validateSession, redirect]);
|
|
9696
|
-
useEffect(() => {
|
|
9697
|
-
// Skip if still loading
|
|
9698
|
-
if (isLoading) {
|
|
9699
|
-
return;
|
|
9700
|
-
}
|
|
9701
|
-
// Redirect if not authenticated
|
|
9702
|
-
if (!isAuthenticated) {
|
|
9703
|
-
redirect(loginRedirectPath);
|
|
9704
|
-
return;
|
|
9705
|
-
}
|
|
9706
|
-
// Check user type if allowedTypes doesn't include 'authenticated'
|
|
9707
|
-
if (!allowedTypes.includes('authenticated') && user) {
|
|
9708
|
-
const userType = user.userType || '';
|
|
9709
|
-
const isAllowed = allowedTypes.some(type => type.toLowerCase() === userType.toLowerCase());
|
|
9710
|
-
if (!isAllowed) {
|
|
9711
|
-
redirect('/access-denied');
|
|
9712
|
-
}
|
|
9713
|
-
}
|
|
9714
|
-
}, [isLoading, isAuthenticated, user, allowedTypes, loginRedirectPath, redirect]);
|
|
9715
|
-
return {
|
|
9716
|
-
user,
|
|
9717
|
-
isAuthenticated,
|
|
9718
|
-
isLoading,
|
|
9719
|
-
validateSession
|
|
9720
|
-
};
|
|
9721
|
-
}
|
|
9722
|
-
|
|
9723
9737
|
/**
|
|
9724
9738
|
* Search Query Builder Hook for React
|
|
9725
9739
|
*
|
|
@@ -9941,5 +9955,5 @@ function useRequireAuth(options = {}) {
|
|
|
9941
9955
|
};
|
|
9942
9956
|
}
|
|
9943
9957
|
|
|
9944
|
-
export { AccountCreationForm, AdvancedFilter, BridgeForm, BridgeList, BridgeTable, BridgeView, BrowserStorageAdapter, LoginForm, OfflineIndicator, PasswordResetForm, PubflowContext, PubflowProvider, ThemeProvider, createStyles, generateCSSVariables, useAuth, useBridgeApi, useBridgeApiRaw, useBridgeCrud, useBridgeMutation, useBridgeQuery, useNetworkStatus, useRequireAuth, useSearchQueryBuilder,
|
|
9958
|
+
export { AccountCreationForm, AdvancedFilter, BridgeForm, BridgeList, BridgeTable, BridgeView, BrowserStorageAdapter, LoginForm, OfflineIndicator, PasswordResetForm, PubflowContext, PubflowProvider, ThemeProvider, createStyles, generateCSSVariables, useAuth, useAuthGuard, useBridgeApi, useBridgeApiRaw, useBridgeCrud, useBridgeMutation, useBridgeQuery, useNetworkStatus, useRequireAuth, useSearchQueryBuilder, useSimpleAuthGuard, useTheme };
|
|
9945
9959
|
//# sourceMappingURL=index.esm.js.map
|