antaeus.keycloak.react 1.0.6

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.
@@ -0,0 +1,1193 @@
1
+ import React from 'react';
2
+ import { User, UserManagerSettings } from 'oidc-client-ts';
3
+ export { User } from 'oidc-client-ts';
4
+ import { useLocation } from 'react-router-dom';
5
+ import * as react_oidc_context from 'react-oidc-context';
6
+ export { AuthContextProps as UseAuthReturn } from 'react-oidc-context';
7
+
8
+ /**
9
+ * Main configuration interface for Keycloak integration
10
+ */
11
+ interface KeycloakConfig {
12
+ /**
13
+ * Keycloak realm authority URL (e.g., https://sso.example.com/realms/myrealm)
14
+ */
15
+ authority: string;
16
+ /**
17
+ * Client ID registered in Keycloak
18
+ */
19
+ clientId: string;
20
+ /**
21
+ * Redirect URI after login (defaults to current origin)
22
+ */
23
+ redirectUri?: string;
24
+ /**
25
+ * Redirect URI after logout (defaults to current origin)
26
+ */
27
+ postLogoutRedirectUri?: string;
28
+ /**
29
+ * OAuth2 scopes to request
30
+ * @default 'openid profile email offline_access'
31
+ */
32
+ scope?: string;
33
+ /**
34
+ * Feature flags to enable/disable functionality
35
+ */
36
+ features?: FeatureFlags;
37
+ /**
38
+ * Silent token renewal configuration
39
+ */
40
+ silentRenew?: SilentRenewConfig;
41
+ /**
42
+ * Event callbacks
43
+ */
44
+ events?: EventCallbacks;
45
+ /**
46
+ * Advanced OIDC options
47
+ */
48
+ advanced?: AdvancedOidcOptions;
49
+ }
50
+ /**
51
+ * Feature flags for optional Keycloak functionality
52
+ */
53
+ interface FeatureFlags {
54
+ /**
55
+ * Enable device flow authentication
56
+ * @default false
57
+ */
58
+ deviceFlow?: boolean;
59
+ /**
60
+ * Enable session monitoring UI
61
+ * @default false
62
+ */
63
+ sessionMonitor?: boolean;
64
+ /**
65
+ * Enable automatic token refresh
66
+ * @default true
67
+ */
68
+ autoRefresh?: boolean;
69
+ }
70
+ /**
71
+ * Silent token renewal configuration
72
+ */
73
+ interface SilentRenewConfig {
74
+ /**
75
+ * Enable silent token renewal
76
+ * @default true
77
+ */
78
+ enabled?: boolean;
79
+ /**
80
+ * Path to silent renew HTML file
81
+ * @default '/silent-renew.html'
82
+ */
83
+ silentRedirectUri?: string;
84
+ /**
85
+ * Threshold in seconds before expiry to trigger renewal
86
+ * @default 300 (5 minutes)
87
+ */
88
+ thresholdSeconds?: number;
89
+ }
90
+ /**
91
+ * Event callbacks for authentication lifecycle
92
+ */
93
+ interface EventCallbacks {
94
+ /**
95
+ * Called after successful login
96
+ */
97
+ onLogin?: (user: User) => void;
98
+ /**
99
+ * Called after logout
100
+ */
101
+ onLogout?: () => void;
102
+ /**
103
+ * Called when token expires
104
+ */
105
+ onTokenExpired?: () => void;
106
+ /**
107
+ * Called on authentication errors
108
+ */
109
+ onError?: (error: Error) => void;
110
+ /**
111
+ * Called on silent renew error
112
+ */
113
+ onSilentRenewError?: (error: Error) => void;
114
+ }
115
+ /**
116
+ * Advanced OIDC configuration options
117
+ */
118
+ interface AdvancedOidcOptions {
119
+ /**
120
+ * Response type
121
+ * @default 'code'
122
+ */
123
+ responseType?: string;
124
+ /**
125
+ * PKCE code challenge method
126
+ * @default 'S256'
127
+ */
128
+ codeChallengeMethod?: string;
129
+ /**
130
+ * Load user info from userinfo endpoint
131
+ * @default true
132
+ */
133
+ loadUserInfo?: boolean;
134
+ /**
135
+ * Automatically sign in if session exists
136
+ * @default false
137
+ */
138
+ automaticSilentSignIn?: boolean;
139
+ }
140
+
141
+ interface KeycloakProviderProps {
142
+ /**
143
+ * Keycloak configuration
144
+ */
145
+ config: KeycloakConfig;
146
+ /**
147
+ * Child components to render
148
+ */
149
+ children: React.ReactNode;
150
+ /**
151
+ * Enable debug logging to console
152
+ * @default false
153
+ */
154
+ debug?: boolean;
155
+ }
156
+ /**
157
+ * Main Keycloak authentication provider component
158
+ *
159
+ * Wraps your application to provide authentication context using Keycloak.
160
+ * This component handles all OIDC flows including login, logout, token refresh,
161
+ * and silent renewal.
162
+ *
163
+ * @example
164
+ * ```tsx
165
+ * import { KeycloakProvider } from 'antaeus.keycloak.react';
166
+ *
167
+ * function App() {
168
+ * return (
169
+ * <KeycloakProvider
170
+ * config={{
171
+ * authority: 'https://sso.example.com/realms/myrealm',
172
+ * clientId: 'my-app',
173
+ * }}
174
+ * >
175
+ * <YourApp />
176
+ * </KeycloakProvider>
177
+ * );
178
+ * }
179
+ * ```
180
+ */
181
+ declare const KeycloakProvider: React.FC<KeycloakProviderProps>;
182
+
183
+ /**
184
+ * Context object passed to custom policy function
185
+ */
186
+ interface PolicyContext {
187
+ /**
188
+ * Current location from react-router
189
+ */
190
+ location: ReturnType<typeof useLocation>;
191
+ /**
192
+ * Any additional context you want to pass
193
+ */
194
+ [key: string]: any;
195
+ }
196
+ /**
197
+ * Custom policy function for fine-grained access control
198
+ */
199
+ type PolicyFunction = (user: User, context: PolicyContext) => boolean;
200
+ interface ProtectedRouteProps {
201
+ /**
202
+ * Child components to render when user is authorized
203
+ */
204
+ children: React.ReactNode;
205
+ /**
206
+ * Required realm roles (OR logic - user needs at least one)
207
+ */
208
+ requiredRoles?: string[];
209
+ /**
210
+ * Require all roles instead of any (AND logic)
211
+ * @default false
212
+ */
213
+ requireAllRoles?: boolean;
214
+ /**
215
+ * Required OAuth 2.0 scopes (OR logic - user needs at least one)
216
+ */
217
+ requiredScopes?: string[];
218
+ /**
219
+ * Require all scopes instead of any (AND logic)
220
+ * @default false
221
+ */
222
+ requireAllScopes?: boolean;
223
+ /**
224
+ * Custom policy function for advanced authorization logic
225
+ * If provided, this takes precedence over role and scope checks
226
+ */
227
+ policy?: PolicyFunction;
228
+ /**
229
+ * Custom loading component to display while checking authentication
230
+ */
231
+ loadingComponent?: React.ReactNode;
232
+ /**
233
+ * Custom unauthorized component to display when user lacks required permissions
234
+ */
235
+ unauthorizedComponent?: React.ReactNode;
236
+ /**
237
+ * Path to redirect to if not authenticated
238
+ * @default '/login'
239
+ */
240
+ redirectTo?: string;
241
+ /**
242
+ * Callback when user is unauthorized
243
+ * @param reason - Reason for unauthorized access
244
+ */
245
+ onUnauthorized?: (reason: 'not-authenticated' | 'insufficient-roles' | 'insufficient-scopes' | 'policy-denied') => void;
246
+ }
247
+ /**
248
+ * Component for protecting routes with authentication, role-based, scope-based, or policy-based authorization
249
+ *
250
+ * This component provides comprehensive route protection with multiple authorization strategies:
251
+ * - Authentication check (always required)
252
+ * - Role-based authorization (realm roles)
253
+ * - Scope-based authorization (OAuth 2.0 scopes)
254
+ * - Custom policy functions (advanced logic)
255
+ *
256
+ * @example Basic authentication required
257
+ * ```tsx
258
+ * import { ProtectedRoute } from 'antaeus.keycloak.react';
259
+ *
260
+ * <Route
261
+ * path="/dashboard"
262
+ * element={
263
+ * <ProtectedRoute>
264
+ * <Dashboard />
265
+ * </ProtectedRoute>
266
+ * }
267
+ * />
268
+ * ```
269
+ *
270
+ * @example Require specific role
271
+ * ```tsx
272
+ * <Route
273
+ * path="/admin"
274
+ * element={
275
+ * <ProtectedRoute requiredRoles={['admin']}>
276
+ * <AdminPanel />
277
+ * </ProtectedRoute>
278
+ * }
279
+ * />
280
+ * ```
281
+ *
282
+ * @example Require any of multiple roles
283
+ * ```tsx
284
+ * <ProtectedRoute requiredRoles={['editor', 'moderator', 'admin']}>
285
+ * <EditPage />
286
+ * </ProtectedRoute>
287
+ * ```
288
+ *
289
+ * @example Require all roles (AND logic)
290
+ * ```tsx
291
+ * <ProtectedRoute
292
+ * requiredRoles={['verified', 'premium']}
293
+ * requireAllRoles={true}
294
+ * >
295
+ * <PremiumContent />
296
+ * </ProtectedRoute>
297
+ * ```
298
+ *
299
+ * @example Require specific scopes
300
+ * ```tsx
301
+ * <ProtectedRoute requiredScopes={['read:users', 'write:users']}>
302
+ * <UserManagement />
303
+ * </ProtectedRoute>
304
+ * ```
305
+ *
306
+ * @example Require all scopes (AND logic)
307
+ * ```tsx
308
+ * <ProtectedRoute
309
+ * requiredScopes={['read:data', 'write:data', 'delete:data']}
310
+ * requireAllScopes={true}
311
+ * >
312
+ * <DataAdmin />
313
+ * </ProtectedRoute>
314
+ * ```
315
+ *
316
+ * @example Combine roles and scopes
317
+ * ```tsx
318
+ * <ProtectedRoute
319
+ * requiredRoles={['admin']}
320
+ * requiredScopes={['manage:users']}
321
+ * >
322
+ * <UserAdmin />
323
+ * </ProtectedRoute>
324
+ * ```
325
+ *
326
+ * @example Custom policy function
327
+ * ```tsx
328
+ * <ProtectedRoute
329
+ * policy={(user, context) => {
330
+ * // Custom authorization logic
331
+ * const isEmailVerified = user.profile.email_verified === true;
332
+ * const isAdult = (user.profile.age || 0) >= 18;
333
+ * return isEmailVerified && isAdult;
334
+ * }}
335
+ * onUnauthorized={(reason) => {
336
+ * console.log('Access denied:', reason);
337
+ * }}
338
+ * >
339
+ * <AdultContent />
340
+ * </ProtectedRoute>
341
+ * ```
342
+ *
343
+ * @example Advanced policy with location context
344
+ * ```tsx
345
+ * <ProtectedRoute
346
+ * policy={(user, context) => {
347
+ * // Check if user is accessing during business hours
348
+ * const hour = new Date().getHours();
349
+ * const isBusinessHours = hour >= 9 && hour < 17;
350
+ *
351
+ * // Or check based on route
352
+ * const isAdminRoute = context.location.pathname.startsWith('/admin');
353
+ * const hasAdminRole = user.profile.realm_access?.roles?.includes('admin');
354
+ *
355
+ * return isBusinessHours && (!isAdminRoute || hasAdminRole);
356
+ * }}
357
+ * >
358
+ * <TimeSensitiveContent />
359
+ * </ProtectedRoute>
360
+ * ```
361
+ */
362
+ declare const ProtectedRoute: React.FC<ProtectedRouteProps>;
363
+
364
+ interface LoginButtonProps {
365
+ /**
366
+ * Button text
367
+ * @default 'Login'
368
+ */
369
+ children?: React.ReactNode;
370
+ /**
371
+ * Additional CSS class names
372
+ */
373
+ className?: string;
374
+ /**
375
+ * Button variant
376
+ * @default 'primary'
377
+ */
378
+ variant?: 'primary' | 'secondary' | 'outline';
379
+ /**
380
+ * Button size
381
+ * @default 'medium'
382
+ */
383
+ size?: 'small' | 'medium' | 'large';
384
+ /**
385
+ * Show login icon
386
+ * @default true
387
+ */
388
+ showIcon?: boolean;
389
+ /**
390
+ * Callback before login starts
391
+ */
392
+ onLoginStart?: () => void;
393
+ /**
394
+ * Custom inline styles
395
+ */
396
+ style?: React.CSSProperties;
397
+ /**
398
+ * Disable the button
399
+ */
400
+ disabled?: boolean;
401
+ }
402
+ /**
403
+ * Pre-built login button component
404
+ *
405
+ * Triggers the Keycloak login flow when clicked. The button automatically
406
+ * hides when the user is already authenticated.
407
+ *
408
+ * @example Basic usage
409
+ * ```tsx
410
+ * import { LoginButton } from 'antaeus.keycloak.react';
411
+ *
412
+ * function Header() {
413
+ * return <LoginButton />;
414
+ * }
415
+ * ```
416
+ *
417
+ * @example Customized
418
+ * ```tsx
419
+ * <LoginButton
420
+ * variant="outline"
421
+ * size="large"
422
+ * onLoginStart={() => console.log('Starting login...')}
423
+ * >
424
+ * Sign In
425
+ * </LoginButton>
426
+ * ```
427
+ *
428
+ * @example With custom styling
429
+ * ```tsx
430
+ * <LoginButton
431
+ * className="my-custom-class"
432
+ * style={{ backgroundColor: '#007bff' }}
433
+ * />
434
+ * ```
435
+ */
436
+ declare const LoginButton: React.FC<LoginButtonProps>;
437
+
438
+ interface LogoutButtonProps {
439
+ /**
440
+ * Button text
441
+ * @default 'Logout'
442
+ */
443
+ children?: React.ReactNode;
444
+ /**
445
+ * Additional CSS class names
446
+ */
447
+ className?: string;
448
+ /**
449
+ * Button variant
450
+ * @default 'secondary'
451
+ */
452
+ variant?: 'primary' | 'secondary' | 'outline';
453
+ /**
454
+ * Button size
455
+ * @default 'medium'
456
+ */
457
+ size?: 'small' | 'medium' | 'large';
458
+ /**
459
+ * Show logout icon
460
+ * @default true
461
+ */
462
+ showIcon?: boolean;
463
+ /**
464
+ * Callback before logout starts
465
+ */
466
+ onLogoutStart?: () => void;
467
+ /**
468
+ * Custom inline styles
469
+ */
470
+ style?: React.CSSProperties;
471
+ /**
472
+ * Disable the button
473
+ */
474
+ disabled?: boolean;
475
+ }
476
+ /**
477
+ * Pre-built logout button component
478
+ *
479
+ * Triggers the Keycloak logout flow when clicked. The button automatically
480
+ * hides when the user is not authenticated.
481
+ *
482
+ * @example Basic usage
483
+ * ```tsx
484
+ * import { LogoutButton } from 'antaeus.keycloak.react';
485
+ *
486
+ * function Header() {
487
+ * return <LogoutButton />;
488
+ * }
489
+ * ```
490
+ *
491
+ * @example Customized
492
+ * ```tsx
493
+ * <LogoutButton
494
+ * variant="outline"
495
+ * size="small"
496
+ * onLogoutStart={() => {
497
+ * // Clean up app state
498
+ * localStorage.clear();
499
+ * }}
500
+ * >
501
+ * Sign Out
502
+ * </LogoutButton>
503
+ * ```
504
+ *
505
+ * @example With custom styling
506
+ * ```tsx
507
+ * <LogoutButton
508
+ * className="my-logout-btn"
509
+ * style={{ backgroundColor: '#dc3545' }}
510
+ * />
511
+ * ```
512
+ */
513
+ declare const LogoutButton: React.FC<LogoutButtonProps>;
514
+
515
+ interface UserProfileProps {
516
+ /**
517
+ * Additional CSS class names
518
+ */
519
+ className?: string;
520
+ /**
521
+ * Show user avatar/icon
522
+ * @default true
523
+ */
524
+ showAvatar?: boolean;
525
+ /**
526
+ * Show user email
527
+ * @default true
528
+ */
529
+ showEmail?: boolean;
530
+ /**
531
+ * Show user roles
532
+ * @default false
533
+ */
534
+ showRoles?: boolean;
535
+ /**
536
+ * Avatar size in pixels
537
+ * @default 40
538
+ */
539
+ avatarSize?: number;
540
+ /**
541
+ * Custom inline styles
542
+ */
543
+ style?: React.CSSProperties;
544
+ /**
545
+ * Callback when profile is clicked
546
+ */
547
+ onClick?: () => void;
548
+ }
549
+ /**
550
+ * Pre-built user profile display component
551
+ *
552
+ * Displays the current user's information including name, email, and optionally roles.
553
+ * Automatically hides when user is not authenticated.
554
+ *
555
+ * @example Basic usage
556
+ * ```tsx
557
+ * import { UserProfile } from 'antaeus.keycloak.react';
558
+ *
559
+ * function Header() {
560
+ * return <UserProfile />;
561
+ * }
562
+ * ```
563
+ *
564
+ * @example With roles
565
+ * ```tsx
566
+ * <UserProfile showRoles={true} />
567
+ * ```
568
+ *
569
+ * @example Clickable profile
570
+ * ```tsx
571
+ * <UserProfile
572
+ * onClick={() => navigate('/profile')}
573
+ * style={{ cursor: 'pointer' }}
574
+ * />
575
+ * ```
576
+ *
577
+ * @example Customized
578
+ * ```tsx
579
+ * <UserProfile
580
+ * showEmail={false}
581
+ * showRoles={true}
582
+ * avatarSize={50}
583
+ * className="my-profile"
584
+ * />
585
+ * ```
586
+ */
587
+ declare const UserProfile: React.FC<UserProfileProps>;
588
+
589
+ interface SessionMonitorProps {
590
+ /**
591
+ * Position on screen
592
+ * @default 'top-right'
593
+ */
594
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
595
+ /**
596
+ * Warning threshold in seconds (yellow state)
597
+ * @default 300 (5 minutes)
598
+ */
599
+ warningThreshold?: number;
600
+ /**
601
+ * Critical threshold in seconds (red state)
602
+ * @default 60 (1 minute)
603
+ */
604
+ criticalThreshold?: number;
605
+ /**
606
+ * Show progress bar
607
+ * @default true
608
+ */
609
+ showProgressBar?: boolean;
610
+ /**
611
+ * Allow minimize/expand
612
+ * @default true
613
+ */
614
+ minimizable?: boolean;
615
+ /**
616
+ * Start minimized
617
+ * @default false
618
+ */
619
+ startMinimized?: boolean;
620
+ /**
621
+ * Custom CSS class names
622
+ */
623
+ className?: string;
624
+ /**
625
+ * Callback when warning threshold is reached
626
+ */
627
+ onWarning?: (secondsRemaining: number) => void;
628
+ /**
629
+ * Callback when critical threshold is reached
630
+ */
631
+ onCritical?: (secondsRemaining: number) => void;
632
+ /**
633
+ * Callback when session expires
634
+ */
635
+ onExpired?: () => void;
636
+ /**
637
+ * Custom inline styles
638
+ */
639
+ style?: React.CSSProperties;
640
+ }
641
+ /**
642
+ * Session monitoring component with countdown timer
643
+ *
644
+ * Displays the time remaining until the user's session expires. Shows visual
645
+ * warnings when the session is about to expire and triggers callbacks for
646
+ * custom handling.
647
+ *
648
+ * @example Basic usage
649
+ * ```tsx
650
+ * import { SessionMonitor } from 'antaeus.keycloak.react';
651
+ *
652
+ * function App() {
653
+ * return (
654
+ * <>
655
+ * <SessionMonitor />
656
+ * <YourApp />
657
+ * </>
658
+ * );
659
+ * }
660
+ * ```
661
+ *
662
+ * @example With custom thresholds
663
+ * ```tsx
664
+ * <SessionMonitor
665
+ * warningThreshold={600} // 10 minutes
666
+ * criticalThreshold={120} // 2 minutes
667
+ * onWarning={(seconds) => {
668
+ * console.log(`Session expiring in ${seconds} seconds`);
669
+ * }}
670
+ * />
671
+ * ```
672
+ *
673
+ * @example Custom position and style
674
+ * ```tsx
675
+ * <SessionMonitor
676
+ * position="bottom-left"
677
+ * showProgressBar={false}
678
+ * minimizable={false}
679
+ * />
680
+ * ```
681
+ */
682
+ declare const SessionMonitor: React.FC<SessionMonitorProps>;
683
+
684
+ interface DeviceLoginProps {
685
+ /**
686
+ * API base URL for device flow endpoints
687
+ * @example 'http://localhost:5000'
688
+ */
689
+ apiBaseUrl: string;
690
+ /**
691
+ * QR code size in pixels
692
+ * @default 256
693
+ */
694
+ qrCodeSize?: number;
695
+ /**
696
+ * Polling interval in seconds
697
+ * @default 5
698
+ */
699
+ pollingInterval?: number;
700
+ /**
701
+ * Custom CSS class
702
+ */
703
+ className?: string;
704
+ /**
705
+ * Callback on successful login
706
+ */
707
+ onSuccess?: (user: User) => void;
708
+ /**
709
+ * Callback on error
710
+ */
711
+ onError?: (error: Error) => void;
712
+ /**
713
+ * Custom inline styles
714
+ */
715
+ style?: React.CSSProperties;
716
+ }
717
+ /**
718
+ * Device flow login component
719
+ *
720
+ * Displays QR code and user code for device authentication. Automatically polls
721
+ * for authorization and completes the login flow.
722
+ *
723
+ * @example Basic usage
724
+ * ```tsx
725
+ * import { DeviceLogin } from 'antaeus.keycloak.react';
726
+ *
727
+ * function TVLoginPage() {
728
+ * return (
729
+ * <DeviceLogin
730
+ * apiBaseUrl="http://localhost:5000"
731
+ * onSuccess={(user) => {
732
+ * console.log('Logged in:', user.profile.name);
733
+ * navigate('/home');
734
+ * }}
735
+ * />
736
+ * );
737
+ * }
738
+ * ```
739
+ *
740
+ * @example With custom settings
741
+ * ```tsx
742
+ * <DeviceLogin
743
+ * apiBaseUrl="http://localhost:5000"
744
+ * qrCodeSize={300}
745
+ * pollingInterval={3}
746
+ * onError={(error) => console.error('Login failed:', error)}
747
+ * />
748
+ * ```
749
+ */
750
+ declare const DeviceLogin: React.FC<DeviceLoginProps>;
751
+
752
+ /**
753
+ * Main authentication hook for accessing Keycloak authentication state and methods
754
+ *
755
+ * This hook provides access to the current user, authentication state, and methods
756
+ * for signing in and out. It must be used within a KeycloakProvider component.
757
+ *
758
+ * @returns Authentication state and methods
759
+ *
760
+ * @example
761
+ * ```tsx
762
+ * import { useAuth } from 'antaeus.keycloak.react';
763
+ *
764
+ * function MyComponent() {
765
+ * const auth = useAuth();
766
+ *
767
+ * if (auth.isLoading) {
768
+ * return <div>Loading...</div>;
769
+ * }
770
+ *
771
+ * if (!auth.isAuthenticated) {
772
+ * return <button onClick={() => auth.signinRedirect()}>Login</button>;
773
+ * }
774
+ *
775
+ * return (
776
+ * <div>
777
+ * <p>Welcome, {auth.user?.profile?.name}</p>
778
+ * <button onClick={() => auth.signoutRedirect()}>Logout</button>
779
+ * </div>
780
+ * );
781
+ * }
782
+ * ```
783
+ *
784
+ * @example Role checking
785
+ * ```tsx
786
+ * function AdminPanel() {
787
+ * const auth = useAuth();
788
+ * const roles = auth.user?.profile?.realm_access?.roles || [];
789
+ *
790
+ * if (!roles.includes('admin')) {
791
+ * return <div>Access denied</div>;
792
+ * }
793
+ *
794
+ * return <div>Admin panel content</div>;
795
+ * }
796
+ * ```
797
+ */
798
+ declare const useAuth: () => react_oidc_context.AuthContextProps;
799
+
800
+ interface UseRolesReturn {
801
+ /**
802
+ * Array of realm roles assigned to the current user
803
+ */
804
+ roles: string[];
805
+ /**
806
+ * Checks if user has a specific realm role
807
+ * @param role - Role name to check
808
+ * @returns True if user has the role
809
+ */
810
+ hasRole: (role: string) => boolean;
811
+ /**
812
+ * Checks if user has any of the specified roles (OR logic)
813
+ * @param roles - Array of role names
814
+ * @returns True if user has at least one of the roles
815
+ */
816
+ hasAnyRole: (roles: string[]) => boolean;
817
+ /**
818
+ * Checks if user has all of the specified roles (AND logic)
819
+ * @param roles - Array of role names
820
+ * @returns True if user has all the roles
821
+ */
822
+ hasAllRoles: (roles: string[]) => boolean;
823
+ /**
824
+ * Gets client-specific roles
825
+ * @param clientId - Client ID to get roles for
826
+ * @returns Array of client roles
827
+ */
828
+ getClientRoles: (clientId: string) => string[];
829
+ }
830
+ /**
831
+ * Hook for working with Keycloak roles
832
+ *
833
+ * Provides convenient methods for checking user roles, both realm-level and client-level.
834
+ * Must be used within a KeycloakProvider component.
835
+ *
836
+ * @returns Role utilities and methods
837
+ *
838
+ * @example Basic usage
839
+ * ```tsx
840
+ * import { useRoles } from 'antaeus.keycloak.react';
841
+ *
842
+ * function MyComponent() {
843
+ * const { roles, hasRole, hasAnyRole } = useRoles();
844
+ *
845
+ * return (
846
+ * <div>
847
+ * <p>Your roles: {roles.join(', ')}</p>
848
+ * {hasRole('admin') && <AdminPanel />}
849
+ * {hasAnyRole(['editor', 'moderator']) && <EditButton />}
850
+ * </div>
851
+ * );
852
+ * }
853
+ * ```
854
+ *
855
+ * @example Client roles
856
+ * ```tsx
857
+ * function ClientRoleExample() {
858
+ * const { getClientRoles } = useRoles();
859
+ * const apiRoles = getClientRoles('my-api');
860
+ *
861
+ * return <div>API roles: {apiRoles.join(', ')}</div>;
862
+ * }
863
+ * ```
864
+ */
865
+ declare function useRoles(): UseRolesReturn;
866
+
867
+ /**
868
+ * Return type for useScopes hook
869
+ */
870
+ interface UseScopesReturn {
871
+ /**
872
+ * Array of granted scopes
873
+ */
874
+ scopes: string[];
875
+ /**
876
+ * Check if user has a specific scope
877
+ */
878
+ hasScope: (scope: string) => boolean;
879
+ /**
880
+ * Check if user has any of the specified scopes
881
+ */
882
+ hasAnyScope: (scopes: string[]) => boolean;
883
+ /**
884
+ * Check if user has all of the specified scopes
885
+ */
886
+ hasAllScopes: (scopes: string[]) => boolean;
887
+ }
888
+ /**
889
+ * Hook for checking OAuth 2.0 scopes
890
+ *
891
+ * Provides utilities for scope-based authorization. Scopes are typically space-separated
892
+ * in the token (e.g., "openid profile email read:users write:users").
893
+ *
894
+ * @returns Scope checking utilities
895
+ *
896
+ * @example Basic usage
897
+ * ```tsx
898
+ * import { useScopes } from 'antaeus.keycloak.react';
899
+ *
900
+ * function MyComponent() {
901
+ * const { scopes, hasScope, hasAnyScope } = useScopes();
902
+ *
903
+ * return (
904
+ * <div>
905
+ * <p>Your scopes: {scopes.join(', ')}</p>
906
+ *
907
+ * {hasScope('read:users') && <UserList />}
908
+ *
909
+ * {hasAnyScope(['write:users', 'admin']) && <CreateUserButton />}
910
+ * </div>
911
+ * );
912
+ * }
913
+ * ```
914
+ *
915
+ * @example Conditional rendering
916
+ * ```tsx
917
+ * function DataActions() {
918
+ * const { hasScope, hasAllScopes } = useScopes();
919
+ *
920
+ * return (
921
+ * <div>
922
+ * {hasScope('read:data') && <ViewButton />}
923
+ * {hasScope('write:data') && <EditButton />}
924
+ * {hasScope('delete:data') && <DeleteButton />}
925
+ * {hasAllScopes(['read:data', 'write:data']) && <ExportButton />}
926
+ * </div>
927
+ * );
928
+ * }
929
+ * ```
930
+ */
931
+ declare function useScopes(): UseScopesReturn;
932
+
933
+ interface UseProtectedFetchOptions {
934
+ /**
935
+ * Base URL for API requests
936
+ * @example 'http://localhost:5000'
937
+ */
938
+ baseUrl?: string;
939
+ /**
940
+ * Callback when request is unauthorized (401)
941
+ */
942
+ onUnauthorized?: () => void;
943
+ /**
944
+ * Retry request on 401 error after token refresh
945
+ * @default true
946
+ */
947
+ retryOn401?: boolean;
948
+ /**
949
+ * Additional headers to include in all requests
950
+ */
951
+ headers?: Record<string, string>;
952
+ }
953
+ interface UseProtectedFetchReturn {
954
+ /**
955
+ * Fetch with automatic token injection and JSON parsing
956
+ *
957
+ * @param url - URL or path to fetch
958
+ * @param init - Fetch init options
959
+ * @returns Parsed JSON response
960
+ */
961
+ fetchJson: <T = any>(url: string, init?: RequestInit) => Promise<T>;
962
+ /**
963
+ * Raw fetch with automatic token injection
964
+ *
965
+ * @param url - URL or path to fetch
966
+ * @param init - Fetch init options
967
+ * @returns Fetch response
968
+ */
969
+ fetch: (url: string, init?: RequestInit) => Promise<Response>;
970
+ /**
971
+ * Check if request is in progress
972
+ */
973
+ isLoading: boolean;
974
+ }
975
+ /**
976
+ * Hook for making authenticated API requests
977
+ *
978
+ * Automatically injects the current user's access token into all requests.
979
+ * Handles 401 errors and provides convenient methods for JSON APIs.
980
+ *
981
+ * @param options - Configuration options
982
+ * @returns Protected fetch methods
983
+ *
984
+ * @example Basic usage
985
+ * ```tsx
986
+ * import { useProtectedFetch } from 'antaeus.keycloak.react';
987
+ *
988
+ * function MyComponent() {
989
+ * const { fetchJson } = useProtectedFetch({
990
+ * baseUrl: 'http://localhost:5000'
991
+ * });
992
+ *
993
+ * const loadData = async () => {
994
+ * // Token is automatically added
995
+ * const data = await fetchJson('/api/data');
996
+ * console.log(data);
997
+ * };
998
+ *
999
+ * return <button onClick={loadData}>Load Data</button>;
1000
+ * }
1001
+ * ```
1002
+ *
1003
+ * @example With custom headers
1004
+ * ```tsx
1005
+ * const { fetchJson } = useProtectedFetch({
1006
+ * baseUrl: 'http://localhost:5000',
1007
+ * headers: {
1008
+ * 'X-Custom-Header': 'value'
1009
+ * }
1010
+ * });
1011
+ * ```
1012
+ *
1013
+ * @example POST request
1014
+ * ```tsx
1015
+ * const { fetchJson } = useProtectedFetch({
1016
+ * baseUrl: 'http://localhost:5000'
1017
+ * });
1018
+ *
1019
+ * const createUser = async (userData: User) => {
1020
+ * const result = await fetchJson<User>('/api/users', {
1021
+ * method: 'POST',
1022
+ * body: JSON.stringify(userData),
1023
+ * headers: {
1024
+ * 'Content-Type': 'application/json'
1025
+ * }
1026
+ * });
1027
+ * return result;
1028
+ * };
1029
+ * ```
1030
+ *
1031
+ * @example Handle unauthorized
1032
+ * ```tsx
1033
+ * const { fetchJson } = useProtectedFetch({
1034
+ * baseUrl: 'http://localhost:5000',
1035
+ * onUnauthorized: () => {
1036
+ * console.log('Unauthorized! Redirecting to login...');
1037
+ * }
1038
+ * });
1039
+ * ```
1040
+ */
1041
+ declare function useProtectedFetch(options?: UseProtectedFetchOptions): UseProtectedFetchReturn;
1042
+
1043
+ /**
1044
+ * Default configuration values for Keycloak integration
1045
+ */
1046
+ declare const defaultConfig: Partial<KeycloakConfig>;
1047
+
1048
+ /**
1049
+ * Configuration builder for Keycloak integration
1050
+ */
1051
+ declare class KeycloakConfigBuilder {
1052
+ /**
1053
+ * Builds OIDC client configuration from Keycloak config
1054
+ *
1055
+ * @param userConfig - User-provided Keycloak configuration
1056
+ * @returns OIDC client settings ready for react-oidc-context
1057
+ * @throws Error if required fields are missing or invalid
1058
+ */
1059
+ static build(userConfig: KeycloakConfig): UserManagerSettings;
1060
+ /**
1061
+ * Validates required configuration fields
1062
+ *
1063
+ * @param config - Configuration to validate
1064
+ * @throws Error if validation fails
1065
+ */
1066
+ private static validate;
1067
+ /**
1068
+ * Merges user configuration with defaults
1069
+ *
1070
+ * @param config - User configuration
1071
+ * @returns Merged configuration with all defaults applied
1072
+ */
1073
+ private static mergeWithDefaults;
1074
+ }
1075
+ /**
1076
+ * Helper function to get configuration from environment variables
1077
+ *
1078
+ * @returns Partial Keycloak configuration from environment
1079
+ */
1080
+ declare function getConfigFromEnv(): Partial<KeycloakConfig>;
1081
+
1082
+ /**
1083
+ * Device authorization response from Keycloak
1084
+ */
1085
+ interface DeviceAuthorizationResponse {
1086
+ /** Device code used for polling */
1087
+ device_code: string;
1088
+ /** User code to display to user */
1089
+ user_code: string;
1090
+ /** Verification URI (plain) */
1091
+ verification_uri: string;
1092
+ /** Complete verification URI with user code (for QR codes) */
1093
+ verification_uri_complete: string;
1094
+ /** Expiration time in seconds */
1095
+ expires_in: number;
1096
+ /** Recommended polling interval in seconds */
1097
+ interval: number;
1098
+ }
1099
+ /**
1100
+ * Token response from Keycloak
1101
+ */
1102
+ interface TokenResponse {
1103
+ /** Access token */
1104
+ access_token: string;
1105
+ /** Token type (usually 'Bearer') */
1106
+ token_type: string;
1107
+ /** Expiration time in seconds */
1108
+ expires_in: number;
1109
+ /** Refresh token (if offline_access scope was requested) */
1110
+ refresh_token?: string;
1111
+ /** ID token */
1112
+ id_token?: string;
1113
+ /** Granted scopes */
1114
+ scope?: string;
1115
+ }
1116
+ /**
1117
+ * Error response from token polling
1118
+ */
1119
+ interface DeviceFlowError {
1120
+ /** Error code */
1121
+ error: string;
1122
+ /** Error description */
1123
+ error_description?: string;
1124
+ }
1125
+ /**
1126
+ * Request device authorization code from the backend API
1127
+ *
1128
+ * This function calls your backend API which proxies the request to Keycloak.
1129
+ * This avoids CORS issues.
1130
+ *
1131
+ * @param apiBaseUrl - Base URL of your backend API (e.g., 'http://localhost:5000')
1132
+ * @returns Device authorization response
1133
+ * @throws Error if request fails
1134
+ *
1135
+ * @example
1136
+ * ```ts
1137
+ * const response = await requestDeviceCode('http://localhost:5000');
1138
+ * console.log('User code:', response.user_code);
1139
+ * console.log('Verification URL:', response.verification_uri_complete);
1140
+ * ```
1141
+ */
1142
+ declare function requestDeviceCode(apiBaseUrl: string): Promise<DeviceAuthorizationResponse>;
1143
+ /**
1144
+ * Poll for token using device code
1145
+ *
1146
+ * This function should be called repeatedly until the user authorizes the device
1147
+ * or the device code expires. The backend handles the actual token exchange with Keycloak.
1148
+ *
1149
+ * @param apiBaseUrl - Base URL of your backend API
1150
+ * @param deviceCode - Device code from requestDeviceCode()
1151
+ * @returns Token response if authorized, null if still pending
1152
+ * @throws Error if request fails or authorization is denied
1153
+ *
1154
+ * @example
1155
+ * ```ts
1156
+ * const deviceCode = 'ABC123';
1157
+ * const interval = setInterval(async () => {
1158
+ * try {
1159
+ * const token = await pollForToken('http://localhost:5000', deviceCode);
1160
+ * if (token) {
1161
+ * clearInterval(interval);
1162
+ * console.log('Authorized! Token:', token.access_token);
1163
+ * }
1164
+ * } catch (error) {
1165
+ * if (error.message.includes('authorization_pending')) {
1166
+ * // Still waiting, continue polling
1167
+ * } else {
1168
+ * // Real error, stop polling
1169
+ * clearInterval(interval);
1170
+ * console.error('Authorization failed:', error);
1171
+ * }
1172
+ * }
1173
+ * }, 5000);
1174
+ * ```
1175
+ */
1176
+ declare function pollForToken(apiBaseUrl: string, deviceCode: string): Promise<TokenResponse | null>;
1177
+ /**
1178
+ * Fetch user information using access token
1179
+ *
1180
+ * @param apiBaseUrl - Base URL of your backend API
1181
+ * @param accessToken - Access token from token response
1182
+ * @returns User information
1183
+ * @throws Error if request fails
1184
+ *
1185
+ * @example
1186
+ * ```ts
1187
+ * const userInfo = await fetchUserInfo('http://localhost:5000', token.access_token);
1188
+ * console.log('User:', userInfo.preferred_username);
1189
+ * ```
1190
+ */
1191
+ declare function fetchUserInfo(apiBaseUrl: string, accessToken: string): Promise<any>;
1192
+
1193
+ export { type AdvancedOidcOptions, type DeviceAuthorizationResponse, type DeviceFlowError, DeviceLogin, type DeviceLoginProps, type EventCallbacks, type FeatureFlags, type KeycloakConfig, KeycloakConfigBuilder, KeycloakProvider, type KeycloakProviderProps, LoginButton, type LoginButtonProps, LogoutButton, type LogoutButtonProps, type PolicyContext, type PolicyFunction, ProtectedRoute, type ProtectedRouteProps, SessionMonitor, type SessionMonitorProps, type SilentRenewConfig, type TokenResponse, type UseProtectedFetchOptions, type UseProtectedFetchReturn, type UseRolesReturn, type UseScopesReturn, UserProfile, type UserProfileProps, defaultConfig, fetchUserInfo, getConfigFromEnv, pollForToken, requestDeviceCode, useAuth, useProtectedFetch, useRoles, useScopes };