@chemmangat/msal-next 3.0.3 → 3.0.4

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 CHANGED
@@ -1,2 +1,915 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
3
+ export { AccountInfo } from '@azure/msal-browser';
4
+ import { ReactNode, CSSProperties, Component, ErrorInfo, ComponentType } from 'react';
5
+ import { NextRequest, NextResponse } from 'next/server';
6
+ export { ServerSession } from './server.mjs';
7
+ export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
1
8
 
2
- export { }
9
+ /**
10
+ * Custom token claims interface for TypeScript generics
11
+ * Extend this interface to add your custom claims
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * interface MyCustomClaims extends CustomTokenClaims {
16
+ * roles: string[];
17
+ * department: string;
18
+ * }
19
+ *
20
+ * const claims = account.idTokenClaims as MyCustomClaims;
21
+ * ```
22
+ */
23
+ interface CustomTokenClaims {
24
+ [key: string]: any;
25
+ }
26
+ interface MsalAuthConfig {
27
+ /**
28
+ * Azure AD Application (client) ID
29
+ */
30
+ clientId: string;
31
+ /**
32
+ * Azure AD Directory (tenant) ID (optional for multi-tenant)
33
+ */
34
+ tenantId?: string;
35
+ /**
36
+ * Authority type: 'common' for multi-tenant, 'organizations', 'consumers', or 'tenant' for single-tenant
37
+ * @default 'common'
38
+ */
39
+ authorityType?: 'common' | 'organizations' | 'consumers' | 'tenant';
40
+ /**
41
+ * Redirect URI after authentication
42
+ * @default window.location.origin
43
+ */
44
+ redirectUri?: string;
45
+ /**
46
+ * Post logout redirect URI
47
+ * @default redirectUri
48
+ */
49
+ postLogoutRedirectUri?: string;
50
+ /**
51
+ * Default scopes for authentication
52
+ * @default ['User.Read']
53
+ */
54
+ scopes?: string[];
55
+ /**
56
+ * Cache location: 'sessionStorage', 'localStorage', or 'memoryStorage'
57
+ * @default 'sessionStorage'
58
+ */
59
+ cacheLocation?: 'sessionStorage' | 'localStorage' | 'memoryStorage';
60
+ /**
61
+ * Store auth state in cookie (for IE11/Edge legacy)
62
+ * @default false
63
+ */
64
+ storeAuthStateInCookie?: boolean;
65
+ /**
66
+ * Navigate to login request URL after authentication
67
+ * @default true
68
+ */
69
+ navigateToLoginRequestUrl?: boolean;
70
+ /**
71
+ * Custom MSAL configuration (overrides all other options)
72
+ */
73
+ msalConfig?: Configuration;
74
+ /**
75
+ * Enable debug logging
76
+ * @default false
77
+ */
78
+ enableLogging?: boolean;
79
+ /**
80
+ * Custom logger callback
81
+ */
82
+ loggerCallback?: (level: LogLevel, message: string, containsPii: boolean) => void;
83
+ /**
84
+ * Allowed redirect URIs for validation (optional but recommended)
85
+ * Helps prevent open redirect vulnerabilities
86
+ * @example ['https://myapp.com', 'http://localhost:3000']
87
+ */
88
+ allowedRedirectUris?: string[];
89
+ /**
90
+ * Loading component to show while MSAL initializes
91
+ */
92
+ loadingComponent?: ReactNode;
93
+ /**
94
+ * Callback invoked after MSAL initialization completes successfully
95
+ */
96
+ onInitialized?: (instance: IPublicClientApplication) => void;
97
+ }
98
+ interface MsalAuthProviderProps extends MsalAuthConfig {
99
+ children: ReactNode;
100
+ }
101
+
102
+ /**
103
+ * Get the current MSAL instance
104
+ * @returns The MSAL instance or null if not initialized
105
+ */
106
+ declare function getMsalInstance(): PublicClientApplication | null;
107
+ declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
108
+
109
+ /**
110
+ * Pre-configured MSALProvider component for Next.js App Router layouts.
111
+ * This component is already marked as 'use client', so you can use it directly
112
+ * in your server-side layout.tsx without needing to create a separate client component.
113
+ *
114
+ * @example
115
+ * ```tsx
116
+ * // app/layout.tsx
117
+ * import { MSALProvider } from '@chemmangat/msal-next'
118
+ *
119
+ * export default function RootLayout({ children }) {
120
+ * return (
121
+ * <html lang="en">
122
+ * <body>
123
+ * <MSALProvider
124
+ * clientId={process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID!}
125
+ * tenantId={process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID!}
126
+ * >
127
+ * {children}
128
+ * </MSALProvider>
129
+ * </body>
130
+ * </html>
131
+ * )
132
+ * }
133
+ * ```
134
+ */
135
+ declare function MSALProvider({ children, ...props }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
136
+
137
+ interface MicrosoftSignInButtonProps {
138
+ /**
139
+ * Button text
140
+ * @default 'Sign in with Microsoft'
141
+ */
142
+ text?: string;
143
+ /**
144
+ * Button variant
145
+ * @default 'dark'
146
+ */
147
+ variant?: 'dark' | 'light';
148
+ /**
149
+ * Button size
150
+ * @default 'medium'
151
+ */
152
+ size?: 'small' | 'medium' | 'large';
153
+ /**
154
+ * Use redirect flow instead of popup
155
+ * @default false
156
+ */
157
+ useRedirect?: boolean;
158
+ /**
159
+ * Scopes to request
160
+ */
161
+ scopes?: string[];
162
+ /**
163
+ * Custom className
164
+ */
165
+ className?: string;
166
+ /**
167
+ * Custom styles
168
+ */
169
+ style?: CSSProperties;
170
+ /**
171
+ * Callback on successful login
172
+ */
173
+ onSuccess?: () => void;
174
+ /**
175
+ * Callback on error
176
+ */
177
+ onError?: (error: Error) => void;
178
+ }
179
+ declare function MicrosoftSignInButton({ text, variant, size, useRedirect, scopes, className, style, onSuccess, onError, }: MicrosoftSignInButtonProps): react_jsx_runtime.JSX.Element;
180
+
181
+ interface SignOutButtonProps {
182
+ /**
183
+ * Button text
184
+ * @default 'Sign out'
185
+ */
186
+ text?: string;
187
+ /**
188
+ * Button variant
189
+ * @default 'dark'
190
+ */
191
+ variant?: 'dark' | 'light';
192
+ /**
193
+ * Button size
194
+ * @default 'medium'
195
+ */
196
+ size?: 'small' | 'medium' | 'large';
197
+ /**
198
+ * Use redirect flow instead of popup
199
+ * @default false
200
+ */
201
+ useRedirect?: boolean;
202
+ /**
203
+ * Custom className
204
+ */
205
+ className?: string;
206
+ /**
207
+ * Custom styles
208
+ */
209
+ style?: CSSProperties;
210
+ /**
211
+ * Callback on successful logout
212
+ */
213
+ onSuccess?: () => void;
214
+ /**
215
+ * Callback on error
216
+ */
217
+ onError?: (error: Error) => void;
218
+ }
219
+ /**
220
+ * SignOutButton component with Microsoft branding
221
+ *
222
+ * @example
223
+ * ```tsx
224
+ * <SignOutButton variant="light" />
225
+ * ```
226
+ */
227
+ declare function SignOutButton({ text, variant, size, useRedirect, className, style, onSuccess, onError, }: SignOutButtonProps): react_jsx_runtime.JSX.Element;
228
+
229
+ interface UserAvatarProps {
230
+ /**
231
+ * Avatar size in pixels
232
+ * @default 40
233
+ */
234
+ size?: number;
235
+ /**
236
+ * Custom className
237
+ */
238
+ className?: string;
239
+ /**
240
+ * Custom styles
241
+ */
242
+ style?: CSSProperties;
243
+ /**
244
+ * Show user name tooltip on hover
245
+ * @default true
246
+ */
247
+ showTooltip?: boolean;
248
+ /**
249
+ * Fallback image URL if MS Graph photo fails
250
+ */
251
+ fallbackImage?: string;
252
+ }
253
+ /**
254
+ * UserAvatar component that displays user photo from MS Graph with fallback initials
255
+ *
256
+ * @example
257
+ * ```tsx
258
+ * <UserAvatar size={48} />
259
+ * ```
260
+ */
261
+ declare function UserAvatar({ size, className, style, showTooltip, fallbackImage, }: UserAvatarProps): react_jsx_runtime.JSX.Element;
262
+
263
+ interface AuthStatusProps {
264
+ /**
265
+ * Custom className
266
+ */
267
+ className?: string;
268
+ /**
269
+ * Custom styles
270
+ */
271
+ style?: CSSProperties;
272
+ /**
273
+ * Show detailed status (includes username)
274
+ * @default false
275
+ */
276
+ showDetails?: boolean;
277
+ /**
278
+ * Custom render function for loading state
279
+ */
280
+ renderLoading?: () => ReactNode;
281
+ /**
282
+ * Custom render function for authenticated state
283
+ */
284
+ renderAuthenticated?: (username: string) => ReactNode;
285
+ /**
286
+ * Custom render function for unauthenticated state
287
+ */
288
+ renderUnauthenticated?: () => ReactNode;
289
+ }
290
+ /**
291
+ * AuthStatus component that shows current authentication state
292
+ *
293
+ * @example
294
+ * ```tsx
295
+ * <AuthStatus showDetails />
296
+ * ```
297
+ */
298
+ declare function AuthStatus({ className, style, showDetails, renderLoading, renderAuthenticated, renderUnauthenticated, }: AuthStatusProps): react_jsx_runtime.JSX.Element;
299
+
300
+ interface AuthGuardProps {
301
+ /**
302
+ * Content to render when authenticated
303
+ */
304
+ children: ReactNode;
305
+ /**
306
+ * Component to show while checking authentication
307
+ */
308
+ loadingComponent?: ReactNode;
309
+ /**
310
+ * Component to show when not authenticated (before redirect)
311
+ */
312
+ fallbackComponent?: ReactNode;
313
+ /**
314
+ * Use redirect flow instead of popup
315
+ * @default true
316
+ */
317
+ useRedirect?: boolean;
318
+ /**
319
+ * Scopes to request during authentication
320
+ */
321
+ scopes?: string[];
322
+ /**
323
+ * Callback when authentication is required
324
+ */
325
+ onAuthRequired?: () => void;
326
+ }
327
+ /**
328
+ * AuthGuard component that protects content and auto-redirects to login
329
+ *
330
+ * @example
331
+ * ```tsx
332
+ * <AuthGuard>
333
+ * <ProtectedContent />
334
+ * </AuthGuard>
335
+ * ```
336
+ */
337
+ declare function AuthGuard({ children, loadingComponent, fallbackComponent, useRedirect, scopes, onAuthRequired, }: AuthGuardProps): react_jsx_runtime.JSX.Element;
338
+
339
+ interface ErrorBoundaryProps {
340
+ /**
341
+ * Content to render when no error
342
+ */
343
+ children: ReactNode;
344
+ /**
345
+ * Custom error fallback component
346
+ */
347
+ fallback?: (error: Error, reset: () => void) => ReactNode;
348
+ /**
349
+ * Callback when error occurs
350
+ */
351
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
352
+ /**
353
+ * Enable debug logging
354
+ * @default false
355
+ */
356
+ debug?: boolean;
357
+ }
358
+ interface ErrorBoundaryState {
359
+ hasError: boolean;
360
+ error: Error | null;
361
+ }
362
+ /**
363
+ * Error boundary for catching authentication errors
364
+ *
365
+ * @example
366
+ * ```tsx
367
+ * <ErrorBoundary>
368
+ * <MsalAuthProvider clientId="...">
369
+ * <App />
370
+ * </MsalAuthProvider>
371
+ * </ErrorBoundary>
372
+ * ```
373
+ */
374
+ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
375
+ constructor(props: ErrorBoundaryProps);
376
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
377
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
378
+ reset: () => void;
379
+ render(): ReactNode;
380
+ }
381
+
382
+ interface UseMsalAuthReturn {
383
+ /**
384
+ * Current authenticated account
385
+ */
386
+ account: AccountInfo | null;
387
+ /**
388
+ * All accounts in the cache
389
+ */
390
+ accounts: AccountInfo[];
391
+ /**
392
+ * Whether user is authenticated
393
+ */
394
+ isAuthenticated: boolean;
395
+ /**
396
+ * Whether MSAL is currently performing an interaction
397
+ */
398
+ inProgress: boolean;
399
+ /**
400
+ * Login using popup
401
+ */
402
+ loginPopup: (scopes?: string[]) => Promise<void>;
403
+ /**
404
+ * Login using redirect
405
+ */
406
+ loginRedirect: (scopes?: string[]) => Promise<void>;
407
+ /**
408
+ * Logout using popup
409
+ */
410
+ logoutPopup: () => Promise<void>;
411
+ /**
412
+ * Logout using redirect
413
+ */
414
+ logoutRedirect: () => Promise<void>;
415
+ /**
416
+ * Acquire access token silently (with fallback to popup)
417
+ */
418
+ acquireToken: (scopes: string[]) => Promise<string>;
419
+ /**
420
+ * Acquire access token silently only (no fallback)
421
+ */
422
+ acquireTokenSilent: (scopes: string[]) => Promise<string>;
423
+ /**
424
+ * Acquire access token using popup
425
+ */
426
+ acquireTokenPopup: (scopes: string[]) => Promise<string>;
427
+ /**
428
+ * Acquire access token using redirect
429
+ */
430
+ acquireTokenRedirect: (scopes: string[]) => Promise<void>;
431
+ /**
432
+ * Clear MSAL session without triggering Microsoft logout
433
+ */
434
+ clearSession: () => Promise<void>;
435
+ }
436
+ declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
437
+
438
+ interface GraphApiOptions extends RequestInit {
439
+ /**
440
+ * Scopes required for the API call
441
+ * @default ['User.Read']
442
+ */
443
+ scopes?: string[];
444
+ /**
445
+ * API version
446
+ * @default 'v1.0'
447
+ */
448
+ version?: 'v1.0' | 'beta';
449
+ /**
450
+ * Enable debug logging
451
+ * @default false
452
+ */
453
+ debug?: boolean;
454
+ }
455
+ interface UseGraphApiReturn {
456
+ /**
457
+ * Make a GET request to MS Graph API
458
+ */
459
+ get: <T = any>(endpoint: string, options?: GraphApiOptions) => Promise<T>;
460
+ /**
461
+ * Make a POST request to MS Graph API
462
+ */
463
+ post: <T = any>(endpoint: string, body?: any, options?: GraphApiOptions) => Promise<T>;
464
+ /**
465
+ * Make a PUT request to MS Graph API
466
+ */
467
+ put: <T = any>(endpoint: string, body?: any, options?: GraphApiOptions) => Promise<T>;
468
+ /**
469
+ * Make a PATCH request to MS Graph API
470
+ */
471
+ patch: <T = any>(endpoint: string, body?: any, options?: GraphApiOptions) => Promise<T>;
472
+ /**
473
+ * Make a DELETE request to MS Graph API
474
+ */
475
+ delete: <T = any>(endpoint: string, options?: GraphApiOptions) => Promise<T>;
476
+ /**
477
+ * Make a custom request to MS Graph API
478
+ */
479
+ request: <T = any>(endpoint: string, options?: GraphApiOptions) => Promise<T>;
480
+ }
481
+ /**
482
+ * Hook for making authenticated requests to MS Graph API
483
+ *
484
+ * @example
485
+ * ```tsx
486
+ * const graph = useGraphApi();
487
+ * const user = await graph.get('/me');
488
+ * ```
489
+ */
490
+ declare function useGraphApi(): UseGraphApiReturn;
491
+
492
+ interface UserProfile {
493
+ id: string;
494
+ displayName: string;
495
+ givenName: string;
496
+ surname: string;
497
+ userPrincipalName: string;
498
+ mail: string;
499
+ jobTitle?: string;
500
+ officeLocation?: string;
501
+ mobilePhone?: string;
502
+ businessPhones?: string[];
503
+ photo?: string;
504
+ }
505
+ interface UseUserProfileReturn {
506
+ /**
507
+ * User profile data
508
+ */
509
+ profile: UserProfile | null;
510
+ /**
511
+ * Whether profile is loading
512
+ */
513
+ loading: boolean;
514
+ /**
515
+ * Error if profile fetch failed
516
+ */
517
+ error: Error | null;
518
+ /**
519
+ * Refetch user profile
520
+ */
521
+ refetch: () => Promise<void>;
522
+ /**
523
+ * Clear cached profile
524
+ */
525
+ clearCache: () => void;
526
+ }
527
+ /**
528
+ * Hook for fetching and caching user profile from MS Graph
529
+ *
530
+ * @example
531
+ * ```tsx
532
+ * const { profile, loading } = useUserProfile();
533
+ * ```
534
+ */
535
+ declare function useUserProfile(): UseUserProfileReturn;
536
+
537
+ interface UseRolesReturn {
538
+ /**
539
+ * User's Azure AD roles
540
+ */
541
+ roles: string[];
542
+ /**
543
+ * User's Azure AD groups
544
+ */
545
+ groups: string[];
546
+ /**
547
+ * Whether roles/groups are loading
548
+ */
549
+ loading: boolean;
550
+ /**
551
+ * Error if fetch failed
552
+ */
553
+ error: Error | null;
554
+ /**
555
+ * Check if user has a specific role
556
+ */
557
+ hasRole: (role: string) => boolean;
558
+ /**
559
+ * Check if user is in a specific group
560
+ */
561
+ hasGroup: (groupId: string) => boolean;
562
+ /**
563
+ * Check if user has any of the specified roles
564
+ */
565
+ hasAnyRole: (roles: string[]) => boolean;
566
+ /**
567
+ * Check if user has all of the specified roles
568
+ */
569
+ hasAllRoles: (roles: string[]) => boolean;
570
+ /**
571
+ * Refetch roles and groups
572
+ */
573
+ refetch: () => Promise<void>;
574
+ }
575
+ /**
576
+ * Hook for fetching user's Azure AD roles and groups
577
+ *
578
+ * @example
579
+ * ```tsx
580
+ * const { roles, hasRole } = useRoles();
581
+ * if (hasRole('Admin')) {
582
+ * // Show admin content
583
+ * }
584
+ * ```
585
+ */
586
+ declare function useRoles(): UseRolesReturn;
587
+
588
+ declare function createMsalConfig(config: MsalAuthConfig): Configuration;
589
+
590
+ interface WithAuthOptions extends Omit<AuthGuardProps, 'children'> {
591
+ /**
592
+ * Display name for the wrapped component (for debugging)
593
+ */
594
+ displayName?: string;
595
+ }
596
+ /**
597
+ * Higher-order component for protecting pages/components
598
+ *
599
+ * @example
600
+ * ```tsx
601
+ * const ProtectedPage = withAuth(MyPage);
602
+ *
603
+ * // With options
604
+ * const ProtectedPage = withAuth(MyPage, {
605
+ * useRedirect: true,
606
+ * scopes: ['User.Read', 'Mail.Read']
607
+ * });
608
+ * ```
609
+ */
610
+ declare function withAuth<P extends object>(Component: ComponentType<P>, options?: WithAuthOptions): ComponentType<P>;
611
+
612
+ /**
613
+ * Retry configuration for token acquisition
614
+ */
615
+ interface RetryConfig {
616
+ /**
617
+ * Maximum number of retry attempts
618
+ * @default 3
619
+ */
620
+ maxRetries?: number;
621
+ /**
622
+ * Initial delay in milliseconds
623
+ * @default 1000
624
+ */
625
+ initialDelay?: number;
626
+ /**
627
+ * Maximum delay in milliseconds
628
+ * @default 10000
629
+ */
630
+ maxDelay?: number;
631
+ /**
632
+ * Backoff multiplier
633
+ * @default 2
634
+ */
635
+ backoffMultiplier?: number;
636
+ /**
637
+ * Enable debug logging
638
+ * @default false
639
+ */
640
+ debug?: boolean;
641
+ }
642
+ /**
643
+ * Exponential backoff retry utility for token acquisition
644
+ *
645
+ * @example
646
+ * ```tsx
647
+ * const token = await retryWithBackoff(
648
+ * () => acquireTokenSilent(scopes),
649
+ * { maxRetries: 3, debug: true }
650
+ * );
651
+ * ```
652
+ */
653
+ declare function retryWithBackoff<T>(fn: () => Promise<T>, config?: RetryConfig): Promise<T>;
654
+ /**
655
+ * Create a retry wrapper for a function
656
+ *
657
+ * @example
658
+ * ```tsx
659
+ * const acquireTokenWithRetry = createRetryWrapper(acquireToken, {
660
+ * maxRetries: 3,
661
+ * debug: true
662
+ * });
663
+ *
664
+ * const token = await acquireTokenWithRetry(scopes);
665
+ * ```
666
+ */
667
+ declare function createRetryWrapper<TArgs extends any[], TReturn>(fn: (...args: TArgs) => Promise<TReturn>, config?: RetryConfig): (...args: TArgs) => Promise<TReturn>;
668
+
669
+ /**
670
+ * Debug logger configuration
671
+ */
672
+ interface DebugLoggerConfig {
673
+ /**
674
+ * Enable debug mode
675
+ * @default false
676
+ */
677
+ enabled?: boolean;
678
+ /**
679
+ * Prefix for log messages
680
+ * @default '[MSAL-Next]'
681
+ */
682
+ prefix?: string;
683
+ /**
684
+ * Show timestamps
685
+ * @default true
686
+ */
687
+ showTimestamp?: boolean;
688
+ /**
689
+ * Log level
690
+ * @default 'info'
691
+ */
692
+ level?: 'error' | 'warn' | 'info' | 'debug';
693
+ /**
694
+ * Enable performance tracking
695
+ * @default false
696
+ */
697
+ enablePerformance?: boolean;
698
+ /**
699
+ * Enable network request logging
700
+ * @default false
701
+ */
702
+ enableNetworkLogs?: boolean;
703
+ /**
704
+ * Maximum log history size
705
+ * @default 100
706
+ */
707
+ maxHistorySize?: number;
708
+ }
709
+ /**
710
+ * Log entry for history tracking
711
+ */
712
+ interface LogEntry {
713
+ timestamp: number;
714
+ level: string;
715
+ message: string;
716
+ data?: any;
717
+ }
718
+ /**
719
+ * Performance timing entry
720
+ */
721
+ interface PerformanceTiming {
722
+ operation: string;
723
+ startTime: number;
724
+ endTime?: number;
725
+ duration?: number;
726
+ }
727
+ declare class DebugLogger {
728
+ private config;
729
+ private logHistory;
730
+ private performanceTimings;
731
+ constructor(config?: DebugLoggerConfig);
732
+ private shouldLog;
733
+ private formatMessage;
734
+ private addToHistory;
735
+ error(message: string, data?: any): void;
736
+ warn(message: string, data?: any): void;
737
+ info(message: string, data?: any): void;
738
+ debug(message: string, data?: any): void;
739
+ group(label: string): void;
740
+ groupEnd(): void;
741
+ /**
742
+ * Start performance timing for an operation
743
+ */
744
+ startTiming(operation: string): void;
745
+ /**
746
+ * End performance timing for an operation
747
+ */
748
+ endTiming(operation: string): number | undefined;
749
+ /**
750
+ * Log network request
751
+ */
752
+ logRequest(method: string, url: string, options?: any): void;
753
+ /**
754
+ * Log network response
755
+ */
756
+ logResponse(method: string, url: string, status: number, data?: any): void;
757
+ /**
758
+ * Get log history
759
+ */
760
+ getHistory(): LogEntry[];
761
+ /**
762
+ * Get performance timings
763
+ */
764
+ getPerformanceTimings(): PerformanceTiming[];
765
+ /**
766
+ * Clear log history
767
+ */
768
+ clearHistory(): void;
769
+ /**
770
+ * Clear performance timings
771
+ */
772
+ clearTimings(): void;
773
+ /**
774
+ * Export logs as JSON
775
+ */
776
+ exportLogs(): string;
777
+ /**
778
+ * Download logs as a file
779
+ */
780
+ downloadLogs(filename?: string): void;
781
+ setEnabled(enabled: boolean): void;
782
+ setLevel(level: DebugLoggerConfig['level']): void;
783
+ }
784
+ /**
785
+ * Get or create the global debug logger
786
+ *
787
+ * @example
788
+ * ```tsx
789
+ * const logger = getDebugLogger({
790
+ * enabled: true,
791
+ * level: 'debug',
792
+ * enablePerformance: true,
793
+ * enableNetworkLogs: true
794
+ * });
795
+ *
796
+ * logger.startTiming('token-acquisition');
797
+ * // ... do work
798
+ * logger.endTiming('token-acquisition');
799
+ *
800
+ * logger.logRequest('GET', '/me');
801
+ * logger.info('User logged in', { username: 'user@example.com' });
802
+ *
803
+ * // Export logs for debugging
804
+ * logger.downloadLogs();
805
+ * ```
806
+ */
807
+ declare function getDebugLogger(config?: DebugLoggerConfig): DebugLogger;
808
+ /**
809
+ * Create a scoped logger with a custom prefix
810
+ *
811
+ * @example
812
+ * ```tsx
813
+ * const logger = createScopedLogger('GraphAPI', {
814
+ * enabled: true,
815
+ * enableNetworkLogs: true
816
+ * });
817
+ * logger.info('Fetching user profile');
818
+ * ```
819
+ */
820
+ declare function createScopedLogger(scope: string, config?: DebugLoggerConfig): DebugLogger;
821
+
822
+ /**
823
+ * Security utilities for input validation and sanitization
824
+ */
825
+ /**
826
+ * Validate account data structure from cookie
827
+ */
828
+ interface ValidatedAccountData {
829
+ homeAccountId: string;
830
+ username: string;
831
+ name?: string;
832
+ }
833
+ /**
834
+ * Safely parse and validate JSON from untrusted sources
835
+ */
836
+ declare function safeJsonParse<T>(jsonString: string, validator: (data: any) => data is T): T | null;
837
+ /**
838
+ * Validate account data structure
839
+ */
840
+ declare function isValidAccountData(data: any): data is ValidatedAccountData;
841
+ /**
842
+ * Sanitize error messages to prevent information disclosure
843
+ */
844
+ declare function sanitizeError(error: unknown): string;
845
+ /**
846
+ * Validate redirect URI to prevent open redirect vulnerabilities
847
+ */
848
+ declare function isValidRedirectUri(uri: string, allowedOrigins: string[]): boolean;
849
+ /**
850
+ * Validate scope strings to prevent injection
851
+ */
852
+ declare function isValidScope(scope: string): boolean;
853
+ /**
854
+ * Validate array of scopes
855
+ */
856
+ declare function validateScopes(scopes: string[]): boolean;
857
+
858
+ interface AuthMiddlewareConfig {
859
+ /**
860
+ * Routes that require authentication
861
+ * @example ['/dashboard', '/profile', '/api/protected']
862
+ */
863
+ protectedRoutes?: string[];
864
+ /**
865
+ * Routes that should be accessible only when NOT authenticated
866
+ * @example ['/login', '/signup']
867
+ */
868
+ publicOnlyRoutes?: string[];
869
+ /**
870
+ * Login page path
871
+ * @default '/login'
872
+ */
873
+ loginPath?: string;
874
+ /**
875
+ * Redirect path after login
876
+ * @default '/'
877
+ */
878
+ redirectAfterLogin?: string;
879
+ /**
880
+ * Cookie name for session
881
+ * @default 'msal.account'
882
+ */
883
+ sessionCookie?: string;
884
+ /**
885
+ * Custom authentication check function
886
+ */
887
+ isAuthenticated?: (request: NextRequest) => boolean | Promise<boolean>;
888
+ /**
889
+ * Enable debug logging
890
+ * @default false
891
+ */
892
+ debug?: boolean;
893
+ }
894
+ /**
895
+ * Creates authentication middleware for Next.js App Router
896
+ *
897
+ * @example
898
+ * ```tsx
899
+ * // middleware.ts
900
+ * import { createAuthMiddleware } from '@chemmangat/msal-next';
901
+ *
902
+ * export const middleware = createAuthMiddleware({
903
+ * protectedRoutes: ['/dashboard', '/profile'],
904
+ * publicOnlyRoutes: ['/login'],
905
+ * loginPath: '/login',
906
+ * });
907
+ *
908
+ * export const config = {
909
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
910
+ * };
911
+ * ```
912
+ */
913
+ declare function createAuthMiddleware(config?: AuthMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
914
+
915
+ export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };