bankML-UIF / scripts /check-creds-split.mjs
Gregory-L's picture
bankML UIF: bankML 0.4.3 pages: Savante's input→response pattern, bankML in this browser by default, one palette, phone to desktop
d3ab583 verified
Raw History Blame Contribute Delete
3.51 kB
// SPDX-License-Identifier: MIT
// Proves the split: the MIT bundles (dist/, dist-space/uif-space.js, dist-mindx/) contain none of the credential
// code, and each build carries the GPL-3.0-only bankml-creds.js beside its page, unchanged. Also: no MIT source
// imports src/creds/. Exit 1 with the findings otherwise. node scripts/check-creds-split.mjs
import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';
const root = new URL('..', import.meta.url).pathname;
/** Strings only the credential module has: the token's header, the OAuth calls, its storage keys, the token check. */
const MARKERS = ['Authorization', 'Bearer ', 'oauthLoginUrl', 'oauthHandleRedirectIfPresent', 'bankml-creds:session',
'bankml-creds:device', 'whoami-v2', 'accessToken', 'usePastedToken', 'hf_oauth', 'OAUTH_CLIENT_ID'];
const walk = d => readdirSync(d).flatMap(f => { const p = join(d, f); return statSync(p).isDirectory() ? walk(p) : [p]; });
const bad = [];
const builds = { dist: 'dist', 'dist-space': 'dist-space', 'dist-mindx': 'dist-mindx' };
const creds = join(root, 'dist-creds/bankml-creds.js');
if (!existsSync(creds)) bad.push('dist-creds/bankml-creds.js is missing');
const credsText = existsSync(creds) ? readFileSync(creds, 'utf8') : '';
if (credsText && !credsText.startsWith('/*! bankml-creds.js — SPDX-License-Identifier: GPL-3.0-only')) bad.push('bankml-creds.js lacks its GPL-3.0-only banner');
for (const [name, dir] of Object.entries(builds)) {
const d = join(root, dir);
if (!existsSync(d)) { bad.push(`${name}: not built`); continue; }
const beside = join(d, 'bankml-creds.js');
if (!existsSync(beside)) bad.push(`${name}: bankml-creds.js is not beside the page`);
else if (readFileSync(beside, 'utf8') !== credsText) bad.push(`${name}: bankml-creds.js differs from dist-creds/`);
const lic = join(d, 'bankml-creds-LICENSE.txt');
if (!existsSync(lic)) bad.push(`${name}: bankml-creds-LICENSE.txt (the GPL-3.0 text) is not beside the page`);
else if (!/GNU GENERAL PUBLIC LICENSE\s+Version 3/.test(readFileSync(lic, 'utf8'))) bad.push(`${name}: bankml-creds-LICENSE.txt is not the GPL-3.0 text`);
// the MIT bundle: the page's own scripts (not browseML's MIT OR Apache-2.0 files, not the creds module)
const mine = walk(d).filter(f => /\.(js|html)$/.test(f) && !/bankml-creds\.js$|browseml[\w-]*\.js$/.test(f));
for (const f of mine) {
const t = readFileSync(f, 'utf8');
for (const m of MARKERS) if (t.includes(m)) bad.push(`${relative(root, f)}: contains "${m}"`);
}
}
// no MIT source imports the credential module
for (const f of walk(join(root, 'src')).filter(f => /\.(ts|tsx)$/.test(f) && !f.includes('/src/creds/'))) {
const t = readFileSync(f, 'utf8');
if (/from\s+['"][^'"]*\/creds(\/|['"])/.test(t) || /import\(\s*['"][^'"]*\/creds\//.test(t)) bad.push(`${relative(root, f)}: imports src/creds/`);
}
// every credential source file is GPL-3.0-only
for (const f of walk(join(root, 'src/creds')).filter(f => /\.(ts|tsx|js)$/.test(f))) {
if (!readFileSync(f, 'utf8').startsWith('// SPDX-License-Identifier: GPL-3.0-only')) bad.push(`${relative(root, f)}: not GPL-3.0-only`);
}
if (bad.length) { console.error('credential split: FAILED\n ' + bad.join('\n ')); process.exit(1); }
console.log(`credential split: ok — ${Object.keys(builds).join(', ')} carry no credential code; bankml-creds.js (GPL-3.0-only, ${credsText.length} bytes) beside each page; no MIT source imports src/creds/`);