@chemmangat/msal-next 2.3.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -4
- package/dist/index.d.mts +95 -2
- package/dist/index.d.ts +95 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,9 +5,12 @@ Production-grade MSAL authentication library for Next.js App Router with minimal
|
|
|
5
5
|
[](https://www.npmjs.com/package/@chemmangat/msal-next)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
+
> **v3.0.0 is here!** 🎉 New CLI tool, enhanced debugging, and better DX. [See what's new](#whats-new-in-v30)
|
|
9
|
+
|
|
8
10
|
## Features
|
|
9
11
|
|
|
10
|
-
✨ **
|
|
12
|
+
✨ **CLI Setup** - Get started in under 2 minutes with `npx @chemmangat/msal-next init`
|
|
13
|
+
🔍 **Enhanced Debugging** - Performance tracking, network logs, and log export
|
|
11
14
|
🔐 **Production Ready** - Comprehensive error handling, retry logic, and SSR support
|
|
12
15
|
🎨 **Beautiful Components** - Pre-styled Microsoft-branded UI components
|
|
13
16
|
🪝 **Powerful Hooks** - Easy-to-use hooks for auth, Graph API, and user data
|
|
@@ -15,10 +18,69 @@ Production-grade MSAL authentication library for Next.js App Router with minimal
|
|
|
15
18
|
⚡ **Edge Compatible** - Middleware support for protecting routes at the edge
|
|
16
19
|
📦 **Zero Config** - Sensible defaults with full customization options
|
|
17
20
|
|
|
21
|
+
## What's New in v3.0
|
|
22
|
+
|
|
23
|
+
### 🚀 CLI Tool (NEW)
|
|
24
|
+
```bash
|
|
25
|
+
# One command setup - that's it!
|
|
26
|
+
npx @chemmangat/msal-next init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The new CLI tool automatically:
|
|
30
|
+
- Detects your Next.js structure (App Router/Pages Router)
|
|
31
|
+
- Installs dependencies
|
|
32
|
+
- Creates configuration files
|
|
33
|
+
- Generates example pages
|
|
34
|
+
- Sets up middleware
|
|
35
|
+
|
|
36
|
+
**Reduces setup time from 30+ minutes to under 2 minutes!**
|
|
37
|
+
|
|
38
|
+
### 🔍 Enhanced Debug Logger (NEW)
|
|
39
|
+
```tsx
|
|
40
|
+
import { getDebugLogger } from '@chemmangat/msal-next';
|
|
41
|
+
|
|
42
|
+
const logger = getDebugLogger({
|
|
43
|
+
enabled: true,
|
|
44
|
+
enablePerformance: true, // Track operation timing
|
|
45
|
+
enableNetworkLogs: true, // Log all requests/responses
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Performance tracking
|
|
49
|
+
logger.startTiming('token-acquisition');
|
|
50
|
+
await acquireToken(['User.Read']);
|
|
51
|
+
logger.endTiming('token-acquisition'); // Logs: "⏱️ Completed: token-acquisition (45ms)"
|
|
52
|
+
|
|
53
|
+
// Export logs for debugging
|
|
54
|
+
logger.downloadLogs('debug-logs.json');
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 📚 New Examples
|
|
58
|
+
- **Role-Based Routing** - Complete RBAC implementation
|
|
59
|
+
- **Multi-Tenant SaaS** - Full multi-tenant architecture
|
|
60
|
+
|
|
61
|
+
### 🔄 Breaking Changes
|
|
62
|
+
- Requires Node.js 18+ (was 16+)
|
|
63
|
+
- Requires Next.js 14.1+ (was 14.0+)
|
|
64
|
+
- Requires @azure/msal-browser v4+ (was v3+)
|
|
65
|
+
- Removed `ServerSession.accessToken` (use client-side `acquireToken()`)
|
|
66
|
+
|
|
67
|
+
[See Migration Guide](./MIGRATION_GUIDE_v3.md) for details.
|
|
68
|
+
|
|
18
69
|
## Installation
|
|
19
70
|
|
|
71
|
+
### Option 1: CLI Setup (Recommended)
|
|
20
72
|
```bash
|
|
21
|
-
|
|
73
|
+
# Create Next.js app
|
|
74
|
+
npx create-next-app@latest my-app
|
|
75
|
+
cd my-app
|
|
76
|
+
|
|
77
|
+
# Initialize MSAL
|
|
78
|
+
npx @chemmangat/msal-next init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Option 2: Manual Installation
|
|
82
|
+
```bash
|
|
83
|
+
npm install @chemmangat/msal-next@3.0.0 @azure/msal-browser@^4.0.0 @azure/msal-react@^3.0.0
|
|
22
84
|
```
|
|
23
85
|
|
|
24
86
|
## Quick Start
|
|
@@ -331,7 +393,7 @@ const acquireTokenWithRetry = createRetryWrapper(acquireToken, {
|
|
|
331
393
|
|
|
332
394
|
### Debug Logger
|
|
333
395
|
|
|
334
|
-
Comprehensive logging for troubleshooting.
|
|
396
|
+
Comprehensive logging for troubleshooting with enhanced v3.0 features.
|
|
335
397
|
|
|
336
398
|
```tsx
|
|
337
399
|
import { getDebugLogger } from '@chemmangat/msal-next';
|
|
@@ -339,11 +401,28 @@ import { getDebugLogger } from '@chemmangat/msal-next';
|
|
|
339
401
|
const logger = getDebugLogger({
|
|
340
402
|
enabled: true,
|
|
341
403
|
level: 'debug',
|
|
342
|
-
showTimestamp: true
|
|
404
|
+
showTimestamp: true,
|
|
405
|
+
enablePerformance: true, // NEW in v3.0
|
|
406
|
+
enableNetworkLogs: true, // NEW in v3.0
|
|
407
|
+
maxHistorySize: 100, // NEW in v3.0
|
|
343
408
|
});
|
|
344
409
|
|
|
410
|
+
// Basic logging
|
|
345
411
|
logger.info('User logged in', { username: 'user@example.com' });
|
|
346
412
|
logger.error('Authentication failed', { error });
|
|
413
|
+
|
|
414
|
+
// NEW: Performance tracking
|
|
415
|
+
logger.startTiming('token-acquisition');
|
|
416
|
+
const token = await acquireToken(['User.Read']);
|
|
417
|
+
logger.endTiming('token-acquisition'); // Logs duration
|
|
418
|
+
|
|
419
|
+
// NEW: Network logging
|
|
420
|
+
logger.logRequest('GET', '/me');
|
|
421
|
+
logger.logResponse('GET', '/me', 200, userData);
|
|
422
|
+
|
|
423
|
+
// NEW: Export logs
|
|
424
|
+
const logs = logger.exportLogs();
|
|
425
|
+
logger.downloadLogs('debug-logs.json'); // Download as file
|
|
347
426
|
```
|
|
348
427
|
|
|
349
428
|
## TypeScript Support
|
|
@@ -508,6 +587,33 @@ Enable debug logging to troubleshoot issues:
|
|
|
508
587
|
|
|
509
588
|
## Migration Guide
|
|
510
589
|
|
|
590
|
+
### From v2.x to v3.0
|
|
591
|
+
|
|
592
|
+
v3.0 includes breaking changes. See [MIGRATION_GUIDE_v3.md](./MIGRATION_GUIDE_v3.md) for complete details.
|
|
593
|
+
|
|
594
|
+
**Quick migration:**
|
|
595
|
+
|
|
596
|
+
```bash
|
|
597
|
+
# 1. Update dependencies
|
|
598
|
+
npm install @chemmangat/msal-next@3.0.0
|
|
599
|
+
npm install @azure/msal-browser@^4.0.0
|
|
600
|
+
npm install @azure/msal-react@^3.0.0
|
|
601
|
+
npm install next@^14.1.0
|
|
602
|
+
|
|
603
|
+
# 2. Update Node.js to 18+
|
|
604
|
+
node --version # Should be v18.0.0+
|
|
605
|
+
|
|
606
|
+
# 3. Remove deprecated ServerSession.accessToken usage
|
|
607
|
+
# Before:
|
|
608
|
+
const session = await getServerSession();
|
|
609
|
+
const token = session.accessToken; // ❌ Removed
|
|
610
|
+
|
|
611
|
+
# After:
|
|
612
|
+
'use client';
|
|
613
|
+
const { acquireToken } = useMsalAuth();
|
|
614
|
+
const token = await acquireToken(['User.Read']); // ✅
|
|
615
|
+
```
|
|
616
|
+
|
|
511
617
|
### From v1.x to v2.x
|
|
512
618
|
|
|
513
619
|
v2.0 is backward compatible with v1.x. New features are additive:
|
|
@@ -542,6 +648,19 @@ MIT © [Chemmangat](https://github.com/chemmangat)
|
|
|
542
648
|
- 📖 [Documentation](https://github.com/chemmangat/msal-next#readme)
|
|
543
649
|
- 🐛 [Issue Tracker](https://github.com/chemmangat/msal-next/issues)
|
|
544
650
|
- 💬 [Discussions](https://github.com/chemmangat/msal-next/discussions)
|
|
651
|
+
- 🚀 [CLI Tool](https://www.npmjs.com/package/@chemmangat/msal-next-cli)
|
|
652
|
+
- 📋 [Migration Guide](./MIGRATION_GUIDE_v3.md)
|
|
653
|
+
- 🧪 [Testing Guide](./TESTING_GUIDE.md)
|
|
654
|
+
|
|
655
|
+
## What's Coming in v3.1
|
|
656
|
+
|
|
657
|
+
- 🧪 80%+ test coverage
|
|
658
|
+
- 📚 6+ additional examples
|
|
659
|
+
- ⚡ Performance optimizations
|
|
660
|
+
- 🔒 Security audit
|
|
661
|
+
- 🆕 New hooks and components
|
|
662
|
+
|
|
663
|
+
[See Roadmap](./V3_ROADMAP.md) for details.
|
|
545
664
|
|
|
546
665
|
## Acknowledgments
|
|
547
666
|
|
package/dist/index.d.mts
CHANGED
|
@@ -661,18 +661,94 @@ interface DebugLoggerConfig {
|
|
|
661
661
|
* @default 'info'
|
|
662
662
|
*/
|
|
663
663
|
level?: 'error' | 'warn' | 'info' | 'debug';
|
|
664
|
+
/**
|
|
665
|
+
* Enable performance tracking
|
|
666
|
+
* @default false
|
|
667
|
+
*/
|
|
668
|
+
enablePerformance?: boolean;
|
|
669
|
+
/**
|
|
670
|
+
* Enable network request logging
|
|
671
|
+
* @default false
|
|
672
|
+
*/
|
|
673
|
+
enableNetworkLogs?: boolean;
|
|
674
|
+
/**
|
|
675
|
+
* Maximum log history size
|
|
676
|
+
* @default 100
|
|
677
|
+
*/
|
|
678
|
+
maxHistorySize?: number;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Log entry for history tracking
|
|
682
|
+
*/
|
|
683
|
+
interface LogEntry {
|
|
684
|
+
timestamp: number;
|
|
685
|
+
level: string;
|
|
686
|
+
message: string;
|
|
687
|
+
data?: any;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Performance timing entry
|
|
691
|
+
*/
|
|
692
|
+
interface PerformanceTiming {
|
|
693
|
+
operation: string;
|
|
694
|
+
startTime: number;
|
|
695
|
+
endTime?: number;
|
|
696
|
+
duration?: number;
|
|
664
697
|
}
|
|
665
698
|
declare class DebugLogger {
|
|
666
699
|
private config;
|
|
700
|
+
private logHistory;
|
|
701
|
+
private performanceTimings;
|
|
667
702
|
constructor(config?: DebugLoggerConfig);
|
|
668
703
|
private shouldLog;
|
|
669
704
|
private formatMessage;
|
|
705
|
+
private addToHistory;
|
|
670
706
|
error(message: string, data?: any): void;
|
|
671
707
|
warn(message: string, data?: any): void;
|
|
672
708
|
info(message: string, data?: any): void;
|
|
673
709
|
debug(message: string, data?: any): void;
|
|
674
710
|
group(label: string): void;
|
|
675
711
|
groupEnd(): void;
|
|
712
|
+
/**
|
|
713
|
+
* Start performance timing for an operation
|
|
714
|
+
*/
|
|
715
|
+
startTiming(operation: string): void;
|
|
716
|
+
/**
|
|
717
|
+
* End performance timing for an operation
|
|
718
|
+
*/
|
|
719
|
+
endTiming(operation: string): number | undefined;
|
|
720
|
+
/**
|
|
721
|
+
* Log network request
|
|
722
|
+
*/
|
|
723
|
+
logRequest(method: string, url: string, options?: any): void;
|
|
724
|
+
/**
|
|
725
|
+
* Log network response
|
|
726
|
+
*/
|
|
727
|
+
logResponse(method: string, url: string, status: number, data?: any): void;
|
|
728
|
+
/**
|
|
729
|
+
* Get log history
|
|
730
|
+
*/
|
|
731
|
+
getHistory(): LogEntry[];
|
|
732
|
+
/**
|
|
733
|
+
* Get performance timings
|
|
734
|
+
*/
|
|
735
|
+
getPerformanceTimings(): PerformanceTiming[];
|
|
736
|
+
/**
|
|
737
|
+
* Clear log history
|
|
738
|
+
*/
|
|
739
|
+
clearHistory(): void;
|
|
740
|
+
/**
|
|
741
|
+
* Clear performance timings
|
|
742
|
+
*/
|
|
743
|
+
clearTimings(): void;
|
|
744
|
+
/**
|
|
745
|
+
* Export logs as JSON
|
|
746
|
+
*/
|
|
747
|
+
exportLogs(): string;
|
|
748
|
+
/**
|
|
749
|
+
* Download logs as a file
|
|
750
|
+
*/
|
|
751
|
+
downloadLogs(filename?: string): void;
|
|
676
752
|
setEnabled(enabled: boolean): void;
|
|
677
753
|
setLevel(level: DebugLoggerConfig['level']): void;
|
|
678
754
|
}
|
|
@@ -681,8 +757,22 @@ declare class DebugLogger {
|
|
|
681
757
|
*
|
|
682
758
|
* @example
|
|
683
759
|
* ```tsx
|
|
684
|
-
* const logger = getDebugLogger({
|
|
760
|
+
* const logger = getDebugLogger({
|
|
761
|
+
* enabled: true,
|
|
762
|
+
* level: 'debug',
|
|
763
|
+
* enablePerformance: true,
|
|
764
|
+
* enableNetworkLogs: true
|
|
765
|
+
* });
|
|
766
|
+
*
|
|
767
|
+
* logger.startTiming('token-acquisition');
|
|
768
|
+
* // ... do work
|
|
769
|
+
* logger.endTiming('token-acquisition');
|
|
770
|
+
*
|
|
771
|
+
* logger.logRequest('GET', '/me');
|
|
685
772
|
* logger.info('User logged in', { username: 'user@example.com' });
|
|
773
|
+
*
|
|
774
|
+
* // Export logs for debugging
|
|
775
|
+
* logger.downloadLogs();
|
|
686
776
|
* ```
|
|
687
777
|
*/
|
|
688
778
|
declare function getDebugLogger(config?: DebugLoggerConfig): DebugLogger;
|
|
@@ -691,7 +781,10 @@ declare function getDebugLogger(config?: DebugLoggerConfig): DebugLogger;
|
|
|
691
781
|
*
|
|
692
782
|
* @example
|
|
693
783
|
* ```tsx
|
|
694
|
-
* const logger = createScopedLogger('GraphAPI', {
|
|
784
|
+
* const logger = createScopedLogger('GraphAPI', {
|
|
785
|
+
* enabled: true,
|
|
786
|
+
* enableNetworkLogs: true
|
|
787
|
+
* });
|
|
695
788
|
* logger.info('Fetching user profile');
|
|
696
789
|
* ```
|
|
697
790
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -661,18 +661,94 @@ interface DebugLoggerConfig {
|
|
|
661
661
|
* @default 'info'
|
|
662
662
|
*/
|
|
663
663
|
level?: 'error' | 'warn' | 'info' | 'debug';
|
|
664
|
+
/**
|
|
665
|
+
* Enable performance tracking
|
|
666
|
+
* @default false
|
|
667
|
+
*/
|
|
668
|
+
enablePerformance?: boolean;
|
|
669
|
+
/**
|
|
670
|
+
* Enable network request logging
|
|
671
|
+
* @default false
|
|
672
|
+
*/
|
|
673
|
+
enableNetworkLogs?: boolean;
|
|
674
|
+
/**
|
|
675
|
+
* Maximum log history size
|
|
676
|
+
* @default 100
|
|
677
|
+
*/
|
|
678
|
+
maxHistorySize?: number;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Log entry for history tracking
|
|
682
|
+
*/
|
|
683
|
+
interface LogEntry {
|
|
684
|
+
timestamp: number;
|
|
685
|
+
level: string;
|
|
686
|
+
message: string;
|
|
687
|
+
data?: any;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Performance timing entry
|
|
691
|
+
*/
|
|
692
|
+
interface PerformanceTiming {
|
|
693
|
+
operation: string;
|
|
694
|
+
startTime: number;
|
|
695
|
+
endTime?: number;
|
|
696
|
+
duration?: number;
|
|
664
697
|
}
|
|
665
698
|
declare class DebugLogger {
|
|
666
699
|
private config;
|
|
700
|
+
private logHistory;
|
|
701
|
+
private performanceTimings;
|
|
667
702
|
constructor(config?: DebugLoggerConfig);
|
|
668
703
|
private shouldLog;
|
|
669
704
|
private formatMessage;
|
|
705
|
+
private addToHistory;
|
|
670
706
|
error(message: string, data?: any): void;
|
|
671
707
|
warn(message: string, data?: any): void;
|
|
672
708
|
info(message: string, data?: any): void;
|
|
673
709
|
debug(message: string, data?: any): void;
|
|
674
710
|
group(label: string): void;
|
|
675
711
|
groupEnd(): void;
|
|
712
|
+
/**
|
|
713
|
+
* Start performance timing for an operation
|
|
714
|
+
*/
|
|
715
|
+
startTiming(operation: string): void;
|
|
716
|
+
/**
|
|
717
|
+
* End performance timing for an operation
|
|
718
|
+
*/
|
|
719
|
+
endTiming(operation: string): number | undefined;
|
|
720
|
+
/**
|
|
721
|
+
* Log network request
|
|
722
|
+
*/
|
|
723
|
+
logRequest(method: string, url: string, options?: any): void;
|
|
724
|
+
/**
|
|
725
|
+
* Log network response
|
|
726
|
+
*/
|
|
727
|
+
logResponse(method: string, url: string, status: number, data?: any): void;
|
|
728
|
+
/**
|
|
729
|
+
* Get log history
|
|
730
|
+
*/
|
|
731
|
+
getHistory(): LogEntry[];
|
|
732
|
+
/**
|
|
733
|
+
* Get performance timings
|
|
734
|
+
*/
|
|
735
|
+
getPerformanceTimings(): PerformanceTiming[];
|
|
736
|
+
/**
|
|
737
|
+
* Clear log history
|
|
738
|
+
*/
|
|
739
|
+
clearHistory(): void;
|
|
740
|
+
/**
|
|
741
|
+
* Clear performance timings
|
|
742
|
+
*/
|
|
743
|
+
clearTimings(): void;
|
|
744
|
+
/**
|
|
745
|
+
* Export logs as JSON
|
|
746
|
+
*/
|
|
747
|
+
exportLogs(): string;
|
|
748
|
+
/**
|
|
749
|
+
* Download logs as a file
|
|
750
|
+
*/
|
|
751
|
+
downloadLogs(filename?: string): void;
|
|
676
752
|
setEnabled(enabled: boolean): void;
|
|
677
753
|
setLevel(level: DebugLoggerConfig['level']): void;
|
|
678
754
|
}
|
|
@@ -681,8 +757,22 @@ declare class DebugLogger {
|
|
|
681
757
|
*
|
|
682
758
|
* @example
|
|
683
759
|
* ```tsx
|
|
684
|
-
* const logger = getDebugLogger({
|
|
760
|
+
* const logger = getDebugLogger({
|
|
761
|
+
* enabled: true,
|
|
762
|
+
* level: 'debug',
|
|
763
|
+
* enablePerformance: true,
|
|
764
|
+
* enableNetworkLogs: true
|
|
765
|
+
* });
|
|
766
|
+
*
|
|
767
|
+
* logger.startTiming('token-acquisition');
|
|
768
|
+
* // ... do work
|
|
769
|
+
* logger.endTiming('token-acquisition');
|
|
770
|
+
*
|
|
771
|
+
* logger.logRequest('GET', '/me');
|
|
685
772
|
* logger.info('User logged in', { username: 'user@example.com' });
|
|
773
|
+
*
|
|
774
|
+
* // Export logs for debugging
|
|
775
|
+
* logger.downloadLogs();
|
|
686
776
|
* ```
|
|
687
777
|
*/
|
|
688
778
|
declare function getDebugLogger(config?: DebugLoggerConfig): DebugLogger;
|
|
@@ -691,7 +781,10 @@ declare function getDebugLogger(config?: DebugLoggerConfig): DebugLogger;
|
|
|
691
781
|
*
|
|
692
782
|
* @example
|
|
693
783
|
* ```tsx
|
|
694
|
-
* const logger = createScopedLogger('GraphAPI', {
|
|
784
|
+
* const logger = createScopedLogger('GraphAPI', {
|
|
785
|
+
* enabled: true,
|
|
786
|
+
* enableNetworkLogs: true
|
|
787
|
+
* });
|
|
695
788
|
* logger.info('Fetching user profile');
|
|
696
789
|
* ```
|
|
697
790
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var msalReact=require('@azure/msal-react'),msalBrowser=require('@azure/msal-browser'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),server=require('next/server');function z(r,e){try{let t=JSON.parse(r);return e(t)?t:(console.warn("[Validation] JSON validation failed"),null)}catch(t){return console.error("[Validation] JSON parse error:",t),null}}function B(r){return typeof r=="object"&&r!==null&&typeof r.homeAccountId=="string"&&r.homeAccountId.length>0&&typeof r.username=="string"&&r.username.length>0&&(r.name===void 0||typeof r.name=="string")}function C(r){return r instanceof Error?r.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function G(r,e){try{let t=new URL(r);return e.some(o=>{let n=new URL(o);return t.origin===n.origin})}catch{return false}}function oe(r){return /^[a-zA-Z0-9._-]+$/.test(r)}function me(r){return Array.isArray(r)&&r.every(oe)}function V(r){if(r.msalConfig)return r.msalConfig;let{clientId:e,tenantId:t,authorityType:o="common",redirectUri:n,postLogoutRedirectUri:u,cacheLocation:d="sessionStorage",storeAuthStateInCookie:l=false,navigateToLoginRequestUrl:c=true,enableLogging:s=false,loggerCallback:h,allowedRedirectUris:p}=r;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let m=()=>{if(o==="tenant"){if(!t)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${t}`}return `https://login.microsoftonline.com/${o}`},g=typeof window<"u"?window.location.origin:"http://localhost:3000",y=n||g;if(p&&p.length>0){if(!G(y,p))throw new Error(`@chemmangat/msal-next: redirectUri "${y}" is not in the allowed list`);let i=u||y;if(!G(i,p))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${i}" is not in the allowed list`)}return {auth:{clientId:e,authority:m(),redirectUri:y,postLogoutRedirectUri:u||y,navigateToLoginRequestUrl:c},cache:{cacheLocation:d,storeAuthStateInCookie:l},system:{loggerOptions:{loggerCallback:h||((i,a,b)=>{if(!(b||!s))switch(i){case msalBrowser.LogLevel.Error:console.error("[MSAL]",a);break;case msalBrowser.LogLevel.Warning:console.warn("[MSAL]",a);break;case msalBrowser.LogLevel.Info:console.info("[MSAL]",a);break;case msalBrowser.LogLevel.Verbose:console.debug("[MSAL]",a);break}}),logLevel:s?msalBrowser.LogLevel.Verbose:msalBrowser.LogLevel.Error}}}}var ie=null;function Re(){return ie}function ve({children:r,loadingComponent:e,onInitialized:t,...o}){let[n,u]=react.useState(null),d=react.useRef(null);return react.useEffect(()=>{if(typeof window>"u"||d.current)return;(async()=>{try{let c=V(o),s=new msalBrowser.PublicClientApplication(c);await s.initialize(),await s.handleRedirectPromise()&&o.enableLogging&&console.log("[MSAL] Redirect authentication successful");let p=o.enableLogging||!1;s.addEventCallback(m=>{if(m.eventType===msalBrowser.EventType.LOGIN_SUCCESS&&p){let g=m.payload;console.log("[MSAL] Login successful:",g.account?.username);}m.eventType===msalBrowser.EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",m.error),m.eventType===msalBrowser.EventType.LOGOUT_SUCCESS&&p&&console.log("[MSAL] Logout successful");}),d.current=s,ie=s,u(s),t&&t(s);}catch(c){throw console.error("[MSAL] Initialization failed:",c),c}})();},[]),typeof window>"u"?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})}):n?jsxRuntime.jsx(msalReact.MsalProvider,{instance:n,children:r}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})})}var _=new Map;function A(r=["User.Read"]){let{instance:e,accounts:t,inProgress:o}=msalReact.useMsal(),n=msalReact.useAccount(t[0]||null),u=react.useRef(false),d=react.useMemo(()=>t.length>0,[t]),l=react.useCallback(async(i=r)=>{try{let a={scopes:i,prompt:"select_account"};await e.loginPopup(a);}catch(a){throw console.error("[MSAL] Login popup failed:",a),a}},[e,r]),c=react.useCallback(async(i=r)=>{try{let a={scopes:i,prompt:"select_account"};await e.loginRedirect(a);}catch(a){throw console.error("[MSAL] Login redirect failed:",a),a}},[e,r]),s=react.useCallback(async()=>{try{await e.logoutPopup({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout popup failed:",i),i}},[e,n]),h=react.useCallback(async()=>{try{await e.logoutRedirect({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout redirect failed:",i),i}},[e,n]),p=react.useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let a={scopes:i,account:n,forceRefresh:!1};return (await e.acquireTokenSilent(a)).accessToken}catch(a){throw console.error("[MSAL] Silent token acquisition failed:",a),a}},[e,n,r]),m=react.useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");if(u.current)throw new Error("[MSAL] Popup already in progress. Please wait.");try{u.current=!0;let a={scopes:i,account:n};return (await e.acquireTokenPopup(a)).accessToken}catch(a){throw console.error("[MSAL] Token popup acquisition failed:",a),a}finally{u.current=false;}},[e,n,r]),g=react.useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let a={scopes:i,account:n};await e.acquireTokenRedirect(a);}catch(a){throw console.error("[MSAL] Token redirect acquisition failed:",a),a}},[e,n,r]),y=react.useCallback(async(i=r)=>{let a=`${n?.homeAccountId||"anonymous"}-${i.sort().join(",")}`,b=_.get(a);if(b)return b;let v=(async()=>{try{return await p(i)}catch{return console.warn("[MSAL] Silent token acquisition failed, falling back to popup"),await m(i)}finally{_.delete(a);}})();return _.set(a,v),v},[p,m,r,n]),f=react.useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:n,accounts:t,isAuthenticated:d,inProgress:o!==msalBrowser.InteractionStatus.None,loginPopup:l,loginRedirect:c,logoutPopup:s,logoutRedirect:h,acquireToken:y,acquireTokenSilent:p,acquireTokenPopup:m,acquireTokenRedirect:g,clearSession:f}}function Le({text:r="Sign in with Microsoft",variant:e="dark",size:t="medium",useRedirect:o=false,scopes:n,className:u="",style:d,onSuccess:l,onError:c}){let{loginPopup:s,loginRedirect:h,inProgress:p}=A(),m=async()=>{try{o?await h(n):await s(n),l?.();}catch(i){c?.(i);}},g={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},f={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:p?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:p?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...g[t],...d};return jsxRuntime.jsxs("button",{onClick:m,disabled:p,className:u,style:f,"aria-label":r,children:[jsxRuntime.jsx(Me,{}),jsxRuntime.jsx("span",{children:r})]})}function Me(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function Ue({text:r="Sign out",variant:e="dark",size:t="medium",useRedirect:o=false,className:n="",style:u,onSuccess:d,onError:l}){let{logoutPopup:c,logoutRedirect:s,inProgress:h}=A(),p=async()=>{try{o?await s():await c(),d?.();}catch(f){l?.(f);}},m={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},y={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:h?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:h?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...m[t],...u};return jsxRuntime.jsxs("button",{onClick:p,disabled:h,className:n,style:y,"aria-label":r,children:[jsxRuntime.jsx(ke,{}),jsxRuntime.jsx("span",{children:r})]})}function ke(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function U(){let{acquireToken:r}=A(),e=react.useCallback(async(l,c={})=>{let{scopes:s=["User.Read"],version:h="v1.0",debug:p=false,...m}=c;try{let g=await r(s),y=`https://graph.microsoft.com/${h}`,f=l.startsWith("http")?l:`${y}${l.startsWith("/")?l:`/${l}`}`;p&&console.log("[GraphAPI] Request:",{url:f,method:m.method||"GET"});let i=await fetch(f,{...m,headers:{Authorization:`Bearer ${g}`,"Content-Type":"application/json",...m.headers}});if(!i.ok){let b=await i.text(),v=`Graph API error (${i.status}): ${b}`;throw new Error(v)}if(i.status===204||i.headers.get("content-length")==="0")return null;let a=await i.json();return p&&console.log("[GraphAPI] Response:",a),a}catch(g){let y=C(g);throw console.error("[GraphAPI] Request failed:",y),new Error(y)}},[r]),t=react.useCallback((l,c={})=>e(l,{...c,method:"GET"}),[e]),o=react.useCallback((l,c,s={})=>e(l,{...s,method:"POST",body:c?JSON.stringify(c):void 0}),[e]),n=react.useCallback((l,c,s={})=>e(l,{...s,method:"PUT",body:c?JSON.stringify(c):void 0}),[e]),u=react.useCallback((l,c,s={})=>e(l,{...s,method:"PATCH",body:c?JSON.stringify(c):void 0}),[e]),d=react.useCallback((l,c={})=>e(l,{...c,method:"DELETE"}),[e]);return {get:t,post:o,put:n,patch:u,delete:d,request:e}}var R=new Map,Fe=300*1e3,ue=100;function Ie(){if(R.size>ue){let r=Array.from(R.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,R.size-ue).forEach(([t])=>{let o=R.get(t);o?.data.photo&&URL.revokeObjectURL(o.data.photo),R.delete(t);});}}function J(){let{isAuthenticated:r,account:e}=A(),t=U(),[o,n]=react.useState(null),[u,d]=react.useState(false),[l,c]=react.useState(null),s=react.useCallback(async()=>{if(!r||!e){n(null);return}let p=e.homeAccountId,m=R.get(p);if(m&&Date.now()-m.timestamp<Fe){n(m.data);return}d(true),c(null);try{let g=await t.get("/me",{scopes:["User.Read"]}),y;try{let i=await t.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});i&&(y=URL.createObjectURL(i));}catch{console.debug("[UserProfile] Photo not available");}let f={id:g.id,displayName:g.displayName,givenName:g.givenName,surname:g.surname,userPrincipalName:g.userPrincipalName,mail:g.mail,jobTitle:g.jobTitle,officeLocation:g.officeLocation,mobilePhone:g.mobilePhone,businessPhones:g.businessPhones,photo:y};R.set(p,{data:f,timestamp:Date.now()}),Ie(),n(f);}catch(g){let f=C(g),i=new Error(f);c(i),console.error("[UserProfile] Failed to fetch profile:",f);}finally{d(false);}},[r,e,t]),h=react.useCallback(()=>{if(e){let p=R.get(e.homeAccountId);p?.data.photo&&URL.revokeObjectURL(p.data.photo),R.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),n(null);},[e,o]);return react.useEffect(()=>(s(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[s]),react.useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:u,error:l,refetch:s,clearCache:h}}function De({size:r=40,className:e="",style:t,showTooltip:o=true,fallbackImage:n}){let{profile:u,loading:d}=J(),[l,c]=react.useState(null),[s,h]=react.useState(false);react.useEffect(()=>{u?.photo&&c(u.photo);},[u?.photo]);let p=()=>{if(!u)return "?";let{givenName:y,surname:f,displayName:i}=u;if(y&&f)return `${y[0]}${f[0]}`.toUpperCase();if(i){let a=i.split(" ");return a.length>=2?`${a[0][0]}${a[a.length-1][0]}`.toUpperCase():i.substring(0,2).toUpperCase()}return "?"},m={width:`${r}px`,height:`${r}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${r*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...t},g=u?.displayName||"User";return d?jsxRuntime.jsx("div",{className:e,style:{...m,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsxRuntime.jsx("span",{style:{fontSize:`${r*.3}px`},children:"..."})}):l&&!s?jsxRuntime.jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:jsxRuntime.jsx("img",{src:l,alt:g,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{h(true),n&&c(n);}})}):jsxRuntime.jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:p()})}function Oe({className:r="",style:e,showDetails:t=false,renderLoading:o,renderAuthenticated:n,renderUnauthenticated:u}){let{isAuthenticated:d,inProgress:l,account:c}=A(),s={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(l)return o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o()}):jsxRuntime.jsxs("div",{className:r,style:{...s,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(Z,{color:"#FFA500"}),jsxRuntime.jsx("span",{children:"Loading..."})]});if(d){let h=c?.username||c?.name||"User";return n?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n(h)}):jsxRuntime.jsxs("div",{className:r,style:{...s,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(Z,{color:"#28A745"}),jsxRuntime.jsx("span",{children:t?`Authenticated as ${h}`:"Authenticated"})]})}return u?jsxRuntime.jsx(jsxRuntime.Fragment,{children:u()}):jsxRuntime.jsxs("div",{className:r,style:{...s,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(Z,{color:"#DC3545"}),jsxRuntime.jsx("span",{children:"Not authenticated"})]})}function Z({color:r}){return jsxRuntime.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("circle",{cx:"4",cy:"4",r:"4",fill:r})})}function Q({children:r,loadingComponent:e,fallbackComponent:t,useRedirect:o=true,scopes:n,onAuthRequired:u}){let{isAuthenticated:d,inProgress:l,loginRedirect:c,loginPopup:s}=A();return react.useEffect(()=>{!d&&!l&&(u?.(),(async()=>{try{o?await c(n):await s(n);}catch(p){console.error("[AuthGuard] Authentication failed:",p);}})());},[d,l,o,n,c,s,u]),l?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Authenticating..."})}):d?jsxRuntime.jsx(jsxRuntime.Fragment,{children:r}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:t||jsxRuntime.jsx("div",{children:"Redirecting to login..."})})}var ee=class extends react.Component{constructor(t){super(t);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(t){return {hasError:true,error:t}}componentDidCatch(t,o){let{onError:n,debug:u}=this.props;u&&(console.error("[ErrorBoundary] Caught error:",t),console.error("[ErrorBoundary] Error info:",o)),n?.(t,o);}render(){let{hasError:t,error:o}=this.state,{children:n,fallback:u}=this.props;return t&&o?u?u(o,this.reset):jsxRuntime.jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsxRuntime.jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsxRuntime.jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsxRuntime.jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):n}};var w=new Map,Be=300*1e3,de=100;function Ve(r){r?w.delete(r):w.clear();}function We(){if(w.size>de){let r=Array.from(w.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,w.size-de).forEach(([t])=>w.delete(t));}}function _e(){let{isAuthenticated:r,account:e}=A(),t=U(),[o,n]=react.useState([]),[u,d]=react.useState([]),[l,c]=react.useState(false),[s,h]=react.useState(null),p=react.useCallback(async()=>{if(!r||!e){n([]),d([]);return}let i=e.homeAccountId,a=w.get(i);if(a&&Date.now()-a.timestamp<Be){n(a.roles),d(a.groups);return}c(true),h(null);try{let v=e.idTokenClaims?.roles||[],O=(await t.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(te=>te.id);w.set(i,{roles:v,groups:O,timestamp:Date.now()}),We(),n(v),d(O);}catch(b){let D=C(b),O=new Error(D);h(O),console.error("[Roles] Failed to fetch roles/groups:",D);let he=e.idTokenClaims?.roles||[];n(he);}finally{c(false);}},[r,e,t]),m=react.useCallback(i=>o.includes(i),[o]),g=react.useCallback(i=>u.includes(i),[u]),y=react.useCallback(i=>i.some(a=>o.includes(a)),[o]),f=react.useCallback(i=>i.every(a=>o.includes(a)),[o]);return react.useEffect(()=>(p(),()=>{e&&Ve(e.homeAccountId);}),[p,e]),{roles:o,groups:u,loading:l,error:s,hasRole:m,hasGroup:g,hasAnyRole:y,hasAllRoles:f,refetch:p}}function je(r,e={}){let{displayName:t,...o}=e,n=u=>jsxRuntime.jsx(Q,{...o,children:jsxRuntime.jsx(r,{...u})});return n.displayName=t||`withAuth(${r.displayName||r.name||"Component"})`,n}async function fe(r,e={}){let{maxRetries:t=3,initialDelay:o=1e3,maxDelay:n=1e4,backoffMultiplier:u=2,debug:d=false}=e,l,c=o;for(let s=0;s<=t;s++)try{return d&&s>0&&console.log(`[TokenRetry] Attempt ${s+1}/${t+1}`),await r()}catch(h){if(l=h,s===t){d&&console.error("[TokenRetry] All retry attempts failed");break}if(!Je(h))throw d&&console.log("[TokenRetry] Non-retryable error, aborting"),h;d&&console.warn(`[TokenRetry] Attempt ${s+1} failed, retrying in ${c}ms...`),await Ze(c),c=Math.min(c*u,n);}throw l}function Je(r){let e=r.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function Ze(r){return new Promise(e=>setTimeout(e,r))}function He(r,e={}){return (...t)=>fe(()=>r(...t),e)}var $=class{constructor(e={}){this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info"};}shouldLog(e){if(!this.config.enabled)return false;let t=["error","warn","info","debug"],o=t.indexOf(this.config.level);return t.indexOf(e)<=o}formatMessage(e,t,o){let n=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",u=this.config.prefix,d=`[${e.toUpperCase()}]`,l=`${n} ${u} ${d} ${t}`;return o!==void 0&&(l+=`
|
|
2
|
-
`+JSON.stringify(o,null,2)),
|
|
1
|
+
'use strict';var msalReact=require('@azure/msal-react'),msalBrowser=require('@azure/msal-browser'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),server=require('next/server');function z(r,e){try{let t=JSON.parse(r);return e(t)?t:(console.warn("[Validation] JSON validation failed"),null)}catch(t){return console.error("[Validation] JSON parse error:",t),null}}function B(r){return typeof r=="object"&&r!==null&&typeof r.homeAccountId=="string"&&r.homeAccountId.length>0&&typeof r.username=="string"&&r.username.length>0&&(r.name===void 0||typeof r.name=="string")}function S(r){return r instanceof Error?r.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function G(r,e){try{let t=new URL(r);return e.some(o=>{let n=new URL(o);return t.origin===n.origin})}catch{return false}}function oe(r){return /^[a-zA-Z0-9._-]+$/.test(r)}function me(r){return Array.isArray(r)&&r.every(oe)}function H(r){if(r.msalConfig)return r.msalConfig;let{clientId:e,tenantId:t,authorityType:o="common",redirectUri:n,postLogoutRedirectUri:a,cacheLocation:d="sessionStorage",storeAuthStateInCookie:c=false,navigateToLoginRequestUrl:u=true,enableLogging:s=false,loggerCallback:h,allowedRedirectUris:p}=r;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let m=()=>{if(o==="tenant"){if(!t)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${t}`}return `https://login.microsoftonline.com/${o}`},g=typeof window<"u"?window.location.origin:"http://localhost:3000",y=n||g;if(p&&p.length>0){if(!G(y,p))throw new Error(`@chemmangat/msal-next: redirectUri "${y}" is not in the allowed list`);let i=a||y;if(!G(i,p))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${i}" is not in the allowed list`)}return {auth:{clientId:e,authority:m(),redirectUri:y,postLogoutRedirectUri:a||y,navigateToLoginRequestUrl:u},cache:{cacheLocation:d,storeAuthStateInCookie:c},system:{loggerOptions:{loggerCallback:h||((i,l,A)=>{if(!(A||!s))switch(i){case msalBrowser.LogLevel.Error:console.error("[MSAL]",l);break;case msalBrowser.LogLevel.Warning:console.warn("[MSAL]",l);break;case msalBrowser.LogLevel.Info:console.info("[MSAL]",l);break;case msalBrowser.LogLevel.Verbose:console.debug("[MSAL]",l);break}}),logLevel:s?msalBrowser.LogLevel.Verbose:msalBrowser.LogLevel.Error}}}}var ie=null;function Pe(){return ie}function ve({children:r,loadingComponent:e,onInitialized:t,...o}){let[n,a]=react.useState(null),d=react.useRef(null);return react.useEffect(()=>{if(typeof window>"u"||d.current)return;(async()=>{try{let u=H(o),s=new msalBrowser.PublicClientApplication(u);await s.initialize(),await s.handleRedirectPromise()&&o.enableLogging&&console.log("[MSAL] Redirect authentication successful");let p=o.enableLogging||!1;s.addEventCallback(m=>{if(m.eventType===msalBrowser.EventType.LOGIN_SUCCESS&&p){let g=m.payload;console.log("[MSAL] Login successful:",g.account?.username);}m.eventType===msalBrowser.EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",m.error),m.eventType===msalBrowser.EventType.LOGOUT_SUCCESS&&p&&console.log("[MSAL] Logout successful");}),d.current=s,ie=s,a(s),t&&t(s);}catch(u){throw console.error("[MSAL] Initialization failed:",u),u}})();},[]),typeof window>"u"?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})}):n?jsxRuntime.jsx(msalReact.MsalProvider,{instance:n,children:r}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})})}var W=new Map;function b(r=["User.Read"]){let{instance:e,accounts:t,inProgress:o}=msalReact.useMsal(),n=msalReact.useAccount(t[0]||null),a=react.useRef(false),d=react.useMemo(()=>t.length>0,[t]),c=react.useCallback(async(i=r)=>{try{let l={scopes:i,prompt:"select_account"};await e.loginPopup(l);}catch(l){throw console.error("[MSAL] Login popup failed:",l),l}},[e,r]),u=react.useCallback(async(i=r)=>{try{let l={scopes:i,prompt:"select_account"};await e.loginRedirect(l);}catch(l){throw console.error("[MSAL] Login redirect failed:",l),l}},[e,r]),s=react.useCallback(async()=>{try{await e.logoutPopup({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout popup failed:",i),i}},[e,n]),h=react.useCallback(async()=>{try{await e.logoutRedirect({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout redirect failed:",i),i}},[e,n]),p=react.useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let l={scopes:i,account:n,forceRefresh:!1};return (await e.acquireTokenSilent(l)).accessToken}catch(l){throw console.error("[MSAL] Silent token acquisition failed:",l),l}},[e,n,r]),m=react.useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");if(a.current)throw new Error("[MSAL] Popup already in progress. Please wait.");try{a.current=!0;let l={scopes:i,account:n};return (await e.acquireTokenPopup(l)).accessToken}catch(l){throw console.error("[MSAL] Token popup acquisition failed:",l),l}finally{a.current=false;}},[e,n,r]),g=react.useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let l={scopes:i,account:n};await e.acquireTokenRedirect(l);}catch(l){throw console.error("[MSAL] Token redirect acquisition failed:",l),l}},[e,n,r]),y=react.useCallback(async(i=r)=>{let l=`${n?.homeAccountId||"anonymous"}-${i.sort().join(",")}`,A=W.get(l);if(A)return A;let v=(async()=>{try{return await p(i)}catch{return console.warn("[MSAL] Silent token acquisition failed, falling back to popup"),await m(i)}finally{W.delete(l);}})();return W.set(l,v),v},[p,m,r,n]),f=react.useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:n,accounts:t,isAuthenticated:d,inProgress:o!==msalBrowser.InteractionStatus.None,loginPopup:c,loginRedirect:u,logoutPopup:s,logoutRedirect:h,acquireToken:y,acquireTokenSilent:p,acquireTokenPopup:m,acquireTokenRedirect:g,clearSession:f}}function Le({text:r="Sign in with Microsoft",variant:e="dark",size:t="medium",useRedirect:o=false,scopes:n,className:a="",style:d,onSuccess:c,onError:u}){let{loginPopup:s,loginRedirect:h,inProgress:p}=b(),m=async()=>{try{o?await h(n):await s(n),c?.();}catch(i){u?.(i);}},g={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},f={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:p?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:p?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...g[t],...d};return jsxRuntime.jsxs("button",{onClick:m,disabled:p,className:a,style:f,"aria-label":r,children:[jsxRuntime.jsx(ke,{}),jsxRuntime.jsx("span",{children:r})]})}function ke(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function Ue({text:r="Sign out",variant:e="dark",size:t="medium",useRedirect:o=false,className:n="",style:a,onSuccess:d,onError:c}){let{logoutPopup:u,logoutRedirect:s,inProgress:h}=b(),p=async()=>{try{o?await s():await u(),d?.();}catch(f){c?.(f);}},m={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},y={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:h?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:h?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...m[t],...a};return jsxRuntime.jsxs("button",{onClick:p,disabled:h,className:n,style:y,"aria-label":r,children:[jsxRuntime.jsx(Me,{}),jsxRuntime.jsx("span",{children:r})]})}function Me(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function U(){let{acquireToken:r}=b(),e=react.useCallback(async(c,u={})=>{let{scopes:s=["User.Read"],version:h="v1.0",debug:p=false,...m}=u;try{let g=await r(s),y=`https://graph.microsoft.com/${h}`,f=c.startsWith("http")?c:`${y}${c.startsWith("/")?c:`/${c}`}`;p&&console.log("[GraphAPI] Request:",{url:f,method:m.method||"GET"});let i=await fetch(f,{...m,headers:{Authorization:`Bearer ${g}`,"Content-Type":"application/json",...m.headers}});if(!i.ok){let A=await i.text(),v=`Graph API error (${i.status}): ${A}`;throw new Error(v)}if(i.status===204||i.headers.get("content-length")==="0")return null;let l=await i.json();return p&&console.log("[GraphAPI] Response:",l),l}catch(g){let y=S(g);throw console.error("[GraphAPI] Request failed:",y),new Error(y)}},[r]),t=react.useCallback((c,u={})=>e(c,{...u,method:"GET"}),[e]),o=react.useCallback((c,u,s={})=>e(c,{...s,method:"POST",body:u?JSON.stringify(u):void 0}),[e]),n=react.useCallback((c,u,s={})=>e(c,{...s,method:"PUT",body:u?JSON.stringify(u):void 0}),[e]),a=react.useCallback((c,u,s={})=>e(c,{...s,method:"PATCH",body:u?JSON.stringify(u):void 0}),[e]),d=react.useCallback((c,u={})=>e(c,{...u,method:"DELETE"}),[e]);return {get:t,post:o,put:n,patch:a,delete:d,request:e}}var P=new Map,Fe=300*1e3,ue=100;function Ne(){if(P.size>ue){let r=Array.from(P.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,P.size-ue).forEach(([t])=>{let o=P.get(t);o?.data.photo&&URL.revokeObjectURL(o.data.photo),P.delete(t);});}}function j(){let{isAuthenticated:r,account:e}=b(),t=U(),[o,n]=react.useState(null),[a,d]=react.useState(false),[c,u]=react.useState(null),s=react.useCallback(async()=>{if(!r||!e){n(null);return}let p=e.homeAccountId,m=P.get(p);if(m&&Date.now()-m.timestamp<Fe){n(m.data);return}d(true),u(null);try{let g=await t.get("/me",{scopes:["User.Read"]}),y;try{let i=await t.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});i&&(y=URL.createObjectURL(i));}catch{console.debug("[UserProfile] Photo not available");}let f={id:g.id,displayName:g.displayName,givenName:g.givenName,surname:g.surname,userPrincipalName:g.userPrincipalName,mail:g.mail,jobTitle:g.jobTitle,officeLocation:g.officeLocation,mobilePhone:g.mobilePhone,businessPhones:g.businessPhones,photo:y};P.set(p,{data:f,timestamp:Date.now()}),Ne(),n(f);}catch(g){let f=S(g),i=new Error(f);u(i),console.error("[UserProfile] Failed to fetch profile:",f);}finally{d(false);}},[r,e,t]),h=react.useCallback(()=>{if(e){let p=P.get(e.homeAccountId);p?.data.photo&&URL.revokeObjectURL(p.data.photo),P.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),n(null);},[e,o]);return react.useEffect(()=>(s(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[s]),react.useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:a,error:c,refetch:s,clearCache:h}}function De({size:r=40,className:e="",style:t,showTooltip:o=true,fallbackImage:n}){let{profile:a,loading:d}=j(),[c,u]=react.useState(null),[s,h]=react.useState(false);react.useEffect(()=>{a?.photo&&u(a.photo);},[a?.photo]);let p=()=>{if(!a)return "?";let{givenName:y,surname:f,displayName:i}=a;if(y&&f)return `${y[0]}${f[0]}`.toUpperCase();if(i){let l=i.split(" ");return l.length>=2?`${l[0][0]}${l[l.length-1][0]}`.toUpperCase():i.substring(0,2).toUpperCase()}return "?"},m={width:`${r}px`,height:`${r}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${r*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...t},g=a?.displayName||"User";return d?jsxRuntime.jsx("div",{className:e,style:{...m,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsxRuntime.jsx("span",{style:{fontSize:`${r*.3}px`},children:"..."})}):c&&!s?jsxRuntime.jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:jsxRuntime.jsx("img",{src:c,alt:g,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{h(true),n&&u(n);}})}):jsxRuntime.jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:p()})}function Oe({className:r="",style:e,showDetails:t=false,renderLoading:o,renderAuthenticated:n,renderUnauthenticated:a}){let{isAuthenticated:d,inProgress:c,account:u}=b(),s={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(c)return o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o()}):jsxRuntime.jsxs("div",{className:r,style:{...s,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(J,{color:"#FFA500"}),jsxRuntime.jsx("span",{children:"Loading..."})]});if(d){let h=u?.username||u?.name||"User";return n?jsxRuntime.jsx(jsxRuntime.Fragment,{children:n(h)}):jsxRuntime.jsxs("div",{className:r,style:{...s,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(J,{color:"#28A745"}),jsxRuntime.jsx("span",{children:t?`Authenticated as ${h}`:"Authenticated"})]})}return a?jsxRuntime.jsx(jsxRuntime.Fragment,{children:a()}):jsxRuntime.jsxs("div",{className:r,style:{...s,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(J,{color:"#DC3545"}),jsxRuntime.jsx("span",{children:"Not authenticated"})]})}function J({color:r}){return jsxRuntime.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("circle",{cx:"4",cy:"4",r:"4",fill:r})})}function Q({children:r,loadingComponent:e,fallbackComponent:t,useRedirect:o=true,scopes:n,onAuthRequired:a}){let{isAuthenticated:d,inProgress:c,loginRedirect:u,loginPopup:s}=b();return react.useEffect(()=>{!d&&!c&&(a?.(),(async()=>{try{o?await u(n):await s(n);}catch(p){console.error("[AuthGuard] Authentication failed:",p);}})());},[d,c,o,n,u,s,a]),c?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Authenticating..."})}):d?jsxRuntime.jsx(jsxRuntime.Fragment,{children:r}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:t||jsxRuntime.jsx("div",{children:"Redirecting to login..."})})}var ee=class extends react.Component{constructor(t){super(t);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(t){return {hasError:true,error:t}}componentDidCatch(t,o){let{onError:n,debug:a}=this.props;a&&(console.error("[ErrorBoundary] Caught error:",t),console.error("[ErrorBoundary] Error info:",o)),n?.(t,o);}render(){let{hasError:t,error:o}=this.state,{children:n,fallback:a}=this.props;return t&&o?a?a(o,this.reset):jsxRuntime.jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsxRuntime.jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsxRuntime.jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsxRuntime.jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):n}};var R=new Map,Be=300*1e3,de=100;function He(r){r?R.delete(r):R.clear();}function Ve(){if(R.size>de){let r=Array.from(R.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,R.size-de).forEach(([t])=>R.delete(t));}}function We(){let{isAuthenticated:r,account:e}=b(),t=U(),[o,n]=react.useState([]),[a,d]=react.useState([]),[c,u]=react.useState(false),[s,h]=react.useState(null),p=react.useCallback(async()=>{if(!r||!e){n([]),d([]);return}let i=e.homeAccountId,l=R.get(i);if(l&&Date.now()-l.timestamp<Be){n(l.roles),d(l.groups);return}u(true),h(null);try{let v=e.idTokenClaims?.roles||[],O=(await t.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(te=>te.id);R.set(i,{roles:v,groups:O,timestamp:Date.now()}),Ve(),n(v),d(O);}catch(A){let D=S(A),O=new Error(D);h(O),console.error("[Roles] Failed to fetch roles/groups:",D);let he=e.idTokenClaims?.roles||[];n(he);}finally{u(false);}},[r,e,t]),m=react.useCallback(i=>o.includes(i),[o]),g=react.useCallback(i=>a.includes(i),[a]),y=react.useCallback(i=>i.some(l=>o.includes(l)),[o]),f=react.useCallback(i=>i.every(l=>o.includes(l)),[o]);return react.useEffect(()=>(p(),()=>{e&&He(e.homeAccountId);}),[p,e]),{roles:o,groups:a,loading:c,error:s,hasRole:m,hasGroup:g,hasAnyRole:y,hasAllRoles:f,refetch:p}}function _e(r,e={}){let{displayName:t,...o}=e,n=a=>jsxRuntime.jsx(Q,{...o,children:jsxRuntime.jsx(r,{...a})});return n.displayName=t||`withAuth(${r.displayName||r.name||"Component"})`,n}async function fe(r,e={}){let{maxRetries:t=3,initialDelay:o=1e3,maxDelay:n=1e4,backoffMultiplier:a=2,debug:d=false}=e,c,u=o;for(let s=0;s<=t;s++)try{return d&&s>0&&console.log(`[TokenRetry] Attempt ${s+1}/${t+1}`),await r()}catch(h){if(c=h,s===t){d&&console.error("[TokenRetry] All retry attempts failed");break}if(!je(h))throw d&&console.log("[TokenRetry] Non-retryable error, aborting"),h;d&&console.warn(`[TokenRetry] Attempt ${s+1} failed, retrying in ${u}ms...`),await Je(u),u=Math.min(u*a,n);}throw c}function je(r){let e=r.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function Je(r){return new Promise(e=>setTimeout(e,r))}function Ze(r,e={}){return (...t)=>fe(()=>r(...t),e)}var q=class{constructor(e={}){this.logHistory=[];this.performanceTimings=new Map;this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info",enablePerformance:e.enablePerformance??false,enableNetworkLogs:e.enableNetworkLogs??false,maxHistorySize:e.maxHistorySize??100};}shouldLog(e){if(!this.config.enabled)return false;let t=["error","warn","info","debug"],o=t.indexOf(this.config.level);return t.indexOf(e)<=o}formatMessage(e,t,o){let n=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",a=this.config.prefix,d=`[${e.toUpperCase()}]`,c=`${n} ${a} ${d} ${t}`;return o!==void 0&&(c+=`
|
|
2
|
+
`+JSON.stringify(o,null,2)),c}addToHistory(e,t,o){this.logHistory.length>=this.config.maxHistorySize&&this.logHistory.shift(),this.logHistory.push({timestamp:Date.now(),level:e,message:t,data:o});}error(e,t){this.shouldLog("error")&&(console.error(this.formatMessage("error",e,t)),this.addToHistory("error",e,t));}warn(e,t){this.shouldLog("warn")&&(console.warn(this.formatMessage("warn",e,t)),this.addToHistory("warn",e,t));}info(e,t){this.shouldLog("info")&&(console.info(this.formatMessage("info",e,t)),this.addToHistory("info",e,t));}debug(e,t){this.shouldLog("debug")&&(console.debug(this.formatMessage("debug",e,t)),this.addToHistory("debug",e,t));}group(e){this.config.enabled&&console.group(`${this.config.prefix} ${e}`);}groupEnd(){this.config.enabled&&console.groupEnd();}startTiming(e){this.config.enablePerformance&&(this.performanceTimings.set(e,{operation:e,startTime:performance.now()}),this.debug(`\u23F1\uFE0F Started: ${e}`));}endTiming(e){if(this.config.enablePerformance){let t=this.performanceTimings.get(e);if(t)return t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.info(`\u23F1\uFE0F Completed: ${e} (${t.duration.toFixed(2)}ms)`),t.duration}}logRequest(e,t,o){this.config.enableNetworkLogs&&this.debug(`\u{1F310} ${e} ${t}`,o);}logResponse(e,t,o,n){if(this.config.enableNetworkLogs){let a=o>=200&&o<300?"\u2705":"\u274C";this.debug(`${a} ${e} ${t} - ${o}`,n);}}getHistory(){return [...this.logHistory]}getPerformanceTimings(){return Array.from(this.performanceTimings.values())}clearHistory(){this.logHistory=[];}clearTimings(){this.performanceTimings.clear();}exportLogs(){return JSON.stringify({config:this.config,history:this.logHistory,performanceTimings:Array.from(this.performanceTimings.values()),exportedAt:new Date().toISOString()},null,2)}downloadLogs(e="msal-next-debug-logs.json"){if(typeof window>"u")return;let t=this.exportLogs(),o=new Blob([t],{type:"application/json"}),n=URL.createObjectURL(o),a=document.createElement("a");a.href=n,a.download=e,a.click(),URL.revokeObjectURL(n);}setEnabled(e){this.config.enabled=e;}setLevel(e){e&&(this.config.level=e);}},I=null;function Ke(r){return I?r&&(r.enabled!==void 0&&I.setEnabled(r.enabled),r.level&&I.setLevel(r.level)):I=new q(r),I}function Xe(r,e){return new q({...e,prefix:`[MSAL-Next:${r}]`})}function Qe(r={}){let{protectedRoutes:e=[],publicOnlyRoutes:t=[],loginPath:o="/login",redirectAfterLogin:n="/",sessionCookie:a="msal.account",isAuthenticated:d,debug:c=false}=r;return async function(s){let{pathname:h}=s.nextUrl;c&&console.log("[AuthMiddleware] Processing:",h);let p=false;d?p=await d(s):p=!!s.cookies.get(a)?.value,c&&console.log("[AuthMiddleware] Authenticated:",p);let m=e.some(f=>h.startsWith(f)),g=t.some(f=>h.startsWith(f));if(m&&!p){c&&console.log("[AuthMiddleware] Redirecting to login");let f=s.nextUrl.clone();return f.pathname=o,f.searchParams.set("returnUrl",h),server.NextResponse.redirect(f)}if(g&&p){c&&console.log("[AuthMiddleware] Redirecting to home");let f=s.nextUrl.searchParams.get("returnUrl"),i=s.nextUrl.clone();return i.pathname=f||n,i.searchParams.delete("returnUrl"),server.NextResponse.redirect(i)}let y=server.NextResponse.next();if(p){y.headers.set("x-msal-authenticated","true");try{let f=s.cookies.get(a);if(f?.value){let i=z(f.value,B);i?.username&&y.headers.set("x-msal-username",i.username);}}catch{c&&console.warn("[AuthMiddleware] Failed to parse session data");}}return y}}Object.defineProperty(exports,"useAccount",{enumerable:true,get:function(){return msalReact.useAccount}});Object.defineProperty(exports,"useIsAuthenticated",{enumerable:true,get:function(){return msalReact.useIsAuthenticated}});Object.defineProperty(exports,"useMsal",{enumerable:true,get:function(){return msalReact.useMsal}});exports.AuthGuard=Q;exports.AuthStatus=Oe;exports.ErrorBoundary=ee;exports.MicrosoftSignInButton=Le;exports.MsalAuthProvider=ve;exports.SignOutButton=Ue;exports.UserAvatar=De;exports.createAuthMiddleware=Qe;exports.createMsalConfig=H;exports.createRetryWrapper=Ze;exports.createScopedLogger=Xe;exports.getDebugLogger=Ke;exports.getMsalInstance=Pe;exports.isValidAccountData=B;exports.isValidRedirectUri=G;exports.isValidScope=oe;exports.retryWithBackoff=fe;exports.safeJsonParse=z;exports.sanitizeError=S;exports.useGraphApi=U;exports.useMsalAuth=b;exports.useRoles=We;exports.useUserProfile=j;exports.validateScopes=me;exports.withAuth=_e;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {MsalProvider,useMsal,useAccount}from'@azure/msal-react';export{useAccount,useIsAuthenticated,useMsal}from'@azure/msal-react';import {LogLevel,PublicClientApplication,EventType,InteractionStatus}from'@azure/msal-browser';import {useState,useRef,useEffect,useMemo,useCallback,Component}from'react';import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {NextResponse}from'next/server';function z(r,e){try{let t=JSON.parse(r);return e(t)?t:(console.warn("[Validation] JSON validation failed"),null)}catch(t){return console.error("[Validation] JSON parse error:",t),null}}function B(r){return typeof r=="object"&&r!==null&&typeof r.homeAccountId=="string"&&r.homeAccountId.length>0&&typeof r.username=="string"&&r.username.length>0&&(r.name===void 0||typeof r.name=="string")}function C(r){return r instanceof Error?r.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function G(r,e){try{let t=new URL(r);return e.some(o=>{let n=new URL(o);return t.origin===n.origin})}catch{return false}}function oe(r){return /^[a-zA-Z0-9._-]+$/.test(r)}function me(r){return Array.isArray(r)&&r.every(oe)}function V(r){if(r.msalConfig)return r.msalConfig;let{clientId:e,tenantId:t,authorityType:o="common",redirectUri:n,postLogoutRedirectUri:u,cacheLocation:d="sessionStorage",storeAuthStateInCookie:l=false,navigateToLoginRequestUrl:c=true,enableLogging:s=false,loggerCallback:h,allowedRedirectUris:p}=r;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let m=()=>{if(o==="tenant"){if(!t)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${t}`}return `https://login.microsoftonline.com/${o}`},g=typeof window<"u"?window.location.origin:"http://localhost:3000",y=n||g;if(p&&p.length>0){if(!G(y,p))throw new Error(`@chemmangat/msal-next: redirectUri "${y}" is not in the allowed list`);let i=u||y;if(!G(i,p))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${i}" is not in the allowed list`)}return {auth:{clientId:e,authority:m(),redirectUri:y,postLogoutRedirectUri:u||y,navigateToLoginRequestUrl:c},cache:{cacheLocation:d,storeAuthStateInCookie:l},system:{loggerOptions:{loggerCallback:h||((i,a,b)=>{if(!(b||!s))switch(i){case LogLevel.Error:console.error("[MSAL]",a);break;case LogLevel.Warning:console.warn("[MSAL]",a);break;case LogLevel.Info:console.info("[MSAL]",a);break;case LogLevel.Verbose:console.debug("[MSAL]",a);break}}),logLevel:s?LogLevel.Verbose:LogLevel.Error}}}}var ie=null;function Re(){return ie}function ve({children:r,loadingComponent:e,onInitialized:t,...o}){let[n,u]=useState(null),d=useRef(null);return useEffect(()=>{if(typeof window>"u"||d.current)return;(async()=>{try{let c=V(o),s=new PublicClientApplication(c);await s.initialize(),await s.handleRedirectPromise()&&o.enableLogging&&console.log("[MSAL] Redirect authentication successful");let p=o.enableLogging||!1;s.addEventCallback(m=>{if(m.eventType===EventType.LOGIN_SUCCESS&&p){let g=m.payload;console.log("[MSAL] Login successful:",g.account?.username);}m.eventType===EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",m.error),m.eventType===EventType.LOGOUT_SUCCESS&&p&&console.log("[MSAL] Logout successful");}),d.current=s,ie=s,u(s),t&&t(s);}catch(c){throw console.error("[MSAL] Initialization failed:",c),c}})();},[]),typeof window>"u"?jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})}):n?jsx(MsalProvider,{instance:n,children:r}):jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})})}var _=new Map;function A(r=["User.Read"]){let{instance:e,accounts:t,inProgress:o}=useMsal(),n=useAccount(t[0]||null),u=useRef(false),d=useMemo(()=>t.length>0,[t]),l=useCallback(async(i=r)=>{try{let a={scopes:i,prompt:"select_account"};await e.loginPopup(a);}catch(a){throw console.error("[MSAL] Login popup failed:",a),a}},[e,r]),c=useCallback(async(i=r)=>{try{let a={scopes:i,prompt:"select_account"};await e.loginRedirect(a);}catch(a){throw console.error("[MSAL] Login redirect failed:",a),a}},[e,r]),s=useCallback(async()=>{try{await e.logoutPopup({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout popup failed:",i),i}},[e,n]),h=useCallback(async()=>{try{await e.logoutRedirect({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout redirect failed:",i),i}},[e,n]),p=useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let a={scopes:i,account:n,forceRefresh:!1};return (await e.acquireTokenSilent(a)).accessToken}catch(a){throw console.error("[MSAL] Silent token acquisition failed:",a),a}},[e,n,r]),m=useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");if(u.current)throw new Error("[MSAL] Popup already in progress. Please wait.");try{u.current=!0;let a={scopes:i,account:n};return (await e.acquireTokenPopup(a)).accessToken}catch(a){throw console.error("[MSAL] Token popup acquisition failed:",a),a}finally{u.current=false;}},[e,n,r]),g=useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let a={scopes:i,account:n};await e.acquireTokenRedirect(a);}catch(a){throw console.error("[MSAL] Token redirect acquisition failed:",a),a}},[e,n,r]),y=useCallback(async(i=r)=>{let a=`${n?.homeAccountId||"anonymous"}-${i.sort().join(",")}`,b=_.get(a);if(b)return b;let v=(async()=>{try{return await p(i)}catch{return console.warn("[MSAL] Silent token acquisition failed, falling back to popup"),await m(i)}finally{_.delete(a);}})();return _.set(a,v),v},[p,m,r,n]),f=useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:n,accounts:t,isAuthenticated:d,inProgress:o!==InteractionStatus.None,loginPopup:l,loginRedirect:c,logoutPopup:s,logoutRedirect:h,acquireToken:y,acquireTokenSilent:p,acquireTokenPopup:m,acquireTokenRedirect:g,clearSession:f}}function Le({text:r="Sign in with Microsoft",variant:e="dark",size:t="medium",useRedirect:o=false,scopes:n,className:u="",style:d,onSuccess:l,onError:c}){let{loginPopup:s,loginRedirect:h,inProgress:p}=A(),m=async()=>{try{o?await h(n):await s(n),l?.();}catch(i){c?.(i);}},g={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},f={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:p?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:p?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...g[t],...d};return jsxs("button",{onClick:m,disabled:p,className:u,style:f,"aria-label":r,children:[jsx(Me,{}),jsx("span",{children:r})]})}function Me(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function Ue({text:r="Sign out",variant:e="dark",size:t="medium",useRedirect:o=false,className:n="",style:u,onSuccess:d,onError:l}){let{logoutPopup:c,logoutRedirect:s,inProgress:h}=A(),p=async()=>{try{o?await s():await c(),d?.();}catch(f){l?.(f);}},m={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},y={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:h?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:h?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...m[t],...u};return jsxs("button",{onClick:p,disabled:h,className:n,style:y,"aria-label":r,children:[jsx(ke,{}),jsx("span",{children:r})]})}function ke(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function U(){let{acquireToken:r}=A(),e=useCallback(async(l,c={})=>{let{scopes:s=["User.Read"],version:h="v1.0",debug:p=false,...m}=c;try{let g=await r(s),y=`https://graph.microsoft.com/${h}`,f=l.startsWith("http")?l:`${y}${l.startsWith("/")?l:`/${l}`}`;p&&console.log("[GraphAPI] Request:",{url:f,method:m.method||"GET"});let i=await fetch(f,{...m,headers:{Authorization:`Bearer ${g}`,"Content-Type":"application/json",...m.headers}});if(!i.ok){let b=await i.text(),v=`Graph API error (${i.status}): ${b}`;throw new Error(v)}if(i.status===204||i.headers.get("content-length")==="0")return null;let a=await i.json();return p&&console.log("[GraphAPI] Response:",a),a}catch(g){let y=C(g);throw console.error("[GraphAPI] Request failed:",y),new Error(y)}},[r]),t=useCallback((l,c={})=>e(l,{...c,method:"GET"}),[e]),o=useCallback((l,c,s={})=>e(l,{...s,method:"POST",body:c?JSON.stringify(c):void 0}),[e]),n=useCallback((l,c,s={})=>e(l,{...s,method:"PUT",body:c?JSON.stringify(c):void 0}),[e]),u=useCallback((l,c,s={})=>e(l,{...s,method:"PATCH",body:c?JSON.stringify(c):void 0}),[e]),d=useCallback((l,c={})=>e(l,{...c,method:"DELETE"}),[e]);return {get:t,post:o,put:n,patch:u,delete:d,request:e}}var R=new Map,Fe=300*1e3,ue=100;function Ie(){if(R.size>ue){let r=Array.from(R.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,R.size-ue).forEach(([t])=>{let o=R.get(t);o?.data.photo&&URL.revokeObjectURL(o.data.photo),R.delete(t);});}}function J(){let{isAuthenticated:r,account:e}=A(),t=U(),[o,n]=useState(null),[u,d]=useState(false),[l,c]=useState(null),s=useCallback(async()=>{if(!r||!e){n(null);return}let p=e.homeAccountId,m=R.get(p);if(m&&Date.now()-m.timestamp<Fe){n(m.data);return}d(true),c(null);try{let g=await t.get("/me",{scopes:["User.Read"]}),y;try{let i=await t.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});i&&(y=URL.createObjectURL(i));}catch{console.debug("[UserProfile] Photo not available");}let f={id:g.id,displayName:g.displayName,givenName:g.givenName,surname:g.surname,userPrincipalName:g.userPrincipalName,mail:g.mail,jobTitle:g.jobTitle,officeLocation:g.officeLocation,mobilePhone:g.mobilePhone,businessPhones:g.businessPhones,photo:y};R.set(p,{data:f,timestamp:Date.now()}),Ie(),n(f);}catch(g){let f=C(g),i=new Error(f);c(i),console.error("[UserProfile] Failed to fetch profile:",f);}finally{d(false);}},[r,e,t]),h=useCallback(()=>{if(e){let p=R.get(e.homeAccountId);p?.data.photo&&URL.revokeObjectURL(p.data.photo),R.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),n(null);},[e,o]);return useEffect(()=>(s(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[s]),useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:u,error:l,refetch:s,clearCache:h}}function De({size:r=40,className:e="",style:t,showTooltip:o=true,fallbackImage:n}){let{profile:u,loading:d}=J(),[l,c]=useState(null),[s,h]=useState(false);useEffect(()=>{u?.photo&&c(u.photo);},[u?.photo]);let p=()=>{if(!u)return "?";let{givenName:y,surname:f,displayName:i}=u;if(y&&f)return `${y[0]}${f[0]}`.toUpperCase();if(i){let a=i.split(" ");return a.length>=2?`${a[0][0]}${a[a.length-1][0]}`.toUpperCase():i.substring(0,2).toUpperCase()}return "?"},m={width:`${r}px`,height:`${r}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${r*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...t},g=u?.displayName||"User";return d?jsx("div",{className:e,style:{...m,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsx("span",{style:{fontSize:`${r*.3}px`},children:"..."})}):l&&!s?jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:jsx("img",{src:l,alt:g,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{h(true),n&&c(n);}})}):jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:p()})}function Oe({className:r="",style:e,showDetails:t=false,renderLoading:o,renderAuthenticated:n,renderUnauthenticated:u}){let{isAuthenticated:d,inProgress:l,account:c}=A(),s={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(l)return o?jsx(Fragment,{children:o()}):jsxs("div",{className:r,style:{...s,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsx(Z,{color:"#FFA500"}),jsx("span",{children:"Loading..."})]});if(d){let h=c?.username||c?.name||"User";return n?jsx(Fragment,{children:n(h)}):jsxs("div",{className:r,style:{...s,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsx(Z,{color:"#28A745"}),jsx("span",{children:t?`Authenticated as ${h}`:"Authenticated"})]})}return u?jsx(Fragment,{children:u()}):jsxs("div",{className:r,style:{...s,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsx(Z,{color:"#DC3545"}),jsx("span",{children:"Not authenticated"})]})}function Z({color:r}){return jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("circle",{cx:"4",cy:"4",r:"4",fill:r})})}function Q({children:r,loadingComponent:e,fallbackComponent:t,useRedirect:o=true,scopes:n,onAuthRequired:u}){let{isAuthenticated:d,inProgress:l,loginRedirect:c,loginPopup:s}=A();return useEffect(()=>{!d&&!l&&(u?.(),(async()=>{try{o?await c(n):await s(n);}catch(p){console.error("[AuthGuard] Authentication failed:",p);}})());},[d,l,o,n,c,s,u]),l?jsx(Fragment,{children:e||jsx("div",{children:"Authenticating..."})}):d?jsx(Fragment,{children:r}):jsx(Fragment,{children:t||jsx("div",{children:"Redirecting to login..."})})}var ee=class extends Component{constructor(t){super(t);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(t){return {hasError:true,error:t}}componentDidCatch(t,o){let{onError:n,debug:u}=this.props;u&&(console.error("[ErrorBoundary] Caught error:",t),console.error("[ErrorBoundary] Error info:",o)),n?.(t,o);}render(){let{hasError:t,error:o}=this.state,{children:n,fallback:u}=this.props;return t&&o?u?u(o,this.reset):jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):n}};var w=new Map,Be=300*1e3,de=100;function Ve(r){r?w.delete(r):w.clear();}function We(){if(w.size>de){let r=Array.from(w.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,w.size-de).forEach(([t])=>w.delete(t));}}function _e(){let{isAuthenticated:r,account:e}=A(),t=U(),[o,n]=useState([]),[u,d]=useState([]),[l,c]=useState(false),[s,h]=useState(null),p=useCallback(async()=>{if(!r||!e){n([]),d([]);return}let i=e.homeAccountId,a=w.get(i);if(a&&Date.now()-a.timestamp<Be){n(a.roles),d(a.groups);return}c(true),h(null);try{let v=e.idTokenClaims?.roles||[],O=(await t.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(te=>te.id);w.set(i,{roles:v,groups:O,timestamp:Date.now()}),We(),n(v),d(O);}catch(b){let D=C(b),O=new Error(D);h(O),console.error("[Roles] Failed to fetch roles/groups:",D);let he=e.idTokenClaims?.roles||[];n(he);}finally{c(false);}},[r,e,t]),m=useCallback(i=>o.includes(i),[o]),g=useCallback(i=>u.includes(i),[u]),y=useCallback(i=>i.some(a=>o.includes(a)),[o]),f=useCallback(i=>i.every(a=>o.includes(a)),[o]);return useEffect(()=>(p(),()=>{e&&Ve(e.homeAccountId);}),[p,e]),{roles:o,groups:u,loading:l,error:s,hasRole:m,hasGroup:g,hasAnyRole:y,hasAllRoles:f,refetch:p}}function je(r,e={}){let{displayName:t,...o}=e,n=u=>jsx(Q,{...o,children:jsx(r,{...u})});return n.displayName=t||`withAuth(${r.displayName||r.name||"Component"})`,n}async function fe(r,e={}){let{maxRetries:t=3,initialDelay:o=1e3,maxDelay:n=1e4,backoffMultiplier:u=2,debug:d=false}=e,l,c=o;for(let s=0;s<=t;s++)try{return d&&s>0&&console.log(`[TokenRetry] Attempt ${s+1}/${t+1}`),await r()}catch(h){if(l=h,s===t){d&&console.error("[TokenRetry] All retry attempts failed");break}if(!Je(h))throw d&&console.log("[TokenRetry] Non-retryable error, aborting"),h;d&&console.warn(`[TokenRetry] Attempt ${s+1} failed, retrying in ${c}ms...`),await Ze(c),c=Math.min(c*u,n);}throw l}function Je(r){let e=r.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function Ze(r){return new Promise(e=>setTimeout(e,r))}function He(r,e={}){return (...t)=>fe(()=>r(...t),e)}var $=class{constructor(e={}){this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info"};}shouldLog(e){if(!this.config.enabled)return false;let t=["error","warn","info","debug"],o=t.indexOf(this.config.level);return t.indexOf(e)<=o}formatMessage(e,t,o){let n=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",u=this.config.prefix,d=`[${e.toUpperCase()}]`,l=`${n} ${u} ${d} ${t}`;return o!==void 0&&(l+=`
|
|
2
|
-
`+JSON.stringify(o,null,2)),
|
|
1
|
+
import {MsalProvider,useMsal,useAccount}from'@azure/msal-react';export{useAccount,useIsAuthenticated,useMsal}from'@azure/msal-react';import {LogLevel,PublicClientApplication,EventType,InteractionStatus}from'@azure/msal-browser';import {useState,useRef,useEffect,useMemo,useCallback,Component}from'react';import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {NextResponse}from'next/server';function z(r,e){try{let t=JSON.parse(r);return e(t)?t:(console.warn("[Validation] JSON validation failed"),null)}catch(t){return console.error("[Validation] JSON parse error:",t),null}}function B(r){return typeof r=="object"&&r!==null&&typeof r.homeAccountId=="string"&&r.homeAccountId.length>0&&typeof r.username=="string"&&r.username.length>0&&(r.name===void 0||typeof r.name=="string")}function S(r){return r instanceof Error?r.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function G(r,e){try{let t=new URL(r);return e.some(o=>{let n=new URL(o);return t.origin===n.origin})}catch{return false}}function oe(r){return /^[a-zA-Z0-9._-]+$/.test(r)}function me(r){return Array.isArray(r)&&r.every(oe)}function H(r){if(r.msalConfig)return r.msalConfig;let{clientId:e,tenantId:t,authorityType:o="common",redirectUri:n,postLogoutRedirectUri:a,cacheLocation:d="sessionStorage",storeAuthStateInCookie:c=false,navigateToLoginRequestUrl:u=true,enableLogging:s=false,loggerCallback:h,allowedRedirectUris:p}=r;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let m=()=>{if(o==="tenant"){if(!t)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${t}`}return `https://login.microsoftonline.com/${o}`},g=typeof window<"u"?window.location.origin:"http://localhost:3000",y=n||g;if(p&&p.length>0){if(!G(y,p))throw new Error(`@chemmangat/msal-next: redirectUri "${y}" is not in the allowed list`);let i=a||y;if(!G(i,p))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${i}" is not in the allowed list`)}return {auth:{clientId:e,authority:m(),redirectUri:y,postLogoutRedirectUri:a||y,navigateToLoginRequestUrl:u},cache:{cacheLocation:d,storeAuthStateInCookie:c},system:{loggerOptions:{loggerCallback:h||((i,l,A)=>{if(!(A||!s))switch(i){case LogLevel.Error:console.error("[MSAL]",l);break;case LogLevel.Warning:console.warn("[MSAL]",l);break;case LogLevel.Info:console.info("[MSAL]",l);break;case LogLevel.Verbose:console.debug("[MSAL]",l);break}}),logLevel:s?LogLevel.Verbose:LogLevel.Error}}}}var ie=null;function Pe(){return ie}function ve({children:r,loadingComponent:e,onInitialized:t,...o}){let[n,a]=useState(null),d=useRef(null);return useEffect(()=>{if(typeof window>"u"||d.current)return;(async()=>{try{let u=H(o),s=new PublicClientApplication(u);await s.initialize(),await s.handleRedirectPromise()&&o.enableLogging&&console.log("[MSAL] Redirect authentication successful");let p=o.enableLogging||!1;s.addEventCallback(m=>{if(m.eventType===EventType.LOGIN_SUCCESS&&p){let g=m.payload;console.log("[MSAL] Login successful:",g.account?.username);}m.eventType===EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",m.error),m.eventType===EventType.LOGOUT_SUCCESS&&p&&console.log("[MSAL] Logout successful");}),d.current=s,ie=s,a(s),t&&t(s);}catch(u){throw console.error("[MSAL] Initialization failed:",u),u}})();},[]),typeof window>"u"?jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})}):n?jsx(MsalProvider,{instance:n,children:r}):jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})})}var W=new Map;function b(r=["User.Read"]){let{instance:e,accounts:t,inProgress:o}=useMsal(),n=useAccount(t[0]||null),a=useRef(false),d=useMemo(()=>t.length>0,[t]),c=useCallback(async(i=r)=>{try{let l={scopes:i,prompt:"select_account"};await e.loginPopup(l);}catch(l){throw console.error("[MSAL] Login popup failed:",l),l}},[e,r]),u=useCallback(async(i=r)=>{try{let l={scopes:i,prompt:"select_account"};await e.loginRedirect(l);}catch(l){throw console.error("[MSAL] Login redirect failed:",l),l}},[e,r]),s=useCallback(async()=>{try{await e.logoutPopup({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout popup failed:",i),i}},[e,n]),h=useCallback(async()=>{try{await e.logoutRedirect({account:n||void 0});}catch(i){throw console.error("[MSAL] Logout redirect failed:",i),i}},[e,n]),p=useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let l={scopes:i,account:n,forceRefresh:!1};return (await e.acquireTokenSilent(l)).accessToken}catch(l){throw console.error("[MSAL] Silent token acquisition failed:",l),l}},[e,n,r]),m=useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");if(a.current)throw new Error("[MSAL] Popup already in progress. Please wait.");try{a.current=!0;let l={scopes:i,account:n};return (await e.acquireTokenPopup(l)).accessToken}catch(l){throw console.error("[MSAL] Token popup acquisition failed:",l),l}finally{a.current=false;}},[e,n,r]),g=useCallback(async(i=r)=>{if(!n)throw new Error("[MSAL] No active account. Please login first.");try{let l={scopes:i,account:n};await e.acquireTokenRedirect(l);}catch(l){throw console.error("[MSAL] Token redirect acquisition failed:",l),l}},[e,n,r]),y=useCallback(async(i=r)=>{let l=`${n?.homeAccountId||"anonymous"}-${i.sort().join(",")}`,A=W.get(l);if(A)return A;let v=(async()=>{try{return await p(i)}catch{return console.warn("[MSAL] Silent token acquisition failed, falling back to popup"),await m(i)}finally{W.delete(l);}})();return W.set(l,v),v},[p,m,r,n]),f=useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:n,accounts:t,isAuthenticated:d,inProgress:o!==InteractionStatus.None,loginPopup:c,loginRedirect:u,logoutPopup:s,logoutRedirect:h,acquireToken:y,acquireTokenSilent:p,acquireTokenPopup:m,acquireTokenRedirect:g,clearSession:f}}function Le({text:r="Sign in with Microsoft",variant:e="dark",size:t="medium",useRedirect:o=false,scopes:n,className:a="",style:d,onSuccess:c,onError:u}){let{loginPopup:s,loginRedirect:h,inProgress:p}=b(),m=async()=>{try{o?await h(n):await s(n),c?.();}catch(i){u?.(i);}},g={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},f={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:p?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:p?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...g[t],...d};return jsxs("button",{onClick:m,disabled:p,className:a,style:f,"aria-label":r,children:[jsx(ke,{}),jsx("span",{children:r})]})}function ke(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function Ue({text:r="Sign out",variant:e="dark",size:t="medium",useRedirect:o=false,className:n="",style:a,onSuccess:d,onError:c}){let{logoutPopup:u,logoutRedirect:s,inProgress:h}=b(),p=async()=>{try{o?await s():await u(),d?.();}catch(f){c?.(f);}},m={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},y={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:h?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:h?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...m[t],...a};return jsxs("button",{onClick:p,disabled:h,className:n,style:y,"aria-label":r,children:[jsx(Me,{}),jsx("span",{children:r})]})}function Me(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function U(){let{acquireToken:r}=b(),e=useCallback(async(c,u={})=>{let{scopes:s=["User.Read"],version:h="v1.0",debug:p=false,...m}=u;try{let g=await r(s),y=`https://graph.microsoft.com/${h}`,f=c.startsWith("http")?c:`${y}${c.startsWith("/")?c:`/${c}`}`;p&&console.log("[GraphAPI] Request:",{url:f,method:m.method||"GET"});let i=await fetch(f,{...m,headers:{Authorization:`Bearer ${g}`,"Content-Type":"application/json",...m.headers}});if(!i.ok){let A=await i.text(),v=`Graph API error (${i.status}): ${A}`;throw new Error(v)}if(i.status===204||i.headers.get("content-length")==="0")return null;let l=await i.json();return p&&console.log("[GraphAPI] Response:",l),l}catch(g){let y=S(g);throw console.error("[GraphAPI] Request failed:",y),new Error(y)}},[r]),t=useCallback((c,u={})=>e(c,{...u,method:"GET"}),[e]),o=useCallback((c,u,s={})=>e(c,{...s,method:"POST",body:u?JSON.stringify(u):void 0}),[e]),n=useCallback((c,u,s={})=>e(c,{...s,method:"PUT",body:u?JSON.stringify(u):void 0}),[e]),a=useCallback((c,u,s={})=>e(c,{...s,method:"PATCH",body:u?JSON.stringify(u):void 0}),[e]),d=useCallback((c,u={})=>e(c,{...u,method:"DELETE"}),[e]);return {get:t,post:o,put:n,patch:a,delete:d,request:e}}var P=new Map,Fe=300*1e3,ue=100;function Ne(){if(P.size>ue){let r=Array.from(P.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,P.size-ue).forEach(([t])=>{let o=P.get(t);o?.data.photo&&URL.revokeObjectURL(o.data.photo),P.delete(t);});}}function j(){let{isAuthenticated:r,account:e}=b(),t=U(),[o,n]=useState(null),[a,d]=useState(false),[c,u]=useState(null),s=useCallback(async()=>{if(!r||!e){n(null);return}let p=e.homeAccountId,m=P.get(p);if(m&&Date.now()-m.timestamp<Fe){n(m.data);return}d(true),u(null);try{let g=await t.get("/me",{scopes:["User.Read"]}),y;try{let i=await t.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});i&&(y=URL.createObjectURL(i));}catch{console.debug("[UserProfile] Photo not available");}let f={id:g.id,displayName:g.displayName,givenName:g.givenName,surname:g.surname,userPrincipalName:g.userPrincipalName,mail:g.mail,jobTitle:g.jobTitle,officeLocation:g.officeLocation,mobilePhone:g.mobilePhone,businessPhones:g.businessPhones,photo:y};P.set(p,{data:f,timestamp:Date.now()}),Ne(),n(f);}catch(g){let f=S(g),i=new Error(f);u(i),console.error("[UserProfile] Failed to fetch profile:",f);}finally{d(false);}},[r,e,t]),h=useCallback(()=>{if(e){let p=P.get(e.homeAccountId);p?.data.photo&&URL.revokeObjectURL(p.data.photo),P.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),n(null);},[e,o]);return useEffect(()=>(s(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[s]),useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:a,error:c,refetch:s,clearCache:h}}function De({size:r=40,className:e="",style:t,showTooltip:o=true,fallbackImage:n}){let{profile:a,loading:d}=j(),[c,u]=useState(null),[s,h]=useState(false);useEffect(()=>{a?.photo&&u(a.photo);},[a?.photo]);let p=()=>{if(!a)return "?";let{givenName:y,surname:f,displayName:i}=a;if(y&&f)return `${y[0]}${f[0]}`.toUpperCase();if(i){let l=i.split(" ");return l.length>=2?`${l[0][0]}${l[l.length-1][0]}`.toUpperCase():i.substring(0,2).toUpperCase()}return "?"},m={width:`${r}px`,height:`${r}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${r*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...t},g=a?.displayName||"User";return d?jsx("div",{className:e,style:{...m,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsx("span",{style:{fontSize:`${r*.3}px`},children:"..."})}):c&&!s?jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:jsx("img",{src:c,alt:g,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{h(true),n&&u(n);}})}):jsx("div",{className:e,style:m,title:o?g:void 0,"aria-label":`${g} avatar`,children:p()})}function Oe({className:r="",style:e,showDetails:t=false,renderLoading:o,renderAuthenticated:n,renderUnauthenticated:a}){let{isAuthenticated:d,inProgress:c,account:u}=b(),s={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(c)return o?jsx(Fragment,{children:o()}):jsxs("div",{className:r,style:{...s,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsx(J,{color:"#FFA500"}),jsx("span",{children:"Loading..."})]});if(d){let h=u?.username||u?.name||"User";return n?jsx(Fragment,{children:n(h)}):jsxs("div",{className:r,style:{...s,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsx(J,{color:"#28A745"}),jsx("span",{children:t?`Authenticated as ${h}`:"Authenticated"})]})}return a?jsx(Fragment,{children:a()}):jsxs("div",{className:r,style:{...s,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsx(J,{color:"#DC3545"}),jsx("span",{children:"Not authenticated"})]})}function J({color:r}){return jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("circle",{cx:"4",cy:"4",r:"4",fill:r})})}function Q({children:r,loadingComponent:e,fallbackComponent:t,useRedirect:o=true,scopes:n,onAuthRequired:a}){let{isAuthenticated:d,inProgress:c,loginRedirect:u,loginPopup:s}=b();return useEffect(()=>{!d&&!c&&(a?.(),(async()=>{try{o?await u(n):await s(n);}catch(p){console.error("[AuthGuard] Authentication failed:",p);}})());},[d,c,o,n,u,s,a]),c?jsx(Fragment,{children:e||jsx("div",{children:"Authenticating..."})}):d?jsx(Fragment,{children:r}):jsx(Fragment,{children:t||jsx("div",{children:"Redirecting to login..."})})}var ee=class extends Component{constructor(t){super(t);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(t){return {hasError:true,error:t}}componentDidCatch(t,o){let{onError:n,debug:a}=this.props;a&&(console.error("[ErrorBoundary] Caught error:",t),console.error("[ErrorBoundary] Error info:",o)),n?.(t,o);}render(){let{hasError:t,error:o}=this.state,{children:n,fallback:a}=this.props;return t&&o?a?a(o,this.reset):jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):n}};var R=new Map,Be=300*1e3,de=100;function He(r){r?R.delete(r):R.clear();}function Ve(){if(R.size>de){let r=Array.from(R.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,R.size-de).forEach(([t])=>R.delete(t));}}function We(){let{isAuthenticated:r,account:e}=b(),t=U(),[o,n]=useState([]),[a,d]=useState([]),[c,u]=useState(false),[s,h]=useState(null),p=useCallback(async()=>{if(!r||!e){n([]),d([]);return}let i=e.homeAccountId,l=R.get(i);if(l&&Date.now()-l.timestamp<Be){n(l.roles),d(l.groups);return}u(true),h(null);try{let v=e.idTokenClaims?.roles||[],O=(await t.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(te=>te.id);R.set(i,{roles:v,groups:O,timestamp:Date.now()}),Ve(),n(v),d(O);}catch(A){let D=S(A),O=new Error(D);h(O),console.error("[Roles] Failed to fetch roles/groups:",D);let he=e.idTokenClaims?.roles||[];n(he);}finally{u(false);}},[r,e,t]),m=useCallback(i=>o.includes(i),[o]),g=useCallback(i=>a.includes(i),[a]),y=useCallback(i=>i.some(l=>o.includes(l)),[o]),f=useCallback(i=>i.every(l=>o.includes(l)),[o]);return useEffect(()=>(p(),()=>{e&&He(e.homeAccountId);}),[p,e]),{roles:o,groups:a,loading:c,error:s,hasRole:m,hasGroup:g,hasAnyRole:y,hasAllRoles:f,refetch:p}}function _e(r,e={}){let{displayName:t,...o}=e,n=a=>jsx(Q,{...o,children:jsx(r,{...a})});return n.displayName=t||`withAuth(${r.displayName||r.name||"Component"})`,n}async function fe(r,e={}){let{maxRetries:t=3,initialDelay:o=1e3,maxDelay:n=1e4,backoffMultiplier:a=2,debug:d=false}=e,c,u=o;for(let s=0;s<=t;s++)try{return d&&s>0&&console.log(`[TokenRetry] Attempt ${s+1}/${t+1}`),await r()}catch(h){if(c=h,s===t){d&&console.error("[TokenRetry] All retry attempts failed");break}if(!je(h))throw d&&console.log("[TokenRetry] Non-retryable error, aborting"),h;d&&console.warn(`[TokenRetry] Attempt ${s+1} failed, retrying in ${u}ms...`),await Je(u),u=Math.min(u*a,n);}throw c}function je(r){let e=r.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function Je(r){return new Promise(e=>setTimeout(e,r))}function Ze(r,e={}){return (...t)=>fe(()=>r(...t),e)}var q=class{constructor(e={}){this.logHistory=[];this.performanceTimings=new Map;this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info",enablePerformance:e.enablePerformance??false,enableNetworkLogs:e.enableNetworkLogs??false,maxHistorySize:e.maxHistorySize??100};}shouldLog(e){if(!this.config.enabled)return false;let t=["error","warn","info","debug"],o=t.indexOf(this.config.level);return t.indexOf(e)<=o}formatMessage(e,t,o){let n=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",a=this.config.prefix,d=`[${e.toUpperCase()}]`,c=`${n} ${a} ${d} ${t}`;return o!==void 0&&(c+=`
|
|
2
|
+
`+JSON.stringify(o,null,2)),c}addToHistory(e,t,o){this.logHistory.length>=this.config.maxHistorySize&&this.logHistory.shift(),this.logHistory.push({timestamp:Date.now(),level:e,message:t,data:o});}error(e,t){this.shouldLog("error")&&(console.error(this.formatMessage("error",e,t)),this.addToHistory("error",e,t));}warn(e,t){this.shouldLog("warn")&&(console.warn(this.formatMessage("warn",e,t)),this.addToHistory("warn",e,t));}info(e,t){this.shouldLog("info")&&(console.info(this.formatMessage("info",e,t)),this.addToHistory("info",e,t));}debug(e,t){this.shouldLog("debug")&&(console.debug(this.formatMessage("debug",e,t)),this.addToHistory("debug",e,t));}group(e){this.config.enabled&&console.group(`${this.config.prefix} ${e}`);}groupEnd(){this.config.enabled&&console.groupEnd();}startTiming(e){this.config.enablePerformance&&(this.performanceTimings.set(e,{operation:e,startTime:performance.now()}),this.debug(`\u23F1\uFE0F Started: ${e}`));}endTiming(e){if(this.config.enablePerformance){let t=this.performanceTimings.get(e);if(t)return t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.info(`\u23F1\uFE0F Completed: ${e} (${t.duration.toFixed(2)}ms)`),t.duration}}logRequest(e,t,o){this.config.enableNetworkLogs&&this.debug(`\u{1F310} ${e} ${t}`,o);}logResponse(e,t,o,n){if(this.config.enableNetworkLogs){let a=o>=200&&o<300?"\u2705":"\u274C";this.debug(`${a} ${e} ${t} - ${o}`,n);}}getHistory(){return [...this.logHistory]}getPerformanceTimings(){return Array.from(this.performanceTimings.values())}clearHistory(){this.logHistory=[];}clearTimings(){this.performanceTimings.clear();}exportLogs(){return JSON.stringify({config:this.config,history:this.logHistory,performanceTimings:Array.from(this.performanceTimings.values()),exportedAt:new Date().toISOString()},null,2)}downloadLogs(e="msal-next-debug-logs.json"){if(typeof window>"u")return;let t=this.exportLogs(),o=new Blob([t],{type:"application/json"}),n=URL.createObjectURL(o),a=document.createElement("a");a.href=n,a.download=e,a.click(),URL.revokeObjectURL(n);}setEnabled(e){this.config.enabled=e;}setLevel(e){e&&(this.config.level=e);}},I=null;function Ke(r){return I?r&&(r.enabled!==void 0&&I.setEnabled(r.enabled),r.level&&I.setLevel(r.level)):I=new q(r),I}function Xe(r,e){return new q({...e,prefix:`[MSAL-Next:${r}]`})}function Qe(r={}){let{protectedRoutes:e=[],publicOnlyRoutes:t=[],loginPath:o="/login",redirectAfterLogin:n="/",sessionCookie:a="msal.account",isAuthenticated:d,debug:c=false}=r;return async function(s){let{pathname:h}=s.nextUrl;c&&console.log("[AuthMiddleware] Processing:",h);let p=false;d?p=await d(s):p=!!s.cookies.get(a)?.value,c&&console.log("[AuthMiddleware] Authenticated:",p);let m=e.some(f=>h.startsWith(f)),g=t.some(f=>h.startsWith(f));if(m&&!p){c&&console.log("[AuthMiddleware] Redirecting to login");let f=s.nextUrl.clone();return f.pathname=o,f.searchParams.set("returnUrl",h),NextResponse.redirect(f)}if(g&&p){c&&console.log("[AuthMiddleware] Redirecting to home");let f=s.nextUrl.searchParams.get("returnUrl"),i=s.nextUrl.clone();return i.pathname=f||n,i.searchParams.delete("returnUrl"),NextResponse.redirect(i)}let y=NextResponse.next();if(p){y.headers.set("x-msal-authenticated","true");try{let f=s.cookies.get(a);if(f?.value){let i=z(f.value,B);i?.username&&y.headers.set("x-msal-username",i.username);}}catch{c&&console.warn("[AuthMiddleware] Failed to parse session data");}}return y}}export{Q as AuthGuard,Oe as AuthStatus,ee as ErrorBoundary,Le as MicrosoftSignInButton,ve as MsalAuthProvider,Ue as SignOutButton,De as UserAvatar,Qe as createAuthMiddleware,H as createMsalConfig,Ze as createRetryWrapper,Xe as createScopedLogger,Ke as getDebugLogger,Pe as getMsalInstance,B as isValidAccountData,G as isValidRedirectUri,oe as isValidScope,fe as retryWithBackoff,z as safeJsonParse,S as sanitizeError,U as useGraphApi,b as useMsalAuth,We as useRoles,j as useUserProfile,me as validateScopes,_e as withAuth};
|
package/package.json
CHANGED