@openparachute/hub 0.5.14-rc.8 → 0.6.0
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/README.md +109 -15
- package/package.json +7 -3
- package/src/__tests__/account-home-ui.test.ts +251 -15
- package/src/__tests__/account-vault-token.test.ts +355 -0
- package/src/__tests__/admin-vaults.test.ts +70 -4
- package/src/__tests__/api-mint-token.test.ts +693 -5
- package/src/__tests__/api-modules-ops.test.ts +45 -0
- package/src/__tests__/api-revoke-token.test.ts +384 -0
- package/src/__tests__/api-users.test.ts +7 -2
- package/src/__tests__/auth.test.ts +157 -30
- package/src/__tests__/cli.test.ts +44 -5
- package/src/__tests__/expose-2fa-warning.test.ts +31 -17
- package/src/__tests__/expose-auth-preflight.test.ts +71 -72
- package/src/__tests__/expose-cloudflare.test.ts +482 -14
- package/src/__tests__/expose.test.ts +52 -2
- package/src/__tests__/hub-server.test.ts +97 -0
- package/src/__tests__/hub.test.ts +85 -6
- package/src/__tests__/init.test.ts +102 -1
- package/src/__tests__/lifecycle.test.ts +464 -2
- package/src/__tests__/oauth-handlers.test.ts +1252 -83
- package/src/__tests__/oauth-ui.test.ts +12 -1
- package/src/__tests__/operator-token-issuer-self-heal.test.ts +412 -0
- package/src/__tests__/resource-binding.test.ts +97 -0
- package/src/__tests__/scope-explanations.test.ts +77 -12
- package/src/__tests__/services-manifest.test.ts +122 -4
- package/src/__tests__/setup-wizard.test.ts +335 -15
- package/src/__tests__/status.test.ts +36 -0
- package/src/__tests__/two-factor-flow.test.ts +602 -0
- package/src/__tests__/two-factor.test.ts +183 -0
- package/src/__tests__/upgrade.test.ts +78 -1
- package/src/__tests__/users.test.ts +68 -0
- package/src/__tests__/vault-auth-status.test.ts +47 -6
- package/src/__tests__/vault-hub-origin-env.test.ts +263 -0
- package/src/account-home-ui.ts +488 -38
- package/src/account-vault-token.ts +282 -0
- package/src/admin-handlers.ts +159 -4
- package/src/admin-login-ui.ts +49 -5
- package/src/admin-vaults.ts +48 -15
- package/src/api-account.ts +14 -0
- package/src/api-mint-token.ts +132 -24
- package/src/api-modules-ops.ts +49 -11
- package/src/api-revoke-token.ts +107 -21
- package/src/api-users.ts +29 -3
- package/src/cli.ts +26 -21
- package/src/clients.ts +18 -6
- package/src/cloudflare/config.ts +10 -4
- package/src/cloudflare/detect.ts +39 -44
- package/src/commands/auth.ts +165 -24
- package/src/commands/expose-2fa-warning.ts +34 -32
- package/src/commands/expose-auth-preflight.ts +89 -78
- package/src/commands/expose-cloudflare.ts +370 -12
- package/src/commands/expose.ts +8 -0
- package/src/commands/init.ts +33 -2
- package/src/commands/lifecycle.ts +386 -17
- package/src/commands/status.ts +22 -0
- package/src/commands/upgrade.ts +55 -11
- package/src/commands/wizard.ts +8 -4
- package/src/env-file.ts +10 -0
- package/src/help.ts +3 -1
- package/src/hub-db.ts +39 -1
- package/src/hub-server.ts +52 -0
- package/src/hub.ts +82 -14
- package/src/oauth-handlers.ts +298 -21
- package/src/oauth-ui.ts +10 -0
- package/src/operator-token.ts +151 -0
- package/src/pending-login.ts +116 -0
- package/src/rate-limit.ts +51 -0
- package/src/resource-binding.ts +134 -0
- package/src/scope-attenuation.ts +85 -0
- package/src/scope-explanations.ts +131 -14
- package/src/services-manifest.ts +112 -0
- package/src/setup-wizard.ts +77 -7
- package/src/tailscale/run.ts +28 -11
- package/src/totp.ts +201 -0
- package/src/two-factor-handlers.ts +287 -0
- package/src/two-factor-store.ts +181 -0
- package/src/two-factor-ui.ts +462 -0
- package/src/users.ts +58 -0
- package/src/vault/auth-status.ts +71 -19
- package/src/vault-hub-origin-env.ts +163 -0
- package/web/ui/dist/assets/index-BiBlvEaj.css +1 -0
- package/web/ui/dist/assets/index-CIN3mnmf.js +61 -0
- package/web/ui/dist/index.html +2 -2
- package/src/__tests__/vault-tokens-create-interactive.test.ts +0 -183
- package/src/commands/vault-tokens-create-interactive.ts +0 -143
- package/web/ui/dist/assets/index-7DtAXz7y.css +0 -1
- package/web/ui/dist/assets/index-tRmPbbC7.js +0 -61
|
@@ -6,9 +6,11 @@ import {
|
|
|
6
6
|
type ServiceEntry,
|
|
7
7
|
ServicesManifestError,
|
|
8
8
|
type UiSubUnit,
|
|
9
|
+
clearStartError,
|
|
9
10
|
findService,
|
|
10
11
|
readManifest,
|
|
11
12
|
readManifestLenient,
|
|
13
|
+
recordStartError,
|
|
12
14
|
removeService,
|
|
13
15
|
upsertService,
|
|
14
16
|
writeManifest,
|
|
@@ -1410,9 +1412,27 @@ describe("readManifestLenient — skips bad entries instead of throwing (hub#406
|
|
|
1410
1412
|
path,
|
|
1411
1413
|
JSON.stringify({
|
|
1412
1414
|
services: [
|
|
1413
|
-
{
|
|
1414
|
-
|
|
1415
|
-
|
|
1415
|
+
{
|
|
1416
|
+
name: "parachute-vault",
|
|
1417
|
+
port: 1940,
|
|
1418
|
+
paths: ["/vault/default"],
|
|
1419
|
+
health: "/vault/default/health",
|
|
1420
|
+
version: "0.4.8-rc.10",
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
name: "parachute-surface",
|
|
1424
|
+
port: 1946,
|
|
1425
|
+
paths: ["/surface"],
|
|
1426
|
+
health: "/surface/healthz",
|
|
1427
|
+
version: "0.2.0-rc.13",
|
|
1428
|
+
},
|
|
1429
|
+
{
|
|
1430
|
+
name: "widget",
|
|
1431
|
+
port: 0,
|
|
1432
|
+
paths: ["/widget"],
|
|
1433
|
+
health: "/widget/health",
|
|
1434
|
+
version: "0.0.1",
|
|
1435
|
+
},
|
|
1416
1436
|
],
|
|
1417
1437
|
}),
|
|
1418
1438
|
);
|
|
@@ -1479,7 +1499,15 @@ describe("readManifestLenient — skips bad entries instead of throwing (hub#406
|
|
|
1479
1499
|
writeFileSync(
|
|
1480
1500
|
path,
|
|
1481
1501
|
JSON.stringify({
|
|
1482
|
-
services: [
|
|
1502
|
+
services: [
|
|
1503
|
+
{
|
|
1504
|
+
name: "widget",
|
|
1505
|
+
port: 0,
|
|
1506
|
+
paths: ["/widget"],
|
|
1507
|
+
health: "/widget/health",
|
|
1508
|
+
version: "0.0.1",
|
|
1509
|
+
},
|
|
1510
|
+
],
|
|
1483
1511
|
}),
|
|
1484
1512
|
);
|
|
1485
1513
|
expect(() => readManifest(path)).toThrow(ServicesManifestError);
|
|
@@ -1487,4 +1515,94 @@ describe("readManifestLenient — skips bad entries instead of throwing (hub#406
|
|
|
1487
1515
|
cleanup();
|
|
1488
1516
|
}
|
|
1489
1517
|
});
|
|
1518
|
+
|
|
1519
|
+
describe("lastStartError", () => {
|
|
1520
|
+
const wire = {
|
|
1521
|
+
error_type: "missing_dependency",
|
|
1522
|
+
error_description: "parachute-vault is required ...",
|
|
1523
|
+
binary: "parachute-vault",
|
|
1524
|
+
why: "run the Vault module Hub supervises",
|
|
1525
|
+
docs_url: "https://parachute.computer",
|
|
1526
|
+
install: { generic: "parachute install vault" },
|
|
1527
|
+
sysadmin_hint: "Or ask your system administrator to install it for you.",
|
|
1528
|
+
};
|
|
1529
|
+
|
|
1530
|
+
test("recordStartError persists the wire + stamps `at`", () => {
|
|
1531
|
+
const { path, cleanup } = makeTempPath();
|
|
1532
|
+
try {
|
|
1533
|
+
upsertService(vault, path);
|
|
1534
|
+
recordStartError("parachute-vault", wire, path);
|
|
1535
|
+
const entry = readManifest(path).services.find((s) => s.name === "parachute-vault");
|
|
1536
|
+
expect(entry?.lastStartError?.error_type).toBe("missing_dependency");
|
|
1537
|
+
expect(entry?.lastStartError?.binary).toBe("parachute-vault");
|
|
1538
|
+
expect(entry?.lastStartError?.install?.generic).toBe("parachute install vault");
|
|
1539
|
+
expect(entry?.lastStartError?.at).toBeDefined();
|
|
1540
|
+
} finally {
|
|
1541
|
+
cleanup();
|
|
1542
|
+
}
|
|
1543
|
+
});
|
|
1544
|
+
|
|
1545
|
+
test("recordStartError is a no-op when the row is absent", () => {
|
|
1546
|
+
const { path, cleanup } = makeTempPath();
|
|
1547
|
+
try {
|
|
1548
|
+
upsertService(vault, path);
|
|
1549
|
+
recordStartError("parachute-scribe", wire, path);
|
|
1550
|
+
const scribe = readManifest(path).services.find((s) => s.name === "parachute-scribe");
|
|
1551
|
+
expect(scribe).toBeUndefined();
|
|
1552
|
+
} finally {
|
|
1553
|
+
cleanup();
|
|
1554
|
+
}
|
|
1555
|
+
});
|
|
1556
|
+
|
|
1557
|
+
test("clearStartError removes a recorded error", () => {
|
|
1558
|
+
const { path, cleanup } = makeTempPath();
|
|
1559
|
+
try {
|
|
1560
|
+
upsertService(vault, path);
|
|
1561
|
+
recordStartError("parachute-vault", wire, path);
|
|
1562
|
+
clearStartError("parachute-vault", path);
|
|
1563
|
+
const entry = readManifest(path).services.find((s) => s.name === "parachute-vault");
|
|
1564
|
+
expect(entry?.lastStartError).toBeUndefined();
|
|
1565
|
+
} finally {
|
|
1566
|
+
cleanup();
|
|
1567
|
+
}
|
|
1568
|
+
});
|
|
1569
|
+
|
|
1570
|
+
test("lastStartError round-trips through validation", () => {
|
|
1571
|
+
const { path, cleanup } = makeTempPath();
|
|
1572
|
+
try {
|
|
1573
|
+
const withErr: ServiceEntry = {
|
|
1574
|
+
...vault,
|
|
1575
|
+
lastStartError: { ...wire, at: "2026-05-29T00:00:00Z" },
|
|
1576
|
+
};
|
|
1577
|
+
upsertService(withErr, path);
|
|
1578
|
+
const entry = readManifest(path).services.find((s) => s.name === "parachute-vault");
|
|
1579
|
+
expect(entry?.lastStartError).toEqual({ ...wire, at: "2026-05-29T00:00:00Z" });
|
|
1580
|
+
} finally {
|
|
1581
|
+
cleanup();
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1584
|
+
|
|
1585
|
+
test("a malformed lastStartError is dropped, not thrown (diagnostic field)", () => {
|
|
1586
|
+
const { path, cleanup } = makeTempPath();
|
|
1587
|
+
try {
|
|
1588
|
+
writeFileSync(
|
|
1589
|
+
path,
|
|
1590
|
+
JSON.stringify({
|
|
1591
|
+
services: [
|
|
1592
|
+
{
|
|
1593
|
+
...vault,
|
|
1594
|
+
// missing error_description → invalid shape → dropped
|
|
1595
|
+
lastStartError: { error_type: "missing_dependency" },
|
|
1596
|
+
},
|
|
1597
|
+
],
|
|
1598
|
+
}),
|
|
1599
|
+
);
|
|
1600
|
+
const entry = readManifest(path).services.find((s) => s.name === "parachute-vault");
|
|
1601
|
+
expect(entry).toBeDefined();
|
|
1602
|
+
expect(entry?.lastStartError).toBeUndefined();
|
|
1603
|
+
} finally {
|
|
1604
|
+
cleanup();
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
});
|
|
1490
1608
|
});
|