* Handles a single control command from the `adm-pool` CLI. * * The control channel is a local Unix domain socket with owner-only (`0600`) * permissions; the operator password is only ever read here, never logged. * @param {{cmd: string, password?: string}} message Parsed control request * @ret
(message)
| 17 | * @returns {object} JSON-serializable response |
| 18 | */ |
| 19 | function handleCommand(message) { |
| 20 | const { cmd, password } = message; |
| 21 | |
| 22 | switch (cmd) { |
| 23 | case 'status': |
| 24 | return { ok: true, health: buildHealth() }; |
| 25 | |
| 26 | case 'unlock': { |
| 27 | if (!password) { |
| 28 | return { ok: false, error: 'Operator password is required.' }; |
| 29 | } |
| 30 | |
| 31 | try { |
| 32 | const { address } = secret.unlock(password); |
| 33 | |
| 34 | log.info(`Pool ${address} unlocked via control socket. Payouts and ADM notifications enabled.`); |
| 35 | |
| 36 | return { ok: true, message: `Pool unlocked for ${address}.`, health: buildHealth() }; |
| 37 | } catch (error) { |
| 38 | return { ok: false, error: error.message }; |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | case 'lock': { |
| 43 | try { |
| 44 | secret.lock(); |
| 45 | |
| 46 | log.log('Pool locked via control socket. Decrypted passphrase cleared from memory.'); |
| 47 | |
| 48 | return { ok: true, message: 'Pool locked. Decrypted passphrase cleared from memory.', health: buildHealth() }; |
| 49 | } catch (error) { |
| 50 | return { ok: false, error: error.message }; |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | default: |
| 55 | return { ok: false, error: `Unknown command: ${cmd}` }; |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * Starts the local control socket that backs `adm-pool unlock`, `lock`, and `status`. |
no test coverage detected