1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9406],{21307:(e,t,a)=>{a.d(t,{RP:()=>s,Xq:()=>n,e9:()=>i,lV:()=>l});var r=a(41463);function n(e){if(e){let t=e.headers.get("origin");if(t)return t;let a=e.headers.get("host");if(a){let t=e.headers.get("x-forwarded-proto")||"https";return`${t}://${a}`}}if(window.location.origin)return window.location.origin;let t=window.NEXT_PUBLIC_APP_URL||r.env.NEXT_PUBLIC_FRONTEND_URL;if(t)return t;throw Error("Unable to determine application URL. Please set NEXT_PUBLIC_APP_URL environment variable.")}function i(){let e=window.NEXT_PUBLIC_API_URL||r.env.BACKEND_API_URL;return e||console.warn("NEXT_PUBLIC_API_URL environment variable is not set, using default"),e||"https://api.atris.ai/api"}let o=["atris://","myapp://"];function s(){let e=r.env.NEXT_PUBLIC_ALLOWED_RETURN_SCHEMES;return e?e.split(",").map(e=>e.trim()).filter(Boolean).map(e=>e.endsWith("://")?e:`${e}://`):o}function l(e,t={}){let a=t.fallbackPath??"/dashboard";if(!e)return a;let r=e.trim();if(!r)return a;let i=r.toLowerCase();if((t.allowCustomSchemes??s()).map(e=>e.toLowerCase()).some(e=>e&&i.startsWith(e)))return r;if(/^[a-z][a-z0-9+.-]*:\/\//i.test(r)&&!/^https?:\/\//i.test(r))return console.warn(`[sanitizeRedirectTarget] Blocked unsupported redirect scheme: ${r}`),a;if(r.startsWith("/"))return r;if(r.startsWith("?")||r.startsWith("#"))return`${a}${r}`;if(/^https?:\/\//i.test(r))try{let e=t.baseUrl??n(),i=new URL(e),o=new URL(r);if(o.host===i.host)return`${o.pathname}${o.search}${o.hash}`||a;return console.warn(`[sanitizeRedirectTarget] Blocked external redirect host: ${o.host}`),a}catch(e){return console.warn("[sanitizeRedirectTarget] Failed to parse redirect URL:",r,e),a}return`/${r.replace(/^\/+/,"")}`}},59406:(e,t,a)=>{a.d(t,{AuthProvider:()=>u,useAuth:()=>c});var r=a(95155),n=a(12115),i=a(73321),o=a(99340);let s={isAuthenticated:!1,isLoading:!0,user:null,error:null,activeSpaceId:null},l=(0,n.createContext)({...s,login:async e=>{throw Error("Login function not implemented")},logout:async()=>{throw Error("Logout function not implemented")},magicLinkLogin:async e=>{throw Error("MagicLinkLogin function not implemented")},oauthLogin:async(e,t)=>{throw Error("OAuthLogin function not implemented")},requestPasswordReset:async e=>{throw Error("RequestPasswordReset function not implemented")},confirmPasswordReset:async(e,t)=>{throw Error("ConfirmPasswordReset function not implemented")},changePassword:async(e,t)=>{throw Error("ChangePassword function not implemented")},refreshAuthState:async()=>{throw Error("RefreshAuthState function not implemented")},setActiveSpaceId:e=>{throw Error("SetActiveSpaceId function not implemented")}}),c=()=>(0,n.useContext)(l),u=({children:e})=>{let[t,a]=(0,n.useState)(s);(0,i.useRouter)();let c=(0,n.useRef)(!1),u=(0,n.useRef)(null),d=(0,n.useRef)(!1),h=(0,n.useCallback)(e=>{a(t=>({...t,...e}))},[]),w=(0,n.useCallback)((e,t="An unexpected authentication error occurred")=>{console.error("Auth error:",e),h({error:e instanceof o.l||e instanceof Error?e.message:t,isLoading:!1,isAuthenticated:!1,user:null,activeSpaceId:null})},[h]),p=(0,n.useCallback)(async()=>{if(c.current&&u.current)return u.current;c.current=!0;let e=async()=>{h({isLoading:!0,error:null});try{let e=await fetch("/api/auth/session",{cache:"no-store"}),t=await e.json();if(e.ok&&t.isAuthenticated||await o.y.refreshToken()&&(await new Promise(e=>setTimeout(e,50)),e=await fetch("/api/auth/session",{cache:"no-store"}),t=await e.json()),!e.ok||!t.isAuthenticated||!t.user)return h({isAuthenticated:!1,user:null,isLoading:!1,error:t.error||"Session not authenticated",activeSpaceId:null}),!1;{let e=t.user,a=localStorage.getItem("activeSpaceId")||e.personal_space_id||null;return h({isAuthenticated:!0,user:e,isLoading:!1,error:null,activeSpaceId:a}),!0}}catch(e){return console.error("AuthContext: Failed to fetch session:",e),w(e,"Failed to fetch session state."),!1}finally{c.current=!1,u.current=null}};return u.current=e(),u.current},[h,w]);(0,n.useEffect)(()=>{d.current||(d.current=!0,p())},[p]);let f=(0,n.useCallback)(async e=>{h({isLoading:!0,error:null});try{let t=await o.y.login(e);if(!await p())throw Error("Login succeeded but session validation failed");return t}catch(e){throw w(e,"Login failed."),e}},[h,p,w]),g=(0,n.useCallback)(async()=>{h({isLoading:!0,error:null});try{await o.y.logout(),localStorage.removeItem("activeSpaceId"),h({isAuthenticated:!1,user:null,isLoading:!1,error:null,activeSpaceId:null})}catch(e){h({isAuthenticated:!1,user:null,isLoading:!1,error:null,activeSpaceId:null}),console.error("Logout error (continuing anyway):",e)}},[h]),y=(0,n.useCallback)(async(e,t)=>{h({isLoading:!0,error:null});try{let a=await o.y.oauthLogin(e,t);return a.auth_url?window.location.href=a.auth_url:await p(),a}catch(t){throw w(t,`OAuth login with ${e} failed to initiate.`),t}},[h,w,p]),m=(0,n.useCallback)(async e=>{h({isLoading:!0,error:null});try{let t=await o.y.magicLinkLogin(e);return h({isLoading:!1,error:null}),t}catch(e){throw w(e,"Magic link login failed."),e}},[h,w]),L=(0,n.useCallback)(async e=>{h({isLoading:!0,error:null});try{let t=await o.y.requestPasswordReset(e);return h({isLoading:!1,error:null}),t}catch(e){throw w(e,"Request password reset failed."),e}},[h,w]),k=(0,n.useCallback)(async(e,t)=>{h({isLoading:!0,error:null});try{let a=await o.y.confirmPasswordReset(e,t);return h({isLoading:!1,error:null}),a}catch(e){throw w(e,"Confirm password reset failed."),e}},[h,w]),S=(0,n.useCallback)(async(e,t)=>{h({isLoading:!0,error:null});try{let a=await o.y.changePassword(e,t);return h({isLoading:!1,error:null}),a}catch(e){throw w(e,"Change password failed."),e}},[h,w]),C=(0,n.useCallback)(e=>{h({activeSpaceId:e}),localStorage.setItem("activeSpaceId",e)},[h]);(0,n.useEffect)(()=>{let e=e=>{"activeSpaceId"===e.key&&null===e.newValue&&t.isAuthenticated&&h({isAuthenticated:!1,user:null,isLoading:!1,error:null,activeSpaceId:null})};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[t.isAuthenticated,h]);let v=(0,n.useMemo)(()=>({...t,login:f,logout:g,magicLinkLogin:m,oauthLogin:y,requestPasswordReset:L,confirmPasswordReset:k,changePassword:S,refreshAuthState:p,setActiveSpaceId:C}),[t,f,g,m,y,L,k,S,p,C]);return(0,r.jsx)(l.Provider,{value:v,children:e})}},99340:(e,t,a)=>{a.d(t,{l:()=>i,y:()=>o});var r=a(21307);let n=(0,r.e9)().replace(/\/$/,"");
1class i extends Error{constructor(e){super(e),this.name="AuthError"}}let o={login:async e=>{let t=await fetch("/api/auth/universal-login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),credentials:"include"});if(!t.ok){let e=await t.json().catch(()=>({detail:"Login failed"}));throw new i(e.detail||e.message||"Login failed")}return t.json()},validateSession:async()=>{try{let e=await fetch("/api/auth/session",{method:"GET",credentials:"include",cache:"no-store"});if(!e.ok)return!1;return!!(await e.json()).isAuthenticated}catch{return!1}},getCurrentUser:async()=>{try{let e=await fetch("/api/auth/session",{method:"GET",credentials:"include",cache:"no-store"});if(!e.ok)return null;return(await e.json()).user||null}catch{return null}},refreshToken:async()=>{try{return(await fetch("/api/auth/refresh",{method:"POST",credentials:"include"})).ok}catch{return!1}},logout:async()=>{try{let e=await fetch("/api/auth/logout",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include"});e.ok||console.error("Backend logout failed:",e.status)}catch(e){console.error("Error calling logout API:",e)}try{localStorage.removeItem("user_data"),localStorage.removeItem("token_expiry")}catch(e){console.warn("Failed to clear local auth cache:",e)}},oauthLogin:async(e,t)=>{let a=`${n}/auth/callback`,o=t?.startsWith("http")?t:`${(0,r.Xq)()}${t||"/dashboard"}`,s=await fetch("/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({provider:e,redirect_uri:a,next:o})});if(!s.ok)throw new i("Failed to initiate OAuth login");return await s.json()},processCallback:async(e,t,a)=>{let r=await fetch("/api/auth/callback",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({code:e,state:t,provider:a})});if(!r.ok)throw new i("OAuth callback failed");return r.json()},handleOAuthCallback:async(e,t,a)=>{let n=await fetch("/api/auth/callback",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({code:t,state:a,provider:e,redirect_uri:`${(0,r.Xq)()}/auth/callback/${e}`})});if(!n.ok){let e=await n.json().catch(()=>({detail:"OAuth callback failed"}));throw new i(e.detail||e.message||"OAuth callback failed")}return n.json()},validateToken:async e=>{if(e){let t=await fetch(`${n}/auth/validate`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({token:e})});return t.ok?{valid:!0,user:(await t.json()).user}:{valid:!1}}return await o.validateSession()?{valid:!0,user:await o.getCurrentUser()}:{valid:!1}},magicLinkLogin:async e=>{let t=await fetch("/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({provider:"magic_link",email:e})});if(!t.ok){let e=await t.json().catch(()=>({detail:"Failed to send magic link"}));throw new i(e.detail||e.message||"Failed to send magic link")}return await t.json()},requestPasswordReset:async e=>{let t=await fetch("/api/auth/reset-password",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({email:e})});if(!t.ok){let e=await t.json().catch(()=>({detail:"Failed to request password reset"}));throw new i(e.detail||e.message||"Failed to request password reset")}return await t.json()},confirmPasswordReset:async(e,t)=>{let a=await fetch("/api/auth/reset-password/confirm",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({token:e,password:t})});if(!a.ok){let e=await a.json().catch(()=>({detail:"Failed to reset password"}));throw new i(e.detail||e.message||"Failed to reset password")}return await a.json()},changePassword:async(e,t)=>{let a=await fetch("/api/user/change-password",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({currentPassword:e,newPassword:t})});if(!a.ok){let e=await a.json().catch(()=>({detail:"Failed to change password"}));throw new i(e.detail||e.message||"Failed to change password")}return await a.json()}}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.