@chemmangat/msal-next 3.0.4 → 3.0.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/dist/index.d.mts CHANGED
@@ -3,7 +3,6 @@ import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplicat
3
3
  export { AccountInfo } from '@azure/msal-browser';
4
4
  import { ReactNode, CSSProperties, Component, ErrorInfo, ComponentType } from 'react';
5
5
  import { NextRequest, NextResponse } from 'next/server';
6
- export { ServerSession } from './server.mjs';
7
6
  export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
8
7
 
9
8
  /**
@@ -912,4 +911,24 @@ interface AuthMiddlewareConfig {
912
911
  */
913
912
  declare function createAuthMiddleware(config?: AuthMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
914
913
 
915
- 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, 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 };
914
+ interface ServerSession {
915
+ /**
916
+ * Whether user is authenticated
917
+ */
918
+ isAuthenticated: boolean;
919
+ /**
920
+ * User's account ID from MSAL cache
921
+ */
922
+ accountId?: string;
923
+ /**
924
+ * User's username/email
925
+ */
926
+ username?: string;
927
+ /**
928
+ * Access token (if available in cookie)
929
+ * @deprecated Storing tokens in cookies is not recommended for security reasons
930
+ */
931
+ accessToken?: string;
932
+ }
933
+
934
+ export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,6 @@ import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplicat
3
3
  export { AccountInfo } from '@azure/msal-browser';
4
4
  import { ReactNode, CSSProperties, Component, ErrorInfo, ComponentType } from 'react';
5
5
  import { NextRequest, NextResponse } from 'next/server';
6
- export { ServerSession } from './server.js';
7
6
  export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
8
7
 
9
8
  /**
@@ -912,4 +911,24 @@ interface AuthMiddlewareConfig {
912
911
  */
913
912
  declare function createAuthMiddleware(config?: AuthMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
914
913
 
915
- 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, 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 };
914
+ interface ServerSession {
915
+ /**
916
+ * Whether user is authenticated
917
+ */
918
+ isAuthenticated: boolean;
919
+ /**
920
+ * User's account ID from MSAL cache
921
+ */
922
+ accountId?: string;
923
+ /**
924
+ * User's username/email
925
+ */
926
+ username?: string;
927
+ /**
928
+ * Access token (if available in cookie)
929
+ * @deprecated Storing tokens in cookies is not recommended for security reasons
930
+ */
931
+ accessToken?: string;
932
+ }
933
+
934
+ export { AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type UseGraphApiReturn, type UseMsalAuthReturn, type UseRolesReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type WithAuthOptions, createAuthMiddleware, createMsalConfig, createRetryWrapper, createScopedLogger, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useRoles, useUserProfile, validateScopes, withAuth };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  "use strict";
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -207,27 +208,34 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
207
208
  const msalConfig = createMsalConfig(config);
208
209
  const instance = new import_msal_browser2.PublicClientApplication(msalConfig);
209
210
  await instance.initialize();
210
- try {
211
- const response = await instance.handleRedirectPromise();
212
- if (response) {
213
- if (config.enableLogging) {
214
- console.log("[MSAL] Redirect authentication successful");
211
+ const isInPopup = window.opener && window.opener !== window;
212
+ if (!isInPopup) {
213
+ try {
214
+ const response = await instance.handleRedirectPromise();
215
+ if (response) {
216
+ if (config.enableLogging) {
217
+ console.log("[MSAL] Redirect authentication successful");
218
+ }
219
+ if (response.account) {
220
+ instance.setActiveAccount(response.account);
221
+ }
215
222
  }
216
- if (response.account) {
217
- instance.setActiveAccount(response.account);
223
+ } catch (redirectError) {
224
+ if (redirectError?.errorCode === "no_token_request_cache_error") {
225
+ if (config.enableLogging) {
226
+ console.log("[MSAL] No pending redirect found (this is normal)");
227
+ }
228
+ } else if (redirectError?.errorCode === "user_cancelled") {
229
+ if (config.enableLogging) {
230
+ console.log("[MSAL] User cancelled authentication");
231
+ }
232
+ } else {
233
+ console.error("[MSAL] Redirect handling error:", redirectError);
218
234
  }
219
235
  }
220
- } catch (redirectError) {
221
- if (redirectError?.errorCode === "no_token_request_cache_error") {
222
- if (config.enableLogging) {
223
- console.log("[MSAL] No pending redirect found (this is normal)");
224
- }
225
- } else if (redirectError?.errorCode === "user_cancelled") {
226
- if (config.enableLogging) {
227
- console.log("[MSAL] User cancelled authentication");
228
- }
229
- } else {
230
- console.error("[MSAL] Redirect handling error:", redirectError);
236
+ } else {
237
+ if (config.enableLogging) {
238
+ console.log("[MSAL] Running in popup window, skipping redirect handling");
231
239
  }
232
240
  }
233
241
  const accounts = instance.getAllAccounts();
package/dist/index.mjs CHANGED
@@ -1,11 +1,4 @@
1
- import {
2
- isValidAccountData,
3
- isValidRedirectUri,
4
- isValidScope,
5
- safeJsonParse,
6
- sanitizeError,
7
- validateScopes
8
- } from "./chunk-AD43IVG7.mjs";
1
+ "use client";
9
2
 
10
3
  // src/components/MsalAuthProvider.tsx
11
4
  import { MsalProvider } from "@azure/msal-react";
@@ -14,6 +7,51 @@ import { useEffect, useState, useRef } from "react";
14
7
 
15
8
  // src/utils/createMsalConfig.ts
16
9
  import { LogLevel } from "@azure/msal-browser";
10
+
11
+ // src/utils/validation.ts
12
+ function safeJsonParse(jsonString, validator) {
13
+ try {
14
+ const parsed = JSON.parse(jsonString);
15
+ if (validator(parsed)) {
16
+ return parsed;
17
+ }
18
+ console.warn("[Validation] JSON validation failed");
19
+ return null;
20
+ } catch (error) {
21
+ console.error("[Validation] JSON parse error:", error);
22
+ return null;
23
+ }
24
+ }
25
+ function isValidAccountData(data) {
26
+ return typeof data === "object" && data !== null && typeof data.homeAccountId === "string" && data.homeAccountId.length > 0 && typeof data.username === "string" && data.username.length > 0 && (data.name === void 0 || typeof data.name === "string");
27
+ }
28
+ function sanitizeError(error) {
29
+ if (error instanceof Error) {
30
+ const message = error.message;
31
+ const sanitized = 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]");
32
+ return sanitized;
33
+ }
34
+ return "An unexpected error occurred";
35
+ }
36
+ function isValidRedirectUri(uri, allowedOrigins) {
37
+ try {
38
+ const url = new URL(uri);
39
+ return allowedOrigins.some((allowed) => {
40
+ const allowedUrl = new URL(allowed);
41
+ return url.origin === allowedUrl.origin;
42
+ });
43
+ } catch {
44
+ return false;
45
+ }
46
+ }
47
+ function isValidScope(scope) {
48
+ return /^[a-zA-Z0-9._-]+$/.test(scope);
49
+ }
50
+ function validateScopes(scopes) {
51
+ return Array.isArray(scopes) && scopes.every(isValidScope);
52
+ }
53
+
54
+ // src/utils/createMsalConfig.ts
17
55
  function createMsalConfig(config) {
18
56
  if (config.msalConfig) {
19
57
  return config.msalConfig;
@@ -117,27 +155,34 @@ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config
117
155
  const msalConfig = createMsalConfig(config);
118
156
  const instance = new PublicClientApplication(msalConfig);
119
157
  await instance.initialize();
120
- try {
121
- const response = await instance.handleRedirectPromise();
122
- if (response) {
123
- if (config.enableLogging) {
124
- console.log("[MSAL] Redirect authentication successful");
158
+ const isInPopup = window.opener && window.opener !== window;
159
+ if (!isInPopup) {
160
+ try {
161
+ const response = await instance.handleRedirectPromise();
162
+ if (response) {
163
+ if (config.enableLogging) {
164
+ console.log("[MSAL] Redirect authentication successful");
165
+ }
166
+ if (response.account) {
167
+ instance.setActiveAccount(response.account);
168
+ }
125
169
  }
126
- if (response.account) {
127
- instance.setActiveAccount(response.account);
170
+ } catch (redirectError) {
171
+ if (redirectError?.errorCode === "no_token_request_cache_error") {
172
+ if (config.enableLogging) {
173
+ console.log("[MSAL] No pending redirect found (this is normal)");
174
+ }
175
+ } else if (redirectError?.errorCode === "user_cancelled") {
176
+ if (config.enableLogging) {
177
+ console.log("[MSAL] User cancelled authentication");
178
+ }
179
+ } else {
180
+ console.error("[MSAL] Redirect handling error:", redirectError);
128
181
  }
129
182
  }
130
- } catch (redirectError) {
131
- if (redirectError?.errorCode === "no_token_request_cache_error") {
132
- if (config.enableLogging) {
133
- console.log("[MSAL] No pending redirect found (this is normal)");
134
- }
135
- } else if (redirectError?.errorCode === "user_cancelled") {
136
- if (config.enableLogging) {
137
- console.log("[MSAL] User cancelled authentication");
138
- }
139
- } else {
140
- console.error("[MSAL] Redirect handling error:", redirectError);
183
+ } else {
184
+ if (config.enableLogging) {
185
+ console.log("[MSAL] Running in popup window, skipping redirect handling");
141
186
  }
142
187
  }
143
188
  const accounts = instance.getAllAccounts();
package/dist/server.mjs CHANGED
@@ -1,10 +1,25 @@
1
- import {
2
- isValidAccountData,
3
- safeJsonParse
4
- } from "./chunk-AD43IVG7.mjs";
5
-
6
1
  // src/utils/getServerSession.ts
7
2
  import { cookies, headers } from "next/headers";
3
+
4
+ // src/utils/validation.ts
5
+ function safeJsonParse(jsonString, validator) {
6
+ try {
7
+ const parsed = JSON.parse(jsonString);
8
+ if (validator(parsed)) {
9
+ return parsed;
10
+ }
11
+ console.warn("[Validation] JSON validation failed");
12
+ return null;
13
+ } catch (error) {
14
+ console.error("[Validation] JSON parse error:", error);
15
+ return null;
16
+ }
17
+ }
18
+ function isValidAccountData(data) {
19
+ return typeof data === "object" && data !== null && typeof data.homeAccountId === "string" && data.homeAccountId.length > 0 && typeof data.username === "string" && data.username.length > 0 && (data.name === void 0 || typeof data.name === "string");
20
+ }
21
+
22
+ // src/utils/getServerSession.ts
8
23
  async function getServerSession() {
9
24
  try {
10
25
  const cookieStore = await cookies();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chemmangat/msal-next",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "Production-grade MSAL authentication package for Next.js App Router with minimal boilerplate",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -1,51 +0,0 @@
1
- // src/utils/validation.ts
2
- function safeJsonParse(jsonString, validator) {
3
- try {
4
- const parsed = JSON.parse(jsonString);
5
- if (validator(parsed)) {
6
- return parsed;
7
- }
8
- console.warn("[Validation] JSON validation failed");
9
- return null;
10
- } catch (error) {
11
- console.error("[Validation] JSON parse error:", error);
12
- return null;
13
- }
14
- }
15
- function isValidAccountData(data) {
16
- return typeof data === "object" && data !== null && typeof data.homeAccountId === "string" && data.homeAccountId.length > 0 && typeof data.username === "string" && data.username.length > 0 && (data.name === void 0 || typeof data.name === "string");
17
- }
18
- function sanitizeError(error) {
19
- if (error instanceof Error) {
20
- const message = error.message;
21
- const sanitized = 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]");
22
- return sanitized;
23
- }
24
- return "An unexpected error occurred";
25
- }
26
- function isValidRedirectUri(uri, allowedOrigins) {
27
- try {
28
- const url = new URL(uri);
29
- return allowedOrigins.some((allowed) => {
30
- const allowedUrl = new URL(allowed);
31
- return url.origin === allowedUrl.origin;
32
- });
33
- } catch {
34
- return false;
35
- }
36
- }
37
- function isValidScope(scope) {
38
- return /^[a-zA-Z0-9._-]+$/.test(scope);
39
- }
40
- function validateScopes(scopes) {
41
- return Array.isArray(scopes) && scopes.every(isValidScope);
42
- }
43
-
44
- export {
45
- safeJsonParse,
46
- isValidAccountData,
47
- sanitizeError,
48
- isValidRedirectUri,
49
- isValidScope,
50
- validateScopes
51
- };