tokentracker-cli 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{Card-C22jvaH-.js → Card-B3zit51o.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-Dv_4x35m.js → DashboardPage-p0PukR6H.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-BjhiTjFW.js → DevicePage-cYRFC4jD.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-CHxDANbJ.js → FadeIn-BeLgcj1F.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-CIfUeDxZ.js → HeaderGithubStar-DJJ-z5Wo.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-DIa0AzUn.js → IpCheckPage-CxswyJC6.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-sh7tcPKd.js → LandingPage-Bc1ahbkE.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-Dg6zcGG1.js → LeaderboardPage-khmZdEvK.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-BOJJ-T57.js → LeaderboardProfilePage-NdMct8UA.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-CdMhF5lF.js → LimitsPage-Dc-Rgfn2.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-BbJO2VUw.js → LoginPage-nhgDDL4s.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-Csxg6Urf.js → PopoverPopup-D7c8Tufb.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-BdfV-wMB.js → ProviderIcon-B79ytQj1.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-B0UsE-Cz.js → SettingsPage-Dv5A3ADR.js} +1 -1
- package/dashboard/dist/assets/{SkillsPage-CpV5GRRc.js → SkillsPage-CJdMytgb.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-DdQEZR9N.js → WidgetsPage-PteVAvZa.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-DKYCqqJa.js → WrappedPage-r7rchUJS.js} +1 -1
- package/dashboard/dist/assets/check-CQ9GtDMA.js +1 -0
- package/dashboard/dist/assets/{chevron-down-Dh0EAuAs.js → chevron-down-CNvz7vRS.js} +1 -1
- package/dashboard/dist/assets/{download-B-u2224w.js → download-HiydOOCL.js} +1 -1
- package/dashboard/dist/assets/{info-Bax52N3e.js → info-CWqFjI4Z.js} +1 -1
- package/dashboard/dist/assets/leaderboard-columns-BWyNquUf.js +1 -0
- package/dashboard/dist/assets/{main-uaLO1Ae7.js → main-C1bPtjN7.js} +15 -15
- package/dashboard/dist/assets/{use-limits-display-prefs-BVawA_Rp.js → use-limits-display-prefs-CTnU4ZMo.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-DHtj5DnD.js → use-native-settings-DkTJDNZG.js} +1 -1
- package/dashboard/dist/assets/{use-reduced-motion-8tbVQBYw.js → use-reduced-motion-DJE4Frme.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-SwQjCSa8.js → use-usage-limits-OjbraegI.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-Bc8I7sE1.js → useCurrency-DJA7tRVi.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/cli.js +1 -2
- package/src/commands/serve.js +2 -57
- package/src/lib/local-api.js +4 -37
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/dashboard/dist/assets/check-CO0YnJo0.js +0 -1
- package/dashboard/dist/assets/leaderboard-columns-CmMWLqut.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a}from"./main-
|
|
1
|
+
import{r as a}from"./main-C1bPtjN7.js";const d=["claude","codex","cursor","gemini","kimi","kiro","copilot","antigravity"],S={claude:"Claude",codex:"Codex",cursor:"Cursor",gemini:"Gemini",kimi:"Kimi",kiro:"Kiro",copilot:"GitHub Copilot",antigravity:"Antigravity"},v={claude:"/brand-logos/claude-code.svg",codex:"/brand-logos/codex.svg",cursor:"/brand-logos/cursor.svg",gemini:"/brand-logos/gemini.svg",kimi:"/brand-logos/kimi.svg",kiro:"/brand-logos/kiro.svg",copilot:"/brand-logos/copilot.svg",antigravity:"/brand-logos/antigravity.svg"},l="tt.limits.providerOrder",g="tt.limits.providerVisibility";function w(){if(typeof window>"u")return[...d];try{const i=window.localStorage.getItem(l);if(!i)return[...d];const s=JSON.parse(i);if(!Array.isArray(s))return[...d];const r=s.filter(c=>d.includes(c));for(const c of d)r.includes(c)||r.push(c);return r}catch{return[...d]}}function y(){const i=Object.fromEntries(d.map(s=>[s,!0]));if(typeof window>"u")return i;try{const s=window.localStorage.getItem(g);if(!s)return i;const r=JSON.parse(s);if(!r||typeof r!="object")return i;const c={...i};for(const u of d)typeof r[u]=="boolean"&&(c[u]=r[u]);return c}catch{return i}}function C(){const[i,s]=a.useState(w),[r,c]=a.useState(y);a.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(l,JSON.stringify(i))}catch{}},[i]),a.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(g,JSON.stringify(r))}catch{}},[r]),a.useEffect(()=>{if(typeof window>"u")return;const o=t=>{t.key===l&&s(w()),t.key===g&&c(y())};return window.addEventListener("storage",o),()=>window.removeEventListener("storage",o)},[]);const u=a.useCallback(o=>{c(t=>({...t,[o]:!t[o]}))},[]),b=a.useCallback(o=>{s(t=>{const e=t.indexOf(o);if(e<=0)return t;const n=[...t];return[n[e-1],n[e]]=[n[e],n[e-1]],n})},[]),p=a.useCallback(o=>{s(t=>{const e=t.indexOf(o);if(e<0||e>=t.length-1)return t;const n=[...t];return[n[e],n[e+1]]=[n[e+1],n[e]],n})},[]),O=a.useCallback((o,t)=>{o!==t&&s(e=>{const n=e.indexOf(o),m=e.indexOf(t);if(n<0||m<0)return e;const f=[...e],[I]=f.splice(n,1);return f.splice(m,0,I),f})},[]),k=a.useCallback(()=>{s([...d]),c(Object.fromEntries(d.map(o=>[o,!0])))},[]),x=a.useMemo(()=>i.filter(o=>r[o]!==!1),[i,r]);return{order:i,visibility:r,visibleOrdered:x,toggle:u,moveUp:b,moveDown:p,moveToward:O,reset:k}}export{v as L,S as a,C as u};
|
package/dashboard/dist/assets/{use-native-settings-DHtj5DnD.js → use-native-settings-DkTJDNZG.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as a,a7 as x,r as n,aH as g,aI as m,aJ as b,aK as u,aL as f,aF as h}from"./main-
|
|
1
|
+
import{C as a,a7 as x,r as n,aH as g,aI as m,aJ as b,aK as u,aL as f,aF as h}from"./main-C1bPtjN7.js";import{C as y}from"./Card-B3zit51o.js";function p({checked:s,onChange:t,disabled:e,ariaLabel:i}){return a.jsx("button",{type:"button",role:"switch","aria-checked":s,"aria-label":i,onClick:t,disabled:e,className:x("relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500 disabled:opacity-50 disabled:cursor-not-allowed",s?"bg-oai-brand-500":"bg-oai-gray-300 dark:bg-oai-gray-700"),children:a.jsx("span",{className:x("inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",s?"translate-x-[18px]":"translate-x-[3px]")})})}function j({label:s,hint:t,control:e}){return a.jsxs("div",{className:"flex items-center justify-between gap-4 py-3",children:[a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("div",{className:"text-sm text-oai-gray-900 dark:text-oai-gray-200",children:s}),t?a.jsx("div",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}):null]}),a.jsx("div",{className:"shrink-0",children:e})]})}function N({title:s,subtitle:t,action:e,children:i}){return a.jsxs(y,{children:[a.jsxs("div",{className:"mb-3 flex items-start justify-between gap-4",children:[a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("h2",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:s}),t?a.jsx("p",{className:"mt-1 truncate text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}):null]}),e?a.jsx("div",{className:"shrink-0",children:e}):null]}),a.jsx("div",{className:"-mb-3 divide-y divide-oai-gray-200/60 dark:divide-oai-gray-800/60",children:i})]})}function w({options:s,value:t,onChange:e}){return a.jsx("div",{className:"inline-flex items-center rounded-lg border border-oai-gray-200 bg-oai-gray-50 p-0.5 dark:border-oai-gray-800 dark:bg-oai-gray-900",children:s.map(({value:i,label:d,Icon:l})=>{const r=t===i;return a.jsxs("button",{type:"button",onClick:()=>e(i),"aria-pressed":r,className:x("inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors",r?"bg-white text-oai-black shadow-sm dark:bg-oai-gray-800 dark:text-white":"text-oai-gray-500 hover:text-oai-black dark:text-oai-gray-400 dark:hover:text-white"),children:[l?a.jsx(l,{className:"h-3.5 w-3.5","aria-hidden":!0}):null,a.jsx("span",{children:d})]},i)})})}function S(){const[s,t]=n.useState(null),e=g()&&m();n.useEffect(()=>{if(!e)return;const r=b(o=>t(o));return u(),r},[e]);const i=n.useCallback((r,o)=>{e&&(t(c=>c&&{...c,[r]:o}),f(r,o))},[e]),d=n.useCallback(r=>{e&&h(r)},[e]),l=n.useCallback(()=>{e&&u()},[e]);return{available:e,settings:s,setSetting:i,runAction:d,refresh:l}}export{N as S,p as T,j as a,w as b,S as u};
|
package/dashboard/dist/assets/{use-reduced-motion-8tbVQBYw.js → use-reduced-motion-DJE4Frme.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aM as t,aN as o,r,aO as s}from"./main-
|
|
1
|
+
import{aM as t,aN as o,r,aO as s}from"./main-C1bPtjN7.js";function u(){!t.current&&o();const[e]=r.useState(s.current);return e}export{u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,al as l}from"./main-
|
|
1
|
+
import{r,al as l}from"./main-C1bPtjN7.js";function y(i){const[o,a]=r.useState(null),[u,s]=r.useState(null),[c,f]=r.useState(!0),n=!!i?.initialRefresh,g=r.useCallback(async()=>{try{const e=await l({refresh:!0});a(e&&typeof e=="object"?e:null),s(null)}catch(e){s(e?.message||String(e))}},[]);return r.useEffect(()=>{let e=!1;return(async()=>{try{const t=await l(n?{refresh:!0}:{});if(e)return;a(t&&typeof t=="object"?t:null),s(null)}catch(t){if(e)return;s(t?.message||String(t))}finally{e||f(!1)}})(),()=>{e=!0}},[n]),{data:o,error:u,isLoading:c,refresh:g}}export{y as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e,aA as t,aB as r,I as c}from"./main-
|
|
1
|
+
import{r as e,aA as t,aB as r,I as c}from"./main-C1bPtjN7.js";const a=Object.freeze({currency:c,rate:1,symbol:"$",rates:{...r},rateSource:"default",rateFetchedAt:null,setCurrency:()=>{}});function u(){return e.useContext(t)??a}export{u};
|
|
@@ -210,7 +210,7 @@
|
|
|
210
210
|
]
|
|
211
211
|
}
|
|
212
212
|
</script>
|
|
213
|
-
<script type="module" crossorigin src="/assets/main-
|
|
213
|
+
<script type="module" crossorigin src="/assets/main-C1bPtjN7.js"></script>
|
|
214
214
|
<link rel="stylesheet" crossorigin href="/assets/main-JP_EYeq-.css">
|
|
215
215
|
</head>
|
|
216
216
|
<body>
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"description": "Shareable Token Tracker dashboard snapshot."
|
|
52
52
|
}
|
|
53
53
|
</script>
|
|
54
|
-
<script type="module" crossorigin src="/assets/main-
|
|
54
|
+
<script type="module" crossorigin src="/assets/main-C1bPtjN7.js"></script>
|
|
55
55
|
<link rel="stylesheet" crossorigin href="/assets/main-JP_EYeq-.css">
|
|
56
56
|
</head>
|
|
57
57
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokentracker-cli",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Token usage tracker for AI agent CLIs (Claude Code, Codex, Cursor, Gemini, Kiro, OpenCode, OpenClaw, Every Code, Hermes, GitHub Copilot, Kimi Code, CodeBuddy, Grok Build, oh-my-pi, pi, Craft Agents, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose)",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
package/src/cli.js
CHANGED
|
@@ -63,7 +63,7 @@ function printHelp() {
|
|
|
63
63
|
"",
|
|
64
64
|
"Usage:",
|
|
65
65
|
" npx tokentracker Open local dashboard",
|
|
66
|
-
" npx tokentracker [--debug] serve [--port 7680] [--
|
|
66
|
+
" npx tokentracker [--debug] serve [--port 7680] [--no-open] [--no-sync]",
|
|
67
67
|
" npx tokentracker [--debug] init [--yes] [--dry-run] [--no-open] [--link-code <code>]",
|
|
68
68
|
" npx tokentracker [--debug] sync [--auto] [--drain] [--from-openclaw]",
|
|
69
69
|
" npx tokentracker [--debug] status [--probe-keychain] [--probe-keychain-details]",
|
|
@@ -82,7 +82,6 @@ function printHelp() {
|
|
|
82
82
|
" - OpenClaw hook auto-links when OpenClaw is installed (requires gateway restart).",
|
|
83
83
|
" - auto sync waits for a device token.",
|
|
84
84
|
" - optional: --dashboard-url for hosted landing.",
|
|
85
|
-
" - serve: --allowed-hosts marks extra hostnames as local-dashboard auth proxy origins (for tunnels/previews).",
|
|
86
85
|
" - sync parses ~/.codex/sessions/**/rollout-*.jsonl and ~/.code/sessions/**/rollout-*.jsonl, then uploads token deltas.",
|
|
87
86
|
" - --from-openclaw marks sync runs triggered by OpenClaw hooks.",
|
|
88
87
|
" - --debug shows original backend errors.",
|
package/src/commands/serve.js
CHANGED
|
@@ -87,7 +87,7 @@ async function cmdServe(argv) {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// 3. Create handler
|
|
90
|
-
const handleApi = createLocalApiHandler({ queuePath
|
|
90
|
+
const handleApi = createLocalApiHandler({ queuePath });
|
|
91
91
|
|
|
92
92
|
const server = http.createServer(async (req, res) => {
|
|
93
93
|
try {
|
|
@@ -104,11 +104,6 @@ async function cmdServe(argv) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
// API routes
|
|
107
|
-
if (url.pathname === "/api/dashboard-config") {
|
|
108
|
-
serveDashboardConfig(res, { allowedHosts: opts.allowedHosts });
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
107
|
if (
|
|
113
108
|
url.pathname.startsWith("/functions/")
|
|
114
109
|
|| url.pathname.startsWith("/api/")
|
|
@@ -229,66 +224,19 @@ function resolveDashboardDir() {
|
|
|
229
224
|
return null;
|
|
230
225
|
}
|
|
231
226
|
|
|
232
|
-
function splitHostList(value) {
|
|
233
|
-
if (Array.isArray(value)) return value.flatMap(splitHostList);
|
|
234
|
-
if (typeof value !== "string") return [];
|
|
235
|
-
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function normalizeAllowedHost(value) {
|
|
239
|
-
if (typeof value !== "string") return null;
|
|
240
|
-
const raw = value.trim();
|
|
241
|
-
if (!raw || raw.includes("*") || /\s/.test(raw)) return null;
|
|
242
|
-
try {
|
|
243
|
-
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw) ? raw : `http://${raw}`;
|
|
244
|
-
const url = new URL(withScheme);
|
|
245
|
-
if (!url.hostname || url.username || url.password) return null;
|
|
246
|
-
return url.hostname.toLowerCase();
|
|
247
|
-
} catch (_e) {
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function normalizeAllowedHosts(values) {
|
|
253
|
-
const out = [];
|
|
254
|
-
const seen = new Set();
|
|
255
|
-
for (const item of splitHostList(values)) {
|
|
256
|
-
const host = normalizeAllowedHost(item);
|
|
257
|
-
if (!host || seen.has(host)) continue;
|
|
258
|
-
seen.add(host);
|
|
259
|
-
out.push(host);
|
|
260
|
-
}
|
|
261
|
-
return out;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function serveDashboardConfig(res, { allowedHosts } = {}) {
|
|
265
|
-
const body = Buffer.from(JSON.stringify({ allowedHosts: normalizeAllowedHosts(allowedHosts) }), "utf8");
|
|
266
|
-
res.writeHead(200, {
|
|
267
|
-
"Content-Type": "application/json; charset=utf-8",
|
|
268
|
-
"Content-Length": body.length,
|
|
269
|
-
"Cache-Control": "no-store",
|
|
270
|
-
});
|
|
271
|
-
res.end(body);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
227
|
function parseArgs(argv) {
|
|
275
|
-
const opts = { port: DEFAULT_PORT, open: true, sync: true
|
|
228
|
+
const opts = { port: DEFAULT_PORT, open: true, sync: true };
|
|
276
229
|
for (let i = 0; i < argv.length; i++) {
|
|
277
230
|
const arg = argv[i];
|
|
278
231
|
if (arg === "--port" && i + 1 < argv.length) {
|
|
279
232
|
const n = parseInt(argv[++i], 10);
|
|
280
233
|
if (Number.isFinite(n) && n > 0 && n < 65536) opts.port = n;
|
|
281
|
-
} else if (arg === "--allowed-hosts" && i + 1 < argv.length && !argv[i + 1].startsWith("-")) {
|
|
282
|
-
opts.allowedHosts.push(...normalizeAllowedHosts(argv[++i]));
|
|
283
|
-
} else if (arg.startsWith("--allowed-hosts=")) {
|
|
284
|
-
opts.allowedHosts.push(...normalizeAllowedHosts(arg.slice("--allowed-hosts=".length)));
|
|
285
234
|
} else if (arg === "--no-open") {
|
|
286
235
|
opts.open = false;
|
|
287
236
|
} else if (arg === "--no-sync") {
|
|
288
237
|
opts.sync = false;
|
|
289
238
|
}
|
|
290
239
|
}
|
|
291
|
-
opts.allowedHosts = normalizeAllowedHosts(opts.allowedHosts);
|
|
292
240
|
return opts;
|
|
293
241
|
}
|
|
294
242
|
|
|
@@ -298,7 +246,4 @@ module.exports = {
|
|
|
298
246
|
NPM_PACKAGE_NAME,
|
|
299
247
|
LOCAL_BIND_HOST,
|
|
300
248
|
getLocalServerUrl,
|
|
301
|
-
parseArgs,
|
|
302
|
-
normalizeAllowedHosts,
|
|
303
|
-
serveDashboardConfig,
|
|
304
249
|
};
|
package/src/lib/local-api.js
CHANGED
|
@@ -457,45 +457,13 @@ function isLoopbackHostname(hostname) {
|
|
|
457
457
|
return hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1" || hostname === "[::1]";
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
-
function
|
|
461
|
-
if (typeof value !== "string") return null;
|
|
462
|
-
const raw = value.trim();
|
|
463
|
-
if (!raw || raw.includes("*") || /\s/.test(raw)) return null;
|
|
464
|
-
try {
|
|
465
|
-
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw) ? raw : `http://${raw}`;
|
|
466
|
-
const url = new URL(withScheme);
|
|
467
|
-
if (!url.hostname || url.username || url.password) return null;
|
|
468
|
-
return url.hostname.toLowerCase();
|
|
469
|
-
} catch (_e) {
|
|
470
|
-
return null;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
function normalizeAllowedHosts(values) {
|
|
475
|
-
const raw = Array.isArray(values) ? values : [values];
|
|
476
|
-
const out = [];
|
|
477
|
-
const seen = new Set();
|
|
478
|
-
for (const item of raw) {
|
|
479
|
-
const host = normalizeAllowedHost(item);
|
|
480
|
-
if (!host || seen.has(host)) continue;
|
|
481
|
-
seen.add(host);
|
|
482
|
-
out.push(host);
|
|
483
|
-
}
|
|
484
|
-
return out;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
function hasAllowedLoopbackOrigin(headers = {}, allowedHosts = []) {
|
|
488
|
-
const allowed = new Set(normalizeAllowedHosts(allowedHosts));
|
|
460
|
+
function hasAllowedLoopbackOrigin(headers = {}) {
|
|
489
461
|
const candidates = [headers.origin, headers.referer];
|
|
490
462
|
for (const raw of candidates) {
|
|
491
463
|
if (raw == null || raw === "") continue;
|
|
492
464
|
try {
|
|
493
465
|
const url = new URL(String(raw));
|
|
494
|
-
if (
|
|
495
|
-
const host = url.hostname.toLowerCase();
|
|
496
|
-
if (url.protocol === "http:" && isLoopbackHostname(host)) continue;
|
|
497
|
-
if (allowed.has(host)) continue;
|
|
498
|
-
return false;
|
|
466
|
+
if (url.protocol !== "http:" || !isLoopbackHostname(url.hostname)) return false;
|
|
499
467
|
} catch (_e) {
|
|
500
468
|
return false;
|
|
501
469
|
}
|
|
@@ -689,9 +657,8 @@ const IP_CHECK_TARGET = "https://ip.net.coffee";
|
|
|
689
657
|
// Main handler factory
|
|
690
658
|
// ---------------------------------------------------------------------------
|
|
691
659
|
|
|
692
|
-
function createLocalApiHandler({ queuePath
|
|
660
|
+
function createLocalApiHandler({ queuePath }) {
|
|
693
661
|
const qp = queuePath || resolveQueuePath();
|
|
694
|
-
const allowedLocalOriginHosts = normalizeAllowedHosts(allowedHosts);
|
|
695
662
|
|
|
696
663
|
// Server-side cookie relay: captures auth cookies from InsForge cloud responses
|
|
697
664
|
// so that both browser and WKWebView share the same login session via the proxy.
|
|
@@ -863,7 +830,7 @@ function createLocalApiHandler({ queuePath, allowedHosts = [] } = {}) {
|
|
|
863
830
|
? headerToken.trim()
|
|
864
831
|
: cookieToken || "";
|
|
865
832
|
if (!token || token !== localAuthToken) return false;
|
|
866
|
-
return hasAllowedLoopbackOrigin(req?.headers || {}
|
|
833
|
+
return hasAllowedLoopbackOrigin(req?.headers || {});
|
|
867
834
|
}
|
|
868
835
|
|
|
869
836
|
return async function handleLocalApi(req, res, url) {
|