const jwt = require('jsonwebtoken'); const http = require('http'); const { execSync } = require('child_process'); const fs = require('fs'); const KEY = 'user:1022172:47'; const SECRET = 'da4e4367277668aa6e048b0a04d1a417ba8bad630f4ac37ccdcea064a9de151e'; const ADDON_ID = 'verstak-bridge@verstak.app'; function makeJWT() { return jwt.sign({ iss: KEY, jti: Math.random().toString(36).slice(2), iat: Math.floor(Date.now() / 1000), exp: Math.floor(Date.now() / 1000) + 300 }, SECRET); } function proxyReq(method, url, headers, body) { return new Promise((resolve, reject) => { const u = new URL(url); const req = http.request({ hostname: 'localhost', port: 12334, path: url, method, headers: Object.assign({ 'Host': u.hostname }, headers) }, res => { const chunks = []; res.on('data', c => chunks.push(c)); res.on('end', () => resolve({ status: res.statusCode, body: Buffer.concat(chunks) })); }); req.on('error', reject); if (body) req.write(body); req.end(); }); } async function main() { const token = makeJWT(); const auth = 'JWT ' + token; // List all versions console.log('==> Listing all versions...'); const vRes = await proxyReq('GET', `https://addons.mozilla.org/api/v5/addons/addon/${ADDON_ID}/versions/?filter=all_with_unlisted`, { 'Authorization': auth }); const vData = JSON.parse(vRes.body.toString()); for (const v of vData.results || []) { const file = v.files?.[0] || v.file; console.log(` v${v.version} id=${v.id} channel=${v.channel} file_status=${file?.status} file_url=${file?.url || 'none'}`); if (v.version === '1.0.2' && file?.status === 'public' && file?.url) { console.log(`\n==> Downloading signed 1.0.2 from: ${file.url}`); fs.mkdirSync('release/firefox', { recursive: true }); const out = 'release/firefox/verstak-firefox-1.0.2.xpi'; execSync(`curl -s -x http://localhost:12334 -L "${file.url}" -H "Authorization: ${auth}" -o "${out}"`, { timeout: 60000 }); const size = fs.statSync(out).size; const fd = fs.openSync(out, 'r'); const magic = Buffer.alloc(4); fs.readSync(fd, magic, 0, 4, 0); fs.closeSync(fd); console.log(` Saved: ${out} (${(size / 1024).toFixed(1)} KB)`); console.log(` ZIP: ${magic[0]===0x50 && magic[1]===0x4B ? 'VALID ✓' : 'INVALID ✗'}`); if (magic[0]===0x50 && magic[1]===0x4B) { execSync(`unzip -l "${out}" 2>&1 | grep -v "^Archive" | grep -v "^ Length" | grep -v "^---------" | grep -v "^-$"`); } return; } } console.log('\n==> 1.0.2 not yet public, checking if we need to wait...'); } main().catch(e => { console.error(e.message); process.exit(1); });