1/* 2 * conmigo_fp.js â device fingerprint (Prevent spam & scam). 3 * Phase 1 / Option A (2026-09-17): Fingerprint Pro (14-day trial, vanilla JS / CDN agent). 4 * Public API key is safe to embed. Exposes window.conmigoFingerprint() 5 * -> Promise<string visitor_id> (or null on failure; caller falls back to a UUID 6 * so login can never break â see web_fingerprint_web.dart). 7 * 8 * COST: each fp.get() is one billable "identification". We cache the visitor_id at two 9 * levels so a whole login session costs ONE identification: 10 * 1. in-memory â every ask within a page load reuses the first result (login asks the 11 * device id ~4x: register-check, login, device-register, socket); 12 * 2. sessionStorage â survives the page reload/navigation that login does, so the 13 * second page load reuses the id instead of paying for a 2nd identification. 14 * sessionStorage is per-tab and clears when the tab closes, so a genuinely new visit still 15 * re-identifies (fresh IP/signals) â and clearing it changes nothing for an evader, since 16 * Fingerprint returns the SAME visitor_id anyway. 17 * 18 * NOTE: this replaces the earlier self-hosted canvas/webgl hash. That approach is 19 * kept out of the bundle for now (see FINGERPRINT-REBUILD-BRIEF.md Option B) in case 20 * Sean rejects the third-party dependency after the trial. 21 */ 22(function () { 23 var _cached = null; // Promise<string|null> visitor_id, computed at most once per load 24 var STORE_KEY = 'conmigo_fp_vid'; // sessionStorage key, survives reloads within the tab 25 //!!2026-09-18!!fp_events The requestId from the SAME fp.get() call. It's the key the backend uses to 26 // pull the FULL Smart Signals (VM, suspect score, proxy...) from Fingerprint's /events endpoint â 27 // the /visitors endpoint the backend falls back to does NOT return them. Captured at no extra cost 28 // (same identification). Per-tab in sessionStorage so the login reload still has it. 29 var _rid = null; // last requestId seen this page load 30 var RID_KEY = 'conmigo_fp_rid'; 31 32 function _saveRid(rid) { 33 if (!rid) return; 34 _rid = rid; 35 try { sessionStorage.setItem(RID_KEY, rid); } catch (e) {} 36 } 37 38 // The most recent Fingerprint requestId (or null). The caller sends it on register/login so the 39 // backend can read the full Smart Signals. Falls back to the stored one from earlier this tab. 40 window.conmigoFingerprintRid = function () { 41 if (_rid) return _rid; 42 try { return sessionStorage.getItem(RID_KEY) || null; } catch (e) { return null; } 43 }; 44 45 window.conmigoFingerprint = function () { 46 if (_cached) return _cached; 47 48 // Reuse an id already captured earlier this tab session (survives the login reload). 49 try { 50 var saved = sessionStorage.getItem(STORE_KEY); 51 if (saved) { _cached = Promise.resolve(saved); return _cached; } 52 } catch (e) { /* private mode / blocked storage â fall through to a live call */ } 53 54 _cached = (async function () { 55 try { 56 var Fp = await import('https://fpjscdn.net/v4/DsOicpE0xEObPHAddT9L'); 57 var fp = await Fp.start({ region: 'us' }); 58 var r = await fp.get(); 59 // The CDN agent's result carries both an id and a per-visit request id; tolerate either 60 // snake_case or camelCase key naming so a future agent version can't silently break capture. 61 var vid = r.visitor_id || r.visitorId || null; 62 // The CDN agent's result names the per-visit id `event_id` (verified live 2026-09-18) â it is 63 // the key for the backend's /v4/events/{event_id} Smart-Signals lookup. Tolerate the documented 64 // requestId aliases too in case a future agent version renames it. 65 _saveRid(r.event_id || r.requestId || r.request_id || null); 66 if (vid) { try { sessionStorage.setItem(STORE_KEY, vid); } catch (e) {} } 67 return vid; 68 } catch (e) { 69 // CDN blocked (ad blocker), offline, or agent error â caller falls back to a UUID. 70 // Do NOT cache a failure: a later ask may succeed (e.g. network recovered). 71 _cached = null; 72 return null; 73 } 74 })(); 75 return _cached; 76 }; 77})();
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.