213 lines
5.2 KiB
TypeScript
213 lines
5.2 KiB
TypeScript
import * as Automerge from 'automerge';
|
||
import assert = require('assert');
|
||
|
||
import * as pgp from 'openpgp';
|
||
import * as fs from 'fs';
|
||
|
||
import { PGPSigner } from '../src/auth';
|
||
|
||
import { Syncable, ArgPair } from '../src/sync';
|
||
|
||
import { MockKeyStore, MockSigner } from './mock';
|
||
|
||
|
||
describe('sync', async () => {
|
||
it('sync_merge', () => {
|
||
const mockSigner = new MockSigner();
|
||
const s = new Syncable('foo', {
|
||
bar: 'baz',
|
||
});
|
||
s.setSigner(mockSigner);
|
||
const changePair = new ArgPair('xyzzy', 42);
|
||
s.update([changePair], 'ch-ch-cha-changes');
|
||
assert.equal(s.m.data['xyzzy'], 42)
|
||
assert.equal(s.m.data['bar'], 'baz')
|
||
assert.equal(s.m['id'], 'foo')
|
||
assert.equal(Automerge.getHistory(s.m).length, 2);
|
||
});
|
||
|
||
it('sync_serialize', () => {
|
||
const mockSigner = new MockSigner();
|
||
const s = new Syncable('foo', {
|
||
bar: 'baz',
|
||
});
|
||
s.setSigner(mockSigner);
|
||
const j = s.toJSON();
|
||
const ss = Syncable.fromJSON(j);
|
||
assert.equal(ss.m['id'], 'foo');
|
||
assert.equal(ss.m['data']['bar'], 'baz');
|
||
assert.equal(Automerge.getHistory(ss.m).length, 1);
|
||
});
|
||
|
||
it('sync_sign_and_wrap', () => {
|
||
const mockSigner = new MockSigner();
|
||
const s = new Syncable('foo', {
|
||
bar: 'baz',
|
||
});
|
||
s.setSigner(mockSigner);
|
||
s.onwrap = (e) => {
|
||
const j = e.toJSON();
|
||
const v = JSON.parse(j);
|
||
assert.deepEqual(v.payload, e.o.payload);
|
||
|
||
}
|
||
s.sign();
|
||
});
|
||
it('sync_verify_success', async () => {
|
||
const pksa = fs.readFileSync(__dirname + '/privatekeys.asc');
|
||
const pks = await pgp.key.readArmored(pksa);
|
||
await pks.keys[0].decrypt('merman');
|
||
await pks.keys[1].decrypt('beastman');
|
||
|
||
const pubksa = fs.readFileSync(__dirname + '/publickeys.asc');
|
||
const pubks = await pgp.key.readArmored(pubksa);
|
||
|
||
const oneStore = new MockKeyStore(pks.keys[0], pubks.keys);
|
||
const twoStore = new MockKeyStore(pks.keys[1], pubks.keys);
|
||
const threeStore = new MockKeyStore(pks.keys[2], [pubks.keys[0], pubks.keys[2]]);
|
||
|
||
const oneSigner = new PGPSigner(oneStore);
|
||
const twoSigner = new PGPSigner(twoStore);
|
||
const threeSigner = new PGPSigner(threeStore);
|
||
|
||
const x = new Syncable('foo', {
|
||
bar: 'baz',
|
||
});
|
||
x.setSigner(oneSigner);
|
||
|
||
// TODO: make this look better
|
||
x.onwrap = (e) => {
|
||
let updateData = new ArgPair('bar', 'xyzzy');
|
||
x.update([updateData], 'change one');
|
||
|
||
x.onwrap = (e) => {
|
||
x.setSigner(twoSigner);
|
||
updateData = new ArgPair('bar', 42);
|
||
x.update([updateData], 'change two');
|
||
|
||
x.onwrap = (e) => {
|
||
const p = e.unwrap();
|
||
p.setSigner(twoSigner);
|
||
p.onauthenticate = (v) => {
|
||
assert(v);
|
||
}
|
||
p.authenticate();
|
||
}
|
||
|
||
x.sign();
|
||
};
|
||
|
||
x.sign();
|
||
}
|
||
|
||
x.sign();
|
||
|
||
});
|
||
|
||
it('sync_verify_fail', async () => {
|
||
const pksa = fs.readFileSync(__dirname + '/privatekeys.asc');
|
||
const pks = await pgp.key.readArmored(pksa);
|
||
await pks.keys[0].decrypt('merman');
|
||
await pks.keys[1].decrypt('beastman');
|
||
|
||
const pubksa = fs.readFileSync(__dirname + '/publickeys.asc');
|
||
const pubks = await pgp.key.readArmored(pubksa);
|
||
|
||
const oneStore = new MockKeyStore(pks.keys[0], pubks.keys);
|
||
const twoStore = new MockKeyStore(pks.keys[1], pubks.keys);
|
||
const threeStore = new MockKeyStore(pks.keys[2], [pubks.keys[0], pubks.keys[2]]);
|
||
|
||
const oneSigner = new PGPSigner(oneStore);
|
||
const twoSigner = new PGPSigner(twoStore);
|
||
const threeSigner = new PGPSigner(threeStore);
|
||
|
||
const x = new Syncable('foo', {
|
||
bar: 'baz',
|
||
});
|
||
x.setSigner(oneSigner);
|
||
|
||
// TODO: make this look better
|
||
x.onwrap = (e) => {
|
||
let updateData = new ArgPair('bar', 'xyzzy');
|
||
x.update([updateData], 'change one');
|
||
|
||
x.onwrap = (e) => {
|
||
x.setSigner(twoSigner);
|
||
updateData = new ArgPair('bar', 42);
|
||
x.update([updateData], 'change two');
|
||
|
||
x.onwrap = (e) => {
|
||
const p = e.unwrap();
|
||
p.setSigner(threeSigner);
|
||
p.onauthenticate = (v) => {
|
||
assert(!v);
|
||
}
|
||
p.authenticate();
|
||
}
|
||
|
||
x.sign();
|
||
};
|
||
|
||
x.sign();
|
||
}
|
||
|
||
x.sign();
|
||
|
||
});
|
||
|
||
xit('sync_verify_shallow_tricked', async () => {
|
||
const pksa = fs.readFileSync(__dirname + '/privatekeys.asc');
|
||
const pks = await pgp.key.readArmored(pksa);
|
||
await pks.keys[0].decrypt('merman');
|
||
await pks.keys[1].decrypt('beastman');
|
||
|
||
const pubksa = fs.readFileSync(__dirname + '/publickeys.asc');
|
||
const pubks = await pgp.key.readArmored(pubksa);
|
||
|
||
const oneStore = new MockKeyStore(pks.keys[0], pubks.keys);
|
||
const twoStore = new MockKeyStore(pks.keys[1], pubks.keys);
|
||
const threeStore = new MockKeyStore(pks.keys[2], [pubks.keys[0], pubks.keys[2]]);
|
||
|
||
const oneSigner = new PGPSigner(oneStore);
|
||
const twoSigner = new PGPSigner(twoStore);
|
||
const threeSigner = new PGPSigner(threeStore);
|
||
|
||
const x = new Syncable('foo', {
|
||
bar: 'baz',
|
||
});
|
||
x.setSigner(twoSigner);
|
||
|
||
// TODO: make this look better
|
||
x.onwrap = (e) => {
|
||
let updateData = new ArgPair('bar', 'xyzzy');
|
||
x.update([updateData], 'change one');
|
||
|
||
x.onwrap = (e) => {
|
||
updateData = new ArgPair('bar', 42);
|
||
x.update([updateData], 'change two');
|
||
x.setSigner(oneSigner);
|
||
|
||
x.onwrap = (e) => {
|
||
const p = e.unwrap();
|
||
p.setSigner(threeSigner);
|
||
p.onauthenticate = (v) => {
|
||
assert(v);
|
||
p.onauthenticate = (v) => {
|
||
assert(!v);
|
||
}
|
||
p.authenticate(true);
|
||
}
|
||
p.authenticate();
|
||
}
|
||
|
||
x.sign();
|
||
};
|
||
|
||
x.sign();
|
||
}
|
||
|
||
x.sign();
|
||
|
||
});
|
||
});
|