1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5380],{13913:(e,r,t)=>{t.d(r,{K:()=>a});function a(e){return!!e&&"object"==typeof e&&"string"==typeof e.email&&e.email.length>0&&"string"==typeof e.token&&e.token.length>0&&"number"==typeof e.LoggedInLabComputer}},37647:(e,r,t)=>{t.d(r,{A:()=>i,y:()=>u});var a=t(75183),o=t(13913);let s=new Set(["password","hash","salt"]);class n{static getInstance(){return n.instance||(n.instance=new n),n.instance}loadStoredUser(){try{let e=localStorage.getItem("auth_user");if(e){let r=JSON.parse(e);(0,o.K)(r)?this.currentUser=r:(console.warn("Invalid user data in localStorage, clearing it and cookies"),this.clearStoredUser(),this.clearCookies(),this.currentUser=null)}else this.refreshUser()}catch(e){console.error("Failed to load stored user:",e),this.clearStoredUser(),this.clearCookies(),this.currentUser=null}}clearCookies(){document.cookie="LoggedInLabComputer=; max-age=0; path=/",document.cookie="userEmail=; max-age=0; path=/"}storeUser(e){try{localStorage.setItem("auth_user",JSON.stringify(e))}catch(e){console.error("Failed to store user:",e)}}clearStoredUser(){localStorage.removeItem("auth_user")}getCookieValue(e){let r="; ".concat(document.cookie).split("; ".concat(e,"="));if(2===r.length){var t;return decodeURIComponent((null==(t=r.pop())?void 0:t.split(";").shift())||"")}return null}async login(e){try{let r=await a.uE.post("/auth/login",e,{maxRetries:4,retryDelay:1500,timeout:3e4,retryableStatusCodes:[502,503,504]});if(!r.success){let e=r.error||"Login failed";if(e.includes("502")||e.includes("Bad Gateway"))return{success:!1,error:{message:"The server is temporarily unavailable. Please try again in a moment."}};if(e.includes("503")||e.includes("Service Unavailable"))return{success:!1,error:{message:"The service is temporarily unavailable. This may happen after logout. Please wait a moment and try again."}};if(e.includes("504")||e.includes("Gateway Timeout"))return{success:!1,error:{message:"The server took too long to respond. Please try again."}};if(e.includes("Email not found"))return{success:!1,error:{field:"email",message:"Email not found"}};if(e.includes("Incorrect password"))return{success:!1,error:{field:"password",message:"Incorrect password, please check"}};if(e.includes("Please verify"))return{success:!1,error:{field:"email",message:"Please verify your email before logging in"}};if(e.includes("timeout")||e.includes("Network"))return{success:!1,error:{message:"Connection timeout. Please check your internet connection and try again."}};return{success:!1,error:{message:e}}}if(r.data){let t={email:e.email,token:r.data.token,LoggedInLabComputer:r.data.LoggedInLabComputer};return this.currentUser=t,this.storeUser(t),document.cookie="LoggedInLabComputer=1; max-age=".concat(604800,"; path=/"),document.cookie="userEmail=".concat(encodeURIComponent(t.email),"; max-age=").concat(604800,"; path=/"),window.dispatchEvent(new CustomEvent("auth-login")),{success:!0,user:t}}return{success:!1,error:{message:"Invalid response from server"}}}catch(e){return console.error("Login error:",e),{success:!1,error:{message:"Network error. Please try again."}}}}async logout(){this.currentUser=null,this.clearStoredUser(),this.clearCookies();try{await a.uE.post("/auth/logout",{},{maxRetries:1,retryDelay:500,timeout:5e3,retryableStatusCodes:[502,503,504]})}catch(e){console.warn("Backend logout request failed (non-critical, local state cleared):",e)}return!0}getCurrentUser(){return this.currentUser}isAuthenticated(){return null!==this.currentUser&&!!this.currentUser.token}getToken(){var e;return(null==(e=this.currentUser)?void 0:e.token)||null}getEmail(){var e;return(null==(e=this.currentUser)?void 0:e.email)||this.getCookieValue("userEmail")}updateUser(e){this.currentUser=e,this.storeUser(e)}async refreshUser(e){try{var r,t,n,u;let i=null!=(u=null!=(n=null==(r=this.currentUser)?void 0:r.token)?n:null==e?void 0:e.token)?u:"";if(!i)return!1;let l=await a.uE.get("/auth/getUser",{headers:{Authorization:"Bearer ".concat(i)}});if(!l.success||!(null==(t=l.data)?void 0:t.user)||"object"!=typeof l.data.user)return!1;let c=function(e){let r={...e};for(let e of s)delete r[e];return r}(l.data.user),d="string"==typeof c.email?c.email:"";if(!d)return!1;let m={...this.currentUser,...c,email:d,token:i,LoggedInLabComputer:1};if(!(0,o.K)(m))return!1;return this.updateUser(m),document.cookie="LoggedInLabComputer=1; max-age=".concat(604800,"; path=/"),document.cookie="userEmail=".concat(encodeURIComponent(d),"; max-age=").concat(604800,"; path=/"),!0}catch(e){return console.error("Failed to refresh user:",e),!1}}async refreshToken(){try{var e,r,t,s;let n=await a.uE.post("/auth/refresh",{},{maxRetries:1,retryDelay:500,timeout:5e3,retryableStatusCodes:[502,503,504]});if(!n.success||!(null==(e=n.data)?void 0:e.token))return!1;let u=null==(r=this.currentUser)?void 0:r.email;if(!u)return!1;let i={...null!=(t=this.currentUser)?t:{},email:u,token:n.data.token,LoggedInLabComputer:null!=(s=n.data.LoggedInLabComputer)?
1s:1};if(!(0,o.K)(i))return!1;return this.updateUser(i),document.cookie="LoggedInLabComputer=1; max-age=".concat(604800,"; path=/"),document.cookie="userEmail=".concat(encodeURIComponent(u),"; max-age=").concat(604800,"; path=/"),!0}catch(e){return console.error("refreshToken failed:",e),!1}}constructor(){this.currentUser=null,this.loadStoredUser()}}let u=n.getInstance(),i=u},65380:(e,r,t)=>{t.d(r,{As:()=>m,AuthProvider:()=>d,Nm:()=>h,w1:()=>g});var a=t(95155),o=t(12115),s=t(37647),n=t(13913),u=t(75183);let i={user:null,isAuthenticated:!1,isLoading:!0,error:null};function l(e,r){switch(r.type){case"LOGIN_START":return{...e,isLoading:!0,error:null};case"LOGIN_SUCCESS":return{...e,user:r.payload,isAuthenticated:!0,isLoading:!1,error:null};case"LOGIN_ERROR":return{...e,user:null,isAuthenticated:!1,isLoading:!1,error:r.payload};case"LOGOUT":return{...e,user:null,isAuthenticated:!1,isLoading:!1,error:null};case"CLEAR_ERROR":return{...e,error:null};case"SET_LOADING":return{...e,isLoading:r.payload};default:return e}}let c=(0,o.createContext)(void 0);function d(e){let{children:r}=e,[t,d]=(0,o.useReducer)(l,i);(0,o.useLayoutEffect)(()=>{let e=e=>{let r="; ".concat(document.cookie).split("; ".concat(e,"="));if(2===r.length){var t;return decodeURIComponent((null==(t=r.pop())?void 0:t.split(";").shift())||"")}return null},r=()=>{document.cookie="LoggedInLabComputer=; max-age=0; path=/",document.cookie="token=; max-age=0; path=/",document.cookie="userEmail=; max-age=0; path=/"};try{let t=localStorage.getItem("auth_user");if(t){let a=JSON.parse(t);if((0,n.K)(a)){let r=e("userEmail"),t=e("LoggedInLabComputer");(r!==a.email||"1"!==t)&&(console.warn("Cookie state mismatch with localStorage, restoring cookies from localStorage"),document.cookie="LoggedInLabComputer=1; max-age=".concat(604800,"; path=/"),document.cookie="userEmail=".concat(encodeURIComponent(a.email),"; max-age=").concat(604800,"; path=/")),d({type:"LOGIN_SUCCESS",payload:a});return}console.warn("Invalid user data in localStorage, clearing it and cookies"),localStorage.removeItem("auth_user"),r()}}catch(e){console.error("Failed to load stored user:",e);try{localStorage.removeItem("auth_user"),r()}catch(e){}}let t=s.y.getCurrentUser();if(t&&(0,n.K)(t))return void d({type:"LOGIN_SUCCESS",payload:t});if(t&&!(0,n.K)(t)){console.warn("Invalid user data in authService, clearing it and cookies"),localStorage.removeItem("auth_user"),r(),d({type:"LOGOUT"});return}let a=e("userEmail");"1"===e("LoggedInLabComputer")&&a&&(console.warn("Corrupt login state detected (cookies exist but localStorage is empty), clearing cookies to prevent stuck state"),r()),d({type:"SET_LOADING",payload:!1})},[]);let m=(0,o.useCallback)(async e=>{d({type:"LOGIN_START"});try{var r,t;let a=await s.y.login({email:e.email.toLowerCase().trim(),password:e.password,forceDetach:!1,username:""});if(a.success&&a.user)try{let e=a.user.email,t=await u.uE.get("/nbgrader/users?email=".concat(encodeURIComponent(e)));if(!t.success||!t.data)return console.warn("Failed to fetch user data from nbgrader/users endpoint:",t.error),d({type:"LOGIN_SUCCESS",payload:a.user}),{success:!0};{let e={...a.user,...t.data};return s.y.updateUser(e),await s.y.refreshUser(),e=null!=(r=s.y.getCurrentUser())?r:e,d({type:"LOGIN_SUCCESS",payload:e}),{success:!0}}}catch(e){return console.warn("Error fetching user data from nbgrader/users endpoint:",e),d({type:"LOGIN_SUCCESS",payload:a.user}),{success:!0}}{let e=(null==(t=a.error)?void 0:t.message)||"Login failed";return d({type:"LOGIN_ERROR",payload:e}),{success:!1,error:a.error}}}catch(r){let e=r instanceof Error?r.message:"An unexpected error occurred";return d({type:"LOGIN_ERROR",payload:e}),{success:!1,error:{message:e}}}},[]),g=(0,o.useCallback)(async()=>{d({type:"SET_LOADING",payload:!0});try{await s.y.logout()}catch(e){throw console.error("Logout error:",e),e}finally{d({type:"LOGOUT"})}},[]),h=(0,o.useCallback)(()=>{d({type:"CLEAR_ERROR"})},[]);(0,o.useEffect)(()=>{var e;t.isAuthenticated&&(null==(e=t.user)?void 0:e.email)&&!t.user.id&&(async()=>{try{let r=t.user.email,a=await u.uE.get("/nbgrader/users?email=".concat(encodeURIComponent(r)));if(a.success&&a.data){var e;let r={...t.user,...a.data};s.y.updateUser(r),await s.y.refreshUser(),r=null!=(e=s.y.getCurrentUser())?e:r,d({type:"LOGIN_SUCCESS",payload:r})}}catch(e){console.warn("Failed to fetch user data from nbgrader/users endpoint on mount:",e)}})()},[t.isAuthenticated,t.user]),(0,o.useLayoutEffect)(()=>{let e=()=>{console.warn("Received 401 Unauthorized, clearing auth state"),d({type:"LOGOUT"})};return window.addEventListener("auth:unauthorized",e),()=>{window.removeEventListener("auth:unauthorized",e)}},[]);let p=(0,o.useMemo)(()=>({state:t,login:m,logout:g,clearError:h}),[t,m,g,h]);return(0,a.jsx)(c.Provider,{value:p,children:r})}function m(){let e=(0,o.useContext)(c);if(void 0===e)throw Error("useAuth must be used within an AuthProvider");return e}function g(){let{state:e}=m();return(0,o.useMemo)(()=>{var r;return{isAuthenticated:e.isAuthenticated,user:e.user,email:(null==(r=e.user)?void 0:r.email)||null}},[e.isAuthenticated,e.user])}function h(){var e;let{state:r}=m();return(0,o.useMemo)(()=>{var e;return(null==(e=r.user)?void 0:e.email)||null},[null==(e=r.user)?void 0:e.email])}}}]);
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.