@openparachute/hub 0.5.14-rc.2 → 0.5.14-rc.21
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-config.test.ts +16 -10
- package/src/__tests__/api-modules-ops.test.ts +45 -0
- package/src/__tests__/api-modules.test.ts +92 -75
- package/src/__tests__/api-ready.test.ts +135 -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__/cloudflare-detect.test.ts +60 -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 +582 -11
- package/src/__tests__/expose-interactive.test.ts +10 -4
- package/src/__tests__/expose-public-auto.test.ts +5 -1
- package/src/__tests__/expose.test.ts +52 -2
- package/src/__tests__/hub-server.test.ts +396 -10
- package/src/__tests__/hub.test.ts +85 -6
- package/src/__tests__/init.test.ts +928 -0
- package/src/__tests__/lifecycle.test.ts +464 -2
- package/src/__tests__/migrate.test.ts +433 -51
- 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__/proxy-error-ui.test.ts +212 -0
- package/src/__tests__/proxy-state.test.ts +192 -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 +633 -53
- 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 +312 -11
- package/src/__tests__/vault-hub-origin-env.test.ts +263 -0
- package/src/__tests__/wizard.test.ts +372 -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-modules.ts +29 -12
- package/src/api-ready.ts +102 -0
- package/src/api-revoke-token.ts +107 -21
- package/src/api-users.ts +29 -3
- package/src/cli.ts +112 -25
- package/src/clients.ts +18 -6
- package/src/cloudflare/config.ts +10 -4
- package/src/cloudflare/detect.ts +82 -20
- 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 +471 -16
- package/src/commands/expose-interactive.ts +10 -11
- package/src/commands/expose-public-auto.ts +6 -4
- package/src/commands/expose.ts +8 -0
- package/src/commands/init.ts +594 -0
- package/src/commands/install.ts +33 -2
- package/src/commands/lifecycle.ts +386 -17
- package/src/commands/migrate.ts +293 -41
- package/src/commands/status.ts +22 -0
- package/src/commands/upgrade.ts +55 -11
- package/src/commands/wizard.ts +847 -0
- package/src/env-file.ts +10 -0
- package/src/help.ts +157 -15
- package/src/hub-db.ts +39 -1
- package/src/hub-server.ts +119 -13
- package/src/hub-settings.ts +11 -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/proxy-error-ui.ts +506 -0
- package/src/proxy-state.ts +131 -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 +738 -125
- 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 +200 -25
- 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
|
@@ -5,7 +5,15 @@ import { join } from "node:path";
|
|
|
5
5
|
import { renderHub, writeHubFile } from "../hub.ts";
|
|
6
6
|
|
|
7
7
|
describe("renderHub", () => {
|
|
8
|
-
|
|
8
|
+
// The verbose discovery body (Get started / Services / Admin) + its
|
|
9
|
+
// data-loading script render only for a signed-in visitor (the signed-out
|
|
10
|
+
// landing is slimmed — see the "signed-out slimming" describe block below).
|
|
11
|
+
// Assertions about that verbose body therefore run against a signed-in
|
|
12
|
+
// render; assertions about the page shell (doctype, styles, brand) hold for
|
|
13
|
+
// both and use whichever render is convenient.
|
|
14
|
+
const html = renderHub({
|
|
15
|
+
session: { displayName: "operator", csrfToken: "csrf-shell" },
|
|
16
|
+
});
|
|
9
17
|
|
|
10
18
|
test("is a self-contained HTML document with inline styles and script", () => {
|
|
11
19
|
expect(html).toStartWith("<!doctype html>");
|
|
@@ -162,12 +170,72 @@ describe("renderHub", () => {
|
|
|
162
170
|
});
|
|
163
171
|
|
|
164
172
|
test("default render (no session) emits the 'Sign in' affordance", () => {
|
|
165
|
-
|
|
166
|
-
expect(
|
|
167
|
-
expect(
|
|
173
|
+
const out = renderHub();
|
|
174
|
+
expect(out).toContain('class="auth-indicator"');
|
|
175
|
+
expect(out).toContain("Sign in");
|
|
176
|
+
expect(out).toContain('href="/login?next=/"');
|
|
168
177
|
// No POST form, no CSRF input — those only appear when signed in.
|
|
169
|
-
expect(
|
|
170
|
-
expect(
|
|
178
|
+
expect(out).not.toContain('action="/logout"');
|
|
179
|
+
expect(out).not.toContain("__csrf");
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe("renderHub — signed-out slimming (operator feedback)", () => {
|
|
184
|
+
// A signed-out visitor should see a clean, minimal landing: brand +
|
|
185
|
+
// tagline (in the header) + a single clear "Sign in" call. The hub's
|
|
186
|
+
// internal detail — the service catalog, vault listings, admin surfaces,
|
|
187
|
+
// and the well-known-driven loading script — must NOT render until the
|
|
188
|
+
// visitor authenticates. The signed-in render is unchanged.
|
|
189
|
+
const signedOut = renderHub();
|
|
190
|
+
const signedIn = renderHub({
|
|
191
|
+
session: { displayName: "operator", csrfToken: "csrf-xyz" },
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("signed-out: brand wordmark + tagline still render (the slim landing keeps the brand)", () => {
|
|
195
|
+
expect(signedOut).toContain("<h1>Parachute</h1>");
|
|
196
|
+
expect(signedOut).toContain("Truly personal computing. Your knowledge belongs with you.");
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("signed-out: a clear 'Sign in' call is the primary affordance", () => {
|
|
200
|
+
expect(signedOut).toContain('data-testid="signed-out-signin"');
|
|
201
|
+
expect(signedOut).toContain('href="/login?next=/"');
|
|
202
|
+
expect(signedOut).toContain("Sign in");
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("signed-out: the verbose Services / Admin / Get started sections are absent", () => {
|
|
206
|
+
expect(signedOut).not.toContain('id="services-section"');
|
|
207
|
+
expect(signedOut).not.toContain('id="admin-section"');
|
|
208
|
+
expect(signedOut).not.toContain('id="get-started-section"');
|
|
209
|
+
expect(signedOut).not.toContain("<h2>Services</h2>");
|
|
210
|
+
expect(signedOut).not.toContain("<h2>Admin</h2>");
|
|
211
|
+
// Admin links / token surface must not be exposed pre-auth.
|
|
212
|
+
expect(signedOut).not.toContain("/admin/vaults");
|
|
213
|
+
expect(signedOut).not.toContain("/admin/tokens");
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("signed-out: the well-known service-catalog loading script is not emitted", () => {
|
|
217
|
+
// No data-driven discovery body to populate when signed out → no script.
|
|
218
|
+
// (The brand mark is an inline SVG, not a <script>; assert on the IIFE's
|
|
219
|
+
// load function rather than a blanket "no <script>".) The footer's
|
|
220
|
+
// public "discovery" anchor → /.well-known/parachute.json stays — it's a
|
|
221
|
+
// plain link, not the catalog-fetching script — so assert on the fetch
|
|
222
|
+
// call + the loader function, not the URL string.
|
|
223
|
+
expect(signedOut).not.toContain("loadServices");
|
|
224
|
+
expect(signedOut).not.toContain("renderServices");
|
|
225
|
+
expect(signedOut).not.toContain("fetch('/.well-known/parachute.json'");
|
|
226
|
+
expect(signedOut).not.toContain("<script>");
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
test("signed-in: the verbose sections + loading script DO render (signed-in view unchanged)", () => {
|
|
230
|
+
expect(signedIn).toContain('id="services-section"');
|
|
231
|
+
expect(signedIn).toContain('id="admin-section"');
|
|
232
|
+
expect(signedIn).toContain('id="get-started-section"');
|
|
233
|
+
expect(signedIn).toContain("/admin/vaults");
|
|
234
|
+
expect(signedIn).toContain("/.well-known/parachute.json");
|
|
235
|
+
expect(signedIn).toContain("loadServices");
|
|
236
|
+
// And the signed-out lede / standalone Sign-in CTA is gone (the
|
|
237
|
+
// auth-indicator carries sign-out instead).
|
|
238
|
+
expect(signedIn).not.toContain('data-testid="signed-out-signin"');
|
|
171
239
|
});
|
|
172
240
|
});
|
|
173
241
|
|
|
@@ -189,6 +257,17 @@ describe("renderHub — signed-in indicator (rc.13)", () => {
|
|
|
189
257
|
expect(html).not.toContain('href="/login?next=/"');
|
|
190
258
|
});
|
|
191
259
|
|
|
260
|
+
test("signed-in indicator carries an Account breadcrumb to /account/", () => {
|
|
261
|
+
// Onboarding discoverability: a signed-in friend needs a single link
|
|
262
|
+
// to the self-service /account/ home (change password, their vault).
|
|
263
|
+
// Applies to admins too — harmless for them.
|
|
264
|
+
const html = renderHub({
|
|
265
|
+
session: { displayName: "aaron", csrfToken: "csrf-token-xyz" },
|
|
266
|
+
});
|
|
267
|
+
expect(html).toContain('href="/account/"');
|
|
268
|
+
expect(html).toContain("Account");
|
|
269
|
+
});
|
|
270
|
+
|
|
192
271
|
test("displayName with HTML special chars is escaped", () => {
|
|
193
272
|
// Username field allows alphanumerics historically, but the
|
|
194
273
|
// displayName field on the wire is forward-compatible with profile
|