@chemmangat/msal-next 2.1.2 → 3.0.0
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 -1415
- package/dist/index.mjs +2 -1378
- package/dist/server.js +1 -91
- package/dist/server.mjs +1 -88
- package/package.json +3 -3
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/server.mjs.map +0 -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
|
*/
|