@jmruthers/pace-core 0.5.66 → 0.5.68
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 +26 -0
- package/dist/{DataTable-MFUXNGPR.js → DataTable-4IUY7BXB.js} +5 -5
- package/dist/{PublicLoadingSpinner-CXJ-W9wZ.d.ts → PublicLoadingSpinner-DdKXTkCZ.d.ts} +94 -1
- package/dist/{UnifiedAuthProvider-CQNiemcB.d.ts → UnifiedAuthProvider-D02AMXgO.d.ts} +3 -3
- package/dist/{chunk-VTJ5HCZB.js → chunk-IPCH4YPT.js} +2 -2
- package/dist/{chunk-QVEOQVD4.js → chunk-KRCRNXPD.js} +106 -14
- package/dist/chunk-KRCRNXPD.js.map +1 -0
- package/dist/{chunk-T2MQY57J.js → chunk-MOJXHWDE.js} +1 -1
- package/dist/{chunk-T2MQY57J.js.map → chunk-MOJXHWDE.js.map} +1 -1
- package/dist/{chunk-FVDOEGGG.js → chunk-NN45OBIS.js} +3 -3
- package/dist/{chunk-4HQ5BOVZ.js → chunk-OPCWH3A4.js} +3 -3
- package/dist/{chunk-CKNY7HYS.js → chunk-PXWEDX7Y.js} +2 -2
- package/dist/{chunk-PSE2XO4L.js → chunk-U6GPOF6J.js} +312 -264
- package/dist/chunk-U6GPOF6J.js.map +1 -0
- package/dist/{chunk-BTCA3ENN.js → chunk-UYA6U6H7.js} +4 -4
- package/dist/{chunk-C7GUF747.js → chunk-ZMS23NS5.js} +3 -3
- package/dist/{chunk-T6HVDA24.js → chunk-ZPG4XPV5.js} +2 -2
- package/dist/components.d.ts +3 -2
- package/dist/components.js +9 -7
- package/dist/components.js.map +1 -1
- package/dist/hooks.js +4 -4
- package/dist/index.d.ts +4 -3
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +3 -3
- package/dist/rbac/index.js +5 -5
- package/dist/utils.js +1 -1
- package/docs/api/README.md +26 -0
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +34 -0
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +4 -4
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +38 -4
- package/docs/api-reference/providers.md +16 -7
- package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +226 -0
- package/docs/security/README.md +5 -1
- package/package.json +2 -1
- package/src/components/Switch/Switch.test.tsx +438 -0
- package/src/components/Switch/Switch.tsx +140 -0
- package/src/components/Switch/index.ts +9 -0
- package/src/components/index.ts +2 -0
- package/src/hooks/public/usePublicEvent.ts +160 -13
- package/src/index.ts +2 -0
- package/src/providers/UnifiedAuthProvider.test.simple.tsx +42 -6
- package/src/providers/UnifiedAuthProvider.tsx +4 -4
- package/dist/chunk-PSE2XO4L.js.map +0 -1
- package/dist/chunk-QVEOQVD4.js.map +0 -1
- /package/dist/{DataTable-MFUXNGPR.js.map → DataTable-4IUY7BXB.js.map} +0 -0
- /package/dist/{chunk-VTJ5HCZB.js.map → chunk-IPCH4YPT.js.map} +0 -0
- /package/dist/{chunk-FVDOEGGG.js.map → chunk-NN45OBIS.js.map} +0 -0
- /package/dist/{chunk-4HQ5BOVZ.js.map → chunk-OPCWH3A4.js.map} +0 -0
- /package/dist/{chunk-CKNY7HYS.js.map → chunk-PXWEDX7Y.js.map} +0 -0
- /package/dist/{chunk-BTCA3ENN.js.map → chunk-UYA6U6H7.js.map} +0 -0
- /package/dist/{chunk-C7GUF747.js.map → chunk-ZMS23NS5.js.map} +0 -0
- /package/dist/{chunk-T6HVDA24.js.map → chunk-ZPG4XPV5.js.map} +0 -0
package/docs/api/modules.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
[@jmruthers/pace-core - v0.5.
|
|
1
|
+
[@jmruthers/pace-core - v0.5.68](README.md) / Exports
|
|
2
2
|
|
|
3
|
-
# @jmruthers/pace-core - v0.5.
|
|
3
|
+
# @jmruthers/pace-core - v0.5.68
|
|
4
4
|
|
|
5
5
|
**`File`**
|
|
6
6
|
|
|
@@ -73,6 +73,7 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
|
|
|
73
73
|
- [PublicPageFooterProps](interfaces/PublicPageFooterProps.md)
|
|
74
74
|
- [PublicPageHeaderProps](interfaces/PublicPageHeaderProps.md)
|
|
75
75
|
- [PublicPageLayoutProps](interfaces/PublicPageLayoutProps.md)
|
|
76
|
+
- [SwitchProps](interfaces/SwitchProps.md)
|
|
76
77
|
- [ToastProps](interfaces/ToastProps.md)
|
|
77
78
|
- [ToastActionElement](interfaces/ToastActionElement.md)
|
|
78
79
|
- [UserMenuProps](interfaces/UserMenuProps.md)
|
|
@@ -233,6 +234,7 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
|
|
|
233
234
|
- [SelectGroup](modules.md#selectgroup)
|
|
234
235
|
- [SelectLabel](modules.md#selectlabel)
|
|
235
236
|
- [SelectSeparator](modules.md#selectseparator)
|
|
237
|
+
- [Switch](modules.md#switch)
|
|
236
238
|
- [Table](modules.md#table)
|
|
237
239
|
- [TableHeader](modules.md#tableheader)
|
|
238
240
|
- [TableBody](modules.md#tablebody)
|
|
@@ -3035,6 +3037,38 @@ ___
|
|
|
3035
3037
|
|
|
3036
3038
|
___
|
|
3037
3039
|
|
|
3040
|
+
### Switch
|
|
3041
|
+
|
|
3042
|
+
▸ **Switch**(`props`): `ReactNode`
|
|
3043
|
+
|
|
3044
|
+
Switch component
|
|
3045
|
+
|
|
3046
|
+
A toggle switch for boolean states. Built on Radix UI for accessibility.
|
|
3047
|
+
|
|
3048
|
+
#### Parameters
|
|
3049
|
+
|
|
3050
|
+
| Name | Type |
|
|
3051
|
+
| :------ | :------ |
|
|
3052
|
+
| `props` | [`SwitchProps`](interfaces/SwitchProps.md) & `RefAttributes`\<`HTMLButtonElement`\> |
|
|
3053
|
+
|
|
3054
|
+
#### Returns
|
|
3055
|
+
|
|
3056
|
+
`ReactNode`
|
|
3057
|
+
|
|
3058
|
+
**`Component`**
|
|
3059
|
+
|
|
3060
|
+
**`Example`**
|
|
3061
|
+
|
|
3062
|
+
```tsx
|
|
3063
|
+
<Switch checked={isEnabled} onCheckedChange={setIsEnabled} />
|
|
3064
|
+
```
|
|
3065
|
+
|
|
3066
|
+
#### Defined in
|
|
3067
|
+
|
|
3068
|
+
[packages/core/src/components/Switch/Switch.tsx:97](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Switch/Switch.tsx#L97)
|
|
3069
|
+
|
|
3070
|
+
___
|
|
3071
|
+
|
|
3038
3072
|
### Table
|
|
3039
3073
|
|
|
3040
3074
|
▸ **Table**(`props`): `ReactNode`
|
|
@@ -3636,7 +3670,7 @@ Useful for testing or when you need to force refresh all data
|
|
|
3636
3670
|
|
|
3637
3671
|
#### Defined in
|
|
3638
3672
|
|
|
3639
|
-
[packages/core/src/hooks/public/usePublicEvent.ts:
|
|
3673
|
+
[packages/core/src/hooks/public/usePublicEvent.ts:391](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEvent.ts#L391)
|
|
3640
3674
|
|
|
3641
3675
|
___
|
|
3642
3676
|
|
|
@@ -3657,7 +3691,7 @@ Get cache statistics for debugging
|
|
|
3657
3691
|
|
|
3658
3692
|
#### Defined in
|
|
3659
3693
|
|
|
3660
|
-
[packages/core/src/hooks/public/usePublicEvent.ts:
|
|
3694
|
+
[packages/core/src/hooks/public/usePublicEvent.ts:402](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEvent.ts#L402)
|
|
3661
3695
|
|
|
3662
3696
|
___
|
|
3663
3697
|
|
|
@@ -18,10 +18,10 @@ interface UnifiedAuthProviderProps {
|
|
|
18
18
|
enableRBAC?: boolean;
|
|
19
19
|
onAuthStateChange?: (event: AuthChangeEvent, session: Session | null) => void;
|
|
20
20
|
|
|
21
|
-
// Inactivity auto-logout configuration
|
|
22
|
-
idleTimeoutMs
|
|
23
|
-
warnBeforeMs
|
|
24
|
-
onIdleLogout
|
|
21
|
+
// Inactivity auto-logout configuration - MANDATORY for security
|
|
22
|
+
idleTimeoutMs: number; // REQUIRED: Inactivity timeout in milliseconds
|
|
23
|
+
warnBeforeMs: number; // REQUIRED: Warning time before logout in milliseconds
|
|
24
|
+
onIdleLogout: (reason: 'inactivity') => void; // REQUIRED: App handles redirect/navigation
|
|
25
25
|
renderInactivityWarning?: (args: {
|
|
26
26
|
timeRemaining: number;
|
|
27
27
|
onStaySignedIn: () => void;
|
|
@@ -36,6 +36,7 @@ interface UnifiedAuthProviderProps {
|
|
|
36
36
|
```tsx
|
|
37
37
|
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
38
38
|
import { createClient } from '@supabase/supabase-js';
|
|
39
|
+
import { useNavigate } from 'react-router-dom';
|
|
39
40
|
|
|
40
41
|
const supabase = createClient(
|
|
41
42
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
@@ -43,12 +44,18 @@ const supabase = createClient(
|
|
|
43
44
|
);
|
|
44
45
|
|
|
45
46
|
function App() {
|
|
47
|
+
const navigate = useNavigate();
|
|
48
|
+
|
|
46
49
|
return (
|
|
47
50
|
<UnifiedAuthProvider
|
|
48
51
|
supabaseClient={supabase}
|
|
49
52
|
appName="my-app"
|
|
50
53
|
enableRBAC={true}
|
|
51
54
|
requireOrganisationContext={true}
|
|
55
|
+
// Required inactivity configuration
|
|
56
|
+
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
57
|
+
warnBeforeMs={5 * 60 * 1000} // 5 minutes warning
|
|
58
|
+
onIdleLogout={() => navigate('/login')}
|
|
52
59
|
>
|
|
53
60
|
<AppContent />
|
|
54
61
|
</UnifiedAuthProvider>
|
|
@@ -66,9 +73,9 @@ function App() {
|
|
|
66
73
|
| `requireOrganisationContext` | `boolean` | `true` | Require organisation context for security |
|
|
67
74
|
| `enableRBAC` | `boolean` | `false` | Enable the RBAC system |
|
|
68
75
|
| `onAuthStateChange` | `function` | `undefined` | Callback for auth state changes |
|
|
69
|
-
| `idleTimeoutMs` | `number` |
|
|
70
|
-
| `warnBeforeMs` | `number` |
|
|
71
|
-
| `onIdleLogout` | `function` |
|
|
76
|
+
| `idleTimeoutMs` | `number` | **Required** | Inactivity timeout in milliseconds (e.g., `30 * 60 * 1000` for 30 minutes) |
|
|
77
|
+
| `warnBeforeMs` | `number` | **Required** | Warning time before logout in milliseconds (e.g., `5 * 60 * 1000` for 5 minutes) |
|
|
78
|
+
| `onIdleLogout` | `function` | **Required** | Callback when user is logged out due to inactivity |
|
|
72
79
|
| `renderInactivityWarning` | `function` | `undefined` | Custom warning UI renderer |
|
|
73
80
|
| `dangerouslyDisableInactivity` | `boolean` | `false` | Dev-only: disable inactivity feature (not allowed in production) |
|
|
74
81
|
|
|
@@ -76,6 +83,8 @@ function App() {
|
|
|
76
83
|
|
|
77
84
|
The `UnifiedAuthProvider` includes built-in inactivity tracking that automatically logs out users after a period of inactivity for security purposes.
|
|
78
85
|
|
|
86
|
+
> **⚠️ Breaking Change**: As of version 0.5.65+, the inactivity timeout configuration (`idleTimeoutMs`, `warnBeforeMs`, `onIdleLogout`) is **mandatory** to prevent apps from accidentally bypassing auto-logout security features.
|
|
87
|
+
|
|
79
88
|
#### Features
|
|
80
89
|
|
|
81
90
|
- **Automatic logout** after 30 minutes of inactivity (configurable)
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# UnifiedAuthProvider Mandatory Timeouts Migration Guide
|
|
2
|
+
|
|
3
|
+
> **Version**: 0.5.65+
|
|
4
|
+
> **Breaking Change**: Yes
|
|
5
|
+
> **Migration Required**: Yes
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
As of version 0.5.65, the `UnifiedAuthProvider` now requires mandatory inactivity timeout configuration to prevent apps from accidentally bypassing auto-logout security features.
|
|
10
|
+
|
|
11
|
+
## What Changed
|
|
12
|
+
|
|
13
|
+
The following props are now **required** (previously optional):
|
|
14
|
+
|
|
15
|
+
- `idleTimeoutMs` - Inactivity timeout in milliseconds
|
|
16
|
+
- `warnBeforeMs` - Warning time before logout in milliseconds
|
|
17
|
+
- `onIdleLogout` - Callback when user is logged out due to inactivity
|
|
18
|
+
|
|
19
|
+
## Migration Steps
|
|
20
|
+
|
|
21
|
+
### 1. Update Your UnifiedAuthProvider
|
|
22
|
+
|
|
23
|
+
**Before (❌ Will now cause TypeScript errors):**
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
27
|
+
|
|
28
|
+
function App() {
|
|
29
|
+
return (
|
|
30
|
+
<UnifiedAuthProvider
|
|
31
|
+
supabaseClient={supabase}
|
|
32
|
+
appName="my-app"
|
|
33
|
+
enableRBAC={true}
|
|
34
|
+
>
|
|
35
|
+
<AppContent />
|
|
36
|
+
</UnifiedAuthProvider>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**After (✅ Required configuration):**
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
45
|
+
import { useNavigate } from 'react-router-dom';
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
const navigate = useNavigate();
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<UnifiedAuthProvider
|
|
52
|
+
supabaseClient={supabase}
|
|
53
|
+
appName="my-app"
|
|
54
|
+
enableRBAC={true}
|
|
55
|
+
// Required inactivity configuration
|
|
56
|
+
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
57
|
+
warnBeforeMs={5 * 60 * 1000} // 5 minutes warning
|
|
58
|
+
onIdleLogout={() => navigate('/login')}
|
|
59
|
+
>
|
|
60
|
+
<AppContent />
|
|
61
|
+
</UnifiedAuthProvider>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Choose Appropriate Timeouts
|
|
67
|
+
|
|
68
|
+
Select timeouts based on your security requirements:
|
|
69
|
+
|
|
70
|
+
#### High Security (Sensitive Data)
|
|
71
|
+
```tsx
|
|
72
|
+
idleTimeoutMs={15 * 60 * 1000} // 15 minutes
|
|
73
|
+
warnBeforeMs={2 * 60 * 1000} // 2 minutes warning
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Standard Security (Most Apps)
|
|
77
|
+
```tsx
|
|
78
|
+
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
79
|
+
warnBeforeMs={5 * 60 * 1000} // 5 minutes warning
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### User-Friendly (Low Security Risk)
|
|
83
|
+
```tsx
|
|
84
|
+
idleTimeoutMs={60 * 60 * 1000} // 1 hour
|
|
85
|
+
warnBeforeMs={10 * 60 * 1000} // 10 minutes warning
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Handle the Logout Callback
|
|
89
|
+
|
|
90
|
+
The `onIdleLogout` callback is called when the user is logged out due to inactivity. Implement appropriate navigation:
|
|
91
|
+
|
|
92
|
+
#### React Router
|
|
93
|
+
```tsx
|
|
94
|
+
import { useNavigate } from 'react-router-dom';
|
|
95
|
+
|
|
96
|
+
function App() {
|
|
97
|
+
const navigate = useNavigate();
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<UnifiedAuthProvider
|
|
101
|
+
// ... other props
|
|
102
|
+
onIdleLogout={() => {
|
|
103
|
+
console.log('User logged out due to inactivity');
|
|
104
|
+
navigate('/login', { replace: true });
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
<AppContent />
|
|
108
|
+
</UnifiedAuthProvider>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Next.js Router
|
|
114
|
+
```tsx
|
|
115
|
+
import { useRouter } from 'next/router';
|
|
116
|
+
|
|
117
|
+
function App() {
|
|
118
|
+
const router = useRouter();
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<UnifiedAuthProvider
|
|
122
|
+
// ... other props
|
|
123
|
+
onIdleLogout={() => {
|
|
124
|
+
console.log('User logged out due to inactivity');
|
|
125
|
+
router.push('/login');
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
<AppContent />
|
|
129
|
+
</UnifiedAuthProvider>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Window Location (Fallback)
|
|
135
|
+
```tsx
|
|
136
|
+
<UnifiedAuthProvider
|
|
137
|
+
// ... other props
|
|
138
|
+
onIdleLogout={() => {
|
|
139
|
+
console.log('User logged out due to inactivity');
|
|
140
|
+
window.location.href = '/login';
|
|
141
|
+
}}
|
|
142
|
+
>
|
|
143
|
+
<AppContent />
|
|
144
|
+
</UnifiedAuthProvider>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 4. Optional: Custom Warning UI
|
|
148
|
+
|
|
149
|
+
You can provide a custom inactivity warning modal:
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
<UnifiedAuthProvider
|
|
153
|
+
// ... other props
|
|
154
|
+
renderInactivityWarning={({ timeRemaining, onStaySignedIn, onSignOutNow }) => (
|
|
155
|
+
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
|
156
|
+
<div className="bg-white p-6 rounded-lg shadow-lg max-w-md">
|
|
157
|
+
<h3 className="text-lg font-semibold mb-4">Session Timeout Warning</h3>
|
|
158
|
+
<p className="mb-4">
|
|
159
|
+
You will be signed out in {Math.ceil(timeRemaining / 1000)} seconds due to inactivity.
|
|
160
|
+
</p>
|
|
161
|
+
<div className="flex gap-2">
|
|
162
|
+
<button
|
|
163
|
+
onClick={onStaySignedIn}
|
|
164
|
+
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
|
|
165
|
+
>
|
|
166
|
+
Stay Signed In
|
|
167
|
+
</button>
|
|
168
|
+
<button
|
|
169
|
+
onClick={onSignOutNow}
|
|
170
|
+
className="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"
|
|
171
|
+
>
|
|
172
|
+
Sign Out Now
|
|
173
|
+
</button>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
>
|
|
179
|
+
<AppContent />
|
|
180
|
+
</UnifiedAuthProvider>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Why This Change Was Made
|
|
184
|
+
|
|
185
|
+
1. **Security**: Prevents apps from accidentally bypassing auto-logout
|
|
186
|
+
2. **Explicit Configuration**: Forces developers to consciously choose timeout values
|
|
187
|
+
3. **Compliance**: Ensures security requirements are met by default
|
|
188
|
+
4. **Consistency**: All apps using pace-core will have proper session management
|
|
189
|
+
|
|
190
|
+
## Testing Your Migration
|
|
191
|
+
|
|
192
|
+
After updating your code:
|
|
193
|
+
|
|
194
|
+
1. **Login to your app**
|
|
195
|
+
2. **Wait for the warning** (should appear before the timeout)
|
|
196
|
+
3. **Don't interact with the app** for the full timeout period
|
|
197
|
+
4. **Verify you're logged out** and redirected to login
|
|
198
|
+
|
|
199
|
+
## Rollback (Not Recommended)
|
|
200
|
+
|
|
201
|
+
If you need to temporarily disable inactivity tracking (development only):
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<UnifiedAuthProvider
|
|
205
|
+
// ... other props
|
|
206
|
+
dangerouslyDisableInactivity={true} // Dev-only, not allowed in production
|
|
207
|
+
>
|
|
208
|
+
<AppContent />
|
|
209
|
+
</UnifiedAuthProvider>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
> **⚠️ Warning**: `dangerouslyDisableInactivity` is automatically disabled in production builds for security.
|
|
213
|
+
|
|
214
|
+
## Support
|
|
215
|
+
|
|
216
|
+
If you encounter issues during migration:
|
|
217
|
+
|
|
218
|
+
1. Check the [API Reference](../api-reference/providers.md) for complete documentation
|
|
219
|
+
2. Review the [Security Guide](../security/README.md) for best practices
|
|
220
|
+
3. Ensure all required props are provided with appropriate values
|
|
221
|
+
|
|
222
|
+
## Related Documentation
|
|
223
|
+
|
|
224
|
+
- [UnifiedAuthProvider API Reference](../api-reference/providers.md)
|
|
225
|
+
- [Security Best Practices](../security/README.md)
|
|
226
|
+
- [Inactivity Tracking Guide](../implementation-guides/inactivity-tracking.md)
|
package/docs/security/README.md
CHANGED
|
@@ -84,17 +84,21 @@ PACE Core includes built-in inactivity tracking for enhanced security:
|
|
|
84
84
|
|
|
85
85
|
```tsx
|
|
86
86
|
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
87
|
+
import { useNavigate } from 'react-router-dom';
|
|
87
88
|
|
|
88
89
|
function App() {
|
|
90
|
+
const navigate = useNavigate();
|
|
91
|
+
|
|
89
92
|
return (
|
|
90
93
|
<UnifiedAuthProvider
|
|
91
94
|
supabaseClient={supabaseClient}
|
|
92
95
|
appName="my-app"
|
|
96
|
+
// Required inactivity configuration for security
|
|
93
97
|
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
94
98
|
warnBeforeMs={60 * 1000} // 60 seconds warning
|
|
95
99
|
onIdleLogout={() => {
|
|
96
100
|
// Handle redirect to login page
|
|
97
|
-
|
|
101
|
+
navigate('/login', { replace: true });
|
|
98
102
|
}}
|
|
99
103
|
>
|
|
100
104
|
<YourApp />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmruthers/pace-core",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.68",
|
|
4
4
|
"description": "Clean, modern React component library with Tailwind v4 styling and native utilities",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -179,6 +179,7 @@
|
|
|
179
179
|
"@radix-ui/react-label": "^2.0.0",
|
|
180
180
|
"@radix-ui/react-progress": "^1.0.0",
|
|
181
181
|
"@radix-ui/react-slot": "^1.0.0",
|
|
182
|
+
"@radix-ui/react-switch": "^1.1.0",
|
|
182
183
|
"@radix-ui/react-toast": "^1.0.0",
|
|
183
184
|
"@radix-ui/react-tooltip": "^1.0.0",
|
|
184
185
|
"@tanstack/react-table": "^8.0.0",
|