@chemmangat/msal-next 4.0.0 → 4.0.2

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
@@ -1,2 +1,123 @@
1
- 'use strict';var msalReact=require('@azure/msal-react'),msalBrowser=require('@azure/msal-browser'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),navigation=require('next/navigation'),server=require('next/server');function H(r,e){try{let t=JSON.parse(r);return e(t)?t:(console.warn("[Validation] JSON validation failed"),null)}catch(t){return console.error("[Validation] JSON parse error:",t),null}}function W(r){return typeof r=="object"&&r!==null&&typeof r.homeAccountId=="string"&&r.homeAccountId.length>0&&typeof r.username=="string"&&r.username.length>0&&(r.name===void 0||typeof r.name=="string")}function w(r){return r instanceof Error?r.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function z(r,e){try{let t=new URL(r);return e.some(o=>{let i=new URL(o);return t.origin===i.origin})}catch{return false}}function ae(r){return /^[a-zA-Z0-9._-]+$/.test(r)}function Ce(r){return Array.isArray(r)&&r.every(ae)}function j(r){if(r.msalConfig)return r.msalConfig;let{clientId:e,tenantId:t,authorityType:o="common",redirectUri:i,postLogoutRedirectUri:a,cacheLocation:g="sessionStorage",storeAuthStateInCookie:u=false,navigateToLoginRequestUrl:l=false,enableLogging:n=false,loggerCallback:h,allowedRedirectUris:f}=r;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let c=()=>{if(o==="tenant"){if(!t)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${t}`}return `https://login.microsoftonline.com/${o}`},s=typeof window<"u"?window.location.origin:"http://localhost:3000",m=i||s;if(f&&f.length>0){if(!z(m,f))throw new Error(`@chemmangat/msal-next: redirectUri "${m}" is not in the allowed list`);let d=a||m;if(!z(d,f))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${d}" is not in the allowed list`)}return {auth:{clientId:e,authority:c(),redirectUri:m,postLogoutRedirectUri:a||m,navigateToLoginRequestUrl:l},cache:{cacheLocation:g,storeAuthStateInCookie:u},system:{loggerOptions:{loggerCallback:h||((d,y,R)=>{if(!(R||!n))switch(d){case msalBrowser.LogLevel.Error:console.error("[MSAL]",y);break;case msalBrowser.LogLevel.Warning:console.warn("[MSAL]",y);break;case msalBrowser.LogLevel.Info:console.info("[MSAL]",y);break;case msalBrowser.LogLevel.Verbose:console.debug("[MSAL]",y);break}}),logLevel:n?msalBrowser.LogLevel.Verbose:msalBrowser.LogLevel.Error}}}}var ce=null;function Ue(){return ce}function J({children:r,loadingComponent:e,onInitialized:t,...o}){let[i,a]=react.useState(null),g=react.useRef(null);return react.useEffect(()=>{if(typeof window>"u"||g.current)return;(async()=>{try{let l=j(o),n=new msalBrowser.PublicClientApplication(l);await n.initialize();try{let c=await n.handleRedirectPromise();c&&(o.enableLogging&&console.log("[MSAL] Redirect authentication successful"),c.account&&n.setActiveAccount(c.account),window.location.hash&&window.history.replaceState(null,"",window.location.pathname+window.location.search));}catch(c){c?.errorCode==="no_token_request_cache_error"?o.enableLogging&&console.log("[MSAL] No pending redirect found (this is normal)"):c?.errorCode==="user_cancelled"?o.enableLogging&&console.log("[MSAL] User cancelled authentication"):console.error("[MSAL] Redirect handling error:",c),window.location.hash&&(window.location.hash.includes("code=")||window.location.hash.includes("error="))&&window.history.replaceState(null,"",window.location.pathname+window.location.search);}let h=n.getAllAccounts();h.length>0&&!n.getActiveAccount()&&n.setActiveAccount(h[0]);let f=o.enableLogging||!1;n.addEventCallback(c=>{if(c.eventType===msalBrowser.EventType.LOGIN_SUCCESS){let s=c.payload;s?.account&&n.setActiveAccount(s.account),f&&console.log("[MSAL] Login successful:",s.account?.username);}if(c.eventType===msalBrowser.EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",c.error),c.eventType===msalBrowser.EventType.LOGOUT_SUCCESS&&(n.setActiveAccount(null),f&&console.log("[MSAL] Logout successful")),c.eventType===msalBrowser.EventType.ACQUIRE_TOKEN_SUCCESS){let s=c.payload;s?.account&&!n.getActiveAccount()&&n.setActiveAccount(s.account);}c.eventType===msalBrowser.EventType.ACQUIRE_TOKEN_FAILURE&&f&&console.error("[MSAL] Token acquisition failed:",c.error);}),g.current=n,ce=n,a(n),t&&t(n);}catch(l){throw console.error("[MSAL] Initialization failed:",l),l}})();},[]),typeof window>"u"?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})}):i?jsxRuntime.jsx(msalReact.MsalProvider,{instance:i,children:r}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})})}var Ne=react.createContext(void 0);function Fe({children:r,protection:e,...t}){return jsxRuntime.jsx(Ne.Provider,{value:e,children:jsxRuntime.jsx(J,{...t,children:r})})}var K=new Map;function A(r=["User.Read"]){let{instance:e,accounts:t,inProgress:o}=msalReact.useMsal(),i=msalReact.useAccount(t[0]||null),a=react.useMemo(()=>t.length>0,[t]),g=react.useCallback(async(c=r)=>{if(o!==msalBrowser.InteractionStatus.None){console.warn("[MSAL] Interaction already in progress");return}try{let s={scopes:c,prompt:"select_account"};await e.loginRedirect(s);}catch(s){if(s?.errorCode==="user_cancelled"){console.log("[MSAL] User cancelled login");return}throw console.error("[MSAL] Login redirect failed:",s),s}},[e,r,o]),u=react.useCallback(async()=>{try{await e.logoutRedirect({account:i||void 0});}catch(c){throw console.error("[MSAL] Logout redirect failed:",c),c}},[e,i]),l=react.useCallback(async(c=r)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let s={scopes:c,account:i,forceRefresh:!1};return (await e.acquireTokenSilent(s)).accessToken}catch(s){throw console.error("[MSAL] Silent token acquisition failed:",s),s}},[e,i,r]),n=react.useCallback(async(c=r)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let s={scopes:c,account:i};await e.acquireTokenRedirect(s);}catch(s){throw console.error("[MSAL] Token redirect acquisition failed:",s),s}},[e,i,r]),h=react.useCallback(async(c=r)=>{let s=`${i?.homeAccountId||"anonymous"}-${c.sort().join(",")}`,m=K.get(s);if(m)return m;let p=(async()=>{try{return await l(c)}catch{throw console.warn("[MSAL] Silent token acquisition failed, falling back to redirect"),await n(c),new Error("[MSAL] Redirecting for token acquisition")}finally{K.delete(s);}})();return K.set(s,p),p},[l,n,r,i]),f=react.useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:i,accounts:t,isAuthenticated:a,inProgress:o!==msalBrowser.InteractionStatus.None,loginRedirect:g,logoutRedirect:u,acquireToken:h,acquireTokenSilent:l,acquireTokenRedirect:n,clearSession:f}}function $e({text:r="Sign in with Microsoft",variant:e="dark",size:t="medium",scopes:o,className:i="",style:a,onSuccess:g,onError:u}){let{loginRedirect:l,inProgress:n}=A(),[h,f]=react.useState(false),c=async()=>{f(true);try{await l(o),g?.();}catch(y){u?.(y);}finally{setTimeout(()=>f(false),500);}},s={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},m={dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}},p=n||h,d={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:p?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:p?.6:1,...m[e],...s[t],...a};return jsxRuntime.jsxs("button",{onClick:c,disabled:p,className:i,style:d,"aria-label":r,children:[jsxRuntime.jsx(ze,{}),jsxRuntime.jsx("span",{children:r})]})}function ze(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function qe({text:r="Sign out",variant:e="dark",size:t="medium",className:o="",style:i,onSuccess:a,onError:g}){let{logoutRedirect:u,inProgress:l}=A(),n=async()=>{try{await u(),a?.();}catch(s){g?.(s);}},h={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},c={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:l?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:l?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...h[t],...i};return jsxRuntime.jsxs("button",{onClick:n,disabled:l,className:o,style:c,"aria-label":r,children:[jsxRuntime.jsx(Be,{}),jsxRuntime.jsx("span",{children:r})]})}function Be(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function N(){let{acquireToken:r}=A(),e=react.useCallback(async(u,l={})=>{let{scopes:n=["User.Read"],version:h="v1.0",debug:f=false,...c}=l;try{let s=await r(n),m=`https://graph.microsoft.com/${h}`,p=u.startsWith("http")?u:`${m}${u.startsWith("/")?u:`/${u}`}`;f&&console.log("[GraphAPI] Request:",{url:p,method:c.method||"GET"});let d=await fetch(p,{...c,headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json",...c.headers}});if(!d.ok){let R=await d.text(),M=`Graph API error (${d.status}): ${R}`;throw new Error(M)}if(d.status===204||d.headers.get("content-length")==="0")return null;let y=await d.json();return f&&console.log("[GraphAPI] Response:",y),y}catch(s){let m=w(s);throw console.error("[GraphAPI] Request failed:",m),new Error(m)}},[r]),t=react.useCallback((u,l={})=>e(u,{...l,method:"GET"}),[e]),o=react.useCallback((u,l,n={})=>e(u,{...n,method:"POST",body:l?JSON.stringify(l):void 0}),[e]),i=react.useCallback((u,l,n={})=>e(u,{...n,method:"PUT",body:l?JSON.stringify(l):void 0}),[e]),a=react.useCallback((u,l,n={})=>e(u,{...n,method:"PATCH",body:l?JSON.stringify(l):void 0}),[e]),g=react.useCallback((u,l={})=>e(u,{...l,method:"DELETE"}),[e]);return {get:t,post:o,put:i,patch:a,delete:g,request:e}}var x=new Map,_e=300*1e3,me=100;function Ve(){if(x.size>me){let r=Array.from(x.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,x.size-me).forEach(([t])=>{let o=x.get(t);o?.data.photo&&URL.revokeObjectURL(o.data.photo),x.delete(t);});}}function Q(){let{isAuthenticated:r,account:e}=A(),t=N(),[o,i]=react.useState(null),[a,g]=react.useState(false),[u,l]=react.useState(null),n=react.useCallback(async()=>{if(!r||!e){i(null);return}let f=e.homeAccountId,c=x.get(f);if(c&&Date.now()-c.timestamp<_e){i(c.data);return}g(true),l(null);try{let s=await t.get("/me",{scopes:["User.Read"]}),m;try{let d=await t.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});d&&(m=URL.createObjectURL(d));}catch{console.debug("[UserProfile] Photo not available");}let p={id:s.id,displayName:s.displayName,givenName:s.givenName,surname:s.surname,userPrincipalName:s.userPrincipalName,mail:s.mail,jobTitle:s.jobTitle,officeLocation:s.officeLocation,mobilePhone:s.mobilePhone,businessPhones:s.businessPhones,photo:m};x.set(f,{data:p,timestamp:Date.now()}),Ve(),i(p);}catch(s){let p=w(s),d=new Error(p);l(d),console.error("[UserProfile] Failed to fetch profile:",p);}finally{g(false);}},[r,e,t]),h=react.useCallback(()=>{if(e){let f=x.get(e.homeAccountId);f?.data.photo&&URL.revokeObjectURL(f.data.photo),x.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),i(null);},[e,o]);return react.useEffect(()=>(n(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[n]),react.useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:a,error:u,refetch:n,clearCache:h}}function We({size:r=40,className:e="",style:t,showTooltip:o=true,fallbackImage:i}){let{profile:a,loading:g}=Q(),[u,l]=react.useState(null),[n,h]=react.useState(false);react.useEffect(()=>{a?.photo&&l(a.photo);},[a?.photo]);let f=()=>{if(!a)return "?";let{givenName:m,surname:p,displayName:d}=a;if(m&&p)return `${m[0]}${p[0]}`.toUpperCase();if(d){let y=d.split(" ");return y.length>=2?`${y[0][0]}${y[y.length-1][0]}`.toUpperCase():d.substring(0,2).toUpperCase()}return "?"},c={width:`${r}px`,height:`${r}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${r*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...t},s=a?.displayName||"User";return g?jsxRuntime.jsx("div",{className:e,style:{...c,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsxRuntime.jsx("span",{style:{fontSize:`${r*.3}px`},children:"..."})}):u&&!n?jsxRuntime.jsx("div",{className:e,style:c,title:o?s:void 0,"aria-label":`${s} avatar`,children:jsxRuntime.jsx("img",{src:u,alt:s,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{h(true),i&&l(i);}})}):jsxRuntime.jsx("div",{className:e,style:c,title:o?s:void 0,"aria-label":`${s} avatar`,children:f()})}function je({className:r="",style:e,showDetails:t=false,renderLoading:o,renderAuthenticated:i,renderUnauthenticated:a}){let{isAuthenticated:g,inProgress:u,account:l}=A(),n={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(u)return o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o()}):jsxRuntime.jsxs("div",{className:r,style:{...n,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(X,{color:"#FFA500"}),jsxRuntime.jsx("span",{children:"Loading..."})]});if(g){let h=l?.username||l?.name||"User";return i?jsxRuntime.jsx(jsxRuntime.Fragment,{children:i(h)}):jsxRuntime.jsxs("div",{className:r,style:{...n,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(X,{color:"#28A745"}),jsxRuntime.jsx("span",{children:t?`Authenticated as ${h}`:"Authenticated"})]})}return a?jsxRuntime.jsx(jsxRuntime.Fragment,{children:a()}):jsxRuntime.jsxs("div",{className:r,style:{...n,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(X,{color:"#DC3545"}),jsxRuntime.jsx("span",{children:"Not authenticated"})]})}function X({color:r}){return jsxRuntime.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("circle",{cx:"4",cy:"4",r:"4",fill:r})})}function re({children:r,loadingComponent:e,fallbackComponent:t,scopes:o,onAuthRequired:i}){let{isAuthenticated:a,inProgress:g,loginRedirect:u}=A();return react.useEffect(()=>{!a&&!g&&(i?.(),(async()=>{try{await u(o);}catch(n){console.error("[AuthGuard] Authentication failed:",n);}})());},[a,g,o,u,i]),g?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Authenticating..."})}):a?jsxRuntime.jsx(jsxRuntime.Fragment,{children:r}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:t||jsxRuntime.jsx("div",{children:"Redirecting to login..."})})}var ne=class extends react.Component{constructor(t){super(t);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(t){return {hasError:true,error:t}}componentDidCatch(t,o){let{onError:i,debug:a}=this.props;a&&(console.error("[ErrorBoundary] Caught error:",t),console.error("[ErrorBoundary] Error info:",o)),i?.(t,o);}render(){let{hasError:t,error:o}=this.state,{children:i,fallback:a}=this.props;return t&&o?a?a(o,this.reset):jsxRuntime.jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsxRuntime.jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsxRuntime.jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsxRuntime.jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):i}};var v=new Map,Xe=300*1e3,Ae=100;function Ye(r){r?v.delete(r):v.clear();}function et(){if(v.size>Ae){let r=Array.from(v.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,v.size-Ae).forEach(([t])=>v.delete(t));}}function tt(){let{isAuthenticated:r,account:e}=A(),t=N(),[o,i]=react.useState([]),[a,g]=react.useState([]),[u,l]=react.useState(false),[n,h]=react.useState(null),f=react.useCallback(async()=>{if(!r||!e){i([]),g([]);return}let d=e.homeAccountId,y=v.get(d);if(y&&Date.now()-y.timestamp<Xe){i(y.roles),g(y.groups);return}l(true),h(null);try{let M=e.idTokenClaims?.roles||[],$=(await t.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(se=>se.id);v.set(d,{roles:M,groups:$,timestamp:Date.now()}),et(),i(M),g($);}catch(R){let V=w(R),$=new Error(V);h($),console.error("[Roles] Failed to fetch roles/groups:",V);let Re=e.idTokenClaims?.roles||[];i(Re);}finally{l(false);}},[r,e,t]),c=react.useCallback(d=>o.includes(d),[o]),s=react.useCallback(d=>a.includes(d),[a]),m=react.useCallback(d=>d.some(y=>o.includes(y)),[o]),p=react.useCallback(d=>d.every(y=>o.includes(y)),[o]);return react.useEffect(()=>(f(),()=>{e&&Ye(e.homeAccountId);}),[f,e]),{roles:o,groups:a,loading:u,error:n,hasRole:c,hasGroup:s,hasAnyRole:m,hasAllRoles:p,refetch:f}}function rt(r,e={}){let{displayName:t,...o}=e,i=a=>jsxRuntime.jsx(re,{...o,children:jsxRuntime.jsx(r,{...a})});return i.displayName=t||`withAuth(${r.displayName||r.name||"Component"})`,i}async function Pe(r,e={}){let{maxRetries:t=3,initialDelay:o=1e3,maxDelay:i=1e4,backoffMultiplier:a=2,debug:g=false}=e,u,l=o;for(let n=0;n<=t;n++)try{return g&&n>0&&console.log(`[TokenRetry] Attempt ${n+1}/${t+1}`),await r()}catch(h){if(u=h,n===t){g&&console.error("[TokenRetry] All retry attempts failed");break}if(!ot(h))throw g&&console.log("[TokenRetry] Non-retryable error, aborting"),h;g&&console.warn(`[TokenRetry] Attempt ${n+1} failed, retrying in ${l}ms...`),await nt(l),l=Math.min(l*a,i);}throw u}function ot(r){let e=r.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function nt(r){return new Promise(e=>setTimeout(e,r))}function it(r,e={}){return (...t)=>Pe(()=>r(...t),e)}var B=class{constructor(e={}){this.logHistory=[];this.performanceTimings=new Map;this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info",enablePerformance:e.enablePerformance??false,enableNetworkLogs:e.enableNetworkLogs??false,maxHistorySize:e.maxHistorySize??100};}shouldLog(e){if(!this.config.enabled)return false;let t=["error","warn","info","debug"],o=t.indexOf(this.config.level);return t.indexOf(e)<=o}formatMessage(e,t,o){let i=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",a=this.config.prefix,g=`[${e.toUpperCase()}]`,u=`${i} ${a} ${g} ${t}`;return o!==void 0&&(u+=`
2
- `+JSON.stringify(o,null,2)),u}addToHistory(e,t,o){this.logHistory.length>=this.config.maxHistorySize&&this.logHistory.shift(),this.logHistory.push({timestamp:Date.now(),level:e,message:t,data:o});}error(e,t){this.shouldLog("error")&&(console.error(this.formatMessage("error",e,t)),this.addToHistory("error",e,t));}warn(e,t){this.shouldLog("warn")&&(console.warn(this.formatMessage("warn",e,t)),this.addToHistory("warn",e,t));}info(e,t){this.shouldLog("info")&&(console.info(this.formatMessage("info",e,t)),this.addToHistory("info",e,t));}debug(e,t){this.shouldLog("debug")&&(console.debug(this.formatMessage("debug",e,t)),this.addToHistory("debug",e,t));}group(e){this.config.enabled&&console.group(`${this.config.prefix} ${e}`);}groupEnd(){this.config.enabled&&console.groupEnd();}startTiming(e){this.config.enablePerformance&&(this.performanceTimings.set(e,{operation:e,startTime:performance.now()}),this.debug(`\u23F1\uFE0F Started: ${e}`));}endTiming(e){if(this.config.enablePerformance){let t=this.performanceTimings.get(e);if(t)return t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.info(`\u23F1\uFE0F Completed: ${e} (${t.duration.toFixed(2)}ms)`),t.duration}}logRequest(e,t,o){this.config.enableNetworkLogs&&this.debug(`\u{1F310} ${e} ${t}`,o);}logResponse(e,t,o,i){if(this.config.enableNetworkLogs){let a=o>=200&&o<300?"\u2705":"\u274C";this.debug(`${a} ${e} ${t} - ${o}`,i);}}getHistory(){return [...this.logHistory]}getPerformanceTimings(){return Array.from(this.performanceTimings.values())}clearHistory(){this.logHistory=[];}clearTimings(){this.performanceTimings.clear();}exportLogs(){return JSON.stringify({config:this.config,history:this.logHistory,performanceTimings:Array.from(this.performanceTimings.values()),exportedAt:new Date().toISOString()},null,2)}downloadLogs(e="msal-next-debug-logs.json"){if(typeof window>"u")return;let t=this.exportLogs(),o=new Blob([t],{type:"application/json"}),i=URL.createObjectURL(o),a=document.createElement("a");a.href=i,a.download=e,a.click(),URL.revokeObjectURL(i);}setEnabled(e){this.config.enabled=e;}setLevel(e){e&&(this.config.level=e);}},O=null;function st(r){return O?r&&(r.enabled!==void 0&&O.setEnabled(r.enabled),r.level&&O.setLevel(r.level)):O=new B(r),O}function at(r,e){return new B({...e,prefix:`[MSAL-Next:${r}]`})}function _({children:r,config:e,defaultRedirectTo:t="/login",defaultLoading:o,defaultUnauthorized:i,debug:a=false}){let g=navigation.useRouter(),{isAuthenticated:u,account:l,inProgress:n}=A(),[h,f]=react.useState(true),[c,s]=react.useState(false);return react.useEffect(()=>{async function m(){if(a&&console.log("[ProtectedPage] Checking auth...",{isAuthenticated:u,inProgress:n,config:e}),!n){if(!e.required){s(true),f(false);return}if(!u||!l){a&&console.log("[ProtectedPage] Not authenticated, redirecting...");let p=e.redirectTo||t,d=encodeURIComponent(window.location.pathname+window.location.search);g.push(`${p}?returnUrl=${d}`);return}if(e.roles&&e.roles.length>0){let p=l.idTokenClaims?.roles||[];if(!e.roles.some(y=>p.includes(y))){a&&console.log("[ProtectedPage] Missing required role",{required:e.roles,user:p}),s(false),f(false);return}}if(e.validate)try{if(!await e.validate(l)){a&&console.log("[ProtectedPage] Custom validation failed"),s(!1),f(!1);return}}catch(p){console.error("[ProtectedPage] Validation error:",p),s(false),f(false);return}a&&console.log("[ProtectedPage] Authorization successful"),s(true),f(false);}}m();},[u,l,n,e,g,t,a]),h||n?e.loading?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e.loading}):o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o}):jsxRuntime.jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsxRuntime.jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"})}):c?jsxRuntime.jsx(jsxRuntime.Fragment,{children:r}):e.unauthorized?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e.unauthorized}):i?jsxRuntime.jsx(jsxRuntime.Fragment,{children:i}):jsxRuntime.jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsxRuntime.jsxs("div",{className:"text-center",children:[jsxRuntime.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-2",children:"Access Denied"}),jsxRuntime.jsx("p",{className:"text-gray-600",children:"You don't have permission to access this page."})]})})}function we(r,e,t){let o=i=>jsxRuntime.jsx(_,{config:e,defaultRedirectTo:t?.defaultRedirectTo,defaultLoading:t?.defaultLoading,defaultUnauthorized:t?.defaultUnauthorized,debug:t?.debug,children:jsxRuntime.jsx(r,{...i})});return o.displayName=`withPageAuth(${r.displayName||r.name||"Component"})`,o}function dt(r={}){let{protectedRoutes:e=[],publicOnlyRoutes:t=[],loginPath:o="/login",redirectAfterLogin:i="/",sessionCookie:a="msal.account",isAuthenticated:g,debug:u=false}=r;return async function(n){let{pathname:h}=n.nextUrl;u&&console.log("[AuthMiddleware] Processing:",h);let f=false;g?f=await g(n):f=!!n.cookies.get(a)?.value,u&&console.log("[AuthMiddleware] Authenticated:",f);let c=e.some(p=>h.startsWith(p)),s=t.some(p=>h.startsWith(p));if(c&&!f){u&&console.log("[AuthMiddleware] Redirecting to login");let p=n.nextUrl.clone();return p.pathname=o,p.searchParams.set("returnUrl",h),server.NextResponse.redirect(p)}if(s&&f){u&&console.log("[AuthMiddleware] Redirecting to home");let p=n.nextUrl.searchParams.get("returnUrl"),d=n.nextUrl.clone();return d.pathname=p||i,d.searchParams.delete("returnUrl"),server.NextResponse.redirect(d)}let m=server.NextResponse.next();if(f){m.headers.set("x-msal-authenticated","true");try{let p=n.cookies.get(a);if(p?.value){let d=H(p.value,W);d?.username&&m.headers.set("x-msal-username",d.username);}}catch{u&&console.warn("[AuthMiddleware] Failed to parse session data");}}return m}}Object.defineProperty(exports,"useAccount",{enumerable:true,get:function(){return msalReact.useAccount}});Object.defineProperty(exports,"useIsAuthenticated",{enumerable:true,get:function(){return msalReact.useIsAuthenticated}});Object.defineProperty(exports,"useMsal",{enumerable:true,get:function(){return msalReact.useMsal}});exports.AuthGuard=re;exports.AuthStatus=je;exports.ErrorBoundary=ne;exports.MSALProvider=Fe;exports.MicrosoftSignInButton=$e;exports.MsalAuthProvider=J;exports.ProtectedPage=_;exports.SignOutButton=qe;exports.UserAvatar=We;exports.createAuthMiddleware=dt;exports.createMsalConfig=j;exports.createRetryWrapper=it;exports.createScopedLogger=at;exports.getDebugLogger=st;exports.getMsalInstance=Ue;exports.isValidAccountData=W;exports.isValidRedirectUri=z;exports.isValidScope=ae;exports.retryWithBackoff=Pe;exports.safeJsonParse=H;exports.sanitizeError=w;exports.useGraphApi=N;exports.useMsalAuth=A;exports.useRoles=tt;exports.useUserProfile=Q;exports.validateScopes=Ce;exports.withAuth=rt;exports.withPageAuth=we;
1
+ 'use strict';var msalReact=require('@azure/msal-react'),msalBrowser=require('@azure/msal-browser'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),navigation=require('next/navigation'),server=require('next/server');function j(t,e){try{let r=JSON.parse(t);return e(r)?r:(console.warn("[Validation] JSON validation failed"),null)}catch(r){return console.error("[Validation] JSON parse error:",r),null}}function Z(t){return typeof t=="object"&&t!==null&&typeof t.homeAccountId=="string"&&t.homeAccountId.length>0&&typeof t.username=="string"&&t.username.length>0&&(t.name===void 0||typeof t.name=="string")}function R(t){return t instanceof Error?t.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function V(t,e){try{let r=new URL(t);return e.some(o=>{let i=new URL(o);return r.origin===i.origin})}catch{return false}}function fe(t){return /^[a-zA-Z0-9._-]+$/.test(t)}function Ne(t){return Array.isArray(t)&&t.every(fe)}function X(t){if(t.msalConfig)return t.msalConfig;let{clientId:e,tenantId:r,authorityType:o="common",redirectUri:i,postLogoutRedirectUri:s,cacheLocation:p="sessionStorage",storeAuthStateInCookie:u=false,navigateToLoginRequestUrl:l=false,enableLogging:a=false,loggerCallback:m,allowedRedirectUris:h}=t;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let c=()=>{if(o==="tenant"){if(!r)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${r}`}return `https://login.microsoftonline.com/${o}`},n=typeof window<"u"?window.location.origin:"http://localhost:3000",f=i||n;if(h&&h.length>0){if(!V(f,h))throw new Error(`@chemmangat/msal-next: redirectUri "${f}" is not in the allowed list`);let d=s||f;if(!V(d,h))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${d}" is not in the allowed list`)}return {auth:{clientId:e,authority:c(),redirectUri:f,postLogoutRedirectUri:s||f,navigateToLoginRequestUrl:l},cache:{cacheLocation:p,storeAuthStateInCookie:u},system:{loggerOptions:{loggerCallback:m||((d,y,C)=>{if(!(C||!a))switch(d){case msalBrowser.LogLevel.Error:console.error("[MSAL]",y);break;case msalBrowser.LogLevel.Warning:console.warn("[MSAL]",y);break;case msalBrowser.LogLevel.Info:console.info("[MSAL]",y);break;case msalBrowser.LogLevel.Verbose:console.debug("[MSAL]",y);break}}),logLevel:a?msalBrowser.LogLevel.Verbose:msalBrowser.LogLevel.Error}}}}var J=null,ge=false;function Y(t){if(process.env.NODE_ENV!=="development")return {valid:true,warnings:[],errors:[]};if(J)return J;let e=[],r=[];if(t.clientId?he(t.clientId)?e.push({field:"clientId",message:"Client ID appears to be a placeholder",fix:`Replace the placeholder with your actual Application (client) ID from Azure Portal.
2
+
3
+ Current value: ${t.clientId}
4
+ Expected format: 12345678-1234-1234-1234-123456789012 (GUID)`}):me(t.clientId)||e.push({field:"clientId",message:"Client ID format is invalid",fix:`Client ID should be a GUID (UUID) format.
5
+
6
+ Current value: ${t.clientId}
7
+ Expected format: 12345678-1234-1234-1234-123456789012
8
+
9
+ Get the correct value from: Azure Portal \u2192 App registrations \u2192 Your app`}):r.push({field:"clientId",message:"Client ID is missing",fix:`Add NEXT_PUBLIC_AZURE_AD_CLIENT_ID to your .env.local file.
10
+
11
+ Get it from: Azure Portal \u2192 App registrations \u2192 Your app \u2192 Application (client) ID`}),t.tenantId&&(he(t.tenantId)?e.push({field:"tenantId",message:"Tenant ID appears to be a placeholder",fix:`Replace the placeholder with your actual Directory (tenant) ID from Azure Portal.
12
+
13
+ Current value: ${t.tenantId}
14
+ Expected format: 87654321-4321-4321-4321-210987654321 (GUID)
15
+
16
+ Or remove tenantId and use authorityType: 'common' for multi-tenant apps.`}):me(t.tenantId)||e.push({field:"tenantId",message:"Tenant ID format is invalid",fix:`Tenant ID should be a GUID (UUID) format.
17
+
18
+ Current value: ${t.tenantId}
19
+ Expected format: 87654321-4321-4321-4321-210987654321
20
+
21
+ Get the correct value from: Azure Portal \u2192 Azure Active Directory \u2192 Properties \u2192 Tenant ID`})),t.redirectUri&&(ke(t.redirectUri)&&!t.redirectUri.startsWith("https://")&&r.push({field:"redirectUri",message:"Production redirect URI must use HTTPS",fix:`Change your redirect URI to use HTTPS in production.
22
+
23
+ Current value: ${t.redirectUri}
24
+ Should be: ${t.redirectUri.replace("http://","https://")}
25
+
26
+ HTTP is only allowed for localhost development.`}),_e(t.redirectUri)||r.push({field:"redirectUri",message:"Redirect URI is not a valid URL",fix:`Provide a valid URL for redirectUri.
27
+
28
+ Current value: ${t.redirectUri}
29
+ Expected format: https://yourdomain.com or http://localhost:3000`})),t.scopes&&t.scopes.length>0){let i=t.scopes.filter(s=>!Fe(s));i.length>0&&e.push({field:"scopes",message:"Some scopes have invalid format",fix:`Invalid scopes: ${i.join(", ")}
30
+
31
+ Scopes should be in format: "Resource.Permission" (e.g., "User.Read", "Mail.Read")
32
+
33
+ Common scopes:
34
+ \u2022 User.Read - Read user profile
35
+ \u2022 Mail.Read - Read user mail
36
+ \u2022 Calendars.Read - Read user calendars
37
+ \u2022 Files.Read - Read user files`});}if(typeof window<"u"){let i=process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID,s=process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID;i||e.push({field:"environment",message:"NEXT_PUBLIC_AZURE_AD_CLIENT_ID not found in environment",fix:`Add NEXT_PUBLIC_AZURE_AD_CLIENT_ID to your .env.local file:
38
+
39
+ NEXT_PUBLIC_AZURE_AD_CLIENT_ID=your-client-id-here
40
+
41
+ Then restart your development server.`}),!s&&t.authorityType==="tenant"&&e.push({field:"environment",message:'NEXT_PUBLIC_AZURE_AD_TENANT_ID not found but authorityType is "tenant"',fix:`Either:
42
+ 1. Add NEXT_PUBLIC_AZURE_AD_TENANT_ID to your .env.local file, OR
43
+ 2. Change authorityType to 'common' for multi-tenant support
44
+
45
+ For single-tenant apps:
46
+ NEXT_PUBLIC_AZURE_AD_TENANT_ID=your-tenant-id-here`});}let o={valid:r.length===0,warnings:e,errors:r};return J=o,o}function K(t){if(!(ge||process.env.NODE_ENV!=="development")){if(ge=true,t.valid&&t.warnings.length===0){console.log("\u2705 MSAL configuration validated successfully");return}console.group("\u{1F50D} MSAL Configuration Validation"),t.errors.length>0&&(console.group("\u274C Errors (must fix)"),t.errors.forEach(e=>{console.error(`
47
+ ${e.field}:`),console.error(` ${e.message}`),console.error(`
48
+ Fix:
49
+ ${e.fix.split(`
50
+ `).join(`
51
+ `)}`);}),console.groupEnd()),t.warnings.length>0&&(console.group("\u26A0\uFE0F Warnings (should fix)"),t.warnings.forEach(e=>{console.warn(`
52
+ ${e.field}:`),console.warn(` ${e.message}`),console.warn(`
53
+ Fix:
54
+ ${e.fix.split(`
55
+ `).join(`
56
+ `)}`);}),console.groupEnd()),console.groupEnd();}}function he(t){let e=["your-client-id","your-tenant-id","your-client-id-here","your-tenant-id-here","client-id","tenant-id","replace-me","changeme","placeholder","example","xxx","000"],r=t.toLowerCase();return e.some(o=>r.includes(o))}function me(t){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)}function ke(t){return !t.includes("localhost")&&!t.includes("127.0.0.1")}function _e(t){try{return new URL(t),!0}catch{return false}}function Fe(t){return /^([a-zA-Z0-9]+\.[a-zA-Z0-9]+|https?:\/\/.+)$/.test(t)}var Q={AADSTS50011:{message:"Redirect URI mismatch",fix:`Your redirect URI doesn't match what's configured in Azure AD.
57
+
58
+ Fix:
59
+ 1. Go to Azure Portal \u2192 Azure Active Directory \u2192 App registrations
60
+ 2. Select your app \u2192 Authentication
61
+ 3. Under "Single-page application", add your redirect URI:
62
+ \u2022 http://localhost:3000 (for development)
63
+ \u2022 https://yourdomain.com (for production)
64
+ 4. Click "Save"
65
+
66
+ Current redirect URI: ${typeof window<"u"?window.location.origin:"unknown"}`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/reply-url"},AADSTS65001:{message:"Admin consent required",fix:`Your app requires admin consent for the requested permissions.
67
+
68
+ Fix:
69
+ 1. Go to Azure Portal \u2192 Azure Active Directory \u2192 App registrations
70
+ 2. Select your app \u2192 API permissions
71
+ 3. Click "Grant admin consent for [Your Organization]"
72
+ 4. Confirm the consent
73
+
74
+ Alternatively, ask your Azure AD administrator to grant consent.`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-admin-consent"},AADSTS700016:{message:"Invalid client application",fix:`The application ID (client ID) is not found in the directory.
75
+
76
+ Fix:
77
+ 1. Verify your NEXT_PUBLIC_AZURE_AD_CLIENT_ID in .env.local
78
+ 2. Ensure the app registration exists in Azure Portal
79
+ 3. Check that you're using the correct tenant
80
+
81
+ Current client ID: Check your environment variables`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes"},AADSTS90002:{message:"Invalid tenant",fix:`The tenant ID is invalid or not found.
82
+
83
+ Fix:
84
+ 1. Verify your NEXT_PUBLIC_AZURE_AD_TENANT_ID in .env.local
85
+ 2. Ensure you're using the correct tenant ID (GUID format)
86
+ 3. For multi-tenant apps, use authorityType: 'common' instead
87
+
88
+ Current tenant ID: Check your environment variables`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-national-cloud"},user_cancelled:{message:"User cancelled authentication",fix:"The user closed the authentication window or cancelled the login process. This is normal user behavior.",docs:void 0},no_token_request_cache_error:{message:"No cached token request",fix:`This usually happens when the page is refreshed during authentication.
89
+
90
+ This is normal and will be handled automatically. If the issue persists:
91
+ 1. Clear your browser cache and cookies
92
+ 2. Try logging in again
93
+ 3. Ensure cookies are enabled in your browser`,docs:void 0},interaction_required:{message:"User interaction required",fix:`The token cannot be acquired silently and requires user interaction.
94
+
95
+ This is normal behavior. The app will redirect you to sign in.`,docs:void 0},consent_required:{message:"User consent required",fix:`Additional consent is required for the requested permissions.
96
+
97
+ This is normal behavior. You'll be prompted to grant consent.`,docs:void 0}},T=class t extends Error{constructor(e){let r=t.parseError(e);super(r.message),this.name="MsalError",this.code=r.code,this.fix=r.fix,this.docs=r.docs,this.originalError=e,Error.captureStackTrace&&Error.captureStackTrace(this,t);}static parseError(e){if(e&&typeof e=="object"){let r=e,o=r.errorCode||r.error||r.code;if(o&&Q[o]){let s=Q[o];return {message:s.message,code:o,fix:s.fix,docs:s.docs}}let i=r.errorMessage||r.message||String(e);for(let[s,p]of Object.entries(Q))if(i.includes(s))return {message:p.message,code:s,fix:p.fix,docs:p.docs};return {message:i||"Authentication error occurred",code:o}}return {message:"An unexpected authentication error occurred"}}toConsoleString(){if(!(process.env.NODE_ENV==="development"))return this.message;let r=`
98
+ \u{1F6A8} MSAL Authentication Error
99
+ `;return r+=`
100
+ Error: ${this.message}
101
+ `,this.code&&(r+=`Code: ${this.code}
102
+ `),this.fix&&(r+=`
103
+ \u{1F4A1} How to fix:
104
+ ${this.fix}
105
+ `),this.docs&&(r+=`
106
+ \u{1F4DA} Documentation: ${this.docs}
107
+ `),r}isUserCancellation(){return this.code==="user_cancelled"}requiresInteraction(){return this.code==="interaction_required"||this.code==="consent_required"}};function P(t){return t instanceof T?t:new T(t)}function $e(t){let e={errorCode:"missing_env_var",errorMessage:`Missing environment variable: ${t}`,message:`${t} not found`},r=`Environment variable ${t} is not set.
108
+
109
+ Fix:
110
+ 1. Copy .env.local.example to .env.local (if it exists)
111
+ 2. Add the following to your .env.local file:
112
+
113
+ ${t}=your-value-here
114
+
115
+ 3. Get the value from Azure Portal:
116
+ \u2022 Go to Azure Active Directory \u2192 App registrations
117
+ \u2022 Select your app
118
+ \u2022 Copy the ${t.includes("CLIENT_ID")?"Application (client) ID":"Directory (tenant) ID"}
119
+
120
+ 4. Restart your development server
121
+
122
+ Note: Environment variables starting with NEXT_PUBLIC_ are exposed to the browser.`;return new T({...e,fix:r,docs:"https://nextjs.org/docs/basic-features/environment-variables"})}var Ae=null;function Be(){return Ae}function ee({children:t,loadingComponent:e,onInitialized:r,...o}){let[i,s]=react.useState(null),p=react.useRef(null);return react.useEffect(()=>{if(typeof window>"u"||p.current)return;(async()=>{try{if(process.env.NODE_ENV==="development"){let c=Y(o);K(c);}let l=X(o),a=new msalBrowser.PublicClientApplication(l);await a.initialize();try{let c=await a.handleRedirectPromise();c&&(o.enableLogging&&console.log("[MSAL] Redirect authentication successful"),c.account&&a.setActiveAccount(c.account),window.location.hash&&window.history.replaceState(null,"",window.location.pathname+window.location.search));}catch(c){let n=P(c);n.code==="no_token_request_cache_error"?o.enableLogging&&console.log("[MSAL] No pending redirect found (this is normal)"):n.isUserCancellation()?o.enableLogging&&console.log("[MSAL] User cancelled authentication"):process.env.NODE_ENV==="development"?console.error(n.toConsoleString()):console.error("[MSAL] Redirect handling error:",n.message),window.location.hash&&(window.location.hash.includes("code=")||window.location.hash.includes("error="))&&window.history.replaceState(null,"",window.location.pathname+window.location.search);}let m=a.getAllAccounts();m.length>0&&!a.getActiveAccount()&&a.setActiveAccount(m[0]);let h=o.enableLogging||!1;a.addEventCallback(c=>{if(c.eventType===msalBrowser.EventType.LOGIN_SUCCESS){let n=c.payload;n?.account&&a.setActiveAccount(n.account),h&&console.log("[MSAL] Login successful:",n.account?.username);}if(c.eventType===msalBrowser.EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",c.error),c.eventType===msalBrowser.EventType.LOGOUT_SUCCESS&&(a.setActiveAccount(null),h&&console.log("[MSAL] Logout successful")),c.eventType===msalBrowser.EventType.ACQUIRE_TOKEN_SUCCESS){let n=c.payload;n?.account&&!a.getActiveAccount()&&a.setActiveAccount(n.account);}c.eventType===msalBrowser.EventType.ACQUIRE_TOKEN_FAILURE&&h&&console.error("[MSAL] Token acquisition failed:",c.error);}),p.current=a,Ae=a,s(a),r&&r(a);}catch(l){throw console.error("[MSAL] Initialization failed:",l),l}})();},[]),typeof window>"u"?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})}):i?jsxRuntime.jsx(msalReact.MsalProvider,{instance:i,children:t}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Loading authentication..."})})}var We=react.createContext(void 0);function je({children:t,protection:e,...r}){return jsxRuntime.jsx(We.Provider,{value:e,children:jsxRuntime.jsx(ee,{...r,children:t})})}var te=new Map;function A(t=["User.Read"]){let{instance:e,accounts:r,inProgress:o}=msalReact.useMsal(),i=msalReact.useAccount(r[0]||null),s=react.useMemo(()=>r.length>0,[r]),p=react.useCallback(async(c=t)=>{if(o!==msalBrowser.InteractionStatus.None){console.warn("[MSAL] Interaction already in progress");return}try{let n={scopes:c,prompt:"select_account"};await e.loginRedirect(n);}catch(n){let f=P(n);if(f.isUserCancellation()){console.log("[MSAL] User cancelled login");return}throw process.env.NODE_ENV==="development"?console.error(f.toConsoleString()):console.error("[MSAL] Login redirect failed:",f.message),f}},[e,t,o]),u=react.useCallback(async()=>{try{await e.logoutRedirect({account:i||void 0});}catch(c){let n=P(c);throw process.env.NODE_ENV==="development"?console.error(n.toConsoleString()):console.error("[MSAL] Logout redirect failed:",n.message),n}},[e,i]),l=react.useCallback(async(c=t)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let n={scopes:c,account:i,forceRefresh:!1};return (await e.acquireTokenSilent(n)).accessToken}catch(n){let f=P(n);throw process.env.NODE_ENV==="development"?console.error(f.toConsoleString()):console.error("[MSAL] Silent token acquisition failed:",f.message),f}},[e,i,t]),a=react.useCallback(async(c=t)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let n={scopes:c,account:i};await e.acquireTokenRedirect(n);}catch(n){let f=P(n);throw process.env.NODE_ENV==="development"?console.error(f.toConsoleString()):console.error("[MSAL] Token redirect acquisition failed:",f.message),f}},[e,i,t]),m=react.useCallback(async(c=t)=>{let n=`${i?.homeAccountId||"anonymous"}-${c.sort().join(",")}`,f=te.get(n);if(f)return f;let g=(async()=>{try{return await l(c)}catch{throw console.warn("[MSAL] Silent token acquisition failed, falling back to redirect"),await a(c),new Error("[MSAL] Redirecting for token acquisition")}finally{te.delete(n);}})();return te.set(n,g),g},[l,a,t,i]),h=react.useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:i,accounts:r,isAuthenticated:s,inProgress:o!==msalBrowser.InteractionStatus.None,loginRedirect:p,logoutRedirect:u,acquireToken:m,acquireTokenSilent:l,acquireTokenRedirect:a,clearSession:h}}function Ke({text:t="Sign in with Microsoft",variant:e="dark",size:r="medium",scopes:o,className:i="",style:s,onSuccess:p,onError:u}){let{loginRedirect:l,inProgress:a}=A(),[m,h]=react.useState(false),c=async()=>{h(true);try{await l(o),p?.();}catch(y){u?.(y);}finally{setTimeout(()=>h(false),500);}},n={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},f={dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}},g=a||m,d={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:g?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:g?.6:1,...f[e],...n[r],...s};return jsxRuntime.jsxs("button",{onClick:c,disabled:g,className:i,style:d,"aria-label":t,children:[jsxRuntime.jsx(Qe,{}),jsxRuntime.jsx("span",{children:t})]})}function Qe(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function et({text:t="Sign out",variant:e="dark",size:r="medium",className:o="",style:i,onSuccess:s,onError:p}){let{logoutRedirect:u,inProgress:l}=A(),a=async()=>{try{await u(),s?.();}catch(n){p?.(n);}},m={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},c={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:l?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:l?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...m[r],...i};return jsxRuntime.jsxs("button",{onClick:a,disabled:l,className:o,style:c,"aria-label":t,children:[jsxRuntime.jsx(tt,{}),jsxRuntime.jsx("span",{children:t})]})}function tt(){return jsxRuntime.jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsxRuntime.jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsxRuntime.jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsxRuntime.jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function k(){let{acquireToken:t}=A(),e=react.useCallback(async(u,l={})=>{let{scopes:a=["User.Read"],version:m="v1.0",debug:h=false,...c}=l;try{let n=await t(a),f=`https://graph.microsoft.com/${m}`,g=u.startsWith("http")?u:`${f}${u.startsWith("/")?u:`/${u}`}`;h&&console.log("[GraphAPI] Request:",{url:g,method:c.method||"GET"});let d=await fetch(g,{...c,headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json",...c.headers}});if(!d.ok){let C=await d.text(),D=`Graph API error (${d.status}): ${C}`;throw new Error(D)}if(d.status===204||d.headers.get("content-length")==="0")return null;let y=await d.json();return h&&console.log("[GraphAPI] Response:",y),y}catch(n){let f=R(n);throw console.error("[GraphAPI] Request failed:",f),new Error(f)}},[t]),r=react.useCallback((u,l={})=>e(u,{...l,method:"GET"}),[e]),o=react.useCallback((u,l,a={})=>e(u,{...a,method:"POST",body:l?JSON.stringify(l):void 0}),[e]),i=react.useCallback((u,l,a={})=>e(u,{...a,method:"PUT",body:l?JSON.stringify(l):void 0}),[e]),s=react.useCallback((u,l,a={})=>e(u,{...a,method:"PATCH",body:l?JSON.stringify(l):void 0}),[e]),p=react.useCallback((u,l={})=>e(u,{...l,method:"DELETE"}),[e]);return {get:r,post:o,put:i,patch:s,delete:p,request:e}}var b=new Map,rt=300*1e3,Ce=100;function ot(){if(b.size>Ce){let t=Array.from(b.entries());t.sort((r,o)=>r[1].timestamp-o[1].timestamp),t.slice(0,b.size-Ce).forEach(([r])=>{let o=b.get(r);o?.data.photo&&URL.revokeObjectURL(o.data.photo),b.delete(r);});}}function oe(){let{isAuthenticated:t,account:e}=A(),r=k(),[o,i]=react.useState(null),[s,p]=react.useState(false),[u,l]=react.useState(null),a=react.useCallback(async()=>{if(!t||!e){i(null);return}let h=e.homeAccountId,c=b.get(h);if(c&&Date.now()-c.timestamp<rt){i(c.data);return}p(true),l(null);try{let n=await r.get("/me",{scopes:["User.Read"]}),f;try{let d=await r.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});d&&(f=URL.createObjectURL(d));}catch{console.debug("[UserProfile] Photo not available");}let g={id:n.id,displayName:n.displayName,givenName:n.givenName,surname:n.surname,userPrincipalName:n.userPrincipalName,mail:n.mail,jobTitle:n.jobTitle,department:n.department,companyName:n.companyName,officeLocation:n.officeLocation,mobilePhone:n.mobilePhone,businessPhones:n.businessPhones,preferredLanguage:n.preferredLanguage,employeeId:n.employeeId,employeeHireDate:n.employeeHireDate,employeeType:n.employeeType,country:n.country,city:n.city,state:n.state,streetAddress:n.streetAddress,postalCode:n.postalCode,usageLocation:n.usageLocation,manager:n.manager,aboutMe:n.aboutMe,birthday:n.birthday,interests:n.interests,skills:n.skills,schools:n.schools,pastProjects:n.pastProjects,responsibilities:n.responsibilities,mySite:n.mySite,faxNumber:n.faxNumber,accountEnabled:n.accountEnabled,ageGroup:n.ageGroup,userType:n.userType,photo:f,...n};b.set(h,{data:g,timestamp:Date.now()}),ot(),i(g);}catch(n){let g=R(n),d=new Error(g);l(d),console.error("[UserProfile] Failed to fetch profile:",g);}finally{p(false);}},[t,e,r]),m=react.useCallback(()=>{if(e){let h=b.get(e.homeAccountId);h?.data.photo&&URL.revokeObjectURL(h.data.photo),b.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),i(null);},[e,o]);return react.useEffect(()=>(a(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[a]),react.useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:s,error:u,refetch:a,clearCache:m}}function it({size:t=40,className:e="",style:r,showTooltip:o=true,fallbackImage:i}){let{profile:s,loading:p}=oe(),[u,l]=react.useState(null),[a,m]=react.useState(false);react.useEffect(()=>{s?.photo&&l(s.photo);},[s?.photo]);let h=()=>{if(!s)return "?";let{givenName:f,surname:g,displayName:d}=s;if(f&&g)return `${f[0]}${g[0]}`.toUpperCase();if(d){let y=d.split(" ");return y.length>=2?`${y[0][0]}${y[y.length-1][0]}`.toUpperCase():d.substring(0,2).toUpperCase()}return "?"},c={width:`${t}px`,height:`${t}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${t*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...r},n=s?.displayName||"User";return p?jsxRuntime.jsx("div",{className:e,style:{...c,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsxRuntime.jsx("span",{style:{fontSize:`${t*.3}px`},children:"..."})}):u&&!a?jsxRuntime.jsx("div",{className:e,style:c,title:o?n:void 0,"aria-label":`${n} avatar`,children:jsxRuntime.jsx("img",{src:u,alt:n,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{m(true),i&&l(i);}})}):jsxRuntime.jsx("div",{className:e,style:c,title:o?n:void 0,"aria-label":`${n} avatar`,children:h()})}function st({className:t="",style:e,showDetails:r=false,renderLoading:o,renderAuthenticated:i,renderUnauthenticated:s}){let{isAuthenticated:p,inProgress:u,account:l}=A(),a={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(u)return o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o()}):jsxRuntime.jsxs("div",{className:t,style:{...a,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(ne,{color:"#FFA500"}),jsxRuntime.jsx("span",{children:"Loading..."})]});if(p){let m=l?.username||l?.name||"User";return i?jsxRuntime.jsx(jsxRuntime.Fragment,{children:i(m)}):jsxRuntime.jsxs("div",{className:t,style:{...a,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(ne,{color:"#28A745"}),jsxRuntime.jsx("span",{children:r?`Authenticated as ${m}`:"Authenticated"})]})}return s?jsxRuntime.jsx(jsxRuntime.Fragment,{children:s()}):jsxRuntime.jsxs("div",{className:t,style:{...a,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsxRuntime.jsx(ne,{color:"#DC3545"}),jsxRuntime.jsx("span",{children:"Not authenticated"})]})}function ne({color:t}){return jsxRuntime.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsxRuntime.jsx("circle",{cx:"4",cy:"4",r:"4",fill:t})})}function le({children:t,loadingComponent:e,fallbackComponent:r,scopes:o,onAuthRequired:i}){let{isAuthenticated:s,inProgress:p,loginRedirect:u}=A();return react.useEffect(()=>{!s&&!p&&(i?.(),(async()=>{try{await u(o);}catch(a){console.error("[AuthGuard] Authentication failed:",a);}})());},[s,p,o,u,i]),p?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e||jsxRuntime.jsx("div",{children:"Authenticating..."})}):s?jsxRuntime.jsx(jsxRuntime.Fragment,{children:t}):jsxRuntime.jsx(jsxRuntime.Fragment,{children:r||jsxRuntime.jsx("div",{children:"Redirecting to login..."})})}var ue=class extends react.Component{constructor(r){super(r);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(r){return {hasError:true,error:r}}componentDidCatch(r,o){let{onError:i,debug:s}=this.props;s&&(console.error("[ErrorBoundary] Caught error:",r),console.error("[ErrorBoundary] Error info:",o)),i?.(r,o);}render(){let{hasError:r,error:o}=this.state,{children:i,fallback:s}=this.props;return r&&o?s?s(o,this.reset):jsxRuntime.jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsxRuntime.jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsxRuntime.jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsxRuntime.jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):i}};var E=new Map,dt=300*1e3,Te=100;function pt(t){t?E.delete(t):E.clear();}function ft(){if(E.size>Te){let t=Array.from(E.entries());t.sort((r,o)=>r[1].timestamp-o[1].timestamp),t.slice(0,E.size-Te).forEach(([r])=>E.delete(r));}}function gt(){let{isAuthenticated:t,account:e}=A(),r=k(),[o,i]=react.useState([]),[s,p]=react.useState([]),[u,l]=react.useState(false),[a,m]=react.useState(null),h=react.useCallback(async()=>{if(!t||!e){i([]),p([]);return}let d=e.homeAccountId,y=E.get(d);if(y&&Date.now()-y.timestamp<dt){i(y.roles),p(y.groups);return}l(true),m(null);try{let D=e.idTokenClaims?.roles||[],G=(await r.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(pe=>pe.id);E.set(d,{roles:D,groups:G,timestamp:Date.now()}),ft(),i(D),p(G);}catch(C){let W=R(C),G=new Error(W);m(G),console.error("[Roles] Failed to fetch roles/groups:",W);let Me=e.idTokenClaims?.roles||[];i(Me);}finally{l(false);}},[t,e,r]),c=react.useCallback(d=>o.includes(d),[o]),n=react.useCallback(d=>s.includes(d),[s]),f=react.useCallback(d=>d.some(y=>o.includes(y)),[o]),g=react.useCallback(d=>d.every(y=>o.includes(y)),[o]);return react.useEffect(()=>(h(),()=>{e&&pt(e.homeAccountId);}),[h,e]),{roles:o,groups:s,loading:u,error:a,hasRole:c,hasGroup:n,hasAnyRole:f,hasAllRoles:g,refetch:h}}function ht(t,e={}){let{displayName:r,...o}=e,i=s=>jsxRuntime.jsx(le,{...o,children:jsxRuntime.jsx(t,{...s})});return i.displayName=r||`withAuth(${t.displayName||t.name||"Component"})`,i}async function Ue(t,e={}){let{maxRetries:r=3,initialDelay:o=1e3,maxDelay:i=1e4,backoffMultiplier:s=2,debug:p=false}=e,u,l=o;for(let a=0;a<=r;a++)try{return p&&a>0&&console.log(`[TokenRetry] Attempt ${a+1}/${r+1}`),await t()}catch(m){if(u=m,a===r){p&&console.error("[TokenRetry] All retry attempts failed");break}if(!mt(m))throw p&&console.log("[TokenRetry] Non-retryable error, aborting"),m;p&&console.warn(`[TokenRetry] Attempt ${a+1} failed, retrying in ${l}ms...`),await yt(l),l=Math.min(l*s,i);}throw u}function mt(t){let e=t.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function yt(t){return new Promise(e=>setTimeout(e,t))}function At(t,e={}){return (...r)=>Ue(()=>t(...r),e)}var B=class{constructor(e={}){this.logHistory=[];this.performanceTimings=new Map;this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info",enablePerformance:e.enablePerformance??false,enableNetworkLogs:e.enableNetworkLogs??false,maxHistorySize:e.maxHistorySize??100};}shouldLog(e){if(!this.config.enabled)return false;let r=["error","warn","info","debug"],o=r.indexOf(this.config.level);return r.indexOf(e)<=o}formatMessage(e,r,o){let i=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",s=this.config.prefix,p=`[${e.toUpperCase()}]`,u=`${i} ${s} ${p} ${r}`;return o!==void 0&&(u+=`
123
+ `+JSON.stringify(o,null,2)),u}addToHistory(e,r,o){this.logHistory.length>=this.config.maxHistorySize&&this.logHistory.shift(),this.logHistory.push({timestamp:Date.now(),level:e,message:r,data:o});}error(e,r){this.shouldLog("error")&&(console.error(this.formatMessage("error",e,r)),this.addToHistory("error",e,r));}warn(e,r){this.shouldLog("warn")&&(console.warn(this.formatMessage("warn",e,r)),this.addToHistory("warn",e,r));}info(e,r){this.shouldLog("info")&&(console.info(this.formatMessage("info",e,r)),this.addToHistory("info",e,r));}debug(e,r){this.shouldLog("debug")&&(console.debug(this.formatMessage("debug",e,r)),this.addToHistory("debug",e,r));}group(e){this.config.enabled&&console.group(`${this.config.prefix} ${e}`);}groupEnd(){this.config.enabled&&console.groupEnd();}startTiming(e){this.config.enablePerformance&&(this.performanceTimings.set(e,{operation:e,startTime:performance.now()}),this.debug(`\u23F1\uFE0F Started: ${e}`));}endTiming(e){if(this.config.enablePerformance){let r=this.performanceTimings.get(e);if(r)return r.endTime=performance.now(),r.duration=r.endTime-r.startTime,this.info(`\u23F1\uFE0F Completed: ${e} (${r.duration.toFixed(2)}ms)`),r.duration}}logRequest(e,r,o){this.config.enableNetworkLogs&&this.debug(`\u{1F310} ${e} ${r}`,o);}logResponse(e,r,o,i){if(this.config.enableNetworkLogs){let s=o>=200&&o<300?"\u2705":"\u274C";this.debug(`${s} ${e} ${r} - ${o}`,i);}}getHistory(){return [...this.logHistory]}getPerformanceTimings(){return Array.from(this.performanceTimings.values())}clearHistory(){this.logHistory=[];}clearTimings(){this.performanceTimings.clear();}exportLogs(){return JSON.stringify({config:this.config,history:this.logHistory,performanceTimings:Array.from(this.performanceTimings.values()),exportedAt:new Date().toISOString()},null,2)}downloadLogs(e="msal-next-debug-logs.json"){if(typeof window>"u")return;let r=this.exportLogs(),o=new Blob([r],{type:"application/json"}),i=URL.createObjectURL(o),s=document.createElement("a");s.href=i,s.download=e,s.click(),URL.revokeObjectURL(i);}setEnabled(e){this.config.enabled=e;}setLevel(e){e&&(this.config.level=e);}},O=null;function vt(t){return O?t&&(t.enabled!==void 0&&O.setEnabled(t.enabled),t.level&&O.setLevel(t.level)):O=new B(t),O}function xt(t,e){return new B({...e,prefix:`[MSAL-Next:${t}]`})}function H({children:t,config:e,defaultRedirectTo:r="/login",defaultLoading:o,defaultUnauthorized:i,debug:s=false}){let p=navigation.useRouter(),{isAuthenticated:u,account:l,inProgress:a}=A(),[m,h]=react.useState(true),[c,n]=react.useState(false);return react.useEffect(()=>{async function f(){if(s&&console.log("[ProtectedPage] Checking auth...",{isAuthenticated:u,inProgress:a,config:e}),!a){if(!e.required){n(true),h(false);return}if(!u||!l){s&&console.log("[ProtectedPage] Not authenticated, redirecting...");let g=e.redirectTo||r,d=encodeURIComponent(window.location.pathname+window.location.search);p.push(`${g}?returnUrl=${d}`);return}if(e.roles&&e.roles.length>0){let g=l.idTokenClaims?.roles||[];if(!e.roles.some(y=>g.includes(y))){s&&console.log("[ProtectedPage] Missing required role",{required:e.roles,user:g}),n(false),h(false);return}}if(e.validate)try{if(!await e.validate(l)){s&&console.log("[ProtectedPage] Custom validation failed"),n(!1),h(!1);return}}catch(g){console.error("[ProtectedPage] Validation error:",g),n(false),h(false);return}s&&console.log("[ProtectedPage] Authorization successful"),n(true),h(false);}}f();},[u,l,a,e,p,r,s]),m||a?e.loading?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e.loading}):o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o}):jsxRuntime.jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsxRuntime.jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"})}):c?jsxRuntime.jsx(jsxRuntime.Fragment,{children:t}):e.unauthorized?jsxRuntime.jsx(jsxRuntime.Fragment,{children:e.unauthorized}):i?jsxRuntime.jsx(jsxRuntime.Fragment,{children:i}):jsxRuntime.jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsxRuntime.jsxs("div",{className:"text-center",children:[jsxRuntime.jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-2",children:"Access Denied"}),jsxRuntime.jsx("p",{className:"text-gray-600",children:"You don't have permission to access this page."})]})})}function De(t,e,r){let o=i=>jsxRuntime.jsx(H,{config:e,defaultRedirectTo:r?.defaultRedirectTo,defaultLoading:r?.defaultLoading,defaultUnauthorized:r?.defaultUnauthorized,debug:r?.debug,children:jsxRuntime.jsx(t,{...i})});return o.displayName=`withPageAuth(${t.displayName||t.name||"Component"})`,o}function Rt(t={}){let{protectedRoutes:e=[],publicOnlyRoutes:r=[],loginPath:o="/login",redirectAfterLogin:i="/",sessionCookie:s="msal.account",isAuthenticated:p,debug:u=false}=t;return async function(a){let{pathname:m}=a.nextUrl;u&&console.log("[AuthMiddleware] Processing:",m);let h=false;p?h=await p(a):h=!!a.cookies.get(s)?.value,u&&console.log("[AuthMiddleware] Authenticated:",h);let c=e.some(g=>m.startsWith(g)),n=r.some(g=>m.startsWith(g));if(c&&!h){u&&console.log("[AuthMiddleware] Redirecting to login");let g=a.nextUrl.clone();return g.pathname=o,g.searchParams.set("returnUrl",m),server.NextResponse.redirect(g)}if(n&&h){u&&console.log("[AuthMiddleware] Redirecting to home");let g=a.nextUrl.searchParams.get("returnUrl"),d=a.nextUrl.clone();return d.pathname=g||i,d.searchParams.delete("returnUrl"),server.NextResponse.redirect(d)}let f=server.NextResponse.next();if(h){f.headers.set("x-msal-authenticated","true");try{let g=a.cookies.get(s);if(g?.value){let d=j(g.value,Z);d?.username&&f.headers.set("x-msal-username",d.username);}}catch{u&&console.warn("[AuthMiddleware] Failed to parse session data");}}return f}}Object.defineProperty(exports,"useAccount",{enumerable:true,get:function(){return msalReact.useAccount}});Object.defineProperty(exports,"useIsAuthenticated",{enumerable:true,get:function(){return msalReact.useIsAuthenticated}});Object.defineProperty(exports,"useMsal",{enumerable:true,get:function(){return msalReact.useMsal}});exports.AuthGuard=le;exports.AuthStatus=st;exports.ErrorBoundary=ue;exports.MSALProvider=je;exports.MicrosoftSignInButton=Ke;exports.MsalAuthProvider=ee;exports.MsalError=T;exports.ProtectedPage=H;exports.SignOutButton=et;exports.UserAvatar=it;exports.createAuthMiddleware=Rt;exports.createMissingEnvVarError=$e;exports.createMsalConfig=X;exports.createRetryWrapper=At;exports.createScopedLogger=xt;exports.displayValidationResults=K;exports.getDebugLogger=vt;exports.getMsalInstance=Be;exports.isValidAccountData=Z;exports.isValidRedirectUri=V;exports.isValidScope=fe;exports.retryWithBackoff=Ue;exports.safeJsonParse=j;exports.sanitizeError=R;exports.useGraphApi=k;exports.useMsalAuth=A;exports.useRoles=gt;exports.useUserProfile=oe;exports.validateConfig=Y;exports.validateScopes=Ne;exports.withAuth=ht;exports.withPageAuth=De;exports.wrapMsalError=P;
package/dist/index.mjs CHANGED
@@ -1,2 +1,123 @@
1
- import {MsalProvider,useMsal,useAccount}from'@azure/msal-react';export{useAccount,useIsAuthenticated,useMsal}from'@azure/msal-react';import {LogLevel,PublicClientApplication,EventType,InteractionStatus}from'@azure/msal-browser';import {createContext,useState,useRef,useEffect,useMemo,useCallback,Component}from'react';import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {useRouter}from'next/navigation';import {NextResponse}from'next/server';function H(r,e){try{let t=JSON.parse(r);return e(t)?t:(console.warn("[Validation] JSON validation failed"),null)}catch(t){return console.error("[Validation] JSON parse error:",t),null}}function W(r){return typeof r=="object"&&r!==null&&typeof r.homeAccountId=="string"&&r.homeAccountId.length>0&&typeof r.username=="string"&&r.username.length>0&&(r.name===void 0||typeof r.name=="string")}function w(r){return r instanceof Error?r.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function z(r,e){try{let t=new URL(r);return e.some(o=>{let i=new URL(o);return t.origin===i.origin})}catch{return false}}function ae(r){return /^[a-zA-Z0-9._-]+$/.test(r)}function Ce(r){return Array.isArray(r)&&r.every(ae)}function j(r){if(r.msalConfig)return r.msalConfig;let{clientId:e,tenantId:t,authorityType:o="common",redirectUri:i,postLogoutRedirectUri:a,cacheLocation:g="sessionStorage",storeAuthStateInCookie:u=false,navigateToLoginRequestUrl:l=false,enableLogging:n=false,loggerCallback:h,allowedRedirectUris:f}=r;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let c=()=>{if(o==="tenant"){if(!t)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${t}`}return `https://login.microsoftonline.com/${o}`},s=typeof window<"u"?window.location.origin:"http://localhost:3000",m=i||s;if(f&&f.length>0){if(!z(m,f))throw new Error(`@chemmangat/msal-next: redirectUri "${m}" is not in the allowed list`);let d=a||m;if(!z(d,f))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${d}" is not in the allowed list`)}return {auth:{clientId:e,authority:c(),redirectUri:m,postLogoutRedirectUri:a||m,navigateToLoginRequestUrl:l},cache:{cacheLocation:g,storeAuthStateInCookie:u},system:{loggerOptions:{loggerCallback:h||((d,y,R)=>{if(!(R||!n))switch(d){case LogLevel.Error:console.error("[MSAL]",y);break;case LogLevel.Warning:console.warn("[MSAL]",y);break;case LogLevel.Info:console.info("[MSAL]",y);break;case LogLevel.Verbose:console.debug("[MSAL]",y);break}}),logLevel:n?LogLevel.Verbose:LogLevel.Error}}}}var ce=null;function Ue(){return ce}function J({children:r,loadingComponent:e,onInitialized:t,...o}){let[i,a]=useState(null),g=useRef(null);return useEffect(()=>{if(typeof window>"u"||g.current)return;(async()=>{try{let l=j(o),n=new PublicClientApplication(l);await n.initialize();try{let c=await n.handleRedirectPromise();c&&(o.enableLogging&&console.log("[MSAL] Redirect authentication successful"),c.account&&n.setActiveAccount(c.account),window.location.hash&&window.history.replaceState(null,"",window.location.pathname+window.location.search));}catch(c){c?.errorCode==="no_token_request_cache_error"?o.enableLogging&&console.log("[MSAL] No pending redirect found (this is normal)"):c?.errorCode==="user_cancelled"?o.enableLogging&&console.log("[MSAL] User cancelled authentication"):console.error("[MSAL] Redirect handling error:",c),window.location.hash&&(window.location.hash.includes("code=")||window.location.hash.includes("error="))&&window.history.replaceState(null,"",window.location.pathname+window.location.search);}let h=n.getAllAccounts();h.length>0&&!n.getActiveAccount()&&n.setActiveAccount(h[0]);let f=o.enableLogging||!1;n.addEventCallback(c=>{if(c.eventType===EventType.LOGIN_SUCCESS){let s=c.payload;s?.account&&n.setActiveAccount(s.account),f&&console.log("[MSAL] Login successful:",s.account?.username);}if(c.eventType===EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",c.error),c.eventType===EventType.LOGOUT_SUCCESS&&(n.setActiveAccount(null),f&&console.log("[MSAL] Logout successful")),c.eventType===EventType.ACQUIRE_TOKEN_SUCCESS){let s=c.payload;s?.account&&!n.getActiveAccount()&&n.setActiveAccount(s.account);}c.eventType===EventType.ACQUIRE_TOKEN_FAILURE&&f&&console.error("[MSAL] Token acquisition failed:",c.error);}),g.current=n,ce=n,a(n),t&&t(n);}catch(l){throw console.error("[MSAL] Initialization failed:",l),l}})();},[]),typeof window>"u"?jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})}):i?jsx(MsalProvider,{instance:i,children:r}):jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})})}var Ne=createContext(void 0);function Fe({children:r,protection:e,...t}){return jsx(Ne.Provider,{value:e,children:jsx(J,{...t,children:r})})}var K=new Map;function A(r=["User.Read"]){let{instance:e,accounts:t,inProgress:o}=useMsal(),i=useAccount(t[0]||null),a=useMemo(()=>t.length>0,[t]),g=useCallback(async(c=r)=>{if(o!==InteractionStatus.None){console.warn("[MSAL] Interaction already in progress");return}try{let s={scopes:c,prompt:"select_account"};await e.loginRedirect(s);}catch(s){if(s?.errorCode==="user_cancelled"){console.log("[MSAL] User cancelled login");return}throw console.error("[MSAL] Login redirect failed:",s),s}},[e,r,o]),u=useCallback(async()=>{try{await e.logoutRedirect({account:i||void 0});}catch(c){throw console.error("[MSAL] Logout redirect failed:",c),c}},[e,i]),l=useCallback(async(c=r)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let s={scopes:c,account:i,forceRefresh:!1};return (await e.acquireTokenSilent(s)).accessToken}catch(s){throw console.error("[MSAL] Silent token acquisition failed:",s),s}},[e,i,r]),n=useCallback(async(c=r)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let s={scopes:c,account:i};await e.acquireTokenRedirect(s);}catch(s){throw console.error("[MSAL] Token redirect acquisition failed:",s),s}},[e,i,r]),h=useCallback(async(c=r)=>{let s=`${i?.homeAccountId||"anonymous"}-${c.sort().join(",")}`,m=K.get(s);if(m)return m;let p=(async()=>{try{return await l(c)}catch{throw console.warn("[MSAL] Silent token acquisition failed, falling back to redirect"),await n(c),new Error("[MSAL] Redirecting for token acquisition")}finally{K.delete(s);}})();return K.set(s,p),p},[l,n,r,i]),f=useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:i,accounts:t,isAuthenticated:a,inProgress:o!==InteractionStatus.None,loginRedirect:g,logoutRedirect:u,acquireToken:h,acquireTokenSilent:l,acquireTokenRedirect:n,clearSession:f}}function $e({text:r="Sign in with Microsoft",variant:e="dark",size:t="medium",scopes:o,className:i="",style:a,onSuccess:g,onError:u}){let{loginRedirect:l,inProgress:n}=A(),[h,f]=useState(false),c=async()=>{f(true);try{await l(o),g?.();}catch(y){u?.(y);}finally{setTimeout(()=>f(false),500);}},s={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},m={dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}},p=n||h,d={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:p?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:p?.6:1,...m[e],...s[t],...a};return jsxs("button",{onClick:c,disabled:p,className:i,style:d,"aria-label":r,children:[jsx(ze,{}),jsx("span",{children:r})]})}function ze(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function qe({text:r="Sign out",variant:e="dark",size:t="medium",className:o="",style:i,onSuccess:a,onError:g}){let{logoutRedirect:u,inProgress:l}=A(),n=async()=>{try{await u(),a?.();}catch(s){g?.(s);}},h={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},c={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:l?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:l?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...h[t],...i};return jsxs("button",{onClick:n,disabled:l,className:o,style:c,"aria-label":r,children:[jsx(Be,{}),jsx("span",{children:r})]})}function Be(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function N(){let{acquireToken:r}=A(),e=useCallback(async(u,l={})=>{let{scopes:n=["User.Read"],version:h="v1.0",debug:f=false,...c}=l;try{let s=await r(n),m=`https://graph.microsoft.com/${h}`,p=u.startsWith("http")?u:`${m}${u.startsWith("/")?u:`/${u}`}`;f&&console.log("[GraphAPI] Request:",{url:p,method:c.method||"GET"});let d=await fetch(p,{...c,headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json",...c.headers}});if(!d.ok){let R=await d.text(),M=`Graph API error (${d.status}): ${R}`;throw new Error(M)}if(d.status===204||d.headers.get("content-length")==="0")return null;let y=await d.json();return f&&console.log("[GraphAPI] Response:",y),y}catch(s){let m=w(s);throw console.error("[GraphAPI] Request failed:",m),new Error(m)}},[r]),t=useCallback((u,l={})=>e(u,{...l,method:"GET"}),[e]),o=useCallback((u,l,n={})=>e(u,{...n,method:"POST",body:l?JSON.stringify(l):void 0}),[e]),i=useCallback((u,l,n={})=>e(u,{...n,method:"PUT",body:l?JSON.stringify(l):void 0}),[e]),a=useCallback((u,l,n={})=>e(u,{...n,method:"PATCH",body:l?JSON.stringify(l):void 0}),[e]),g=useCallback((u,l={})=>e(u,{...l,method:"DELETE"}),[e]);return {get:t,post:o,put:i,patch:a,delete:g,request:e}}var x=new Map,_e=300*1e3,me=100;function Ve(){if(x.size>me){let r=Array.from(x.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,x.size-me).forEach(([t])=>{let o=x.get(t);o?.data.photo&&URL.revokeObjectURL(o.data.photo),x.delete(t);});}}function Q(){let{isAuthenticated:r,account:e}=A(),t=N(),[o,i]=useState(null),[a,g]=useState(false),[u,l]=useState(null),n=useCallback(async()=>{if(!r||!e){i(null);return}let f=e.homeAccountId,c=x.get(f);if(c&&Date.now()-c.timestamp<_e){i(c.data);return}g(true),l(null);try{let s=await t.get("/me",{scopes:["User.Read"]}),m;try{let d=await t.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});d&&(m=URL.createObjectURL(d));}catch{console.debug("[UserProfile] Photo not available");}let p={id:s.id,displayName:s.displayName,givenName:s.givenName,surname:s.surname,userPrincipalName:s.userPrincipalName,mail:s.mail,jobTitle:s.jobTitle,officeLocation:s.officeLocation,mobilePhone:s.mobilePhone,businessPhones:s.businessPhones,photo:m};x.set(f,{data:p,timestamp:Date.now()}),Ve(),i(p);}catch(s){let p=w(s),d=new Error(p);l(d),console.error("[UserProfile] Failed to fetch profile:",p);}finally{g(false);}},[r,e,t]),h=useCallback(()=>{if(e){let f=x.get(e.homeAccountId);f?.data.photo&&URL.revokeObjectURL(f.data.photo),x.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),i(null);},[e,o]);return useEffect(()=>(n(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[n]),useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:a,error:u,refetch:n,clearCache:h}}function We({size:r=40,className:e="",style:t,showTooltip:o=true,fallbackImage:i}){let{profile:a,loading:g}=Q(),[u,l]=useState(null),[n,h]=useState(false);useEffect(()=>{a?.photo&&l(a.photo);},[a?.photo]);let f=()=>{if(!a)return "?";let{givenName:m,surname:p,displayName:d}=a;if(m&&p)return `${m[0]}${p[0]}`.toUpperCase();if(d){let y=d.split(" ");return y.length>=2?`${y[0][0]}${y[y.length-1][0]}`.toUpperCase():d.substring(0,2).toUpperCase()}return "?"},c={width:`${r}px`,height:`${r}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${r*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...t},s=a?.displayName||"User";return g?jsx("div",{className:e,style:{...c,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsx("span",{style:{fontSize:`${r*.3}px`},children:"..."})}):u&&!n?jsx("div",{className:e,style:c,title:o?s:void 0,"aria-label":`${s} avatar`,children:jsx("img",{src:u,alt:s,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{h(true),i&&l(i);}})}):jsx("div",{className:e,style:c,title:o?s:void 0,"aria-label":`${s} avatar`,children:f()})}function je({className:r="",style:e,showDetails:t=false,renderLoading:o,renderAuthenticated:i,renderUnauthenticated:a}){let{isAuthenticated:g,inProgress:u,account:l}=A(),n={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(u)return o?jsx(Fragment,{children:o()}):jsxs("div",{className:r,style:{...n,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsx(X,{color:"#FFA500"}),jsx("span",{children:"Loading..."})]});if(g){let h=l?.username||l?.name||"User";return i?jsx(Fragment,{children:i(h)}):jsxs("div",{className:r,style:{...n,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsx(X,{color:"#28A745"}),jsx("span",{children:t?`Authenticated as ${h}`:"Authenticated"})]})}return a?jsx(Fragment,{children:a()}):jsxs("div",{className:r,style:{...n,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsx(X,{color:"#DC3545"}),jsx("span",{children:"Not authenticated"})]})}function X({color:r}){return jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("circle",{cx:"4",cy:"4",r:"4",fill:r})})}function re({children:r,loadingComponent:e,fallbackComponent:t,scopes:o,onAuthRequired:i}){let{isAuthenticated:a,inProgress:g,loginRedirect:u}=A();return useEffect(()=>{!a&&!g&&(i?.(),(async()=>{try{await u(o);}catch(n){console.error("[AuthGuard] Authentication failed:",n);}})());},[a,g,o,u,i]),g?jsx(Fragment,{children:e||jsx("div",{children:"Authenticating..."})}):a?jsx(Fragment,{children:r}):jsx(Fragment,{children:t||jsx("div",{children:"Redirecting to login..."})})}var ne=class extends Component{constructor(t){super(t);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(t){return {hasError:true,error:t}}componentDidCatch(t,o){let{onError:i,debug:a}=this.props;a&&(console.error("[ErrorBoundary] Caught error:",t),console.error("[ErrorBoundary] Error info:",o)),i?.(t,o);}render(){let{hasError:t,error:o}=this.state,{children:i,fallback:a}=this.props;return t&&o?a?a(o,this.reset):jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):i}};var v=new Map,Xe=300*1e3,Ae=100;function Ye(r){r?v.delete(r):v.clear();}function et(){if(v.size>Ae){let r=Array.from(v.entries());r.sort((t,o)=>t[1].timestamp-o[1].timestamp),r.slice(0,v.size-Ae).forEach(([t])=>v.delete(t));}}function tt(){let{isAuthenticated:r,account:e}=A(),t=N(),[o,i]=useState([]),[a,g]=useState([]),[u,l]=useState(false),[n,h]=useState(null),f=useCallback(async()=>{if(!r||!e){i([]),g([]);return}let d=e.homeAccountId,y=v.get(d);if(y&&Date.now()-y.timestamp<Xe){i(y.roles),g(y.groups);return}l(true),h(null);try{let M=e.idTokenClaims?.roles||[],$=(await t.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(se=>se.id);v.set(d,{roles:M,groups:$,timestamp:Date.now()}),et(),i(M),g($);}catch(R){let V=w(R),$=new Error(V);h($),console.error("[Roles] Failed to fetch roles/groups:",V);let Re=e.idTokenClaims?.roles||[];i(Re);}finally{l(false);}},[r,e,t]),c=useCallback(d=>o.includes(d),[o]),s=useCallback(d=>a.includes(d),[a]),m=useCallback(d=>d.some(y=>o.includes(y)),[o]),p=useCallback(d=>d.every(y=>o.includes(y)),[o]);return useEffect(()=>(f(),()=>{e&&Ye(e.homeAccountId);}),[f,e]),{roles:o,groups:a,loading:u,error:n,hasRole:c,hasGroup:s,hasAnyRole:m,hasAllRoles:p,refetch:f}}function rt(r,e={}){let{displayName:t,...o}=e,i=a=>jsx(re,{...o,children:jsx(r,{...a})});return i.displayName=t||`withAuth(${r.displayName||r.name||"Component"})`,i}async function Pe(r,e={}){let{maxRetries:t=3,initialDelay:o=1e3,maxDelay:i=1e4,backoffMultiplier:a=2,debug:g=false}=e,u,l=o;for(let n=0;n<=t;n++)try{return g&&n>0&&console.log(`[TokenRetry] Attempt ${n+1}/${t+1}`),await r()}catch(h){if(u=h,n===t){g&&console.error("[TokenRetry] All retry attempts failed");break}if(!ot(h))throw g&&console.log("[TokenRetry] Non-retryable error, aborting"),h;g&&console.warn(`[TokenRetry] Attempt ${n+1} failed, retrying in ${l}ms...`),await nt(l),l=Math.min(l*a,i);}throw u}function ot(r){let e=r.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function nt(r){return new Promise(e=>setTimeout(e,r))}function it(r,e={}){return (...t)=>Pe(()=>r(...t),e)}var B=class{constructor(e={}){this.logHistory=[];this.performanceTimings=new Map;this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info",enablePerformance:e.enablePerformance??false,enableNetworkLogs:e.enableNetworkLogs??false,maxHistorySize:e.maxHistorySize??100};}shouldLog(e){if(!this.config.enabled)return false;let t=["error","warn","info","debug"],o=t.indexOf(this.config.level);return t.indexOf(e)<=o}formatMessage(e,t,o){let i=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",a=this.config.prefix,g=`[${e.toUpperCase()}]`,u=`${i} ${a} ${g} ${t}`;return o!==void 0&&(u+=`
2
- `+JSON.stringify(o,null,2)),u}addToHistory(e,t,o){this.logHistory.length>=this.config.maxHistorySize&&this.logHistory.shift(),this.logHistory.push({timestamp:Date.now(),level:e,message:t,data:o});}error(e,t){this.shouldLog("error")&&(console.error(this.formatMessage("error",e,t)),this.addToHistory("error",e,t));}warn(e,t){this.shouldLog("warn")&&(console.warn(this.formatMessage("warn",e,t)),this.addToHistory("warn",e,t));}info(e,t){this.shouldLog("info")&&(console.info(this.formatMessage("info",e,t)),this.addToHistory("info",e,t));}debug(e,t){this.shouldLog("debug")&&(console.debug(this.formatMessage("debug",e,t)),this.addToHistory("debug",e,t));}group(e){this.config.enabled&&console.group(`${this.config.prefix} ${e}`);}groupEnd(){this.config.enabled&&console.groupEnd();}startTiming(e){this.config.enablePerformance&&(this.performanceTimings.set(e,{operation:e,startTime:performance.now()}),this.debug(`\u23F1\uFE0F Started: ${e}`));}endTiming(e){if(this.config.enablePerformance){let t=this.performanceTimings.get(e);if(t)return t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.info(`\u23F1\uFE0F Completed: ${e} (${t.duration.toFixed(2)}ms)`),t.duration}}logRequest(e,t,o){this.config.enableNetworkLogs&&this.debug(`\u{1F310} ${e} ${t}`,o);}logResponse(e,t,o,i){if(this.config.enableNetworkLogs){let a=o>=200&&o<300?"\u2705":"\u274C";this.debug(`${a} ${e} ${t} - ${o}`,i);}}getHistory(){return [...this.logHistory]}getPerformanceTimings(){return Array.from(this.performanceTimings.values())}clearHistory(){this.logHistory=[];}clearTimings(){this.performanceTimings.clear();}exportLogs(){return JSON.stringify({config:this.config,history:this.logHistory,performanceTimings:Array.from(this.performanceTimings.values()),exportedAt:new Date().toISOString()},null,2)}downloadLogs(e="msal-next-debug-logs.json"){if(typeof window>"u")return;let t=this.exportLogs(),o=new Blob([t],{type:"application/json"}),i=URL.createObjectURL(o),a=document.createElement("a");a.href=i,a.download=e,a.click(),URL.revokeObjectURL(i);}setEnabled(e){this.config.enabled=e;}setLevel(e){e&&(this.config.level=e);}},O=null;function st(r){return O?r&&(r.enabled!==void 0&&O.setEnabled(r.enabled),r.level&&O.setLevel(r.level)):O=new B(r),O}function at(r,e){return new B({...e,prefix:`[MSAL-Next:${r}]`})}function _({children:r,config:e,defaultRedirectTo:t="/login",defaultLoading:o,defaultUnauthorized:i,debug:a=false}){let g=useRouter(),{isAuthenticated:u,account:l,inProgress:n}=A(),[h,f]=useState(true),[c,s]=useState(false);return useEffect(()=>{async function m(){if(a&&console.log("[ProtectedPage] Checking auth...",{isAuthenticated:u,inProgress:n,config:e}),!n){if(!e.required){s(true),f(false);return}if(!u||!l){a&&console.log("[ProtectedPage] Not authenticated, redirecting...");let p=e.redirectTo||t,d=encodeURIComponent(window.location.pathname+window.location.search);g.push(`${p}?returnUrl=${d}`);return}if(e.roles&&e.roles.length>0){let p=l.idTokenClaims?.roles||[];if(!e.roles.some(y=>p.includes(y))){a&&console.log("[ProtectedPage] Missing required role",{required:e.roles,user:p}),s(false),f(false);return}}if(e.validate)try{if(!await e.validate(l)){a&&console.log("[ProtectedPage] Custom validation failed"),s(!1),f(!1);return}}catch(p){console.error("[ProtectedPage] Validation error:",p),s(false),f(false);return}a&&console.log("[ProtectedPage] Authorization successful"),s(true),f(false);}}m();},[u,l,n,e,g,t,a]),h||n?e.loading?jsx(Fragment,{children:e.loading}):o?jsx(Fragment,{children:o}):jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"})}):c?jsx(Fragment,{children:r}):e.unauthorized?jsx(Fragment,{children:e.unauthorized}):i?jsx(Fragment,{children:i}):jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsxs("div",{className:"text-center",children:[jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-2",children:"Access Denied"}),jsx("p",{className:"text-gray-600",children:"You don't have permission to access this page."})]})})}function we(r,e,t){let o=i=>jsx(_,{config:e,defaultRedirectTo:t?.defaultRedirectTo,defaultLoading:t?.defaultLoading,defaultUnauthorized:t?.defaultUnauthorized,debug:t?.debug,children:jsx(r,{...i})});return o.displayName=`withPageAuth(${r.displayName||r.name||"Component"})`,o}function dt(r={}){let{protectedRoutes:e=[],publicOnlyRoutes:t=[],loginPath:o="/login",redirectAfterLogin:i="/",sessionCookie:a="msal.account",isAuthenticated:g,debug:u=false}=r;return async function(n){let{pathname:h}=n.nextUrl;u&&console.log("[AuthMiddleware] Processing:",h);let f=false;g?f=await g(n):f=!!n.cookies.get(a)?.value,u&&console.log("[AuthMiddleware] Authenticated:",f);let c=e.some(p=>h.startsWith(p)),s=t.some(p=>h.startsWith(p));if(c&&!f){u&&console.log("[AuthMiddleware] Redirecting to login");let p=n.nextUrl.clone();return p.pathname=o,p.searchParams.set("returnUrl",h),NextResponse.redirect(p)}if(s&&f){u&&console.log("[AuthMiddleware] Redirecting to home");let p=n.nextUrl.searchParams.get("returnUrl"),d=n.nextUrl.clone();return d.pathname=p||i,d.searchParams.delete("returnUrl"),NextResponse.redirect(d)}let m=NextResponse.next();if(f){m.headers.set("x-msal-authenticated","true");try{let p=n.cookies.get(a);if(p?.value){let d=H(p.value,W);d?.username&&m.headers.set("x-msal-username",d.username);}}catch{u&&console.warn("[AuthMiddleware] Failed to parse session data");}}return m}}export{re as AuthGuard,je as AuthStatus,ne as ErrorBoundary,Fe as MSALProvider,$e as MicrosoftSignInButton,J as MsalAuthProvider,_ as ProtectedPage,qe as SignOutButton,We as UserAvatar,dt as createAuthMiddleware,j as createMsalConfig,it as createRetryWrapper,at as createScopedLogger,st as getDebugLogger,Ue as getMsalInstance,W as isValidAccountData,z as isValidRedirectUri,ae as isValidScope,Pe as retryWithBackoff,H as safeJsonParse,w as sanitizeError,N as useGraphApi,A as useMsalAuth,tt as useRoles,Q as useUserProfile,Ce as validateScopes,rt as withAuth,we as withPageAuth};
1
+ import {MsalProvider,useMsal,useAccount}from'@azure/msal-react';export{useAccount,useIsAuthenticated,useMsal}from'@azure/msal-react';import {LogLevel,PublicClientApplication,EventType,InteractionStatus}from'@azure/msal-browser';import {createContext,useState,useRef,useEffect,useMemo,useCallback,Component}from'react';import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {useRouter}from'next/navigation';import {NextResponse}from'next/server';function j(t,e){try{let r=JSON.parse(t);return e(r)?r:(console.warn("[Validation] JSON validation failed"),null)}catch(r){return console.error("[Validation] JSON parse error:",r),null}}function Z(t){return typeof t=="object"&&t!==null&&typeof t.homeAccountId=="string"&&t.homeAccountId.length>0&&typeof t.username=="string"&&t.username.length>0&&(t.name===void 0||typeof t.name=="string")}function R(t){return t instanceof Error?t.message.replace(/[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}/g,"[TOKEN_REDACTED]").replace(/[a-f0-9]{32,}/gi,"[SECRET_REDACTED]").replace(/Bearer\s+[^\s]+/gi,"Bearer [REDACTED]"):"An unexpected error occurred"}function V(t,e){try{let r=new URL(t);return e.some(o=>{let i=new URL(o);return r.origin===i.origin})}catch{return false}}function fe(t){return /^[a-zA-Z0-9._-]+$/.test(t)}function Ne(t){return Array.isArray(t)&&t.every(fe)}function X(t){if(t.msalConfig)return t.msalConfig;let{clientId:e,tenantId:r,authorityType:o="common",redirectUri:i,postLogoutRedirectUri:s,cacheLocation:p="sessionStorage",storeAuthStateInCookie:u=false,navigateToLoginRequestUrl:l=false,enableLogging:a=false,loggerCallback:m,allowedRedirectUris:h}=t;if(!e)throw new Error("@chemmangat/msal-next: clientId is required");let c=()=>{if(o==="tenant"){if(!r)throw new Error('@chemmangat/msal-next: tenantId is required when authorityType is "tenant"');return `https://login.microsoftonline.com/${r}`}return `https://login.microsoftonline.com/${o}`},n=typeof window<"u"?window.location.origin:"http://localhost:3000",f=i||n;if(h&&h.length>0){if(!V(f,h))throw new Error(`@chemmangat/msal-next: redirectUri "${f}" is not in the allowed list`);let d=s||f;if(!V(d,h))throw new Error(`@chemmangat/msal-next: postLogoutRedirectUri "${d}" is not in the allowed list`)}return {auth:{clientId:e,authority:c(),redirectUri:f,postLogoutRedirectUri:s||f,navigateToLoginRequestUrl:l},cache:{cacheLocation:p,storeAuthStateInCookie:u},system:{loggerOptions:{loggerCallback:m||((d,y,C)=>{if(!(C||!a))switch(d){case LogLevel.Error:console.error("[MSAL]",y);break;case LogLevel.Warning:console.warn("[MSAL]",y);break;case LogLevel.Info:console.info("[MSAL]",y);break;case LogLevel.Verbose:console.debug("[MSAL]",y);break}}),logLevel:a?LogLevel.Verbose:LogLevel.Error}}}}var J=null,ge=false;function Y(t){if(process.env.NODE_ENV!=="development")return {valid:true,warnings:[],errors:[]};if(J)return J;let e=[],r=[];if(t.clientId?he(t.clientId)?e.push({field:"clientId",message:"Client ID appears to be a placeholder",fix:`Replace the placeholder with your actual Application (client) ID from Azure Portal.
2
+
3
+ Current value: ${t.clientId}
4
+ Expected format: 12345678-1234-1234-1234-123456789012 (GUID)`}):me(t.clientId)||e.push({field:"clientId",message:"Client ID format is invalid",fix:`Client ID should be a GUID (UUID) format.
5
+
6
+ Current value: ${t.clientId}
7
+ Expected format: 12345678-1234-1234-1234-123456789012
8
+
9
+ Get the correct value from: Azure Portal \u2192 App registrations \u2192 Your app`}):r.push({field:"clientId",message:"Client ID is missing",fix:`Add NEXT_PUBLIC_AZURE_AD_CLIENT_ID to your .env.local file.
10
+
11
+ Get it from: Azure Portal \u2192 App registrations \u2192 Your app \u2192 Application (client) ID`}),t.tenantId&&(he(t.tenantId)?e.push({field:"tenantId",message:"Tenant ID appears to be a placeholder",fix:`Replace the placeholder with your actual Directory (tenant) ID from Azure Portal.
12
+
13
+ Current value: ${t.tenantId}
14
+ Expected format: 87654321-4321-4321-4321-210987654321 (GUID)
15
+
16
+ Or remove tenantId and use authorityType: 'common' for multi-tenant apps.`}):me(t.tenantId)||e.push({field:"tenantId",message:"Tenant ID format is invalid",fix:`Tenant ID should be a GUID (UUID) format.
17
+
18
+ Current value: ${t.tenantId}
19
+ Expected format: 87654321-4321-4321-4321-210987654321
20
+
21
+ Get the correct value from: Azure Portal \u2192 Azure Active Directory \u2192 Properties \u2192 Tenant ID`})),t.redirectUri&&(ke(t.redirectUri)&&!t.redirectUri.startsWith("https://")&&r.push({field:"redirectUri",message:"Production redirect URI must use HTTPS",fix:`Change your redirect URI to use HTTPS in production.
22
+
23
+ Current value: ${t.redirectUri}
24
+ Should be: ${t.redirectUri.replace("http://","https://")}
25
+
26
+ HTTP is only allowed for localhost development.`}),_e(t.redirectUri)||r.push({field:"redirectUri",message:"Redirect URI is not a valid URL",fix:`Provide a valid URL for redirectUri.
27
+
28
+ Current value: ${t.redirectUri}
29
+ Expected format: https://yourdomain.com or http://localhost:3000`})),t.scopes&&t.scopes.length>0){let i=t.scopes.filter(s=>!Fe(s));i.length>0&&e.push({field:"scopes",message:"Some scopes have invalid format",fix:`Invalid scopes: ${i.join(", ")}
30
+
31
+ Scopes should be in format: "Resource.Permission" (e.g., "User.Read", "Mail.Read")
32
+
33
+ Common scopes:
34
+ \u2022 User.Read - Read user profile
35
+ \u2022 Mail.Read - Read user mail
36
+ \u2022 Calendars.Read - Read user calendars
37
+ \u2022 Files.Read - Read user files`});}if(typeof window<"u"){let i=process.env.NEXT_PUBLIC_AZURE_AD_CLIENT_ID,s=process.env.NEXT_PUBLIC_AZURE_AD_TENANT_ID;i||e.push({field:"environment",message:"NEXT_PUBLIC_AZURE_AD_CLIENT_ID not found in environment",fix:`Add NEXT_PUBLIC_AZURE_AD_CLIENT_ID to your .env.local file:
38
+
39
+ NEXT_PUBLIC_AZURE_AD_CLIENT_ID=your-client-id-here
40
+
41
+ Then restart your development server.`}),!s&&t.authorityType==="tenant"&&e.push({field:"environment",message:'NEXT_PUBLIC_AZURE_AD_TENANT_ID not found but authorityType is "tenant"',fix:`Either:
42
+ 1. Add NEXT_PUBLIC_AZURE_AD_TENANT_ID to your .env.local file, OR
43
+ 2. Change authorityType to 'common' for multi-tenant support
44
+
45
+ For single-tenant apps:
46
+ NEXT_PUBLIC_AZURE_AD_TENANT_ID=your-tenant-id-here`});}let o={valid:r.length===0,warnings:e,errors:r};return J=o,o}function K(t){if(!(ge||process.env.NODE_ENV!=="development")){if(ge=true,t.valid&&t.warnings.length===0){console.log("\u2705 MSAL configuration validated successfully");return}console.group("\u{1F50D} MSAL Configuration Validation"),t.errors.length>0&&(console.group("\u274C Errors (must fix)"),t.errors.forEach(e=>{console.error(`
47
+ ${e.field}:`),console.error(` ${e.message}`),console.error(`
48
+ Fix:
49
+ ${e.fix.split(`
50
+ `).join(`
51
+ `)}`);}),console.groupEnd()),t.warnings.length>0&&(console.group("\u26A0\uFE0F Warnings (should fix)"),t.warnings.forEach(e=>{console.warn(`
52
+ ${e.field}:`),console.warn(` ${e.message}`),console.warn(`
53
+ Fix:
54
+ ${e.fix.split(`
55
+ `).join(`
56
+ `)}`);}),console.groupEnd()),console.groupEnd();}}function he(t){let e=["your-client-id","your-tenant-id","your-client-id-here","your-tenant-id-here","client-id","tenant-id","replace-me","changeme","placeholder","example","xxx","000"],r=t.toLowerCase();return e.some(o=>r.includes(o))}function me(t){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)}function ke(t){return !t.includes("localhost")&&!t.includes("127.0.0.1")}function _e(t){try{return new URL(t),!0}catch{return false}}function Fe(t){return /^([a-zA-Z0-9]+\.[a-zA-Z0-9]+|https?:\/\/.+)$/.test(t)}var Q={AADSTS50011:{message:"Redirect URI mismatch",fix:`Your redirect URI doesn't match what's configured in Azure AD.
57
+
58
+ Fix:
59
+ 1. Go to Azure Portal \u2192 Azure Active Directory \u2192 App registrations
60
+ 2. Select your app \u2192 Authentication
61
+ 3. Under "Single-page application", add your redirect URI:
62
+ \u2022 http://localhost:3000 (for development)
63
+ \u2022 https://yourdomain.com (for production)
64
+ 4. Click "Save"
65
+
66
+ Current redirect URI: ${typeof window<"u"?window.location.origin:"unknown"}`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/reply-url"},AADSTS65001:{message:"Admin consent required",fix:`Your app requires admin consent for the requested permissions.
67
+
68
+ Fix:
69
+ 1. Go to Azure Portal \u2192 Azure Active Directory \u2192 App registrations
70
+ 2. Select your app \u2192 API permissions
71
+ 3. Click "Grant admin consent for [Your Organization]"
72
+ 4. Confirm the consent
73
+
74
+ Alternatively, ask your Azure AD administrator to grant consent.`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-admin-consent"},AADSTS700016:{message:"Invalid client application",fix:`The application ID (client ID) is not found in the directory.
75
+
76
+ Fix:
77
+ 1. Verify your NEXT_PUBLIC_AZURE_AD_CLIENT_ID in .env.local
78
+ 2. Ensure the app registration exists in Azure Portal
79
+ 3. Check that you're using the correct tenant
80
+
81
+ Current client ID: Check your environment variables`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes"},AADSTS90002:{message:"Invalid tenant",fix:`The tenant ID is invalid or not found.
82
+
83
+ Fix:
84
+ 1. Verify your NEXT_PUBLIC_AZURE_AD_TENANT_ID in .env.local
85
+ 2. Ensure you're using the correct tenant ID (GUID format)
86
+ 3. For multi-tenant apps, use authorityType: 'common' instead
87
+
88
+ Current tenant ID: Check your environment variables`,docs:"https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-national-cloud"},user_cancelled:{message:"User cancelled authentication",fix:"The user closed the authentication window or cancelled the login process. This is normal user behavior.",docs:void 0},no_token_request_cache_error:{message:"No cached token request",fix:`This usually happens when the page is refreshed during authentication.
89
+
90
+ This is normal and will be handled automatically. If the issue persists:
91
+ 1. Clear your browser cache and cookies
92
+ 2. Try logging in again
93
+ 3. Ensure cookies are enabled in your browser`,docs:void 0},interaction_required:{message:"User interaction required",fix:`The token cannot be acquired silently and requires user interaction.
94
+
95
+ This is normal behavior. The app will redirect you to sign in.`,docs:void 0},consent_required:{message:"User consent required",fix:`Additional consent is required for the requested permissions.
96
+
97
+ This is normal behavior. You'll be prompted to grant consent.`,docs:void 0}},T=class t extends Error{constructor(e){let r=t.parseError(e);super(r.message),this.name="MsalError",this.code=r.code,this.fix=r.fix,this.docs=r.docs,this.originalError=e,Error.captureStackTrace&&Error.captureStackTrace(this,t);}static parseError(e){if(e&&typeof e=="object"){let r=e,o=r.errorCode||r.error||r.code;if(o&&Q[o]){let s=Q[o];return {message:s.message,code:o,fix:s.fix,docs:s.docs}}let i=r.errorMessage||r.message||String(e);for(let[s,p]of Object.entries(Q))if(i.includes(s))return {message:p.message,code:s,fix:p.fix,docs:p.docs};return {message:i||"Authentication error occurred",code:o}}return {message:"An unexpected authentication error occurred"}}toConsoleString(){if(!(process.env.NODE_ENV==="development"))return this.message;let r=`
98
+ \u{1F6A8} MSAL Authentication Error
99
+ `;return r+=`
100
+ Error: ${this.message}
101
+ `,this.code&&(r+=`Code: ${this.code}
102
+ `),this.fix&&(r+=`
103
+ \u{1F4A1} How to fix:
104
+ ${this.fix}
105
+ `),this.docs&&(r+=`
106
+ \u{1F4DA} Documentation: ${this.docs}
107
+ `),r}isUserCancellation(){return this.code==="user_cancelled"}requiresInteraction(){return this.code==="interaction_required"||this.code==="consent_required"}};function P(t){return t instanceof T?t:new T(t)}function $e(t){let e={errorCode:"missing_env_var",errorMessage:`Missing environment variable: ${t}`,message:`${t} not found`},r=`Environment variable ${t} is not set.
108
+
109
+ Fix:
110
+ 1. Copy .env.local.example to .env.local (if it exists)
111
+ 2. Add the following to your .env.local file:
112
+
113
+ ${t}=your-value-here
114
+
115
+ 3. Get the value from Azure Portal:
116
+ \u2022 Go to Azure Active Directory \u2192 App registrations
117
+ \u2022 Select your app
118
+ \u2022 Copy the ${t.includes("CLIENT_ID")?"Application (client) ID":"Directory (tenant) ID"}
119
+
120
+ 4. Restart your development server
121
+
122
+ Note: Environment variables starting with NEXT_PUBLIC_ are exposed to the browser.`;return new T({...e,fix:r,docs:"https://nextjs.org/docs/basic-features/environment-variables"})}var Ae=null;function Be(){return Ae}function ee({children:t,loadingComponent:e,onInitialized:r,...o}){let[i,s]=useState(null),p=useRef(null);return useEffect(()=>{if(typeof window>"u"||p.current)return;(async()=>{try{if(process.env.NODE_ENV==="development"){let c=Y(o);K(c);}let l=X(o),a=new PublicClientApplication(l);await a.initialize();try{let c=await a.handleRedirectPromise();c&&(o.enableLogging&&console.log("[MSAL] Redirect authentication successful"),c.account&&a.setActiveAccount(c.account),window.location.hash&&window.history.replaceState(null,"",window.location.pathname+window.location.search));}catch(c){let n=P(c);n.code==="no_token_request_cache_error"?o.enableLogging&&console.log("[MSAL] No pending redirect found (this is normal)"):n.isUserCancellation()?o.enableLogging&&console.log("[MSAL] User cancelled authentication"):process.env.NODE_ENV==="development"?console.error(n.toConsoleString()):console.error("[MSAL] Redirect handling error:",n.message),window.location.hash&&(window.location.hash.includes("code=")||window.location.hash.includes("error="))&&window.history.replaceState(null,"",window.location.pathname+window.location.search);}let m=a.getAllAccounts();m.length>0&&!a.getActiveAccount()&&a.setActiveAccount(m[0]);let h=o.enableLogging||!1;a.addEventCallback(c=>{if(c.eventType===EventType.LOGIN_SUCCESS){let n=c.payload;n?.account&&a.setActiveAccount(n.account),h&&console.log("[MSAL] Login successful:",n.account?.username);}if(c.eventType===EventType.LOGIN_FAILURE&&console.error("[MSAL] Login failed:",c.error),c.eventType===EventType.LOGOUT_SUCCESS&&(a.setActiveAccount(null),h&&console.log("[MSAL] Logout successful")),c.eventType===EventType.ACQUIRE_TOKEN_SUCCESS){let n=c.payload;n?.account&&!a.getActiveAccount()&&a.setActiveAccount(n.account);}c.eventType===EventType.ACQUIRE_TOKEN_FAILURE&&h&&console.error("[MSAL] Token acquisition failed:",c.error);}),p.current=a,Ae=a,s(a),r&&r(a);}catch(l){throw console.error("[MSAL] Initialization failed:",l),l}})();},[]),typeof window>"u"?jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})}):i?jsx(MsalProvider,{instance:i,children:t}):jsx(Fragment,{children:e||jsx("div",{children:"Loading authentication..."})})}var We=createContext(void 0);function je({children:t,protection:e,...r}){return jsx(We.Provider,{value:e,children:jsx(ee,{...r,children:t})})}var te=new Map;function A(t=["User.Read"]){let{instance:e,accounts:r,inProgress:o}=useMsal(),i=useAccount(r[0]||null),s=useMemo(()=>r.length>0,[r]),p=useCallback(async(c=t)=>{if(o!==InteractionStatus.None){console.warn("[MSAL] Interaction already in progress");return}try{let n={scopes:c,prompt:"select_account"};await e.loginRedirect(n);}catch(n){let f=P(n);if(f.isUserCancellation()){console.log("[MSAL] User cancelled login");return}throw process.env.NODE_ENV==="development"?console.error(f.toConsoleString()):console.error("[MSAL] Login redirect failed:",f.message),f}},[e,t,o]),u=useCallback(async()=>{try{await e.logoutRedirect({account:i||void 0});}catch(c){let n=P(c);throw process.env.NODE_ENV==="development"?console.error(n.toConsoleString()):console.error("[MSAL] Logout redirect failed:",n.message),n}},[e,i]),l=useCallback(async(c=t)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let n={scopes:c,account:i,forceRefresh:!1};return (await e.acquireTokenSilent(n)).accessToken}catch(n){let f=P(n);throw process.env.NODE_ENV==="development"?console.error(f.toConsoleString()):console.error("[MSAL] Silent token acquisition failed:",f.message),f}},[e,i,t]),a=useCallback(async(c=t)=>{if(!i)throw new Error("[MSAL] No active account. Please login first.");try{let n={scopes:c,account:i};await e.acquireTokenRedirect(n);}catch(n){let f=P(n);throw process.env.NODE_ENV==="development"?console.error(f.toConsoleString()):console.error("[MSAL] Token redirect acquisition failed:",f.message),f}},[e,i,t]),m=useCallback(async(c=t)=>{let n=`${i?.homeAccountId||"anonymous"}-${c.sort().join(",")}`,f=te.get(n);if(f)return f;let g=(async()=>{try{return await l(c)}catch{throw console.warn("[MSAL] Silent token acquisition failed, falling back to redirect"),await a(c),new Error("[MSAL] Redirecting for token acquisition")}finally{te.delete(n);}})();return te.set(n,g),g},[l,a,t,i]),h=useCallback(async()=>{e.setActiveAccount(null),await e.clearCache();},[e]);return {account:i,accounts:r,isAuthenticated:s,inProgress:o!==InteractionStatus.None,loginRedirect:p,logoutRedirect:u,acquireToken:m,acquireTokenSilent:l,acquireTokenRedirect:a,clearSession:h}}function Ke({text:t="Sign in with Microsoft",variant:e="dark",size:r="medium",scopes:o,className:i="",style:s,onSuccess:p,onError:u}){let{loginRedirect:l,inProgress:a}=A(),[m,h]=useState(false),c=async()=>{h(true);try{await l(o),p?.();}catch(y){u?.(y);}finally{setTimeout(()=>h(false),500);}},n={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},f={dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}},g=a||m,d={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:g?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:g?.6:1,...f[e],...n[r],...s};return jsxs("button",{onClick:c,disabled:g,className:i,style:d,"aria-label":t,children:[jsx(Qe,{}),jsx("span",{children:t})]})}function Qe(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function et({text:t="Sign out",variant:e="dark",size:r="medium",className:o="",style:i,onSuccess:s,onError:p}){let{logoutRedirect:u,inProgress:l}=A(),a=async()=>{try{await u(),s?.();}catch(n){p?.(n);}},m={small:{padding:"8px 16px",fontSize:"14px",height:"36px"},medium:{padding:"10px 20px",fontSize:"15px",height:"41px"},large:{padding:"12px 24px",fontSize:"16px",height:"48px"}},c={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:"12px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontWeight:600,borderRadius:"2px",cursor:l?"not-allowed":"pointer",transition:"all 0.2s ease",opacity:l?.6:1,...{dark:{backgroundColor:"#2F2F2F",color:"#FFFFFF",border:"1px solid #8C8C8C"},light:{backgroundColor:"#FFFFFF",color:"#5E5E5E",border:"1px solid #8C8C8C"}}[e],...m[r],...i};return jsxs("button",{onClick:a,disabled:l,className:o,style:c,"aria-label":t,children:[jsx(tt,{}),jsx("span",{children:t})]})}function tt(){return jsxs("svg",{width:"21",height:"21",viewBox:"0 0 21 21",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsx("rect",{width:"10",height:"10",fill:"#F25022"}),jsx("rect",{x:"11",width:"10",height:"10",fill:"#7FBA00"}),jsx("rect",{y:"11",width:"10",height:"10",fill:"#00A4EF"}),jsx("rect",{x:"11",y:"11",width:"10",height:"10",fill:"#FFB900"})]})}function k(){let{acquireToken:t}=A(),e=useCallback(async(u,l={})=>{let{scopes:a=["User.Read"],version:m="v1.0",debug:h=false,...c}=l;try{let n=await t(a),f=`https://graph.microsoft.com/${m}`,g=u.startsWith("http")?u:`${f}${u.startsWith("/")?u:`/${u}`}`;h&&console.log("[GraphAPI] Request:",{url:g,method:c.method||"GET"});let d=await fetch(g,{...c,headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json",...c.headers}});if(!d.ok){let C=await d.text(),D=`Graph API error (${d.status}): ${C}`;throw new Error(D)}if(d.status===204||d.headers.get("content-length")==="0")return null;let y=await d.json();return h&&console.log("[GraphAPI] Response:",y),y}catch(n){let f=R(n);throw console.error("[GraphAPI] Request failed:",f),new Error(f)}},[t]),r=useCallback((u,l={})=>e(u,{...l,method:"GET"}),[e]),o=useCallback((u,l,a={})=>e(u,{...a,method:"POST",body:l?JSON.stringify(l):void 0}),[e]),i=useCallback((u,l,a={})=>e(u,{...a,method:"PUT",body:l?JSON.stringify(l):void 0}),[e]),s=useCallback((u,l,a={})=>e(u,{...a,method:"PATCH",body:l?JSON.stringify(l):void 0}),[e]),p=useCallback((u,l={})=>e(u,{...l,method:"DELETE"}),[e]);return {get:r,post:o,put:i,patch:s,delete:p,request:e}}var b=new Map,rt=300*1e3,Ce=100;function ot(){if(b.size>Ce){let t=Array.from(b.entries());t.sort((r,o)=>r[1].timestamp-o[1].timestamp),t.slice(0,b.size-Ce).forEach(([r])=>{let o=b.get(r);o?.data.photo&&URL.revokeObjectURL(o.data.photo),b.delete(r);});}}function oe(){let{isAuthenticated:t,account:e}=A(),r=k(),[o,i]=useState(null),[s,p]=useState(false),[u,l]=useState(null),a=useCallback(async()=>{if(!t||!e){i(null);return}let h=e.homeAccountId,c=b.get(h);if(c&&Date.now()-c.timestamp<rt){i(c.data);return}p(true),l(null);try{let n=await r.get("/me",{scopes:["User.Read"]}),f;try{let d=await r.get("/me/photo/$value",{scopes:["User.Read"],headers:{"Content-Type":"image/jpeg"}});d&&(f=URL.createObjectURL(d));}catch{console.debug("[UserProfile] Photo not available");}let g={id:n.id,displayName:n.displayName,givenName:n.givenName,surname:n.surname,userPrincipalName:n.userPrincipalName,mail:n.mail,jobTitle:n.jobTitle,department:n.department,companyName:n.companyName,officeLocation:n.officeLocation,mobilePhone:n.mobilePhone,businessPhones:n.businessPhones,preferredLanguage:n.preferredLanguage,employeeId:n.employeeId,employeeHireDate:n.employeeHireDate,employeeType:n.employeeType,country:n.country,city:n.city,state:n.state,streetAddress:n.streetAddress,postalCode:n.postalCode,usageLocation:n.usageLocation,manager:n.manager,aboutMe:n.aboutMe,birthday:n.birthday,interests:n.interests,skills:n.skills,schools:n.schools,pastProjects:n.pastProjects,responsibilities:n.responsibilities,mySite:n.mySite,faxNumber:n.faxNumber,accountEnabled:n.accountEnabled,ageGroup:n.ageGroup,userType:n.userType,photo:f,...n};b.set(h,{data:g,timestamp:Date.now()}),ot(),i(g);}catch(n){let g=R(n),d=new Error(g);l(d),console.error("[UserProfile] Failed to fetch profile:",g);}finally{p(false);}},[t,e,r]),m=useCallback(()=>{if(e){let h=b.get(e.homeAccountId);h?.data.photo&&URL.revokeObjectURL(h.data.photo),b.delete(e.homeAccountId);}o?.photo&&URL.revokeObjectURL(o.photo),i(null);},[e,o]);return useEffect(()=>(a(),()=>{o?.photo&&URL.revokeObjectURL(o.photo);}),[a]),useEffect(()=>()=>{o?.photo&&URL.revokeObjectURL(o.photo);},[o?.photo]),{profile:o,loading:s,error:u,refetch:a,clearCache:m}}function it({size:t=40,className:e="",style:r,showTooltip:o=true,fallbackImage:i}){let{profile:s,loading:p}=oe(),[u,l]=useState(null),[a,m]=useState(false);useEffect(()=>{s?.photo&&l(s.photo);},[s?.photo]);let h=()=>{if(!s)return "?";let{givenName:f,surname:g,displayName:d}=s;if(f&&g)return `${f[0]}${g[0]}`.toUpperCase();if(d){let y=d.split(" ");return y.length>=2?`${y[0][0]}${y[y.length-1][0]}`.toUpperCase():d.substring(0,2).toUpperCase()}return "?"},c={width:`${t}px`,height:`${t}px`,borderRadius:"50%",display:"inline-flex",alignItems:"center",justifyContent:"center",fontSize:`${t*.4}px`,fontWeight:600,fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',backgroundColor:"#0078D4",color:"#FFFFFF",overflow:"hidden",userSelect:"none",...r},n=s?.displayName||"User";return p?jsx("div",{className:e,style:{...c,backgroundColor:"#E1E1E1"},"aria-label":"Loading user avatar",children:jsx("span",{style:{fontSize:`${t*.3}px`},children:"..."})}):u&&!a?jsx("div",{className:e,style:c,title:o?n:void 0,"aria-label":`${n} avatar`,children:jsx("img",{src:u,alt:n,style:{width:"100%",height:"100%",objectFit:"cover"},onError:()=>{m(true),i&&l(i);}})}):jsx("div",{className:e,style:c,title:o?n:void 0,"aria-label":`${n} avatar`,children:h()})}function st({className:t="",style:e,showDetails:r=false,renderLoading:o,renderAuthenticated:i,renderUnauthenticated:s}){let{isAuthenticated:p,inProgress:u,account:l}=A(),a={display:"inline-flex",alignItems:"center",gap:"8px",padding:"8px 12px",borderRadius:"4px",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',fontSize:"14px",fontWeight:500,...e};if(u)return o?jsx(Fragment,{children:o()}):jsxs("div",{className:t,style:{...a,backgroundColor:"#FFF4CE",color:"#8A6D3B"},role:"status","aria-live":"polite",children:[jsx(ne,{color:"#FFA500"}),jsx("span",{children:"Loading..."})]});if(p){let m=l?.username||l?.name||"User";return i?jsx(Fragment,{children:i(m)}):jsxs("div",{className:t,style:{...a,backgroundColor:"#D4EDDA",color:"#155724"},role:"status","aria-live":"polite",children:[jsx(ne,{color:"#28A745"}),jsx("span",{children:r?`Authenticated as ${m}`:"Authenticated"})]})}return s?jsx(Fragment,{children:s()}):jsxs("div",{className:t,style:{...a,backgroundColor:"#F8D7DA",color:"#721C24"},role:"status","aria-live":"polite",children:[jsx(ne,{color:"#DC3545"}),jsx("span",{children:"Not authenticated"})]})}function ne({color:t}){return jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:jsx("circle",{cx:"4",cy:"4",r:"4",fill:t})})}function le({children:t,loadingComponent:e,fallbackComponent:r,scopes:o,onAuthRequired:i}){let{isAuthenticated:s,inProgress:p,loginRedirect:u}=A();return useEffect(()=>{!s&&!p&&(i?.(),(async()=>{try{await u(o);}catch(a){console.error("[AuthGuard] Authentication failed:",a);}})());},[s,p,o,u,i]),p?jsx(Fragment,{children:e||jsx("div",{children:"Authenticating..."})}):s?jsx(Fragment,{children:t}):jsx(Fragment,{children:r||jsx("div",{children:"Redirecting to login..."})})}var ue=class extends Component{constructor(r){super(r);this.reset=()=>{this.setState({hasError:false,error:null});};this.state={hasError:false,error:null};}static getDerivedStateFromError(r){return {hasError:true,error:r}}componentDidCatch(r,o){let{onError:i,debug:s}=this.props;s&&(console.error("[ErrorBoundary] Caught error:",r),console.error("[ErrorBoundary] Error info:",o)),i?.(r,o);}render(){let{hasError:r,error:o}=this.state,{children:i,fallback:s}=this.props;return r&&o?s?s(o,this.reset):jsxs("div",{style:{padding:"20px",margin:"20px",border:"1px solid #DC3545",borderRadius:"4px",backgroundColor:"#F8D7DA",color:"#721C24",fontFamily:'"Segoe UI", Tahoma, Geneva, Verdana, sans-serif'},children:[jsx("h2",{style:{margin:"0 0 10px 0",fontSize:"18px"},children:"Authentication Error"}),jsx("p",{style:{margin:"0 0 10px 0"},children:o.message}),jsx("button",{onClick:this.reset,style:{padding:"8px 16px",backgroundColor:"#DC3545",color:"#FFFFFF",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"14px",fontWeight:600},children:"Try Again"})]}):i}};var E=new Map,dt=300*1e3,Te=100;function pt(t){t?E.delete(t):E.clear();}function ft(){if(E.size>Te){let t=Array.from(E.entries());t.sort((r,o)=>r[1].timestamp-o[1].timestamp),t.slice(0,E.size-Te).forEach(([r])=>E.delete(r));}}function gt(){let{isAuthenticated:t,account:e}=A(),r=k(),[o,i]=useState([]),[s,p]=useState([]),[u,l]=useState(false),[a,m]=useState(null),h=useCallback(async()=>{if(!t||!e){i([]),p([]);return}let d=e.homeAccountId,y=E.get(d);if(y&&Date.now()-y.timestamp<dt){i(y.roles),p(y.groups);return}l(true),m(null);try{let D=e.idTokenClaims?.roles||[],G=(await r.get("/me/memberOf",{scopes:["User.Read","Directory.Read.All"]})).value.map(pe=>pe.id);E.set(d,{roles:D,groups:G,timestamp:Date.now()}),ft(),i(D),p(G);}catch(C){let W=R(C),G=new Error(W);m(G),console.error("[Roles] Failed to fetch roles/groups:",W);let Me=e.idTokenClaims?.roles||[];i(Me);}finally{l(false);}},[t,e,r]),c=useCallback(d=>o.includes(d),[o]),n=useCallback(d=>s.includes(d),[s]),f=useCallback(d=>d.some(y=>o.includes(y)),[o]),g=useCallback(d=>d.every(y=>o.includes(y)),[o]);return useEffect(()=>(h(),()=>{e&&pt(e.homeAccountId);}),[h,e]),{roles:o,groups:s,loading:u,error:a,hasRole:c,hasGroup:n,hasAnyRole:f,hasAllRoles:g,refetch:h}}function ht(t,e={}){let{displayName:r,...o}=e,i=s=>jsx(le,{...o,children:jsx(t,{...s})});return i.displayName=r||`withAuth(${t.displayName||t.name||"Component"})`,i}async function Ue(t,e={}){let{maxRetries:r=3,initialDelay:o=1e3,maxDelay:i=1e4,backoffMultiplier:s=2,debug:p=false}=e,u,l=o;for(let a=0;a<=r;a++)try{return p&&a>0&&console.log(`[TokenRetry] Attempt ${a+1}/${r+1}`),await t()}catch(m){if(u=m,a===r){p&&console.error("[TokenRetry] All retry attempts failed");break}if(!mt(m))throw p&&console.log("[TokenRetry] Non-retryable error, aborting"),m;p&&console.warn(`[TokenRetry] Attempt ${a+1} failed, retrying in ${l}ms...`),await yt(l),l=Math.min(l*s,i);}throw u}function mt(t){let e=t.message.toLowerCase();return !!(e.includes("network")||e.includes("timeout")||e.includes("fetch")||e.includes("connection")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("429")||e.includes("rate limit")||e.includes("token")&&e.includes("expired"))}function yt(t){return new Promise(e=>setTimeout(e,t))}function At(t,e={}){return (...r)=>Ue(()=>t(...r),e)}var B=class{constructor(e={}){this.logHistory=[];this.performanceTimings=new Map;this.config={enabled:e.enabled??false,prefix:e.prefix??"[MSAL-Next]",showTimestamp:e.showTimestamp??true,level:e.level??"info",enablePerformance:e.enablePerformance??false,enableNetworkLogs:e.enableNetworkLogs??false,maxHistorySize:e.maxHistorySize??100};}shouldLog(e){if(!this.config.enabled)return false;let r=["error","warn","info","debug"],o=r.indexOf(this.config.level);return r.indexOf(e)<=o}formatMessage(e,r,o){let i=this.config.showTimestamp?`[${new Date().toISOString()}]`:"",s=this.config.prefix,p=`[${e.toUpperCase()}]`,u=`${i} ${s} ${p} ${r}`;return o!==void 0&&(u+=`
123
+ `+JSON.stringify(o,null,2)),u}addToHistory(e,r,o){this.logHistory.length>=this.config.maxHistorySize&&this.logHistory.shift(),this.logHistory.push({timestamp:Date.now(),level:e,message:r,data:o});}error(e,r){this.shouldLog("error")&&(console.error(this.formatMessage("error",e,r)),this.addToHistory("error",e,r));}warn(e,r){this.shouldLog("warn")&&(console.warn(this.formatMessage("warn",e,r)),this.addToHistory("warn",e,r));}info(e,r){this.shouldLog("info")&&(console.info(this.formatMessage("info",e,r)),this.addToHistory("info",e,r));}debug(e,r){this.shouldLog("debug")&&(console.debug(this.formatMessage("debug",e,r)),this.addToHistory("debug",e,r));}group(e){this.config.enabled&&console.group(`${this.config.prefix} ${e}`);}groupEnd(){this.config.enabled&&console.groupEnd();}startTiming(e){this.config.enablePerformance&&(this.performanceTimings.set(e,{operation:e,startTime:performance.now()}),this.debug(`\u23F1\uFE0F Started: ${e}`));}endTiming(e){if(this.config.enablePerformance){let r=this.performanceTimings.get(e);if(r)return r.endTime=performance.now(),r.duration=r.endTime-r.startTime,this.info(`\u23F1\uFE0F Completed: ${e} (${r.duration.toFixed(2)}ms)`),r.duration}}logRequest(e,r,o){this.config.enableNetworkLogs&&this.debug(`\u{1F310} ${e} ${r}`,o);}logResponse(e,r,o,i){if(this.config.enableNetworkLogs){let s=o>=200&&o<300?"\u2705":"\u274C";this.debug(`${s} ${e} ${r} - ${o}`,i);}}getHistory(){return [...this.logHistory]}getPerformanceTimings(){return Array.from(this.performanceTimings.values())}clearHistory(){this.logHistory=[];}clearTimings(){this.performanceTimings.clear();}exportLogs(){return JSON.stringify({config:this.config,history:this.logHistory,performanceTimings:Array.from(this.performanceTimings.values()),exportedAt:new Date().toISOString()},null,2)}downloadLogs(e="msal-next-debug-logs.json"){if(typeof window>"u")return;let r=this.exportLogs(),o=new Blob([r],{type:"application/json"}),i=URL.createObjectURL(o),s=document.createElement("a");s.href=i,s.download=e,s.click(),URL.revokeObjectURL(i);}setEnabled(e){this.config.enabled=e;}setLevel(e){e&&(this.config.level=e);}},O=null;function vt(t){return O?t&&(t.enabled!==void 0&&O.setEnabled(t.enabled),t.level&&O.setLevel(t.level)):O=new B(t),O}function xt(t,e){return new B({...e,prefix:`[MSAL-Next:${t}]`})}function H({children:t,config:e,defaultRedirectTo:r="/login",defaultLoading:o,defaultUnauthorized:i,debug:s=false}){let p=useRouter(),{isAuthenticated:u,account:l,inProgress:a}=A(),[m,h]=useState(true),[c,n]=useState(false);return useEffect(()=>{async function f(){if(s&&console.log("[ProtectedPage] Checking auth...",{isAuthenticated:u,inProgress:a,config:e}),!a){if(!e.required){n(true),h(false);return}if(!u||!l){s&&console.log("[ProtectedPage] Not authenticated, redirecting...");let g=e.redirectTo||r,d=encodeURIComponent(window.location.pathname+window.location.search);p.push(`${g}?returnUrl=${d}`);return}if(e.roles&&e.roles.length>0){let g=l.idTokenClaims?.roles||[];if(!e.roles.some(y=>g.includes(y))){s&&console.log("[ProtectedPage] Missing required role",{required:e.roles,user:g}),n(false),h(false);return}}if(e.validate)try{if(!await e.validate(l)){s&&console.log("[ProtectedPage] Custom validation failed"),n(!1),h(!1);return}}catch(g){console.error("[ProtectedPage] Validation error:",g),n(false),h(false);return}s&&console.log("[ProtectedPage] Authorization successful"),n(true),h(false);}}f();},[u,l,a,e,p,r,s]),m||a?e.loading?jsx(Fragment,{children:e.loading}):o?jsx(Fragment,{children:o}):jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"})}):c?jsx(Fragment,{children:t}):e.unauthorized?jsx(Fragment,{children:e.unauthorized}):i?jsx(Fragment,{children:i}):jsx("div",{className:"flex items-center justify-center min-h-screen",children:jsxs("div",{className:"text-center",children:[jsx("h1",{className:"text-2xl font-bold text-gray-900 mb-2",children:"Access Denied"}),jsx("p",{className:"text-gray-600",children:"You don't have permission to access this page."})]})})}function De(t,e,r){let o=i=>jsx(H,{config:e,defaultRedirectTo:r?.defaultRedirectTo,defaultLoading:r?.defaultLoading,defaultUnauthorized:r?.defaultUnauthorized,debug:r?.debug,children:jsx(t,{...i})});return o.displayName=`withPageAuth(${t.displayName||t.name||"Component"})`,o}function Rt(t={}){let{protectedRoutes:e=[],publicOnlyRoutes:r=[],loginPath:o="/login",redirectAfterLogin:i="/",sessionCookie:s="msal.account",isAuthenticated:p,debug:u=false}=t;return async function(a){let{pathname:m}=a.nextUrl;u&&console.log("[AuthMiddleware] Processing:",m);let h=false;p?h=await p(a):h=!!a.cookies.get(s)?.value,u&&console.log("[AuthMiddleware] Authenticated:",h);let c=e.some(g=>m.startsWith(g)),n=r.some(g=>m.startsWith(g));if(c&&!h){u&&console.log("[AuthMiddleware] Redirecting to login");let g=a.nextUrl.clone();return g.pathname=o,g.searchParams.set("returnUrl",m),NextResponse.redirect(g)}if(n&&h){u&&console.log("[AuthMiddleware] Redirecting to home");let g=a.nextUrl.searchParams.get("returnUrl"),d=a.nextUrl.clone();return d.pathname=g||i,d.searchParams.delete("returnUrl"),NextResponse.redirect(d)}let f=NextResponse.next();if(h){f.headers.set("x-msal-authenticated","true");try{let g=a.cookies.get(s);if(g?.value){let d=j(g.value,Z);d?.username&&f.headers.set("x-msal-username",d.username);}}catch{u&&console.warn("[AuthMiddleware] Failed to parse session data");}}return f}}export{le as AuthGuard,st as AuthStatus,ue as ErrorBoundary,je as MSALProvider,Ke as MicrosoftSignInButton,ee as MsalAuthProvider,T as MsalError,H as ProtectedPage,et as SignOutButton,it as UserAvatar,Rt as createAuthMiddleware,$e as createMissingEnvVarError,X as createMsalConfig,At as createRetryWrapper,xt as createScopedLogger,K as displayValidationResults,vt as getDebugLogger,Be as getMsalInstance,Z as isValidAccountData,V as isValidRedirectUri,fe as isValidScope,Ue as retryWithBackoff,j as safeJsonParse,R as sanitizeError,k as useGraphApi,A as useMsalAuth,gt as useRoles,oe as useUserProfile,Y as validateConfig,Ne as validateScopes,ht as withAuth,De as withPageAuth,P as wrapMsalError};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chemmangat/msal-next",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "description": "Production-grade MSAL authentication package for Next.js App Router with minimal boilerplate",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",