import test from 'brittle' import b4a from 'b4a' import Hyperdrive from 'hyperdrive' import Corestore from 'corestore' import { mkdirSync, rmSync } from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { createVfs } from './lib/vfs.js' import { createBareOsIpc } from './lib/bare-os-ipc.js' import { bareHolesailManagedStartService, bareHolesailManagedStopService, bareHolesailManagedPersistentSeedLooksValid, bareHolesailManagedReadState, bareHolesailManagedWriteState } from './lib/bare-holesail-managed.js' import { bareOsSshHolesailConnectionId, ensureBareOsSshHolesailTunnel } from './lib/bare-os-ssh-holesail.js' const __dirname = path.dirname(fileURLToPath(import.meta.url)) function testCorestoreDir(name) { const dir = path.join( __dirname, '.test-data', name + '-' + process.pid + '-' + Math.random().toString(36).slice(2) ) mkdirSync(path.dirname(dir), { recursive: true }) return dir } function testCtx(drive, personal, env = {}) { const shellEnv = { HOME: '/home/user', PATH: '/bin', USER: 'user', UID: '1000', GID: '1000', PWD: '/home/user', BARE_OS_EXIT_STATUS: '0', BARE_OS_SSH_LISTEN_PORT: '0', ...env } const bareOsIpc = createBareOsIpc() const vfs = createVfs(drive, personal, shellEnv, null, { bareOsIpc }) return { drive, personalDrive: personal, vfs, bareOsIpc, env: shellEnv, console, b4a, bareOsRegisterSuspendHook: () => {}, bareOsRegisterResumeHook: () => {} } } test('ensureBareOsSshHolesailTunnel persists managed server entry (2222 / 127.0.0.1)', async (t) => { const dir = testCorestoreDir('sshhs') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psshhs')) await sys.ready() await personal.ready() const ctx = testCtx(sys, personal, { USER: 'guest', HOME: '/home/guest', UID: '65534', GID: '65534', PWD: '/home/guest' }) const p = 2222 const h = '127.0.0.1' const id = bareOsSshHolesailConnectionId(p) const empty = { version: 1, connections: {} } await bareHolesailManagedWriteState( ctx, /** @type {Record} */ (ctx.env), empty ) await ensureBareOsSshHolesailTunnel(ctx, ctx.env, p, h) const { state } = await bareHolesailManagedReadState( ctx, /** @type {Record} */ (ctx.env) ) const row = state.connections[id] t.ok(row && /** @type {{ server?: boolean }} */ (row).server === true) t.is(/** @type {{ port?: number }} */ (row).port, p) t.is(/** @type {{ host?: string }} */ (row).host, h) const seedStr = /** @type {{ seed?: string }} */ (row).seed t.ok(seedStr && bareHolesailManagedPersistentSeedLooksValid(seedStr)) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ensureBareOsSshHolesailTunnel preserves hs key and migrates seed like www', async (t) => { const dir = testCorestoreDir('sshhskey') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psshsk')) await sys.ready() await personal.ready() const ctx = testCtx(sys, personal, { USER: 'guest', HOME: '/home/guest', UID: '65534', GID: '65534', PWD: '/home/guest' }) const p = 2222 const h = '127.0.0.1' const id = bareOsSshHolesailConnectionId(p) const keepKey = 'hs://0000keepthiskey000000000000000000000000000000000000000000' await bareHolesailManagedWriteState( ctx, /** @type {Record} */ (ctx.env), { version: 1, connections: { [id]: { server: true, port: 19999, host: '0.0.0.0', enabled: true, key: keepKey } } } ) await ensureBareOsSshHolesailTunnel(ctx, ctx.env, p, h) const { state } = await bareHolesailManagedReadState( ctx, /** @type {Record} */ (ctx.env) ) const row = /** @type {{ port?: number, host?: string, key?: string }} */ ( state.connections[id] ) t.is(row.port, p) t.is(row.host, h) t.is(row.key, keepKey) const migratedSeed = /** @type {{ seed?: string }} */ (row).seed t.ok(migratedSeed && bareHolesailManagedPersistentSeedLooksValid(migratedSeed)) t.is( migratedSeed, 'keepthiskey000000000000000000000000000000000000000000'.toLowerCase() ) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ensureBareOsSshHolesailTunnel reuses existing identity and prunes duplicate prefixed entries', async (t) => { const dir = testCorestoreDir('sshhsdedupe') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psshdedupe')) await sys.ready() await personal.ready() const ctx = testCtx(sys, personal, { USER: 'guest', HOME: '/home/guest', UID: '65534', GID: '65534', PWD: '/home/guest' }) const keepId = bareOsSshHolesailConnectionId(35657) const dropId = bareOsSshHolesailConnectionId(34155) const keepKey = 'hs://0000keepidentity000000000000000000000000000000000000000000' await bareHolesailManagedWriteState( ctx, /** @type {Record} */ (ctx.env), { version: 1, connections: { [keepId]: { server: true, port: 35657, host: '127.0.0.1', enabled: true, key: keepKey }, [dropId]: { server: true, port: 34155, host: '127.0.0.1', enabled: true, seed: 'a'.repeat(64) } } } ) await ensureBareOsSshHolesailTunnel(ctx, ctx.env, 33691, '127.0.0.1') const { state } = await bareHolesailManagedReadState( ctx, /** @type {Record} */ (ctx.env) ) const nextId = bareOsSshHolesailConnectionId(33691) t.ok(Object.prototype.hasOwnProperty.call(state.connections, nextId)) const row = /** @type {{ port?: number, key?: string, seed?: string }} */ ( state.connections[nextId] ) t.is(row.port, 33691) t.ok(row.seed && bareHolesailManagedPersistentSeedLooksValid(row.seed)) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('ensureBareOsSshHolesailTunnel restarts managed runtime when SSH port changes', async (t) => { const dir = testCorestoreDir('sshhssync') const store = new Corestore(dir) const sys = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psshsync')) await sys.ready() await personal.ready() const ctx = testCtx(sys, personal, { USER: 'guest', HOME: '/home/guest', UID: '65534', GID: '65534', PWD: '/home/guest', BARE_OS_HOLESAIL_INITD: '1', BARE_OS_HOLESAIL_MANAGED: '1' }) const id = bareOsSshHolesailConnectionId(45931) await bareHolesailManagedWriteState( ctx, /** @type {Record} */ (ctx.env), { version: 1, connections: { [id]: { server: true, port: 45931, host: '127.0.0.1', enabled: true, seed: 'c'.repeat(64) } } } ) await bareHolesailManagedStartService(ctx, ctx.env) await ensureBareOsSshHolesailTunnel(ctx, ctx.env, 33403, '127.0.0.1') const { state } = await bareHolesailManagedReadState( ctx, /** @type {Record} */ (ctx.env) ) const nextId = bareOsSshHolesailConnectionId(33403) t.absent(state.connections[id]) const row = /** @type {{ port?: number }} */ (state.connections[nextId]) t.is(row.port, 33403) await bareHolesailManagedStopService(ctx) await store.close() rmSync(dir, { recursive: true, force: true }) })