Files
ycode/scripts/rea/recover-permission-control.cjs
T

57 lines
3.6 KiB
JavaScript

// Read retained REA exports only. Never accesses the installed WorkBuddy or CDP.
const fs = require('node:fs')
const crypto = require('node:crypto')
const { parse } = require('@babel/parser')
const traverse = require('@babel/traverse').default
const postcss = require('postcss')
const assert = require('node:assert/strict')
const sha = text => crypto.createHash('sha256').update(text).digest('hex')
const archive = JSON.parse(fs.readFileSync('.tmp/rea-runtime-scripts.json', 'utf8'))
const source = archive.items.find(item => item.file_path.endsWith('src-DbE1_mgM.js')).source.artifact
assert.equal(sha(source.text), '6c6ce63c93854783270e855572797d75e536e3b8d4548410e31fe9d147e1feb4')
const css = fs.readFileSync('.tmp/rea-css-recovered/src-CyXHA0IC.css', 'utf8')
assert.equal(sha(css), 'a5e26b537bb50323aefbf25abddad52e288dd3868598be8d255d70886fe77cfe')
const primitiveCss = fs.readFileSync('.tmp/rea-css-recovered/src-Bh3YZ35H.css', 'utf8')
assert.equal(sha(primitiveCss), '88dbdc1cd3f59d0e8b75824512a465a2be714bc7af481d790fe3a9484f85e01a')
const ast = parse(source.text, { sourceType: 'module' })
const wanted = new Set(['ShieldSecuredIcon', 'ShieldDangerIcon', 'ShieldErrorIcon'])
const bodies = new Map()
traverse(ast, {
FunctionDeclaration(p) { if (wanted.has(p.node.id?.name)) bodies.set(p.node.id.name, p.node) },
AssignmentExpression(p) { if (wanted.has(p.node.left.name)) bodies.set(p.node.left.name, p.node.right) },
VariableDeclarator(p) { if (wanted.has(p.node.id.name) && p.node.init) bodies.set(p.node.id.name, p.node.init) }
})
assert.ok(bodies.has('ShieldSecuredIcon') && bodies.has('ShieldDangerIcon'))
let icons = '// Generated from fixed REA ' + archive.evidence_id + '.\n// @ts-nocheck -- the original JSX runtime bodies are retained.\nimport { jsx, jsxs } from "react/jsx-runtime"\n'
for (const [name, node] of bodies) {
let body = source.text.slice(node.start, node.end).replace(/\(0,[\w$]+\.(jsx|jsxs)\)/g, '$1')
assert.ok(!/\(0,[\w$]+\.(jsx|jsxs)\)/.test(body), `${name}: unresolved JSX runtime alias`)
icons += node.type === 'FunctionDeclaration' ? `export ${body}\n` : `export const ${name} = ${body}\n`
}
const rules = []
postcss.parse(css).walkRules(rule => {
if (/\.cr-permission-(panel|setting-popover|confirm)/.test(rule.selector)) rules.push(rule.toString())
})
postcss.parse(css).walkAtRules('keyframes', rule => {
if (rule.params === 'permissionPopIn') rules.push(rule.toString())
})
assert.ok(rules.length >= 20)
// The existing workspace adapter only recovered the button variants it used.
// Bring in the confirmation's actual danger/secondary states, including disabled.
postcss.parse(primitiveCss).walkRules(rule => {
if (!/\.wb-button(?:\b|--|__)/.test(rule.selector)) return
const copy = rule.clone()
copy.selectors = copy.selectors.map(selector => `.yc-source-permission ${selector}`)
rules.push(copy.toString())
})
const outputs = [
['src/renderer/src/workbuddy/composer/permission/SourcePermissionIcons.tsx', icons],
['src/renderer/src/workbuddy/composer/permission/source-permission-recovered.css',
`/* REA ${archive.evidence_id}; CSS ev_377c8790468b3c67dad8577aabb327f98d3140659f0fffdbabfcff5a40cc9e94.\n * Source SHA-256 ${sha(css)}. Exact permission panel/confirmation declarations. */\n${rules.join('\n')}\n`]
]
for (const [filename, text] of outputs) {
if (process.argv.includes('--check')) assert.equal(fs.readFileSync(filename, 'utf8'), text, filename)
else { fs.mkdirSync(require('node:path').dirname(filename), { recursive: true }); fs.writeFileSync(filename, text) }
}
console.log(`PERMISSION_SOURCE_PASS ${bodies.size} icons, ${rules.length} rules`)