@chemmangat/msal-next 3.0.3 → 3.0.5

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