@monster-orange/den 0.4.19 → 0.4.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +7 -7
  3. package/docs/distributions.md +121 -13
  4. package/package.json +1 -1
  5. package/src/shared/attest-code.ts +125 -0
  6. package/src/shared/claim-code.ts +6 -2
  7. package/src/{ui/server/edge-exposure.ts → shared/edge/exposure.ts} +7 -1
  8. package/src/shared/github-app.ts +4 -0
  9. package/src/shared/github-device.ts +38 -1
  10. package/src/shared/owner-github.ts +100 -0
  11. package/src/shared/product.ts +45 -5
  12. package/src/shared/profile.ts +26 -2
  13. package/src/shared/secrets/index.ts +71 -3
  14. package/src/shared/secrets/onepassword.ts +87 -14
  15. package/src/shared/secrets/op-token.ts +270 -0
  16. package/src/shared/secrets/secret-env.ts +19 -6
  17. package/src/shared/secrets/strategies.ts +6 -0
  18. package/src/shared/secrets/types.ts +8 -0
  19. package/src/shared/web-session.ts +112 -6
  20. package/src/ui/cli/create.ts +92 -6
  21. package/src/ui/cli/doctor-command.ts +108 -17
  22. package/src/ui/cli/doctor-owner.ts +122 -0
  23. package/src/ui/cli/service-command.ts +16 -0
  24. package/src/ui/cli/web-command.ts +74 -12
  25. package/src/ui/server/device-flows.ts +45 -10
  26. package/src/ui/server/github-routes.ts +169 -16
  27. package/src/ui/server/index.ts +148 -13
  28. package/src/ui/server/public/error-page.js +115 -33
  29. package/src/ui/server/public/error.html +16 -0
  30. package/src/ui/server/public/header.js +5 -7
  31. package/src/ui/server/public/i18n/es.js +11 -1
  32. package/src/ui/server/public/i18n/ja.js +11 -1
  33. package/src/ui/server/public/settings-registry.js +23 -1
  34. package/src/ui/server/public/shell.js +11 -1
  35. package/src/ui/server/route-classes.ts +7 -0
@@ -81,6 +81,13 @@ export const DEN_SETTING_CATEGORIES = [
81
81
  description:
82
82
  "Reach this Den from your other devices: sign in with GitHub as its owner, or pair a device with a one-time link. On localhost nothing asks.",
83
83
  },
84
+ {
85
+ id: "secrets",
86
+ label: "Secrets",
87
+ order: 58,
88
+ description:
89
+ "Where this machine gets the credentials Den resolves secrets with. Per machine (config/local/user.yml); only the source is shown, never a secret.",
90
+ },
84
91
  {
85
92
  id: "cli",
86
93
  label: "Command line",
@@ -418,7 +425,7 @@ function drawPair(host, ctx) {
418
425
  out.innerHTML =
419
426
  `<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start;margin-top:8px">` +
420
427
  `<div id="set-pair-qr" style="line-height:0">${qrSvg(p.url, { scale: 4, margin: 4 })}</div>` +
421
- `<div style="flex:1 1 220px;min-width:0"><p class="set-note" style="margin:0 0 8px">Scan it with the other device, or open the link there. It works once, within 60 seconds, and signs that browser in for good.</p>` +
428
+ `<div style="flex:1 1 220px;min-width:0"><p class="set-note" style="margin:0 0 8px">Scan it with the other device, or open the link there. It works once, until it expires (below), and signs that browser in for good.</p>` +
422
429
  `<a id="set-pair-link" href="${escHtml(p.url)}" style="font:12px var(--mono);overflow-wrap:anywhere">${escHtml(p.url)}</a>` +
423
430
  `<p class="set-note" id="set-pair-left" style="margin:8px 0 0"></p></div></div>`;
424
431
  const until = Date.parse(p.expiresAt);
@@ -1033,6 +1040,21 @@ export const DEN_SETTINGS = [
1033
1040
  read: () => null,
1034
1041
  },
1035
1042
 
1043
+ {
1044
+ // 1Password for a Den running as a service: where its service-account
1045
+ // token comes from (secrets.onepassword.token in user.yml). The source
1046
+ // only, never the token.
1047
+ id: "cli.op_token",
1048
+ category: "secrets",
1049
+ label: "1Password token source",
1050
+ description:
1051
+ "Where this machine's 1Password service-account token comes from, for a Den running as a service. Set secrets.onepassword.token in config/local/user.yml: keychain:<service>, file:<path> or env:<VAR>. The token itself is never shown.",
1052
+ keywords: ["secrets", "1password", "op", "service account", "token"],
1053
+ scope: "user",
1054
+ control: { type: "readonly" },
1055
+ read: (ctx) => ctx.data.op_token_source ?? "not set",
1056
+ },
1057
+
1036
1058
  ...ACCESS_ROWS,
1037
1059
 
1038
1060
  // ── Distribution (read-only) ───────────────────────────────────────────
@@ -420,6 +420,16 @@
420
420
  "err.signin.ghOnly":
421
421
  "Only the owner's GitHub account can sign in this way. For anyone else, use Approve this computer.",
422
422
  "err.signin.ghLearn": "Learn more",
423
+ "err.signin.claimTitle": "Connect your GitHub account",
424
+ "err.signin.claimLead":
425
+ "{name} has no owner yet. Connect your GitHub account to make it yours.",
426
+ "err.signin.claimOrg":
427
+ "Members of the {org} GitHub org can claim it, in a browser on {host}.",
428
+ "err.signin.claimHere": "This is my computer: connect GitHub",
429
+ "err.signin.claimAs": "Sign in as @{login}",
430
+ "err.signin.claimHereNote":
431
+ "This is my computer works only in a browser on {host}. Anywhere else it opens nothing.",
432
+ "err.signin.claimChecking": "Checking this is {host}…",
423
433
  "err.signin.githubRefused":
424
434
  "@{login} isn't the owner of this {name}. Only the owner's account can use Sign in with GitHub. Use Approve this computer instead.",
425
435
  "err.signin.approveOr": "Or approve this computer",
@@ -467,7 +477,6 @@
467
477
  "err.signin.github": "Sign in with GitHub",
468
478
  "err.signin.githubEnter": "Enter this code at {url}:",
469
479
  "err.signin.githubOpen": "Open GitHub",
470
- "err.signin.githubCopy": "Copy code",
471
480
  "err.signin.githubWaiting": "Waiting for you to approve it on GitHub…",
472
481
  "err.signin.githubDone": "Signed in. Loading…",
473
482
  "err.signin.githubExpired": "The code expired before it was approved.",
@@ -516,6 +525,7 @@
516
525
  "set.cli.web_port": "Your web port",
517
526
  "set.cli.signin": "Browser sign-in",
518
527
  "set.cli.sudo": "Admin password",
528
+ "set.cli.op_token": "1Password token source",
519
529
  "set.access.owner": "Owner",
520
530
  "set.access.devices": "Linked devices",
521
531
  "ident.local": "Local",
@@ -243,6 +243,10 @@ export const ROUTES: readonly RouteEntry[] = [
243
243
  "/signin",
244
244
  "the signed-out landing page (§6b.3): it renders signed out; signed in, it goes on to `next`",
245
245
  ),
246
+ R(
247
+ "/attest",
248
+ 'D17: "This is my computer", on localhost only: a 303 back to one of this server\'s edge hosts with a short-lived code (it never makes a session)',
249
+ ),
246
250
  M(["POST"], "/api/session/logout", "ends this browser's session"),
247
251
  S(
248
252
  ["GET", "HEAD"],
@@ -452,6 +456,9 @@ export const SIGNIN_FREE: readonly string[] = [
452
456
  "/auth",
453
457
  "/signin",
454
458
  "/api/session",
459
+ // D17: "This is my computer" answers for itself: on localhost a 303,
460
+ // anywhere else its own "only on this computer" page (never a code).
461
+ "/attest",
455
462
  // SEC-2a: Sign in with GitHub, from the signed-out page.
456
463
  "/api/github/signin",
457
464
  "/api/github/signin/:id",