{"version":3,"file":"AuthGate.CdKB5bzw.mjs","names":["useState","useRef"],"sources":["https:/framerusercontent.com/modules/ljuZ3j1LfbRBXg10UZtH/mgXP5OuMBAolhbfWZCV9/AuthGate.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef,useState}from\"react\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";import{motion}from\"framer-motion\";/**\n * Auth Gate\n * Invisible guard for member-only pages.\n *\n * @author Shokhnur — https://www.framer.com/@shokhnur\n *\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n */// Invisible guard for member-only pages. Draws a solid cover over the page\n// content, checks the local session (instant), then either lifts the cover\n// (logged in) or keeps it down and sends the visitor into the Shopify\n// email-code login (logged out). Uses location.replace so the gated page\n// doesn't pollute Back-button history. UX protection only — real security is\n// Shopify's API refusing bad tokens. Session keys must match\n// ShopifyLoginButton / ShopifyAuthCallback.\nconst STORAGE_KEY=\"eybna_auth\";const VERIFIER_KEY=\"eybna_pkce_verifier\";const STATE_KEY=\"eybna_pkce_state\";const AUTH_EVENT=\"eybna-auth-change\";function toB64Url(bytes){const arr=bytes instanceof Uint8Array?bytes:new Uint8Array(bytes);let s=\"\";for(let i=0;i<arr.length;i++)s+=String.fromCharCode(arr[i]);return btoa(s).replace(/\\+/g,\"-\").replace(/\\//g,\"_\").replace(/=+$/,\"\");}function absoluteUrl(link,fallbackPath){const v=(link||fallbackPath||\"\").trim();if(v.indexOf(\"http://\")===0||v.indexOf(\"https://\")===0)return v;if(typeof window===\"undefined\")return v;return window.location.origin+(v.charAt(0)===\"/\"?v:\"/\"+v);}function readSession(){if(typeof window===\"undefined\")return null;try{const raw=window.localStorage.getItem(STORAGE_KEY);if(!raw)return null;const s=JSON.parse(raw);if(!s||!s.access_token)return null;if(s.expires_at&&Date.now()>s.expires_at)return null;return s;}catch{return null;}}export default function AuthGate(props){const{shopID:shopIdProp,clientID:clientIdProp,callbackLink,mode,redirectLink,liveHosts,previewNote,noteColor,coverColor,showSpinner,spinnerColor,canvasPreview,style}=props;// Hard fallbacks so the gate can never break on a missing prop.\nconst shopId=shopIdProp||\"78993621049\";const clientId=clientIdProp||\"8cf60a76-fa54-48a2-bbb8-970878512b6d\";const isCanvas=RenderTarget.current()===RenderTarget.canvas;const[allowed,setAllowed]=useState(false);const[offOrigin,setOffOrigin]=useState(false);const firedRef=useRef(false);useEffect(()=>{if(isCanvas||typeof window===\"undefined\")return;const hosts=String(liveHosts||\"\").split(\",\").map(h=>h.trim().toLowerCase()).filter(Boolean);const onLiveHost=hosts.length===0||hosts.indexOf(window.location.hostname.toLowerCase())!==-1;const deny=async()=>{if(!onLiveHost){setOffOrigin(true);return;}if(firedRef.current)return;firedRef.current=true;if(mode===\"redirect\"){window.location.replace(absoluteUrl(redirectLink,\"/\"));return;}try{const verifier=toB64Url(crypto.getRandomValues(new Uint8Array(32)));const digest=await crypto.subtle.digest(\"SHA-256\",new TextEncoder().encode(verifier));const challenge=toB64Url(digest);const state=toB64Url(crypto.getRandomValues(new Uint8Array(16)));window.sessionStorage.setItem(VERIFIER_KEY,verifier);window.sessionStorage.setItem(STATE_KEY,state);const url=new URL(`https://shopify.com/authentication/${shopId}/oauth/authorize`);url.searchParams.set(\"client_id\",clientId);url.searchParams.set(\"response_type\",\"code\");url.searchParams.set(\"redirect_uri\",absoluteUrl(callbackLink,\"/account/callback\"));url.searchParams.set(\"scope\",\"openid email customer-account-api:full\");url.searchParams.set(\"state\",state);url.searchParams.set(\"code_challenge\",challenge);url.searchParams.set(\"code_challenge_method\",\"S256\");window.location.replace(url.toString());}catch{window.location.replace(absoluteUrl(redirectLink,\"/\"));}};const check=()=>{if(readSession()){setAllowed(true);}else{setAllowed(false);deny();}};check();window.addEventListener(AUTH_EVENT,check);window.addEventListener(\"storage\",check);return()=>{window.removeEventListener(AUTH_EVENT,check);window.removeEventListener(\"storage\",check);};},[isCanvas,mode,redirectLink,callbackLink,shopId,clientId,liveHosts]);// Canvas: invisible unless previewing the cover for styling.\nif(isCanvas&&!canvasPreview)return null;// Live: session confirmed — lift the cover.\nif(!isCanvas&&allowed)return null;// Off-origin (Framer Preview, or any host not in liveHosts): there is no\n// session to check and no redirect to make, so DON'T cover the page — that\n// made preview unusable. Show a small, click-through badge instead.\nif(offOrigin){return /*#__PURE__*/_jsx(\"div\",{style:{position:\"relative\",width:\"100%\",height:\"auto\",boxSizing:\"border-box\",display:\"flex\",alignItems:\"center\",justifyContent:\"center\",padding:\"6px 0px\",pointerEvents:\"none\",...style},\"aria-hidden\":\"true\",children:/*#__PURE__*/_jsx(\"span\",{style:{color:noteColor,fontFamily:\"Inter, system-ui, sans-serif\",fontSize:12,padding:\"4px 10px\",borderRadius:100,border:`1px solid ${noteColor}`,opacity:.7},children:previewNote})});}// Real gating moment on a live host: session not yet confirmed and a\n// redirect is imminent. The cover is VISUAL ONLY — pointerEvents \"none\" so\n// it can never trap clicks. Real protection is Shopify rejecting bad tokens.\nreturn /*#__PURE__*/_jsx(\"div\",{style:{position:\"relative\",width:\"100%\",height:\"100%\",boxSizing:\"border-box\",backgroundColor:coverColor,display:\"flex\",alignItems:\"center\",justifyContent:\"center\",pointerEvents:\"none\",...style},\"aria-busy\":\"true\",\"aria-live\":\"polite\",children:showSpinner?/*#__PURE__*/_jsx(motion.div,{style:{width:28,height:28,borderRadius:\"50%\",border:\"2px solid transparent\",borderTopColor:spinnerColor,borderRightColor:spinnerColor},animate:{rotate:360},transition:{repeat:Infinity,duration:.9,ease:\"linear\"}}):null});}AuthGate.displayName=\"Auth Gate\";addPropertyControls(AuthGate,{shopID:{type:ControlType.String,title:\"Shop ID\",defaultValue:\"78993621049\"},clientID:{type:ControlType.String,title:\"Client ID\",defaultValue:\"8cf60a76-fa54-48a2-bbb8-970878512b6d\"},callbackLink:{type:ControlType.Link,title:\"Callback\",defaultValue:\"/account/callback\"},mode:{type:ControlType.Enum,title:\"If Logged Out\",options:[\"login\",\"redirect\"],optionTitles:[\"Start Login\",\"Go to Link\"],defaultValue:\"login\",displaySegmentedControl:true,segmentedControlDirection:\"vertical\"},redirectLink:{type:ControlType.Link,title:\"Link\",defaultValue:\"/\",hidden:p=>p.mode!==\"redirect\"},liveHosts:{type:ControlType.String,title:\"Live Hosts\",defaultValue:\"eybna-new.framer.website, renewed-career-324443.framer.app, eybna.com\",description:\"Redirect fires only on these domains. Elsewhere (editor preview) the cover shows a note instead.\"},previewNote:{type:ControlType.String,title:\"Preview Note\",defaultValue:\"Login required\"},noteColor:{type:ControlType.Color,title:\"Note Color\",defaultValue:\"rgba(5, 5, 55, 0.55)\"},coverColor:{type:ControlType.Color,title:\"Cover\",defaultValue:\"#FFFFFF\"},showSpinner:{type:ControlType.Boolean,title:\"Spinner\",defaultValue:true},spinnerColor:{type:ControlType.Color,title:\"Spinner Color\",defaultValue:\"rgb(72, 152, 135)\",hidden:p=>!p.showSpinner},canvasPreview:{type:ControlType.Boolean,title:\"Canvas Preview\",defaultValue:false,description:\"Show the cover on canvas for styling. Live behavior is unaffected.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"AuthGate\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./AuthGate.map"],"mappings":"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"}