@chemmangat/msal-next 1.0.0 → 1.2.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 +193 -0
- package/dist/index.d.mts +61 -4
- package/dist/index.d.ts +61 -4
- package/dist/index.js +128 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +126 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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,44 @@ 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
|
+
|
|
96
|
+
### MicrosoftSignInButton
|
|
97
|
+
|
|
98
|
+
Pre-built button component with official Microsoft branding:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
<MicrosoftSignInButton
|
|
102
|
+
variant="dark" // 'dark' | 'light'
|
|
103
|
+
size="medium" // 'small' | 'medium' | 'large'
|
|
104
|
+
text="Sign in with Microsoft"
|
|
105
|
+
useRedirect={false}
|
|
106
|
+
scopes={['User.Read']}
|
|
107
|
+
onSuccess={() => console.log('Success!')}
|
|
108
|
+
onError={(error) => console.error(error)}
|
|
109
|
+
/>
|
|
110
|
+
```
|
|
111
|
+
|
|
76
112
|
### useMsalAuth Hook
|
|
77
113
|
|
|
78
114
|
```tsx
|
|
@@ -89,9 +125,166 @@ const {
|
|
|
89
125
|
acquireTokenSilent,
|
|
90
126
|
acquireTokenPopup,
|
|
91
127
|
acquireTokenRedirect,
|
|
128
|
+
clearSession,
|
|
92
129
|
} = useMsalAuth();
|
|
93
130
|
```
|
|
94
131
|
|
|
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.
|
|
276
|
+
|
|
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
|
+
```
|
|
287
|
+
|
|
95
288
|
## 🔗 Links
|
|
96
289
|
|
|
97
290
|
- [Documentation](https://msal-next.chemmangat.dev)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { Configuration, LogLevel, AccountInfo } from '@azure/msal-browser';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
|
|
3
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
4
4
|
export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
|
|
5
5
|
|
|
6
6
|
interface MsalAuthConfig {
|
|
@@ -64,12 +64,65 @@ 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
|
-
|
|
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;
|
|
82
|
+
|
|
83
|
+
interface MicrosoftSignInButtonProps {
|
|
84
|
+
/**
|
|
85
|
+
* Button text
|
|
86
|
+
* @default 'Sign in with Microsoft'
|
|
87
|
+
*/
|
|
88
|
+
text?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Button variant
|
|
91
|
+
* @default 'dark'
|
|
92
|
+
*/
|
|
93
|
+
variant?: 'dark' | 'light';
|
|
94
|
+
/**
|
|
95
|
+
* Button size
|
|
96
|
+
* @default 'medium'
|
|
97
|
+
*/
|
|
98
|
+
size?: 'small' | 'medium' | 'large';
|
|
99
|
+
/**
|
|
100
|
+
* Use redirect flow instead of popup
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
useRedirect?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Scopes to request
|
|
106
|
+
*/
|
|
107
|
+
scopes?: string[];
|
|
108
|
+
/**
|
|
109
|
+
* Custom className
|
|
110
|
+
*/
|
|
111
|
+
className?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Custom styles
|
|
114
|
+
*/
|
|
115
|
+
style?: CSSProperties;
|
|
116
|
+
/**
|
|
117
|
+
* Callback on successful login
|
|
118
|
+
*/
|
|
119
|
+
onSuccess?: () => void;
|
|
120
|
+
/**
|
|
121
|
+
* Callback on error
|
|
122
|
+
*/
|
|
123
|
+
onError?: (error: Error) => void;
|
|
124
|
+
}
|
|
125
|
+
declare function MicrosoftSignInButton({ text, variant, size, useRedirect, scopes, className, style, onSuccess, onError, }: MicrosoftSignInButtonProps): react_jsx_runtime.JSX.Element;
|
|
73
126
|
|
|
74
127
|
interface UseMsalAuthReturn {
|
|
75
128
|
/**
|
|
@@ -120,7 +173,11 @@ interface UseMsalAuthReturn {
|
|
|
120
173
|
* Acquire access token using redirect
|
|
121
174
|
*/
|
|
122
175
|
acquireTokenRedirect: (scopes: string[]) => Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Clear MSAL session without triggering Microsoft logout
|
|
178
|
+
*/
|
|
179
|
+
clearSession: () => Promise<void>;
|
|
123
180
|
}
|
|
124
181
|
declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
|
|
125
182
|
|
|
126
|
-
export { 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,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { Configuration, LogLevel, AccountInfo } from '@azure/msal-browser';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { Configuration, LogLevel, IPublicClientApplication, PublicClientApplication, AccountInfo } from '@azure/msal-browser';
|
|
3
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
4
4
|
export { useAccount, useIsAuthenticated, useMsal } from '@azure/msal-react';
|
|
5
5
|
|
|
6
6
|
interface MsalAuthConfig {
|
|
@@ -64,12 +64,65 @@ 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
|
-
|
|
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;
|
|
82
|
+
|
|
83
|
+
interface MicrosoftSignInButtonProps {
|
|
84
|
+
/**
|
|
85
|
+
* Button text
|
|
86
|
+
* @default 'Sign in with Microsoft'
|
|
87
|
+
*/
|
|
88
|
+
text?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Button variant
|
|
91
|
+
* @default 'dark'
|
|
92
|
+
*/
|
|
93
|
+
variant?: 'dark' | 'light';
|
|
94
|
+
/**
|
|
95
|
+
* Button size
|
|
96
|
+
* @default 'medium'
|
|
97
|
+
*/
|
|
98
|
+
size?: 'small' | 'medium' | 'large';
|
|
99
|
+
/**
|
|
100
|
+
* Use redirect flow instead of popup
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
useRedirect?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Scopes to request
|
|
106
|
+
*/
|
|
107
|
+
scopes?: string[];
|
|
108
|
+
/**
|
|
109
|
+
* Custom className
|
|
110
|
+
*/
|
|
111
|
+
className?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Custom styles
|
|
114
|
+
*/
|
|
115
|
+
style?: CSSProperties;
|
|
116
|
+
/**
|
|
117
|
+
* Callback on successful login
|
|
118
|
+
*/
|
|
119
|
+
onSuccess?: () => void;
|
|
120
|
+
/**
|
|
121
|
+
* Callback on error
|
|
122
|
+
*/
|
|
123
|
+
onError?: (error: Error) => void;
|
|
124
|
+
}
|
|
125
|
+
declare function MicrosoftSignInButton({ text, variant, size, useRedirect, scopes, className, style, onSuccess, onError, }: MicrosoftSignInButtonProps): react_jsx_runtime.JSX.Element;
|
|
73
126
|
|
|
74
127
|
interface UseMsalAuthReturn {
|
|
75
128
|
/**
|
|
@@ -120,7 +173,11 @@ interface UseMsalAuthReturn {
|
|
|
120
173
|
* Acquire access token using redirect
|
|
121
174
|
*/
|
|
122
175
|
acquireTokenRedirect: (scopes: string[]) => Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Clear MSAL session without triggering Microsoft logout
|
|
178
|
+
*/
|
|
179
|
+
clearSession: () => Promise<void>;
|
|
123
180
|
}
|
|
124
181
|
declare function useMsalAuth(defaultScopes?: string[]): UseMsalAuthReturn;
|
|
125
182
|
|
|
126
|
-
export { 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
|
@@ -21,7 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
MicrosoftSignInButton: () => MicrosoftSignInButton,
|
|
24
25
|
MsalAuthProvider: () => MsalAuthProvider,
|
|
26
|
+
getMsalInstance: () => getMsalInstance,
|
|
25
27
|
useAccount: () => import_msal_react3.useAccount,
|
|
26
28
|
useIsAuthenticated: () => import_msal_react3.useIsAuthenticated,
|
|
27
29
|
useMsal: () => import_msal_react3.useMsal,
|
|
@@ -106,10 +108,17 @@ function createMsalConfig(config) {
|
|
|
106
108
|
|
|
107
109
|
// src/components/MsalAuthProvider.tsx
|
|
108
110
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
109
|
-
|
|
111
|
+
var globalMsalInstance = null;
|
|
112
|
+
function getMsalInstance() {
|
|
113
|
+
return globalMsalInstance;
|
|
114
|
+
}
|
|
115
|
+
function MsalAuthProvider({ children, loadingComponent, onInitialized, ...config }) {
|
|
110
116
|
const [msalInstance, setMsalInstance] = (0, import_react.useState)(null);
|
|
111
117
|
const instanceRef = (0, import_react.useRef)(null);
|
|
112
118
|
(0, import_react.useEffect)(() => {
|
|
119
|
+
if (typeof window === "undefined") {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
113
122
|
if (instanceRef.current) {
|
|
114
123
|
return;
|
|
115
124
|
}
|
|
@@ -119,23 +128,32 @@ function MsalAuthProvider({ children, loadingComponent, ...config }) {
|
|
|
119
128
|
const instance = new import_msal_browser2.PublicClientApplication(msalConfig);
|
|
120
129
|
await instance.initialize();
|
|
121
130
|
const response = await instance.handleRedirectPromise();
|
|
122
|
-
if (response) {
|
|
131
|
+
if (response && config.enableLogging) {
|
|
123
132
|
console.log("[MSAL] Redirect authentication successful");
|
|
124
133
|
}
|
|
134
|
+
const enableLogging = config.enableLogging || false;
|
|
125
135
|
instance.addEventCallback((event) => {
|
|
126
136
|
if (event.eventType === import_msal_browser2.EventType.LOGIN_SUCCESS) {
|
|
127
|
-
|
|
128
|
-
|
|
137
|
+
if (enableLogging) {
|
|
138
|
+
const payload = event.payload;
|
|
139
|
+
console.log("[MSAL] Login successful:", payload.account?.username);
|
|
140
|
+
}
|
|
129
141
|
}
|
|
130
142
|
if (event.eventType === import_msal_browser2.EventType.LOGIN_FAILURE) {
|
|
131
143
|
console.error("[MSAL] Login failed:", event.error);
|
|
132
144
|
}
|
|
133
145
|
if (event.eventType === import_msal_browser2.EventType.LOGOUT_SUCCESS) {
|
|
134
|
-
|
|
146
|
+
if (enableLogging) {
|
|
147
|
+
console.log("[MSAL] Logout successful");
|
|
148
|
+
}
|
|
135
149
|
}
|
|
136
150
|
});
|
|
137
151
|
instanceRef.current = instance;
|
|
152
|
+
globalMsalInstance = instance;
|
|
138
153
|
setMsalInstance(instance);
|
|
154
|
+
if (onInitialized) {
|
|
155
|
+
onInitialized(instance);
|
|
156
|
+
}
|
|
139
157
|
} catch (error) {
|
|
140
158
|
console.error("[MSAL] Initialization failed:", error);
|
|
141
159
|
throw error;
|
|
@@ -143,6 +161,9 @@ function MsalAuthProvider({ children, loadingComponent, ...config }) {
|
|
|
143
161
|
};
|
|
144
162
|
initializeMsal();
|
|
145
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
|
+
}
|
|
146
167
|
if (!msalInstance) {
|
|
147
168
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Loading authentication..." }) });
|
|
148
169
|
}
|
|
@@ -274,6 +295,10 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
274
295
|
},
|
|
275
296
|
[acquireTokenSilent, acquireTokenPopup, defaultScopes]
|
|
276
297
|
);
|
|
298
|
+
const clearSession = (0, import_react2.useCallback)(async () => {
|
|
299
|
+
instance.setActiveAccount(null);
|
|
300
|
+
await instance.clearCache();
|
|
301
|
+
}, [instance]);
|
|
277
302
|
return {
|
|
278
303
|
account,
|
|
279
304
|
accounts,
|
|
@@ -286,15 +311,112 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
286
311
|
acquireToken,
|
|
287
312
|
acquireTokenSilent,
|
|
288
313
|
acquireTokenPopup,
|
|
289
|
-
acquireTokenRedirect
|
|
314
|
+
acquireTokenRedirect,
|
|
315
|
+
clearSession
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/components/MicrosoftSignInButton.tsx
|
|
320
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
321
|
+
function MicrosoftSignInButton({
|
|
322
|
+
text = "Sign in with Microsoft",
|
|
323
|
+
variant = "dark",
|
|
324
|
+
size = "medium",
|
|
325
|
+
useRedirect = false,
|
|
326
|
+
scopes,
|
|
327
|
+
className = "",
|
|
328
|
+
style,
|
|
329
|
+
onSuccess,
|
|
330
|
+
onError
|
|
331
|
+
}) {
|
|
332
|
+
const { loginPopup, loginRedirect, inProgress } = useMsalAuth();
|
|
333
|
+
const handleClick = async () => {
|
|
334
|
+
try {
|
|
335
|
+
if (useRedirect) {
|
|
336
|
+
await loginRedirect(scopes);
|
|
337
|
+
} else {
|
|
338
|
+
await loginPopup(scopes);
|
|
339
|
+
}
|
|
340
|
+
onSuccess?.();
|
|
341
|
+
} catch (error) {
|
|
342
|
+
onError?.(error);
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
const sizeStyles = {
|
|
346
|
+
small: {
|
|
347
|
+
padding: "8px 16px",
|
|
348
|
+
fontSize: "14px",
|
|
349
|
+
height: "36px"
|
|
350
|
+
},
|
|
351
|
+
medium: {
|
|
352
|
+
padding: "10px 20px",
|
|
353
|
+
fontSize: "15px",
|
|
354
|
+
height: "41px"
|
|
355
|
+
},
|
|
356
|
+
large: {
|
|
357
|
+
padding: "12px 24px",
|
|
358
|
+
fontSize: "16px",
|
|
359
|
+
height: "48px"
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
const variantStyles = {
|
|
363
|
+
dark: {
|
|
364
|
+
backgroundColor: "#2F2F2F",
|
|
365
|
+
color: "#FFFFFF",
|
|
366
|
+
border: "1px solid #8C8C8C"
|
|
367
|
+
},
|
|
368
|
+
light: {
|
|
369
|
+
backgroundColor: "#FFFFFF",
|
|
370
|
+
color: "#5E5E5E",
|
|
371
|
+
border: "1px solid #8C8C8C"
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
const baseStyles = {
|
|
375
|
+
display: "inline-flex",
|
|
376
|
+
alignItems: "center",
|
|
377
|
+
justifyContent: "center",
|
|
378
|
+
gap: "12px",
|
|
379
|
+
fontFamily: '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',
|
|
380
|
+
fontWeight: 600,
|
|
381
|
+
borderRadius: "2px",
|
|
382
|
+
cursor: inProgress ? "not-allowed" : "pointer",
|
|
383
|
+
transition: "all 0.2s ease",
|
|
384
|
+
opacity: inProgress ? 0.6 : 1,
|
|
385
|
+
...variantStyles[variant],
|
|
386
|
+
...sizeStyles[size],
|
|
387
|
+
...style
|
|
290
388
|
};
|
|
389
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
390
|
+
"button",
|
|
391
|
+
{
|
|
392
|
+
onClick: handleClick,
|
|
393
|
+
disabled: inProgress,
|
|
394
|
+
className,
|
|
395
|
+
style: baseStyles,
|
|
396
|
+
"aria-label": text,
|
|
397
|
+
children: [
|
|
398
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MicrosoftLogo, {}),
|
|
399
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: text })
|
|
400
|
+
]
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
function MicrosoftLogo() {
|
|
405
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "21", height: "21", viewBox: "0 0 21 21", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
406
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "10", height: "10", fill: "#F25022" }),
|
|
407
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "11", width: "10", height: "10", fill: "#7FBA00" }),
|
|
408
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { y: "11", width: "10", height: "10", fill: "#00A4EF" }),
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "11", y: "11", width: "10", height: "10", fill: "#FFB900" })
|
|
410
|
+
] });
|
|
291
411
|
}
|
|
292
412
|
|
|
293
413
|
// src/index.ts
|
|
294
414
|
var import_msal_react3 = require("@azure/msal-react");
|
|
295
415
|
// Annotate the CommonJS export names for ESM import in node:
|
|
296
416
|
0 && (module.exports = {
|
|
417
|
+
MicrosoftSignInButton,
|
|
297
418
|
MsalAuthProvider,
|
|
419
|
+
getMsalInstance,
|
|
298
420
|
useAccount,
|
|
299
421
|
useIsAuthenticated,
|
|
300
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"],"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"]}
|
|
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
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
-
|
|
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,14 +280,111 @@ function useMsalAuth(defaultScopes = ["User.Read"]) {
|
|
|
257
280
|
acquireToken,
|
|
258
281
|
acquireTokenSilent,
|
|
259
282
|
acquireTokenPopup,
|
|
260
|
-
acquireTokenRedirect
|
|
283
|
+
acquireTokenRedirect,
|
|
284
|
+
clearSession
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/components/MicrosoftSignInButton.tsx
|
|
289
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
290
|
+
function MicrosoftSignInButton({
|
|
291
|
+
text = "Sign in with Microsoft",
|
|
292
|
+
variant = "dark",
|
|
293
|
+
size = "medium",
|
|
294
|
+
useRedirect = false,
|
|
295
|
+
scopes,
|
|
296
|
+
className = "",
|
|
297
|
+
style,
|
|
298
|
+
onSuccess,
|
|
299
|
+
onError
|
|
300
|
+
}) {
|
|
301
|
+
const { loginPopup, loginRedirect, inProgress } = useMsalAuth();
|
|
302
|
+
const handleClick = async () => {
|
|
303
|
+
try {
|
|
304
|
+
if (useRedirect) {
|
|
305
|
+
await loginRedirect(scopes);
|
|
306
|
+
} else {
|
|
307
|
+
await loginPopup(scopes);
|
|
308
|
+
}
|
|
309
|
+
onSuccess?.();
|
|
310
|
+
} catch (error) {
|
|
311
|
+
onError?.(error);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
const sizeStyles = {
|
|
315
|
+
small: {
|
|
316
|
+
padding: "8px 16px",
|
|
317
|
+
fontSize: "14px",
|
|
318
|
+
height: "36px"
|
|
319
|
+
},
|
|
320
|
+
medium: {
|
|
321
|
+
padding: "10px 20px",
|
|
322
|
+
fontSize: "15px",
|
|
323
|
+
height: "41px"
|
|
324
|
+
},
|
|
325
|
+
large: {
|
|
326
|
+
padding: "12px 24px",
|
|
327
|
+
fontSize: "16px",
|
|
328
|
+
height: "48px"
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
const variantStyles = {
|
|
332
|
+
dark: {
|
|
333
|
+
backgroundColor: "#2F2F2F",
|
|
334
|
+
color: "#FFFFFF",
|
|
335
|
+
border: "1px solid #8C8C8C"
|
|
336
|
+
},
|
|
337
|
+
light: {
|
|
338
|
+
backgroundColor: "#FFFFFF",
|
|
339
|
+
color: "#5E5E5E",
|
|
340
|
+
border: "1px solid #8C8C8C"
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
const baseStyles = {
|
|
344
|
+
display: "inline-flex",
|
|
345
|
+
alignItems: "center",
|
|
346
|
+
justifyContent: "center",
|
|
347
|
+
gap: "12px",
|
|
348
|
+
fontFamily: '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',
|
|
349
|
+
fontWeight: 600,
|
|
350
|
+
borderRadius: "2px",
|
|
351
|
+
cursor: inProgress ? "not-allowed" : "pointer",
|
|
352
|
+
transition: "all 0.2s ease",
|
|
353
|
+
opacity: inProgress ? 0.6 : 1,
|
|
354
|
+
...variantStyles[variant],
|
|
355
|
+
...sizeStyles[size],
|
|
356
|
+
...style
|
|
261
357
|
};
|
|
358
|
+
return /* @__PURE__ */ jsxs(
|
|
359
|
+
"button",
|
|
360
|
+
{
|
|
361
|
+
onClick: handleClick,
|
|
362
|
+
disabled: inProgress,
|
|
363
|
+
className,
|
|
364
|
+
style: baseStyles,
|
|
365
|
+
"aria-label": text,
|
|
366
|
+
children: [
|
|
367
|
+
/* @__PURE__ */ jsx2(MicrosoftLogo, {}),
|
|
368
|
+
/* @__PURE__ */ jsx2("span", { children: text })
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
function MicrosoftLogo() {
|
|
374
|
+
return /* @__PURE__ */ jsxs("svg", { width: "21", height: "21", viewBox: "0 0 21 21", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
375
|
+
/* @__PURE__ */ jsx2("rect", { width: "10", height: "10", fill: "#F25022" }),
|
|
376
|
+
/* @__PURE__ */ jsx2("rect", { x: "11", width: "10", height: "10", fill: "#7FBA00" }),
|
|
377
|
+
/* @__PURE__ */ jsx2("rect", { y: "11", width: "10", height: "10", fill: "#00A4EF" }),
|
|
378
|
+
/* @__PURE__ */ jsx2("rect", { x: "11", y: "11", width: "10", height: "10", fill: "#FFB900" })
|
|
379
|
+
] });
|
|
262
380
|
}
|
|
263
381
|
|
|
264
382
|
// src/index.ts
|
|
265
383
|
import { useMsal as useMsal2, useIsAuthenticated, useAccount as useAccount2 } from "@azure/msal-react";
|
|
266
384
|
export {
|
|
385
|
+
MicrosoftSignInButton,
|
|
267
386
|
MsalAuthProvider,
|
|
387
|
+
getMsalInstance,
|
|
268
388
|
useAccount2 as useAccount,
|
|
269
389
|
useIsAuthenticated,
|
|
270
390
|
useMsal2 as useMsal,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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":"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","names":["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.
|
|
3
|
+
"version": "1.2.0",
|
|
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"
|