File size: 3,506 Bytes
d3ab583
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 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/`);