novy-syndicate/src/server.ts

74 lines
2.8 KiB
TypeScript

import { Actor, Handle, Turn } from './actor.js';
import { Dataspace } from './dataspace.js';
import { Relay, spawnRelay } from './relay.js';
import * as net from 'net';
import { mint, sturdyEncode, validate } from './sturdy.js';
import { KEY_LENGTH } from './cryptography.js';
import { attenuate } from './rewrite.js';
import { Bytes, IdentityMap } from '@preserves/core';
import { Attenuation, fromSturdyRef, toResolve } from './gen/sturdy.js';
const secretKey = new Bytes(KEY_LENGTH);
mint('syndicate', secretKey).then(v => {
console.log(fromSturdyRef(v).asPreservesText());
console.log(sturdyEncode(fromSturdyRef(v)).toHex());
});
new Actor(t => {
t.activeFacet.preventInertCheck();
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.stopActor() : t.crash(err)));
socket.on('close', () => t.freshen(t => t.stopActor()));
socket.on('end', () => t.freshen(t => t.stopActor()));
socket.on('data', data => r.accept(data));
t.activeFacet.actor.atExit(() => socket.destroy());
},
initialRef: t.ref({
handleMap: new IdentityMap<Handle, Handle>(),
async assert(t, a0, h) {
const a = toResolve(a0);
if (a === void 0) return;
const r = a.sturdyref;
if (!await validate(r, secretKey)) {
console.warn(`Invalid SturdyRef: ${r.asPreservesText()}`);
return;
}
const cavs: Attenuation = [];
r.caveatChain.forEach(cs => cavs.push(... cs));
const attenuated_ds = attenuate(ds, ... cavs);
t.freshen(t => this.handleMap.set(
h,
t.assert(a.observer, 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.activeFacet.preventInertCheck();
t.activeFacet.actor.atExit(() => {
try {
server.close();
} catch (e) {
console.error(e);
}
});
});
});