@boole-digital/cli 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +45 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -347,10 +347,32 @@ var BooleApi = class {
|
|
|
347
347
|
}
|
|
348
348
|
// Returns the plaintext SSH password for a droplet. Field name varies by
|
|
349
349
|
// server version, so probe the likely shapes.
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
350
|
+
// The ssh-password endpoint is gated by a server-side connect access code
|
|
351
|
+
// (env.CLAUDE_CONNECT_ACCESS_CODE) with brute-force lockout, so we MUST send it
|
|
352
|
+
// in the POST body (the web app does the same). Without it the backend replies
|
|
353
|
+
// "Incorrect access code".
|
|
354
|
+
async getSshPassword(id, accessCode) {
|
|
355
|
+
const body = await this.request(`/api/v1/droplets/${id}/ssh-password`, {
|
|
356
|
+
method: "POST",
|
|
357
|
+
body: JSON.stringify({ accessCode: (accessCode || "").trim() })
|
|
358
|
+
});
|
|
359
|
+
const cand = [
|
|
360
|
+
body?.data?.droplet_password,
|
|
361
|
+
body?.data?.password,
|
|
362
|
+
body?.data?.ssh_password,
|
|
363
|
+
body?.data?.sshPassword,
|
|
364
|
+
body?.droplet_password,
|
|
365
|
+
body?.password,
|
|
366
|
+
body?.ssh_password,
|
|
367
|
+
body?.sshPassword,
|
|
368
|
+
body?.result?.password
|
|
369
|
+
];
|
|
370
|
+
const pw = cand.find((v) => typeof v === "string" && v.length > 0);
|
|
371
|
+
if (!pw) {
|
|
372
|
+
throw new Error(
|
|
373
|
+
"SSH password not present. topKeys=" + JSON.stringify(Object.keys(body || {})) + " dataKeys=" + JSON.stringify(Object.keys(body?.data || {}))
|
|
374
|
+
);
|
|
375
|
+
}
|
|
354
376
|
return String(pw);
|
|
355
377
|
}
|
|
356
378
|
// ---- talk to the gateway on the box (via the ownership-checked proxy) ---
|
|
@@ -600,7 +622,23 @@ async function connect(opts = {}) {
|
|
|
600
622
|
if (!READY(target)) die(`Trading computer "${target.name}" is not ready yet (status=${target.status}).`);
|
|
601
623
|
if (!target.ip_address) die(`Trading computer "${target.name}" has no IP yet. Try again shortly.`);
|
|
602
624
|
info(`Fetching access for ${c.bold(target.name)}\u2026`);
|
|
603
|
-
|
|
625
|
+
let password;
|
|
626
|
+
try {
|
|
627
|
+
password = await api.getSshPassword(target.id, opts.code || "");
|
|
628
|
+
} catch (e) {
|
|
629
|
+
if (!/access code/i.test(e?.message || "")) throw e;
|
|
630
|
+
let code = (opts.code || "").trim();
|
|
631
|
+
if (!code && process.stdin.isTTY) {
|
|
632
|
+
code = (await prompt("This computer needs a connect access code (from the Boole app):")).trim();
|
|
633
|
+
}
|
|
634
|
+
if (!code) die("This computer needs a connect access code: run `boole connect --code <code>` (from the Boole app).");
|
|
635
|
+
try {
|
|
636
|
+
password = await api.getSshPassword(target.id, code);
|
|
637
|
+
} catch (e2) {
|
|
638
|
+
if (/access code/i.test(e2?.message || "")) die("Connect access code was rejected \u2014 re-run `boole connect --code <code>` with the correct code.");
|
|
639
|
+
throw e2;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
604
642
|
saveSession({ agent: target.name, dropletId: target.id, ip: target.ip_address, password, sshUser: "customer" });
|
|
605
643
|
ok(`Connected to ${c.bold(target.name)} (${target.ip_address}).`);
|
|
606
644
|
log("");
|
|
@@ -728,7 +766,7 @@ function init(opts = {}) {
|
|
|
728
766
|
}
|
|
729
767
|
|
|
730
768
|
// src/index.ts
|
|
731
|
-
var VERSION = "0.2.
|
|
769
|
+
var VERSION = "0.2.5";
|
|
732
770
|
function parse(argv) {
|
|
733
771
|
const _ = [];
|
|
734
772
|
const flags = {};
|
|
@@ -815,7 +853,7 @@ async function main() {
|
|
|
815
853
|
await provision({ name: str(flags.name), region: str(flags.region), size: str(flags.size) });
|
|
816
854
|
break;
|
|
817
855
|
case "connect":
|
|
818
|
-
await connect({ name: _[1] });
|
|
856
|
+
await connect({ name: _[1], code: str(flags.code) });
|
|
819
857
|
break;
|
|
820
858
|
case "init":
|
|
821
859
|
init({ dir: _[1], force: !!flags.force });
|
package/package.json
CHANGED