Fix production ARR reads and add audited source field review

This commit is contained in:
Wyndham ARR committed 2026-10-08 17:01:54 +08:00
1 parent 2417b1a41c
commit fe8735aac2
26 files changed
+2417 -157

No files matched your search

+81 -29
View File
@@ -1,34 +1,7 @@
// Runs actual submission code in a JS sandbox; no browser, network or database.
const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
const {webcrypto} = require('node:crypto');
const source = fs.readFileSync(path.resolve(__dirname, '../../arr_web/static/app.js'), 'utf8');
const boot = ' boot();\n})();';
assert(source.endsWith(boot+'\n') || source.endsWith(boot));
function harness(respond) {
const elements=new Map(), storage=new Map(), calls=[];
const element=selector => {
if (!elements.has(selector)) elements.set(selector,{value:'', disabled:false, hidden:false, textContent:'',
classList:{add(){},remove(){},toggle(){},contains(){return false;}},setAttribute(){}});
return elements.get(selector);
};
const context=vm.createContext({Headers, console, Date, Intl, Uint8Array,
document:{hidden:false,querySelector:element},
window:{ARRI18n:{t:key=>key,text:value=>value,errorMessage:code=>code},crypto:webcrypto,
setTimeout(){return 1;},clearTimeout(){},location:{replace(){}}},
localStorage:{setItem:(k,v)=>storage.set(k,v),getItem:k=>storage.get(k),removeItem:k=>storage.delete(k)},
fetch:async (url, options) => {calls.push({url,method:options.method||'GET',body:options.body});return respond(url,options,calls);},
});
vm.runInContext(source.replace(boot,' globalThis.subject = {state, submitARRDownload, rememberARRIntent, acceptARRDownloadTask, handleARRDownloadDateChange, initARRDownload};\n})();'),context);
const subject=context.subject;
Object.assign(subject.state,{arrDownloadReady:true,arrDownloadLoaded:true,arrDownloadStorageKey:'test',csrf:'fixture'});
element('#arr-download-date').value='2026-09-16';
return {...subject,calls,storage,element,submit:()=>subject.submitARRDownload({preventDefault(){}})};
}
const response=(status,data,code) => ({status,ok:status<400,json:async()=>code?{ok:false,error:{code}}:{ok:true,data}});
const {harness,response,scopedKey} = require('./helpers/arr_ui_harness.cjs');
const refusal=()=>response(409,null,'REPLAY_DATE_NOT_AVAILABLE');
test('definite unavailable source date clears only the refused intent and permits correction',async()=>{
@@ -143,7 +116,7 @@ for (const status of ['succeeded','failed']) {
test('editing before status loads still restores the running task and retains the selected date',async()=>{
const task={request_id:'e'.repeat(32),report_date:'2026-09-15',status:'downloading',can_retry:false};
const h=harness(()=>response(200,{ready:true,default_date:'2026-09-17',latest_task:task}));
const h=harness(()=>response(200,{context_id:'production',ready:true,default_date:'2026-09-17',latest_task:task}));
h.handleARRDownloadDateChange();
await h.initARRDownload();
assert.equal(h.state.arrDownloadTask.request_id,task.request_id);
@@ -152,3 +125,82 @@ test('editing before status loads still restores the running task and retains th
assert.equal(h.calls.length,1);
assert.equal(h.calls[0].method,'GET');
});
test('config is fetched first and only this instance and user may restore an intent',async()=>{
const intent={request_id:'f'.repeat(32),report_date:'2026-10-07'};
const h=harness((url)=>{
if(url==='/api/arr-downloads') {
assert.equal(h.storageReads.length,0,'identity must be fetched before storage is read');
return response(200,{context_id:'production',ready:true,default_date:'2026-10-06'});
}
assert.equal(url,`/api/arr-downloads/${intent.request_id}`);
return response(200,{...intent,status:'downloading',can_retry:false});
});
h.storage.set(scopedKey(),JSON.stringify(intent));
h.storage.set(scopedKey('sandbox'),JSON.stringify({...intent,request_id:'a'.repeat(32)}));
h.storage.set(scopedKey('production','another-user'),JSON.stringify({...intent,request_id:'b'.repeat(32)}));
h.storage.set('arr:last-download:operator',JSON.stringify({...intent,report_date:'2026-09-15'}));
await h.initARRDownload();
assert.deepEqual(h.storageReads,[scopedKey()]);
assert.equal(h.state.arrDownloadTask.request_id,intent.request_id);
assert.equal(h.element('#arr-download-date').value,intent.report_date);
assert.equal(h.calls.every(call=>call.method==='GET'),true);
});
test('legacy or another context cannot replace default date with an old failed task',async()=>{
const old={request_id:'a'.repeat(32),report_date:'2026-09-15',status:'failed',can_retry:true};
const h=harness(()=>response(200,{context_id:'production',ready:true,default_date:'2026-10-07',latest_task:old}));
h.storage.set('arr:last-download:operator',JSON.stringify(old));
h.storage.set(scopedKey('sandbox'),JSON.stringify(old));
await h.initARRDownload();
assert.equal(h.state.arrDownloadTask,null);
assert.equal(h.state.arrDownloadIntent,null);
assert.equal(h.element('#arr-download-date').value,'2026-10-07');
assert.deepEqual(h.storageReads,[scopedKey()]);
assert.equal(h.calls.length,1);
});
test('config failure does not read any saved request before identity is known',async()=>{
const h=harness(()=>{throw new TypeError('offline');});
h.storage.set('arr:last-download:operator',JSON.stringify({request_id:'a'.repeat(32),report_date:'2026-09-15'}));
await h.initARRDownload();
assert.equal(h.storageReads.length,0);
assert.equal(h.state.arrDownloadIntent,null);
assert.equal(h.state.arrDownloadRestored,false);
});
test('an unavailable instance without an identity stays unavailable without restoring storage',async()=>{
const h=harness(()=>response(200,{ready:false,context_id:null,default_date:'2026-10-07'}));
await h.initARRDownload();
assert.equal(h.storageReads.length,0);
assert.equal(h.state.arrDownloadReady,false);
assert.equal(h.state.arrDownloadConfigDisconnected,false);
assert.equal(h.element('#arr-download-date').value,'2026-10-07');
assert.equal(h.element('#arr-download-button').disabled,true);
});
test('a running task from config preselects its date and only scoped terminal intent restores later',async()=>{
const task={request_id:'a'.repeat(32),report_date:'2026-10-07',status:'processing',can_retry:false};
const h=harness(url=>response(200,url==='/api/arr-downloads'
? {context_id:'production',ready:true,default_date:'2026-10-06',latest_task:task} : {...task,status:'failed',can_retry:true}));
await h.initARRDownload();
assert.equal(h.element('#arr-download-date').value,task.report_date);
assert.equal(h.element('#arr-download-button').disabled,true);
await h.initARRDownload();
assert.equal(h.state.arrDownloadTask.status,'failed');
assert.equal(h.state.arrDownloadIntent.request_id,task.request_id);
assert.equal(h.element('#arr-download-date').value,task.report_date);
});
test('changing source context clears the previous in-memory intent before restoring',async()=>{
let context='sandbox';
const h=harness(()=>response(200,{context_id:context,ready:true,default_date:'2026-10-07'}));
await h.initARRDownload();
h.rememberARRIntent({request_id:'a'.repeat(32),report_date:'2026-09-15'});
context='production';
await h.initARRDownload();
assert.equal(h.state.arrDownloadIntent,null);
assert.equal(h.state.arrDownloadTask,null);
assert.equal(h.element('#arr-download-date').value,'2026-10-07');
assert.equal(h.calls.length,2);
});