Private CLI workflow for reviewed depowit operations
This commit is contained in:
Executable
+19
@@ -0,0 +1,19 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { parseCustodyDbArguments } from '../server/market/custody-db-args.ts';
|
||||
|
||||
test('custody database CLI parses two-argument deposit operations without shifting arguments', () => {
|
||||
assert.deepEqual(parseCustodyDbArguments(['deposit-prepare-credit', 'a'.repeat(64), `${'b'.repeat(64)}:${'c'.repeat(64)}`]), {
|
||||
action: 'deposit-prepare-credit', argument: 'a'.repeat(64), extraArgument: `${'b'.repeat(64)}:${'c'.repeat(64)}`,
|
||||
});
|
||||
assert.deepEqual(parseCustodyDbArguments(['deposit-prepare-resolve-hold', 'credit-id', 'hold-id']), {
|
||||
action: 'deposit-prepare-resolve-hold', argument: 'credit-id', extraArgument: 'hold-id',
|
||||
});
|
||||
});
|
||||
|
||||
test('custody database CLI rejects unknown, missing, empty, and excess arguments', () => {
|
||||
for (const args of [[], ['unknown'], ['audit', 'extra'], ['deposit-prepare-credit', 'wallet'],
|
||||
['deposit-prepare-credit', 'wallet', 'observation', 'extra'], ['deposit-release', '']]) {
|
||||
assert.throws(() => parseCustodyDbArguments(args));
|
||||
}
|
||||
});
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { chmod, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { loadMoneroDepositReviewApproval, loadMoneroDepositReviewPolicy } from '../server/market/monero-deposit-review-config.ts';
|
||||
|
||||
const owner = 'a'.repeat(64);
|
||||
|
||||
async function privateFile(path: string, content: string) {
|
||||
await writeFile(path, content, { mode: 0o600 });
|
||||
await chmod(path, 0o600);
|
||||
}
|
||||
|
||||
test('deposit review policy requires an owner-only protected file and strict bounds', async t => {
|
||||
if (process.platform === 'win32') {
|
||||
await assert.rejects(loadMoneroDepositReviewPolicy({ WIKIDECK_MONERO_DEPOSIT_REVIEW_POLICY_FILE: 'C:\\private\\policy.json' }), /Invalid or inaccessible/);
|
||||
return;
|
||||
}
|
||||
const directory = await mkdtemp(join(tmpdir(), 'wikideck-deposit-review-'));
|
||||
t.after(() => rm(directory, { recursive: true, force: true }));
|
||||
const policyPath = join(directory, 'policy.json');
|
||||
const env = { WIKIDECK_MONERO_DEPOSIT_REVIEW_POLICY_FILE: policyPath };
|
||||
const valid = { approvedReviewerOwners: [owner], minimumConfirmations: 10, maximumObservationAgeMs: 120_000 };
|
||||
await assert.rejects(loadMoneroDepositReviewPolicy({}), /required/);
|
||||
await privateFile(policyPath, JSON.stringify(valid));
|
||||
assert.deepEqual(await loadMoneroDepositReviewPolicy(env), valid);
|
||||
|
||||
await privateFile(policyPath, JSON.stringify({ ...valid, unexpected: true }));
|
||||
await assert.rejects(loadMoneroDepositReviewPolicy(env), /Invalid or inaccessible/);
|
||||
await privateFile(policyPath, JSON.stringify({ ...valid, minimumConfirmations: 2 }));
|
||||
await assert.rejects(loadMoneroDepositReviewPolicy(env), /Invalid or inaccessible/);
|
||||
|
||||
await privateFile(policyPath, JSON.stringify(valid)); await chmod(policyPath, 0o644);
|
||||
await assert.rejects(loadMoneroDepositReviewPolicy(env), /Invalid or inaccessible/);
|
||||
await rm(policyPath);
|
||||
await symlink(join(directory, 'missing-target.json'), policyPath);
|
||||
await assert.rejects(loadMoneroDepositReviewPolicy(env), /Invalid or inaccessible/);
|
||||
});
|
||||
|
||||
test('deposit approval file loader requires an absolute, bounded, private regular file', async t => {
|
||||
if (process.platform === 'win32') {
|
||||
await assert.rejects(loadMoneroDepositReviewApproval('C:\\private\\approval.json'), /Invalid or inaccessible/);
|
||||
return;
|
||||
}
|
||||
const directory = await mkdtemp(join(tmpdir(), 'wikideck-deposit-approval-'));
|
||||
t.after(() => rm(directory, { recursive: true, force: true }));
|
||||
const approvalPath = join(directory, 'approval.json');
|
||||
const approval = { version: 1, signature: 'signed-review-fixture' };
|
||||
await assert.rejects(loadMoneroDepositReviewApproval('relative-approval.json'), /protected Monero deposit review approval/);
|
||||
await privateFile(approvalPath, JSON.stringify(approval));
|
||||
assert.deepEqual(await loadMoneroDepositReviewApproval(approvalPath), approval);
|
||||
|
||||
await privateFile(approvalPath, 'x'.repeat(64 * 1024 + 1));
|
||||
await assert.rejects(loadMoneroDepositReviewApproval(approvalPath), /protected Monero deposit review approval/);
|
||||
await privateFile(approvalPath, '{malformed');
|
||||
await assert.rejects(loadMoneroDepositReviewApproval(approvalPath), /protected Monero deposit review approval/);
|
||||
});
|
||||
Reference in New Issue
Block a user