@boole-digital/cli 0.2.3 → 0.2.4
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 +28 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -347,8 +347,15 @@ 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
|
-
|
|
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
|
+
});
|
|
352
359
|
const pw = body?.password ?? body?.ssh_password ?? body?.data?.password ?? body?.data?.ssh_password;
|
|
353
360
|
if (!pw) throw new Error("SSH password not present in API response (check field name in api.ts:getSshPassword).");
|
|
354
361
|
return String(pw);
|
|
@@ -600,7 +607,23 @@ async function connect(opts = {}) {
|
|
|
600
607
|
if (!READY(target)) die(`Trading computer "${target.name}" is not ready yet (status=${target.status}).`);
|
|
601
608
|
if (!target.ip_address) die(`Trading computer "${target.name}" has no IP yet. Try again shortly.`);
|
|
602
609
|
info(`Fetching access for ${c.bold(target.name)}\u2026`);
|
|
603
|
-
|
|
610
|
+
let password;
|
|
611
|
+
try {
|
|
612
|
+
password = await api.getSshPassword(target.id, opts.code || "");
|
|
613
|
+
} catch (e) {
|
|
614
|
+
if (!/access code/i.test(e?.message || "")) throw e;
|
|
615
|
+
let code = (opts.code || "").trim();
|
|
616
|
+
if (!code && process.stdin.isTTY) {
|
|
617
|
+
code = (await prompt("This computer needs a connect access code (from the Boole app):")).trim();
|
|
618
|
+
}
|
|
619
|
+
if (!code) die("This computer needs a connect access code: run `boole connect --code <code>` (from the Boole app).");
|
|
620
|
+
try {
|
|
621
|
+
password = await api.getSshPassword(target.id, code);
|
|
622
|
+
} catch (e2) {
|
|
623
|
+
if (/access code/i.test(e2?.message || "")) die("Connect access code was rejected \u2014 re-run `boole connect --code <code>` with the correct code.");
|
|
624
|
+
throw e2;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
604
627
|
saveSession({ agent: target.name, dropletId: target.id, ip: target.ip_address, password, sshUser: "customer" });
|
|
605
628
|
ok(`Connected to ${c.bold(target.name)} (${target.ip_address}).`);
|
|
606
629
|
log("");
|
|
@@ -728,7 +751,7 @@ function init(opts = {}) {
|
|
|
728
751
|
}
|
|
729
752
|
|
|
730
753
|
// src/index.ts
|
|
731
|
-
var VERSION = "0.2.
|
|
754
|
+
var VERSION = "0.2.4";
|
|
732
755
|
function parse(argv) {
|
|
733
756
|
const _ = [];
|
|
734
757
|
const flags = {};
|
|
@@ -815,7 +838,7 @@ async function main() {
|
|
|
815
838
|
await provision({ name: str(flags.name), region: str(flags.region), size: str(flags.size) });
|
|
816
839
|
break;
|
|
817
840
|
case "connect":
|
|
818
|
-
await connect({ name: _[1] });
|
|
841
|
+
await connect({ name: _[1], code: str(flags.code) });
|
|
819
842
|
break;
|
|
820
843
|
case "init":
|
|
821
844
|
init({ dir: _[1], force: !!flags.force });
|
package/package.json
CHANGED