import { readFile } from 'node:fs/promises' import path from 'node:path' import { PassThrough } from 'node:stream' import { fileURLToPath } from 'node:url' import test from 'brittle' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor async function loadLoginBin() { const runtime = await readFile(path.join(__dirname, '../lib/runtime.js'), 'utf8') const preamble = await readFile( path.join(__dirname, '../lib/edit/interactive-masked-line.js'), 'utf8' ) const body = await readFile(path.join(__dirname, '../src/login.js'), 'utf8') return new AsyncFunction( 'ctx', 'argv', `${runtime}\n${preamble}\n${body}\nif (typeof run === 'function') return await run(ctx, argv)\n` ) } function mockTtyStreams() { const stdin = new PassThrough() stdin.isTTY = true stdin.setRawMode = () => {} const stdout = new PassThrough() return { stdin, stdout } } test('login rejects passphrase on argv', async (t) => { const run = await loadLoginBin() const logs = [] const errs = [] const ctx = { console: { log: () => {}, error: (m) => errs.push(String(m)) }, exitCode: 0, applyRegister: async () => {}, applyUnlock: async () => { logs.push('should-not') } } await run(ctx, ['login', 'secret']) t.is(logs.length, 0) t.is(ctx.exitCode, 1) t.ok(errs.some((e) => e.includes('must not be given on the command line'))) }) test('login prompts via TTY streams (masked path)', async (t) => { const run = await loadLoginBin() let unlocked = '' const { stdin, stdout } = mockTtyStreams() const ctx = { console: { log: () => {}, error: () => {} }, exitCode: 0, stdin, stdout, suspendReplForSubprocess() {}, resumeReplAfterSubprocess() {}, applyRegister: async () => {}, applyUnlock: async (p) => { unlocked = p } } const p = run(ctx, ['login']) await new Promise((r) => setImmediate(r)) stdin.write('two words') stdin.write('\n') await p t.is(unlocked, 'two words') t.is(ctx.exitCode, 0) }) test('login --help', async (t) => { const run = await loadLoginBin() const logs = [] const ctx = { console: { log: (m) => logs.push(String(m)), error: () => {} }, exitCode: 1 } await run(ctx, ['login', '--help']) t.is(ctx.exitCode, 0) t.ok(logs.join('\n').includes('several words')) })