Sign-up guard: honeypot is read-only until a trusted focus and ignores browser autofill (own email); masked value logging
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+12
-1
@@ -154,12 +154,23 @@ window.IAP = (function () {
|
||||
host.querySelectorAll('.ic-btn').forEach(b => b.addEventListener('click', () => { host.innerHTML = ''; host.hidden = true; resolve(b.textContent); }, { once: true }));
|
||||
});
|
||||
}
|
||||
// honeypot fields (join + sign-in): read-only until a trusted focus, so browser autofill and
|
||||
// password managers leave them alone; a value that appeared without a trusted event is ignored
|
||||
function armHoneypots() {
|
||||
document.querySelectorAll('.hp-field').forEach(el => {
|
||||
if (el.dataset.armed) return; el.dataset.armed = '1'; el.readOnly = true;
|
||||
const touch = e => { if (e.isTrusted) { el.readOnly = false; el.dataset.touched = '1'; } };
|
||||
el.addEventListener('focus', touch); el.addEventListener('input', touch); el.addEventListener('keydown', touch);
|
||||
});
|
||||
}
|
||||
armHoneypots(); document.addEventListener('DOMContentLoaded', armHoneypots);
|
||||
const hpValue = el => (el && el.dataset.touched === '1') ? (el.value || '') : '';
|
||||
async function requestCode(email, opts) {
|
||||
const o = opts || {};
|
||||
let pick = null;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const r = await (await fetch('/api/auth/email/start', { method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, fts: FORM_TS, hp_field_x9: (o.honeypot && o.honeypot.value) || '', pick }) })).json();
|
||||
body: JSON.stringify({ email, fts: FORM_TS, hp_field_x9: hpValue(o.honeypot), pick }) })).json();
|
||||
if (r.challenge && o.host) { pick = await iconCheck(o.host, r.challenge, r.error); continue; }
|
||||
if (r.error) throw new Error(r.error);
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user