Consolidate Persimmons source

This commit is contained in:
matcha committed 2026-10-04 02:46:28 +00:00
1 parent 534961db9b
commit 5fc3cd5795
1 file changed
+56
+56
View File
@@ -0,0 +1,56 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {createHash} from 'node:crypto';
import {readFile} from 'node:fs/promises';
import {initialize, unlock, encryptItem, decryptItem, isHttpsOrigin} from '../human-crypto.mjs';
import {EXTENSION_ID} from '../identity.mjs';
import {vaultRequest} from '../human-api.mjs';
test('deterministic unpacked ID agrees with the exact server Origin', async () => {
const manifest = JSON.parse(await readFile(new URL('../manifest.json', import.meta.url)));
const derived = createHash('sha256').update(Buffer.from(manifest.key, 'base64')).digest('hex').slice(0, 32)
.replace(/[0-9a-f]/g, c => String.fromCharCode(97 + parseInt(c, 16)));
assert.equal(derived, EXTENSION_ID);
const server = await readFile(new URL('../../tea_mcp/human_vault.py', import.meta.url), 'utf8');
assert.ok(server.includes(`EXTENSION_ORIGIN = "chrome-extension://${derived}"`));
});
test('exact HTTPS origins are data while extension origin remains the caller boundary', () => {
for (const origin of ['https://example.com','https://accounts.example.com','https://example.com:8443']) assert.equal(isHttpsOrigin(origin),true);
for (const origin of ['http://example.com','https://example.com/path','https://user@example.com','not-a-url']) assert.equal(isHttpsOrigin(origin),false);
});
test('local wrapping and authenticated ciphertext work for ordinary HTTPS sites', async () => {
const passphrase = 'disposable test passphrase';
const owner = 'fixture';
const record = await initialize(passphrase, owner);
assert.ok(!JSON.stringify(record).includes(passphrase));
const key = await unlock(passphrase, owner, record);
assert.equal(key.extractable, false);
await assert.rejects(crypto.subtle.exportKey('raw', key));
await assert.rejects(unlock('wrong passphrase', owner, record), /Unlock failed/);
const account = {username: 'DISPOSABLE_USER_SENTINEL', password: 'DISPOSABLE_PASSWORD_SENTINEL'};
const item = await encryptItem(key, owner, 'https://example.com', account);
assert.deepEqual(await decryptItem(key, owner, item), account);
assert.equal(item.username, account.username);
assert.ok(!JSON.stringify(item).includes(account.password));
const updated = await encryptItem(key, owner, item.origin, account, item.id);
assert.notEqual(updated.iv, item.iv);
assert.notEqual(updated.ciphertext, item.ciphertext);
for (const bad of [{...item,id:'0'.repeat(32)},{...item,origin:'https://other.example'},{...item,v:2}])
await assert.rejects(decryptItem(key, owner, bad), /failed authentication/);
});
test('vault HTTP has no query or keys; session failures never echo bodies', async () => {
await vaultRequest('GET', 'fixture', '1'.repeat(32), undefined, async (url, options) => {
assert.equal(url, 'https://teahub.xyz/tea/site/chat/persimmons/human-vault/items/' + '1'.repeat(32) + '/read');
assert.equal(options.method, 'POST');
assert.equal(options.credentials, 'include');
assert.equal(options.headers['X-Vault-Owner'], 'fixture');
return new Response(JSON.stringify({owner: 'fixture'}), {headers: {'Content-Type': 'application/json'}});
});
for (const status of [401,403,500]) await assert.rejects(
vaultRequest('GET', undefined, undefined, undefined, async()=>new Response('PRIVATE_SENTINEL',{status})),
/Vault unavailable/
);
});