1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4039],{24039:function(e,t,n){n.d(t,{H:function(){return f},Z:function(){return h}});var r=n(57437),o=n(2265),i=n(32489),a=n(99388),c=n(51817),s=n(30401),l=n(65934),d=n(94508),u=n(90908);let p=(0,o.createContext)(null);function f(){let e=(0,o.useContext)(p);if(!e)throw Error("useProtectedAccess must be used inside ProtectedOtpProvider");return e}function h(e){var t,n,f,h,m;let{children:v}=e,{data:b,status:x,update:y}=(0,l.kP)(),g=(0,o.useRef)(null),w=(0,o.useRef)(""),[k,S]=(0,o.useState)(!1),[j,N]=(0,o.useState)("phone"),[C,P]=(0,o.useState)(""),[E,z]=(0,o.useState)(""),[I,O]=(0,o.useState)(""),[T,R]=(0,o.useState)(""),[U,M]=(0,o.useState)(0),[_,A]=(0,o.useState)(!1),[D,X]=(0,o.useState)(""),[Y,V]=(0,o.useState)("idle"),[J,L]=(0,o.useState)(!1),[Z,F]=(0,o.useState)(!1),K=(0,o.useRef)(null),[W,q]=(0,o.useState)(!1),B=(0,o.useRef)(new Set),H=(0,o.useRef)(!1),G=!!(J||(null==b?void 0:null===(n=b.user)||void 0===n?void 0:null===(t=n.access)||void 0===t?void 0:t.canUseProtectedModules)||(null==b?void 0:null===(h=b.user)||void 0===h?void 0:null===(f=h.phoneVerification)||void 0===f?void 0:f.verified)),$=String((null==b?void 0:null===(m=b.user)||void 0===m?void 0:m.id)||""),Q=null==b?void 0:b.authSession,ee="authenticated"===x&&(null==Q?void 0:Q.authMethod)==="oauth",et=(0,o.useCallback)(()=>{_||(g.current=null,w.current="",H.current=!1,S(!1),N("phone"),z(""),O(""),X(""),V("idle"),q(!1))},[_]);(0,o.useEffect)(()=>{if("unauthenticated"===x){K.current=null,L(!1),B.current.clear();return}"authenticated"===x&&$&&(K.current&&K.current!==$&&(L(!1),B.current.clear()),K.current=$)},[$,x]),(0,o.useEffect)(()=>{if(!k)return;let e=document.body.style.overflow;document.body.style.overflow="hidden";let t=e=>{"Escape"===e.key&&et()};return window.addEventListener("keydown",t),()=>{document.body.style.overflow=e,window.removeEventListener("keydown",t)}},[et,k]),(0,o.useEffect)(()=>{if(U<=0)return;let e=window.setInterval(()=>M(e=>Math.max(0,e-1)),1e3);return()=>window.clearInterval(e)},[U]);let en=(0,o.useCallback)(e=>{var t;let n=(0,d.R7)(e);if(!n)return!1;let r=(0,d.R7)(String((null==b?void 0:null===(t=b.user)||void 0===t?void 0:t.phone)||""));return(!r||n!==r)&&!B.current.has(n)},[null==b?void 0:b.user]),er=(0,o.useCallback)((e,t)=>{P(e),q(t),N("phone"),z(""),X(""),V("idle"),S(!0)},[]),eo=(0,o.useCallback)((e,t)=>{var n;let r=String((null==t?void 0:t.phone)||(null==b?void 0:null===(n=b.user)||void 0===n?void 0:n.phone)||"");if("loading"===x){g.current=e,w.current=r,H.current=!!(null==t?void 0:t.requireOtpWhenPhoneDiffers),F(!0);return}if(G){if((null==t?void 0:t.requireOtpWhenPhoneDiffers)&&en(String((null==t?void 0:t.phone)||""))){g.current=e,w.current=r,er(r,!0);return}e();return}g.current=e,w.current=r,er(r,!1)},[G,en,er,null==b?void 0:b.user,x]);(0,o.useEffect)(()=>{var e;if(!Z||"loading"===x)return;F(!1);let t=g.current;if(t){if(G){if(H.current&&en(w.current)){er(w.current,!0);return}g.current=null,H.current=!1,t();return}er(w.current||String((null==b?void 0:null===(e=b.user)||void 0===e?void 0:e.phone)||""),!1)}},[G,Z,en,er,null==b?void 0:b.user,x]);let ei=async()=>{let e=C.replace(/[\s-]/g,"");if(!(0,d.vJ)(e)){X("Enter a valid Pakistani mobile number.");return}A(!0),X("");try{var t,n,r;let o=ee&&!W,i=await fetch(o?"/api/auth/phone-link/start":"/api/auth/otp/start",{method:"POST",headers:{"content-type":"application/json","x-device-id":(0,u.N3)()},credentials:"include",body:JSON.stringify(o?{phone:e}:{phone:e,purpose:W?"contact_verify":"login"})}),a=await (0,u.IK)(i),c=(null===(t=a.data)||void 0===t?void 0:t.challengeId)||"";if(!i.ok||!c){X(a.message||"Unable to send the verification code.");return}O(c),R((null===(n=a.data)||void 0===n?void 0:n.maskedPhone)||e),M((null===(r=a.data)||void 0===r?void 0:r.resendAfterSeconds)||60),z(""),N("otp")}catch(e){X("Unable to send the verification code. Check your connection and try again.")}finally{A(!1)}},ea=async()=>{if(!/^\d{6}$/.test(E)){X("Enter the 6-digit verification code.");return}A(!0),X("");try{var e,t;let n=await fetch(W?"/api/auth/otp/contact/verify":ee?"/api/auth/phone-link/verify":"/api/auth/otp/verify",{method:"POST",headers:{"content-type":"application/json","x-device-id":(0,u.N3)()},credentials:"include",body:JSON.stringify({challengeId:I,otp:E})}),r=await (0,u.IK)(n);
1if(!n.ok){X((0,u.bS)(r,"The verification code is invalid or expired."));return}if(W){let t=(0,d.R7)(String((null===(e=r.data)||void 0===e?void 0:e.verifiedPhone)||C));t&&B.current.add(t)}else if(ee)try{await y({refreshBackendSession:!0})}catch(e){X("Your phone was verified, but the website session could not be updated. Please try again.");return}else{let e=await (0,l.zB)("credentials",{otpSession:"cookie",redirect:!1});if(!(null==e?void 0:e.ok)||e.error){X("Your phone was verified, but the website session could not be started.");return}let n=!1;for(let e=0;e<5;e+=1){let e=await (0,l.Gg)();if(null==e?void 0:null===(t=e.user)||void 0===t?void 0:t.id){n=!0;break}await new Promise(e=>window.setTimeout(e,200))}if(!n){X("Your phone was verified, but the website session is not ready. Please try again.");return}}V("success"),await new Promise(e=>window.setTimeout(e,420)),W||L(!0);let o=g.current;g.current=null,w.current="",H.current=!1,S(!1),q(!1),o&&o()}catch(e){X("Unable to verify the code. Check your connection and try again.")}finally{A(!1)}},ec=async()=>{if(I&&!(U>0)&&!_){A(!0),X("");try{var e;let t=await fetch("/api/auth/otp/resend",{method:"POST",headers:{"content-type":"application/json","x-device-id":(0,u.N3)()},credentials:"include",body:JSON.stringify({challengeId:I})}),n=await (0,u.IK)(t);if(!t.ok){X(n.message||"Unable to resend the verification code.");return}M((null===(e=n.data)||void 0===e?void 0:e.resendAfterSeconds)||60)}catch(e){X("Unable to resend the verification code.")}finally{A(!1)}}};return(0,r.jsxs)(p.Provider,{value:{runWithProtectedAccess:eo},children:[v,k&&(0,r.jsx)("div",{className:"fixed inset-0 z-[1000] flex items-center justify-center bg-black/50 p-4 font-outfit",onMouseDown:e=>{e.target===e.currentTarget&&et()},children:(0,r.jsxs)("div",{role:"dialog","aria-modal":"true","aria-labelledby":"protected-otp-title","data-state":"success"===Y?"success":D?"error":"idle",className:"relative w-full max-w-[420px] rounded-[12px] bg-white p-5 shadow-xl sm:p-6",children:[(0,r.jsx)("button",{type:"button","aria-label":"Close phone verification",onClick:et,disabled:_,className:"absolute right-4 top-4 flex h-9 w-9 items-center justify-center rounded-full text-[var(--color-neutral-500)] hover:bg-[var(--color-border-lighter)] disabled:opacity-50",children:(0,r.jsx)(i.Z,{size:20})}),(0,r.jsx)("h2",{id:"protected-otp-title",className:"pr-10 text-[20px] font-bold text-[var(--color-neutral-dark)]",children:W?"Verify this contact number":"Verify your phone number"}),(0,r.jsx)("p",{className:"mt-1 text-[13px] text-[var(--color-neutral-500)]",children:W?"This number is different from your account's verified number, so we'll send it a one-time code to confirm.":"Verify once to continue and unlock protected CarMandi services."}),(0,r.jsxs)("form",{onSubmit:e=>{e.preventDefault(),"phone"===j?ei():ea()},className:"mt-5 space-y-4 ".concat(D?"protected-otp-error":""),children:["phone"===j?(0,r.jsxs)("div",{children:[(0,r.jsx)("label",{htmlFor:"protected-phone",className:"mb-1.5 block text-[13px] font-medium text-[var(--color-neutral-dark)]",children:"Phone Number"}
1),(0,r.jsx)("input",{id:"protected-phone",autoFocus:!0,type:"tel",inputMode:"tel",autoComplete:"tel",placeholder:"0300 1234567",value:C,onChange:e=>{P(e.target.value),X("")},disabled:_,className:"h-[48px] w-full rounded-[8px] border-2 border-[var(--color-neutral-50)] px-4 text-[14px] outline-none focus:border-[var(--color-brand-primary)] disabled:opacity-60"})]}):(0,r.jsxs)("div",{children:[(0,r.jsxs)("div",{className:"mb-1.5 flex items-center justify-between",children:[(0,r.jsx)("label",{htmlFor:"protected-otp",className:"text-[13px] font-medium text-[var(--color-neutral-dark)]",children:"Verification Code"}),(0,r.jsx)("button",{type:"button",onClick:()=>{N("phone"),z(""),X("")},disabled:_,className:"text-[12px] font-medium text-[var(--color-brand-primary-light)] hover:underline",children:"Change number"})]}),(0,r.jsxs)("p",{className:"mb-2 text-[12px] text-[var(--color-neutral-500)]",children:["Enter the code sent to ",T,"."]}),(0,r.jsx)("input",{id:"protected-otp",autoFocus:!0,type:"text",inputMode:"numeric",autoComplete:"one-time-code",placeholder:"6-digit code",value:E,onChange:e=>{z(e.target.value.replace(/\D/g,"").slice(0,6)),X("")},disabled:_,className:"h-[48px] w-full rounded-[8px] border-2 border-[var(--color-neutral-50)] px-4 text-center text-[18px] font-semibold tracking-[0.35em] outline-none focus:border-[var(--color-brand-primary)] disabled:opacity-60"})]}),D&&(0,r.jsxs)("div",{role:"alert",className:"flex items-center justify-center gap-2 rounded-[8px] bg-red-50 px-3 py-2 text-center text-[13px] font-medium text-[var(--color-brand-secondary-hover)]",children:[(0,r.jsx)(a.Z,{size:17,className:"shrink-0"}),(0,r.jsx)("span",{children:D})]}),(0,r.jsx)("button",{type:"submit",disabled:_,className:"protected-otp-action flex h-[48px] w-full items-center justify-center gap-2 rounded-[8px] bg-[var(--color-brand-primary-dark)] text-[14px] font-semibold text-white disabled:opacity-60",children:(0,r.jsxs)("span",{className:"protected-otp-action-content flex items-center justify-center gap-2",children:[_&&"success"!==Y&&(0,r.jsx)(c.Z,{size:18,className:"animate-spin"}),"phone"===j?"Send OTP":"Verify & Continue"]})}),"otp"===j&&(0,r.jsx)("button",{type:"button",onClick:()=>void ec(),disabled:U>0||_,className:"w-full text-[12px] font-medium text-[var(--color-brand-primary-light)] disabled:text-[var(--color-neutral-300)]",children:U>0?"Resend code in ".concat(U,"s"):"Resend code"})]}),"success"===Y&&(0,r.jsxs)("div",{className:"protected-otp-success absolute inset-0 z-20 flex flex-col items-center justify-center rounded-[12px] bg-white px-6 text-center",role:"status","aria-live":"polite",children:[(0,r.jsx)("span",{className:"protected-otp-success-icon flex h-16 w-16 items-center justify-center rounded-full bg-[var(--color-brand-primary-lighter)] text-[var(--color-brand-primary-dark)]",children:(0,r.jsx)(s.Z,{size:34,strokeWidth:3})}),(0,r.jsx)("strong",{className:"mt-4 text-[20px] text-[var(--color-neutral-dark)]",children:"Phone verified"}),(0,r.jsx)("span",{className:"mt-1 text-[13px] text-[var(--color-neutral-500)]",children:"Continuing securely..."})]}),(0,r.jsx)("style",{children:'\n .protected-otp-action {\n position: relative;\n isolation: isolate;\n overflow: hidden;\n transition:\n color 200ms ease,\n transform 120ms ease;\n }\n\n .protected-otp-action::before,\n .protected-otp-action::after {\n content: "";\n position: absolute;\n left: 0;\n bottom: 0;\n width: 100%;\n pointer-events: none;\n }\n\n .protected-otp-action::before {\n z-index: 1;\n height: 2px;\n background: var(--color-brand-primary-light);\n transform: scaleX(0);\n transform-origin: left;
1\n transition: transform 250ms cubic-bezier(0.25, 1, 0.5, 1);\n }\n\n .protected-otp-action::after {\n z-index: 0;\n height: 100%;\n background: var(--color-brand-primary);\n transform: scaleY(0);\n transform-origin: bottom;\n transition: transform 280ms cubic-bezier(0.25, 1, 0.5, 1);\n }\n\n .protected-otp-action-content {\n position: relative;\n z-index: 2;\n }\n\n .protected-otp-action:hover::before,\n .protected-otp-action:focus-visible::before {\n transform: scaleX(1);\n }\n\n .protected-otp-action:hover::after,\n .protected-otp-action:focus-visible::after {\n transform: scaleY(1);\n transition-delay: 120ms;\n }\n\n .protected-otp-action:active {\n transform: scale(0.985);\n }\n\n .protected-otp-error {\n animation: protected-otp-shake 260ms\n cubic-bezier(0.25, 1, 0.5, 1);\n }\n\n .protected-otp-success {\n animation: protected-otp-success-in 240ms\n cubic-bezier(0.22, 1, 0.36, 1);\n }\n\n .protected-otp-success-icon {\n animation: protected-otp-check-in 300ms\n cubic-bezier(0.22, 1, 0.36, 1);\n }\n\n @keyframes protected-otp-shake {\n 0%,\n 100% {\n transform: translateX(0);\n }\n 30% {\n transform: translateX(-7px);\n }\n 60% {\n transform: translateX(5px);\n }\n 80% {\n transform: translateX(-2px);\n }\n }\n\n @keyframes protected-otp-success-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n @keyframes protected-otp-check-in {\n from {\n opacity: 0;\n transform: scale(0.72);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .protected-otp-action,\n .protected-otp-action::before,\n .protected-otp-action::after,\n .protected-otp-error,\n .protected-otp-success,\n .protected-otp-success-icon {\n animation: none;\n transition: none;\n }\n }\n '})]})})]})}},90908:function(e,t,n){n.d(t,{IK:function(){return a},N3:function(){return i},bS:function(){return o}});let r={ACCOUNT_ALREADY_EXISTS:"An account with this phone number already exists. Use Log in and continue with Phone OTP. If you need help recovering your account, contact CarMandi Support at [email protected].",PHONE_ALREADY_IN_USE:"This phone number is already linked to another CarMandi account. Sign out, then sign in with Phone OTP to access it. If you need help recovering or linking accounts, contact CarMandi Support at [email protected]."};function o(e,t){return e.code&&r[e.code]||e.message||t}function i(){let e="carmandi.authDeviceId",t=window.localStorage.getItem(e);if(t)return t;let n=window.crypto.randomUUID();return window.localStorage.setItem(e,n),n}async function a(e){let t=await e.text();try{return t?JSON.parse(t):{}}catch(e){return{message:"Unexpected response from the authentication service."}}}}}]);
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.