From 0f214fd1eeee81165d1e5bdec90434ca36e88d8e Mon Sep 17 00:00:00 2001 From: zouyun Date: Mon, 24 Aug 2026 17:25:06 +0800 Subject: [PATCH] Add access-code gate --- access.json | 5 +++++ index.html | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 access.json diff --git a/access.json b/access.json new file mode 100644 index 0000000..4c4dd5b --- /dev/null +++ b/access.json @@ -0,0 +1,5 @@ +{ + "version": 1, + "salt": "amazon-za-report-access-v1", + "hash": "3ffcf23473036ad716ae6862a3be38dd9a2158d5a637681d9f0a962e69692161" +} diff --git a/index.html b/index.html index c6ca38e..71e5abd 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,7 @@ @media(prefers-color-scheme:dark){:root{--bg:#0c1220;--panel:#121a2a;--ink:#eef3fb;--muted:#9ba9bd;--line:#28354a;--soft:#182743;--shadow:none}} -
+
Daily Delivery · ZA

Amazon - ZA daily tracker

Loading data…

Key Metrics

August Budget Pacing

AugZARUSD
@@ -24,7 +24,6 @@ const fmt=n=>new Intl.NumberFormat('en-US').format(n), money=n=>'$'+new Intl.Num const label=d=>d.slice(5).replace('-','/'); function bars(el,data,series,max){const showValues=data.length<=12;el.style.minWidth=Math.max(0,data.length*48)+'px';el.innerHTML=data.map(d=>`
${series.map(s=>`
${showValues?`${s.format(d[s.key])}`:''}
`).join('')}
${label(d.date)}
`).join('')} function lineChart(el,data,series,format){const w=Math.max(760,data.length*42),h=260,p={l:48,r:18,t:18,b:34},vals=data.flatMap(d=>series.map(s=>Number(d[s.key])||0)),max=Math.max(...vals,1),min=0,x=i=>p.l+i*(w-p.l-p.r)/Math.max(data.length-1,1),y=v=>h-p.b-(v-min)*(h-p.t-p.b)/(max-min||1),ticks=[0,.25,.5,.75,1];el.innerHTML=`${ticks.map(t=>`${format(max*t)}`).join('')}${data.map((d,i)=>`${label(d.date)}`).join('')}${series.map(s=>`${data.map((d,i)=>`${d.date} · ${s.name}: ${format(d[s.key]||0)}`).join('')}`).join('')}`} -const ACCESS={emails:['a91dc567bcdb6d054cf121d7e4016454ee3d316e3b452b851ae4d3087bc99bb2'],salt:'amazon-za-delivery-2026-08',password:'2344c6c9cf72430cafbf48e014d7f721a53484f766f1455f0c12232515ec61e9'}; async function sha256(value){const bytes=new TextEncoder().encode(value);const digest=await crypto.subtle.digest('SHA-256',bytes);return [...new Uint8Array(digest)].map(x=>x.toString(16).padStart(2,'0')).join('')} function showReport(){document.getElementById('login').hidden=true;document.getElementById('report').hidden=false;loadReport()} async function loadReport(){fetch('data.json',{cache:'no-store'}).then(r=>{if(!r.ok)throw Error('data.json '+r.status);return r.json()}).then(data=>{ @@ -36,6 +35,6 @@ async function loadReport(){fetch('data.json',{cache:'no-store'}).then(r=>{if(!r document.getElementById('rows').innerHTML=all.map((x,i)=>{const prev=i?all[i-1]:null,spike=x.is_actual&&prev&&prev.is_actual&&Math.abs((x.e1e2_rate||0)-(prev.e1e2_rate||0))>=5;return `${x.date}${fmt(x.install)}${fmt(x.event1)}${fmt(x.event2)}${fmt(x.e1e2)}${pct(x.e1e2_rate)}${zar(x.e1e2*payinZar)}${zar(dailyBudgetZar)}${pct(x.e1e2/dailyCap*100)}${money(x.midas_spend)}`}).join(''); document.getElementById('weeklyRows').innerHTML=data.weekly.map(w=>`${w.label}${fmt(w.install)}${fmt(w.e1e2)}${pct(w.e1e2_rate)}${zar(w.e1e2*payinZar)}${money(w.midas_spend)}`).join(''); }).catch(e=>{document.getElementById('range').textContent='Failed to load data: '+e.message})} -document.getElementById('loginForm').addEventListener('submit',async e=>{e.preventDefault();const button=document.getElementById('loginButton'),error=document.getElementById('loginError');button.disabled=true;error.textContent='';try{const email=document.getElementById('email').value.trim().toLowerCase(),password=document.getElementById('password').value;const [emailHash,passwordHash]=await Promise.all([sha256(email),sha256(ACCESS.salt+':'+password)]);if(ACCESS.emails.includes(emailHash)&&passwordHash===ACCESS.password){sessionStorage.setItem('amazonZaAccess','granted');showReport()}else{error.textContent='Incorrect email or password.'}}catch(_){error.textContent='This browser cannot complete verification. Please use a modern browser.'}finally{button.disabled=false}}); -if(sessionStorage.getItem('amazonZaAccess')==='granted')showReport(); +document.getElementById('loginForm').addEventListener('submit',async e=>{e.preventDefault();const button=document.getElementById('loginButton'),error=document.getElementById('loginError');button.disabled=true;error.textContent='';try{const access=await fetch('access.json',{cache:'no-store'}).then(r=>{if(!r.ok)throw Error('access configuration unavailable');return r.json()}),code=document.getElementById('accessCode').value,codeHash=await sha256(access.salt+':'+code);if(codeHash===access.hash){sessionStorage.setItem('amazonZaCodeAccessV1','granted');showReport()}else{error.textContent='Incorrect access code.'}}catch(_){error.textContent='Unable to verify access. Please try again.'}finally{button.disabled=false}}); +if(sessionStorage.getItem('amazonZaCodeAccessV1')==='granted')showReport();