@chemmangat/msal-next 3.1.1 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -0
- package/README.md +23 -4
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +34 -6
- package/dist/index.mjs +33 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,97 @@
|
|
|
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
|
+
### ✨ New Feature - Separate Popup Redirect URI
|
|
8
|
+
|
|
9
|
+
**Added `popupRedirectUri` prop** - Now you can have different redirect URIs for popup vs redirect flows!
|
|
10
|
+
|
|
11
|
+
**Changes:**
|
|
12
|
+
- Added `popupRedirectUri` prop to MSALProvider (defaults to `/blank.html`)
|
|
13
|
+
- `redirectUri` prop is now used only for redirect flow
|
|
14
|
+
- Popup authentication automatically uses `popupRedirectUri`
|
|
15
|
+
- Exported `getPopupRedirectUri()` utility function
|
|
16
|
+
|
|
17
|
+
**Usage:**
|
|
18
|
+
```tsx
|
|
19
|
+
<MSALProvider
|
|
20
|
+
clientId="..."
|
|
21
|
+
redirectUri="/auth/callback" // For redirect flow
|
|
22
|
+
popupRedirectUri="/blank.html" // For popup flow (default)
|
|
23
|
+
>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Benefits:**
|
|
27
|
+
- Use your custom redirect URI for redirect flow
|
|
28
|
+
- Popup always uses blank.html (no full app loading in popup)
|
|
29
|
+
- More flexible configuration
|
|
30
|
+
|
|
31
|
+
## [3.1.4] - 2026-03-05
|
|
32
|
+
|
|
33
|
+
### 🔧 Configuration Fix - Popup Redirect
|
|
34
|
+
|
|
35
|
+
**BREAKING CHANGE:** You must now create a `public/blank.html` file and configure it as a redirect URI in Azure AD.
|
|
36
|
+
|
|
37
|
+
**Why:** This prevents your full app from loading in the popup window after authentication.
|
|
38
|
+
|
|
39
|
+
**Setup Required:**
|
|
40
|
+
|
|
41
|
+
1. Create `public/blank.html`:
|
|
42
|
+
```html
|
|
43
|
+
<!DOCTYPE html>
|
|
44
|
+
<html>
|
|
45
|
+
<head><title>Auth</title></head>
|
|
46
|
+
<body></body>
|
|
47
|
+
</html>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. Add to Azure AD redirect URIs:
|
|
51
|
+
- `http://localhost:3000/blank.html`
|
|
52
|
+
- `https://yourdomain.com/blank.html`
|
|
53
|
+
|
|
54
|
+
3. Update your MSALProvider:
|
|
55
|
+
```tsx
|
|
56
|
+
<MSALProvider
|
|
57
|
+
clientId="..."
|
|
58
|
+
redirectUri={typeof window !== 'undefined' ? `${window.location.origin}/blank.html` : undefined}
|
|
59
|
+
>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Changes:**
|
|
63
|
+
- Set `navigateToLoginRequestUrl` default to `false`
|
|
64
|
+
- Updated README with blank.html setup instructions
|
|
65
|
+
- Added PUBLIC_BLANK_HTML.md guide
|
|
66
|
+
|
|
67
|
+
## [3.1.3] - 2026-03-05
|
|
68
|
+
|
|
69
|
+
### 🐛 Critical Fix - Popup Redirect Issue
|
|
70
|
+
|
|
71
|
+
**Fixed:** Popup window now stays as popup and doesn't navigate to redirect URI.
|
|
72
|
+
|
|
73
|
+
**Changes:**
|
|
74
|
+
- Added `windowHashTimeout`, `iframeHashTimeout`, and `loadFrameTimeout` to MSAL config
|
|
75
|
+
- Set `redirectUri: undefined` in popup requests to prevent navigation
|
|
76
|
+
- Popup now properly closes after authentication without showing redirect page
|
|
77
|
+
|
|
78
|
+
**This fixes the issue where the redirect URI was opening inside the popup window instead of the popup closing.**
|
|
79
|
+
|
|
80
|
+
## [3.1.2] - 2026-03-05
|
|
81
|
+
|
|
82
|
+
### 📝 Documentation Update
|
|
83
|
+
|
|
84
|
+
- Updated README with current version number
|
|
85
|
+
- No code changes from 3.1.1
|
|
86
|
+
|
|
87
|
+
## [3.1.1] - 2026-03-05
|
|
88
|
+
|
|
89
|
+
### 📝 Documentation & Build
|
|
90
|
+
|
|
91
|
+
- Fixed landing page build issues
|
|
92
|
+
- Cleaned up redundant documentation files
|
|
93
|
+
- Updated package files list
|
|
94
|
+
- No code changes from 3.0.8
|
|
95
|
+
|
|
5
96
|
## [3.0.8] - 2026-03-05
|
|
6
97
|
|
|
7
98
|
### 🚨 CRITICAL BUG FIX
|
package/README.md
CHANGED
|
@@ -5,11 +5,11 @@ 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.
|
|
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
|
|
|
12
|
-
>
|
|
12
|
+
> **💡 Having issues?** Check the [Troubleshooting Guide](./TROUBLESHOOTING.md) for common problems and solutions.
|
|
13
13
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
@@ -91,7 +91,23 @@ npm install @chemmangat/msal-next@latest @azure/msal-browser@^4.0.0 @azure/msal-
|
|
|
91
91
|
|
|
92
92
|
> **Important:** Use `MSALProvider` (not `MsalAuthProvider`) in your layout.tsx to avoid the "createContext only works in Client Components" error.
|
|
93
93
|
|
|
94
|
-
### 1.
|
|
94
|
+
### 1. Create blank.html for popup authentication
|
|
95
|
+
|
|
96
|
+
Create `public/blank.html`:
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<!DOCTYPE html>
|
|
100
|
+
<html>
|
|
101
|
+
<head><title>Auth</title></head>
|
|
102
|
+
<body></body>
|
|
103
|
+
</html>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Add to Azure AD redirect URIs:
|
|
107
|
+
- `http://localhost:3000/blank.html`
|
|
108
|
+
- `https://yourdomain.com/blank.html`
|
|
109
|
+
|
|
110
|
+
### 2. Wrap your app with MSALProvider
|
|
95
111
|
|
|
96
112
|
```tsx
|
|
97
113
|
// app/layout.tsx
|
|
@@ -104,6 +120,9 @@ export default function RootLayout({ children }) {
|
|
|
104
120
|
<MSALProvider
|
|
105
121
|
clientId={process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID!}
|
|
106
122
|
tenantId={process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID!}
|
|
123
|
+
// Optional: specify custom redirect URIs
|
|
124
|
+
// redirectUri="/auth/callback" // For redirect flow
|
|
125
|
+
// popupRedirectUri="/blank.html" // For popup flow (default)
|
|
107
126
|
>
|
|
108
127
|
{children}
|
|
109
128
|
</MSALProvider>
|
|
@@ -113,7 +132,7 @@ export default function RootLayout({ children }) {
|
|
|
113
132
|
}
|
|
114
133
|
```
|
|
115
134
|
|
|
116
|
-
###
|
|
135
|
+
### 3. Add sign-in button
|
|
117
136
|
|
|
118
137
|
```tsx
|
|
119
138
|
// app/page.tsx
|
package/dist/index.d.mts
CHANGED
|
@@ -41,6 +41,12 @@ interface MsalAuthConfig {
|
|
|
41
41
|
* @default window.location.origin
|
|
42
42
|
*/
|
|
43
43
|
redirectUri?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Redirect URI for popup authentication (recommended: /blank.html)
|
|
46
|
+
* If not specified, uses redirectUri
|
|
47
|
+
* @default redirectUri
|
|
48
|
+
*/
|
|
49
|
+
popupRedirectUri?: string;
|
|
44
50
|
/**
|
|
45
51
|
* Post logout redirect URI
|
|
46
52
|
* @default redirectUri
|
|
@@ -103,7 +109,7 @@ interface MsalAuthProviderProps extends MsalAuthConfig {
|
|
|
103
109
|
* @returns The MSAL instance or null if not initialized
|
|
104
110
|
*/
|
|
105
111
|
declare function getMsalInstance(): PublicClientApplication | null;
|
|
106
|
-
declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
112
|
+
declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element | null;
|
|
107
113
|
|
|
108
114
|
/**
|
|
109
115
|
* Pre-configured MSALProvider component for Next.js App Router layouts.
|
|
@@ -584,6 +590,7 @@ interface UseRolesReturn {
|
|
|
584
590
|
*/
|
|
585
591
|
declare function useRoles(): UseRolesReturn;
|
|
586
592
|
|
|
593
|
+
declare function getPopupRedirectUri(): string | undefined;
|
|
587
594
|
declare function createMsalConfig(config: MsalAuthConfig): Configuration;
|
|
588
595
|
|
|
589
596
|
interface WithAuthOptions extends Omit<AuthGuardProps, 'children'> {
|
|
@@ -931,4 +938,4 @@ interface ServerSession {
|
|
|
931
938
|
accessToken?: string;
|
|
932
939
|
}
|
|
933
940
|
|
|
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 };
|
|
941
|
+
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,12 @@ interface MsalAuthConfig {
|
|
|
41
41
|
* @default window.location.origin
|
|
42
42
|
*/
|
|
43
43
|
redirectUri?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Redirect URI for popup authentication (recommended: /blank.html)
|
|
46
|
+
* If not specified, uses redirectUri
|
|
47
|
+
* @default redirectUri
|
|
48
|
+
*/
|
|
49
|
+
popupRedirectUri?: string;
|
|
44
50
|
/**
|
|
45
51
|
* Post logout redirect URI
|
|
46
52
|
* @default redirectUri
|
|
@@ -103,7 +109,7 @@ interface MsalAuthProviderProps extends MsalAuthConfig {
|
|
|
103
109
|
* @returns The MSAL instance or null if not initialized
|
|
104
110
|
*/
|
|
105
111
|
declare function getMsalInstance(): PublicClientApplication | null;
|
|
106
|
-
declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
112
|
+
declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element | null;
|
|
107
113
|
|
|
108
114
|
/**
|
|
109
115
|
* Pre-configured MSALProvider component for Next.js App Router layouts.
|
|
@@ -584,6 +590,7 @@ interface UseRolesReturn {
|
|
|
584
590
|
*/
|
|
585
591
|
declare function useRoles(): UseRolesReturn;
|
|
586
592
|
|
|
593
|
+
declare function getPopupRedirectUri(): string | undefined;
|
|
587
594
|
declare function createMsalConfig(config: MsalAuthConfig): Configuration;
|
|
588
595
|
|
|
589
596
|
interface WithAuthOptions extends Omit<AuthGuardProps, 'children'> {
|
|
@@ -931,4 +938,4 @@ interface ServerSession {
|
|
|
931
938
|
accessToken?: string;
|
|
932
939
|
}
|
|
933
940
|
|
|
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 };
|
|
941
|
+
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,9 @@ 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 defaultPopupRedirectUri = typeof window !== "undefined" ? `${window.location.origin}/blank.html` : "http://localhost:3000/blank.html";
|
|
146
|
+
const finalPopupRedirectUri = popupRedirectUri || defaultPopupRedirectUri;
|
|
147
|
+
storedPopupRedirectUri = finalPopupRedirectUri;
|
|
139
148
|
if (allowedRedirectUris && allowedRedirectUris.length > 0) {
|
|
140
149
|
if (!isValidRedirectUri(finalRedirectUri, allowedRedirectUris)) {
|
|
141
150
|
throw new Error(
|
|
@@ -162,6 +171,10 @@ function createMsalConfig(config) {
|
|
|
162
171
|
storeAuthStateInCookie
|
|
163
172
|
},
|
|
164
173
|
system: {
|
|
174
|
+
windowHashTimeout: 6e4,
|
|
175
|
+
// Increase timeout for popup
|
|
176
|
+
iframeHashTimeout: 6e3,
|
|
177
|
+
loadFrameTimeout: 0,
|
|
165
178
|
loggerOptions: {
|
|
166
179
|
loggerCallback: loggerCallback || ((level, message, containsPii) => {
|
|
167
180
|
if (containsPii || !enableLogging) return;
|
|
@@ -200,6 +213,13 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
200
213
|
if (typeof window === "undefined") {
|
|
201
214
|
return;
|
|
202
215
|
}
|
|
216
|
+
const isInPopup2 = window.opener && window.opener !== window;
|
|
217
|
+
if (isInPopup2) {
|
|
218
|
+
if (config.enableLogging) {
|
|
219
|
+
console.log("[MSAL] Detected popup window - minimal initialization");
|
|
220
|
+
}
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
203
223
|
if (instanceRef.current) {
|
|
204
224
|
return;
|
|
205
225
|
}
|
|
@@ -208,17 +228,17 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
208
228
|
const msalConfig = createMsalConfig(config);
|
|
209
229
|
const instance = new import_msal_browser2.PublicClientApplication(msalConfig);
|
|
210
230
|
await instance.initialize();
|
|
211
|
-
const
|
|
231
|
+
const isInPopup3 = window.opener && window.opener !== window;
|
|
212
232
|
try {
|
|
213
233
|
const response = await instance.handleRedirectPromise();
|
|
214
234
|
if (response) {
|
|
215
235
|
if (config.enableLogging) {
|
|
216
|
-
console.log("[MSAL] Redirect authentication successful",
|
|
236
|
+
console.log("[MSAL] Redirect authentication successful", isInPopup3 ? "(popup)" : "(main)");
|
|
217
237
|
}
|
|
218
238
|
if (response.account) {
|
|
219
239
|
instance.setActiveAccount(response.account);
|
|
220
240
|
}
|
|
221
|
-
if (!
|
|
241
|
+
if (!isInPopup3 && window.location.hash) {
|
|
222
242
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
223
243
|
}
|
|
224
244
|
}
|
|
@@ -234,7 +254,7 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
234
254
|
} else {
|
|
235
255
|
console.error("[MSAL] Redirect handling error:", redirectError);
|
|
236
256
|
}
|
|
237
|
-
if (!
|
|
257
|
+
if (!isInPopup3 && window.location.hash && (window.location.hash.includes("code=") || window.location.hash.includes("error="))) {
|
|
238
258
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
239
259
|
}
|
|
240
260
|
}
|
|
@@ -290,6 +310,10 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
290
310
|
if (typeof window === "undefined") {
|
|
291
311
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
|
|
292
312
|
}
|
|
313
|
+
const isInPopup = window.opener && window.opener !== window;
|
|
314
|
+
if (isInPopup) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
293
317
|
if (!msalInstance) {
|
|
294
318
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
|
|
295
319
|
}
|
|
@@ -319,9 +343,12 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
319
343
|
return;
|
|
320
344
|
}
|
|
321
345
|
try {
|
|
346
|
+
const popupRedirectUri = getPopupRedirectUri();
|
|
322
347
|
const request = {
|
|
323
348
|
scopes,
|
|
324
|
-
prompt: "select_account"
|
|
349
|
+
prompt: "select_account",
|
|
350
|
+
// Use popup-specific redirect URI (defaults to /blank.html)
|
|
351
|
+
redirectUri: popupRedirectUri
|
|
325
352
|
};
|
|
326
353
|
const response = await instance.loginPopup(request);
|
|
327
354
|
if (response?.account) {
|
|
@@ -1682,6 +1709,7 @@ var import_msal_react3 = require("@azure/msal-react");
|
|
|
1682
1709
|
createScopedLogger,
|
|
1683
1710
|
getDebugLogger,
|
|
1684
1711
|
getMsalInstance,
|
|
1712
|
+
getPopupRedirectUri,
|
|
1685
1713
|
isValidAccountData,
|
|
1686
1714
|
isValidRedirectUri,
|
|
1687
1715
|
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,9 @@ 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 defaultPopupRedirectUri = typeof window !== "undefined" ? `${window.location.origin}/blank.html` : "http://localhost:3000/blank.html";
|
|
92
|
+
const finalPopupRedirectUri = popupRedirectUri || defaultPopupRedirectUri;
|
|
93
|
+
storedPopupRedirectUri = finalPopupRedirectUri;
|
|
86
94
|
if (allowedRedirectUris && allowedRedirectUris.length > 0) {
|
|
87
95
|
if (!isValidRedirectUri(finalRedirectUri, allowedRedirectUris)) {
|
|
88
96
|
throw new Error(
|
|
@@ -109,6 +117,10 @@ function createMsalConfig(config) {
|
|
|
109
117
|
storeAuthStateInCookie
|
|
110
118
|
},
|
|
111
119
|
system: {
|
|
120
|
+
windowHashTimeout: 6e4,
|
|
121
|
+
// Increase timeout for popup
|
|
122
|
+
iframeHashTimeout: 6e3,
|
|
123
|
+
loadFrameTimeout: 0,
|
|
112
124
|
loggerOptions: {
|
|
113
125
|
loggerCallback: loggerCallback || ((level, message, containsPii) => {
|
|
114
126
|
if (containsPii || !enableLogging) return;
|
|
@@ -147,6 +159,13 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
147
159
|
if (typeof window === "undefined") {
|
|
148
160
|
return;
|
|
149
161
|
}
|
|
162
|
+
const isInPopup2 = window.opener && window.opener !== window;
|
|
163
|
+
if (isInPopup2) {
|
|
164
|
+
if (config.enableLogging) {
|
|
165
|
+
console.log("[MSAL] Detected popup window - minimal initialization");
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
150
169
|
if (instanceRef.current) {
|
|
151
170
|
return;
|
|
152
171
|
}
|
|
@@ -155,17 +174,17 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
155
174
|
const msalConfig = createMsalConfig(config);
|
|
156
175
|
const instance = new PublicClientApplication(msalConfig);
|
|
157
176
|
await instance.initialize();
|
|
158
|
-
const
|
|
177
|
+
const isInPopup3 = window.opener && window.opener !== window;
|
|
159
178
|
try {
|
|
160
179
|
const response = await instance.handleRedirectPromise();
|
|
161
180
|
if (response) {
|
|
162
181
|
if (config.enableLogging) {
|
|
163
|
-
console.log("[MSAL] Redirect authentication successful",
|
|
182
|
+
console.log("[MSAL] Redirect authentication successful", isInPopup3 ? "(popup)" : "(main)");
|
|
164
183
|
}
|
|
165
184
|
if (response.account) {
|
|
166
185
|
instance.setActiveAccount(response.account);
|
|
167
186
|
}
|
|
168
|
-
if (!
|
|
187
|
+
if (!isInPopup3 && window.location.hash) {
|
|
169
188
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
170
189
|
}
|
|
171
190
|
}
|
|
@@ -181,7 +200,7 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
181
200
|
} else {
|
|
182
201
|
console.error("[MSAL] Redirect handling error:", redirectError);
|
|
183
202
|
}
|
|
184
|
-
if (!
|
|
203
|
+
if (!isInPopup3 && window.location.hash && (window.location.hash.includes("code=") || window.location.hash.includes("error="))) {
|
|
185
204
|
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
186
205
|
}
|
|
187
206
|
}
|
|
@@ -237,6 +256,10 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
|
|
|
237
256
|
if (typeof window === "undefined") {
|
|
238
257
|
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
|
|
239
258
|
}
|
|
259
|
+
const isInPopup = window.opener && window.opener !== window;
|
|
260
|
+
if (isInPopup) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
240
263
|
if (!msalInstance) {
|
|
241
264
|
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
|
|
242
265
|
}
|
|
@@ -266,9 +289,12 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
266
289
|
return;
|
|
267
290
|
}
|
|
268
291
|
try {
|
|
292
|
+
const popupRedirectUri = getPopupRedirectUri();
|
|
269
293
|
const request = {
|
|
270
294
|
scopes,
|
|
271
|
-
prompt: "select_account"
|
|
295
|
+
prompt: "select_account",
|
|
296
|
+
// Use popup-specific redirect URI (defaults to /blank.html)
|
|
297
|
+
redirectUri: popupRedirectUri
|
|
272
298
|
};
|
|
273
299
|
const response = await instance.loginPopup(request);
|
|
274
300
|
if (response?.account) {
|
|
@@ -1628,6 +1654,7 @@ export {
|
|
|
1628
1654
|
createScopedLogger,
|
|
1629
1655
|
getDebugLogger,
|
|
1630
1656
|
getMsalInstance,
|
|
1657
|
+
getPopupRedirectUri,
|
|
1631
1658
|
isValidAccountData,
|
|
1632
1659
|
isValidRedirectUri,
|
|
1633
1660
|
isValidScope,
|
package/package.json
CHANGED