@chemmangat/msal-next 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,8 @@ Fully configurable MSAL (Microsoft Authentication Library) package for Next.js A
8
8
  npm install @chemmangat/msal-next @azure/msal-browser @azure/msal-react
9
9
  ```
10
10
 
11
+ > Supports both v3 and v4 of `@azure/msal-browser` and v2/v3 of `@azure/msal-react`
12
+
11
13
  ```tsx
12
14
  // app/layout.tsx
13
15
  import { MsalAuthProvider } from '@chemmangat/msal-next';
@@ -54,6 +56,7 @@ Visit [https://msal-next.chemmangat.dev](https://msal-next.chemmangat.dev) for f
54
56
  - ✅ Automatic token acquisition with silent refresh
55
57
  - ✅ Zero configuration for simple use cases
56
58
  - ✅ Highly configurable when needed
59
+ - ✅ SSR/SSG safe - works seamlessly with server-rendered pages
57
60
 
58
61
  ## 📖 API
59
62
 
@@ -68,11 +71,28 @@ Visit [https://msal-next.chemmangat.dev](https://msal-next.chemmangat.dev) for f
68
71
  cacheLocation="sessionStorage"
69
72
  enableLogging={false}
70
73
  loadingComponent={<div>Loading...</div>}
74
+ onInitialized={(instance) => {
75
+ // Optional: Access MSAL instance after initialization
76
+ console.log('MSAL initialized');
77
+ }}
71
78
  >
72
79
  {children}
73
80
  </MsalAuthProvider>
74
81
  ```
75
82
 
83
+ #### Props
84
+
85
+ | Prop | Type | Default | Description |
86
+ |------|------|---------|-------------|
87
+ | `clientId` | `string` | required | Azure AD Application (client) ID |
88
+ | `tenantId` | `string` | optional | Azure AD Directory (tenant) ID |
89
+ | `authorityType` | `'common' \| 'organizations' \| 'consumers' \| 'tenant'` | `'common'` | Authority type |
90
+ | `scopes` | `string[]` | `['User.Read']` | Default scopes |
91
+ | `cacheLocation` | `'sessionStorage' \| 'localStorage' \| 'memoryStorage'` | `'sessionStorage'` | Cache location |
92
+ | `enableLogging` | `boolean` | `false` | Enable debug logging |
93
+ | `loadingComponent` | `ReactNode` | Loading message | Custom loading component |
94
+ | `onInitialized` | `(instance: IPublicClientApplication) => void` | optional | Callback after initialization |
95
+
76
96
  ### MicrosoftSignInButton
77
97
 
78
98
  Pre-built button component with official Microsoft branding:
@@ -105,15 +125,165 @@ const {
105
125
  acquireTokenSilent,
106
126
  acquireTokenPopup,
107
127
  acquireTokenRedirect,
128
+ clearSession,
108
129
  } = useMsalAuth();
109
130
  ```
110
131
 
111
- ## 🔗 Links
132
+ #### Return Values
133
+
134
+ | Property | Type | Description |
135
+ |----------|------|-------------|
136
+ | `isAuthenticated` | `boolean` | Whether user is authenticated |
137
+ | `account` | `AccountInfo \| null` | Current authenticated account |
138
+ | `accounts` | `AccountInfo[]` | All accounts in cache |
139
+ | `inProgress` | `boolean` | Whether MSAL is performing an interaction |
140
+ | `loginPopup` | `(scopes?: string[]) => Promise<void>` | Login using popup |
141
+ | `loginRedirect` | `(scopes?: string[]) => Promise<void>` | Login using redirect |
142
+ | `logoutPopup` | `() => Promise<void>` | Logout using popup |
143
+ | `logoutRedirect` | `() => Promise<void>` | Logout using redirect |
144
+ | `acquireToken` | `(scopes: string[]) => Promise<string>` | Acquire token silently with popup fallback |
145
+ | `acquireTokenSilent` | `(scopes: string[]) => Promise<string>` | Acquire token silently only |
146
+ | `acquireTokenPopup` | `(scopes: string[]) => Promise<string>` | Acquire token using popup |
147
+ | `acquireTokenRedirect` | `(scopes: string[]) => Promise<void>` | Acquire token using redirect |
148
+ | `clearSession` | `() => Promise<void>` | Clear MSAL cache without Microsoft logout |
149
+
150
+ ### getMsalInstance()
151
+
152
+ Access the MSAL instance outside of React components:
153
+
154
+ ```tsx
155
+ import { getMsalInstance } from '@chemmangat/msal-next';
156
+
157
+ // In API clients, middleware, etc.
158
+ const instance = getMsalInstance();
159
+ if (instance) {
160
+ const accounts = instance.getAllAccounts();
161
+ }
162
+ ```
163
+
164
+ ## 🔧 Advanced Usage
165
+
166
+ ### Using onInitialized for Axios Interceptors
167
+
168
+ Access the MSAL instance to set up API interceptors:
169
+
170
+ ```tsx
171
+ // app/layout.tsx
172
+ 'use client';
173
+ import { MsalAuthProvider } from '@chemmangat/msal-next';
174
+ import { setupAxiosInterceptors } from '@/lib/axios';
175
+
176
+ export default function RootLayout({ children }) {
177
+ return (
178
+ <MsalAuthProvider
179
+ clientId={process.env.NEXT_PUBLIC_CLIENT_ID!}
180
+ onInitialized={(instance) => {
181
+ // Set up Axios interceptors with MSAL instance
182
+ setupAxiosInterceptors(instance);
183
+ }}
184
+ >
185
+ {children}
186
+ </MsalAuthProvider>
187
+ );
188
+ }
189
+ ```
190
+
191
+ ```tsx
192
+ // lib/axios.ts
193
+ import axios from 'axios';
194
+ import { IPublicClientApplication } from '@azure/msal-browser';
195
+
196
+ export function setupAxiosInterceptors(msalInstance: IPublicClientApplication) {
197
+ axios.interceptors.request.use(async (config) => {
198
+ const accounts = msalInstance.getAllAccounts();
199
+ if (accounts.length > 0) {
200
+ try {
201
+ const response = await msalInstance.acquireTokenSilent({
202
+ scopes: ['User.Read'],
203
+ account: accounts[0],
204
+ });
205
+ config.headers.Authorization = `Bearer ${response.accessToken}`;
206
+ } catch (error) {
207
+ console.error('Token acquisition failed:', error);
208
+ }
209
+ }
210
+ return config;
211
+ });
212
+ }
213
+ ```
214
+
215
+ ### Using getMsalInstance() in API Clients
216
+
217
+ For non-React code like API clients or middleware:
218
+
219
+ ```tsx
220
+ // lib/api-client.ts
221
+ import { getMsalInstance } from '@chemmangat/msal-next';
222
+
223
+ export async function fetchUserData() {
224
+ const instance = getMsalInstance();
225
+ if (!instance) {
226
+ throw new Error('MSAL not initialized');
227
+ }
228
+
229
+ const accounts = instance.getAllAccounts();
230
+ if (accounts.length === 0) {
231
+ throw new Error('No authenticated user');
232
+ }
233
+
234
+ const response = await instance.acquireTokenSilent({
235
+ scopes: ['User.Read'],
236
+ account: accounts[0],
237
+ });
238
+
239
+ return fetch('/api/user', {
240
+ headers: {
241
+ Authorization: `Bearer ${response.accessToken}`,
242
+ },
243
+ });
244
+ }
245
+ ```
246
+
247
+ ### Silent Logout with clearSession()
248
+
249
+ Clear MSAL cache without redirecting to Microsoft logout:
250
+
251
+ ```tsx
252
+ 'use client';
253
+ import { useMsalAuth } from '@chemmangat/msal-next';
254
+
255
+ export function LogoutButton() {
256
+ const { clearSession } = useMsalAuth();
257
+
258
+ const handleLogout = async () => {
259
+ // Call your backend logout API
260
+ await fetch('/api/logout', { method: 'POST' });
261
+
262
+ // Clear local MSAL cache without Microsoft redirect
263
+ await clearSession();
264
+
265
+ // Redirect to home
266
+ window.location.href = '/';
267
+ };
268
+
269
+ return <button onClick={handleLogout}>Logout</button>;
270
+ }
271
+ ```
272
+
273
+ ### SSR/SSG Notes
274
+
275
+ This package is safe to use in server-rendered pages. The `MsalAuthProvider` automatically detects server-side rendering and skips MSAL initialization on the server, rendering the loading component instead. MSAL will initialize normally on the client side.
112
276
 
113
- - [Documentation](https://msal-next.chemmangat.dev)
114
- - [GitHub](https://github.com/chemmangat/msal-next)
115
- - [npm](https://www.npmjs.com/package/@chemmangat/msal-next)
116
- - [Examples](https://github.com/chemmangat/msal-next/tree/main/example)
277
+ ```tsx
278
+ // This works in both SSR and SSG pages
279
+ export default function Page() {
280
+ return (
281
+ <MsalAuthProvider clientId="...">
282
+ <YourApp />
283
+ </MsalAuthProvider>
284
+ );
285
+ }
286
+ ```
117
287
 
118
288
  ## 📄 License
119
289
 
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Configuration, LogLevel, AccountInfo } from '@azure/msal-browser';
2
+ import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
3
3
  import { ReactNode, CSSProperties } from 'react';
4
4
  export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
5
5
 
@@ -64,12 +64,21 @@ interface MsalAuthConfig {
64
64
  * Loading component to show while MSAL initializes
65
65
  */
66
66
  loadingComponent?: ReactNode;
67
+ /**
68
+ * Callback invoked after MSAL initialization completes successfully
69
+ */
70
+ onInitialized?: (instance: IPublicClientApplication) => void;
67
71
  }
68
72
  interface MsalAuthProviderProps extends MsalAuthConfig {
69
73
  children: ReactNode;
70
74
  }
71
75
 
72
- declare function MsalAuthProvider({ children, loadingComponent, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
76
+ /**
77
+ * Get the current MSAL instance
78
+ * @returns The MSAL instance or null if not initialized
79
+ */
80
+ declare function getMsalInstance(): PublicClientApplication | null;
81
+ declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
73
82
 
74
83
  interface MicrosoftSignInButtonProps {
75
84
  /**
@@ -164,7 +173,11 @@ interface UseMsalAuthReturn {
164
173
  * Acquire access token using redirect
165
174
  */
166
175
  acquireTokenRedirect: (scopes: string[]) => Promise<void>;
176
+ /**
177
+ * Clear MSAL session without triggering Microsoft logout
178
+ */
179
+ clearSession: () => Promise<void>;
167
180
  }
168
181
  declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
169
182
 
170
- export { MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, useMsalAuth };
183
+ export { MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type UseMsalAuthReturn, getMsalInstance, useMsalAuth };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Configuration, LogLevel, AccountInfo } from '@azure/msal-browser';
2
+ import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
3
3
  import { ReactNode, CSSProperties } from 'react';
4
4
  export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
5
5
 
@@ -64,12 +64,21 @@ interface MsalAuthConfig {
64
64
  * Loading component to show while MSAL initializes
65
65
  */
66
66
  loadingComponent?: ReactNode;
67
+ /**
68
+ * Callback invoked after MSAL initialization completes successfully
69
+ */
70
+ onInitialized?: (instance: IPublicClientApplication) => void;
67
71
  }
68
72
  interface MsalAuthProviderProps extends MsalAuthConfig {
69
73
  children: ReactNode;
70
74
  }
71
75
 
72
- declare function MsalAuthProvider({ children, loadingComponent, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
76
+ /**
77
+ * Get the current MSAL instance
78
+ * @returns The MSAL instance or null if not initialized
79
+ */
80
+ declare function getMsalInstance(): PublicClientApplication | null;
81
+ declare function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
73
82
 
74
83
  interface MicrosoftSignInButtonProps {
75
84
  /**
@@ -164,7 +173,11 @@ interface UseMsalAuthReturn {
164
173
  * Acquire access token using redirect
165
174
  */
166
175
  acquireTokenRedirect: (scopes: string[]) => Promise<void>;
176
+ /**
177
+ * Clear MSAL session without triggering Microsoft logout
178
+ */
179
+ clearSession: () => Promise<void>;
167
180
  }
168
181
  declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
169
182
 
170
- export { MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, useMsalAuth };
183
+ export { MicrosoftSignInButton, type MicrosoftSignInButtonProps, type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, type UseMsalAuthReturn, getMsalInstance, useMsalAuth };
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ var index_exports = {};
23
23
  __export(index_exports, {
24
24
  MicrosoftSignInButton: () => MicrosoftSignInButton,
25
25
  MsalAuthProvider: () => MsalAuthProvider,
26
+ getMsalInstance: () => getMsalInstance,
26
27
  useAccount: () => import_msal_react3.useAccount,
27
28
  useIsAuthenticated: () => import_msal_react3.useIsAuthenticated,
28
29
  useMsal: () => import_msal_react3.useMsal,
@@ -107,10 +108,17 @@ function createMsalConfig(config) {
107
108
 
108
109
  // src/components/MsalAuthProvider.tsx
109
110
  var import_jsx_runtime = require("react/jsx-runtime");
110
- function MsalAuthProvider({ children, loadingComponent, ...config }) {
111
+ var globalMsalInstance = null;
112
+ function getMsalInstance() {
113
+ return globalMsalInstance;
114
+ }
115
+ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }) {
111
116
  const [msalInstance, setMsalInstance] = (0, import_react.useState)(null);
112
117
  const instanceRef = (0, import_react.useRef)(null);
113
118
  (0, import_react.useEffect)(() => {
119
+ if (typeof window === "undefined") {
120
+ return;
121
+ }
114
122
  if (instanceRef.current) {
115
123
  return;
116
124
  }
@@ -120,23 +128,32 @@ function MsalAuthProvider({ children, loadingComponent, ...config }) {
120
128
  const instance = new import_msal_browser2.PublicClientApplication(msalConfig);
121
129
  await instance.initialize();
122
130
  const response = await instance.handleRedirectPromise();
123
- if (response) {
131
+ if (response && config.enableLogging) {
124
132
  console.log("[MSAL] Redirect authentication successful");
125
133
  }
134
+ const enableLogging = config.enableLogging || false;
126
135
  instance.addEventCallback((event) => {
127
136
  if (event.eventType === import_msal_browser2.EventType.LOGIN_SUCCESS) {
128
- const payload = event.payload;
129
- console.log("[MSAL] Login successful:", payload.account?.username);
137
+ if (enableLogging) {
138
+ const payload = event.payload;
139
+ console.log("[MSAL] Login successful:", payload.account?.username);
140
+ }
130
141
  }
131
142
  if (event.eventType === import_msal_browser2.EventType.LOGIN_FAILURE) {
132
143
  console.error("[MSAL] Login failed:", event.error);
133
144
  }
134
145
  if (event.eventType === import_msal_browser2.EventType.LOGOUT_SUCCESS) {
135
- console.log("[MSAL] Logout successful");
146
+ if (enableLogging) {
147
+ console.log("[MSAL] Logout successful");
148
+ }
136
149
  }
137
150
  });
138
151
  instanceRef.current = instance;
152
+ globalMsalInstance = instance;
139
153
  setMsalInstance(instance);
154
+ if (onInitialized) {
155
+ onInitialized(instance);
156
+ }
140
157
  } catch (error) {
141
158
  console.error("[MSAL] Initialization failed:", error);
142
159
  throw error;
@@ -144,6 +161,9 @@ function MsalAuthProvider({ children, loadingComponent, ...config }) {
144
161
  };
145
162
  initializeMsal();
146
163
  }, []);
164
+ if (typeof window === "undefined") {
165
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
166
+ }
147
167
  if (!msalInstance) {
148
168
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
149
169
  }
@@ -275,6 +295,10 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
275
295
  },
276
296
  [acquireTokenSilent, acquireTokenPopup, defaultScopes]
277
297
  );
298
+ const clearSession = (0, import_react2.useCallback)(async () => {
299
+ instance.setActiveAccount(null);
300
+ await instance.clearCache();
301
+ }, [instance]);
278
302
  return {
279
303
  account,
280
304
  accounts,
@@ -287,7 +311,8 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
287
311
  acquireToken,
288
312
  acquireTokenSilent,
289
313
  acquireTokenPopup,
290
- acquireTokenRedirect
314
+ acquireTokenRedirect,
315
+ clearSession
291
316
  };
292
317
  }
293
318
 
@@ -391,6 +416,7 @@ var import_msal_react3 = require("@azure/msal-react");
391
416
  0 && (module.exports = {
392
417
  MicrosoftSignInButton,
393
418
  MsalAuthProvider,
419
+ getMsalInstance,
394
420
  useAccount,
395
421
  useIsAuthenticated,
396
422
  useMsal,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/MsalAuthProvider.tsx","../src/utils/createMsalConfig.ts","../src/hooks/useMsalAuth.ts","../src/components/MicrosoftSignInButton.tsx"],"sourcesContent":["export { MsalAuthProvider } from './components/MsalAuthProvider';\r\nexport { MicrosoftSignInButton } from './components/MicrosoftSignInButton';\r\nexport { useMsalAuth } from './hooks/useMsalAuth';\r\nexport type { MsalAuthConfig, MsalAuthProviderProps } from './types';\r\nexport type { MicrosoftSignInButtonProps } from './components/MicrosoftSignInButton';\r\n\r\n// Re-export useful MSAL hooks\r\nexport { useMsal, useIsAuthenticated, useAccount } from '@azure/msal-react';\r\n","'use client';\r\n\r\nimport { MsalProvider } from '@azure/msal-react';\r\nimport { PublicClientApplication, EventType, EventMessage, AuthenticationResult } from '@azure/msal-browser';\r\nimport { useEffect, useState, useRef } from 'react';\r\nimport { MsalAuthProviderProps } from '../types';\r\nimport { createMsalConfig } from '../utils/createMsalConfig';\r\n\r\nexport function MsalAuthProvider({ children, loadingComponent, ...config }: MsalAuthProviderProps) {\r\n const [msalInstance, setMsalInstance] = useState<PublicClientApplication | null>(null);\r\n const instanceRef = useRef<PublicClientApplication | null>(null);\r\n\r\n useEffect(() => {\r\n // Prevent multiple initializations\r\n if (instanceRef.current) {\r\n return;\r\n }\r\n\r\n const initializeMsal = async () => {\r\n try {\r\n const msalConfig = createMsalConfig(config);\r\n const instance = new PublicClientApplication(msalConfig);\r\n \r\n await instance.initialize();\r\n\r\n // Handle redirect promise\r\n const response = await instance.handleRedirectPromise();\r\n if (response) {\r\n console.log('[MSAL] Redirect authentication successful');\r\n }\r\n\r\n // Optional: Set up event callbacks\r\n instance.addEventCallback((event: EventMessage) => {\r\n if (event.eventType === EventType.LOGIN_SUCCESS) {\r\n const payload = event.payload as AuthenticationResult;\r\n console.log('[MSAL] Login successful:', payload.account?.username);\r\n }\r\n \r\n if (event.eventType === EventType.LOGIN_FAILURE) {\r\n console.error('[MSAL] Login failed:', event.error);\r\n }\r\n\r\n if (event.eventType === EventType.LOGOUT_SUCCESS) {\r\n console.log('[MSAL] Logout successful');\r\n }\r\n });\r\n\r\n instanceRef.current = instance;\r\n setMsalInstance(instance);\r\n } catch (error) {\r\n console.error('[MSAL] Initialization failed:', error);\r\n throw error;\r\n }\r\n };\r\n\r\n initializeMsal();\r\n }, []); // Empty dependency array - only initialize once\r\n\r\n if (!msalInstance) {\r\n return <>{loadingComponent || <div>Loading authentication...</div>}</>;\r\n }\r\n\r\n return <MsalProvider instance={msalInstance}>{children}</MsalProvider>;\r\n}\r\n","import { Configuration, LogLevel } from '@azure/msal-browser';\r\nimport { MsalAuthConfig } from '../types';\r\n\r\nexport function createMsalConfig(config: MsalAuthConfig): Configuration {\r\n // If custom config provided, use it\r\n if (config.msalConfig) {\r\n return config.msalConfig;\r\n }\r\n\r\n const {\r\n clientId,\r\n tenantId,\r\n authorityType = 'common',\r\n redirectUri,\r\n postLogoutRedirectUri,\r\n cacheLocation = 'sessionStorage',\r\n storeAuthStateInCookie = false,\r\n navigateToLoginRequestUrl = true,\r\n enableLogging = false,\r\n loggerCallback,\r\n } = config;\r\n\r\n if (!clientId) {\r\n throw new Error('@chemmangat/msal-next: clientId is required');\r\n }\r\n\r\n // Build authority URL\r\n const getAuthority = (): string => {\r\n if (authorityType === 'tenant') {\r\n if (!tenantId) {\r\n throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is \"tenant\"');\r\n }\r\n return `https://login.microsoftonline.com/${tenantId}`;\r\n }\r\n return `https://login.microsoftonline.com/${authorityType}`;\r\n };\r\n\r\n // Default redirect URI\r\n const defaultRedirectUri = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000';\r\n const finalRedirectUri = redirectUri || defaultRedirectUri;\r\n\r\n const msalConfig: Configuration = {\r\n auth: {\r\n clientId,\r\n authority: getAuthority(),\r\n redirectUri: finalRedirectUri,\r\n postLogoutRedirectUri: postLogoutRedirectUri || finalRedirectUri,\r\n navigateToLoginRequestUrl,\r\n },\r\n cache: {\r\n cacheLocation,\r\n storeAuthStateInCookie,\r\n },\r\n system: {\r\n loggerOptions: {\r\n loggerCallback: loggerCallback || ((level: LogLevel, message: string, containsPii: boolean) => {\r\n if (containsPii || !enableLogging) return;\r\n \r\n switch (level) {\r\n case LogLevel.Error:\r\n console.error('[MSAL]', message);\r\n break;\r\n case LogLevel.Warning:\r\n console.warn('[MSAL]', message);\r\n break;\r\n case LogLevel.Info:\r\n console.info('[MSAL]', message);\r\n break;\r\n case LogLevel.Verbose:\r\n console.debug('[MSAL]', message);\r\n break;\r\n }\r\n }),\r\n logLevel: enableLogging ? LogLevel.Verbose : LogLevel.Error,\r\n },\r\n },\r\n };\r\n\r\n return msalConfig;\r\n}\r\n","'use client';\r\n\r\nimport { useMsal, useAccount } from '@azure/msal-react';\r\nimport { AccountInfo, InteractionStatus, PopupRequest, RedirectRequest, SilentRequest } from '@azure/msal-browser';\r\nimport { useCallback, useMemo } from 'react';\r\n\r\nexport interface UseMsalAuthReturn {\r\n /**\r\n * Current authenticated account\r\n */\r\n account: AccountInfo | null;\r\n\r\n /**\r\n * All accounts in the cache\r\n */\r\n accounts: AccountInfo[];\r\n\r\n /**\r\n * Whether user is authenticated\r\n */\r\n isAuthenticated: boolean;\r\n\r\n /**\r\n * Whether MSAL is currently performing an interaction\r\n */\r\n inProgress: boolean;\r\n\r\n /**\r\n * Login using popup\r\n */\r\n loginPopup: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Login using redirect\r\n */\r\n loginRedirect: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Logout using popup\r\n */\r\n logoutPopup: () => Promise<void>;\r\n\r\n /**\r\n * Logout using redirect\r\n */\r\n logoutRedirect: () => Promise<void>;\r\n\r\n /**\r\n * Acquire access token silently (with fallback to popup)\r\n */\r\n acquireToken: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token silently only (no fallback)\r\n */\r\n acquireTokenSilent: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using popup\r\n */\r\n acquireTokenPopup: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using redirect\r\n */\r\n acquireTokenRedirect: (scopes: string[]) => Promise<void>;\r\n}\r\n\r\nexport function useMsalAuth(defaultScopes: string[] = ['User.Read']): UseMsalAuthReturn {\r\n const { instance, accounts, inProgress } = useMsal();\r\n const account = useAccount(accounts[0] || null);\r\n\r\n const isAuthenticated = useMemo(() => accounts.length > 0, [accounts]);\r\n\r\n const loginPopup = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginPopup(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login popup failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const loginRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login redirect failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const logoutPopup = useCallback(async () => {\r\n try {\r\n await instance.logoutPopup({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout popup failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const logoutRedirect = useCallback(async () => {\r\n try {\r\n await instance.logoutRedirect({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout redirect failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const acquireTokenSilent = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: SilentRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenSilent(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Silent token acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenPopup = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenPopup(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Token popup acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<void> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n account,\r\n };\r\n await instance.acquireTokenRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Token redirect acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireToken = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n try {\r\n return await acquireTokenSilent(scopes);\r\n } catch (error) {\r\n console.warn('[MSAL] Silent token acquisition failed, falling back to popup');\r\n return await acquireTokenPopup(scopes);\r\n }\r\n },\r\n [acquireTokenSilent, acquireTokenPopup, defaultScopes]\r\n );\r\n\r\n return {\r\n account,\r\n accounts,\r\n isAuthenticated,\r\n inProgress: inProgress !== InteractionStatus.None,\r\n loginPopup,\r\n loginRedirect,\r\n logoutPopup,\r\n logoutRedirect,\r\n acquireToken,\r\n acquireTokenSilent,\r\n acquireTokenPopup,\r\n acquireTokenRedirect,\r\n };\r\n}\r\n","'use client';\r\n\r\nimport { useMsalAuth } from '../hooks/useMsalAuth';\r\nimport { CSSProperties } from 'react';\r\n\r\nexport interface MicrosoftSignInButtonProps {\r\n /**\r\n * Button text\r\n * @default 'Sign in with Microsoft'\r\n */\r\n text?: string;\r\n \r\n /**\r\n * Button variant\r\n * @default 'dark'\r\n */\r\n variant?: 'dark' | 'light';\r\n \r\n /**\r\n * Button size\r\n * @default 'medium'\r\n */\r\n size?: 'small' | 'medium' | 'large';\r\n \r\n /**\r\n * Use redirect flow instead of popup\r\n * @default false\r\n */\r\n useRedirect?: boolean;\r\n \r\n /**\r\n * Scopes to request\r\n */\r\n scopes?: string[];\r\n \r\n /**\r\n * Custom className\r\n */\r\n className?: string;\r\n \r\n /**\r\n * Custom styles\r\n */\r\n style?: CSSProperties;\r\n \r\n /**\r\n * Callback on successful login\r\n */\r\n onSuccess?: () => void;\r\n \r\n /**\r\n * Callback on error\r\n */\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport function MicrosoftSignInButton({\r\n text = 'Sign in with Microsoft',\r\n variant = 'dark',\r\n size = 'medium',\r\n useRedirect = false,\r\n scopes,\r\n className = '',\r\n style,\r\n onSuccess,\r\n onError,\r\n}: MicrosoftSignInButtonProps) {\r\n const { loginPopup, loginRedirect, inProgress } = useMsalAuth();\r\n\r\n const handleClick = async () => {\r\n try {\r\n if (useRedirect) {\r\n await loginRedirect(scopes);\r\n } else {\r\n await loginPopup(scopes);\r\n }\r\n onSuccess?.();\r\n } catch (error) {\r\n onError?.(error as Error);\r\n }\r\n };\r\n\r\n const sizeStyles = {\r\n small: {\r\n padding: '8px 16px',\r\n fontSize: '14px',\r\n height: '36px',\r\n },\r\n medium: {\r\n padding: '10px 20px',\r\n fontSize: '15px',\r\n height: '41px',\r\n },\r\n large: {\r\n padding: '12px 24px',\r\n fontSize: '16px',\r\n height: '48px',\r\n },\r\n };\r\n\r\n const variantStyles = {\r\n dark: {\r\n backgroundColor: '#2F2F2F',\r\n color: '#FFFFFF',\r\n border: '1px solid #8C8C8C',\r\n },\r\n light: {\r\n backgroundColor: '#FFFFFF',\r\n color: '#5E5E5E',\r\n border: '1px solid #8C8C8C',\r\n },\r\n };\r\n\r\n const baseStyles: CSSProperties = {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '12px',\r\n fontFamily: '\"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif',\r\n fontWeight: 600,\r\n borderRadius: '2px',\r\n cursor: inProgress ? 'not-allowed' : 'pointer',\r\n transition: 'all 0.2s ease',\r\n opacity: inProgress ? 0.6 : 1,\r\n ...variantStyles[variant],\r\n ...sizeStyles[size],\r\n ...style,\r\n };\r\n\r\n return (\r\n <button\r\n onClick={handleClick}\r\n disabled={inProgress}\r\n className={className}\r\n style={baseStyles}\r\n aria-label={text}\r\n >\r\n <MicrosoftLogo />\r\n <span>{text}</span>\r\n </button>\r\n );\r\n}\r\n\r\nfunction MicrosoftLogo() {\r\n return (\r\n <svg width=\"21\" height=\"21\" viewBox=\"0 0 21 21\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <rect width=\"10\" height=\"10\" fill=\"#F25022\" />\r\n <rect x=\"11\" width=\"10\" height=\"10\" fill=\"#7FBA00\" />\r\n <rect y=\"11\" width=\"10\" height=\"10\" fill=\"#00A4EF\" />\r\n <rect x=\"11\" y=\"11\" width=\"10\" height=\"10\" fill=\"#FFB900\" />\r\n </svg>\r\n );\r\n}\r\n"],"mappings":"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","names":["import_msal_browser","import_msal_react","import_msal_browser","import_react","import_jsx_runtime","import_msal_react"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/MsalAuthProvider.tsx","../src/utils/createMsalConfig.ts","../src/hooks/useMsalAuth.ts","../src/components/MicrosoftSignInButton.tsx"],"sourcesContent":["export { MsalAuthProvider, getMsalInstance } from './components/MsalAuthProvider';\r\nexport { MicrosoftSignInButton } from './components/MicrosoftSignInButton';\r\nexport { useMsalAuth } from './hooks/useMsalAuth';\r\nexport type { UseMsalAuthReturn } from './hooks/useMsalAuth';\r\nexport type { MsalAuthConfig, MsalAuthProviderProps } from './types';\r\nexport type { MicrosoftSignInButtonProps } from './components/MicrosoftSignInButton';\r\n\r\n// Re-export useful MSAL hooks\r\nexport { useMsal, useIsAuthenticated, useAccount } from '@azure/msal-react';\r\n","'use client';\r\n\r\nimport { MsalProvider } from '@azure/msal-react';\r\nimport { PublicClientApplication, EventType, EventMessage, AuthenticationResult } from '@azure/msal-browser';\r\nimport { useEffect, useState, useRef } from 'react';\r\nimport { MsalAuthProviderProps } from '../types';\r\nimport { createMsalConfig } from '../utils/createMsalConfig';\r\n\r\n// Module-level variable to store the MSAL instance\r\nlet globalMsalInstance: PublicClientApplication | null = null;\r\n\r\n/**\r\n * Get the current MSAL instance\r\n * @returns The MSAL instance or null if not initialized\r\n */\r\nexport function getMsalInstance(): PublicClientApplication | null {\r\n return globalMsalInstance;\r\n}\r\n\r\nexport function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps) {\r\n const [msalInstance, setMsalInstance] = useState<PublicClientApplication | null>(null);\r\n const instanceRef = useRef<PublicClientApplication | null>(null);\r\n\r\n useEffect(() => {\r\n // SSR safety guard\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n\r\n // Prevent multiple initializations\r\n if (instanceRef.current) {\r\n return;\r\n }\r\n\r\n const initializeMsal = async () => {\r\n try {\r\n const msalConfig = createMsalConfig(config);\r\n const instance = new PublicClientApplication(msalConfig);\r\n \r\n await instance.initialize();\r\n\r\n // Handle redirect promise\r\n const response = await instance.handleRedirectPromise();\r\n if (response && config.enableLogging) {\r\n console.log('[MSAL] Redirect authentication successful');\r\n }\r\n\r\n // Set up event callbacks\r\n const enableLogging = config.enableLogging || false;\r\n instance.addEventCallback((event: EventMessage) => {\r\n if (event.eventType === EventType.LOGIN_SUCCESS) {\r\n if (enableLogging) {\r\n const payload = event.payload as AuthenticationResult;\r\n console.log('[MSAL] Login successful:', payload.account?.username);\r\n }\r\n }\r\n \r\n if (event.eventType === EventType.LOGIN_FAILURE) {\r\n // Always log errors regardless of enableLogging\r\n console.error('[MSAL] Login failed:', event.error);\r\n }\r\n\r\n if (event.eventType === EventType.LOGOUT_SUCCESS) {\r\n if (enableLogging) {\r\n console.log('[MSAL] Logout successful');\r\n }\r\n }\r\n });\r\n\r\n instanceRef.current = instance;\r\n globalMsalInstance = instance;\r\n setMsalInstance(instance);\r\n\r\n // Call onInitialized callback if provided\r\n if (onInitialized) {\r\n onInitialized(instance);\r\n }\r\n } catch (error) {\r\n console.error('[MSAL] Initialization failed:', error);\r\n throw error;\r\n }\r\n };\r\n\r\n initializeMsal();\r\n }, []); // Empty dependency array - only initialize once\r\n\r\n // SSR safety guard - render children or loading component on server\r\n if (typeof window === 'undefined') {\r\n return <>{loadingComponent || <div>Loading authentication...</div>}</>;\r\n }\r\n\r\n if (!msalInstance) {\r\n return <>{loadingComponent || <div>Loading authentication...</div>}</>;\r\n }\r\n\r\n return <MsalProvider instance={msalInstance}>{children}</MsalProvider>;\r\n}\r\n","import { Configuration, LogLevel } from '@azure/msal-browser';\r\nimport { MsalAuthConfig } from '../types';\r\n\r\nexport function createMsalConfig(config: MsalAuthConfig): Configuration {\r\n // If custom config provided, use it\r\n if (config.msalConfig) {\r\n return config.msalConfig;\r\n }\r\n\r\n const {\r\n clientId,\r\n tenantId,\r\n authorityType = 'common',\r\n redirectUri,\r\n postLogoutRedirectUri,\r\n cacheLocation = 'sessionStorage',\r\n storeAuthStateInCookie = false,\r\n navigateToLoginRequestUrl = true,\r\n enableLogging = false,\r\n loggerCallback,\r\n } = config;\r\n\r\n if (!clientId) {\r\n throw new Error('@chemmangat/msal-next: clientId is required');\r\n }\r\n\r\n // Build authority URL\r\n const getAuthority = (): string => {\r\n if (authorityType === 'tenant') {\r\n if (!tenantId) {\r\n throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is \"tenant\"');\r\n }\r\n return `https://login.microsoftonline.com/${tenantId}`;\r\n }\r\n return `https://login.microsoftonline.com/${authorityType}`;\r\n };\r\n\r\n // Default redirect URI\r\n const defaultRedirectUri = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000';\r\n const finalRedirectUri = redirectUri || defaultRedirectUri;\r\n\r\n const msalConfig: Configuration = {\r\n auth: {\r\n clientId,\r\n authority: getAuthority(),\r\n redirectUri: finalRedirectUri,\r\n postLogoutRedirectUri: postLogoutRedirectUri || finalRedirectUri,\r\n navigateToLoginRequestUrl,\r\n },\r\n cache: {\r\n cacheLocation,\r\n storeAuthStateInCookie,\r\n },\r\n system: {\r\n loggerOptions: {\r\n loggerCallback: loggerCallback || ((level: LogLevel, message: string, containsPii: boolean) => {\r\n if (containsPii || !enableLogging) return;\r\n \r\n switch (level) {\r\n case LogLevel.Error:\r\n console.error('[MSAL]', message);\r\n break;\r\n case LogLevel.Warning:\r\n console.warn('[MSAL]', message);\r\n break;\r\n case LogLevel.Info:\r\n console.info('[MSAL]', message);\r\n break;\r\n case LogLevel.Verbose:\r\n console.debug('[MSAL]', message);\r\n break;\r\n }\r\n }),\r\n logLevel: enableLogging ? LogLevel.Verbose : LogLevel.Error,\r\n },\r\n },\r\n };\r\n\r\n return msalConfig;\r\n}\r\n","'use client';\r\n\r\nimport { useMsal, useAccount } from '@azure/msal-react';\r\nimport { AccountInfo, InteractionStatus, PopupRequest, RedirectRequest, SilentRequest } from '@azure/msal-browser';\r\nimport { useCallback, useMemo } from 'react';\r\n\r\nexport interface UseMsalAuthReturn {\r\n /**\r\n * Current authenticated account\r\n */\r\n account: AccountInfo | null;\r\n\r\n /**\r\n * All accounts in the cache\r\n */\r\n accounts: AccountInfo[];\r\n\r\n /**\r\n * Whether user is authenticated\r\n */\r\n isAuthenticated: boolean;\r\n\r\n /**\r\n * Whether MSAL is currently performing an interaction\r\n */\r\n inProgress: boolean;\r\n\r\n /**\r\n * Login using popup\r\n */\r\n loginPopup: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Login using redirect\r\n */\r\n loginRedirect: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Logout using popup\r\n */\r\n logoutPopup: () => Promise<void>;\r\n\r\n /**\r\n * Logout using redirect\r\n */\r\n logoutRedirect: () => Promise<void>;\r\n\r\n /**\r\n * Acquire access token silently (with fallback to popup)\r\n */\r\n acquireToken: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token silently only (no fallback)\r\n */\r\n acquireTokenSilent: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using popup\r\n */\r\n acquireTokenPopup: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using redirect\r\n */\r\n acquireTokenRedirect: (scopes: string[]) => Promise<void>;\r\n\r\n /**\r\n * Clear MSAL session without triggering Microsoft logout\r\n */\r\n clearSession: () => Promise<void>;\r\n}\r\n\r\nexport function useMsalAuth(defaultScopes: string[] = ['User.Read']): UseMsalAuthReturn {\r\n const { instance, accounts, inProgress } = useMsal();\r\n const account = useAccount(accounts[0] || null);\r\n\r\n const isAuthenticated = useMemo(() => accounts.length > 0, [accounts]);\r\n\r\n const loginPopup = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginPopup(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login popup failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const loginRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login redirect failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const logoutPopup = useCallback(async () => {\r\n try {\r\n await instance.logoutPopup({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout popup failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const logoutRedirect = useCallback(async () => {\r\n try {\r\n await instance.logoutRedirect({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout redirect failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const acquireTokenSilent = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: SilentRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenSilent(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Silent token acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenPopup = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenPopup(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Token popup acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<void> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n account,\r\n };\r\n await instance.acquireTokenRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Token redirect acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireToken = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n try {\r\n return await acquireTokenSilent(scopes);\r\n } catch (error) {\r\n console.warn('[MSAL] Silent token acquisition failed, falling back to popup');\r\n return await acquireTokenPopup(scopes);\r\n }\r\n },\r\n [acquireTokenSilent, acquireTokenPopup, defaultScopes]\r\n );\r\n\r\n const clearSession = useCallback(async () => {\r\n instance.setActiveAccount(null);\r\n await instance.clearCache();\r\n }, [instance]);\r\n\r\n return {\r\n account,\r\n accounts,\r\n isAuthenticated,\r\n inProgress: inProgress !== InteractionStatus.None,\r\n loginPopup,\r\n loginRedirect,\r\n logoutPopup,\r\n logoutRedirect,\r\n acquireToken,\r\n acquireTokenSilent,\r\n acquireTokenPopup,\r\n acquireTokenRedirect,\r\n clearSession,\r\n };\r\n}\r\n","'use client';\r\n\r\nimport { useMsalAuth } from '../hooks/useMsalAuth';\r\nimport { CSSProperties } from 'react';\r\n\r\nexport interface MicrosoftSignInButtonProps {\r\n /**\r\n * Button text\r\n * @default 'Sign in with Microsoft'\r\n */\r\n text?: string;\r\n \r\n /**\r\n * Button variant\r\n * @default 'dark'\r\n */\r\n variant?: 'dark' | 'light';\r\n \r\n /**\r\n * Button size\r\n * @default 'medium'\r\n */\r\n size?: 'small' | 'medium' | 'large';\r\n \r\n /**\r\n * Use redirect flow instead of popup\r\n * @default false\r\n */\r\n useRedirect?: boolean;\r\n \r\n /**\r\n * Scopes to request\r\n */\r\n scopes?: string[];\r\n \r\n /**\r\n * Custom className\r\n */\r\n className?: string;\r\n \r\n /**\r\n * Custom styles\r\n */\r\n style?: CSSProperties;\r\n \r\n /**\r\n * Callback on successful login\r\n */\r\n onSuccess?: () => void;\r\n \r\n /**\r\n * Callback on error\r\n */\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport function MicrosoftSignInButton({\r\n text = 'Sign in with Microsoft',\r\n variant = 'dark',\r\n size = 'medium',\r\n useRedirect = false,\r\n scopes,\r\n className = '',\r\n style,\r\n onSuccess,\r\n onError,\r\n}: MicrosoftSignInButtonProps) {\r\n const { loginPopup, loginRedirect, inProgress } = useMsalAuth();\r\n\r\n const handleClick = async () => {\r\n try {\r\n if (useRedirect) {\r\n await loginRedirect(scopes);\r\n } else {\r\n await loginPopup(scopes);\r\n }\r\n onSuccess?.();\r\n } catch (error) {\r\n onError?.(error as Error);\r\n }\r\n };\r\n\r\n const sizeStyles = {\r\n small: {\r\n padding: '8px 16px',\r\n fontSize: '14px',\r\n height: '36px',\r\n },\r\n medium: {\r\n padding: '10px 20px',\r\n fontSize: '15px',\r\n height: '41px',\r\n },\r\n large: {\r\n padding: '12px 24px',\r\n fontSize: '16px',\r\n height: '48px',\r\n },\r\n };\r\n\r\n const variantStyles = {\r\n dark: {\r\n backgroundColor: '#2F2F2F',\r\n color: '#FFFFFF',\r\n border: '1px solid #8C8C8C',\r\n },\r\n light: {\r\n backgroundColor: '#FFFFFF',\r\n color: '#5E5E5E',\r\n border: '1px solid #8C8C8C',\r\n },\r\n };\r\n\r\n const baseStyles: CSSProperties = {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '12px',\r\n fontFamily: '\"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif',\r\n fontWeight: 600,\r\n borderRadius: '2px',\r\n cursor: inProgress ? 'not-allowed' : 'pointer',\r\n transition: 'all 0.2s ease',\r\n opacity: inProgress ? 0.6 : 1,\r\n ...variantStyles[variant],\r\n ...sizeStyles[size],\r\n ...style,\r\n };\r\n\r\n return (\r\n <button\r\n onClick={handleClick}\r\n disabled={inProgress}\r\n className={className}\r\n style={baseStyles}\r\n aria-label={text}\r\n >\r\n <MicrosoftLogo />\r\n <span>{text}</span>\r\n </button>\r\n );\r\n}\r\n\r\nfunction MicrosoftLogo() {\r\n return (\r\n <svg width=\"21\" height=\"21\" viewBox=\"0 0 21 21\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <rect width=\"10\" height=\"10\" fill=\"#F25022\" />\r\n <rect x=\"11\" width=\"10\" height=\"10\" fill=\"#7FBA00\" />\r\n <rect y=\"11\" width=\"10\" height=\"10\" fill=\"#00A4EF\" />\r\n <rect x=\"11\" y=\"11\" width=\"10\" height=\"10\" fill=\"#FFB900\" />\r\n </svg>\r\n );\r\n}\r\n"],"mappings":"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","names":["import_msal_browser","import_msal_react","import_msal_browser","import_react","import_jsx_runtime","import_msal_react"]}
package/dist/index.mjs CHANGED
@@ -77,10 +77,17 @@ function createMsalConfig(config) {
77
77
 
78
78
  // src/components/MsalAuthProvider.tsx
79
79
  import { Fragment, jsx } from "react/jsx-runtime";
80
- function MsalAuthProvider({ children, loadingComponent, ...config }) {
80
+ var globalMsalInstance = null;
81
+ function getMsalInstance() {
82
+ return globalMsalInstance;
83
+ }
84
+ function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }) {
81
85
  const [msalInstance, setMsalInstance] = useState(null);
82
86
  const instanceRef = useRef(null);
83
87
  useEffect(() => {
88
+ if (typeof window === "undefined") {
89
+ return;
90
+ }
84
91
  if (instanceRef.current) {
85
92
  return;
86
93
  }
@@ -90,23 +97,32 @@ function MsalAuthProvider({ children, loadingComponent, ...config }) {
90
97
  const instance = new PublicClientApplication(msalConfig);
91
98
  await instance.initialize();
92
99
  const response = await instance.handleRedirectPromise();
93
- if (response) {
100
+ if (response && config.enableLogging) {
94
101
  console.log("[MSAL] Redirect authentication successful");
95
102
  }
103
+ const enableLogging = config.enableLogging || false;
96
104
  instance.addEventCallback((event) => {
97
105
  if (event.eventType === EventType.LOGIN_SUCCESS) {
98
- const payload = event.payload;
99
- console.log("[MSAL] Login successful:", payload.account?.username);
106
+ if (enableLogging) {
107
+ const payload = event.payload;
108
+ console.log("[MSAL] Login successful:", payload.account?.username);
109
+ }
100
110
  }
101
111
  if (event.eventType === EventType.LOGIN_FAILURE) {
102
112
  console.error("[MSAL] Login failed:", event.error);
103
113
  }
104
114
  if (event.eventType === EventType.LOGOUT_SUCCESS) {
105
- console.log("[MSAL] Logout successful");
115
+ if (enableLogging) {
116
+ console.log("[MSAL] Logout successful");
117
+ }
106
118
  }
107
119
  });
108
120
  instanceRef.current = instance;
121
+ globalMsalInstance = instance;
109
122
  setMsalInstance(instance);
123
+ if (onInitialized) {
124
+ onInitialized(instance);
125
+ }
110
126
  } catch (error) {
111
127
  console.error("[MSAL] Initialization failed:", error);
112
128
  throw error;
@@ -114,6 +130,9 @@ function MsalAuthProvider({ children, loadingComponent, ...config }) {
114
130
  };
115
131
  initializeMsal();
116
132
  }, []);
133
+ if (typeof window === "undefined") {
134
+ return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
135
+ }
117
136
  if (!msalInstance) {
118
137
  return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
119
138
  }
@@ -245,6 +264,10 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
245
264
  },
246
265
  [acquireTokenSilent, acquireTokenPopup, defaultScopes]
247
266
  );
267
+ const clearSession = useCallback(async () => {
268
+ instance.setActiveAccount(null);
269
+ await instance.clearCache();
270
+ }, [instance]);
248
271
  return {
249
272
  account,
250
273
  accounts,
@@ -257,7 +280,8 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
257
280
  acquireToken,
258
281
  acquireTokenSilent,
259
282
  acquireTokenPopup,
260
- acquireTokenRedirect
283
+ acquireTokenRedirect,
284
+ clearSession
261
285
  };
262
286
  }
263
287
 
@@ -360,6 +384,7 @@ import { useMsal as useMsal2, useIsAuthenticated, useAccount as useAccount2 } fr
360
384
  export {
361
385
  MicrosoftSignInButton,
362
386
  MsalAuthProvider,
387
+ getMsalInstance,
363
388
  useAccount2 as useAccount,
364
389
  useIsAuthenticated,
365
390
  useMsal2 as useMsal,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/MsalAuthProvider.tsx","../src/utils/createMsalConfig.ts","../src/hooks/useMsalAuth.ts","../src/components/MicrosoftSignInButton.tsx","../src/index.ts"],"sourcesContent":["'use client';\r\n\r\nimport { MsalProvider } from '@azure/msal-react';\r\nimport { PublicClientApplication, EventType, EventMessage, AuthenticationResult } from '@azure/msal-browser';\r\nimport { useEffect, useState, useRef } from 'react';\r\nimport { MsalAuthProviderProps } from '../types';\r\nimport { createMsalConfig } from '../utils/createMsalConfig';\r\n\r\nexport function MsalAuthProvider({ children, loadingComponent, ...config }: MsalAuthProviderProps) {\r\n const [msalInstance, setMsalInstance] = useState<PublicClientApplication | null>(null);\r\n const instanceRef = useRef<PublicClientApplication | null>(null);\r\n\r\n useEffect(() => {\r\n // Prevent multiple initializations\r\n if (instanceRef.current) {\r\n return;\r\n }\r\n\r\n const initializeMsal = async () => {\r\n try {\r\n const msalConfig = createMsalConfig(config);\r\n const instance = new PublicClientApplication(msalConfig);\r\n \r\n await instance.initialize();\r\n\r\n // Handle redirect promise\r\n const response = await instance.handleRedirectPromise();\r\n if (response) {\r\n console.log('[MSAL] Redirect authentication successful');\r\n }\r\n\r\n // Optional: Set up event callbacks\r\n instance.addEventCallback((event: EventMessage) => {\r\n if (event.eventType === EventType.LOGIN_SUCCESS) {\r\n const payload = event.payload as AuthenticationResult;\r\n console.log('[MSAL] Login successful:', payload.account?.username);\r\n }\r\n \r\n if (event.eventType === EventType.LOGIN_FAILURE) {\r\n console.error('[MSAL] Login failed:', event.error);\r\n }\r\n\r\n if (event.eventType === EventType.LOGOUT_SUCCESS) {\r\n console.log('[MSAL] Logout successful');\r\n }\r\n });\r\n\r\n instanceRef.current = instance;\r\n setMsalInstance(instance);\r\n } catch (error) {\r\n console.error('[MSAL] Initialization failed:', error);\r\n throw error;\r\n }\r\n };\r\n\r\n initializeMsal();\r\n }, []); // Empty dependency array - only initialize once\r\n\r\n if (!msalInstance) {\r\n return <>{loadingComponent || <div>Loading authentication...</div>}</>;\r\n }\r\n\r\n return <MsalProvider instance={msalInstance}>{children}</MsalProvider>;\r\n}\r\n","import { Configuration, LogLevel } from '@azure/msal-browser';\r\nimport { MsalAuthConfig } from '../types';\r\n\r\nexport function createMsalConfig(config: MsalAuthConfig): Configuration {\r\n // If custom config provided, use it\r\n if (config.msalConfig) {\r\n return config.msalConfig;\r\n }\r\n\r\n const {\r\n clientId,\r\n tenantId,\r\n authorityType = 'common',\r\n redirectUri,\r\n postLogoutRedirectUri,\r\n cacheLocation = 'sessionStorage',\r\n storeAuthStateInCookie = false,\r\n navigateToLoginRequestUrl = true,\r\n enableLogging = false,\r\n loggerCallback,\r\n } = config;\r\n\r\n if (!clientId) {\r\n throw new Error('@chemmangat/msal-next: clientId is required');\r\n }\r\n\r\n // Build authority URL\r\n const getAuthority = (): string => {\r\n if (authorityType === 'tenant') {\r\n if (!tenantId) {\r\n throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is \"tenant\"');\r\n }\r\n return `https://login.microsoftonline.com/${tenantId}`;\r\n }\r\n return `https://login.microsoftonline.com/${authorityType}`;\r\n };\r\n\r\n // Default redirect URI\r\n const defaultRedirectUri = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000';\r\n const finalRedirectUri = redirectUri || defaultRedirectUri;\r\n\r\n const msalConfig: Configuration = {\r\n auth: {\r\n clientId,\r\n authority: getAuthority(),\r\n redirectUri: finalRedirectUri,\r\n postLogoutRedirectUri: postLogoutRedirectUri || finalRedirectUri,\r\n navigateToLoginRequestUrl,\r\n },\r\n cache: {\r\n cacheLocation,\r\n storeAuthStateInCookie,\r\n },\r\n system: {\r\n loggerOptions: {\r\n loggerCallback: loggerCallback || ((level: LogLevel, message: string, containsPii: boolean) => {\r\n if (containsPii || !enableLogging) return;\r\n \r\n switch (level) {\r\n case LogLevel.Error:\r\n console.error('[MSAL]', message);\r\n break;\r\n case LogLevel.Warning:\r\n console.warn('[MSAL]', message);\r\n break;\r\n case LogLevel.Info:\r\n console.info('[MSAL]', message);\r\n break;\r\n case LogLevel.Verbose:\r\n console.debug('[MSAL]', message);\r\n break;\r\n }\r\n }),\r\n logLevel: enableLogging ? LogLevel.Verbose : LogLevel.Error,\r\n },\r\n },\r\n };\r\n\r\n return msalConfig;\r\n}\r\n","'use client';\r\n\r\nimport { useMsal, useAccount } from '@azure/msal-react';\r\nimport { AccountInfo, InteractionStatus, PopupRequest, RedirectRequest, SilentRequest } from '@azure/msal-browser';\r\nimport { useCallback, useMemo } from 'react';\r\n\r\nexport interface UseMsalAuthReturn {\r\n /**\r\n * Current authenticated account\r\n */\r\n account: AccountInfo | null;\r\n\r\n /**\r\n * All accounts in the cache\r\n */\r\n accounts: AccountInfo[];\r\n\r\n /**\r\n * Whether user is authenticated\r\n */\r\n isAuthenticated: boolean;\r\n\r\n /**\r\n * Whether MSAL is currently performing an interaction\r\n */\r\n inProgress: boolean;\r\n\r\n /**\r\n * Login using popup\r\n */\r\n loginPopup: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Login using redirect\r\n */\r\n loginRedirect: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Logout using popup\r\n */\r\n logoutPopup: () => Promise<void>;\r\n\r\n /**\r\n * Logout using redirect\r\n */\r\n logoutRedirect: () => Promise<void>;\r\n\r\n /**\r\n * Acquire access token silently (with fallback to popup)\r\n */\r\n acquireToken: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token silently only (no fallback)\r\n */\r\n acquireTokenSilent: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using popup\r\n */\r\n acquireTokenPopup: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using redirect\r\n */\r\n acquireTokenRedirect: (scopes: string[]) => Promise<void>;\r\n}\r\n\r\nexport function useMsalAuth(defaultScopes: string[] = ['User.Read']): UseMsalAuthReturn {\r\n const { instance, accounts, inProgress } = useMsal();\r\n const account = useAccount(accounts[0] || null);\r\n\r\n const isAuthenticated = useMemo(() => accounts.length > 0, [accounts]);\r\n\r\n const loginPopup = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginPopup(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login popup failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const loginRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login redirect failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const logoutPopup = useCallback(async () => {\r\n try {\r\n await instance.logoutPopup({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout popup failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const logoutRedirect = useCallback(async () => {\r\n try {\r\n await instance.logoutRedirect({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout redirect failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const acquireTokenSilent = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: SilentRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenSilent(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Silent token acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenPopup = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenPopup(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Token popup acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<void> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n account,\r\n };\r\n await instance.acquireTokenRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Token redirect acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireToken = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n try {\r\n return await acquireTokenSilent(scopes);\r\n } catch (error) {\r\n console.warn('[MSAL] Silent token acquisition failed, falling back to popup');\r\n return await acquireTokenPopup(scopes);\r\n }\r\n },\r\n [acquireTokenSilent, acquireTokenPopup, defaultScopes]\r\n );\r\n\r\n return {\r\n account,\r\n accounts,\r\n isAuthenticated,\r\n inProgress: inProgress !== InteractionStatus.None,\r\n loginPopup,\r\n loginRedirect,\r\n logoutPopup,\r\n logoutRedirect,\r\n acquireToken,\r\n acquireTokenSilent,\r\n acquireTokenPopup,\r\n acquireTokenRedirect,\r\n };\r\n}\r\n","'use client';\r\n\r\nimport { useMsalAuth } from '../hooks/useMsalAuth';\r\nimport { CSSProperties } from 'react';\r\n\r\nexport interface MicrosoftSignInButtonProps {\r\n /**\r\n * Button text\r\n * @default 'Sign in with Microsoft'\r\n */\r\n text?: string;\r\n \r\n /**\r\n * Button variant\r\n * @default 'dark'\r\n */\r\n variant?: 'dark' | 'light';\r\n \r\n /**\r\n * Button size\r\n * @default 'medium'\r\n */\r\n size?: 'small' | 'medium' | 'large';\r\n \r\n /**\r\n * Use redirect flow instead of popup\r\n * @default false\r\n */\r\n useRedirect?: boolean;\r\n \r\n /**\r\n * Scopes to request\r\n */\r\n scopes?: string[];\r\n \r\n /**\r\n * Custom className\r\n */\r\n className?: string;\r\n \r\n /**\r\n * Custom styles\r\n */\r\n style?: CSSProperties;\r\n \r\n /**\r\n * Callback on successful login\r\n */\r\n onSuccess?: () => void;\r\n \r\n /**\r\n * Callback on error\r\n */\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport function MicrosoftSignInButton({\r\n text = 'Sign in with Microsoft',\r\n variant = 'dark',\r\n size = 'medium',\r\n useRedirect = false,\r\n scopes,\r\n className = '',\r\n style,\r\n onSuccess,\r\n onError,\r\n}: MicrosoftSignInButtonProps) {\r\n const { loginPopup, loginRedirect, inProgress } = useMsalAuth();\r\n\r\n const handleClick = async () => {\r\n try {\r\n if (useRedirect) {\r\n await loginRedirect(scopes);\r\n } else {\r\n await loginPopup(scopes);\r\n }\r\n onSuccess?.();\r\n } catch (error) {\r\n onError?.(error as Error);\r\n }\r\n };\r\n\r\n const sizeStyles = {\r\n small: {\r\n padding: '8px 16px',\r\n fontSize: '14px',\r\n height: '36px',\r\n },\r\n medium: {\r\n padding: '10px 20px',\r\n fontSize: '15px',\r\n height: '41px',\r\n },\r\n large: {\r\n padding: '12px 24px',\r\n fontSize: '16px',\r\n height: '48px',\r\n },\r\n };\r\n\r\n const variantStyles = {\r\n dark: {\r\n backgroundColor: '#2F2F2F',\r\n color: '#FFFFFF',\r\n border: '1px solid #8C8C8C',\r\n },\r\n light: {\r\n backgroundColor: '#FFFFFF',\r\n color: '#5E5E5E',\r\n border: '1px solid #8C8C8C',\r\n },\r\n };\r\n\r\n const baseStyles: CSSProperties = {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '12px',\r\n fontFamily: '\"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif',\r\n fontWeight: 600,\r\n borderRadius: '2px',\r\n cursor: inProgress ? 'not-allowed' : 'pointer',\r\n transition: 'all 0.2s ease',\r\n opacity: inProgress ? 0.6 : 1,\r\n ...variantStyles[variant],\r\n ...sizeStyles[size],\r\n ...style,\r\n };\r\n\r\n return (\r\n <button\r\n onClick={handleClick}\r\n disabled={inProgress}\r\n className={className}\r\n style={baseStyles}\r\n aria-label={text}\r\n >\r\n <MicrosoftLogo />\r\n <span>{text}</span>\r\n </button>\r\n );\r\n}\r\n\r\nfunction MicrosoftLogo() {\r\n return (\r\n <svg width=\"21\" height=\"21\" viewBox=\"0 0 21 21\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <rect width=\"10\" height=\"10\" fill=\"#F25022\" />\r\n <rect x=\"11\" width=\"10\" height=\"10\" fill=\"#7FBA00\" />\r\n <rect y=\"11\" width=\"10\" height=\"10\" fill=\"#00A4EF\" />\r\n <rect x=\"11\" y=\"11\" width=\"10\" height=\"10\" fill=\"#FFB900\" />\r\n </svg>\r\n );\r\n}\r\n","export { MsalAuthProvider } from './components/MsalAuthProvider';\r\nexport { MicrosoftSignInButton } from './components/MicrosoftSignInButton';\r\nexport { useMsalAuth } from './hooks/useMsalAuth';\r\nexport type { MsalAuthConfig, MsalAuthProviderProps } from './types';\r\nexport type { MicrosoftSignInButtonProps } from './components/MicrosoftSignInButton';\r\n\r\n// Re-export useful MSAL hooks\r\nexport { useMsal, useIsAuthenticated, useAccount } from '@azure/msal-react';\r\n"],"mappings":"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","names":["jsx","useMsal","useAccount"]}
1
+ {"version":3,"sources":["../src/components/MsalAuthProvider.tsx","../src/utils/createMsalConfig.ts","../src/hooks/useMsalAuth.ts","../src/components/MicrosoftSignInButton.tsx","../src/index.ts"],"sourcesContent":["'use client';\r\n\r\nimport { MsalProvider } from '@azure/msal-react';\r\nimport { PublicClientApplication, EventType, EventMessage, AuthenticationResult } from '@azure/msal-browser';\r\nimport { useEffect, useState, useRef } from 'react';\r\nimport { MsalAuthProviderProps } from '../types';\r\nimport { createMsalConfig } from '../utils/createMsalConfig';\r\n\r\n// Module-level variable to store the MSAL instance\r\nlet globalMsalInstance: PublicClientApplication | null = null;\r\n\r\n/**\r\n * Get the current MSAL instance\r\n * @returns The MSAL instance or null if not initialized\r\n */\r\nexport function getMsalInstance(): PublicClientApplication | null {\r\n return globalMsalInstance;\r\n}\r\n\r\nexport function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }: MsalAuthProviderProps) {\r\n const [msalInstance, setMsalInstance] = useState<PublicClientApplication | null>(null);\r\n const instanceRef = useRef<PublicClientApplication | null>(null);\r\n\r\n useEffect(() => {\r\n // SSR safety guard\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n\r\n // Prevent multiple initializations\r\n if (instanceRef.current) {\r\n return;\r\n }\r\n\r\n const initializeMsal = async () => {\r\n try {\r\n const msalConfig = createMsalConfig(config);\r\n const instance = new PublicClientApplication(msalConfig);\r\n \r\n await instance.initialize();\r\n\r\n // Handle redirect promise\r\n const response = await instance.handleRedirectPromise();\r\n if (response && config.enableLogging) {\r\n console.log('[MSAL] Redirect authentication successful');\r\n }\r\n\r\n // Set up event callbacks\r\n const enableLogging = config.enableLogging || false;\r\n instance.addEventCallback((event: EventMessage) => {\r\n if (event.eventType === EventType.LOGIN_SUCCESS) {\r\n if (enableLogging) {\r\n const payload = event.payload as AuthenticationResult;\r\n console.log('[MSAL] Login successful:', payload.account?.username);\r\n }\r\n }\r\n \r\n if (event.eventType === EventType.LOGIN_FAILURE) {\r\n // Always log errors regardless of enableLogging\r\n console.error('[MSAL] Login failed:', event.error);\r\n }\r\n\r\n if (event.eventType === EventType.LOGOUT_SUCCESS) {\r\n if (enableLogging) {\r\n console.log('[MSAL] Logout successful');\r\n }\r\n }\r\n });\r\n\r\n instanceRef.current = instance;\r\n globalMsalInstance = instance;\r\n setMsalInstance(instance);\r\n\r\n // Call onInitialized callback if provided\r\n if (onInitialized) {\r\n onInitialized(instance);\r\n }\r\n } catch (error) {\r\n console.error('[MSAL] Initialization failed:', error);\r\n throw error;\r\n }\r\n };\r\n\r\n initializeMsal();\r\n }, []); // Empty dependency array - only initialize once\r\n\r\n // SSR safety guard - render children or loading component on server\r\n if (typeof window === 'undefined') {\r\n return <>{loadingComponent || <div>Loading authentication...</div>}</>;\r\n }\r\n\r\n if (!msalInstance) {\r\n return <>{loadingComponent || <div>Loading authentication...</div>}</>;\r\n }\r\n\r\n return <MsalProvider instance={msalInstance}>{children}</MsalProvider>;\r\n}\r\n","import { Configuration, LogLevel } from '@azure/msal-browser';\r\nimport { MsalAuthConfig } from '../types';\r\n\r\nexport function createMsalConfig(config: MsalAuthConfig): Configuration {\r\n // If custom config provided, use it\r\n if (config.msalConfig) {\r\n return config.msalConfig;\r\n }\r\n\r\n const {\r\n clientId,\r\n tenantId,\r\n authorityType = 'common',\r\n redirectUri,\r\n postLogoutRedirectUri,\r\n cacheLocation = 'sessionStorage',\r\n storeAuthStateInCookie = false,\r\n navigateToLoginRequestUrl = true,\r\n enableLogging = false,\r\n loggerCallback,\r\n } = config;\r\n\r\n if (!clientId) {\r\n throw new Error('@chemmangat/msal-next: clientId is required');\r\n }\r\n\r\n // Build authority URL\r\n const getAuthority = (): string => {\r\n if (authorityType === 'tenant') {\r\n if (!tenantId) {\r\n throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is \"tenant\"');\r\n }\r\n return `https://login.microsoftonline.com/${tenantId}`;\r\n }\r\n return `https://login.microsoftonline.com/${authorityType}`;\r\n };\r\n\r\n // Default redirect URI\r\n const defaultRedirectUri = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000';\r\n const finalRedirectUri = redirectUri || defaultRedirectUri;\r\n\r\n const msalConfig: Configuration = {\r\n auth: {\r\n clientId,\r\n authority: getAuthority(),\r\n redirectUri: finalRedirectUri,\r\n postLogoutRedirectUri: postLogoutRedirectUri || finalRedirectUri,\r\n navigateToLoginRequestUrl,\r\n },\r\n cache: {\r\n cacheLocation,\r\n storeAuthStateInCookie,\r\n },\r\n system: {\r\n loggerOptions: {\r\n loggerCallback: loggerCallback || ((level: LogLevel, message: string, containsPii: boolean) => {\r\n if (containsPii || !enableLogging) return;\r\n \r\n switch (level) {\r\n case LogLevel.Error:\r\n console.error('[MSAL]', message);\r\n break;\r\n case LogLevel.Warning:\r\n console.warn('[MSAL]', message);\r\n break;\r\n case LogLevel.Info:\r\n console.info('[MSAL]', message);\r\n break;\r\n case LogLevel.Verbose:\r\n console.debug('[MSAL]', message);\r\n break;\r\n }\r\n }),\r\n logLevel: enableLogging ? LogLevel.Verbose : LogLevel.Error,\r\n },\r\n },\r\n };\r\n\r\n return msalConfig;\r\n}\r\n","'use client';\r\n\r\nimport { useMsal, useAccount } from '@azure/msal-react';\r\nimport { AccountInfo, InteractionStatus, PopupRequest, RedirectRequest, SilentRequest } from '@azure/msal-browser';\r\nimport { useCallback, useMemo } from 'react';\r\n\r\nexport interface UseMsalAuthReturn {\r\n /**\r\n * Current authenticated account\r\n */\r\n account: AccountInfo | null;\r\n\r\n /**\r\n * All accounts in the cache\r\n */\r\n accounts: AccountInfo[];\r\n\r\n /**\r\n * Whether user is authenticated\r\n */\r\n isAuthenticated: boolean;\r\n\r\n /**\r\n * Whether MSAL is currently performing an interaction\r\n */\r\n inProgress: boolean;\r\n\r\n /**\r\n * Login using popup\r\n */\r\n loginPopup: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Login using redirect\r\n */\r\n loginRedirect: (scopes?: string[]) => Promise<void>;\r\n\r\n /**\r\n * Logout using popup\r\n */\r\n logoutPopup: () => Promise<void>;\r\n\r\n /**\r\n * Logout using redirect\r\n */\r\n logoutRedirect: () => Promise<void>;\r\n\r\n /**\r\n * Acquire access token silently (with fallback to popup)\r\n */\r\n acquireToken: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token silently only (no fallback)\r\n */\r\n acquireTokenSilent: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using popup\r\n */\r\n acquireTokenPopup: (scopes: string[]) => Promise<string>;\r\n\r\n /**\r\n * Acquire access token using redirect\r\n */\r\n acquireTokenRedirect: (scopes: string[]) => Promise<void>;\r\n\r\n /**\r\n * Clear MSAL session without triggering Microsoft logout\r\n */\r\n clearSession: () => Promise<void>;\r\n}\r\n\r\nexport function useMsalAuth(defaultScopes: string[] = ['User.Read']): UseMsalAuthReturn {\r\n const { instance, accounts, inProgress } = useMsal();\r\n const account = useAccount(accounts[0] || null);\r\n\r\n const isAuthenticated = useMemo(() => accounts.length > 0, [accounts]);\r\n\r\n const loginPopup = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginPopup(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login popup failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const loginRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes) => {\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n prompt: 'select_account',\r\n };\r\n await instance.loginRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Login redirect failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, defaultScopes]\r\n );\r\n\r\n const logoutPopup = useCallback(async () => {\r\n try {\r\n await instance.logoutPopup({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout popup failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const logoutRedirect = useCallback(async () => {\r\n try {\r\n await instance.logoutRedirect({\r\n account: account || undefined,\r\n });\r\n } catch (error) {\r\n console.error('[MSAL] Logout redirect failed:', error);\r\n throw error;\r\n }\r\n }, [instance, account]);\r\n\r\n const acquireTokenSilent = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: SilentRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenSilent(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Silent token acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenPopup = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: PopupRequest = {\r\n scopes,\r\n account,\r\n };\r\n const response = await instance.acquireTokenPopup(request);\r\n return response.accessToken;\r\n } catch (error) {\r\n console.error('[MSAL] Token popup acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireTokenRedirect = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<void> => {\r\n if (!account) {\r\n throw new Error('[MSAL] No active account. Please login first.');\r\n }\r\n\r\n try {\r\n const request: RedirectRequest = {\r\n scopes,\r\n account,\r\n };\r\n await instance.acquireTokenRedirect(request);\r\n } catch (error) {\r\n console.error('[MSAL] Token redirect acquisition failed:', error);\r\n throw error;\r\n }\r\n },\r\n [instance, account, defaultScopes]\r\n );\r\n\r\n const acquireToken = useCallback(\r\n async (scopes: string[] = defaultScopes): Promise<string> => {\r\n try {\r\n return await acquireTokenSilent(scopes);\r\n } catch (error) {\r\n console.warn('[MSAL] Silent token acquisition failed, falling back to popup');\r\n return await acquireTokenPopup(scopes);\r\n }\r\n },\r\n [acquireTokenSilent, acquireTokenPopup, defaultScopes]\r\n );\r\n\r\n const clearSession = useCallback(async () => {\r\n instance.setActiveAccount(null);\r\n await instance.clearCache();\r\n }, [instance]);\r\n\r\n return {\r\n account,\r\n accounts,\r\n isAuthenticated,\r\n inProgress: inProgress !== InteractionStatus.None,\r\n loginPopup,\r\n loginRedirect,\r\n logoutPopup,\r\n logoutRedirect,\r\n acquireToken,\r\n acquireTokenSilent,\r\n acquireTokenPopup,\r\n acquireTokenRedirect,\r\n clearSession,\r\n };\r\n}\r\n","'use client';\r\n\r\nimport { useMsalAuth } from '../hooks/useMsalAuth';\r\nimport { CSSProperties } from 'react';\r\n\r\nexport interface MicrosoftSignInButtonProps {\r\n /**\r\n * Button text\r\n * @default 'Sign in with Microsoft'\r\n */\r\n text?: string;\r\n \r\n /**\r\n * Button variant\r\n * @default 'dark'\r\n */\r\n variant?: 'dark' | 'light';\r\n \r\n /**\r\n * Button size\r\n * @default 'medium'\r\n */\r\n size?: 'small' | 'medium' | 'large';\r\n \r\n /**\r\n * Use redirect flow instead of popup\r\n * @default false\r\n */\r\n useRedirect?: boolean;\r\n \r\n /**\r\n * Scopes to request\r\n */\r\n scopes?: string[];\r\n \r\n /**\r\n * Custom className\r\n */\r\n className?: string;\r\n \r\n /**\r\n * Custom styles\r\n */\r\n style?: CSSProperties;\r\n \r\n /**\r\n * Callback on successful login\r\n */\r\n onSuccess?: () => void;\r\n \r\n /**\r\n * Callback on error\r\n */\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport function MicrosoftSignInButton({\r\n text = 'Sign in with Microsoft',\r\n variant = 'dark',\r\n size = 'medium',\r\n useRedirect = false,\r\n scopes,\r\n className = '',\r\n style,\r\n onSuccess,\r\n onError,\r\n}: MicrosoftSignInButtonProps) {\r\n const { loginPopup, loginRedirect, inProgress } = useMsalAuth();\r\n\r\n const handleClick = async () => {\r\n try {\r\n if (useRedirect) {\r\n await loginRedirect(scopes);\r\n } else {\r\n await loginPopup(scopes);\r\n }\r\n onSuccess?.();\r\n } catch (error) {\r\n onError?.(error as Error);\r\n }\r\n };\r\n\r\n const sizeStyles = {\r\n small: {\r\n padding: '8px 16px',\r\n fontSize: '14px',\r\n height: '36px',\r\n },\r\n medium: {\r\n padding: '10px 20px',\r\n fontSize: '15px',\r\n height: '41px',\r\n },\r\n large: {\r\n padding: '12px 24px',\r\n fontSize: '16px',\r\n height: '48px',\r\n },\r\n };\r\n\r\n const variantStyles = {\r\n dark: {\r\n backgroundColor: '#2F2F2F',\r\n color: '#FFFFFF',\r\n border: '1px solid #8C8C8C',\r\n },\r\n light: {\r\n backgroundColor: '#FFFFFF',\r\n color: '#5E5E5E',\r\n border: '1px solid #8C8C8C',\r\n },\r\n };\r\n\r\n const baseStyles: CSSProperties = {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '12px',\r\n fontFamily: '\"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif',\r\n fontWeight: 600,\r\n borderRadius: '2px',\r\n cursor: inProgress ? 'not-allowed' : 'pointer',\r\n transition: 'all 0.2s ease',\r\n opacity: inProgress ? 0.6 : 1,\r\n ...variantStyles[variant],\r\n ...sizeStyles[size],\r\n ...style,\r\n };\r\n\r\n return (\r\n <button\r\n onClick={handleClick}\r\n disabled={inProgress}\r\n className={className}\r\n style={baseStyles}\r\n aria-label={text}\r\n >\r\n <MicrosoftLogo />\r\n <span>{text}</span>\r\n </button>\r\n );\r\n}\r\n\r\nfunction MicrosoftLogo() {\r\n return (\r\n <svg width=\"21\" height=\"21\" viewBox=\"0 0 21 21\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <rect width=\"10\" height=\"10\" fill=\"#F25022\" />\r\n <rect x=\"11\" width=\"10\" height=\"10\" fill=\"#7FBA00\" />\r\n <rect y=\"11\" width=\"10\" height=\"10\" fill=\"#00A4EF\" />\r\n <rect x=\"11\" y=\"11\" width=\"10\" height=\"10\" fill=\"#FFB900\" />\r\n </svg>\r\n );\r\n}\r\n","export { MsalAuthProvider, getMsalInstance } from './components/MsalAuthProvider';\r\nexport { MicrosoftSignInButton } from './components/MicrosoftSignInButton';\r\nexport { useMsalAuth } from './hooks/useMsalAuth';\r\nexport type { UseMsalAuthReturn } from './hooks/useMsalAuth';\r\nexport type { MsalAuthConfig, MsalAuthProviderProps } from './types';\r\nexport type { MicrosoftSignInButtonProps } from './components/MicrosoftSignInButton';\r\n\r\n// Re-export useful MSAL hooks\r\nexport { useMsal, useIsAuthenticated, useAccount } from '@azure/msal-react';\r\n"],"mappings":"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","names":["jsx","useMsal","useAccount"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chemmangat/msal-next",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Fully configurable MSAL authentication package for Next.js App Router",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -44,8 +44,8 @@
44
44
  "url": "https://github.com/chemmangat/msal-next/issues"
45
45
  },
46
46
  "peerDependencies": {
47
- "@azure/msal-browser": "^3.11.0",
48
- "@azure/msal-react": "^2.0.0",
47
+ "@azure/msal-browser": "^3.11.0 || ^4.0.0",
48
+ "@azure/msal-react": "^2.0.0 || ^3.0.0",
49
49
  "next": ">=14.0.0",
50
50
  "react": ">=18.0.0",
51
51
  "react-dom": ">=18.0.0"