@chemmangat/msal-next 1.0.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/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # @chemmangat/msal-next
2
+
3
+ Fully configurable MSAL (Microsoft Authentication Library) package for Next.js App Router with TypeScript support.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ```bash
8
+ npm install @chemmangat/msal-next @azure/msal-browser @azure/msal-react
9
+ ```
10
+
11
+ ```tsx
12
+ // app/layout.tsx
13
+ import { MsalAuthProvider } from '@chemmangat/msal-next';
14
+
15
+ export default function RootLayout({ children }) {
16
+ return (
17
+ <html>
18
+ <body>
19
+ <MsalAuthProvider clientId="your-client-id">
20
+ {children}
21
+ </MsalAuthProvider>
22
+ </body>
23
+ </html>
24
+ );
25
+ }
26
+ ```
27
+
28
+ ```tsx
29
+ // app/page.tsx
30
+ 'use client';
31
+ import { useMsalAuth } from '@chemmangat/msal-next';
32
+
33
+ export default function Home() {
34
+ const { isAuthenticated, loginPopup } = useMsalAuth();
35
+
36
+ if (!isAuthenticated) {
37
+ return <button onClick={() => loginPopup()}>Sign In</button>;
38
+ }
39
+
40
+ return <div>Welcome!</div>;
41
+ }
42
+ ```
43
+
44
+ ## 📚 Documentation
45
+
46
+ Visit [https://msal-next.chemmangat.dev](https://msal-next.chemmangat.dev) for full documentation.
47
+
48
+ ## ✨ Features
49
+
50
+ - ✅ Next.js 14+ App Router support
51
+ - ✅ TypeScript with full type definitions
52
+ - ✅ Multi-tenant and single-tenant authentication
53
+ - ✅ Popup and redirect authentication flows
54
+ - ✅ Automatic token acquisition with silent refresh
55
+ - ✅ Zero configuration for simple use cases
56
+ - ✅ Highly configurable when needed
57
+
58
+ ## 📖 API
59
+
60
+ ### MsalAuthProvider
61
+
62
+ ```tsx
63
+ <MsalAuthProvider
64
+ clientId="required"
65
+ tenantId="optional"
66
+ authorityType="common" // 'common' | 'organizations' | 'consumers' | 'tenant'
67
+ scopes={['User.Read']}
68
+ cacheLocation="sessionStorage"
69
+ enableLogging={false}
70
+ loadingComponent={<div>Loading...</div>}
71
+ >
72
+ {children}
73
+ </MsalAuthProvider>
74
+ ```
75
+
76
+ ### useMsalAuth Hook
77
+
78
+ ```tsx
79
+ const {
80
+ isAuthenticated,
81
+ account,
82
+ accounts,
83
+ inProgress,
84
+ loginPopup,
85
+ loginRedirect,
86
+ logoutPopup,
87
+ logoutRedirect,
88
+ acquireToken,
89
+ acquireTokenSilent,
90
+ acquireTokenPopup,
91
+ acquireTokenRedirect,
92
+ } = useMsalAuth();
93
+ ```
94
+
95
+ ## 🔗 Links
96
+
97
+ - [Documentation](https://msal-next.chemmangat.dev)
98
+ - [GitHub](https://github.com/chemmangat/msal-next)
99
+ - [npm](https://www.npmjs.com/package/@chemmangat/msal-next)
100
+ - [Examples](https://github.com/chemmangat/msal-next/tree/main/example)
101
+
102
+ ## 📄 License
103
+
104
+ MIT © Chemmangat
@@ -0,0 +1,126 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { Configuration, LogLevel, AccountInfo } from '@azure/msal-browser';
3
+ import { ReactNode } from 'react';
4
+ export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
5
+
6
+ interface MsalAuthConfig {
7
+ /**
8
+ * Azure AD Application (client) ID
9
+ */
10
+ clientId: string;
11
+ /**
12
+ * Azure AD Directory (tenant) ID (optional for multi-tenant)
13
+ */
14
+ tenantId?: string;
15
+ /**
16
+ * Authority type: 'common' for multi-tenant, 'organizations', 'consumers', or 'tenant' for single-tenant
17
+ * @default 'common'
18
+ */
19
+ authorityType?: 'common' | 'organizations' | 'consumers' | 'tenant';
20
+ /**
21
+ * Redirect URI after authentication
22
+ * @default window.location.origin
23
+ */
24
+ redirectUri?: string;
25
+ /**
26
+ * Post logout redirect URI
27
+ * @default redirectUri
28
+ */
29
+ postLogoutRedirectUri?: string;
30
+ /**
31
+ * Default scopes for authentication
32
+ * @default ['User.Read']
33
+ */
34
+ scopes?: string[];
35
+ /**
36
+ * Cache location: 'sessionStorage', 'localStorage', or 'memoryStorage'
37
+ * @default 'sessionStorage'
38
+ */
39
+ cacheLocation?: 'sessionStorage' | 'localStorage' | 'memoryStorage';
40
+ /**
41
+ * Store auth state in cookie (for IE11/Edge legacy)
42
+ * @default false
43
+ */
44
+ storeAuthStateInCookie?: boolean;
45
+ /**
46
+ * Navigate to login request URL after authentication
47
+ * @default true
48
+ */
49
+ navigateToLoginRequestUrl?: boolean;
50
+ /**
51
+ * Custom MSAL configuration (overrides all other options)
52
+ */
53
+ msalConfig?: Configuration;
54
+ /**
55
+ * Enable debug logging
56
+ * @default false
57
+ */
58
+ enableLogging?: boolean;
59
+ /**
60
+ * Custom logger callback
61
+ */
62
+ loggerCallback?: (level: LogLevel, message: string, containsPii: boolean) => void;
63
+ /**
64
+ * Loading component to show while MSAL initializes
65
+ */
66
+ loadingComponent?: ReactNode;
67
+ }
68
+ interface MsalAuthProviderProps extends MsalAuthConfig {
69
+ children: ReactNode;
70
+ }
71
+
72
+ declare function MsalAuthProvider({ children, loadingComponent, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
73
+
74
+ interface UseMsalAuthReturn {
75
+ /**
76
+ * Current authenticated account
77
+ */
78
+ account: AccountInfo | null;
79
+ /**
80
+ * All accounts in the cache
81
+ */
82
+ accounts: AccountInfo[];
83
+ /**
84
+ * Whether user is authenticated
85
+ */
86
+ isAuthenticated: boolean;
87
+ /**
88
+ * Whether MSAL is currently performing an interaction
89
+ */
90
+ inProgress: boolean;
91
+ /**
92
+ * Login using popup
93
+ */
94
+ loginPopup: (scopes?: string[]) => Promise<void>;
95
+ /**
96
+ * Login using redirect
97
+ */
98
+ loginRedirect: (scopes?: string[]) => Promise<void>;
99
+ /**
100
+ * Logout using popup
101
+ */
102
+ logoutPopup: () => Promise<void>;
103
+ /**
104
+ * Logout using redirect
105
+ */
106
+ logoutRedirect: () => Promise<void>;
107
+ /**
108
+ * Acquire access token silently (with fallback to popup)
109
+ */
110
+ acquireToken: (scopes: string[]) => Promise<string>;
111
+ /**
112
+ * Acquire access token silently only (no fallback)
113
+ */
114
+ acquireTokenSilent: (scopes: string[]) => Promise<string>;
115
+ /**
116
+ * Acquire access token using popup
117
+ */
118
+ acquireTokenPopup: (scopes: string[]) => Promise<string>;
119
+ /**
120
+ * Acquire access token using redirect
121
+ */
122
+ acquireTokenRedirect: (scopes: string[]) => Promise<void>;
123
+ }
124
+ declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
125
+
126
+ export { type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, useMsalAuth };
@@ -0,0 +1,126 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { Configuration, LogLevel, AccountInfo } from '@azure/msal-browser';
3
+ import { ReactNode } from 'react';
4
+ export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
5
+
6
+ interface MsalAuthConfig {
7
+ /**
8
+ * Azure AD Application (client) ID
9
+ */
10
+ clientId: string;
11
+ /**
12
+ * Azure AD Directory (tenant) ID (optional for multi-tenant)
13
+ */
14
+ tenantId?: string;
15
+ /**
16
+ * Authority type: 'common' for multi-tenant, 'organizations', 'consumers', or 'tenant' for single-tenant
17
+ * @default 'common'
18
+ */
19
+ authorityType?: 'common' | 'organizations' | 'consumers' | 'tenant';
20
+ /**
21
+ * Redirect URI after authentication
22
+ * @default window.location.origin
23
+ */
24
+ redirectUri?: string;
25
+ /**
26
+ * Post logout redirect URI
27
+ * @default redirectUri
28
+ */
29
+ postLogoutRedirectUri?: string;
30
+ /**
31
+ * Default scopes for authentication
32
+ * @default ['User.Read']
33
+ */
34
+ scopes?: string[];
35
+ /**
36
+ * Cache location: 'sessionStorage', 'localStorage', or 'memoryStorage'
37
+ * @default 'sessionStorage'
38
+ */
39
+ cacheLocation?: 'sessionStorage' | 'localStorage' | 'memoryStorage';
40
+ /**
41
+ * Store auth state in cookie (for IE11/Edge legacy)
42
+ * @default false
43
+ */
44
+ storeAuthStateInCookie?: boolean;
45
+ /**
46
+ * Navigate to login request URL after authentication
47
+ * @default true
48
+ */
49
+ navigateToLoginRequestUrl?: boolean;
50
+ /**
51
+ * Custom MSAL configuration (overrides all other options)
52
+ */
53
+ msalConfig?: Configuration;
54
+ /**
55
+ * Enable debug logging
56
+ * @default false
57
+ */
58
+ enableLogging?: boolean;
59
+ /**
60
+ * Custom logger callback
61
+ */
62
+ loggerCallback?: (level: LogLevel, message: string, containsPii: boolean) => void;
63
+ /**
64
+ * Loading component to show while MSAL initializes
65
+ */
66
+ loadingComponent?: ReactNode;
67
+ }
68
+ interface MsalAuthProviderProps extends MsalAuthConfig {
69
+ children: ReactNode;
70
+ }
71
+
72
+ declare function MsalAuthProvider({ children, loadingComponent, ...config }: MsalAuthProviderProps): react_jsx_runtime.JSX.Element;
73
+
74
+ interface UseMsalAuthReturn {
75
+ /**
76
+ * Current authenticated account
77
+ */
78
+ account: AccountInfo | null;
79
+ /**
80
+ * All accounts in the cache
81
+ */
82
+ accounts: AccountInfo[];
83
+ /**
84
+ * Whether user is authenticated
85
+ */
86
+ isAuthenticated: boolean;
87
+ /**
88
+ * Whether MSAL is currently performing an interaction
89
+ */
90
+ inProgress: boolean;
91
+ /**
92
+ * Login using popup
93
+ */
94
+ loginPopup: (scopes?: string[]) => Promise<void>;
95
+ /**
96
+ * Login using redirect
97
+ */
98
+ loginRedirect: (scopes?: string[]) => Promise<void>;
99
+ /**
100
+ * Logout using popup
101
+ */
102
+ logoutPopup: () => Promise<void>;
103
+ /**
104
+ * Logout using redirect
105
+ */
106
+ logoutRedirect: () => Promise<void>;
107
+ /**
108
+ * Acquire access token silently (with fallback to popup)
109
+ */
110
+ acquireToken: (scopes: string[]) => Promise<string>;
111
+ /**
112
+ * Acquire access token silently only (no fallback)
113
+ */
114
+ acquireTokenSilent: (scopes: string[]) => Promise<string>;
115
+ /**
116
+ * Acquire access token using popup
117
+ */
118
+ acquireTokenPopup: (scopes: string[]) => Promise<string>;
119
+ /**
120
+ * Acquire access token using redirect
121
+ */
122
+ acquireTokenRedirect: (scopes: string[]) => Promise<void>;
123
+ }
124
+ declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
125
+
126
+ export { type MsalAuthConfig, MsalAuthProvider, type MsalAuthProviderProps, useMsalAuth };
package/dist/index.js ADDED
@@ -0,0 +1,303 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ MsalAuthProvider: () => MsalAuthProvider,
25
+ useAccount: () => import_msal_react3.useAccount,
26
+ useIsAuthenticated: () => import_msal_react3.useIsAuthenticated,
27
+ useMsal: () => import_msal_react3.useMsal,
28
+ useMsalAuth: () => useMsalAuth
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/components/MsalAuthProvider.tsx
33
+ var import_msal_react = require("@azure/msal-react");
34
+ var import_msal_browser2 = require("@azure/msal-browser");
35
+ var import_react = require("react");
36
+
37
+ // src/utils/createMsalConfig.ts
38
+ var import_msal_browser = require("@azure/msal-browser");
39
+ function createMsalConfig(config) {
40
+ if (config.msalConfig) {
41
+ return config.msalConfig;
42
+ }
43
+ const {
44
+ clientId,
45
+ tenantId,
46
+ authorityType = "common",
47
+ redirectUri,
48
+ postLogoutRedirectUri,
49
+ cacheLocation = "sessionStorage",
50
+ storeAuthStateInCookie = false,
51
+ navigateToLoginRequestUrl = true,
52
+ enableLogging = false,
53
+ loggerCallback
54
+ } = config;
55
+ if (!clientId) {
56
+ throw new Error("@chemmangat/msal-next: clientId is required");
57
+ }
58
+ const getAuthority = () => {
59
+ if (authorityType === "tenant") {
60
+ if (!tenantId) {
61
+ throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');
62
+ }
63
+ return `https://login.microsoftonline.com/${tenantId}`;
64
+ }
65
+ return `https://login.microsoftonline.com/${authorityType}`;
66
+ };
67
+ const defaultRedirectUri = typeof window !== "undefined" ? window.location.origin : "http://localhost:3000";
68
+ const finalRedirectUri = redirectUri || defaultRedirectUri;
69
+ const msalConfig = {
70
+ auth: {
71
+ clientId,
72
+ authority: getAuthority(),
73
+ redirectUri: finalRedirectUri,
74
+ postLogoutRedirectUri: postLogoutRedirectUri || finalRedirectUri,
75
+ navigateToLoginRequestUrl
76
+ },
77
+ cache: {
78
+ cacheLocation,
79
+ storeAuthStateInCookie
80
+ },
81
+ system: {
82
+ loggerOptions: {
83
+ loggerCallback: loggerCallback || ((level, message, containsPii) => {
84
+ if (containsPii || !enableLogging) return;
85
+ switch (level) {
86
+ case import_msal_browser.LogLevel.Error:
87
+ console.error("[MSAL]", message);
88
+ break;
89
+ case import_msal_browser.LogLevel.Warning:
90
+ console.warn("[MSAL]", message);
91
+ break;
92
+ case import_msal_browser.LogLevel.Info:
93
+ console.info("[MSAL]", message);
94
+ break;
95
+ case import_msal_browser.LogLevel.Verbose:
96
+ console.debug("[MSAL]", message);
97
+ break;
98
+ }
99
+ }),
100
+ logLevel: enableLogging ? import_msal_browser.LogLevel.Verbose : import_msal_browser.LogLevel.Error
101
+ }
102
+ }
103
+ };
104
+ return msalConfig;
105
+ }
106
+
107
+ // src/components/MsalAuthProvider.tsx
108
+ var import_jsx_runtime = require("react/jsx-runtime");
109
+ function MsalAuthProvider({ children, loadingComponent, ...config }) {
110
+ const [msalInstance, setMsalInstance] = (0, import_react.useState)(null);
111
+ const instanceRef = (0, import_react.useRef)(null);
112
+ (0, import_react.useEffect)(() => {
113
+ if (instanceRef.current) {
114
+ return;
115
+ }
116
+ const initializeMsal = async () => {
117
+ try {
118
+ const msalConfig = createMsalConfig(config);
119
+ const instance = new import_msal_browser2.PublicClientApplication(msalConfig);
120
+ await instance.initialize();
121
+ const response = await instance.handleRedirectPromise();
122
+ if (response) {
123
+ console.log("[MSAL] Redirect authentication successful");
124
+ }
125
+ instance.addEventCallback((event) => {
126
+ if (event.eventType === import_msal_browser2.EventType.LOGIN_SUCCESS) {
127
+ const payload = event.payload;
128
+ console.log("[MSAL] Login successful:", payload.account?.username);
129
+ }
130
+ if (event.eventType === import_msal_browser2.EventType.LOGIN_FAILURE) {
131
+ console.error("[MSAL] Login failed:", event.error);
132
+ }
133
+ if (event.eventType === import_msal_browser2.EventType.LOGOUT_SUCCESS) {
134
+ console.log("[MSAL] Logout successful");
135
+ }
136
+ });
137
+ instanceRef.current = instance;
138
+ setMsalInstance(instance);
139
+ } catch (error) {
140
+ console.error("[MSAL] Initialization failed:", error);
141
+ throw error;
142
+ }
143
+ };
144
+ initializeMsal();
145
+ }, []);
146
+ if (!msalInstance) {
147
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
148
+ }
149
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_msal_react.MsalProvider, { instance: msalInstance, children });
150
+ }
151
+
152
+ // src/hooks/useMsalAuth.ts
153
+ var import_msal_react2 = require("@azure/msal-react");
154
+ var import_msal_browser3 = require("@azure/msal-browser");
155
+ var import_react2 = require("react");
156
+ function useMsalAuth(defaultScopes = ["User.Read"]) {
157
+ const { instance, accounts, inProgress } = (0, import_msal_react2.useMsal)();
158
+ const account = (0, import_msal_react2.useAccount)(accounts[0] || null);
159
+ const isAuthenticated = (0, import_react2.useMemo)(() => accounts.length > 0, [accounts]);
160
+ const loginPopup = (0, import_react2.useCallback)(
161
+ async (scopes = defaultScopes) => {
162
+ try {
163
+ const request = {
164
+ scopes,
165
+ prompt: "select_account"
166
+ };
167
+ await instance.loginPopup(request);
168
+ } catch (error) {
169
+ console.error("[MSAL] Login popup failed:", error);
170
+ throw error;
171
+ }
172
+ },
173
+ [instance, defaultScopes]
174
+ );
175
+ const loginRedirect = (0, import_react2.useCallback)(
176
+ async (scopes = defaultScopes) => {
177
+ try {
178
+ const request = {
179
+ scopes,
180
+ prompt: "select_account"
181
+ };
182
+ await instance.loginRedirect(request);
183
+ } catch (error) {
184
+ console.error("[MSAL] Login redirect failed:", error);
185
+ throw error;
186
+ }
187
+ },
188
+ [instance, defaultScopes]
189
+ );
190
+ const logoutPopup = (0, import_react2.useCallback)(async () => {
191
+ try {
192
+ await instance.logoutPopup({
193
+ account: account || void 0
194
+ });
195
+ } catch (error) {
196
+ console.error("[MSAL] Logout popup failed:", error);
197
+ throw error;
198
+ }
199
+ }, [instance, account]);
200
+ const logoutRedirect = (0, import_react2.useCallback)(async () => {
201
+ try {
202
+ await instance.logoutRedirect({
203
+ account: account || void 0
204
+ });
205
+ } catch (error) {
206
+ console.error("[MSAL] Logout redirect failed:", error);
207
+ throw error;
208
+ }
209
+ }, [instance, account]);
210
+ const acquireTokenSilent = (0, import_react2.useCallback)(
211
+ async (scopes = defaultScopes) => {
212
+ if (!account) {
213
+ throw new Error("[MSAL] No active account. Please login first.");
214
+ }
215
+ try {
216
+ const request = {
217
+ scopes,
218
+ account
219
+ };
220
+ const response = await instance.acquireTokenSilent(request);
221
+ return response.accessToken;
222
+ } catch (error) {
223
+ console.error("[MSAL] Silent token acquisition failed:", error);
224
+ throw error;
225
+ }
226
+ },
227
+ [instance, account, defaultScopes]
228
+ );
229
+ const acquireTokenPopup = (0, import_react2.useCallback)(
230
+ async (scopes = defaultScopes) => {
231
+ if (!account) {
232
+ throw new Error("[MSAL] No active account. Please login first.");
233
+ }
234
+ try {
235
+ const request = {
236
+ scopes,
237
+ account
238
+ };
239
+ const response = await instance.acquireTokenPopup(request);
240
+ return response.accessToken;
241
+ } catch (error) {
242
+ console.error("[MSAL] Token popup acquisition failed:", error);
243
+ throw error;
244
+ }
245
+ },
246
+ [instance, account, defaultScopes]
247
+ );
248
+ const acquireTokenRedirect = (0, import_react2.useCallback)(
249
+ async (scopes = defaultScopes) => {
250
+ if (!account) {
251
+ throw new Error("[MSAL] No active account. Please login first.");
252
+ }
253
+ try {
254
+ const request = {
255
+ scopes,
256
+ account
257
+ };
258
+ await instance.acquireTokenRedirect(request);
259
+ } catch (error) {
260
+ console.error("[MSAL] Token redirect acquisition failed:", error);
261
+ throw error;
262
+ }
263
+ },
264
+ [instance, account, defaultScopes]
265
+ );
266
+ const acquireToken = (0, import_react2.useCallback)(
267
+ async (scopes = defaultScopes) => {
268
+ try {
269
+ return await acquireTokenSilent(scopes);
270
+ } catch (error) {
271
+ console.warn("[MSAL] Silent token acquisition failed, falling back to popup");
272
+ return await acquireTokenPopup(scopes);
273
+ }
274
+ },
275
+ [acquireTokenSilent, acquireTokenPopup, defaultScopes]
276
+ );
277
+ return {
278
+ account,
279
+ accounts,
280
+ isAuthenticated,
281
+ inProgress: inProgress !== import_msal_browser3.InteractionStatus.None,
282
+ loginPopup,
283
+ loginRedirect,
284
+ logoutPopup,
285
+ logoutRedirect,
286
+ acquireToken,
287
+ acquireTokenSilent,
288
+ acquireTokenPopup,
289
+ acquireTokenRedirect
290
+ };
291
+ }
292
+
293
+ // src/index.ts
294
+ var import_msal_react3 = require("@azure/msal-react");
295
+ // Annotate the CommonJS export names for ESM import in node:
296
+ 0 && (module.exports = {
297
+ MsalAuthProvider,
298
+ useAccount,
299
+ useIsAuthenticated,
300
+ useMsal,
301
+ useMsalAuth
302
+ });
303
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/components/MsalAuthProvider.tsx","../src/utils/createMsalConfig.ts","../src/hooks/useMsalAuth.ts"],"sourcesContent":["export { MsalAuthProvider } from './components/MsalAuthProvider';\r\nexport { useMsalAuth } from './hooks/useMsalAuth';\r\nexport type { MsalAuthConfig, MsalAuthProviderProps } from './types';\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"],"mappings":"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","names":["import_msal_browser","import_msal_react","import_msal_browser","import_react","import_msal_react"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,273 @@
1
+ "use client";
2
+
3
+ // src/components/MsalAuthProvider.tsx
4
+ import { MsalProvider } from "@azure/msal-react";
5
+ import { PublicClientApplication, EventType } from "@azure/msal-browser";
6
+ import { useEffect, useState, useRef } from "react";
7
+
8
+ // src/utils/createMsalConfig.ts
9
+ import { LogLevel } from "@azure/msal-browser";
10
+ function createMsalConfig(config) {
11
+ if (config.msalConfig) {
12
+ return config.msalConfig;
13
+ }
14
+ const {
15
+ clientId,
16
+ tenantId,
17
+ authorityType = "common",
18
+ redirectUri,
19
+ postLogoutRedirectUri,
20
+ cacheLocation = "sessionStorage",
21
+ storeAuthStateInCookie = false,
22
+ navigateToLoginRequestUrl = true,
23
+ enableLogging = false,
24
+ loggerCallback
25
+ } = config;
26
+ if (!clientId) {
27
+ throw new Error("@chemmangat/msal-next: clientId is required");
28
+ }
29
+ const getAuthority = () => {
30
+ if (authorityType === "tenant") {
31
+ if (!tenantId) {
32
+ throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');
33
+ }
34
+ return `https://login.microsoftonline.com/${tenantId}`;
35
+ }
36
+ return `https://login.microsoftonline.com/${authorityType}`;
37
+ };
38
+ const defaultRedirectUri = typeof window !== "undefined" ? window.location.origin : "http://localhost:3000";
39
+ const finalRedirectUri = redirectUri || defaultRedirectUri;
40
+ const msalConfig = {
41
+ auth: {
42
+ clientId,
43
+ authority: getAuthority(),
44
+ redirectUri: finalRedirectUri,
45
+ postLogoutRedirectUri: postLogoutRedirectUri || finalRedirectUri,
46
+ navigateToLoginRequestUrl
47
+ },
48
+ cache: {
49
+ cacheLocation,
50
+ storeAuthStateInCookie
51
+ },
52
+ system: {
53
+ loggerOptions: {
54
+ loggerCallback: loggerCallback || ((level, message, containsPii) => {
55
+ if (containsPii || !enableLogging) return;
56
+ switch (level) {
57
+ case LogLevel.Error:
58
+ console.error("[MSAL]", message);
59
+ break;
60
+ case LogLevel.Warning:
61
+ console.warn("[MSAL]", message);
62
+ break;
63
+ case LogLevel.Info:
64
+ console.info("[MSAL]", message);
65
+ break;
66
+ case LogLevel.Verbose:
67
+ console.debug("[MSAL]", message);
68
+ break;
69
+ }
70
+ }),
71
+ logLevel: enableLogging ? LogLevel.Verbose : LogLevel.Error
72
+ }
73
+ }
74
+ };
75
+ return msalConfig;
76
+ }
77
+
78
+ // src/components/MsalAuthProvider.tsx
79
+ import { Fragment, jsx } from "react/jsx-runtime";
80
+ function MsalAuthProvider({ children, loadingComponent, ...config }) {
81
+ const [msalInstance, setMsalInstance] = useState(null);
82
+ const instanceRef = useRef(null);
83
+ useEffect(() => {
84
+ if (instanceRef.current) {
85
+ return;
86
+ }
87
+ const initializeMsal = async () => {
88
+ try {
89
+ const msalConfig = createMsalConfig(config);
90
+ const instance = new PublicClientApplication(msalConfig);
91
+ await instance.initialize();
92
+ const response = await instance.handleRedirectPromise();
93
+ if (response) {
94
+ console.log("[MSAL] Redirect authentication successful");
95
+ }
96
+ instance.addEventCallback((event) => {
97
+ if (event.eventType === EventType.LOGIN_SUCCESS) {
98
+ const payload = event.payload;
99
+ console.log("[MSAL] Login successful:", payload.account?.username);
100
+ }
101
+ if (event.eventType === EventType.LOGIN_FAILURE) {
102
+ console.error("[MSAL] Login failed:", event.error);
103
+ }
104
+ if (event.eventType === EventType.LOGOUT_SUCCESS) {
105
+ console.log("[MSAL] Logout successful");
106
+ }
107
+ });
108
+ instanceRef.current = instance;
109
+ setMsalInstance(instance);
110
+ } catch (error) {
111
+ console.error("[MSAL] Initialization failed:", error);
112
+ throw error;
113
+ }
114
+ };
115
+ initializeMsal();
116
+ }, []);
117
+ if (!msalInstance) {
118
+ return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { children: "Loading authentication..." }) });
119
+ }
120
+ return /* @__PURE__ */ jsx(MsalProvider, { instance: msalInstance, children });
121
+ }
122
+
123
+ // src/hooks/useMsalAuth.ts
124
+ import { useMsal, useAccount } from "@azure/msal-react";
125
+ import { InteractionStatus } from "@azure/msal-browser";
126
+ import { useCallback, useMemo } from "react";
127
+ function useMsalAuth(defaultScopes = ["User.Read"]) {
128
+ const { instance, accounts, inProgress } = useMsal();
129
+ const account = useAccount(accounts[0] || null);
130
+ const isAuthenticated = useMemo(() => accounts.length > 0, [accounts]);
131
+ const loginPopup = useCallback(
132
+ async (scopes = defaultScopes) => {
133
+ try {
134
+ const request = {
135
+ scopes,
136
+ prompt: "select_account"
137
+ };
138
+ await instance.loginPopup(request);
139
+ } catch (error) {
140
+ console.error("[MSAL] Login popup failed:", error);
141
+ throw error;
142
+ }
143
+ },
144
+ [instance, defaultScopes]
145
+ );
146
+ const loginRedirect = useCallback(
147
+ async (scopes = defaultScopes) => {
148
+ try {
149
+ const request = {
150
+ scopes,
151
+ prompt: "select_account"
152
+ };
153
+ await instance.loginRedirect(request);
154
+ } catch (error) {
155
+ console.error("[MSAL] Login redirect failed:", error);
156
+ throw error;
157
+ }
158
+ },
159
+ [instance, defaultScopes]
160
+ );
161
+ const logoutPopup = useCallback(async () => {
162
+ try {
163
+ await instance.logoutPopup({
164
+ account: account || void 0
165
+ });
166
+ } catch (error) {
167
+ console.error("[MSAL] Logout popup failed:", error);
168
+ throw error;
169
+ }
170
+ }, [instance, account]);
171
+ const logoutRedirect = useCallback(async () => {
172
+ try {
173
+ await instance.logoutRedirect({
174
+ account: account || void 0
175
+ });
176
+ } catch (error) {
177
+ console.error("[MSAL] Logout redirect failed:", error);
178
+ throw error;
179
+ }
180
+ }, [instance, account]);
181
+ const acquireTokenSilent = useCallback(
182
+ async (scopes = defaultScopes) => {
183
+ if (!account) {
184
+ throw new Error("[MSAL] No active account. Please login first.");
185
+ }
186
+ try {
187
+ const request = {
188
+ scopes,
189
+ account
190
+ };
191
+ const response = await instance.acquireTokenSilent(request);
192
+ return response.accessToken;
193
+ } catch (error) {
194
+ console.error("[MSAL] Silent token acquisition failed:", error);
195
+ throw error;
196
+ }
197
+ },
198
+ [instance, account, defaultScopes]
199
+ );
200
+ const acquireTokenPopup = useCallback(
201
+ async (scopes = defaultScopes) => {
202
+ if (!account) {
203
+ throw new Error("[MSAL] No active account. Please login first.");
204
+ }
205
+ try {
206
+ const request = {
207
+ scopes,
208
+ account
209
+ };
210
+ const response = await instance.acquireTokenPopup(request);
211
+ return response.accessToken;
212
+ } catch (error) {
213
+ console.error("[MSAL] Token popup acquisition failed:", error);
214
+ throw error;
215
+ }
216
+ },
217
+ [instance, account, defaultScopes]
218
+ );
219
+ const acquireTokenRedirect = useCallback(
220
+ async (scopes = defaultScopes) => {
221
+ if (!account) {
222
+ throw new Error("[MSAL] No active account. Please login first.");
223
+ }
224
+ try {
225
+ const request = {
226
+ scopes,
227
+ account
228
+ };
229
+ await instance.acquireTokenRedirect(request);
230
+ } catch (error) {
231
+ console.error("[MSAL] Token redirect acquisition failed:", error);
232
+ throw error;
233
+ }
234
+ },
235
+ [instance, account, defaultScopes]
236
+ );
237
+ const acquireToken = useCallback(
238
+ async (scopes = defaultScopes) => {
239
+ try {
240
+ return await acquireTokenSilent(scopes);
241
+ } catch (error) {
242
+ console.warn("[MSAL] Silent token acquisition failed, falling back to popup");
243
+ return await acquireTokenPopup(scopes);
244
+ }
245
+ },
246
+ [acquireTokenSilent, acquireTokenPopup, defaultScopes]
247
+ );
248
+ return {
249
+ account,
250
+ accounts,
251
+ isAuthenticated,
252
+ inProgress: inProgress !== InteractionStatus.None,
253
+ loginPopup,
254
+ loginRedirect,
255
+ logoutPopup,
256
+ logoutRedirect,
257
+ acquireToken,
258
+ acquireTokenSilent,
259
+ acquireTokenPopup,
260
+ acquireTokenRedirect
261
+ };
262
+ }
263
+
264
+ // src/index.ts
265
+ import { useMsal as useMsal2, useIsAuthenticated, useAccount as useAccount2 } from "@azure/msal-react";
266
+ export {
267
+ MsalAuthProvider,
268
+ useAccount2 as useAccount,
269
+ useIsAuthenticated,
270
+ useMsal2 as useMsal,
271
+ useMsalAuth
272
+ };
273
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/MsalAuthProvider.tsx","../src/utils/createMsalConfig.ts","../src/hooks/useMsalAuth.ts","../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","export { MsalAuthProvider } from './components/MsalAuthProvider';\r\nexport { useMsalAuth } from './hooks/useMsalAuth';\r\nexport type { MsalAuthConfig, MsalAuthProviderProps } from './types';\r\n\r\n// Re-export useful MSAL hooks\r\nexport { useMsal, useIsAuthenticated, useAccount } from '@azure/msal-react';\r\n"],"mappings":";;;AAEA,SAAS,oBAAoB;AAC7B,SAAS,yBAAyB,iBAAqD;AACvF,SAAS,WAAW,UAAU,cAAc;;;ACJ5C,SAAwB,gBAAgB;AAGjC,SAAS,iBAAiB,QAAuC;AAEtE,MAAI,OAAO,YAAY;AACrB,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,yBAAyB;AAAA,IACzB,4BAA4B;AAAA,IAC5B,gBAAgB;AAAA,IAChB;AAAA,EACF,IAAI;AAEJ,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAGA,QAAM,eAAe,MAAc;AACjC,QAAI,kBAAkB,UAAU;AAC9B,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,4EAA4E;AAAA,MAC9F;AACA,aAAO,qCAAqC,QAAQ;AAAA,IACtD;AACA,WAAO,qCAAqC,aAAa;AAAA,EAC3D;AAGA,QAAM,qBAAqB,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AACpF,QAAM,mBAAmB,eAAe;AAExC,QAAM,aAA4B;AAAA,IAChC,MAAM;AAAA,MACJ;AAAA,MACA,WAAW,aAAa;AAAA,MACxB,aAAa;AAAA,MACb,uBAAuB,yBAAyB;AAAA,MAChD;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,eAAe;AAAA,QACb,gBAAgB,mBAAmB,CAAC,OAAiB,SAAiB,gBAAyB;AAC7F,cAAI,eAAe,CAAC,cAAe;AAEnC,kBAAQ,OAAO;AAAA,YACb,KAAK,SAAS;AACZ,sBAAQ,MAAM,UAAU,OAAO;AAC/B;AAAA,YACF,KAAK,SAAS;AACZ,sBAAQ,KAAK,UAAU,OAAO;AAC9B;AAAA,YACF,KAAK,SAAS;AACZ,sBAAQ,KAAK,UAAU,OAAO;AAC9B;AAAA,YACF,KAAK,SAAS;AACZ,sBAAQ,MAAM,UAAU,OAAO;AAC/B;AAAA,UACJ;AAAA,QACF;AAAA,QACA,UAAU,gBAAgB,SAAS,UAAU,SAAS;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADpBW,mBAAuB,WAAvB;AAnDJ,SAAS,iBAAiB,EAAE,UAAU,kBAAkB,GAAG,OAAO,GAA0B;AACjG,QAAM,CAAC,cAAc,eAAe,IAAI,SAAyC,IAAI;AACrF,QAAM,cAAc,OAAuC,IAAI;AAE/D,YAAU,MAAM;AAEd,QAAI,YAAY,SAAS;AACvB;AAAA,IACF;AAEA,UAAM,iBAAiB,YAAY;AACjC,UAAI;AACF,cAAM,aAAa,iBAAiB,MAAM;AAC1C,cAAM,WAAW,IAAI,wBAAwB,UAAU;AAEvD,cAAM,SAAS,WAAW;AAG1B,cAAM,WAAW,MAAM,SAAS,sBAAsB;AACtD,YAAI,UAAU;AACZ,kBAAQ,IAAI,2CAA2C;AAAA,QACzD;AAGA,iBAAS,iBAAiB,CAAC,UAAwB;AACjD,cAAI,MAAM,cAAc,UAAU,eAAe;AAC/C,kBAAM,UAAU,MAAM;AACtB,oBAAQ,IAAI,4BAA4B,QAAQ,SAAS,QAAQ;AAAA,UACnE;AAEA,cAAI,MAAM,cAAc,UAAU,eAAe;AAC/C,oBAAQ,MAAM,wBAAwB,MAAM,KAAK;AAAA,UACnD;AAEA,cAAI,MAAM,cAAc,UAAU,gBAAgB;AAChD,oBAAQ,IAAI,0BAA0B;AAAA,UACxC;AAAA,QACF,CAAC;AAED,oBAAY,UAAU;AACtB,wBAAgB,QAAQ;AAAA,MAC1B,SAAS,OAAO;AACd,gBAAQ,MAAM,iCAAiC,KAAK;AACpD,cAAM;AAAA,MACR;AAAA,IACF;AAEA,mBAAe;AAAA,EACjB,GAAG,CAAC,CAAC;AAEL,MAAI,CAAC,cAAc;AACjB,WAAO,gCAAG,8BAAoB,oBAAC,SAAI,uCAAyB,GAAO;AAAA,EACrE;AAEA,SAAO,oBAAC,gBAAa,UAAU,cAAe,UAAS;AACzD;;;AE7DA,SAAS,SAAS,kBAAkB;AACpC,SAAsB,yBAAuE;AAC7F,SAAS,aAAa,eAAe;AAgE9B,SAAS,YAAY,gBAA0B,CAAC,WAAW,GAAsB;AACtF,QAAM,EAAE,UAAU,UAAU,WAAW,IAAI,QAAQ;AACnD,QAAM,UAAU,WAAW,SAAS,CAAC,KAAK,IAAI;AAE9C,QAAM,kBAAkB,QAAQ,MAAM,SAAS,SAAS,GAAG,CAAC,QAAQ,CAAC;AAErE,QAAM,aAAa;AAAA,IACjB,OAAO,SAAmB,kBAAkB;AAC1C,UAAI;AACF,cAAM,UAAwB;AAAA,UAC5B;AAAA,UACA,QAAQ;AAAA,QACV;AACA,cAAM,SAAS,WAAW,OAAO;AAAA,MACnC,SAAS,OAAO;AACd,gBAAQ,MAAM,8BAA8B,KAAK;AACjD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,aAAa;AAAA,EAC1B;AAEA,QAAM,gBAAgB;AAAA,IACpB,OAAO,SAAmB,kBAAkB;AAC1C,UAAI;AACF,cAAM,UAA2B;AAAA,UAC/B;AAAA,UACA,QAAQ;AAAA,QACV;AACA,cAAM,SAAS,cAAc,OAAO;AAAA,MACtC,SAAS,OAAO;AACd,gBAAQ,MAAM,iCAAiC,KAAK;AACpD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,aAAa;AAAA,EAC1B;AAEA,QAAM,cAAc,YAAY,YAAY;AAC1C,QAAI;AACF,YAAM,SAAS,YAAY;AAAA,QACzB,SAAS,WAAW;AAAA,MACtB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA+B,KAAK;AAClD,YAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,UAAU,OAAO,CAAC;AAEtB,QAAM,iBAAiB,YAAY,YAAY;AAC7C,QAAI;AACF,YAAM,SAAS,eAAe;AAAA,QAC5B,SAAS,WAAW;AAAA,MACtB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AACrD,YAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,UAAU,OAAO,CAAC;AAEtB,QAAM,qBAAqB;AAAA,IACzB,OAAO,SAAmB,kBAAmC;AAC3D,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AAEA,UAAI;AACF,cAAM,UAAyB;AAAA,UAC7B;AAAA,UACA;AAAA,QACF;AACA,cAAM,WAAW,MAAM,SAAS,mBAAmB,OAAO;AAC1D,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,gBAAQ,MAAM,2CAA2C,KAAK;AAC9D,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,SAAS,aAAa;AAAA,EACnC;AAEA,QAAM,oBAAoB;AAAA,IACxB,OAAO,SAAmB,kBAAmC;AAC3D,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AAEA,UAAI;AACF,cAAM,UAAwB;AAAA,UAC5B;AAAA,UACA;AAAA,QACF;AACA,cAAM,WAAW,MAAM,SAAS,kBAAkB,OAAO;AACzD,eAAO,SAAS;AAAA,MAClB,SAAS,OAAO;AACd,gBAAQ,MAAM,0CAA0C,KAAK;AAC7D,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,SAAS,aAAa;AAAA,EACnC;AAEA,QAAM,uBAAuB;AAAA,IAC3B,OAAO,SAAmB,kBAAiC;AACzD,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AAEA,UAAI;AACF,cAAM,UAA2B;AAAA,UAC/B;AAAA,UACA;AAAA,QACF;AACA,cAAM,SAAS,qBAAqB,OAAO;AAAA,MAC7C,SAAS,OAAO;AACd,gBAAQ,MAAM,6CAA6C,KAAK;AAChE,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,UAAU,SAAS,aAAa;AAAA,EACnC;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO,SAAmB,kBAAmC;AAC3D,UAAI;AACF,eAAO,MAAM,mBAAmB,MAAM;AAAA,MACxC,SAAS,OAAO;AACd,gBAAQ,KAAK,+DAA+D;AAC5E,eAAO,MAAM,kBAAkB,MAAM;AAAA,MACvC;AAAA,IACF;AAAA,IACA,CAAC,oBAAoB,mBAAmB,aAAa;AAAA,EACvD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,eAAe,kBAAkB;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACnNA,SAAS,WAAAA,UAAS,oBAAoB,cAAAC,mBAAkB;","names":["useMsal","useAccount"]}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@chemmangat/msal-next",
3
+ "version": "1.0.0",
4
+ "description": "Fully configurable MSAL authentication package for Next.js App Router",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "dev": "tsup --watch",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "msal",
26
+ "nextjs",
27
+ "authentication",
28
+ "azure-ad",
29
+ "microsoft",
30
+ "oauth",
31
+ "next.js",
32
+ "app-router",
33
+ "typescript"
34
+ ],
35
+ "author": "Chemmangat",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/chemmangat/msal-next.git",
40
+ "directory": "packages/core"
41
+ },
42
+ "homepage": "https://github.com/chemmangat/msal-next#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/chemmangat/msal-next/issues"
45
+ },
46
+ "peerDependencies": {
47
+ "@azure/msal-browser": "^3.11.0",
48
+ "@azure/msal-react": "^2.0.0",
49
+ "next": ">=14.0.0",
50
+ "react": ">=18.0.0",
51
+ "react-dom": ">=18.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@azure/msal-browser": "^3.11.1",
55
+ "@azure/msal-react": "^2.0.15",
56
+ "@types/react": "^18.2.0",
57
+ "react": "^18.2.0",
58
+ "tsup": "^8.0.1",
59
+ "typescript": "^5.3.0"
60
+ }
61
+ }