@chemmangat/msal-next 5.2.0 → 5.3.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/CHANGELOG.md +61 -1
- package/dist/index.d.mts +23 -43
- package/dist/index.d.ts +23 -43
- package/dist/index.js +43 -114
- package/dist/index.mjs +39 -109
- package/dist/middleware.d.mts +115 -0
- package/dist/middleware.d.ts +115 -0
- package/dist/middleware.js +203 -0
- package/dist/middleware.mjs +201 -0
- package/dist/server.d.mts +24 -5
- package/dist/server.d.ts +24 -5
- package/dist/server.js +16 -14
- package/dist/server.mjs +16 -15
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,67 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [5.
|
|
5
|
+
## [5.3.0] - 2026-04-07
|
|
6
|
+
|
|
7
|
+
### 🐛 Bug Fixes
|
|
8
|
+
|
|
9
|
+
#### Fix 1 — Auto-sync `msal.account` session cookie (no manual cookie code needed)
|
|
10
|
+
|
|
11
|
+
`MsalAuthProvider` now automatically writes and clears the `msal.account` cookie on every auth event. The middleware works out of the box with zero manual setup.
|
|
12
|
+
|
|
13
|
+
- `LOGIN_SUCCESS` → writes `msal.account` cookie (`{ homeAccountId, username, name }`, URL-encoded, `path=/; SameSite=Lax`)
|
|
14
|
+
- `LOGOUT_SUCCESS` / `LOGOUT_END` → clears the cookie
|
|
15
|
+
- Redirect flow (`handleRedirectPromise`) → writes cookie immediately after redirect completes
|
|
16
|
+
- Existing cached account on init → restores cookie (handles browser restart with `localStorage` cache)
|
|
17
|
+
|
|
18
|
+
#### Fix 2 — `setServerSessionCookie` no longer calls a non-existent API route
|
|
19
|
+
|
|
20
|
+
The old implementation called `fetch('/api/auth/session')` which required an undocumented route that didn't exist. It now writes `document.cookie` directly — same format as Fix 1. The function signature changed from `async (account, accessToken?) => Promise<void>` to `(account) => void`.
|
|
21
|
+
|
|
22
|
+
A new `clearServerSessionCookie()` helper is also exported from `@chemmangat/msal-next/server`.
|
|
23
|
+
|
|
24
|
+
> As of v5.3.0 you rarely need to call either function manually — `MsalAuthProvider` handles the cookie automatically.
|
|
25
|
+
|
|
26
|
+
#### Fix 3 — `useTokenRefresh` now reads real token expiry
|
|
27
|
+
|
|
28
|
+
The hook previously hardcoded `expiresIn = 3600`. It now calls `instance.acquireTokenSilent` directly and reads `response.expiresOn` to calculate the actual remaining seconds. Falls back to `3600` if `expiresOn` is `null`.
|
|
29
|
+
|
|
30
|
+
#### Fix 4 — `navigateToLoginRequestUrl` JSDoc default corrected
|
|
31
|
+
|
|
32
|
+
The `@defaultValue` in `MsalAuthConfig` was documented as `true` but the actual default in `createMsalConfig` was `false`. Corrected to `@defaultValue false`.
|
|
33
|
+
|
|
34
|
+
#### Fix 5 — No `/api/auth/session` route required
|
|
35
|
+
|
|
36
|
+
All references to the non-existent `/api/auth/session` route have been removed. Cookie management is now entirely client-side via `document.cookie`.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### 🐛 Bug Fix
|
|
43
|
+
|
|
44
|
+
#### `createAuthMiddleware` now importable from `@chemmangat/msal-next/middleware`
|
|
45
|
+
|
|
46
|
+
`createAuthMiddleware` was previously bundled inside `dist/index.mjs` which carries a `"use client"` directive. Importing it in `middleware.ts` caused Next.js to throw:
|
|
47
|
+
|
|
48
|
+
> "Attempted to call createAuthMiddleware() from the server but createAuthMiddleware is on the client."
|
|
49
|
+
|
|
50
|
+
It now has its own edge-compatible entry point with no React, no `@azure/msal-browser`, and no `"use client"` — only `next/server`.
|
|
51
|
+
|
|
52
|
+
**Migration** (update your import):
|
|
53
|
+
```ts
|
|
54
|
+
// Before
|
|
55
|
+
import { createAuthMiddleware } from '@chemmangat/msal-next';
|
|
56
|
+
|
|
57
|
+
// After
|
|
58
|
+
import { createAuthMiddleware } from '@chemmangat/msal-next/middleware';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Also fixed `tenantValidator.ts` to use `import type` for its `@azure/msal-browser` and `types.ts` imports, ensuring those never get bundled into the middleware output.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
|
|
6
66
|
|
|
7
67
|
### 🔧 Compatibility
|
|
8
68
|
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
|
|
3
3
|
export { AccountInfo } from '@azure/msal-browser';
|
|
4
4
|
import { ReactNode, CSSProperties, Component, ErrorInfo, ComponentType } from 'react';
|
|
5
|
-
import { NextRequest
|
|
5
|
+
import { NextRequest } from 'next/server';
|
|
6
6
|
export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -167,7 +167,7 @@ interface MsalAuthConfig {
|
|
|
167
167
|
* @remarks
|
|
168
168
|
* If true, redirects to the page that initiated login after successful auth.
|
|
169
169
|
*
|
|
170
|
-
* @defaultValue
|
|
170
|
+
* @defaultValue false
|
|
171
171
|
*/
|
|
172
172
|
navigateToLoginRequestUrl?: boolean;
|
|
173
173
|
/**
|
|
@@ -1865,6 +1865,26 @@ declare function withPageAuth<P extends object>(Component: ComponentType<P>, aut
|
|
|
1865
1865
|
displayName: string;
|
|
1866
1866
|
};
|
|
1867
1867
|
|
|
1868
|
+
interface ServerSession {
|
|
1869
|
+
/**
|
|
1870
|
+
* Whether user is authenticated
|
|
1871
|
+
*/
|
|
1872
|
+
isAuthenticated: boolean;
|
|
1873
|
+
/**
|
|
1874
|
+
* User's account ID from MSAL cache
|
|
1875
|
+
*/
|
|
1876
|
+
accountId?: string;
|
|
1877
|
+
/**
|
|
1878
|
+
* User's username/email
|
|
1879
|
+
*/
|
|
1880
|
+
username?: string;
|
|
1881
|
+
/**
|
|
1882
|
+
* Access token (if available in cookie)
|
|
1883
|
+
* @deprecated Storing tokens in cookies is not recommended for security reasons
|
|
1884
|
+
*/
|
|
1885
|
+
accessToken?: string;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1868
1888
|
interface AuthMiddlewareConfig {
|
|
1869
1889
|
/**
|
|
1870
1890
|
* Routes that require authentication
|
|
@@ -1911,45 +1931,5 @@ interface AuthMiddlewareConfig {
|
|
|
1911
1931
|
*/
|
|
1912
1932
|
debug?: boolean;
|
|
1913
1933
|
}
|
|
1914
|
-
/**
|
|
1915
|
-
* Creates authentication middleware for Next.js App Router
|
|
1916
|
-
*
|
|
1917
|
-
* @example
|
|
1918
|
-
* ```tsx
|
|
1919
|
-
* // middleware.ts
|
|
1920
|
-
* import { createAuthMiddleware } from '@chemmangat/msal-next';
|
|
1921
|
-
*
|
|
1922
|
-
* export const middleware = createAuthMiddleware({
|
|
1923
|
-
* protectedRoutes: ['/dashboard', '/profile'],
|
|
1924
|
-
* publicOnlyRoutes: ['/login'],
|
|
1925
|
-
* loginPath: '/login',
|
|
1926
|
-
* });
|
|
1927
|
-
*
|
|
1928
|
-
* export const config = {
|
|
1929
|
-
* matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
1930
|
-
* };
|
|
1931
|
-
* ```
|
|
1932
|
-
*/
|
|
1933
|
-
declare function createAuthMiddleware(config?: AuthMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
1934
|
-
|
|
1935
|
-
interface ServerSession {
|
|
1936
|
-
/**
|
|
1937
|
-
* Whether user is authenticated
|
|
1938
|
-
*/
|
|
1939
|
-
isAuthenticated: boolean;
|
|
1940
|
-
/**
|
|
1941
|
-
* User's account ID from MSAL cache
|
|
1942
|
-
*/
|
|
1943
|
-
accountId?: string;
|
|
1944
|
-
/**
|
|
1945
|
-
* User's username/email
|
|
1946
|
-
*/
|
|
1947
|
-
username?: string;
|
|
1948
|
-
/**
|
|
1949
|
-
* Access token (if available in cookie)
|
|
1950
|
-
* @deprecated Storing tokens in cookies is not recommended for security reasons
|
|
1951
|
-
*/
|
|
1952
|
-
accessToken?: string;
|
|
1953
|
-
}
|
|
1954
1934
|
|
|
1955
|
-
export { AccountList, type AccountListProps, AccountSwitcher, type AccountSwitcherProps, AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, type AuthProtectionConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, MsalError, type MultiTenantConfig, type PageAuthConfig, ProtectedPage, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type TenantAuthConfig, type TenantInfo, type UseGraphApiReturn, type UseMsalAuthReturn, type UseMultiAccountReturn, type UseRolesReturn, type UseTenantReturn, type UseTokenRefreshOptions, type UseTokenRefreshReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type ValidationError, type ValidationResult, type ValidationWarning, type WithAuthOptions,
|
|
1935
|
+
export { AccountList, type AccountListProps, AccountSwitcher, type AccountSwitcherProps, AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, type AuthProtectionConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, MsalError, type MultiTenantConfig, type PageAuthConfig, ProtectedPage, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type TenantAuthConfig, type TenantInfo, type UseGraphApiReturn, type UseMsalAuthReturn, type UseMultiAccountReturn, type UseRolesReturn, type UseTenantReturn, type UseTokenRefreshOptions, type UseTokenRefreshReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type ValidationError, type ValidationResult, type ValidationWarning, type WithAuthOptions, createMissingEnvVarError, createMsalConfig, createRetryWrapper, createScopedLogger, displayValidationResults, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useMultiAccount, useRoles, useTenant, useTenantConfig, useTokenRefresh, useUserProfile, validateConfig, validateScopes, withAuth, withPageAuth, wrapMsalError };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
|
|
3
3
|
export { AccountInfo } from '@azure/msal-browser';
|
|
4
4
|
import { ReactNode, CSSProperties, Component, ErrorInfo, ComponentType } from 'react';
|
|
5
|
-
import { NextRequest
|
|
5
|
+
import { NextRequest } from 'next/server';
|
|
6
6
|
export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -167,7 +167,7 @@ interface MsalAuthConfig {
|
|
|
167
167
|
* @remarks
|
|
168
168
|
* If true, redirects to the page that initiated login after successful auth.
|
|
169
169
|
*
|
|
170
|
-
* @defaultValue
|
|
170
|
+
* @defaultValue false
|
|
171
171
|
*/
|
|
172
172
|
navigateToLoginRequestUrl?: boolean;
|
|
173
173
|
/**
|
|
@@ -1865,6 +1865,26 @@ declare function withPageAuth<P extends object>(Component: ComponentType<P>, aut
|
|
|
1865
1865
|
displayName: string;
|
|
1866
1866
|
};
|
|
1867
1867
|
|
|
1868
|
+
interface ServerSession {
|
|
1869
|
+
/**
|
|
1870
|
+
* Whether user is authenticated
|
|
1871
|
+
*/
|
|
1872
|
+
isAuthenticated: boolean;
|
|
1873
|
+
/**
|
|
1874
|
+
* User's account ID from MSAL cache
|
|
1875
|
+
*/
|
|
1876
|
+
accountId?: string;
|
|
1877
|
+
/**
|
|
1878
|
+
* User's username/email
|
|
1879
|
+
*/
|
|
1880
|
+
username?: string;
|
|
1881
|
+
/**
|
|
1882
|
+
* Access token (if available in cookie)
|
|
1883
|
+
* @deprecated Storing tokens in cookies is not recommended for security reasons
|
|
1884
|
+
*/
|
|
1885
|
+
accessToken?: string;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1868
1888
|
interface AuthMiddlewareConfig {
|
|
1869
1889
|
/**
|
|
1870
1890
|
* Routes that require authentication
|
|
@@ -1911,45 +1931,5 @@ interface AuthMiddlewareConfig {
|
|
|
1911
1931
|
*/
|
|
1912
1932
|
debug?: boolean;
|
|
1913
1933
|
}
|
|
1914
|
-
/**
|
|
1915
|
-
* Creates authentication middleware for Next.js App Router
|
|
1916
|
-
*
|
|
1917
|
-
* @example
|
|
1918
|
-
* ```tsx
|
|
1919
|
-
* // middleware.ts
|
|
1920
|
-
* import { createAuthMiddleware } from '@chemmangat/msal-next';
|
|
1921
|
-
*
|
|
1922
|
-
* export const middleware = createAuthMiddleware({
|
|
1923
|
-
* protectedRoutes: ['/dashboard', '/profile'],
|
|
1924
|
-
* publicOnlyRoutes: ['/login'],
|
|
1925
|
-
* loginPath: '/login',
|
|
1926
|
-
* });
|
|
1927
|
-
*
|
|
1928
|
-
* export const config = {
|
|
1929
|
-
* matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
1930
|
-
* };
|
|
1931
|
-
* ```
|
|
1932
|
-
*/
|
|
1933
|
-
declare function createAuthMiddleware(config?: AuthMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
1934
|
-
|
|
1935
|
-
interface ServerSession {
|
|
1936
|
-
/**
|
|
1937
|
-
* Whether user is authenticated
|
|
1938
|
-
*/
|
|
1939
|
-
isAuthenticated: boolean;
|
|
1940
|
-
/**
|
|
1941
|
-
* User's account ID from MSAL cache
|
|
1942
|
-
*/
|
|
1943
|
-
accountId?: string;
|
|
1944
|
-
/**
|
|
1945
|
-
* User's username/email
|
|
1946
|
-
*/
|
|
1947
|
-
username?: string;
|
|
1948
|
-
/**
|
|
1949
|
-
* Access token (if available in cookie)
|
|
1950
|
-
* @deprecated Storing tokens in cookies is not recommended for security reasons
|
|
1951
|
-
*/
|
|
1952
|
-
accessToken?: string;
|
|
1953
|
-
}
|
|
1954
1934
|
|
|
1955
|
-
export { AccountList, type AccountListProps, AccountSwitcher, type AccountSwitcherProps, AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, type AuthProtectionConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, MsalError, type MultiTenantConfig, type PageAuthConfig, ProtectedPage, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type TenantAuthConfig, type TenantInfo, type UseGraphApiReturn, type UseMsalAuthReturn, type UseMultiAccountReturn, type UseRolesReturn, type UseTenantReturn, type UseTokenRefreshOptions, type UseTokenRefreshReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type ValidationError, type ValidationResult, type ValidationWarning, type WithAuthOptions,
|
|
1935
|
+
export { AccountList, type AccountListProps, AccountSwitcher, type AccountSwitcherProps, AuthGuard, type AuthGuardProps, type AuthMiddlewareConfig, type AuthProtectionConfig, AuthStatus, type AuthStatusProps, type CustomTokenClaims, type DebugLoggerConfig, ErrorBoundary, type ErrorBoundaryProps, type GraphApiOptions, MSALProvider, MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, MsalError, type MultiTenantConfig, type PageAuthConfig, ProtectedPage, type RetryConfig, type ServerSession, SignOutButton, type SignOutButtonProps, type TenantAuthConfig, type TenantInfo, type UseGraphApiReturn, type UseMsalAuthReturn, type UseMultiAccountReturn, type UseRolesReturn, type UseTenantReturn, type UseTokenRefreshOptions, type UseTokenRefreshReturn, type UseUserProfileReturn, UserAvatar, type UserAvatarProps, type UserProfile, type ValidatedAccountData, type ValidationError, type ValidationResult, type ValidationWarning, type WithAuthOptions, createMissingEnvVarError, createMsalConfig, createRetryWrapper, createScopedLogger, displayValidationResults, getDebugLogger, getMsalInstance, isValidAccountData, isValidRedirectUri, isValidScope, retryWithBackoff, safeJsonParse, sanitizeError, useGraphApi, useMsalAuth, useMultiAccount, useRoles, useTenant, useTenantConfig, useTokenRefresh, useUserProfile, validateConfig, validateScopes, withAuth, withPageAuth, wrapMsalError };
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,6 @@ __export(client_exports, {
|
|
|
33
33
|
ProtectedPage: () => ProtectedPage,
|
|
34
34
|
SignOutButton: () => SignOutButton,
|
|
35
35
|
UserAvatar: () => UserAvatar,
|
|
36
|
-
createAuthMiddleware: () => createAuthMiddleware,
|
|
37
36
|
createMissingEnvVarError: () => createMissingEnvVarError,
|
|
38
37
|
createMsalConfig: () => createMsalConfig,
|
|
39
38
|
createRetryWrapper: () => createRetryWrapper,
|
|
@@ -47,10 +46,10 @@ __export(client_exports, {
|
|
|
47
46
|
retryWithBackoff: () => retryWithBackoff,
|
|
48
47
|
safeJsonParse: () => safeJsonParse,
|
|
49
48
|
sanitizeError: () => sanitizeError,
|
|
50
|
-
useAccount: () =>
|
|
49
|
+
useAccount: () => import_msal_react5.useAccount,
|
|
51
50
|
useGraphApi: () => useGraphApi,
|
|
52
|
-
useIsAuthenticated: () =>
|
|
53
|
-
useMsal: () =>
|
|
51
|
+
useIsAuthenticated: () => import_msal_react5.useIsAuthenticated,
|
|
52
|
+
useMsal: () => import_msal_react5.useMsal,
|
|
54
53
|
useMsalAuth: () => useMsalAuth,
|
|
55
54
|
useMultiAccount: () => useMultiAccount,
|
|
56
55
|
useRoles: () => useRoles,
|
|
@@ -67,7 +66,7 @@ __export(client_exports, {
|
|
|
67
66
|
module.exports = __toCommonJS(client_exports);
|
|
68
67
|
|
|
69
68
|
// src/components/MsalAuthProvider.tsx
|
|
70
|
-
var
|
|
69
|
+
var import_msal_react3 = require("@azure/msal-react");
|
|
71
70
|
var import_msal_browser3 = require("@azure/msal-browser");
|
|
72
71
|
var import_react3 = require("react");
|
|
73
72
|
|
|
@@ -674,6 +673,7 @@ Note: Environment variables starting with NEXT_PUBLIC_ are exposed to the browse
|
|
|
674
673
|
|
|
675
674
|
// src/hooks/useTokenRefresh.ts
|
|
676
675
|
var import_react2 = require("react");
|
|
676
|
+
var import_msal_react2 = require("@azure/msal-react");
|
|
677
677
|
|
|
678
678
|
// src/hooks/useMsalAuth.ts
|
|
679
679
|
var import_msal_react = require("@azure/msal-react");
|
|
@@ -852,7 +852,8 @@ function useTokenRefresh(options = {}) {
|
|
|
852
852
|
onRefresh,
|
|
853
853
|
onError
|
|
854
854
|
} = options;
|
|
855
|
-
const { isAuthenticated, account
|
|
855
|
+
const { isAuthenticated, account } = useMsalAuth();
|
|
856
|
+
const { instance } = (0, import_msal_react2.useMsal)();
|
|
856
857
|
const intervalRef = (0, import_react2.useRef)(null);
|
|
857
858
|
const lastRefreshRef = (0, import_react2.useRef)(null);
|
|
858
859
|
const expiresInRef = (0, import_react2.useRef)(null);
|
|
@@ -861,23 +862,27 @@ function useTokenRefresh(options = {}) {
|
|
|
861
862
|
return;
|
|
862
863
|
}
|
|
863
864
|
try {
|
|
864
|
-
await acquireTokenSilent(
|
|
865
|
+
const response = await instance.acquireTokenSilent({
|
|
866
|
+
scopes,
|
|
867
|
+
account,
|
|
868
|
+
forceRefresh: false
|
|
869
|
+
});
|
|
865
870
|
lastRefreshRef.current = /* @__PURE__ */ new Date();
|
|
866
|
-
const expiresIn = 3600;
|
|
871
|
+
const expiresIn = response.expiresOn ? Math.max(0, response.expiresOn.getTime() / 1e3 - Date.now() / 1e3) : 3600;
|
|
867
872
|
expiresInRef.current = expiresIn;
|
|
868
873
|
onRefresh?.(expiresIn);
|
|
869
874
|
} catch (error) {
|
|
870
875
|
console.error("[TokenRefresh] Failed to refresh token:", error);
|
|
871
876
|
onError?.(error);
|
|
872
877
|
}
|
|
873
|
-
}, [isAuthenticated, account,
|
|
878
|
+
}, [isAuthenticated, account, instance, scopes, onRefresh, onError]);
|
|
874
879
|
(0, import_react2.useEffect)(() => {
|
|
875
880
|
if (!enabled || !isAuthenticated) {
|
|
876
881
|
return;
|
|
877
882
|
}
|
|
878
883
|
refresh();
|
|
879
884
|
intervalRef.current = setInterval(() => {
|
|
880
|
-
if (
|
|
885
|
+
if (expiresInRef.current === null) {
|
|
881
886
|
return;
|
|
882
887
|
}
|
|
883
888
|
const timeSinceRefresh = lastRefreshRef.current ? (Date.now() - lastRefreshRef.current.getTime()) / 1e3 : 0;
|
|
@@ -1010,6 +1015,23 @@ function validateTenantAccess(account, config) {
|
|
|
1010
1015
|
// src/components/MsalAuthProvider.tsx
|
|
1011
1016
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1012
1017
|
var globalMsalInstance = null;
|
|
1018
|
+
function writeMsalSessionCookie(account) {
|
|
1019
|
+
try {
|
|
1020
|
+
const data = encodeURIComponent(JSON.stringify({
|
|
1021
|
+
homeAccountId: account.homeAccountId,
|
|
1022
|
+
username: account.username,
|
|
1023
|
+
name: account.name ?? ""
|
|
1024
|
+
}));
|
|
1025
|
+
document.cookie = `msal.account=${data}; path=/; SameSite=Lax`;
|
|
1026
|
+
} catch {
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
function clearMsalSessionCookie() {
|
|
1030
|
+
try {
|
|
1031
|
+
document.cookie = "msal.account=; path=/; SameSite=Lax; expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
|
1032
|
+
} catch {
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1013
1035
|
function getMsalInstance() {
|
|
1014
1036
|
return globalMsalInstance;
|
|
1015
1037
|
}
|
|
@@ -1059,6 +1081,7 @@ function MsalAuthProvider({
|
|
|
1059
1081
|
}
|
|
1060
1082
|
if (response.account) {
|
|
1061
1083
|
instance.setActiveAccount(response.account);
|
|
1084
|
+
writeMsalSessionCookie(response.account);
|
|
1062
1085
|
if (config.multiTenant) {
|
|
1063
1086
|
const validation = validateTenantAccess(response.account, config.multiTenant);
|
|
1064
1087
|
if (!validation.allowed) {
|
|
@@ -1104,6 +1127,7 @@ function MsalAuthProvider({
|
|
|
1104
1127
|
const accounts = instance.getAllAccounts();
|
|
1105
1128
|
if (accounts.length > 0 && !instance.getActiveAccount()) {
|
|
1106
1129
|
instance.setActiveAccount(accounts[0]);
|
|
1130
|
+
writeMsalSessionCookie(accounts[0]);
|
|
1107
1131
|
}
|
|
1108
1132
|
const loggingEnabled = config.enableLogging || false;
|
|
1109
1133
|
instance.addEventCallback((event) => {
|
|
@@ -1112,6 +1136,7 @@ function MsalAuthProvider({
|
|
|
1112
1136
|
const account = "account" in payload ? payload.account : payload;
|
|
1113
1137
|
if (account) {
|
|
1114
1138
|
instance.setActiveAccount(account);
|
|
1139
|
+
writeMsalSessionCookie(account);
|
|
1115
1140
|
}
|
|
1116
1141
|
if (loggingEnabled) {
|
|
1117
1142
|
console.log("[MSAL] Login successful:", account?.username);
|
|
@@ -1123,10 +1148,14 @@ function MsalAuthProvider({
|
|
|
1123
1148
|
}
|
|
1124
1149
|
if (event.eventType === import_msal_browser3.EventType.LOGOUT_SUCCESS) {
|
|
1125
1150
|
instance.setActiveAccount(null);
|
|
1151
|
+
clearMsalSessionCookie();
|
|
1126
1152
|
if (loggingEnabled) {
|
|
1127
1153
|
console.log("[MSAL] Logout successful");
|
|
1128
1154
|
}
|
|
1129
1155
|
}
|
|
1156
|
+
if (import_msal_browser3.EventType.LOGOUT_END !== void 0 && event.eventType === import_msal_browser3.EventType.LOGOUT_END) {
|
|
1157
|
+
clearMsalSessionCookie();
|
|
1158
|
+
}
|
|
1130
1159
|
if (event.eventType === import_msal_browser3.EventType.ACQUIRE_TOKEN_SUCCESS) {
|
|
1131
1160
|
const payload = event.payload;
|
|
1132
1161
|
if (payload?.account && !instance.getActiveAccount()) {
|
|
@@ -1158,7 +1187,7 @@ function MsalAuthProvider({
|
|
|
1158
1187
|
if (!msalInstance) {
|
|
1159
1188
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
|
|
1160
1189
|
}
|
|
1161
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_msal_react3.MsalProvider, { instance: msalInstance, children: [
|
|
1162
1191
|
autoRefreshToken && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1163
1192
|
TokenRefreshManager,
|
|
1164
1193
|
{
|
|
@@ -1928,11 +1957,11 @@ var ErrorBoundary = class extends import_react10.Component {
|
|
|
1928
1957
|
};
|
|
1929
1958
|
|
|
1930
1959
|
// src/hooks/useMultiAccount.ts
|
|
1931
|
-
var
|
|
1960
|
+
var import_msal_react4 = require("@azure/msal-react");
|
|
1932
1961
|
var import_msal_browser4 = require("@azure/msal-browser");
|
|
1933
1962
|
var import_react11 = require("react");
|
|
1934
1963
|
function useMultiAccount(defaultScopes = ["User.Read"]) {
|
|
1935
|
-
const { instance, accounts, inProgress } = (0,
|
|
1964
|
+
const { instance, accounts, inProgress } = (0, import_msal_react4.useMsal)();
|
|
1936
1965
|
const [activeAccount, setActiveAccount] = (0, import_react11.useState)(
|
|
1937
1966
|
instance.getActiveAccount()
|
|
1938
1967
|
);
|
|
@@ -3166,107 +3195,8 @@ function withPageAuth(Component2, authConfig, globalConfig) {
|
|
|
3166
3195
|
return WrappedComponent;
|
|
3167
3196
|
}
|
|
3168
3197
|
|
|
3169
|
-
// src/middleware/createAuthMiddleware.ts
|
|
3170
|
-
var import_server = require("next/server");
|
|
3171
|
-
function createAuthMiddleware(config = {}) {
|
|
3172
|
-
const {
|
|
3173
|
-
protectedRoutes = [],
|
|
3174
|
-
publicOnlyRoutes = [],
|
|
3175
|
-
loginPath = "/login",
|
|
3176
|
-
redirectAfterLogin = "/",
|
|
3177
|
-
sessionCookie = "msal.account",
|
|
3178
|
-
isAuthenticated: customAuthCheck,
|
|
3179
|
-
tenantConfig,
|
|
3180
|
-
tenantDeniedPath = "/unauthorized",
|
|
3181
|
-
debug = false
|
|
3182
|
-
} = config;
|
|
3183
|
-
return async function authMiddleware(request) {
|
|
3184
|
-
const { pathname } = request.nextUrl;
|
|
3185
|
-
if (debug) {
|
|
3186
|
-
console.log("[AuthMiddleware] Processing:", pathname);
|
|
3187
|
-
}
|
|
3188
|
-
let authenticated = false;
|
|
3189
|
-
if (customAuthCheck) {
|
|
3190
|
-
authenticated = await customAuthCheck(request);
|
|
3191
|
-
} else {
|
|
3192
|
-
const sessionData = request.cookies.get(sessionCookie);
|
|
3193
|
-
authenticated = !!sessionData?.value;
|
|
3194
|
-
}
|
|
3195
|
-
if (debug) {
|
|
3196
|
-
console.log("[AuthMiddleware] Authenticated:", authenticated);
|
|
3197
|
-
}
|
|
3198
|
-
const isProtectedRoute = protectedRoutes.some(
|
|
3199
|
-
(route) => pathname.startsWith(route)
|
|
3200
|
-
);
|
|
3201
|
-
const isPublicOnlyRoute = publicOnlyRoutes.some(
|
|
3202
|
-
(route) => pathname.startsWith(route)
|
|
3203
|
-
);
|
|
3204
|
-
if (isProtectedRoute && !authenticated) {
|
|
3205
|
-
if (debug) {
|
|
3206
|
-
console.log("[AuthMiddleware] Redirecting to login");
|
|
3207
|
-
}
|
|
3208
|
-
const url = request.nextUrl.clone();
|
|
3209
|
-
url.pathname = loginPath;
|
|
3210
|
-
url.searchParams.set("returnUrl", pathname);
|
|
3211
|
-
return import_server.NextResponse.redirect(url);
|
|
3212
|
-
}
|
|
3213
|
-
if (isProtectedRoute && authenticated && tenantConfig) {
|
|
3214
|
-
try {
|
|
3215
|
-
const sessionData = request.cookies.get(sessionCookie);
|
|
3216
|
-
if (sessionData?.value) {
|
|
3217
|
-
const account = safeJsonParse(sessionData.value, isValidAccountData);
|
|
3218
|
-
if (account) {
|
|
3219
|
-
const tenantResult = validateTenantAccess(account, tenantConfig);
|
|
3220
|
-
if (!tenantResult.allowed) {
|
|
3221
|
-
if (debug) {
|
|
3222
|
-
console.log("[AuthMiddleware] Tenant access denied:", tenantResult.reason);
|
|
3223
|
-
}
|
|
3224
|
-
const url = request.nextUrl.clone();
|
|
3225
|
-
url.pathname = tenantDeniedPath;
|
|
3226
|
-
url.searchParams.set("reason", tenantResult.reason || "access_denied");
|
|
3227
|
-
return import_server.NextResponse.redirect(url);
|
|
3228
|
-
}
|
|
3229
|
-
}
|
|
3230
|
-
}
|
|
3231
|
-
} catch (error) {
|
|
3232
|
-
if (debug) {
|
|
3233
|
-
console.warn("[AuthMiddleware] Tenant validation error:", error);
|
|
3234
|
-
}
|
|
3235
|
-
}
|
|
3236
|
-
}
|
|
3237
|
-
if (isPublicOnlyRoute && authenticated) {
|
|
3238
|
-
if (debug) {
|
|
3239
|
-
console.log("[AuthMiddleware] Redirecting to home");
|
|
3240
|
-
}
|
|
3241
|
-
const returnUrl = request.nextUrl.searchParams.get("returnUrl");
|
|
3242
|
-
const url = request.nextUrl.clone();
|
|
3243
|
-
url.pathname = returnUrl || redirectAfterLogin;
|
|
3244
|
-
url.searchParams.delete("returnUrl");
|
|
3245
|
-
return import_server.NextResponse.redirect(url);
|
|
3246
|
-
}
|
|
3247
|
-
const response = import_server.NextResponse.next();
|
|
3248
|
-
if (authenticated) {
|
|
3249
|
-
response.headers.set("x-msal-authenticated", "true");
|
|
3250
|
-
try {
|
|
3251
|
-
const sessionData = request.cookies.get(sessionCookie);
|
|
3252
|
-
if (sessionData?.value) {
|
|
3253
|
-
const account = safeJsonParse(sessionData.value, isValidAccountData);
|
|
3254
|
-
if (account?.username) {
|
|
3255
|
-
response.headers.set("x-msal-username", account.username);
|
|
3256
|
-
}
|
|
3257
|
-
}
|
|
3258
|
-
} catch (error) {
|
|
3259
|
-
if (debug) {
|
|
3260
|
-
console.warn("[AuthMiddleware] Failed to parse session data");
|
|
3261
|
-
}
|
|
3262
|
-
}
|
|
3263
|
-
}
|
|
3264
|
-
return response;
|
|
3265
|
-
};
|
|
3266
|
-
}
|
|
3267
|
-
|
|
3268
3198
|
// src/client.ts
|
|
3269
|
-
var
|
|
3199
|
+
var import_msal_react5 = require("@azure/msal-react");
|
|
3270
3200
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3271
3201
|
0 && (module.exports = {
|
|
3272
3202
|
AccountList,
|
|
@@ -3281,7 +3211,6 @@ var import_msal_react4 = require("@azure/msal-react");
|
|
|
3281
3211
|
ProtectedPage,
|
|
3282
3212
|
SignOutButton,
|
|
3283
3213
|
UserAvatar,
|
|
3284
|
-
createAuthMiddleware,
|
|
3285
3214
|
createMissingEnvVarError,
|
|
3286
3215
|
createMsalConfig,
|
|
3287
3216
|
createRetryWrapper,
|