@withbuddi/buddi 0.1.0-pre.37 → 0.1.0-pre.39
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/extension/background.js +764 -32
- package/extension/manifest.json +2 -2
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/access-cmd.d.ts +10 -0
- package/node_modules/@buddi/cli/dist/access-cmd.d.ts.map +1 -0
- package/node_modules/@buddi/cli/dist/access-cmd.js +180 -0
- package/node_modules/@buddi/cli/dist/access-cmd.js.map +1 -0
- package/node_modules/@buddi/cli/dist/args.d.ts +10 -0
- package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/args.js +34 -1
- package/node_modules/@buddi/cli/dist/args.js.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.js +39 -2
- package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.js +54 -29
- package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts +36 -12
- package/node_modules/@buddi/cli/dist/doctor.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.js +32 -9
- package/node_modules/@buddi/cli/dist/doctor.js.map +1 -1
- package/node_modules/@buddi/cli/dist/main.d.ts +2 -0
- package/node_modules/@buddi/cli/dist/main.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/main.js +20 -2
- package/node_modules/@buddi/cli/dist/main.js.map +1 -1
- package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.d.ts +2 -0
- package/node_modules/@buddi/core/dist/agents/catalog.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.js +1 -0
- package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/edit.d.ts +2 -0
- package/node_modules/@buddi/core/dist/agents/edit.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/edit.js +3 -1
- package/node_modules/@buddi/core/dist/agents/edit.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts +11 -0
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.js +7 -0
- package/node_modules/@buddi/core/dist/agents/frontmatter.js.map +1 -1
- package/node_modules/@buddi/core/dist/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.js +1 -0
- package/node_modules/@buddi/core/dist/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.d.ts +3 -0
- package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js +3 -0
- package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/version.d.ts +1 -1
- package/node_modules/@buddi/core/dist/plugin/version.js +1 -1
- package/node_modules/@buddi/core/dist/questions/store.d.ts +12 -0
- package/node_modules/@buddi/core/dist/questions/store.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/questions/store.js +11 -1
- package/node_modules/@buddi/core/dist/questions/store.js.map +1 -1
- package/node_modules/@buddi/core/dist/questions/types.d.ts +8 -0
- package/node_modules/@buddi/core/dist/questions/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/questions/types.js +15 -0
- package/node_modules/@buddi/core/dist/questions/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/queue/jobs.d.ts +8 -0
- package/node_modules/@buddi/core/dist/queue/jobs.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/jobs.js +9 -3
- package/node_modules/@buddi/core/dist/queue/jobs.js.map +1 -1
- package/node_modules/@buddi/core/dist/queue/worker.d.ts +2 -0
- package/node_modules/@buddi/core/dist/queue/worker.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/worker.js +2 -1
- package/node_modules/@buddi/core/dist/queue/worker.js.map +1 -1
- package/node_modules/@buddi/core/dist/registry.d.ts +7 -1
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +73 -11
- package/node_modules/@buddi/core/dist/registry.js.map +1 -1
- package/node_modules/@buddi/core/dist/routes.d.ts +153 -0
- package/node_modules/@buddi/core/dist/routes.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/routes.js +47 -0
- package/node_modules/@buddi/core/dist/routes.js.map +1 -0
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts +5 -3
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/missions.js +9 -7
- package/node_modules/@buddi/core/dist/scheduler/missions.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts +7 -0
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.js +1 -0
- package/node_modules/@buddi/core/dist/scheduler/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/tools.d.ts +59 -2
- package/node_modules/@buddi/core/dist/tools.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/tools.js.map +1 -1
- package/node_modules/@buddi/core/migrations/075_access_providers.sql +43 -0
- package/node_modules/@buddi/core/migrations/076_mission_browser.sql +7 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/agents/canvas.d.ts +12 -12
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts +38 -20
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js +6 -0
- package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/delegation.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/agents/delegation.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/delegation.js +1 -0
- package/node_modules/@buddi/gateway/dist/agents/delegation.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts +7 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js +15 -6
- package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/bootstrap.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/bootstrap.js +8 -0
- package/node_modules/@buddi/gateway/dist/bootstrap.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts +30 -1
- package/node_modules/@buddi/gateway/dist/browser-host.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/browser-host.js +56 -1
- package/node_modules/@buddi/gateway/dist/browser-host.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js +9 -5
- package/node_modules/@buddi/gateway/dist/chat/session.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/index.d.ts +2 -1
- package/node_modules/@buddi/gateway/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/index.js +2 -1
- package/node_modules/@buddi/gateway/dist/index.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/ask-cap.d.ts +26 -0
- package/node_modules/@buddi/gateway/dist/missions/ask-cap.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/ask-cap.js +83 -0
- package/node_modules/@buddi/gateway/dist/missions/ask-cap.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts +45 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js +156 -10
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/parked.d.ts +139 -0
- package/node_modules/@buddi/gateway/dist/missions/parked.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/parked.js +255 -0
- package/node_modules/@buddi/gateway/dist/missions/parked.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/serve.d.ts +7 -0
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +49 -9
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts +18 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js +42 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.js +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.d.ts +6 -0
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.js +7 -1
- package/node_modules/@buddi/gateway/dist/surfaces/owner-request.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.d.ts +7 -0
- package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.js +14 -7
- package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.d.ts +17 -17
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.js +33 -37
- package/node_modules/@buddi/gateway/dist/telegram/browser-view.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/channel.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/channel.js +17 -1
- package/node_modules/@buddi/gateway/dist/telegram/channel.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.js +11 -3
- package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +10 -0
- package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/facts.d.ts +8 -0
- package/node_modules/@buddi/gateway/dist/tips/facts.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/facts.js +8 -2
- package/node_modules/@buddi/gateway/dist/tips/facts.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/rules.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/tips/rules.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/rules.js +15 -0
- package/node_modules/@buddi/gateway/dist/tips/rules.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/arrival.d.ts +24 -0
- package/node_modules/@buddi/gateway/dist/web/access/arrival.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/arrival.js +18 -0
- package/node_modules/@buddi/gateway/dist/web/access/arrival.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.d.ts +124 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.js +206 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-api.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts +163 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js +438 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.d.ts +31 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js +74 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.d.ts +145 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.js +474 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.d.ts +9 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.js +9 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.d.ts +30 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.js +76 -0
- package/node_modules/@buddi/gateway/dist/web/access/ingress.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.d.ts +173 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.js +11 -0
- package/node_modules/@buddi/gateway/dist/web/access/provider.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.d.ts +33 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.js +32 -0
- package/node_modules/@buddi/gateway/dist/web/access/registry.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/{tailscale.d.ts → access/tailscale.d.ts} +27 -0
- package/node_modules/@buddi/gateway/dist/web/access/tailscale.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/{tailscale.js → access/tailscale.js} +118 -3
- package/node_modules/@buddi/gateway/dist/web/access/tailscale.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/agents.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/web/agents.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/agents.js +19 -1
- package/node_modules/@buddi/gateway/dist/web/agents.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts +4 -3
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js +106 -19
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.js +11 -3
- package/node_modules/@buddi/gateway/dist/web/attention.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts +23 -0
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +62 -2
- package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/client-key.d.ts +3 -0
- package/node_modules/@buddi/gateway/dist/web/client-key.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/client-key.js +8 -1
- package/node_modules/@buddi/gateway/dist/web/client-key.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts +21 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.js +183 -3
- package/node_modules/@buddi/gateway/dist/web/extension.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/http.d.ts +7 -0
- package/node_modules/@buddi/gateway/dist/web/http.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/http.js +15 -1
- package/node_modules/@buddi/gateway/dist/web/http.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.d.ts +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/index.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/onboarding.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/onboarding.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/remote-hand.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/remote-hand.js +45 -2
- package/node_modules/@buddi/gateway/dist/web/remote-hand.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.d.ts +26 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.js +66 -3
- package/node_modules/@buddi/gateway/dist/web/secrets.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts +38 -2
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +634 -147
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts +24 -14
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.js +42 -14
- package/node_modules/@buddi/gateway/dist/web/sessions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.js +47 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/version.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/web/version.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/version.js +5 -1
- package/node_modules/@buddi/gateway/dist/web/version.js.map +1 -1
- package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/install/dist/app-layout.d.ts +127 -0
- package/node_modules/@buddi/install/dist/app-layout.d.ts.map +1 -0
- package/node_modules/@buddi/install/dist/app-layout.js +323 -0
- package/node_modules/@buddi/install/dist/app-layout.js.map +1 -0
- package/node_modules/@buddi/install/dist/index.d.ts +1 -0
- package/node_modules/@buddi/install/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/index.js +1 -0
- package/node_modules/@buddi/install/dist/index.js.map +1 -1
- package/node_modules/@buddi/install/dist/launcher.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/launcher.js +18 -4
- package/node_modules/@buddi/install/dist/launcher.js.map +1 -1
- package/node_modules/@buddi/install/dist/provenance.d.ts +34 -0
- package/node_modules/@buddi/install/dist/provenance.d.ts.map +1 -0
- package/node_modules/@buddi/install/dist/provenance.js +200 -0
- package/node_modules/@buddi/install/dist/provenance.js.map +1 -0
- package/node_modules/@buddi/install/dist/supervisor.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/supervisor.js +9 -4
- package/node_modules/@buddi/install/dist/supervisor.js.map +1 -1
- package/node_modules/@buddi/install/dist/upgrade.d.ts +77 -3
- package/node_modules/@buddi/install/dist/upgrade.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/upgrade.js +325 -43
- package/node_modules/@buddi/install/dist/upgrade.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/delegate.d.ts +8 -0
- package/node_modules/@buddi/runtime/dist/delegate.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/delegate.js +19 -1
- package/node_modules/@buddi/runtime/dist/delegate.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.d.ts +2 -0
- package/node_modules/@buddi/runtime/dist/loop.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.js +18 -4
- package/node_modules/@buddi/runtime/dist/loop.js.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/availability.d.ts +2 -2
- package/node_modules/@buddi/tool-browser/dist/availability.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/availability.js +2 -2
- package/node_modules/@buddi/tool-browser/dist/availability.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts +82 -58
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.js +823 -217
- package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/driver.d.ts +3 -1
- package/node_modules/@buddi/tool-browser/dist/driver.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/driver.js +82 -1
- package/node_modules/@buddi/tool-browser/dist/driver.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts +70 -5
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.js +94 -9
- package/node_modules/@buddi/tool-browser/dist/extension.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.d.ts +17 -7
- package/node_modules/@buddi/tool-browser/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.js +35 -15
- package/node_modules/@buddi/tool-browser/dist/index.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/logins.d.ts +150 -0
- package/node_modules/@buddi/tool-browser/dist/logins.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/logins.js +476 -0
- package/node_modules/@buddi/tool-browser/dist/logins.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/manager.d.ts +39 -21
- package/node_modules/@buddi/tool-browser/dist/manager.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/manager.js +229 -136
- package/node_modules/@buddi/tool-browser/dist/manager.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts +151 -0
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/routes.js +331 -0
- package/node_modules/@buddi/tool-browser/dist/routes.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/secrets.d.ts +3 -1
- package/node_modules/@buddi/tool-browser/dist/secrets.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/secrets.js +10 -6
- package/node_modules/@buddi/tool-browser/dist/secrets.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.d.ts +182 -115
- package/node_modules/@buddi/tool-browser/dist/service.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.js +491 -388
- package/node_modules/@buddi/tool-browser/dist/service.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/settings.d.ts +88 -0
- package/node_modules/@buddi/tool-browser/dist/settings.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/settings.js +86 -0
- package/node_modules/@buddi/tool-browser/dist/settings.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.d.ts +203 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.d.ts.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.js +142 -0
- package/node_modules/@buddi/tool-browser/dist/telemetry.js.map +1 -0
- package/node_modules/@buddi/tool-browser/dist/types.d.ts +102 -3
- package/node_modules/@buddi/tool-browser/dist/types.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/types.js +27 -9
- package/node_modules/@buddi/tool-browser/dist/types.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-mcp/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-memory/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-web/dist/.tsbuildinfo +1 -1
- package/node_modules/hono/dist/cjs/hono-base.js +2 -0
- package/node_modules/hono/dist/cjs/middleware/language/language.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/mount/index.js +71 -0
- package/node_modules/hono/dist/cjs/request.js +4 -4
- package/node_modules/hono/dist/hono-base.js +2 -0
- package/node_modules/hono/dist/middleware/mount/index.js +70 -0
- package/node_modules/hono/dist/request.js +4 -4
- package/node_modules/hono/dist/types/hono-base.d.ts +2 -0
- package/node_modules/hono/dist/types/jsx/base.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/mount/index.d.ts +46 -0
- package/node_modules/hono/dist/types/request.d.ts +4 -4
- package/node_modules/hono/package.json +9 -1
- package/node_modules/imapflow/CHANGELOG.md +15 -0
- package/node_modules/imapflow/dist/cjs/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/cjs/package-info.js +1 -1
- package/node_modules/imapflow/dist/cjs/search-compiler.js +21 -31
- package/node_modules/imapflow/dist/esm/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/esm/package-info.js +1 -1
- package/node_modules/imapflow/dist/esm/search-compiler.js +21 -31
- package/node_modules/imapflow/package.json +2 -2
- package/node_modules/pino/CONTRIBUTING.md +1 -5
- package/node_modules/pino/LICENSE +1 -1
- package/node_modules/pino/README.md +1 -1
- package/node_modules/pino/SECURITY.md +2 -18
- package/node_modules/pino/browser.js +8 -68
- package/node_modules/pino/docs/api.md +4 -75
- package/node_modules/pino/docs/asynchronous.md +3 -18
- package/node_modules/pino/docs/browser.md +0 -63
- package/node_modules/pino/docs/child-loggers.md +1 -22
- package/node_modules/pino/docs/ecosystem.md +0 -1
- package/node_modules/pino/docs/help.md +3 -11
- package/node_modules/pino/docs/lts.md +0 -29
- package/node_modules/pino/docs/pretty.md +0 -3
- package/node_modules/pino/docs/redaction.md +8 -3
- package/node_modules/pino/docs/transports.md +0 -71
- package/node_modules/pino/docs/web.md +14 -11
- package/node_modules/pino/eslint.config.js +7 -15
- package/node_modules/pino/lib/caller.js +0 -10
- package/node_modules/pino/lib/meta.js +1 -1
- package/node_modules/pino/lib/multistream.js +7 -15
- package/node_modules/pino/lib/redaction.js +3 -8
- package/node_modules/pino/lib/symbols.js +1 -3
- package/node_modules/pino/lib/tools.js +2 -2
- package/node_modules/pino/lib/transport.js +1 -14
- package/node_modules/pino/lib/worker.js +1 -4
- package/node_modules/pino/package.json +22 -14
- package/node_modules/pino/pino.d.ts +736 -709
- package/node_modules/pino/pino.js +2 -27
- package/node_modules/pino/test/basic.test.js +0 -66
- package/node_modules/pino/test/escaping.test.js +0 -17
- package/node_modules/pino/test/fixtures/ts/transpile.cjs +3 -3
- package/node_modules/pino/test/helper.js +2 -6
- package/node_modules/pino/test/multistream.test.js +0 -64
- package/node_modules/pino/test/redact.test.js +0 -30
- package/node_modules/pino/test/transport/core.test.js +0 -85
- package/node_modules/pino/test/transport/sync-false.test.js +0 -12
- package/node_modules/pino/test/transport/uses-pino-config.test.js +4 -4
- package/node_modules/pino/test/types/pino-import.test-d.cts +30 -0
- package/node_modules/pino/test/types/pino-multistream.test-d.ts +28 -0
- package/node_modules/pino/test/types/pino-top-export.test-d.ts +34 -0
- package/node_modules/pino/test/types/{pino-transport.tst.ts → pino-transport.test-d.ts} +70 -85
- package/node_modules/pino/test/types/pino-type-only.test-d.ts +75 -0
- package/node_modules/pino/test/types/{pino.tst.ts → pino.test-d.ts} +137 -135
- package/node_modules/pino/test/types/pino.ts +7 -14
- package/node_modules/pino/tsconfig.json +6 -6
- package/node_modules/real-require/README.md +6 -6
- package/node_modules/real-require/package.json +21 -10
- package/node_modules/real-require/src/index.js +2 -2
- package/node_modules/thread-stream/node_modules/real-require/LICENSE.md +21 -0
- package/node_modules/thread-stream/node_modules/real-require/README.md +51 -0
- package/node_modules/thread-stream/node_modules/real-require/package.json +38 -0
- package/node_modules/thread-stream/node_modules/real-require/src/index.js +14 -0
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/access-cmd.d.ts +10 -0
- package/packages/cli/dist/access-cmd.d.ts.map +1 -0
- package/packages/cli/dist/access-cmd.js +180 -0
- package/packages/cli/dist/access-cmd.js.map +1 -0
- package/packages/cli/dist/args.d.ts +10 -0
- package/packages/cli/dist/args.d.ts.map +1 -1
- package/packages/cli/dist/args.js +34 -1
- package/packages/cli/dist/args.js.map +1 -1
- package/packages/cli/dist/commands.d.ts.map +1 -1
- package/packages/cli/dist/commands.js +39 -2
- package/packages/cli/dist/commands.js.map +1 -1
- package/packages/cli/dist/doctor-probes.d.ts.map +1 -1
- package/packages/cli/dist/doctor-probes.js +54 -29
- package/packages/cli/dist/doctor-probes.js.map +1 -1
- package/packages/cli/dist/doctor.d.ts +36 -12
- package/packages/cli/dist/doctor.d.ts.map +1 -1
- package/packages/cli/dist/doctor.js +32 -9
- package/packages/cli/dist/doctor.js.map +1 -1
- package/packages/cli/dist/main.d.ts +2 -0
- package/packages/cli/dist/main.d.ts.map +1 -1
- package/packages/cli/dist/main.js +20 -2
- package/packages/cli/dist/main.js.map +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/agents/catalog.d.ts +2 -0
- package/packages/core/dist/agents/catalog.d.ts.map +1 -1
- package/packages/core/dist/agents/catalog.js +1 -0
- package/packages/core/dist/agents/catalog.js.map +1 -1
- package/packages/core/dist/agents/edit.d.ts +2 -0
- package/packages/core/dist/agents/edit.d.ts.map +1 -1
- package/packages/core/dist/agents/edit.js +3 -1
- package/packages/core/dist/agents/edit.js.map +1 -1
- package/packages/core/dist/agents/frontmatter.d.ts +11 -0
- package/packages/core/dist/agents/frontmatter.d.ts.map +1 -1
- package/packages/core/dist/agents/frontmatter.js +7 -0
- package/packages/core/dist/agents/frontmatter.js.map +1 -1
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/plugin/index.d.ts +3 -0
- package/packages/core/dist/plugin/index.d.ts.map +1 -1
- package/packages/core/dist/plugin/index.js +3 -0
- package/packages/core/dist/plugin/index.js.map +1 -1
- package/packages/core/dist/plugin/version.d.ts +1 -1
- package/packages/core/dist/plugin/version.js +1 -1
- package/packages/core/dist/questions/store.d.ts +12 -0
- package/packages/core/dist/questions/store.d.ts.map +1 -1
- package/packages/core/dist/questions/store.js +11 -1
- package/packages/core/dist/questions/store.js.map +1 -1
- package/packages/core/dist/questions/types.d.ts +8 -0
- package/packages/core/dist/questions/types.d.ts.map +1 -1
- package/packages/core/dist/questions/types.js +15 -0
- package/packages/core/dist/questions/types.js.map +1 -1
- package/packages/core/dist/queue/jobs.d.ts +8 -0
- package/packages/core/dist/queue/jobs.d.ts.map +1 -1
- package/packages/core/dist/queue/jobs.js +9 -3
- package/packages/core/dist/queue/jobs.js.map +1 -1
- package/packages/core/dist/queue/worker.d.ts +2 -0
- package/packages/core/dist/queue/worker.d.ts.map +1 -1
- package/packages/core/dist/queue/worker.js +2 -1
- package/packages/core/dist/queue/worker.js.map +1 -1
- package/packages/core/dist/registry.d.ts +7 -1
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +73 -11
- package/packages/core/dist/registry.js.map +1 -1
- package/packages/core/dist/routes.d.ts +153 -0
- package/packages/core/dist/routes.d.ts.map +1 -0
- package/packages/core/dist/routes.js +47 -0
- package/packages/core/dist/routes.js.map +1 -0
- package/packages/core/dist/scheduler/missions.d.ts +5 -3
- package/packages/core/dist/scheduler/missions.d.ts.map +1 -1
- package/packages/core/dist/scheduler/missions.js +9 -7
- package/packages/core/dist/scheduler/missions.js.map +1 -1
- package/packages/core/dist/scheduler/types.d.ts +7 -0
- package/packages/core/dist/scheduler/types.d.ts.map +1 -1
- package/packages/core/dist/scheduler/types.js +1 -0
- package/packages/core/dist/scheduler/types.js.map +1 -1
- package/packages/core/dist/tools.d.ts +59 -2
- package/packages/core/dist/tools.d.ts.map +1 -1
- package/packages/core/dist/tools.js.map +1 -1
- package/packages/core/migrations/075_access_providers.sql +43 -0
- package/packages/core/migrations/076_mission_browser.sql +7 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/agents/canvas.d.ts +12 -12
- package/packages/gateway/dist/agents/catalogue-package.d.ts +38 -20
- package/packages/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
- package/packages/gateway/dist/agents/catalogue-package.js +6 -0
- package/packages/gateway/dist/agents/catalogue-package.js.map +1 -1
- package/packages/gateway/dist/agents/delegation.d.ts +10 -0
- package/packages/gateway/dist/agents/delegation.d.ts.map +1 -1
- package/packages/gateway/dist/agents/delegation.js +1 -0
- package/packages/gateway/dist/agents/delegation.js.map +1 -1
- package/packages/gateway/dist/agents/platform-catalogue.d.ts +7 -1
- package/packages/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
- package/packages/gateway/dist/agents/platform-catalogue.js +15 -6
- package/packages/gateway/dist/agents/platform-catalogue.js.map +1 -1
- package/packages/gateway/dist/bootstrap.d.ts.map +1 -1
- package/packages/gateway/dist/bootstrap.js +8 -0
- package/packages/gateway/dist/bootstrap.js.map +1 -1
- package/packages/gateway/dist/browser-host.d.ts +30 -1
- package/packages/gateway/dist/browser-host.d.ts.map +1 -1
- package/packages/gateway/dist/browser-host.js +56 -1
- package/packages/gateway/dist/browser-host.js.map +1 -1
- package/packages/gateway/dist/chat/session.d.ts.map +1 -1
- package/packages/gateway/dist/chat/session.js +9 -5
- package/packages/gateway/dist/chat/session.js.map +1 -1
- package/packages/gateway/dist/index.d.ts +2 -1
- package/packages/gateway/dist/index.d.ts.map +1 -1
- package/packages/gateway/dist/index.js +2 -1
- package/packages/gateway/dist/index.js.map +1 -1
- package/packages/gateway/dist/missions/ask-cap.d.ts +26 -0
- package/packages/gateway/dist/missions/ask-cap.d.ts.map +1 -0
- package/packages/gateway/dist/missions/ask-cap.js +83 -0
- package/packages/gateway/dist/missions/ask-cap.js.map +1 -0
- package/packages/gateway/dist/missions/execute.d.ts +45 -1
- package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
- package/packages/gateway/dist/missions/execute.js +156 -10
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/parked.d.ts +139 -0
- package/packages/gateway/dist/missions/parked.d.ts.map +1 -0
- package/packages/gateway/dist/missions/parked.js +255 -0
- package/packages/gateway/dist/missions/parked.js.map +1 -0
- package/packages/gateway/dist/serve.d.ts +7 -0
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +49 -9
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/surfaces/browser-cards.d.ts +18 -0
- package/packages/gateway/dist/surfaces/browser-cards.d.ts.map +1 -0
- package/packages/gateway/dist/surfaces/browser-cards.js +42 -0
- package/packages/gateway/dist/surfaces/browser-cards.js.map +1 -0
- package/packages/gateway/dist/surfaces/browser-continuation.js +1 -1
- package/packages/gateway/dist/surfaces/browser-continuation.js.map +1 -1
- package/packages/gateway/dist/surfaces/owner-request.d.ts +6 -0
- package/packages/gateway/dist/surfaces/owner-request.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/owner-request.js +7 -1
- package/packages/gateway/dist/surfaces/owner-request.js.map +1 -1
- package/packages/gateway/dist/system-context.d.ts +7 -0
- package/packages/gateway/dist/system-context.d.ts.map +1 -1
- package/packages/gateway/dist/system-context.js +14 -7
- package/packages/gateway/dist/system-context.js.map +1 -1
- package/packages/gateway/dist/telegram/browser-view.d.ts +17 -17
- package/packages/gateway/dist/telegram/browser-view.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/browser-view.js +33 -37
- package/packages/gateway/dist/telegram/browser-view.js.map +1 -1
- package/packages/gateway/dist/telegram/channel.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/channel.js +17 -1
- package/packages/gateway/dist/telegram/channel.js.map +1 -1
- package/packages/gateway/dist/telegram/main.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/main.js +11 -3
- package/packages/gateway/dist/telegram/main.js.map +1 -1
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +10 -0
- package/packages/gateway/dist/telegram/surface.js.map +1 -1
- package/packages/gateway/dist/tips/facts.d.ts +8 -0
- package/packages/gateway/dist/tips/facts.d.ts.map +1 -1
- package/packages/gateway/dist/tips/facts.js +8 -2
- package/packages/gateway/dist/tips/facts.js.map +1 -1
- package/packages/gateway/dist/tips/rules.d.ts +2 -0
- package/packages/gateway/dist/tips/rules.d.ts.map +1 -1
- package/packages/gateway/dist/tips/rules.js +15 -0
- package/packages/gateway/dist/tips/rules.js.map +1 -1
- package/packages/gateway/dist/web/access/arrival.d.ts +24 -0
- package/packages/gateway/dist/web/access/arrival.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/arrival.js +18 -0
- package/packages/gateway/dist/web/access/arrival.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-api.d.ts +124 -0
- package/packages/gateway/dist/web/access/cloudflare-api.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-api.js +206 -0
- package/packages/gateway/dist/web/access/cloudflare-api.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.d.ts +163 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.js +438 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-token.d.ts +31 -0
- package/packages/gateway/dist/web/access/cloudflare-token.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-token.js +74 -0
- package/packages/gateway/dist/web/access/cloudflare-token.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare.d.ts +145 -0
- package/packages/gateway/dist/web/access/cloudflare.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare.js +474 -0
- package/packages/gateway/dist/web/access/cloudflare.js.map +1 -0
- package/packages/gateway/dist/web/access/index.d.ts +9 -0
- package/packages/gateway/dist/web/access/index.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/index.js +9 -0
- package/packages/gateway/dist/web/access/index.js.map +1 -0
- package/packages/gateway/dist/web/access/ingress.d.ts +30 -0
- package/packages/gateway/dist/web/access/ingress.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/ingress.js +76 -0
- package/packages/gateway/dist/web/access/ingress.js.map +1 -0
- package/packages/gateway/dist/web/access/provider.d.ts +173 -0
- package/packages/gateway/dist/web/access/provider.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/provider.js +11 -0
- package/packages/gateway/dist/web/access/provider.js.map +1 -0
- package/packages/gateway/dist/web/access/registry.d.ts +33 -0
- package/packages/gateway/dist/web/access/registry.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/registry.js +32 -0
- package/packages/gateway/dist/web/access/registry.js.map +1 -0
- package/packages/gateway/dist/web/{tailscale.d.ts → access/tailscale.d.ts} +27 -0
- package/packages/gateway/dist/web/access/tailscale.d.ts.map +1 -0
- package/packages/gateway/dist/web/{tailscale.js → access/tailscale.js} +118 -3
- package/packages/gateway/dist/web/access/tailscale.js.map +1 -0
- package/packages/gateway/dist/web/agents.d.ts +2 -0
- package/packages/gateway/dist/web/agents.d.ts.map +1 -1
- package/packages/gateway/dist/web/agents.js +19 -1
- package/packages/gateway/dist/web/agents.js.map +1 -1
- package/packages/gateway/dist/web/api-routes.d.ts +4 -3
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/packages/gateway/dist/web/api-routes.js +106 -19
- package/packages/gateway/dist/web/api-routes.js.map +1 -1
- package/packages/gateway/dist/web/attention.d.ts.map +1 -1
- package/packages/gateway/dist/web/attention.js +11 -3
- package/packages/gateway/dist/web/attention.js.map +1 -1
- package/packages/gateway/dist/web/chat.d.ts +23 -0
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +62 -2
- package/packages/gateway/dist/web/chat.js.map +1 -1
- package/packages/gateway/dist/web/client-key.d.ts +3 -0
- package/packages/gateway/dist/web/client-key.d.ts.map +1 -1
- package/packages/gateway/dist/web/client-key.js +8 -1
- package/packages/gateway/dist/web/client-key.js.map +1 -1
- package/packages/gateway/dist/web/extension.d.ts +21 -1
- package/packages/gateway/dist/web/extension.d.ts.map +1 -1
- package/packages/gateway/dist/web/extension.js +183 -3
- package/packages/gateway/dist/web/extension.js.map +1 -1
- package/packages/gateway/dist/web/http.d.ts +7 -0
- package/packages/gateway/dist/web/http.d.ts.map +1 -1
- package/packages/gateway/dist/web/http.js +15 -1
- package/packages/gateway/dist/web/http.js.map +1 -1
- package/packages/gateway/dist/web/index.d.ts +1 -1
- package/packages/gateway/dist/web/index.d.ts.map +1 -1
- package/packages/gateway/dist/web/index.js +1 -1
- package/packages/gateway/dist/web/index.js.map +1 -1
- package/packages/gateway/dist/web/onboarding.js +1 -1
- package/packages/gateway/dist/web/onboarding.js.map +1 -1
- package/packages/gateway/dist/web/remote-hand.d.ts.map +1 -1
- package/packages/gateway/dist/web/remote-hand.js +45 -2
- package/packages/gateway/dist/web/remote-hand.js.map +1 -1
- package/packages/gateway/dist/web/secrets.d.ts +26 -1
- package/packages/gateway/dist/web/secrets.d.ts.map +1 -1
- package/packages/gateway/dist/web/secrets.js +66 -3
- package/packages/gateway/dist/web/secrets.js.map +1 -1
- package/packages/gateway/dist/web/server.d.ts +38 -2
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +634 -147
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/sessions.d.ts +24 -14
- package/packages/gateway/dist/web/sessions.d.ts.map +1 -1
- package/packages/gateway/dist/web/sessions.js +42 -14
- package/packages/gateway/dist/web/sessions.js.map +1 -1
- package/packages/gateway/dist/web/signed-out.d.ts +10 -0
- package/packages/gateway/dist/web/signed-out.d.ts.map +1 -1
- package/packages/gateway/dist/web/signed-out.js +47 -0
- package/packages/gateway/dist/web/signed-out.js.map +1 -1
- package/packages/gateway/dist/web/version.d.ts +2 -0
- package/packages/gateway/dist/web/version.d.ts.map +1 -1
- package/packages/gateway/dist/web/version.js +5 -1
- package/packages/gateway/dist/web/version.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/install/dist/app-layout.d.ts +127 -0
- package/packages/install/dist/app-layout.d.ts.map +1 -0
- package/packages/install/dist/app-layout.js +323 -0
- package/packages/install/dist/app-layout.js.map +1 -0
- package/packages/install/dist/index.d.ts +1 -0
- package/packages/install/dist/index.d.ts.map +1 -1
- package/packages/install/dist/index.js +1 -0
- package/packages/install/dist/index.js.map +1 -1
- package/packages/install/dist/launcher.d.ts.map +1 -1
- package/packages/install/dist/launcher.js +18 -4
- package/packages/install/dist/launcher.js.map +1 -1
- package/packages/install/dist/provenance.d.ts +34 -0
- package/packages/install/dist/provenance.d.ts.map +1 -0
- package/packages/install/dist/provenance.js +200 -0
- package/packages/install/dist/provenance.js.map +1 -0
- package/packages/install/dist/supervisor.d.ts.map +1 -1
- package/packages/install/dist/supervisor.js +9 -4
- package/packages/install/dist/supervisor.js.map +1 -1
- package/packages/install/dist/upgrade.d.ts +77 -3
- package/packages/install/dist/upgrade.d.ts.map +1 -1
- package/packages/install/dist/upgrade.js +325 -43
- package/packages/install/dist/upgrade.js.map +1 -1
- package/packages/runtime/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/delegate.d.ts +8 -0
- package/packages/runtime/dist/delegate.d.ts.map +1 -1
- package/packages/runtime/dist/delegate.js +19 -1
- package/packages/runtime/dist/delegate.js.map +1 -1
- package/packages/runtime/dist/loop.d.ts +2 -0
- package/packages/runtime/dist/loop.d.ts.map +1 -1
- package/packages/runtime/dist/loop.js +18 -4
- package/packages/runtime/dist/loop.js.map +1 -1
- package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/availability.d.ts +2 -2
- package/packages/tools/browser/dist/availability.d.ts.map +1 -1
- package/packages/tools/browser/dist/availability.js +2 -2
- package/packages/tools/browser/dist/availability.js.map +1 -1
- package/packages/tools/browser/dist/controller.d.ts +82 -58
- package/packages/tools/browser/dist/controller.d.ts.map +1 -1
- package/packages/tools/browser/dist/controller.js +823 -217
- package/packages/tools/browser/dist/controller.js.map +1 -1
- package/packages/tools/browser/dist/driver.d.ts +3 -1
- package/packages/tools/browser/dist/driver.d.ts.map +1 -1
- package/packages/tools/browser/dist/driver.js +82 -1
- package/packages/tools/browser/dist/driver.js.map +1 -1
- package/packages/tools/browser/dist/extension.d.ts +70 -5
- package/packages/tools/browser/dist/extension.d.ts.map +1 -1
- package/packages/tools/browser/dist/extension.js +94 -9
- package/packages/tools/browser/dist/extension.js.map +1 -1
- package/packages/tools/browser/dist/index.d.ts +17 -7
- package/packages/tools/browser/dist/index.d.ts.map +1 -1
- package/packages/tools/browser/dist/index.js +35 -15
- package/packages/tools/browser/dist/index.js.map +1 -1
- package/packages/tools/browser/dist/logins.d.ts +150 -0
- package/packages/tools/browser/dist/logins.d.ts.map +1 -0
- package/packages/tools/browser/dist/logins.js +476 -0
- package/packages/tools/browser/dist/logins.js.map +1 -0
- package/packages/tools/browser/dist/manager.d.ts +39 -21
- package/packages/tools/browser/dist/manager.d.ts.map +1 -1
- package/packages/tools/browser/dist/manager.js +229 -136
- package/packages/tools/browser/dist/manager.js.map +1 -1
- package/packages/tools/browser/dist/routes.d.ts +151 -0
- package/packages/tools/browser/dist/routes.d.ts.map +1 -0
- package/packages/tools/browser/dist/routes.js +331 -0
- package/packages/tools/browser/dist/routes.js.map +1 -0
- package/packages/tools/browser/dist/secrets.d.ts +3 -1
- package/packages/tools/browser/dist/secrets.d.ts.map +1 -1
- package/packages/tools/browser/dist/secrets.js +10 -6
- package/packages/tools/browser/dist/secrets.js.map +1 -1
- package/packages/tools/browser/dist/service.d.ts +182 -115
- package/packages/tools/browser/dist/service.d.ts.map +1 -1
- package/packages/tools/browser/dist/service.js +491 -388
- package/packages/tools/browser/dist/service.js.map +1 -1
- package/packages/tools/browser/dist/settings.d.ts +88 -0
- package/packages/tools/browser/dist/settings.d.ts.map +1 -0
- package/packages/tools/browser/dist/settings.js +86 -0
- package/packages/tools/browser/dist/settings.js.map +1 -0
- package/packages/tools/browser/dist/telemetry.d.ts +203 -0
- package/packages/tools/browser/dist/telemetry.d.ts.map +1 -0
- package/packages/tools/browser/dist/telemetry.js +142 -0
- package/packages/tools/browser/dist/telemetry.js.map +1 -0
- package/packages/tools/browser/dist/types.d.ts +102 -3
- package/packages/tools/browser/dist/types.d.ts.map +1 -1
- package/packages/tools/browser/dist/types.js +27 -9
- package/packages/tools/browser/dist/types.js.map +1 -1
- package/packages/tools/email/dist/.tsbuildinfo +1 -1
- package/packages/tools/host/dist/.tsbuildinfo +1 -1
- package/packages/tools/mcp/dist/.tsbuildinfo +1 -1
- package/packages/tools/memory/dist/.tsbuildinfo +1 -1
- package/packages/tools/web/dist/.tsbuildinfo +1 -1
- package/packages/web/dist/assets/index-DYfeUW-0.css +1 -0
- package/packages/web/dist/assets/index-vpc904_b.js +146 -0
- package/packages/web/dist/assets/{lottie_light-CKJ88Yuk.js → lottie_light-BFAMYgLA.js} +1 -1
- package/packages/web/dist/build.json +1 -1
- package/packages/web/dist/index.html +2 -2
- package/packages/web/dist/precache.json +4 -4
- package/node_modules/@buddi/gateway/dist/web/apps.d.ts +0 -18
- package/node_modules/@buddi/gateway/dist/web/apps.d.ts.map +0 -1
- package/node_modules/@buddi/gateway/dist/web/apps.js +0 -84
- package/node_modules/@buddi/gateway/dist/web/apps.js.map +0 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts.map +0 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.js.map +0 -1
- package/node_modules/@buddi/tool-browser/dist/computer.d.ts +0 -153
- package/node_modules/@buddi/tool-browser/dist/computer.d.ts.map +0 -1
- package/node_modules/@buddi/tool-browser/dist/computer.js +0 -392
- package/node_modules/@buddi/tool-browser/dist/computer.js.map +0 -1
- package/node_modules/@buddi/tool-browser/dist/native/buddi-computer +0 -0
- package/node_modules/pino/test/browser-bindings.test.js +0 -114
- package/node_modules/pino/test/browser-redaction.test.js +0 -264
- package/node_modules/pino/test/browser-set-bindings.test.js +0 -99
- package/node_modules/pino/test/caller.test.js +0 -20
- package/node_modules/pino/test/fixtures/caller-loop.js +0 -6
- package/node_modules/pino/test/smoke.js +0 -59
- package/node_modules/pino/test/types/pino-import.tst.cts +0 -30
- package/node_modules/pino/test/types/pino-import.tst.js +0 -73
- package/node_modules/pino/test/types/pino-multistream.tst.ts +0 -49
- package/node_modules/pino/test/types/pino-top-export.tst.ts +0 -32
- package/node_modules/pino/test/types/pino-type-only.tst.ts +0 -77
- package/node_modules/pino/test/types/tsconfig.json +0 -10
- package/packages/gateway/dist/web/apps.d.ts +0 -18
- package/packages/gateway/dist/web/apps.d.ts.map +0 -1
- package/packages/gateway/dist/web/apps.js +0 -84
- package/packages/gateway/dist/web/apps.js.map +0 -1
- package/packages/gateway/dist/web/tailscale.d.ts.map +0 -1
- package/packages/gateway/dist/web/tailscale.js.map +0 -1
- package/packages/tools/browser/dist/computer.d.ts +0 -153
- package/packages/tools/browser/dist/computer.d.ts.map +0 -1
- package/packages/tools/browser/dist/computer.js +0 -392
- package/packages/tools/browser/dist/computer.js.map +0 -1
- package/packages/tools/browser/dist/native/buddi-computer +0 -0
- package/packages/web/dist/assets/index-CN1AXMI1.css +0 -1
- package/packages/web/dist/assets/index-CQRE9LJX.js +0 -145
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider 2: Cloudflare Tunnel + Cloudflare Access (specs/trusted-access.md §5).
|
|
3
|
+
*
|
|
4
|
+
* The tunnel (cloudflared, on this machine) carries the traffic to the
|
|
5
|
+
* ingress listener; Access, at Cloudflare's edge, decides who may pass and
|
|
6
|
+
* puts a signed JWT on every request it lets through, in the
|
|
7
|
+
* `Cf-Access-Jwt-Assertion` header. buddi verifies that JWT itself, on every
|
|
8
|
+
* request, and never trusts a plain header:
|
|
9
|
+
*
|
|
10
|
+
* 1. The request arrived on the ingress listener (`arrival.ts`). A JWT on
|
|
11
|
+
* the main listener is a replay from a local process, and earns nothing.
|
|
12
|
+
* 2. The header is present, once. The `CF_Authorization` cookie is ignored:
|
|
13
|
+
* the header is what Access adds at the edge, the cookie is what a
|
|
14
|
+
* browser can carry anywhere.
|
|
15
|
+
* 3. The signature verifies (RS256) against the team's keys from
|
|
16
|
+
* `https://<team>.cloudflareaccess.com/cdn-cgi/access/certs`, cached by
|
|
17
|
+
* `kid` for an hour, refetched on an unknown `kid` at most once a minute.
|
|
18
|
+
* 4. `iss` is `https://<team>.cloudflareaccess.com`; `aud` contains the
|
|
19
|
+
* application's AUD tag; `exp` and `nbf` hold, with 60 seconds of skew.
|
|
20
|
+
* 5. The `email` claim is the allowed email (compared as Tailscale logins
|
|
21
|
+
* are). A service-token JWT (no `email`, a `common_name`) is refused.
|
|
22
|
+
*
|
|
23
|
+
* `Cf-Connecting-Ip`, `Cf-Access-Authenticated-User-Email` and every other
|
|
24
|
+
* header are never identity. `Cf-Connecting-Ip` is a rate-limit bucket, and
|
|
25
|
+
* only after the JWT verified.
|
|
26
|
+
*
|
|
27
|
+
* Replay: within its life a JWT is a bearer credential — that is Access's
|
|
28
|
+
* model, and the browser presents the same one on every request. buddi adds
|
|
29
|
+
* the arrival check (it must come through the tunnel), the `exp` with a small
|
|
30
|
+
* skew, and on a session the JWT must keep naming the same email.
|
|
31
|
+
*/
|
|
32
|
+
import { type KeyObject } from 'node:crypto';
|
|
33
|
+
import { type HttpTransport } from '@buddi/runtime';
|
|
34
|
+
import { type AccessProvider } from './provider.js';
|
|
35
|
+
export declare const CLOUDFLARE_SETTING_KEY = "access.cloudflare";
|
|
36
|
+
export declare const CF_ASSERTION_HEADER = "cf-access-jwt-assertion";
|
|
37
|
+
/** How long the team's keys are used before they are fetched again. */
|
|
38
|
+
export declare const JWKS_CACHE_MS: number;
|
|
39
|
+
/** The least time between two fetches, whatever `kid` turns up. */
|
|
40
|
+
export declare const JWKS_REFETCH_MIN_MS = 60000;
|
|
41
|
+
/** Clock skew allowed on `exp`, `nbf` and `iat`. */
|
|
42
|
+
export declare const JWT_SKEW_MS = 60000;
|
|
43
|
+
/** The hard cap on a Cloudflare session, and on any JWT's own lifetime. */
|
|
44
|
+
export declare const CLOUDFLARE_ABSOLUTE_CAP_MS: number;
|
|
45
|
+
export interface CloudflareAccessSetting {
|
|
46
|
+
enabled: boolean;
|
|
47
|
+
/** `<team>.cloudflareaccess.com`, lower case, no scheme. */
|
|
48
|
+
teamDomain: string;
|
|
49
|
+
/** The Access application's AUD tag. */
|
|
50
|
+
aud: string;
|
|
51
|
+
/** The one email allowed to sign in. */
|
|
52
|
+
email: string;
|
|
53
|
+
/** The public hostname as an origin (`https://buddi.example.com`), or empty. */
|
|
54
|
+
publicOrigin: string;
|
|
55
|
+
}
|
|
56
|
+
/** Shape checks only; nothing here proves a team or an email exists. */
|
|
57
|
+
export declare function normalizeTeamDomain(raw: string): string;
|
|
58
|
+
export declare function plausibleTeamDomain(value: string): boolean;
|
|
59
|
+
export declare function plausibleAud(value: string): boolean;
|
|
60
|
+
export declare function plausibleEmail(value: string): boolean;
|
|
61
|
+
/** An `https://` origin with nothing after the host, or null. */
|
|
62
|
+
export declare function normalizePublicOrigin(raw: string): string | null;
|
|
63
|
+
/** What is stored, made safe: anything unexpected in the row reads as off. */
|
|
64
|
+
export declare function toCloudflareSetting(value: unknown): CloudflareAccessSetting;
|
|
65
|
+
/** What is missing before this can be turned on, in words; empty when nothing. */
|
|
66
|
+
export declare function cloudflareMissing(setting: Pick<CloudflareAccessSetting, 'teamDomain' | 'aud' | 'email'>): string[];
|
|
67
|
+
/** "a, b and c". */
|
|
68
|
+
export declare function listInWords(items: string[]): string;
|
|
69
|
+
/**
|
|
70
|
+
* The owner's input to the panel, validated: the setting to store, or the
|
|
71
|
+
* sentence saying what is wrong with it.
|
|
72
|
+
*/
|
|
73
|
+
export declare function validateCloudflareInput(input: Record<string, unknown>): {
|
|
74
|
+
ok: true;
|
|
75
|
+
value: CloudflareAccessSetting;
|
|
76
|
+
} | {
|
|
77
|
+
ok: false;
|
|
78
|
+
error: string;
|
|
79
|
+
};
|
|
80
|
+
export type JwksAnswer = KeyObject | 'unknown' | 'unanswered';
|
|
81
|
+
export interface JwksFetchResult {
|
|
82
|
+
ok: boolean;
|
|
83
|
+
/** How many RS256 signing keys came back. */
|
|
84
|
+
keys: number;
|
|
85
|
+
/** Why not, in words, when `ok` is false. Never echoes a body. */
|
|
86
|
+
error?: string | undefined;
|
|
87
|
+
}
|
|
88
|
+
export interface Jwks {
|
|
89
|
+
/** The key for this `kid`: fetched once on a miss, at most once a minute. */
|
|
90
|
+
key(teamDomain: string, kid: string): Promise<JwksAnswer>;
|
|
91
|
+
/** Fetch the team's keys now, whatever the cache holds (Save, Test my setup). */
|
|
92
|
+
refresh(teamDomain: string): Promise<JwksFetchResult>;
|
|
93
|
+
/** Did the last fetch for this team fail? */
|
|
94
|
+
failing(teamDomain: string): boolean;
|
|
95
|
+
}
|
|
96
|
+
export declare function certsUrl(teamDomain: string): string;
|
|
97
|
+
/**
|
|
98
|
+
* The team's JWKS, cached by `kid`.
|
|
99
|
+
*
|
|
100
|
+
* One cache per team domain, so changing the setting never mixes keys. A key
|
|
101
|
+
* set is used for an hour; an unknown `kid` refetches at once unless a fetch
|
|
102
|
+
* happened in the last minute (a stranger varying `kid` cannot make the
|
|
103
|
+
* gateway hammer Cloudflare). A fetch that fails is never cached as "no keys":
|
|
104
|
+
* the request is `unanswered` and the next one asks again, within the budget.
|
|
105
|
+
*/
|
|
106
|
+
export declare function createJwks(deps?: {
|
|
107
|
+
transport?: HttpTransport | undefined;
|
|
108
|
+
now?: (() => Date) | undefined;
|
|
109
|
+
log?: ((line: string) => void) | undefined;
|
|
110
|
+
}): Jwks;
|
|
111
|
+
export type CloudflareRefusal = 'setting-off' | 'not-through-the-tunnel' | 'no-assertion' | 'malformed' | 'wrong-algorithm' | 'unknown-key' | 'bad-signature' | 'wrong-issuer' | 'wrong-audience' | 'expired' | 'not-yet-valid' | 'too-long-lived' | 'service-token' | 'email-not-allowed' | 'keys-unreachable';
|
|
112
|
+
export declare function cloudflareRefusalReason(reason: CloudflareRefusal): string;
|
|
113
|
+
export interface VerifiedAssertion {
|
|
114
|
+
email: string;
|
|
115
|
+
expiresAt: Date;
|
|
116
|
+
issuedAt?: Date | undefined;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Verify one assertion against the setting: steps 3–5 above. Never throws.
|
|
120
|
+
*/
|
|
121
|
+
export declare function verifyAccessJwt(token: string, setting: Pick<CloudflareAccessSetting, 'teamDomain' | 'aud' | 'email'>, deps: {
|
|
122
|
+
jwks: Jwks;
|
|
123
|
+
now: Date;
|
|
124
|
+
}): Promise<{
|
|
125
|
+
ok: true;
|
|
126
|
+
assertion: VerifiedAssertion;
|
|
127
|
+
} | {
|
|
128
|
+
ok: false;
|
|
129
|
+
reason: CloudflareRefusal;
|
|
130
|
+
}>;
|
|
131
|
+
export interface CloudflareProviderDeps {
|
|
132
|
+
jwks: Jwks;
|
|
133
|
+
log?: ((line: string) => void) | undefined;
|
|
134
|
+
/** The ingress listener could not be bound, in words; null while it is fine. */
|
|
135
|
+
ingressProblem?: (() => string | null) | undefined;
|
|
136
|
+
}
|
|
137
|
+
export interface CloudflareProvider extends AccessProvider<CloudflareAccessSetting> {
|
|
138
|
+
/** When a visit last verified, and as whom. In memory: a restart waits for the next one. */
|
|
139
|
+
lastVisit(): {
|
|
140
|
+
at: Date;
|
|
141
|
+
email: string;
|
|
142
|
+
} | null;
|
|
143
|
+
}
|
|
144
|
+
export declare function cloudflareProvider(deps: CloudflareProviderDeps): CloudflareProvider;
|
|
145
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/web/access/cloudflare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAA0D,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAErG,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAKL,KAAK,cAAc,EAIpB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAC1D,eAAO,MAAM,mBAAmB,4BAA4B,CAAC;AAE7D,uEAAuE;AACvE,eAAO,MAAM,aAAa,QAAc,CAAC;AACzC,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,oDAAoD;AACpD,eAAO,MAAM,WAAW,QAAS,CAAC;AAClC,2EAA2E;AAC3E,eAAO,MAAM,0BAA0B,QAAuB,CAAC;AAI/D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE1D;AACD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AACD,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWhE;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAS3E;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC,GAAG,MAAM,EAAE,CAMlH;AAED,oBAAoB;AACpB,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,uBAAuB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAoBnJ;AAMD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,IAAI;IACnB,6EAA6E;IAC7E,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1D,iFAAiF;IACjF,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACtD,6CAA6C;IAC7C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAED,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAAO,GAAG,IAAI,CA6EjK;AAMD,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,wBAAwB,GACxB,cAAc,GACd,WAAW,GACX,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,mBAAmB,GACnB,kBAAkB,CAAC;AAoBvB,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAEzE;AAUD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CAC7B;AAWD;;GAEG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC,EACtE,IAAI,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAC9B,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,iBAAiB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAgDhG;AAMD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3C,gFAAgF;IAChF,cAAc,CAAC,EAAE,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;CACpD;AAED,MAAM,WAAW,kBAAmB,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACjF,4FAA4F;IAC5F,SAAS,IAAI;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACjD;AAoBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,kBAAkB,CA6GnF"}
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider 2: Cloudflare Tunnel + Cloudflare Access (specs/trusted-access.md §5).
|
|
3
|
+
*
|
|
4
|
+
* The tunnel (cloudflared, on this machine) carries the traffic to the
|
|
5
|
+
* ingress listener; Access, at Cloudflare's edge, decides who may pass and
|
|
6
|
+
* puts a signed JWT on every request it lets through, in the
|
|
7
|
+
* `Cf-Access-Jwt-Assertion` header. buddi verifies that JWT itself, on every
|
|
8
|
+
* request, and never trusts a plain header:
|
|
9
|
+
*
|
|
10
|
+
* 1. The request arrived on the ingress listener (`arrival.ts`). A JWT on
|
|
11
|
+
* the main listener is a replay from a local process, and earns nothing.
|
|
12
|
+
* 2. The header is present, once. The `CF_Authorization` cookie is ignored:
|
|
13
|
+
* the header is what Access adds at the edge, the cookie is what a
|
|
14
|
+
* browser can carry anywhere.
|
|
15
|
+
* 3. The signature verifies (RS256) against the team's keys from
|
|
16
|
+
* `https://<team>.cloudflareaccess.com/cdn-cgi/access/certs`, cached by
|
|
17
|
+
* `kid` for an hour, refetched on an unknown `kid` at most once a minute.
|
|
18
|
+
* 4. `iss` is `https://<team>.cloudflareaccess.com`; `aud` contains the
|
|
19
|
+
* application's AUD tag; `exp` and `nbf` hold, with 60 seconds of skew.
|
|
20
|
+
* 5. The `email` claim is the allowed email (compared as Tailscale logins
|
|
21
|
+
* are). A service-token JWT (no `email`, a `common_name`) is refused.
|
|
22
|
+
*
|
|
23
|
+
* `Cf-Connecting-Ip`, `Cf-Access-Authenticated-User-Email` and every other
|
|
24
|
+
* header are never identity. `Cf-Connecting-Ip` is a rate-limit bucket, and
|
|
25
|
+
* only after the JWT verified.
|
|
26
|
+
*
|
|
27
|
+
* Replay: within its life a JWT is a bearer credential — that is Access's
|
|
28
|
+
* model, and the browser presents the same one on every request. buddi adds
|
|
29
|
+
* the arrival check (it must come through the tunnel), the `exp` with a small
|
|
30
|
+
* skew, and on a session the JWT must keep naming the same email.
|
|
31
|
+
*/
|
|
32
|
+
import { createHash, createPublicKey, verify as verifySignature } from 'node:crypto';
|
|
33
|
+
import { defaultHttpTransport } from '@buddi/runtime';
|
|
34
|
+
import { arrivalOf } from './arrival.js';
|
|
35
|
+
import { sameSubject, } from './provider.js';
|
|
36
|
+
export const CLOUDFLARE_SETTING_KEY = 'access.cloudflare';
|
|
37
|
+
export const CF_ASSERTION_HEADER = 'cf-access-jwt-assertion';
|
|
38
|
+
/** How long the team's keys are used before they are fetched again. */
|
|
39
|
+
export const JWKS_CACHE_MS = 60 * 60_000;
|
|
40
|
+
/** The least time between two fetches, whatever `kid` turns up. */
|
|
41
|
+
export const JWKS_REFETCH_MIN_MS = 60_000;
|
|
42
|
+
/** Clock skew allowed on `exp`, `nbf` and `iat`. */
|
|
43
|
+
export const JWT_SKEW_MS = 60_000;
|
|
44
|
+
/** The hard cap on a Cloudflare session, and on any JWT's own lifetime. */
|
|
45
|
+
export const CLOUDFLARE_ABSOLUTE_CAP_MS = 7 * 24 * 60 * 60_000;
|
|
46
|
+
/** The largest assertion read. Access's are about a kilobyte. */
|
|
47
|
+
const MAX_ASSERTION = 16_384;
|
|
48
|
+
/** Shape checks only; nothing here proves a team or an email exists. */
|
|
49
|
+
export function normalizeTeamDomain(raw) {
|
|
50
|
+
let value = raw.trim().toLowerCase().replace(/^https?:\/\//, '').replace(/\/.*$/, '');
|
|
51
|
+
if (/^[a-z0-9][a-z0-9-]{0,62}$/.test(value))
|
|
52
|
+
value = `${value}.cloudflareaccess.com`;
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
export function plausibleTeamDomain(value) {
|
|
56
|
+
return /^[a-z0-9][a-z0-9-]{0,62}\.cloudflareaccess\.com$/.test(value);
|
|
57
|
+
}
|
|
58
|
+
export function plausibleAud(value) {
|
|
59
|
+
return /^[A-Za-z0-9]{16,128}$/.test(value);
|
|
60
|
+
}
|
|
61
|
+
export function plausibleEmail(value) {
|
|
62
|
+
return value.length <= 254 && /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value);
|
|
63
|
+
}
|
|
64
|
+
/** An `https://` origin with nothing after the host, or null. */
|
|
65
|
+
export function normalizePublicOrigin(raw) {
|
|
66
|
+
const value = raw.trim();
|
|
67
|
+
if (value === '')
|
|
68
|
+
return '';
|
|
69
|
+
try {
|
|
70
|
+
const url = new URL(value.includes('://') ? value : `https://${value}`);
|
|
71
|
+
if (url.protocol !== 'https:' || url.username || url.password)
|
|
72
|
+
return null;
|
|
73
|
+
if ((url.pathname !== '/' && url.pathname !== '') || url.search || url.hash)
|
|
74
|
+
return null;
|
|
75
|
+
return url.origin;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** What is stored, made safe: anything unexpected in the row reads as off. */
|
|
82
|
+
export function toCloudflareSetting(value) {
|
|
83
|
+
const row = (value ?? {});
|
|
84
|
+
const str = (v) => (typeof v === 'string' ? v.trim() : '');
|
|
85
|
+
const teamDomain = normalizeTeamDomain(str(row.teamDomain));
|
|
86
|
+
const aud = str(row.aud);
|
|
87
|
+
const email = str(row.email);
|
|
88
|
+
const origin = normalizePublicOrigin(str(row.publicOrigin)) ?? '';
|
|
89
|
+
const complete = plausibleTeamDomain(teamDomain) && plausibleAud(aud) && plausibleEmail(email);
|
|
90
|
+
return { enabled: row.enabled === true && complete, teamDomain, aud, email, publicOrigin: origin };
|
|
91
|
+
}
|
|
92
|
+
/** What is missing before this can be turned on, in words; empty when nothing. */
|
|
93
|
+
export function cloudflareMissing(setting) {
|
|
94
|
+
const missing = [];
|
|
95
|
+
if (!plausibleTeamDomain(setting.teamDomain))
|
|
96
|
+
missing.push('the team domain');
|
|
97
|
+
if (!plausibleAud(setting.aud))
|
|
98
|
+
missing.push('the AUD tag');
|
|
99
|
+
if (!plausibleEmail(setting.email))
|
|
100
|
+
missing.push('your email');
|
|
101
|
+
return missing;
|
|
102
|
+
}
|
|
103
|
+
/** "a, b and c". */
|
|
104
|
+
export function listInWords(items) {
|
|
105
|
+
if (items.length <= 1)
|
|
106
|
+
return items.join('');
|
|
107
|
+
return `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The owner's input to the panel, validated: the setting to store, or the
|
|
111
|
+
* sentence saying what is wrong with it.
|
|
112
|
+
*/
|
|
113
|
+
export function validateCloudflareInput(input) {
|
|
114
|
+
if (typeof input.enabled !== 'boolean')
|
|
115
|
+
return { ok: false, error: '`enabled` must be true or false' };
|
|
116
|
+
const str = (v) => (typeof v === 'string' ? v.trim() : '');
|
|
117
|
+
const teamDomain = normalizeTeamDomain(str(input.teamDomain));
|
|
118
|
+
const aud = str(input.aud);
|
|
119
|
+
const email = str(input.email);
|
|
120
|
+
const origin = normalizePublicOrigin(str(input.publicOrigin));
|
|
121
|
+
if (teamDomain !== '' && !plausibleTeamDomain(teamDomain)) {
|
|
122
|
+
return { ok: false, error: 'That is not a Cloudflare team domain. It looks like yourteam.cloudflareaccess.com, under Zero Trust → Settings.' };
|
|
123
|
+
}
|
|
124
|
+
if (aud !== '' && !plausibleAud(aud)) {
|
|
125
|
+
return { ok: false, error: 'That is not an AUD tag. It is the long string of letters and digits on the Access application’s Overview tab.' };
|
|
126
|
+
}
|
|
127
|
+
if (email !== '' && !plausibleEmail(email))
|
|
128
|
+
return { ok: false, error: 'That is not an email address.' };
|
|
129
|
+
if (origin === null)
|
|
130
|
+
return { ok: false, error: 'The public address must be an https:// address with nothing after the host, like https://buddi.example.com.' };
|
|
131
|
+
if (input.enabled) {
|
|
132
|
+
const missing = cloudflareMissing({ teamDomain, aud, email });
|
|
133
|
+
if (missing.length > 0)
|
|
134
|
+
return { ok: false, error: `To turn this on, fill in ${listInWords(missing)}.` };
|
|
135
|
+
}
|
|
136
|
+
return { ok: true, value: { enabled: input.enabled, teamDomain, aud, email, publicOrigin: origin } };
|
|
137
|
+
}
|
|
138
|
+
export function certsUrl(teamDomain) {
|
|
139
|
+
return `https://${teamDomain}/cdn-cgi/access/certs`;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The team's JWKS, cached by `kid`.
|
|
143
|
+
*
|
|
144
|
+
* One cache per team domain, so changing the setting never mixes keys. A key
|
|
145
|
+
* set is used for an hour; an unknown `kid` refetches at once unless a fetch
|
|
146
|
+
* happened in the last minute (a stranger varying `kid` cannot make the
|
|
147
|
+
* gateway hammer Cloudflare). A fetch that fails is never cached as "no keys":
|
|
148
|
+
* the request is `unanswered` and the next one asks again, within the budget.
|
|
149
|
+
*/
|
|
150
|
+
export function createJwks(deps = {}) {
|
|
151
|
+
const transport = deps.transport ?? defaultHttpTransport;
|
|
152
|
+
const now = deps.now ?? (() => new Date());
|
|
153
|
+
const teams = new Map();
|
|
154
|
+
const entry = (team) => {
|
|
155
|
+
let e = teams.get(team);
|
|
156
|
+
if (!e) {
|
|
157
|
+
if (teams.size > 8)
|
|
158
|
+
teams.clear();
|
|
159
|
+
e = { keys: new Map(), fetchedAt: Number.NEGATIVE_INFINITY, triedAt: Number.NEGATIVE_INFINITY, failing: false };
|
|
160
|
+
teams.set(team, e);
|
|
161
|
+
}
|
|
162
|
+
return e;
|
|
163
|
+
};
|
|
164
|
+
const fetchKeys = (team) => {
|
|
165
|
+
const e = entry(team);
|
|
166
|
+
if (e.inFlight)
|
|
167
|
+
return e.inFlight;
|
|
168
|
+
e.triedAt = now().getTime();
|
|
169
|
+
const run = (async () => {
|
|
170
|
+
try {
|
|
171
|
+
const res = await transport(certsUrl(team), { method: 'GET', headers: { accept: 'application/json' }, idleTimeoutMs: 5_000, maxBytes: 256_000 });
|
|
172
|
+
if (!res.ok) {
|
|
173
|
+
e.failing = true;
|
|
174
|
+
return { ok: false, keys: 0, error: `${team} didn’t answer with signing keys (${res.status}). Check the team domain.` };
|
|
175
|
+
}
|
|
176
|
+
const body = (await res.json().catch(() => null));
|
|
177
|
+
const keys = new Map();
|
|
178
|
+
for (const jwk of Array.isArray(body?.keys) ? body.keys : []) {
|
|
179
|
+
const k = jwk;
|
|
180
|
+
if (typeof k.kid !== 'string' || k.kty !== 'RSA')
|
|
181
|
+
continue;
|
|
182
|
+
if (k.alg !== undefined && k.alg !== 'RS256')
|
|
183
|
+
continue;
|
|
184
|
+
if (k.use !== undefined && k.use !== 'sig')
|
|
185
|
+
continue;
|
|
186
|
+
try {
|
|
187
|
+
keys.set(k.kid, createPublicKey({ key: jwk, format: 'jwk' }));
|
|
188
|
+
}
|
|
189
|
+
catch { /* a key that does not parse is not a key */ }
|
|
190
|
+
}
|
|
191
|
+
if (keys.size === 0) {
|
|
192
|
+
e.failing = true;
|
|
193
|
+
return { ok: false, keys: 0, error: `${team} answered, but with no signing keys buddi can use.` };
|
|
194
|
+
}
|
|
195
|
+
e.keys = keys;
|
|
196
|
+
e.fetchedAt = now().getTime();
|
|
197
|
+
e.failing = false;
|
|
198
|
+
return { ok: true, keys: keys.size };
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
e.failing = true;
|
|
202
|
+
deps.log?.(`access: fetching Cloudflare's signing keys failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
203
|
+
return { ok: false, keys: 0, error: `${team} could not be reached just now. Check the team domain and this computer’s connection.` };
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
delete e.inFlight;
|
|
207
|
+
}
|
|
208
|
+
})();
|
|
209
|
+
e.inFlight = run;
|
|
210
|
+
return run;
|
|
211
|
+
};
|
|
212
|
+
return {
|
|
213
|
+
async key(team, kid) {
|
|
214
|
+
const e = entry(team);
|
|
215
|
+
const at = now().getTime();
|
|
216
|
+
const fresh = at - e.fetchedAt < JWKS_CACHE_MS;
|
|
217
|
+
const hit = e.keys.get(kid);
|
|
218
|
+
if (hit && fresh)
|
|
219
|
+
return hit;
|
|
220
|
+
if (at - e.triedAt < JWKS_REFETCH_MIN_MS && !e.inFlight) {
|
|
221
|
+
// Asked a moment ago. A stale set still answers for a known kid until
|
|
222
|
+
// the next fetch is allowed; an unknown kid waits.
|
|
223
|
+
if (hit)
|
|
224
|
+
return hit;
|
|
225
|
+
return e.failing ? 'unanswered' : 'unknown';
|
|
226
|
+
}
|
|
227
|
+
const result = await fetchKeys(team);
|
|
228
|
+
if (!result.ok)
|
|
229
|
+
return 'unanswered';
|
|
230
|
+
return e.keys.get(kid) ?? 'unknown';
|
|
231
|
+
},
|
|
232
|
+
refresh: (team) => fetchKeys(team),
|
|
233
|
+
failing: (team) => teams.get(team)?.failing ?? false,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
const REASONS = {
|
|
237
|
+
'setting-off': 'a request arrived through the tunnel but signing in through Cloudflare is off',
|
|
238
|
+
'not-through-the-tunnel': 'a Cloudflare Access assertion arrived somewhere other than the ingress listener',
|
|
239
|
+
'no-assertion': 'a request arrived through the tunnel without Cloudflare Access’s signed assertion',
|
|
240
|
+
malformed: 'the Cloudflare Access assertion is not a JWT buddi can read',
|
|
241
|
+
'wrong-algorithm': 'the Cloudflare Access assertion is not signed with RS256',
|
|
242
|
+
'unknown-key': 'the Cloudflare Access assertion is signed with a key the team does not publish',
|
|
243
|
+
'bad-signature': 'the Cloudflare Access assertion’s signature does not verify',
|
|
244
|
+
'wrong-issuer': 'the Cloudflare Access assertion was issued by another team',
|
|
245
|
+
'wrong-audience': 'the Cloudflare Access assertion is for another application',
|
|
246
|
+
expired: 'the Cloudflare Access assertion has expired',
|
|
247
|
+
'not-yet-valid': 'the Cloudflare Access assertion is not valid yet',
|
|
248
|
+
'too-long-lived': 'the Cloudflare Access assertion claims a lifetime longer than seven days',
|
|
249
|
+
'service-token': 'the Cloudflare Access assertion is a service token, not a person',
|
|
250
|
+
'email-not-allowed': 'the email Cloudflare signed in is not the one allowed to sign in through Cloudflare',
|
|
251
|
+
'keys-unreachable': 'Cloudflare’s signing keys could not be fetched just now',
|
|
252
|
+
};
|
|
253
|
+
export function cloudflareRefusalReason(reason) {
|
|
254
|
+
return REASONS[reason];
|
|
255
|
+
}
|
|
256
|
+
function refusalOf(reason) {
|
|
257
|
+
return {
|
|
258
|
+
refusal: reason,
|
|
259
|
+
sentence: REASONS[reason],
|
|
260
|
+
kind: reason === 'keys-unreachable' ? 'unanswered' : reason === 'email-not-allowed' ? 'login' : 'other',
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function b64json(part) {
|
|
264
|
+
try {
|
|
265
|
+
const value = JSON.parse(Buffer.from(part, 'base64url').toString('utf8'));
|
|
266
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Verify one assertion against the setting: steps 3–5 above. Never throws.
|
|
274
|
+
*/
|
|
275
|
+
export async function verifyAccessJwt(token, setting, deps) {
|
|
276
|
+
if (token.length > MAX_ASSERTION)
|
|
277
|
+
return { ok: false, reason: 'malformed' };
|
|
278
|
+
const parts = token.split('.');
|
|
279
|
+
if (parts.length !== 3 || parts.some((p) => !/^[A-Za-z0-9_-]+$/.test(p)))
|
|
280
|
+
return { ok: false, reason: 'malformed' };
|
|
281
|
+
const [h, p, s] = parts;
|
|
282
|
+
const header = b64json(h);
|
|
283
|
+
const payload = b64json(p);
|
|
284
|
+
if (!header || !payload)
|
|
285
|
+
return { ok: false, reason: 'malformed' };
|
|
286
|
+
// Only RS256: never `none`, never an HMAC a public key could be fed into.
|
|
287
|
+
if (header.alg !== 'RS256')
|
|
288
|
+
return { ok: false, reason: 'wrong-algorithm' };
|
|
289
|
+
if (typeof header.kid !== 'string' || header.kid === '' || header.kid.length > 256)
|
|
290
|
+
return { ok: false, reason: 'malformed' };
|
|
291
|
+
const key = await deps.jwks.key(setting.teamDomain, header.kid);
|
|
292
|
+
if (key === 'unanswered')
|
|
293
|
+
return { ok: false, reason: 'keys-unreachable' };
|
|
294
|
+
if (key === 'unknown')
|
|
295
|
+
return { ok: false, reason: 'unknown-key' };
|
|
296
|
+
let good = false;
|
|
297
|
+
try {
|
|
298
|
+
good = verifySignature('RSA-SHA256', Buffer.from(`${h}.${p}`, 'utf8'), key, Buffer.from(s, 'base64url'));
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
good = false;
|
|
302
|
+
}
|
|
303
|
+
if (!good)
|
|
304
|
+
return { ok: false, reason: 'bad-signature' };
|
|
305
|
+
if (payload.iss !== `https://${setting.teamDomain}`)
|
|
306
|
+
return { ok: false, reason: 'wrong-issuer' };
|
|
307
|
+
const aud = payload.aud;
|
|
308
|
+
const auds = Array.isArray(aud) ? aud : [aud];
|
|
309
|
+
if (!auds.some((a) => typeof a === 'string' && a === setting.aud))
|
|
310
|
+
return { ok: false, reason: 'wrong-audience' };
|
|
311
|
+
const at = deps.now.getTime();
|
|
312
|
+
const exp = typeof payload.exp === 'number' ? payload.exp * 1000 : NaN;
|
|
313
|
+
if (!Number.isFinite(exp))
|
|
314
|
+
return { ok: false, reason: 'malformed' };
|
|
315
|
+
if (exp + JWT_SKEW_MS <= at)
|
|
316
|
+
return { ok: false, reason: 'expired' };
|
|
317
|
+
if (payload.nbf !== undefined) {
|
|
318
|
+
if (typeof payload.nbf !== 'number')
|
|
319
|
+
return { ok: false, reason: 'malformed' };
|
|
320
|
+
if (payload.nbf * 1000 - JWT_SKEW_MS > at)
|
|
321
|
+
return { ok: false, reason: 'not-yet-valid' };
|
|
322
|
+
}
|
|
323
|
+
let issuedAt;
|
|
324
|
+
if (payload.iat !== undefined) {
|
|
325
|
+
if (typeof payload.iat !== 'number')
|
|
326
|
+
return { ok: false, reason: 'malformed' };
|
|
327
|
+
if (payload.iat * 1000 - JWT_SKEW_MS > at)
|
|
328
|
+
return { ok: false, reason: 'not-yet-valid' };
|
|
329
|
+
issuedAt = new Date(payload.iat * 1000);
|
|
330
|
+
}
|
|
331
|
+
if (exp - at > CLOUDFLARE_ABSOLUTE_CAP_MS + JWT_SKEW_MS)
|
|
332
|
+
return { ok: false, reason: 'too-long-lived' };
|
|
333
|
+
// A service token names a `common_name`, not a person.
|
|
334
|
+
if (typeof payload.email !== 'string' || payload.email.trim() === '')
|
|
335
|
+
return { ok: false, reason: 'service-token' };
|
|
336
|
+
if (!sameSubject(payload.email, setting.email))
|
|
337
|
+
return { ok: false, reason: 'email-not-allowed' };
|
|
338
|
+
return { ok: true, assertion: { email: payload.email.trim(), expiresAt: new Date(exp), ...(issuedAt ? { issuedAt } : {}) } };
|
|
339
|
+
}
|
|
340
|
+
const LOG_EVERY_MS = 60_000;
|
|
341
|
+
/** The single assertion header, or nothing: two header lines are not one assertion. */
|
|
342
|
+
function assertionOf(req) {
|
|
343
|
+
const raw = req.headers[CF_ASSERTION_HEADER];
|
|
344
|
+
if (raw === undefined)
|
|
345
|
+
return undefined;
|
|
346
|
+
if (Array.isArray(raw))
|
|
347
|
+
return null;
|
|
348
|
+
const value = raw.trim();
|
|
349
|
+
return value === '' ? undefined : value;
|
|
350
|
+
}
|
|
351
|
+
function connectingIp(req) {
|
|
352
|
+
const raw = req.headers['cf-connecting-ip'];
|
|
353
|
+
const value = (Array.isArray(raw) ? raw[0] : raw)?.trim() ?? '';
|
|
354
|
+
// Only ever a bucket name, but kept to the shape of an address.
|
|
355
|
+
return /^[0-9A-Fa-f:.]{2,45}$/.test(value) ? value.toLowerCase() : 'unknown';
|
|
356
|
+
}
|
|
357
|
+
export function cloudflareProvider(deps) {
|
|
358
|
+
const lastLogged = new Map();
|
|
359
|
+
let visit = null;
|
|
360
|
+
const complain = (reason, now) => {
|
|
361
|
+
const last = lastLogged.get(reason) ?? 0;
|
|
362
|
+
if (now.getTime() - last >= LOG_EVERY_MS) {
|
|
363
|
+
lastLogged.set(reason, now.getTime());
|
|
364
|
+
(deps.log ?? ((line) => console.error(line)))(`access: cloudflare: ${REASONS[reason]}`);
|
|
365
|
+
}
|
|
366
|
+
return { ok: false, ...refusalOf(reason) };
|
|
367
|
+
};
|
|
368
|
+
const identify = async (req, setting, now) => {
|
|
369
|
+
const token = assertionOf(req);
|
|
370
|
+
if (arrivalOf(req) !== 'ingress') {
|
|
371
|
+
// Only a request that claims something is worth a word in the log.
|
|
372
|
+
return token === undefined ? null : complain('not-through-the-tunnel', now);
|
|
373
|
+
}
|
|
374
|
+
if (!setting.enabled)
|
|
375
|
+
return complain('setting-off', now);
|
|
376
|
+
if (token === undefined)
|
|
377
|
+
return complain('no-assertion', now);
|
|
378
|
+
// An assertion presented that does not verify is a failed sign-in, counted
|
|
379
|
+
// per Cf-Connecting-Ip; keys that could not be fetched are not an answer.
|
|
380
|
+
const attempt = (raw) => ({ bucket: `cf:${connectingIp(req)}`, credential: createHash('sha256').update(`cf-assertion:${raw}`).digest('base64url') });
|
|
381
|
+
if (token === null) {
|
|
382
|
+
const raw = req.headers[CF_ASSERTION_HEADER];
|
|
383
|
+
return { ...complain('malformed', now), attempt: attempt(Array.isArray(raw) ? raw.join('\n') : String(raw)) };
|
|
384
|
+
}
|
|
385
|
+
const verified = await verifyAccessJwt(token, setting, { jwks: deps.jwks, now });
|
|
386
|
+
if (!verified.ok) {
|
|
387
|
+
const refused = complain(verified.reason, now);
|
|
388
|
+
return verified.reason === 'keys-unreachable' ? refused : { ...refused, attempt: attempt(token) };
|
|
389
|
+
}
|
|
390
|
+
visit = { at: now, email: verified.assertion.email };
|
|
391
|
+
return {
|
|
392
|
+
ok: true,
|
|
393
|
+
identity: {
|
|
394
|
+
provider: 'cloudflare-access',
|
|
395
|
+
subject: verified.assertion.email,
|
|
396
|
+
name: verified.assertion.email,
|
|
397
|
+
detail: { team: setting.teamDomain },
|
|
398
|
+
bucket: `cf:${connectingIp(req)}`,
|
|
399
|
+
expiresAt: verified.assertion.expiresAt,
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
return {
|
|
404
|
+
id: 'cloudflare-access',
|
|
405
|
+
title: 'Cloudflare Access',
|
|
406
|
+
identity: 'login',
|
|
407
|
+
proxy: 'this-machine',
|
|
408
|
+
arrival: 'ingress',
|
|
409
|
+
settingKey: CLOUDFLARE_SETTING_KEY,
|
|
410
|
+
absoluteCapMs: CLOUDFLARE_ABSOLUTE_CAP_MS,
|
|
411
|
+
parseSetting: toCloudflareSetting,
|
|
412
|
+
enabled: (setting) => setting.enabled,
|
|
413
|
+
allowed: (setting) => setting.email,
|
|
414
|
+
lastVisit: () => visit,
|
|
415
|
+
async status(setting) {
|
|
416
|
+
// Off is off, however much of the form is filled in: what is missing
|
|
417
|
+
// is the panel's neutral line until the owner tries to turn it on.
|
|
418
|
+
if (!setting.enabled)
|
|
419
|
+
return { state: 'off', sentence: 'Off. Your own domain, with Cloudflare’s sign-in in front of it.' };
|
|
420
|
+
const problem = deps.ingressProblem?.() ?? null;
|
|
421
|
+
if (problem)
|
|
422
|
+
return { state: 'needs-setup', sentence: problem };
|
|
423
|
+
if (deps.jwks.failing(setting.teamDomain)) {
|
|
424
|
+
return { state: 'unanswered', sentence: 'Cloudflare’s signing keys couldn’t be fetched just now. Visits wait until they can.' };
|
|
425
|
+
}
|
|
426
|
+
if (!visit)
|
|
427
|
+
return { state: 'waiting', sentence: 'Waiting for a first visit through Cloudflare.' };
|
|
428
|
+
const host = setting.publicOrigin ? new URL(setting.publicOrigin).host : setting.teamDomain;
|
|
429
|
+
return { state: 'ready', sentence: `Ready at ${host}, for ${setting.email}` };
|
|
430
|
+
},
|
|
431
|
+
setup(_setting, ctx) {
|
|
432
|
+
const port = ctx.ingressPort() ?? ctx.dashboardPort() + 2;
|
|
433
|
+
return {
|
|
434
|
+
steps: [
|
|
435
|
+
{ text: 'Install cloudflared on this computer. On Linux, use the .deb from Cloudflare or its package repository.', command: 'brew install cloudflared' },
|
|
436
|
+
{ text: 'In Cloudflare’s dashboard: Zero Trust → Networks → Tunnels → Create a tunnel. Run the cloudflared service install … line it shows.' },
|
|
437
|
+
{ text: 'Add a public hostname, like buddi.example.com, with this service. Not the dashboard’s port: everything on this one counts as a visit from elsewhere.', command: `http://127.0.0.1:${port}` },
|
|
438
|
+
{ text: 'Zero Trust → Access → Applications → Add a self-hosted application for that hostname. Policy: Allow, Include → Emails → your email.' },
|
|
439
|
+
{ text: 'Copy the team domain and the application’s AUD tag here.' },
|
|
440
|
+
],
|
|
441
|
+
fields: [
|
|
442
|
+
{ key: 'teamDomain', label: 'Team domain', placeholder: 'yourteam.cloudflareaccess.com' },
|
|
443
|
+
{ key: 'aud', label: 'Application AUD tag', placeholder: '64 letters and digits' },
|
|
444
|
+
{ key: 'email', label: 'Your email', hint: 'The one your Access policy allows.', placeholder: 'you@example.com' },
|
|
445
|
+
{ key: 'publicOrigin', label: 'Public address', hint: 'So cookies and the Origin check use it.', placeholder: 'https://buddi.example.com' },
|
|
446
|
+
],
|
|
447
|
+
};
|
|
448
|
+
},
|
|
449
|
+
// Everything on the ingress listener is this provider's: cloudflared
|
|
450
|
+
// points there, and nothing else does.
|
|
451
|
+
matches: (req) => arrivalOf(req) === 'ingress',
|
|
452
|
+
identify,
|
|
453
|
+
async confirm(session, req, setting, now) {
|
|
454
|
+
if (!setting.enabled)
|
|
455
|
+
return { answer: 'end', refusal: refusalOf('setting-off') };
|
|
456
|
+
if (!sameSubject(session.providerSubject, setting.email))
|
|
457
|
+
return { answer: 'end', refusal: refusalOf('email-not-allowed') };
|
|
458
|
+
const result = await identify(req, setting, now);
|
|
459
|
+
if (result?.ok) {
|
|
460
|
+
// The same email it was minted for, or the session goes.
|
|
461
|
+
return sameSubject(result.identity.subject, session.providerSubject) ? { answer: 'keep' } : { answer: 'end' };
|
|
462
|
+
}
|
|
463
|
+
if (result && result.kind === 'unanswered')
|
|
464
|
+
return { answer: 'unanswered', refusal: result };
|
|
465
|
+
if (result && result.kind === 'login')
|
|
466
|
+
return { answer: 'end', refusal: result };
|
|
467
|
+
// A missing or failed assertion ends this request, not the session: a
|
|
468
|
+
// stray request without the header cannot sign the owner out.
|
|
469
|
+
return { answer: 'refuse', refusal: result ?? refusalOf('no-assertion') };
|
|
470
|
+
},
|
|
471
|
+
clientKey: () => 'cf:unverified',
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
//# sourceMappingURL=cloudflare.js.map
|