mirror of
https://github.com/hanzoai/a.git
synced 2026-10-30 18:50:12 +00:00
RED (manual, agent hit the session limit): (1) secret-key guard /^(hk-|sk-)/ was case-SENSITIVE and missed fw_ — HK-/SK-/fw_ secrets slipped past into the browser. Now /^(hk-|sk-|fw_)/i across chat/analytics/checkout (keys already .trim()'d, so no space bypass). (2) checkout sent a client data-price as unitPrice even for a slug'd item → a forged data-price='0.01' could set the charge. Now unitPrice is sent ONLY for a slug-LESS ad-hoc amount; any slug'd item is repriced server-side from the catalog (forgery-proof). XSS verified PASS separately (ask.js renders model output via textContent; the sole innerHTML is a static glyph).
53 lines
2.1 KiB
JavaScript
53 lines
2.1 KiB
JavaScript
/*
|
|
* a.hanzo.ai/analytics — <script src=".../analytics" data-key="pk_..."></script>
|
|
* Loads [email protected] (window.HanzoTrack), inits the `native` integration to
|
|
* api.hanzo.ai/v1/analytics, runs Annotate(). data-key is a publishable ingest
|
|
* token (pk_) — never a secret. Idempotent; never throws into the host page.
|
|
* Optional: data-host, data-product, data-annotate.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
if (window.__hanzoAnalytics) return;
|
|
var self = document.currentScript;
|
|
if (!self) return;
|
|
window.__hanzoAnalytics = true;
|
|
|
|
var origin = new URL(self.src, location.href).origin;
|
|
var d = self.dataset || {};
|
|
var key = (d.key || '').trim();
|
|
|
|
if (!key) {
|
|
console.warn('[hanzo/analytics] missing data-key — add data-key="pk_…" (a publishable ingest token). Not loaded.');
|
|
return;
|
|
}
|
|
if (/^(hk-|sk-|fw_)/i.test(key)) {
|
|
console.error('[hanzo/analytics] data-key looks like a SECRET key — never expose hk-/sk-/fw_ keys in a browser. Use a publishable pk_ token. Aborted.');
|
|
return;
|
|
}
|
|
|
|
var opts = {
|
|
token: key,
|
|
host: (d.host || 'https://api.hanzo.ai').replace(/\/+$/, ''),
|
|
product: d.product || location.hostname
|
|
};
|
|
var annotate = d.annotate !== 'false';
|
|
|
|
var s = document.createElement('script');
|
|
s.async = true;
|
|
s.src = origin + '/vendor/track.min.js';
|
|
s.onload = function () {
|
|
try {
|
|
var T = window.HanzoTrack;
|
|
if (!T || !T.Analytics) { console.warn('[hanzo/analytics] track build loaded without HanzoTrack.Analytics.'); return; }
|
|
var a = new T.Analytics();
|
|
a.initialize({ integrations: [{ type: 'native', token: opts.token, host: opts.host, product: opts.product }] });
|
|
if (annotate && T.Annotate) { try { T.Annotate(a, {}); } catch (e) {} }
|
|
window.hanzoAnalytics = a; // stable handle for manual a.track(name, params)
|
|
} catch (e) {
|
|
console.warn('[hanzo/analytics] init failed:', e && e.message);
|
|
}
|
|
};
|
|
s.onerror = function () { console.warn('[hanzo/analytics] failed to load analytics build from ' + origin + '/vendor/track.min.js'); };
|
|
(document.head || document.documentElement).appendChild(s);
|
|
})();
|