pithos/hosted/main.js
Local Dev d00bd369b7 Pithos: run your drives on Silent Mode with your own Sia account
s3d binds one Sia account per process, so the server runs one s3d per
person (pithos-hosted), started on demand and flushed and stopped when idle.
Only the connected s3d data folder moves between PC and server; the Sia
recovery phrase never leaves the PC and nothing is re-uploaded to Sia.

Because the server holds the connection key, local Pithos encrypts names and
contents before they leave the machine, with keys from the Theseus vault (or
a local key file elsewhere). What s3d cannot do on its own, the gateway now
enforces: public folders, expiring share links and S3 keys for other people
limited to one folder with read, add-only or edit rights. Files those reach
are stored readable, since visitors have no key, and go back to encrypted
when the rule is removed. Sign-up needs a BNS name signature, a deposit or
an invite, with a per-IP limit.
2026-10-04 01:33:20 +02:00

39 lines
1.4 KiB
JavaScript

#!/usr/bin/env node
// pithos-hosted entry: node hosted/main.js --config /etc/pithos-hosted.json
import fs from 'node:fs';
import { createHosted } from './server.js';
const DEFAULTS = {
listen: '127.0.0.1:8720',
publicUrl: 'https://s3.silentmode.st',
root: '/var/lib/pithos-hosted',
s3dBinary: null,
portBase: 21000,
maxRunning: 30,
idleMinutes: 30,
bufferLimitBytes: 2 * 1024 ** 3,
maxDataBytes: 4 * 1024 ** 3,
downloadCapBytes: 50 * 1024 ** 3,
trustProxy: false,
gate: { bns: { api: 'https://navigate.st' }, deposit: null, invites: [], perIpPerDay: 3 },
};
const i = process.argv.indexOf('--config');
const file = i > 0 ? process.argv[i + 1] : process.env.PITHOS_HOSTED_CONFIG;
if (!file) { console.error('usage: pithos-hosted --config <file.json>'); process.exit(2); }
const cfg = { ...DEFAULTS, ...JSON.parse(fs.readFileSync(file, 'utf8')) };
if (!cfg.s3dBinary || !fs.existsSync(cfg.s3dBinary)) { console.error(`s3dBinary not found: ${cfg.s3dBinary}`); process.exit(2); }
cfg.publicUrl = cfg.publicUrl.replace(/\/$/, '');
const hosted = await createHosted(cfg);
let stopping = false;
for (const sig of ['SIGTERM', 'SIGINT']) {
process.on(sig, async () => {
if (stopping) return;
stopping = true;
console.log(`${sig}: flushing and stopping every s3d`);
await hosted.close().catch((e) => console.error(e));
process.exit(0);
});
}