@chemmangat/msal-next 3.1.2 → 3.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -0
- package/README.md +60 -3
- package/dist/index.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +33 -7
- package/dist/index.mjs +32 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,123 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [3.1.5] - 2026-03-05
|
|
6
|
+
|
|
7
|
+
### 🔄 Breaking Change - Redirect Flow by Default
|
|
8
|
+
|
|
9
|
+
**MicrosoftSignInButton now uses redirect flow by default** instead of popup flow.
|
|
10
|
+
|
|
11
|
+
**Why this change?**
|
|
12
|
+
- Popup flow requires additional setup (blank.html page)
|
|
13
|
+
- Popup flow causes the full app to load in popup window
|
|
14
|
+
- Redirect flow is simpler and works out of the box
|
|
15
|
+
- Most users prefer redirect flow for better UX
|
|
16
|
+
|
|
17
|
+
**Migration:**
|
|
18
|
+
|
|
19
|
+
If you were using the default popup behavior:
|
|
20
|
+
```tsx
|
|
21
|
+
// Before (v3.1.4 and earlier) - used popup by default
|
|
22
|
+
<MicrosoftSignInButton />
|
|
23
|
+
|
|
24
|
+
// After (v3.1.5) - uses redirect by default
|
|
25
|
+
<MicrosoftSignInButton /> // Now redirects full page
|
|
26
|
+
|
|
27
|
+
// To keep popup behavior:
|
|
28
|
+
<MicrosoftSignInButton useRedirect={false} />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**New Default Behavior:**
|
|
32
|
+
- Button redirects the entire browser window to Microsoft login
|
|
33
|
+
- After authentication, redirects back to your app
|
|
34
|
+
- No popup windows, no blank.html needed
|
|
35
|
+
- Works with your existing Azure AD redirect URI
|
|
36
|
+
|
|
37
|
+
### ✨ Optional Popup Support
|
|
38
|
+
|
|
39
|
+
**Added optional `popupRedirectUri` prop** - Only use if you prefer popup flow.
|
|
40
|
+
|
|
41
|
+
**For Popup Flow (Optional):**
|
|
42
|
+
1. Create `public/blank.html`
|
|
43
|
+
2. Add `/blank.html` to Azure AD redirect URIs
|
|
44
|
+
3. Use:
|
|
45
|
+
```tsx
|
|
46
|
+
<MSALProvider popupRedirectUri="/blank.html">
|
|
47
|
+
<MicrosoftSignInButton useRedirect={false} />
|
|
48
|
+
</MSALProvider>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Benefits:**
|
|
52
|
+
- Simpler default experience (no setup required)
|
|
53
|
+
- Redirect flow works out of the box
|
|
54
|
+
- Popup flow still available for those who need it
|
|
55
|
+
- Backward compatible (just set `useRedirect={false}`)
|
|
56
|
+
|
|
57
|
+
## [3.1.4] - 2026-03-05
|
|
58
|
+
|
|
59
|
+
### 🔧 Configuration Fix - Popup Redirect
|
|
60
|
+
|
|
61
|
+
**BREAKING CHANGE:** You must now create a `public/blank.html` file and configure it as a redirect URI in Azure AD.
|
|
62
|
+
|
|
63
|
+
**Why:** This prevents your full app from loading in the popup window after authentication.
|
|
64
|
+
|
|
65
|
+
**Setup Required:**
|
|
66
|
+
|
|
67
|
+
1. Create `public/blank.html`:
|
|
68
|
+
```html
|
|
69
|
+
<!DOCTYPE html>
|
|
70
|
+
<html>
|
|
71
|
+
<head><title>Auth</title></head>
|
|
72
|
+
<body></body>
|
|
73
|
+
</html>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
2. Add to Azure AD redirect URIs:
|
|
77
|
+
- `http://localhost:3000/blank.html`
|
|
78
|
+
- `https://yourdomain.com/blank.html`
|
|
79
|
+
|
|
80
|
+
3. Update your MSALProvider:
|
|
81
|
+
```tsx
|
|
82
|
+
<MSALProvider
|
|
83
|
+
clientId="..."
|
|
84
|
+
redirectUri={typeof window !== 'undefined' ? `${window.location.origin}/blank.html` : undefined}
|
|
85
|
+
>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Changes:**
|
|
89
|
+
- Set `navigateToLoginRequestUrl` default to `false`
|
|
90
|
+
- Updated README with blank.html setup instructions
|
|
91
|
+
- Added PUBLIC_BLANK_HTML.md guide
|
|
92
|
+
|
|
93
|
+
## [3.1.3] - 2026-03-05
|
|
94
|
+
|
|
95
|
+
### 🐛 Critical Fix - Popup Redirect Issue
|
|
96
|
+
|
|
97
|
+
**Fixed:** Popup window now stays as popup and doesn't navigate to redirect URI.
|
|
98
|
+
|
|
99
|
+
**Changes:**
|
|
100
|
+
- Added `windowHashTimeout`, `iframeHashTimeout`, and `loadFrameTimeout` to MSAL config
|
|
101
|
+
- Set `redirectUri: undefined` in popup requests to prevent navigation
|
|
102
|
+
- Popup now properly closes after authentication without showing redirect page
|
|
103
|
+
|
|
104
|
+
**This fixes the issue where the redirect URI was opening inside the popup window instead of the popup closing.**
|
|
105
|
+
|
|
106
|
+
## [3.1.2] - 2026-03-05
|
|
107
|
+
|
|
108
|
+
### 📝 Documentation Update
|
|
109
|
+
|
|
110
|
+
- Updated README with current version number
|
|
111
|
+
- No code changes from 3.1.1
|
|
112
|
+
|
|
113
|
+
## [3.1.1] - 2026-03-05
|
|
114
|
+
|
|
115
|
+
### 📝 Documentation & Build
|
|
116
|
+
|
|
117
|
+
- Fixed landing page build issues
|
|
118
|
+
- Cleaned up redundant documentation files
|
|
119
|
+
- Updated package files list
|
|
120
|
+
- No code changes from 3.0.8
|
|
121
|
+
|
|
5
122
|
## [3.0.8] - 2026-03-05
|
|
6
123
|
|
|
7
124
|
### 🚨 CRITICAL BUG FIX
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ 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
|
-
> **📦 Current Version: 3.1.
|
|
8
|
+
> **📦 Current Version: 3.1.5** - Separate popup redirect URI support. [See changelog](./CHANGELOG.md)
|
|
9
9
|
|
|
10
10
|
> **⚠️ Important:** If you're on v3.0.6 or v3.0.7, please update immediately - those versions have a critical popup authentication bug.
|
|
11
11
|
|
|
@@ -134,6 +134,60 @@ export default function Home() {
|
|
|
134
134
|
|
|
135
135
|
That's it! 🎉
|
|
136
136
|
|
|
137
|
+
The button uses redirect flow by default (full page redirect to Microsoft login, then back to your app). No popups, no blank.html needed.
|
|
138
|
+
|
|
139
|
+
## Optional: Fix Popup Window Issue
|
|
140
|
+
|
|
141
|
+
**Important:** When using popup authentication, the popup window MUST navigate to your redirect URI to complete the OAuth flow. This is how OAuth works and cannot be avoided.
|
|
142
|
+
|
|
143
|
+
By default, this means your full Next.js app will briefly load in the popup before it closes. The package detects this and renders minimal content, but you may still see a flash of your app.
|
|
144
|
+
|
|
145
|
+
### Solution: Use a Blank Page (Recommended for Popup Flow)
|
|
146
|
+
|
|
147
|
+
For the cleanest popup experience, create a blank HTML page:
|
|
148
|
+
|
|
149
|
+
### 1. Create blank.html
|
|
150
|
+
|
|
151
|
+
Create `public/blank.html`:
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<!DOCTYPE html>
|
|
155
|
+
<html>
|
|
156
|
+
<head><title>Auth</title></head>
|
|
157
|
+
<body></body>
|
|
158
|
+
</html>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 2. Add to Azure AD
|
|
162
|
+
|
|
163
|
+
Add to Azure AD redirect URIs:
|
|
164
|
+
- `http://localhost:3000/blank.html`
|
|
165
|
+
- `https://yourdomain.com/blank.html`
|
|
166
|
+
|
|
167
|
+
### 3. Configure MSALProvider
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
<MSALProvider
|
|
171
|
+
clientId={process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID!}
|
|
172
|
+
tenantId={process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID!}
|
|
173
|
+
popupRedirectUri="/blank.html" // Add this line
|
|
174
|
+
>
|
|
175
|
+
{children}
|
|
176
|
+
</MSALProvider>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
This ensures the popup shows only a blank page and closes immediately.
|
|
180
|
+
|
|
181
|
+
### Alternative: Use Redirect Flow
|
|
182
|
+
|
|
183
|
+
If you don't want to set up blank.html, use redirect flow instead:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
<MicrosoftSignInButton useRedirect={true} />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Redirect flow navigates the entire browser window (no popup), so there's no "app in popup" issue.
|
|
190
|
+
|
|
137
191
|
## Components
|
|
138
192
|
|
|
139
193
|
### MSALProvider (Recommended for App Router)
|
|
@@ -186,15 +240,18 @@ export function MyProviders({ children }) {
|
|
|
186
240
|
|
|
187
241
|
### MicrosoftSignInButton
|
|
188
242
|
|
|
189
|
-
Pre-styled sign-in button with Microsoft branding.
|
|
243
|
+
Pre-styled sign-in button with Microsoft branding. Uses redirect flow by default (no popups).
|
|
190
244
|
|
|
191
245
|
```tsx
|
|
192
246
|
<MicrosoftSignInButton
|
|
193
247
|
variant="dark" // or "light"
|
|
194
248
|
size="medium" // "small", "medium", "large"
|
|
195
|
-
useRedirect={
|
|
249
|
+
useRedirect={true} // Default: true (full page redirect)
|
|
196
250
|
onSuccess={() => console.log('Signed in!')}
|
|
197
251
|
/>
|
|
252
|
+
|
|
253
|
+
// If you prefer popup (requires blank.html setup):
|
|
254
|
+
<MicrosoftSignInButton useRedirect={false} />
|
|
198
255
|
```
|
|
199
256
|
|
|
200
257
|
### SignOutButton
|
package/dist/index.d.mts
CHANGED
|
@@ -41,6 +41,13 @@ interface MsalAuthConfig {
|
|
|
41
41
|
* @default window.location.origin
|
|
42
42
|
*/
|
|
43
43
|
redirectUri?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Redirect URI for popup authentication (optional)
|
|
46
|
+
* If not specified, uses the same redirectUri as redirect flow
|
|
47
|
+
* Only set this if you want a different URI for popup (e.g., /blank.html)
|
|
48
|
+
* @default redirectUri
|
|
49
|
+
*/
|
|
50
|
+
popupRedirectUri?: string;
|
|
44
51
|
/**
|
|
45
52
|
* Post logout redirect URI
|
|
46
53
|
* @default redirectUri
|
|
@@ -151,7 +158,7 @@ interface MicrosoftSignInButtonProps {
|
|
|
151
158
|
size?: 'small' | 'medium' | 'large';
|
|
152
159
|
/**
|
|
153
160
|
* Use redirect flow instead of popup
|
|
154
|
-
* @default
|
|
161
|
+
* @default true
|
|
155
162
|
*/
|
|
156
163
|
useRedirect?: boolean;
|
|
157
164
|
/**
|
|
@@ -584,6 +591,7 @@ interface UseRolesReturn {
|
|
|
584
591
|
*/
|
|
585
592
|
declare function useRoles(): UseRolesReturn;
|
|
586
593
|
|
|
594
|
+
declare function getPopupRedirectUri(): string | undefined;
|
|
587
595
|
declare function createMsalConfig(config: MsalAuthConfig): Configuration;
|
|
588
596
|
|
|
589
597
|
interface WithAuthOptions extends Omit<AuthGuardProps, 'children'> {
|
|
@@ -931,4 +939,4 @@ interface ServerSession {
|
|
|
931
939
|
accessToken?: string;
|
|
932
940
|
}
|
|
933
941
|
|
|
934
|
-
export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };
|
|
942
|
+
export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, getPopupRedirectUri, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,13 @@ interface MsalAuthConfig {
|
|
|
41
41
|
* @default window.location.origin
|
|
42
42
|
*/
|
|
43
43
|
redirectUri?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Redirect URI for popup authentication (optional)
|
|
46
|
+
* If not specified, uses the same redirectUri as redirect flow
|
|
47
|
+
* Only set this if you want a different URI for popup (e.g., /blank.html)
|
|
48
|
+
* @default redirectUri
|
|
49
|
+
*/
|
|
50
|
+
popupRedirectUri?: string;
|
|
44
51
|
/**
|
|
45
52
|
* Post logout redirect URI
|
|
46
53
|
* @default redirectUri
|
|
@@ -151,7 +158,7 @@ interface MicrosoftSignInButtonProps {
|
|
|
151
158
|
size?: 'small' | 'medium' | 'large';
|
|
152
159
|
/**
|
|
153
160
|
* Use redirect flow instead of popup
|
|
154
|
-
* @default
|
|
161
|
+
* @default true
|
|
155
162
|
*/
|
|
156
163
|
useRedirect?: boolean;
|
|
157
164
|
/**
|
|
@@ -584,6 +591,7 @@ interface UseRolesReturn {
|
|
|
584
591
|
*/
|
|
585
592
|
declare function useRoles(): UseRolesReturn;
|
|
586
593
|
|
|
594
|
+
declare function getPopupRedirectUri(): string | undefined;
|
|
587
595
|
declare function createMsalConfig(config: MsalAuthConfig): Configuration;
|
|
588
596
|
|
|
589
597
|
interface WithAuthOptions extends Omit<AuthGuardProps, 'children'> {
|
|
@@ -931,4 +939,4 @@ interface ServerSession {
|
|
|
931
939
|
accessToken?: string;
|
|
932
940
|
}
|
|
933
941
|
|
|
934
|
-
export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };
|
|
942
|
+
export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, getPopupRedirectUri, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,7 @@ __export(client_exports, {
|
|
|
35
35
|
createScopedLogger: () => createScopedLogger,
|
|
36
36
|
getDebugLogger: () => getDebugLogger,
|
|
37
37
|
getMsalInstance: () => getMsalInstance,
|
|
38
|
+
getPopupRedirectUri: () => getPopupRedirectUri,
|
|
38
39
|
isValidAccountData: () => isValidAccountData,
|
|
39
40
|
isValidRedirectUri: () => isValidRedirectUri,
|
|
40
41
|
isValidScope: () => isValidScope,
|
|
@@ -105,6 +106,10 @@ function validateScopes(scopes) {
|
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
// src/utils/createMsalConfig.ts
|
|
109
|
+
var storedPopupRedirectUri;
|
|
110
|
+
function getPopupRedirectUri() {
|
|
111
|
+
return storedPopupRedirectUri;
|
|
112
|
+
}
|
|
108
113
|
function createMsalConfig(config) {
|
|
109
114
|
if (config.msalConfig) {
|
|
110
115
|
return config.msalConfig;
|
|
@@ -114,10 +119,11 @@ function createMsalConfig(config) {
|
|
|
114
119
|
tenantId,
|
|
115
120
|
authorityType = "common",
|
|
116
121
|
redirectUri,
|
|
122
|
+
popupRedirectUri,
|
|
117
123
|
postLogoutRedirectUri,
|
|
118
124
|
cacheLocation = "sessionStorage",
|
|
119
125
|
storeAuthStateInCookie = false,
|
|
120
|
-
navigateToLoginRequestUrl =
|
|
126
|
+
navigateToLoginRequestUrl = false,
|
|
121
127
|
enableLogging = false,
|
|
122
128
|
loggerCallback,
|
|
123
129
|
allowedRedirectUris
|
|
@@ -136,6 +142,8 @@ function createMsalConfig(config) {
|
|
|
136
142
|
};
|
|
137
143
|
const defaultRedirectUri = typeof window !== "undefined" ? window.location.origin : "http://localhost:3000";
|
|
138
144
|
const finalRedirectUri = redirectUri || defaultRedirectUri;
|
|
145
|
+
const finalPopupRedirectUri = popupRedirectUri || finalRedirectUri;
|
|
146
|
+
storedPopupRedirectUri = finalPopupRedirectUri;
|
|
139
147
|
if (allowedRedirectUris && allowedRedirectUris.length > 0) {
|
|
140
148
|
if (!isValidRedirectUri(finalRedirectUri, allowedRedirectUris)) {
|
|
141
149
|
throw new Error(
|
|
@@ -162,6 +170,10 @@ function createMsalConfig(config) {
|
|
|
162
170
|
storeAuthStateInCookie
|
|
163
171
|
},
|
|
164
172
|
system: {
|
|
173
|
+
windowHashTimeout: 6e4,
|
|
174
|
+
// Increase timeout for popup
|
|
175
|
+
iframeHashTimeout: 6e3,
|
|
176
|
+
loadFrameTimeout: 0,
|
|
165
177
|
loggerOptions: {
|
|
166
178
|
loggerCallback: loggerCallback || ((level, message, containsPii) => {
|
|
167
179
|
if (containsPii || !enableLogging) return;
|
|
@@ -196,10 +208,17 @@ function getMsalInstance() {
|
|
|
196
208
|
function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }) {
|
|
197
209
|
const [msalInstance, setMsalInstance] = (0, import_react.useState)(null);
|
|
198
210
|
const instanceRef = (0, import_react.useRef)(null);
|
|
211
|
+
const isInPopup = typeof window !== "undefined" && window.opener && window.opener !== window;
|
|
199
212
|
(0, import_react.useEffect)(() => {
|
|
200
213
|
if (typeof window === "undefined") {
|
|
201
214
|
return;
|
|
202
215
|
}
|
|
216
|
+
if (isInPopup) {
|
|
217
|
+
if (config.enableLogging) {
|
|
218
|
+
console.log("[MSAL] Detected popup window - minimal initialization");
|
|
219
|
+
}
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
203
222
|
if (instanceRef.current) {
|
|
204
223
|
return;
|
|
205
224
|
}
|
|
@@ -208,17 +227,17 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
208
227
|
const msalConfig = createMsalConfig(config);
|
|
209
228
|
const instance = new import_msal_browser2.PublicClientApplication(msalConfig);
|
|
210
229
|
await instance.initialize();
|
|
211
|
-
const
|
|
230
|
+
const isInPopup2 = window.opener && window.opener !== window;
|
|
212
231
|
try {
|
|
213
232
|
const response = await instance.handleRedirectPromise();
|
|
214
233
|
if (response) {
|
|
215
234
|
if (config.enableLogging) {
|
|
216
|
-
console.log("[MSAL] Redirect authentication successful",
|
|
235
|
+
console.log("[MSAL] Redirect authentication successful", isInPopup2 ? "(popup)" : "(main)");
|
|
217
236
|
}
|
|
218
237
|
if (response.account) {
|
|
219
238
|
instance.setActiveAccount(response.account);
|
|
220
239
|
}
|
|
221
|
-
if (!
|
|
240
|
+
if (!isInPopup2 && window.location.hash) {
|
|
222
241
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
223
242
|
}
|
|
224
243
|
}
|
|
@@ -234,7 +253,7 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
234
253
|
} else {
|
|
235
254
|
console.error("[MSAL] Redirect handling error:", redirectError);
|
|
236
255
|
}
|
|
237
|
-
if (!
|
|
256
|
+
if (!isInPopup2 && window.location.hash && (window.location.hash.includes("code=") || window.location.hash.includes("error="))) {
|
|
238
257
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
239
258
|
}
|
|
240
259
|
}
|
|
@@ -290,6 +309,9 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
290
309
|
if (typeof window === "undefined") {
|
|
291
310
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
|
|
292
311
|
}
|
|
312
|
+
if (isInPopup) {
|
|
313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "none" }, children: "Completing authentication..." });
|
|
314
|
+
}
|
|
293
315
|
if (!msalInstance) {
|
|
294
316
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
|
|
295
317
|
}
|
|
@@ -319,9 +341,12 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
319
341
|
return;
|
|
320
342
|
}
|
|
321
343
|
try {
|
|
344
|
+
const popupRedirectUri = getPopupRedirectUri();
|
|
322
345
|
const request = {
|
|
323
346
|
scopes,
|
|
324
|
-
prompt: "select_account"
|
|
347
|
+
prompt: "select_account",
|
|
348
|
+
// Use popup-specific redirect URI (defaults to /blank.html)
|
|
349
|
+
redirectUri: popupRedirectUri
|
|
325
350
|
};
|
|
326
351
|
const response = await instance.loginPopup(request);
|
|
327
352
|
if (response?.account) {
|
|
@@ -494,7 +519,7 @@ function MicrosoftSignInButton({
|
|
|
494
519
|
text = "Sign in with Microsoft",
|
|
495
520
|
variant = "dark",
|
|
496
521
|
size = "medium",
|
|
497
|
-
useRedirect =
|
|
522
|
+
useRedirect = true,
|
|
498
523
|
scopes,
|
|
499
524
|
className = "",
|
|
500
525
|
style,
|
|
@@ -1682,6 +1707,7 @@ var import_msal_react3 = require("@azure/msal-react");
|
|
|
1682
1707
|
createScopedLogger,
|
|
1683
1708
|
getDebugLogger,
|
|
1684
1709
|
getMsalInstance,
|
|
1710
|
+
getPopupRedirectUri,
|
|
1685
1711
|
isValidAccountData,
|
|
1686
1712
|
isValidRedirectUri,
|
|
1687
1713
|
isValidScope,
|
package/dist/index.mjs
CHANGED
|
@@ -52,6 +52,10 @@ function validateScopes(scopes) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// src/utils/createMsalConfig.ts
|
|
55
|
+
var storedPopupRedirectUri;
|
|
56
|
+
function getPopupRedirectUri() {
|
|
57
|
+
return storedPopupRedirectUri;
|
|
58
|
+
}
|
|
55
59
|
function createMsalConfig(config) {
|
|
56
60
|
if (config.msalConfig) {
|
|
57
61
|
return config.msalConfig;
|
|
@@ -61,10 +65,11 @@ function createMsalConfig(config) {
|
|
|
61
65
|
tenantId,
|
|
62
66
|
authorityType = "common",
|
|
63
67
|
redirectUri,
|
|
68
|
+
popupRedirectUri,
|
|
64
69
|
postLogoutRedirectUri,
|
|
65
70
|
cacheLocation = "sessionStorage",
|
|
66
71
|
storeAuthStateInCookie = false,
|
|
67
|
-
navigateToLoginRequestUrl =
|
|
72
|
+
navigateToLoginRequestUrl = false,
|
|
68
73
|
enableLogging = false,
|
|
69
74
|
loggerCallback,
|
|
70
75
|
allowedRedirectUris
|
|
@@ -83,6 +88,8 @@ function createMsalConfig(config) {
|
|
|
83
88
|
};
|
|
84
89
|
const defaultRedirectUri = typeof window !== "undefined" ? window.location.origin : "http://localhost:3000";
|
|
85
90
|
const finalRedirectUri = redirectUri || defaultRedirectUri;
|
|
91
|
+
const finalPopupRedirectUri = popupRedirectUri || finalRedirectUri;
|
|
92
|
+
storedPopupRedirectUri = finalPopupRedirectUri;
|
|
86
93
|
if (allowedRedirectUris && allowedRedirectUris.length > 0) {
|
|
87
94
|
if (!isValidRedirectUri(finalRedirectUri, allowedRedirectUris)) {
|
|
88
95
|
throw new Error(
|
|
@@ -109,6 +116,10 @@ function createMsalConfig(config) {
|
|
|
109
116
|
storeAuthStateInCookie
|
|
110
117
|
},
|
|
111
118
|
system: {
|
|
119
|
+
windowHashTimeout: 6e4,
|
|
120
|
+
// Increase timeout for popup
|
|
121
|
+
iframeHashTimeout: 6e3,
|
|
122
|
+
loadFrameTimeout: 0,
|
|
112
123
|
loggerOptions: {
|
|
113
124
|
loggerCallback: loggerCallback || ((level, message, containsPii) => {
|
|
114
125
|
if (containsPii || !enableLogging) return;
|
|
@@ -143,10 +154,17 @@ function getMsalInstance() {
|
|
|
143
154
|
function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }) {
|
|
144
155
|
const [msalInstance, setMsalInstance] = useState(null);
|
|
145
156
|
const instanceRef = useRef(null);
|
|
157
|
+
const isInPopup = typeof window !== "undefined" && window.opener && window.opener !== window;
|
|
146
158
|
useEffect(() => {
|
|
147
159
|
if (typeof window === "undefined") {
|
|
148
160
|
return;
|
|
149
161
|
}
|
|
162
|
+
if (isInPopup) {
|
|
163
|
+
if (config.enableLogging) {
|
|
164
|
+
console.log("[MSAL] Detected popup window - minimal initialization");
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
150
168
|
if (instanceRef.current) {
|
|
151
169
|
return;
|
|
152
170
|
}
|
|
@@ -155,17 +173,17 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
155
173
|
const msalConfig = createMsalConfig(config);
|
|
156
174
|
const instance = new PublicClientApplication(msalConfig);
|
|
157
175
|
await instance.initialize();
|
|
158
|
-
const
|
|
176
|
+
const isInPopup2 = window.opener && window.opener !== window;
|
|
159
177
|
try {
|
|
160
178
|
const response = await instance.handleRedirectPromise();
|
|
161
179
|
if (response) {
|
|
162
180
|
if (config.enableLogging) {
|
|
163
|
-
console.log("[MSAL] Redirect authentication successful",
|
|
181
|
+
console.log("[MSAL] Redirect authentication successful", isInPopup2 ? "(popup)" : "(main)");
|
|
164
182
|
}
|
|
165
183
|
if (response.account) {
|
|
166
184
|
instance.setActiveAccount(response.account);
|
|
167
185
|
}
|
|
168
|
-
if (!
|
|
186
|
+
if (!isInPopup2 && window.location.hash) {
|
|
169
187
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
170
188
|
}
|
|
171
189
|
}
|
|
@@ -181,7 +199,7 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
181
199
|
} else {
|
|
182
200
|
console.error("[MSAL] Redirect handling error:", redirectError);
|
|
183
201
|
}
|
|
184
|
-
if (!
|
|
202
|
+
if (!isInPopup2 && window.location.hash && (window.location.hash.includes("code=") || window.location.hash.includes("error="))) {
|
|
185
203
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
186
204
|
}
|
|
187
205
|
}
|
|
@@ -237,6 +255,9 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
237
255
|
if (typeof window === "undefined") {
|
|
238
256
|
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
|
|
239
257
|
}
|
|
258
|
+
if (isInPopup) {
|
|
259
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "none" }, children: "Completing authentication..." });
|
|
260
|
+
}
|
|
240
261
|
if (!msalInstance) {
|
|
241
262
|
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
|
|
242
263
|
}
|
|
@@ -266,9 +287,12 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
266
287
|
return;
|
|
267
288
|
}
|
|
268
289
|
try {
|
|
290
|
+
const popupRedirectUri = getPopupRedirectUri();
|
|
269
291
|
const request = {
|
|
270
292
|
scopes,
|
|
271
|
-
prompt: "select_account"
|
|
293
|
+
prompt: "select_account",
|
|
294
|
+
// Use popup-specific redirect URI (defaults to /blank.html)
|
|
295
|
+
redirectUri: popupRedirectUri
|
|
272
296
|
};
|
|
273
297
|
const response = await instance.loginPopup(request);
|
|
274
298
|
if (response?.account) {
|
|
@@ -441,7 +465,7 @@ function MicrosoftSignInButton({
|
|
|
441
465
|
text = "Sign in with Microsoft",
|
|
442
466
|
variant = "dark",
|
|
443
467
|
size = "medium",
|
|
444
|
-
useRedirect =
|
|
468
|
+
useRedirect = true,
|
|
445
469
|
scopes,
|
|
446
470
|
className = "",
|
|
447
471
|
style,
|
|
@@ -1628,6 +1652,7 @@ export {
|
|
|
1628
1652
|
createScopedLogger,
|
|
1629
1653
|
getDebugLogger,
|
|
1630
1654
|
getMsalInstance,
|
|
1655
|
+
getPopupRedirectUri,
|
|
1631
1656
|
isValidAccountData,
|
|
1632
1657
|
isValidRedirectUri,
|
|
1633
1658
|
isValidScope,
|
package/package.json
CHANGED