@chemmangat/msal-next 4.1.1 → 4.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/dist/index.js CHANGED
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/client.ts
22
22
  var client_exports = {};
23
23
  __export(client_exports, {
24
+ AccountList: () => AccountList,
25
+ AccountSwitcher: () => AccountSwitcher,
24
26
  AuthGuard: () => AuthGuard,
25
27
  AuthStatus: () => AuthStatus,
26
28
  ErrorBoundary: () => ErrorBoundary,
@@ -45,11 +47,12 @@ __export(client_exports, {
45
47
  retryWithBackoff: () => retryWithBackoff,
46
48
  safeJsonParse: () => safeJsonParse,
47
49
  sanitizeError: () => sanitizeError,
48
- useAccount: () => import_msal_react3.useAccount,
50
+ useAccount: () => import_msal_react4.useAccount,
49
51
  useGraphApi: () => useGraphApi,
50
- useIsAuthenticated: () => import_msal_react3.useIsAuthenticated,
51
- useMsal: () => import_msal_react3.useMsal,
52
+ useIsAuthenticated: () => import_msal_react4.useIsAuthenticated,
53
+ useMsal: () => import_msal_react4.useMsal,
52
54
  useMsalAuth: () => useMsalAuth,
55
+ useMultiAccount: () => useMultiAccount,
53
56
  useRoles: () => useRoles,
54
57
  useTokenRefresh: () => useTokenRefresh,
55
58
  useUserProfile: () => useUserProfile,
@@ -1747,8 +1750,673 @@ var ErrorBoundary = class extends import_react10.Component {
1747
1750
  }
1748
1751
  };
1749
1752
 
1750
- // src/hooks/useRoles.ts
1753
+ // src/hooks/useMultiAccount.ts
1754
+ var import_msal_react3 = require("@azure/msal-react");
1755
+ var import_msal_browser4 = require("@azure/msal-browser");
1751
1756
  var import_react11 = require("react");
1757
+ function useMultiAccount(defaultScopes = ["User.Read"]) {
1758
+ const { instance, accounts, inProgress } = (0, import_msal_react3.useMsal)();
1759
+ const [activeAccount, setActiveAccount] = (0, import_react11.useState)(
1760
+ instance.getActiveAccount()
1761
+ );
1762
+ (0, import_react11.useEffect)(() => {
1763
+ const currentActive = instance.getActiveAccount();
1764
+ if (currentActive?.homeAccountId !== activeAccount?.homeAccountId) {
1765
+ setActiveAccount(currentActive);
1766
+ }
1767
+ }, [instance, accounts, activeAccount]);
1768
+ const hasMultipleAccounts = (0, import_react11.useMemo)(() => accounts.length > 1, [accounts]);
1769
+ const accountCount = (0, import_react11.useMemo)(() => accounts.length, [accounts]);
1770
+ const switchAccount = (0, import_react11.useCallback)(
1771
+ (account) => {
1772
+ try {
1773
+ instance.setActiveAccount(account);
1774
+ setActiveAccount(account);
1775
+ if (process.env.NODE_ENV === "development") {
1776
+ console.log("[MSAL Multi-Account] Switched to account:", account.username);
1777
+ }
1778
+ } catch (error) {
1779
+ const msalError = wrapMsalError(error);
1780
+ console.error("[MSAL Multi-Account] Failed to switch account:", msalError.message);
1781
+ throw msalError;
1782
+ }
1783
+ },
1784
+ [instance]
1785
+ );
1786
+ const addAccount = (0, import_react11.useCallback)(
1787
+ async (scopes = defaultScopes) => {
1788
+ if (inProgress !== import_msal_browser4.InteractionStatus.None) {
1789
+ console.warn("[MSAL Multi-Account] Interaction already in progress");
1790
+ return;
1791
+ }
1792
+ try {
1793
+ const request = {
1794
+ scopes,
1795
+ prompt: "select_account",
1796
+ // Force account selection
1797
+ loginHint: void 0
1798
+ // Don't hint any account
1799
+ };
1800
+ await instance.loginRedirect(request);
1801
+ } catch (error) {
1802
+ const msalError = wrapMsalError(error);
1803
+ if (msalError.isUserCancellation()) {
1804
+ console.log("[MSAL Multi-Account] User cancelled adding account");
1805
+ return;
1806
+ }
1807
+ if (process.env.NODE_ENV === "development") {
1808
+ console.error(msalError.toConsoleString());
1809
+ } else {
1810
+ console.error("[MSAL Multi-Account] Failed to add account:", msalError.message);
1811
+ }
1812
+ throw msalError;
1813
+ }
1814
+ },
1815
+ [instance, defaultScopes, inProgress]
1816
+ );
1817
+ const removeAccount = (0, import_react11.useCallback)(
1818
+ async (account) => {
1819
+ try {
1820
+ if (activeAccount?.homeAccountId === account.homeAccountId) {
1821
+ const otherAccounts = accounts.filter(
1822
+ (acc) => acc.homeAccountId !== account.homeAccountId
1823
+ );
1824
+ if (otherAccounts.length > 0) {
1825
+ instance.setActiveAccount(otherAccounts[0]);
1826
+ setActiveAccount(otherAccounts[0]);
1827
+ } else {
1828
+ instance.setActiveAccount(null);
1829
+ setActiveAccount(null);
1830
+ }
1831
+ }
1832
+ await instance.clearCache({
1833
+ account
1834
+ });
1835
+ if (process.env.NODE_ENV === "development") {
1836
+ console.log("[MSAL Multi-Account] Removed account:", account.username);
1837
+ }
1838
+ } catch (error) {
1839
+ const msalError = wrapMsalError(error);
1840
+ console.error("[MSAL Multi-Account] Failed to remove account:", msalError.message);
1841
+ throw msalError;
1842
+ }
1843
+ },
1844
+ [instance, activeAccount, accounts]
1845
+ );
1846
+ const signOutAccount = (0, import_react11.useCallback)(
1847
+ async (account) => {
1848
+ try {
1849
+ await instance.logoutRedirect({
1850
+ account
1851
+ });
1852
+ } catch (error) {
1853
+ const msalError = wrapMsalError(error);
1854
+ console.error("[MSAL Multi-Account] Failed to sign out account:", msalError.message);
1855
+ throw msalError;
1856
+ }
1857
+ },
1858
+ [instance]
1859
+ );
1860
+ const signOutAll = (0, import_react11.useCallback)(async () => {
1861
+ try {
1862
+ await instance.logoutRedirect({
1863
+ account: activeAccount || void 0
1864
+ });
1865
+ instance.setActiveAccount(null);
1866
+ await instance.clearCache();
1867
+ } catch (error) {
1868
+ const msalError = wrapMsalError(error);
1869
+ console.error("[MSAL Multi-Account] Failed to sign out all accounts:", msalError.message);
1870
+ throw msalError;
1871
+ }
1872
+ }, [instance, activeAccount]);
1873
+ const getAccountByUsername = (0, import_react11.useCallback)(
1874
+ (username) => {
1875
+ return accounts.find((acc) => acc.username === username);
1876
+ },
1877
+ [accounts]
1878
+ );
1879
+ const getAccountById = (0, import_react11.useCallback)(
1880
+ (homeAccountId) => {
1881
+ return accounts.find((acc) => acc.homeAccountId === homeAccountId);
1882
+ },
1883
+ [accounts]
1884
+ );
1885
+ const isActiveAccount = (0, import_react11.useCallback)(
1886
+ (account) => {
1887
+ return activeAccount?.homeAccountId === account.homeAccountId;
1888
+ },
1889
+ [activeAccount]
1890
+ );
1891
+ return {
1892
+ accounts,
1893
+ activeAccount,
1894
+ hasMultipleAccounts,
1895
+ accountCount,
1896
+ inProgress: inProgress !== import_msal_browser4.InteractionStatus.None,
1897
+ switchAccount,
1898
+ addAccount,
1899
+ removeAccount,
1900
+ signOutAccount,
1901
+ signOutAll,
1902
+ getAccountByUsername,
1903
+ getAccountById,
1904
+ isActiveAccount
1905
+ };
1906
+ }
1907
+
1908
+ // src/components/AccountSwitcher.tsx
1909
+ var import_react12 = require("react");
1910
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1911
+ function AccountSwitcher({
1912
+ showAvatars = true,
1913
+ maxAccounts = 5,
1914
+ onSwitch,
1915
+ onAdd,
1916
+ onRemove,
1917
+ className = "",
1918
+ style,
1919
+ variant = "default",
1920
+ showAddButton = true,
1921
+ showRemoveButton = true
1922
+ }) {
1923
+ const {
1924
+ accounts,
1925
+ activeAccount,
1926
+ switchAccount,
1927
+ addAccount,
1928
+ removeAccount,
1929
+ isActiveAccount,
1930
+ accountCount
1931
+ } = useMultiAccount();
1932
+ const [isOpen, setIsOpen] = (0, import_react12.useState)(false);
1933
+ const [removingAccount, setRemovingAccount] = (0, import_react12.useState)(null);
1934
+ const handleSwitch = (account) => {
1935
+ switchAccount(account);
1936
+ setIsOpen(false);
1937
+ onSwitch?.(account);
1938
+ };
1939
+ const handleAdd = async () => {
1940
+ if (accountCount >= maxAccounts) {
1941
+ alert(`Maximum ${maxAccounts} accounts allowed`);
1942
+ return;
1943
+ }
1944
+ await addAccount();
1945
+ onAdd?.();
1946
+ };
1947
+ const handleRemove = async (account, e) => {
1948
+ e.stopPropagation();
1949
+ if (!confirm(`Remove account ${account.username}?`)) {
1950
+ return;
1951
+ }
1952
+ setRemovingAccount(account.homeAccountId);
1953
+ try {
1954
+ await removeAccount(account);
1955
+ onRemove?.(account);
1956
+ } finally {
1957
+ setRemovingAccount(null);
1958
+ }
1959
+ };
1960
+ const containerStyle = {
1961
+ position: "relative",
1962
+ display: "inline-block",
1963
+ ...style
1964
+ };
1965
+ const buttonStyle = {
1966
+ display: "flex",
1967
+ alignItems: "center",
1968
+ gap: "8px",
1969
+ padding: variant === "compact" ? "6px 12px" : "8px 16px",
1970
+ backgroundColor: "#fff",
1971
+ border: "1px solid #d1d5db",
1972
+ borderRadius: "6px",
1973
+ cursor: "pointer",
1974
+ fontSize: variant === "compact" ? "13px" : "14px",
1975
+ fontFamily: "system-ui, -apple-system, sans-serif"
1976
+ };
1977
+ const dropdownStyle = {
1978
+ position: "absolute",
1979
+ top: "100%",
1980
+ right: 0,
1981
+ marginTop: "4px",
1982
+ backgroundColor: "#fff",
1983
+ border: "1px solid #d1d5db",
1984
+ borderRadius: "8px",
1985
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
1986
+ minWidth: variant === "minimal" ? "200px" : "280px",
1987
+ maxWidth: "320px",
1988
+ zIndex: 1e3,
1989
+ overflow: "hidden"
1990
+ };
1991
+ const accountItemStyle = {
1992
+ display: "flex",
1993
+ alignItems: "center",
1994
+ gap: "12px",
1995
+ padding: "12px 16px",
1996
+ cursor: "pointer",
1997
+ borderBottom: "1px solid #f3f4f6",
1998
+ transition: "background-color 0.15s"
1999
+ };
2000
+ const avatarStyle = {
2001
+ width: variant === "compact" ? "28px" : "32px",
2002
+ height: variant === "compact" ? "28px" : "32px",
2003
+ borderRadius: "50%",
2004
+ backgroundColor: "#3b82f6",
2005
+ color: "#fff",
2006
+ display: "flex",
2007
+ alignItems: "center",
2008
+ justifyContent: "center",
2009
+ fontSize: variant === "compact" ? "12px" : "14px",
2010
+ fontWeight: "600",
2011
+ flexShrink: 0
2012
+ };
2013
+ const getInitials = (name) => {
2014
+ if (!name) return "?";
2015
+ const parts = name.split(" ");
2016
+ if (parts.length >= 2) {
2017
+ return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
2018
+ }
2019
+ return name.substring(0, 2).toUpperCase();
2020
+ };
2021
+ if (!activeAccount) {
2022
+ return null;
2023
+ }
2024
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className, style: containerStyle, children: [
2025
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2026
+ "button",
2027
+ {
2028
+ onClick: () => setIsOpen(!isOpen),
2029
+ style: buttonStyle,
2030
+ onMouseEnter: (e) => {
2031
+ e.currentTarget.style.backgroundColor = "#f9fafb";
2032
+ },
2033
+ onMouseLeave: (e) => {
2034
+ e.currentTarget.style.backgroundColor = "#fff";
2035
+ },
2036
+ children: [
2037
+ showAvatars && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: avatarStyle, children: getInitials(activeAccount.name) }),
2038
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-start" }, children: [
2039
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: "500" }, children: activeAccount.name || activeAccount.username }),
2040
+ variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: "12px", color: "#6b7280" }, children: activeAccount.username })
2041
+ ] }),
2042
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2043
+ "svg",
2044
+ {
2045
+ width: "16",
2046
+ height: "16",
2047
+ viewBox: "0 0 16 16",
2048
+ fill: "none",
2049
+ style: {
2050
+ marginLeft: "auto",
2051
+ transform: isOpen ? "rotate(180deg)" : "rotate(0deg)",
2052
+ transition: "transform 0.2s"
2053
+ },
2054
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2055
+ "path",
2056
+ {
2057
+ d: "M4 6L8 10L12 6",
2058
+ stroke: "currentColor",
2059
+ strokeWidth: "2",
2060
+ strokeLinecap: "round",
2061
+ strokeLinejoin: "round"
2062
+ }
2063
+ )
2064
+ }
2065
+ )
2066
+ ]
2067
+ }
2068
+ ),
2069
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2070
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2071
+ "div",
2072
+ {
2073
+ style: {
2074
+ position: "fixed",
2075
+ top: 0,
2076
+ left: 0,
2077
+ right: 0,
2078
+ bottom: 0,
2079
+ zIndex: 999
2080
+ },
2081
+ onClick: () => setIsOpen(false)
2082
+ }
2083
+ ),
2084
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: dropdownStyle, children: [
2085
+ accounts.map((account) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2086
+ "div",
2087
+ {
2088
+ onClick: () => handleSwitch(account),
2089
+ style: {
2090
+ ...accountItemStyle,
2091
+ backgroundColor: isActiveAccount(account) ? "#eff6ff" : "#fff"
2092
+ },
2093
+ onMouseEnter: (e) => {
2094
+ if (!isActiveAccount(account)) {
2095
+ e.currentTarget.style.backgroundColor = "#f9fafb";
2096
+ }
2097
+ },
2098
+ onMouseLeave: (e) => {
2099
+ if (!isActiveAccount(account)) {
2100
+ e.currentTarget.style.backgroundColor = "#fff";
2101
+ }
2102
+ },
2103
+ children: [
2104
+ showAvatars && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: avatarStyle, children: getInitials(account.name) }),
2105
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
2106
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: "500", fontSize: "14px" }, children: account.name || account.username }),
2107
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2108
+ "div",
2109
+ {
2110
+ style: {
2111
+ fontSize: "12px",
2112
+ color: "#6b7280",
2113
+ overflow: "hidden",
2114
+ textOverflow: "ellipsis",
2115
+ whiteSpace: "nowrap"
2116
+ },
2117
+ children: account.username
2118
+ }
2119
+ )
2120
+ ] }),
2121
+ isActiveAccount(account) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2122
+ "svg",
2123
+ {
2124
+ width: "20",
2125
+ height: "20",
2126
+ viewBox: "0 0 20 20",
2127
+ fill: "none",
2128
+ style: { flexShrink: 0 },
2129
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2130
+ "path",
2131
+ {
2132
+ d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
2133
+ fill: "#3b82f6"
2134
+ }
2135
+ )
2136
+ }
2137
+ ),
2138
+ showRemoveButton && accounts.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2139
+ "button",
2140
+ {
2141
+ onClick: (e) => handleRemove(account, e),
2142
+ disabled: removingAccount === account.homeAccountId,
2143
+ style: {
2144
+ padding: "4px",
2145
+ backgroundColor: "transparent",
2146
+ border: "none",
2147
+ cursor: "pointer",
2148
+ borderRadius: "4px",
2149
+ display: "flex",
2150
+ alignItems: "center",
2151
+ justifyContent: "center",
2152
+ opacity: removingAccount === account.homeAccountId ? 0.5 : 1
2153
+ },
2154
+ onMouseEnter: (e) => {
2155
+ e.currentTarget.style.backgroundColor = "#fee2e2";
2156
+ },
2157
+ onMouseLeave: (e) => {
2158
+ e.currentTarget.style.backgroundColor = "transparent";
2159
+ },
2160
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2161
+ "path",
2162
+ {
2163
+ d: "M4 4L12 12M12 4L4 12",
2164
+ stroke: "#ef4444",
2165
+ strokeWidth: "2",
2166
+ strokeLinecap: "round"
2167
+ }
2168
+ ) })
2169
+ }
2170
+ )
2171
+ ]
2172
+ },
2173
+ account.homeAccountId
2174
+ )),
2175
+ showAddButton && accountCount < maxAccounts && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2176
+ "button",
2177
+ {
2178
+ onClick: handleAdd,
2179
+ style: {
2180
+ width: "100%",
2181
+ padding: "12px 16px",
2182
+ backgroundColor: "#fff",
2183
+ border: "none",
2184
+ borderTop: "1px solid #e5e7eb",
2185
+ cursor: "pointer",
2186
+ fontSize: "14px",
2187
+ fontWeight: "500",
2188
+ color: "#3b82f6",
2189
+ display: "flex",
2190
+ alignItems: "center",
2191
+ gap: "8px",
2192
+ justifyContent: "center"
2193
+ },
2194
+ onMouseEnter: (e) => {
2195
+ e.currentTarget.style.backgroundColor = "#f9fafb";
2196
+ },
2197
+ onMouseLeave: (e) => {
2198
+ e.currentTarget.style.backgroundColor = "#fff";
2199
+ },
2200
+ children: [
2201
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2202
+ "path",
2203
+ {
2204
+ d: "M8 3V13M3 8H13",
2205
+ stroke: "currentColor",
2206
+ strokeWidth: "2",
2207
+ strokeLinecap: "round"
2208
+ }
2209
+ ) }),
2210
+ "Add Another Account"
2211
+ ]
2212
+ }
2213
+ ),
2214
+ accountCount >= maxAccounts && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2215
+ "div",
2216
+ {
2217
+ style: {
2218
+ padding: "8px 16px",
2219
+ fontSize: "12px",
2220
+ color: "#6b7280",
2221
+ textAlign: "center",
2222
+ borderTop: "1px solid #e5e7eb"
2223
+ },
2224
+ children: [
2225
+ "Maximum ",
2226
+ maxAccounts,
2227
+ " accounts reached"
2228
+ ]
2229
+ }
2230
+ )
2231
+ ] })
2232
+ ] })
2233
+ ] });
2234
+ }
2235
+
2236
+ // src/components/AccountList.tsx
2237
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2238
+ function AccountList({
2239
+ showAvatars = true,
2240
+ showDetails = true,
2241
+ showActiveIndicator = true,
2242
+ clickToSwitch = true,
2243
+ onAccountClick,
2244
+ className = "",
2245
+ style,
2246
+ orientation = "vertical"
2247
+ }) {
2248
+ const { accounts, switchAccount, isActiveAccount } = useMultiAccount();
2249
+ const handleAccountClick = (account) => {
2250
+ if (clickToSwitch && !isActiveAccount(account)) {
2251
+ switchAccount(account);
2252
+ }
2253
+ onAccountClick?.(account);
2254
+ };
2255
+ const getInitials = (name) => {
2256
+ if (!name) return "?";
2257
+ const parts = name.split(" ");
2258
+ if (parts.length >= 2) {
2259
+ return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
2260
+ }
2261
+ return name.substring(0, 2).toUpperCase();
2262
+ };
2263
+ const containerStyle = {
2264
+ display: "flex",
2265
+ flexDirection: orientation === "vertical" ? "column" : "row",
2266
+ gap: orientation === "vertical" ? "12px" : "16px",
2267
+ ...style
2268
+ };
2269
+ const accountItemStyle = {
2270
+ display: "flex",
2271
+ alignItems: "center",
2272
+ gap: "12px",
2273
+ padding: "16px",
2274
+ backgroundColor: "#fff",
2275
+ border: "1px solid #e5e7eb",
2276
+ borderRadius: "8px",
2277
+ cursor: clickToSwitch ? "pointer" : "default",
2278
+ transition: "all 0.15s",
2279
+ position: "relative"
2280
+ };
2281
+ const avatarStyle = {
2282
+ width: "48px",
2283
+ height: "48px",
2284
+ borderRadius: "50%",
2285
+ backgroundColor: "#3b82f6",
2286
+ color: "#fff",
2287
+ display: "flex",
2288
+ alignItems: "center",
2289
+ justifyContent: "center",
2290
+ fontSize: "18px",
2291
+ fontWeight: "600",
2292
+ flexShrink: 0
2293
+ };
2294
+ if (accounts.length === 0) {
2295
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2296
+ "div",
2297
+ {
2298
+ className,
2299
+ style: {
2300
+ padding: "24px",
2301
+ textAlign: "center",
2302
+ color: "#6b7280",
2303
+ backgroundColor: "#f9fafb",
2304
+ borderRadius: "8px",
2305
+ ...style
2306
+ },
2307
+ children: "No accounts signed in"
2308
+ }
2309
+ );
2310
+ }
2311
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className, style: containerStyle, children: accounts.map((account) => {
2312
+ const isActive = isActiveAccount(account);
2313
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2314
+ "div",
2315
+ {
2316
+ onClick: () => handleAccountClick(account),
2317
+ style: {
2318
+ ...accountItemStyle,
2319
+ borderColor: isActive ? "#3b82f6" : "#e5e7eb",
2320
+ backgroundColor: isActive ? "#eff6ff" : "#fff",
2321
+ boxShadow: isActive ? "0 0 0 3px rgba(59, 130, 246, 0.1)" : "none"
2322
+ },
2323
+ onMouseEnter: (e) => {
2324
+ if (clickToSwitch && !isActive) {
2325
+ e.currentTarget.style.backgroundColor = "#f9fafb";
2326
+ e.currentTarget.style.borderColor = "#d1d5db";
2327
+ }
2328
+ },
2329
+ onMouseLeave: (e) => {
2330
+ if (clickToSwitch && !isActive) {
2331
+ e.currentTarget.style.backgroundColor = "#fff";
2332
+ e.currentTarget.style.borderColor = "#e5e7eb";
2333
+ }
2334
+ },
2335
+ children: [
2336
+ showAvatars && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: avatarStyle, children: getInitials(account.name) }),
2337
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
2338
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2339
+ "div",
2340
+ {
2341
+ style: {
2342
+ fontSize: "16px",
2343
+ fontWeight: "600",
2344
+ color: "#111827",
2345
+ marginBottom: showDetails ? "4px" : 0
2346
+ },
2347
+ children: account.name || account.username
2348
+ }
2349
+ ),
2350
+ showDetails && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2351
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2352
+ "div",
2353
+ {
2354
+ style: {
2355
+ fontSize: "14px",
2356
+ color: "#6b7280",
2357
+ overflow: "hidden",
2358
+ textOverflow: "ellipsis",
2359
+ whiteSpace: "nowrap"
2360
+ },
2361
+ children: account.username
2362
+ }
2363
+ ),
2364
+ account.tenantId && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2365
+ "div",
2366
+ {
2367
+ style: {
2368
+ fontSize: "12px",
2369
+ color: "#9ca3af",
2370
+ marginTop: "2px"
2371
+ },
2372
+ children: [
2373
+ "Tenant: ",
2374
+ account.tenantId.substring(0, 8),
2375
+ "..."
2376
+ ]
2377
+ }
2378
+ )
2379
+ ] })
2380
+ ] }),
2381
+ showActiveIndicator && isActive && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2382
+ "div",
2383
+ {
2384
+ style: {
2385
+ display: "flex",
2386
+ alignItems: "center",
2387
+ gap: "6px",
2388
+ padding: "4px 12px",
2389
+ backgroundColor: "#3b82f6",
2390
+ color: "#fff",
2391
+ borderRadius: "12px",
2392
+ fontSize: "12px",
2393
+ fontWeight: "600",
2394
+ flexShrink: 0
2395
+ },
2396
+ children: [
2397
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2398
+ "path",
2399
+ {
2400
+ d: "M10 3L4.5 8.5L2 6",
2401
+ stroke: "currentColor",
2402
+ strokeWidth: "2",
2403
+ strokeLinecap: "round",
2404
+ strokeLinejoin: "round"
2405
+ }
2406
+ ) }),
2407
+ "Active"
2408
+ ]
2409
+ }
2410
+ )
2411
+ ]
2412
+ },
2413
+ account.homeAccountId
2414
+ );
2415
+ }) });
2416
+ }
2417
+
2418
+ // src/hooks/useRoles.ts
2419
+ var import_react13 = require("react");
1752
2420
  var rolesCache = /* @__PURE__ */ new Map();
1753
2421
  var CACHE_DURATION2 = 5 * 60 * 1e3;
1754
2422
  var MAX_CACHE_SIZE2 = 100;
@@ -1770,11 +2438,11 @@ function enforceCacheLimit2() {
1770
2438
  function useRoles() {
1771
2439
  const { isAuthenticated, account } = useMsalAuth();
1772
2440
  const graph = useGraphApi();
1773
- const [roles, setRoles] = (0, import_react11.useState)([]);
1774
- const [groups, setGroups] = (0, import_react11.useState)([]);
1775
- const [loading, setLoading] = (0, import_react11.useState)(false);
1776
- const [error, setError] = (0, import_react11.useState)(null);
1777
- const fetchRolesAndGroups = (0, import_react11.useCallback)(async () => {
2441
+ const [roles, setRoles] = (0, import_react13.useState)([]);
2442
+ const [groups, setGroups] = (0, import_react13.useState)([]);
2443
+ const [loading, setLoading] = (0, import_react13.useState)(false);
2444
+ const [error, setError] = (0, import_react13.useState)(null);
2445
+ const fetchRolesAndGroups = (0, import_react13.useCallback)(async () => {
1778
2446
  if (!isAuthenticated || !account) {
1779
2447
  setRoles([]);
1780
2448
  setGroups([]);
@@ -1817,31 +2485,31 @@ function useRoles() {
1817
2485
  setLoading(false);
1818
2486
  }
1819
2487
  }, [isAuthenticated, account, graph]);
1820
- const hasRole = (0, import_react11.useCallback)(
2488
+ const hasRole = (0, import_react13.useCallback)(
1821
2489
  (role) => {
1822
2490
  return roles.includes(role);
1823
2491
  },
1824
2492
  [roles]
1825
2493
  );
1826
- const hasGroup = (0, import_react11.useCallback)(
2494
+ const hasGroup = (0, import_react13.useCallback)(
1827
2495
  (groupId) => {
1828
2496
  return groups.includes(groupId);
1829
2497
  },
1830
2498
  [groups]
1831
2499
  );
1832
- const hasAnyRole = (0, import_react11.useCallback)(
2500
+ const hasAnyRole = (0, import_react13.useCallback)(
1833
2501
  (checkRoles) => {
1834
2502
  return checkRoles.some((role) => roles.includes(role));
1835
2503
  },
1836
2504
  [roles]
1837
2505
  );
1838
- const hasAllRoles = (0, import_react11.useCallback)(
2506
+ const hasAllRoles = (0, import_react13.useCallback)(
1839
2507
  (checkRoles) => {
1840
2508
  return checkRoles.every((role) => roles.includes(role));
1841
2509
  },
1842
2510
  [roles]
1843
2511
  );
1844
- (0, import_react11.useEffect)(() => {
2512
+ (0, import_react13.useEffect)(() => {
1845
2513
  fetchRolesAndGroups();
1846
2514
  return () => {
1847
2515
  if (account) {
@@ -1863,11 +2531,11 @@ function useRoles() {
1863
2531
  }
1864
2532
 
1865
2533
  // src/utils/withAuth.tsx
1866
- var import_jsx_runtime9 = require("react/jsx-runtime");
2534
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1867
2535
  function withAuth(Component2, options = {}) {
1868
2536
  const { displayName, ...guardProps } = options;
1869
2537
  const WrappedComponent = (props) => {
1870
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AuthGuard, { ...guardProps, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Component2, { ...props }) });
2538
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AuthGuard, { ...guardProps, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Component2, { ...props }) });
1871
2539
  };
1872
2540
  WrappedComponent.displayName = displayName || `withAuth(${Component2.displayName || Component2.name || "Component"})`;
1873
2541
  return WrappedComponent;
@@ -2139,9 +2807,9 @@ function createScopedLogger(scope, config) {
2139
2807
  }
2140
2808
 
2141
2809
  // src/protection/ProtectedPage.tsx
2142
- var import_react12 = require("react");
2810
+ var import_react14 = require("react");
2143
2811
  var import_navigation = require("next/navigation");
2144
- var import_jsx_runtime10 = require("react/jsx-runtime");
2812
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2145
2813
  function ProtectedPage({
2146
2814
  children,
2147
2815
  config,
@@ -2152,9 +2820,9 @@ function ProtectedPage({
2152
2820
  }) {
2153
2821
  const router = (0, import_navigation.useRouter)();
2154
2822
  const { isAuthenticated, account, inProgress } = useMsalAuth();
2155
- const [isValidating, setIsValidating] = (0, import_react12.useState)(true);
2156
- const [isAuthorized, setIsAuthorized] = (0, import_react12.useState)(false);
2157
- (0, import_react12.useEffect)(() => {
2823
+ const [isValidating, setIsValidating] = (0, import_react14.useState)(true);
2824
+ const [isAuthorized, setIsAuthorized] = (0, import_react14.useState)(false);
2825
+ (0, import_react14.useEffect)(() => {
2158
2826
  async function checkAuth() {
2159
2827
  if (debug) {
2160
2828
  console.log("[ProtectedPage] Checking auth...", {
@@ -2223,33 +2891,33 @@ function ProtectedPage({
2223
2891
  }, [isAuthenticated, account, inProgress, config, router, defaultRedirectTo, debug]);
2224
2892
  if (isValidating || inProgress) {
2225
2893
  if (config.loading) {
2226
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: config.loading });
2894
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: config.loading });
2227
2895
  }
2228
2896
  if (defaultLoading) {
2229
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: defaultLoading });
2897
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: defaultLoading });
2230
2898
  }
2231
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600" }) });
2899
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600" }) });
2232
2900
  }
2233
2901
  if (!isAuthorized) {
2234
2902
  if (config.unauthorized) {
2235
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: config.unauthorized });
2903
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: config.unauthorized });
2236
2904
  }
2237
2905
  if (defaultUnauthorized) {
2238
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: defaultUnauthorized });
2906
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: defaultUnauthorized });
2239
2907
  }
2240
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "text-center", children: [
2241
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "text-2xl font-bold text-gray-900 mb-2", children: "Access Denied" }),
2242
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-gray-600", children: "You don't have permission to access this page." })
2908
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-center", children: [
2909
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h1", { className: "text-2xl font-bold text-gray-900 mb-2", children: "Access Denied" }),
2910
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-gray-600", children: "You don't have permission to access this page." })
2243
2911
  ] }) });
2244
2912
  }
2245
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children });
2913
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children });
2246
2914
  }
2247
2915
 
2248
2916
  // src/protection/withPageAuth.tsx
2249
- var import_jsx_runtime11 = require("react/jsx-runtime");
2917
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2250
2918
  function withPageAuth(Component2, authConfig, globalConfig) {
2251
2919
  const WrappedComponent = (props) => {
2252
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2920
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2253
2921
  ProtectedPage,
2254
2922
  {
2255
2923
  config: authConfig,
@@ -2257,7 +2925,7 @@ function withPageAuth(Component2, authConfig, globalConfig) {
2257
2925
  defaultLoading: globalConfig?.defaultLoading,
2258
2926
  defaultUnauthorized: globalConfig?.defaultUnauthorized,
2259
2927
  debug: globalConfig?.debug,
2260
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Component2, { ...props })
2928
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Component2, { ...props })
2261
2929
  }
2262
2930
  );
2263
2931
  };
@@ -2339,9 +3007,11 @@ function createAuthMiddleware(config = {}) {
2339
3007
  }
2340
3008
 
2341
3009
  // src/client.ts
2342
- var import_msal_react3 = require("@azure/msal-react");
3010
+ var import_msal_react4 = require("@azure/msal-react");
2343
3011
  // Annotate the CommonJS export names for ESM import in node:
2344
3012
  0 && (module.exports = {
3013
+ AccountList,
3014
+ AccountSwitcher,
2345
3015
  AuthGuard,
2346
3016
  AuthStatus,
2347
3017
  ErrorBoundary,
@@ -2371,6 +3041,7 @@ var import_msal_react3 = require("@azure/msal-react");
2371
3041
  useIsAuthenticated,
2372
3042
  useMsal,
2373
3043
  useMsalAuth,
3044
+ useMultiAccount,
2374
3045
  useRoles,
2375
3046
  useTokenRefresh,
2376
3047
  useUserProfile,