80 lines
3.1 KiB
TypeScript
80 lines
3.1 KiB
TypeScript
import { Actor, Handle, Turn } from './actor.js';
|
|
import { Dataspace, Observe } from './dataspace.js';
|
|
import { Relay, spawnRelay } from './relay.js';
|
|
import * as net from 'net';
|
|
|
|
import { Caveat, mint, Or, Rewrite, sturdyEncode, SturdyRef, validate, _Or, _Rewrite } from './sturdy.js';
|
|
import { KEY_LENGTH } from './cryptography.js';
|
|
import { attenuate, Attenuation } from './rewrite.js';
|
|
import { Bytes, IdentityMap } from 'preserves';
|
|
|
|
const secretKey = new Bytes(KEY_LENGTH);
|
|
mint('syndicate', secretKey).then(v => {
|
|
console.log(v.asPreservesText());
|
|
console.log(sturdyEncode(v).toHex());
|
|
});
|
|
|
|
function internalize(caveatChain: Caveat[][]): Attenuation {
|
|
const a: Attenuation = [];
|
|
caveatChain.slice().reverse().forEach(cs => a.push(... cs.map(c => {
|
|
const alts = c.label === _Rewrite ? [c] : Or<Rewrite>()._.alternatives(c);
|
|
return alts.map(r => ({ pattern: Rewrite._.pattern(r), template: Rewrite._.template(r) }));
|
|
})));
|
|
return a;
|
|
}
|
|
|
|
Turn.for(new Actor(), t => {
|
|
const ds = t.ref(new Dataspace());
|
|
|
|
function spawnConnection(t: Turn, socket: net.Socket) {
|
|
console.log('connection', socket.remoteAddress, socket.remotePort);
|
|
spawnRelay(t, {
|
|
packetWriter: bs => socket.write(bs),
|
|
setup(t: Turn, r: Relay) {
|
|
socket.on('error', err => t.freshen(t =>
|
|
((err as any).code === 'ECONNRESET') ? t.quit() : t.crash(err)));
|
|
socket.on('close', () => t.freshen(t => t.quit()));
|
|
socket.on('end', () => t.freshen(t => t.quit()));
|
|
socket.on('data', data => r.accept(data));
|
|
t.actor.atExit(() => socket.destroy());
|
|
},
|
|
initialRef: t.ref({
|
|
handleMap: new IdentityMap<Handle, Handle>(),
|
|
async assert(t, a, h) {
|
|
if (!Observe.isClassOf(a)) return;
|
|
const r = Observe._.label(a);
|
|
if (!SturdyRef.isClassOf(r)) return;
|
|
if (!await validate(r, secretKey)) {
|
|
console.warn(`Invalid SturdyRef: ${r.asPreservesText()}`);
|
|
return;
|
|
}
|
|
const attenuated_ds = attenuate(
|
|
ds,
|
|
... internalize(SturdyRef._.caveatChain(r)));
|
|
t.freshen(t => this.handleMap.set(
|
|
h,
|
|
t.assert(Observe._.observer(a), attenuated_ds)));
|
|
},
|
|
retract(t, h) {
|
|
t.retract(this.handleMap.get(h));
|
|
this.handleMap.delete(h);
|
|
}
|
|
}),
|
|
// debug: true,
|
|
});
|
|
}
|
|
|
|
t.spawn(t => {
|
|
const server = net.createServer(socket => t.freshen(t => spawnConnection(t, socket)));
|
|
server.on('error', err => t.freshen(t => t.crash(err)));
|
|
server.listen(5999, '0.0.0.0', 512);
|
|
t.actor.atExit(() => {
|
|
try {
|
|
server.close();
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
});
|
|
});
|
|
});
|