@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.1
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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +20 -2
- package/bootstrap.json +26 -0
- package/dist/admin/admin.controller.d.ts +139 -0
- package/dist/admin/admin.controller.js +238 -0
- package/dist/admin/extensions.controller.d.ts +100 -0
- package/dist/admin/extensions.controller.js +226 -0
- package/dist/admin/setup.controller.d.ts +36 -0
- package/dist/admin/setup.controller.js +106 -0
- package/dist/admin/setup.service.d.ts +47 -0
- package/dist/admin/setup.service.js +90 -0
- package/dist/agents/agents.controller.d.ts +205 -0
- package/dist/agents/agents.controller.js +144 -0
- package/dist/agents/agents.service.d.ts +177 -0
- package/dist/agents/agents.service.js +677 -0
- package/dist/agents/definition.d.ts +198 -0
- package/dist/agents/definition.js +152 -0
- package/dist/agents/models.controller.d.ts +13 -0
- package/dist/agents/models.controller.js +31 -0
- package/dist/agents/templates.controller.d.ts +15 -0
- package/dist/agents/templates.controller.js +37 -0
- package/dist/agents/templates.d.ts +83 -0
- package/dist/agents/templates.js +173 -0
- package/dist/catalog/admin-catalog.controller.d.ts +143 -0
- package/dist/catalog/admin-catalog.controller.js +245 -0
- package/dist/catalog/catalog.service.d.ts +430 -0
- package/dist/catalog/catalog.service.js +882 -0
- package/dist/catalog/claude/agents.d.ts +27 -0
- package/dist/catalog/claude/agents.js +270 -0
- package/dist/catalog/claude/commands.d.ts +50 -0
- package/dist/catalog/claude/commands.js +179 -0
- package/dist/catalog/claude/manifest.d.ts +69 -0
- package/dist/catalog/claude/manifest.js +134 -0
- package/dist/catalog/claude/marketplace.d.ts +35 -0
- package/dist/catalog/claude/marketplace.js +194 -0
- package/dist/catalog/claude/mcp.d.ts +33 -0
- package/dist/catalog/claude/mcp.js +226 -0
- package/dist/catalog/claude/report.d.ts +86 -0
- package/dist/catalog/claude/report.js +121 -0
- package/dist/catalog/claude/translate.d.ts +56 -0
- package/dist/catalog/claude/translate.js +857 -0
- package/dist/catalog/cli.d.ts +46 -0
- package/dist/catalog/cli.js +211 -0
- package/dist/catalog/git-source.d.ts +127 -0
- package/dist/catalog/git-source.js +520 -0
- package/dist/catalog/marketplace-fetch.d.ts +99 -0
- package/dist/catalog/marketplace-fetch.js +203 -0
- package/dist/catalog/marketplaces.controller.d.ts +97 -0
- package/dist/catalog/marketplaces.controller.js +197 -0
- package/dist/catalog/marketplaces.service.d.ts +340 -0
- package/dist/catalog/marketplaces.service.js +1217 -0
- package/dist/catalog/org-catalog.controller.d.ts +128 -0
- package/dist/catalog/org-catalog.controller.js +277 -0
- package/dist/catalog/org-catalog.service.d.ts +246 -0
- package/dist/catalog/org-catalog.service.js +625 -0
- package/dist/catalog/plugin-import.d.ts +436 -0
- package/dist/catalog/plugin-import.js +1069 -0
- package/dist/catalog/plugin-install.d.ts +447 -0
- package/dist/catalog/plugin-install.js +1333 -0
- package/dist/catalog/plugin-package.d.ts +143 -0
- package/dist/catalog/plugin-package.js +382 -0
- package/dist/catalog/plugin-upgrade.d.ts +222 -0
- package/dist/catalog/plugin-upgrade.js +1219 -0
- package/dist/catalog/requests.service.d.ts +162 -0
- package/dist/catalog/requests.service.js +504 -0
- package/dist/catalog/schema-path.d.ts +7 -0
- package/dist/catalog/schema-path.js +63 -0
- package/dist/catalog/upgrade-targets.d.ts +59 -0
- package/dist/catalog/upgrade-targets.js +90 -0
- package/dist/catalog/versions.d.ts +31 -0
- package/dist/catalog/versions.js +44 -0
- package/dist/channels/actions.d.ts +37 -0
- package/dist/channels/actions.js +121 -0
- package/dist/channels/cards.d.ts +44 -0
- package/dist/channels/cards.js +156 -0
- package/dist/channels/connections.controller.d.ts +59 -0
- package/dist/channels/connections.controller.js +115 -0
- package/dist/channels/connections.service.d.ts +187 -0
- package/dist/channels/connections.service.js +534 -0
- package/dist/channels/features.d.ts +12 -0
- package/dist/channels/features.js +22 -0
- package/dist/channels/inbound.d.ts +120 -0
- package/dist/channels/inbound.js +332 -0
- package/dist/channels/outbound.d.ts +140 -0
- package/dist/channels/outbound.js +1126 -0
- package/dist/channels/phrases.d.ts +100 -0
- package/dist/channels/phrases.js +81 -0
- package/dist/channels/supervisor.d.ts +182 -0
- package/dist/channels/supervisor.js +625 -0
- package/dist/channels/threads.d.ts +29 -0
- package/dist/channels/threads.js +104 -0
- package/dist/channels/webhook-url.d.ts +16 -0
- package/dist/channels/webhook-url.js +34 -0
- package/dist/channels/webhook.controller.d.ts +19 -0
- package/dist/channels/webhook.controller.js +72 -0
- package/dist/channels/webhook.d.ts +73 -0
- package/dist/channels/webhook.js +274 -0
- package/dist/config/docs.d.ts +9 -0
- package/dist/config/docs.js +85 -0
- package/dist/config/env.d.ts +6 -0
- package/dist/config/env.js +73 -0
- package/dist/config/fields.d.ts +42 -0
- package/dist/config/fields.js +214 -0
- package/dist/config/file-source.d.ts +3 -0
- package/dist/config/file-source.js +31 -0
- package/dist/config/load.d.ts +20 -0
- package/dist/config/load.js +98 -0
- package/dist/config/nacos-source.d.ts +31 -0
- package/dist/config/nacos-source.js +229 -0
- package/dist/config/schema.d.ts +237 -0
- package/dist/config/schema.js +1192 -0
- package/dist/config/sources.d.ts +18 -0
- package/dist/config/sources.js +59 -0
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.js +7 -0
- package/dist/conversations/artifacts.d.ts +52 -0
- package/dist/conversations/artifacts.js +137 -0
- package/dist/conversations/attachments.controller.d.ts +28 -0
- package/dist/conversations/attachments.controller.js +96 -0
- package/dist/conversations/attachments.service.d.ts +180 -0
- package/dist/conversations/attachments.service.js +578 -0
- package/dist/conversations/conversations.controller.d.ts +288 -0
- package/dist/conversations/conversations.controller.js +607 -0
- package/dist/conversations/conversations.service.d.ts +321 -0
- package/dist/conversations/conversations.service.js +754 -0
- package/dist/conversations/event-log.d.ts +122 -0
- package/dist/conversations/event-log.js +259 -0
- package/dist/conversations/events.d.ts +856 -0
- package/dist/conversations/events.js +639 -0
- package/dist/conversations/files.d.ts +92 -0
- package/dist/conversations/files.js +213 -0
- package/dist/conversations/outputs-read.d.ts +34 -0
- package/dist/conversations/outputs-read.js +37 -0
- package/dist/conversations/queue.d.ts +169 -0
- package/dist/conversations/queue.js +527 -0
- package/dist/conversations/sandbox-status.d.ts +21 -0
- package/dist/conversations/sandbox-status.js +24 -0
- package/dist/conversations/selection.d.ts +46 -0
- package/dist/conversations/selection.js +75 -0
- package/dist/conversations/titles.d.ts +93 -0
- package/dist/conversations/titles.js +423 -0
- package/dist/ctx/bus.d.ts +16 -0
- package/dist/ctx/bus.js +101 -0
- package/dist/ctx/create-ctx.d.ts +109 -0
- package/dist/ctx/create-ctx.js +592 -0
- package/dist/ctx/kv.d.ts +4 -0
- package/dist/ctx/kv.js +31 -0
- package/dist/ctx/lock.d.ts +4 -0
- package/dist/ctx/lock.js +39 -0
- package/dist/ctx/namespace.d.ts +6 -0
- package/dist/ctx/namespace.js +12 -0
- package/dist/ctx/queue.d.ts +25 -0
- package/dist/ctx/queue.js +151 -0
- package/dist/ctx/secrets.d.ts +45 -0
- package/dist/ctx/secrets.js +175 -0
- package/dist/db/kernel-schema.d.ts +1122 -0
- package/dist/db/kernel-schema.js +5 -0
- package/dist/db/migrator.d.ts +28 -0
- package/dist/db/migrator.js +140 -0
- package/dist/db/pool.d.ts +21 -0
- package/dist/db/pool.js +28 -0
- package/dist/db/sql-statements.d.ts +34 -0
- package/dist/db/sql-statements.js +168 -0
- package/dist/errors.d.ts +211 -0
- package/dist/errors.js +213 -0
- package/dist/evals/budget.d.ts +61 -0
- package/dist/evals/budget.js +181 -0
- package/dist/evals/diff.d.ts +55 -0
- package/dist/evals/diff.js +133 -0
- package/dist/evals/judge.d.ts +53 -0
- package/dist/evals/judge.js +149 -0
- package/dist/evals/plan.d.ts +47 -0
- package/dist/evals/plan.js +77 -0
- package/dist/evals/reconstruct.d.ts +137 -0
- package/dist/evals/reconstruct.js +322 -0
- package/dist/evals/recorded-tools.d.ts +54 -0
- package/dist/evals/recorded-tools.js +167 -0
- package/dist/evals/run-replay.d.ts +86 -0
- package/dist/evals/run-replay.js +502 -0
- package/dist/evals/runs.controller.d.ts +100 -0
- package/dist/evals/runs.controller.js +199 -0
- package/dist/evals/runs.service.d.ts +275 -0
- package/dist/evals/runs.service.js +836 -0
- package/dist/evals/sets.controller.d.ts +61 -0
- package/dist/evals/sets.controller.js +183 -0
- package/dist/evals/sets.service.d.ts +128 -0
- package/dist/evals/sets.service.js +558 -0
- package/dist/evals/snapshot.d.ts +76 -0
- package/dist/evals/snapshot.js +207 -0
- package/dist/evals/step-replay.d.ts +113 -0
- package/dist/evals/step-replay.js +181 -0
- package/dist/evals/trajectory.controller.d.ts +41 -0
- package/dist/evals/trajectory.controller.js +88 -0
- package/dist/evals/trajectory.d.ts +144 -0
- package/dist/evals/trajectory.js +338 -0
- package/dist/evals/trajectory.service.d.ts +108 -0
- package/dist/evals/trajectory.service.js +323 -0
- package/dist/evals/worker.d.ts +101 -0
- package/dist/evals/worker.js +790 -0
- package/dist/extensions/admin-ops.d.ts +105 -0
- package/dist/extensions/admin-ops.js +353 -0
- package/dist/extensions/admin-view.d.ts +79 -0
- package/dist/extensions/admin-view.js +327 -0
- package/dist/extensions/approvals.d.ts +119 -0
- package/dist/extensions/approvals.js +205 -0
- package/dist/extensions/blobs.d.ts +45 -0
- package/dist/extensions/blobs.js +160 -0
- package/dist/extensions/bootstrap.d.ts +176 -0
- package/dist/extensions/bootstrap.js +535 -0
- package/dist/extensions/cli.d.ts +61 -0
- package/dist/extensions/cli.js +165 -0
- package/dist/extensions/config-json-schema.d.ts +9 -0
- package/dist/extensions/config-json-schema.js +73 -0
- package/dist/extensions/deployment-config.d.ts +138 -0
- package/dist/extensions/deployment-config.js +394 -0
- package/dist/extensions/enabled.d.ts +31 -0
- package/dist/extensions/enabled.js +55 -0
- package/dist/extensions/hooks.d.ts +161 -0
- package/dist/extensions/hooks.js +425 -0
- package/dist/extensions/host.d.ts +577 -0
- package/dist/extensions/host.js +2071 -0
- package/dist/extensions/inflight.d.ts +69 -0
- package/dist/extensions/inflight.js +277 -0
- package/dist/extensions/installs.d.ts +166 -0
- package/dist/extensions/installs.js +253 -0
- package/dist/extensions/instance.d.ts +167 -0
- package/dist/extensions/instance.js +329 -0
- package/dist/extensions/ledger.d.ts +30 -0
- package/dist/extensions/ledger.js +50 -0
- package/dist/extensions/lifecycle.d.ts +80 -0
- package/dist/extensions/lifecycle.js +152 -0
- package/dist/extensions/migrate-lock.d.ts +51 -0
- package/dist/extensions/migrate-lock.js +100 -0
- package/dist/extensions/org-config.controller.d.ts +24 -0
- package/dist/extensions/org-config.controller.js +59 -0
- package/dist/extensions/org-config.d.ts +169 -0
- package/dist/extensions/org-config.js +520 -0
- package/dist/extensions/package.d.ts +115 -0
- package/dist/extensions/package.js +246 -0
- package/dist/extensions/permission-set.d.ts +117 -0
- package/dist/extensions/permission-set.js +184 -0
- package/dist/extensions/permission-view.d.ts +194 -0
- package/dist/extensions/permission-view.js +284 -0
- package/dist/extensions/registry.d.ts +24 -0
- package/dist/extensions/registry.js +56 -0
- package/dist/extensions/resolve.d.ts +12 -0
- package/dist/extensions/resolve.js +71 -0
- package/dist/extensions/sources.d.ts +69 -0
- package/dist/extensions/sources.js +120 -0
- package/dist/extensions/sync.d.ts +40 -0
- package/dist/extensions/sync.js +242 -0
- package/dist/files/previewers.controller.d.ts +46 -0
- package/dist/files/previewers.controller.js +105 -0
- package/dist/files/previewers.d.ts +100 -0
- package/dist/files/previewers.js +250 -0
- package/dist/http/api.module.d.ts +114 -0
- package/dist/http/api.module.js +448 -0
- package/dist/http/app.d.ts +77 -0
- package/dist/http/app.js +220 -0
- package/dist/http/error.filter.d.ts +21 -0
- package/dist/http/error.filter.js +85 -0
- package/dist/http/gateway.module.d.ts +15 -0
- package/dist/http/gateway.module.js +13 -0
- package/dist/http/health.controller.d.ts +26 -0
- package/dist/http/health.controller.js +79 -0
- package/dist/http/nest-logger.d.ts +20 -0
- package/dist/http/nest-logger.js +28 -0
- package/dist/http/plugin-dispatch.d.ts +68 -0
- package/dist/http/plugin-dispatch.js +200 -0
- package/dist/http/tokens.d.ts +131 -0
- package/dist/http/tokens.js +131 -0
- package/dist/http/zod.pipe.d.ts +8 -0
- package/dist/http/zod.pipe.js +14 -0
- package/dist/identity/accounts.d.ts +93 -0
- package/dist/identity/accounts.js +367 -0
- package/dist/identity/api-tokens.d.ts +73 -0
- package/dist/identity/api-tokens.js +197 -0
- package/dist/identity/audit.d.ts +23 -0
- package/dist/identity/audit.js +41 -0
- package/dist/identity/auth.controller.d.ts +40 -0
- package/dist/identity/auth.controller.js +130 -0
- package/dist/identity/auth.guard.d.ts +41 -0
- package/dist/identity/auth.guard.js +162 -0
- package/dist/identity/binding.d.ts +47 -0
- package/dist/identity/binding.js +84 -0
- package/dist/identity/cookies.d.ts +16 -0
- package/dist/identity/cookies.js +32 -0
- package/dist/identity/credential-check.d.ts +17 -0
- package/dist/identity/credential-check.js +24 -0
- package/dist/identity/enterprise-admin.d.ts +14 -0
- package/dist/identity/enterprise-admin.js +27 -0
- package/dist/identity/external.d.ts +106 -0
- package/dist/identity/external.js +337 -0
- package/dist/identity/hash.d.ts +2 -0
- package/dist/identity/hash.js +3 -0
- package/dist/identity/login.d.ts +6 -0
- package/dist/identity/login.js +20 -0
- package/dist/identity/me.controller.d.ts +61 -0
- package/dist/identity/me.controller.js +159 -0
- package/dist/identity/passwords.d.ts +6 -0
- package/dist/identity/passwords.js +37 -0
- package/dist/identity/principal.d.ts +56 -0
- package/dist/identity/principal.js +38 -0
- package/dist/identity/rate-limit.d.ts +55 -0
- package/dist/identity/rate-limit.js +121 -0
- package/dist/identity/sessions.d.ts +84 -0
- package/dist/identity/sessions.js +306 -0
- package/dist/identity/settings.d.ts +121 -0
- package/dist/identity/settings.js +248 -0
- package/dist/identity/sso.controller.d.ts +59 -0
- package/dist/identity/sso.controller.js +192 -0
- package/dist/identity/sso.d.ts +83 -0
- package/dist/identity/sso.js +202 -0
- package/dist/inbox/inbox.service.d.ts +43 -0
- package/dist/inbox/inbox.service.js +57 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +67 -0
- package/dist/kernel.d.ts +259 -0
- package/dist/kernel.js +1326 -0
- package/dist/log-config.d.ts +9 -0
- package/dist/log-config.js +27 -0
- package/dist/log-context.d.ts +32 -0
- package/dist/log-context.js +40 -0
- package/dist/log-loki.d.ts +34 -0
- package/dist/log-loki.js +145 -0
- package/dist/log.d.ts +79 -0
- package/dist/log.js +303 -0
- package/dist/models/prices.d.ts +53 -0
- package/dist/models/prices.js +121 -0
- package/dist/models/purposes.controller.d.ts +19 -0
- package/dist/models/purposes.controller.js +56 -0
- package/dist/models/purposes.d.ts +140 -0
- package/dist/models/purposes.js +267 -0
- package/dist/net/proxy.d.ts +44 -0
- package/dist/net/proxy.js +162 -0
- package/dist/net/public-address.d.ts +60 -0
- package/dist/net/public-address.js +272 -0
- package/dist/net/safe-fetch.d.ts +38 -0
- package/dist/net/safe-fetch.js +140 -0
- package/dist/orgs/directory-sync.controller.d.ts +14 -0
- package/dist/orgs/directory-sync.controller.js +40 -0
- package/dist/orgs/directory-sync.d.ts +166 -0
- package/dist/orgs/directory-sync.js +558 -0
- package/dist/orgs/invitations.controller.d.ts +58 -0
- package/dist/orgs/invitations.controller.js +137 -0
- package/dist/orgs/invitations.service.d.ts +80 -0
- package/dist/orgs/invitations.service.js +217 -0
- package/dist/orgs/members.service.d.ts +63 -0
- package/dist/orgs/members.service.js +234 -0
- package/dist/orgs/offboarding.d.ts +141 -0
- package/dist/orgs/offboarding.js +398 -0
- package/dist/orgs/org-lock.d.ts +32 -0
- package/dist/orgs/org-lock.js +46 -0
- package/dist/orgs/org.guard.d.ts +35 -0
- package/dist/orgs/org.guard.js +95 -0
- package/dist/orgs/orgs.controller.d.ts +78 -0
- package/dist/orgs/orgs.controller.js +192 -0
- package/dist/orgs/orgs.service.d.ts +61 -0
- package/dist/orgs/orgs.service.js +209 -0
- package/dist/orgs/roles.d.ts +13 -0
- package/dist/orgs/roles.js +58 -0
- package/dist/orgs/settings.controller.d.ts +20 -0
- package/dist/orgs/settings.controller.js +53 -0
- package/dist/orgs/settings.service.d.ts +120 -0
- package/dist/orgs/settings.service.js +178 -0
- package/dist/packages/npm.d.ts +50 -0
- package/dist/packages/npm.js +218 -0
- package/dist/packages/provenance.d.ts +47 -0
- package/dist/packages/provenance.js +147 -0
- package/dist/packages/tgz.d.ts +76 -0
- package/dist/packages/tgz.js +225 -0
- package/dist/runtime/abort.d.ts +32 -0
- package/dist/runtime/abort.js +71 -0
- package/dist/runtime/checkpointer.d.ts +32 -0
- package/dist/runtime/checkpointer.js +243 -0
- package/dist/runtime/context/build.d.ts +254 -0
- package/dist/runtime/context/build.js +693 -0
- package/dist/runtime/context/claude-tools.d.ts +11 -0
- package/dist/runtime/context/claude-tools.js +24 -0
- package/dist/runtime/context/compaction.d.ts +26 -0
- package/dist/runtime/context/compaction.js +195 -0
- package/dist/runtime/context/pairing.d.ts +11 -0
- package/dist/runtime/context/pairing.js +82 -0
- package/dist/runtime/context/reminders.d.ts +5 -0
- package/dist/runtime/context/reminders.js +11 -0
- package/dist/runtime/context/skills.d.ts +105 -0
- package/dist/runtime/context/skills.js +283 -0
- package/dist/runtime/context/tokens.d.ts +19 -0
- package/dist/runtime/context/tokens.js +104 -0
- package/dist/runtime/conversation-lock.d.ts +40 -0
- package/dist/runtime/conversation-lock.js +97 -0
- package/dist/runtime/hook-calls.d.ts +84 -0
- package/dist/runtime/hook-calls.js +136 -0
- package/dist/runtime/langgraph-loop.d.ts +52 -0
- package/dist/runtime/langgraph-loop.js +247 -0
- package/dist/runtime/loop.d.ts +93 -0
- package/dist/runtime/loop.js +7 -0
- package/dist/runtime/maintenance.d.ts +80 -0
- package/dist/runtime/maintenance.js +148 -0
- package/dist/runtime/media-cache.d.ts +21 -0
- package/dist/runtime/media-cache.js +51 -0
- package/dist/runtime/model-call.d.ts +176 -0
- package/dist/runtime/model-call.js +1049 -0
- package/dist/runtime/providers.d.ts +86 -0
- package/dist/runtime/providers.js +224 -0
- package/dist/runtime/quota.d.ts +29 -0
- package/dist/runtime/quota.js +70 -0
- package/dist/runtime/run-finish.d.ts +45 -0
- package/dist/runtime/run-finish.js +69 -0
- package/dist/runtime/run-queue.d.ts +121 -0
- package/dist/runtime/run-queue.js +493 -0
- package/dist/runtime/run-worker.d.ts +138 -0
- package/dist/runtime/run-worker.js +806 -0
- package/dist/runtime/stream.controller.d.ts +34 -0
- package/dist/runtime/stream.controller.js +122 -0
- package/dist/runtime/stream.d.ts +63 -0
- package/dist/runtime/stream.js +262 -0
- package/dist/runtime/subagents/child.d.ts +80 -0
- package/dist/runtime/subagents/child.js +225 -0
- package/dist/runtime/subagents/definition.d.ts +103 -0
- package/dist/runtime/subagents/definition.js +392 -0
- package/dist/runtime/subagents/dispatch.d.ts +69 -0
- package/dist/runtime/subagents/dispatch.js +502 -0
- package/dist/runtime/subagents/limits.d.ts +23 -0
- package/dist/runtime/subagents/limits.js +34 -0
- package/dist/runtime/subagents/org-agents.d.ts +50 -0
- package/dist/runtime/subagents/org-agents.js +70 -0
- package/dist/runtime/subagents/preamble.d.ts +7 -0
- package/dist/runtime/subagents/preamble.js +11 -0
- package/dist/runtime/subagents/progress.d.ts +26 -0
- package/dist/runtime/subagents/progress.js +36 -0
- package/dist/runtime/subagents/roster.d.ts +55 -0
- package/dist/runtime/subagents/roster.js +111 -0
- package/dist/runtime/subagents/skill-fork.d.ts +123 -0
- package/dist/runtime/subagents/skill-fork.js +259 -0
- package/dist/runtime/usage-report.d.ts +163 -0
- package/dist/runtime/usage-report.js +551 -0
- package/dist/runtime/waits.d.ts +233 -0
- package/dist/runtime/waits.js +883 -0
- package/dist/sandbox/leases.d.ts +169 -0
- package/dist/sandbox/leases.js +515 -0
- package/dist/sandbox/lifecycle.d.ts +21 -0
- package/dist/sandbox/lifecycle.js +68 -0
- package/dist/sandbox/sandbox.service.d.ts +249 -0
- package/dist/sandbox/sandbox.service.js +908 -0
- package/dist/skills/catalog.d.ts +149 -0
- package/dist/skills/catalog.js +405 -0
- package/dist/skills/changes.controller.d.ts +56 -0
- package/dist/skills/changes.controller.js +136 -0
- package/dist/skills/changes.service.d.ts +175 -0
- package/dist/skills/changes.service.js +805 -0
- package/dist/skills/invocable.controller.d.ts +23 -0
- package/dist/skills/invocable.controller.js +50 -0
- package/dist/skills/invocation-keys.d.ts +23 -0
- package/dist/skills/invocation-keys.js +44 -0
- package/dist/skills/invoke.d.ts +135 -0
- package/dist/skills/invoke.js +286 -0
- package/dist/skills/package.d.ts +87 -0
- package/dist/skills/package.js +227 -0
- package/dist/skills/skills.controller.d.ts +40 -0
- package/dist/skills/skills.controller.js +110 -0
- package/dist/skills/skills.service.d.ts +192 -0
- package/dist/skills/skills.service.js +567 -0
- package/dist/storage/prefix.d.ts +36 -0
- package/dist/storage/prefix.js +104 -0
- package/dist/storage/purge.d.ts +27 -0
- package/dist/storage/purge.js +75 -0
- package/dist/storage/storage.service.d.ts +44 -0
- package/dist/storage/storage.service.js +145 -0
- package/dist/text.d.ts +13 -0
- package/dist/text.js +13 -0
- package/dist/tools/approvals.controller.d.ts +53 -0
- package/dist/tools/approvals.controller.js +128 -0
- package/dist/tools/approvals.service.d.ts +172 -0
- package/dist/tools/approvals.service.js +568 -0
- package/dist/tools/breaker.d.ts +28 -0
- package/dist/tools/breaker.js +72 -0
- package/dist/tools/builtins/agent.d.ts +81 -0
- package/dist/tools/builtins/agent.js +223 -0
- package/dist/tools/builtins/ask-user.d.ts +28 -0
- package/dist/tools/builtins/ask-user.js +139 -0
- package/dist/tools/builtins/read-tool-output.d.ts +18 -0
- package/dist/tools/builtins/read-tool-output.js +108 -0
- package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
- package/dist/tools/builtins/sandbox/bash.js +137 -0
- package/dist/tools/builtins/sandbox/common.d.ts +116 -0
- package/dist/tools/builtins/sandbox/common.js +306 -0
- package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
- package/dist/tools/builtins/sandbox/deliver.js +180 -0
- package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
- package/dist/tools/builtins/sandbox/edit.js +98 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
- package/dist/tools/builtins/sandbox/glob-match.js +240 -0
- package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
- package/dist/tools/builtins/sandbox/glob.js +104 -0
- package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
- package/dist/tools/builtins/sandbox/grep.js +133 -0
- package/dist/tools/builtins/sandbox/index.d.ts +12 -0
- package/dist/tools/builtins/sandbox/index.js +27 -0
- package/dist/tools/builtins/sandbox/names.d.ts +7 -0
- package/dist/tools/builtins/sandbox/names.js +20 -0
- package/dist/tools/builtins/sandbox/read.d.ts +8 -0
- package/dist/tools/builtins/sandbox/read.js +121 -0
- package/dist/tools/builtins/sandbox/write.d.ts +4 -0
- package/dist/tools/builtins/sandbox/write.js +88 -0
- package/dist/tools/builtins/skill-load.d.ts +53 -0
- package/dist/tools/builtins/skill-load.js +446 -0
- package/dist/tools/builtins/skill-write.d.ts +59 -0
- package/dist/tools/builtins/skill-write.js +244 -0
- package/dist/tools/builtins/tool-search.d.ts +31 -0
- package/dist/tools/builtins/tool-search.js +171 -0
- package/dist/tools/connector-content.controller.d.ts +34 -0
- package/dist/tools/connector-content.controller.js +78 -0
- package/dist/tools/connector-content.d.ts +104 -0
- package/dist/tools/connector-content.js +267 -0
- package/dist/tools/connectors.controller.d.ts +210 -0
- package/dist/tools/connectors.controller.js +234 -0
- package/dist/tools/connectors.service.d.ts +303 -0
- package/dist/tools/connectors.service.js +1102 -0
- package/dist/tools/credentials.d.ts +139 -0
- package/dist/tools/credentials.js +351 -0
- package/dist/tools/drift.d.ts +141 -0
- package/dist/tools/drift.js +539 -0
- package/dist/tools/elicitation.d.ts +81 -0
- package/dist/tools/elicitation.js +266 -0
- package/dist/tools/endpoint.d.ts +18 -0
- package/dist/tools/endpoint.js +115 -0
- package/dist/tools/info.d.ts +67 -0
- package/dist/tools/info.js +113 -0
- package/dist/tools/naming.d.ts +27 -0
- package/dist/tools/naming.js +47 -0
- package/dist/tools/oauth/discovery.d.ts +65 -0
- package/dist/tools/oauth/discovery.js +307 -0
- package/dist/tools/oauth/flow.d.ts +63 -0
- package/dist/tools/oauth/flow.js +237 -0
- package/dist/tools/oauth/oauth.controller.d.ts +31 -0
- package/dist/tools/oauth/oauth.controller.js +95 -0
- package/dist/tools/oauth/tokens.d.ts +111 -0
- package/dist/tools/oauth/tokens.js +258 -0
- package/dist/tools/outputs.d.ts +61 -0
- package/dist/tools/outputs.js +156 -0
- package/dist/tools/pipeline.d.ts +322 -0
- package/dist/tools/pipeline.js +1236 -0
- package/dist/tools/policy.d.ts +60 -0
- package/dist/tools/policy.js +236 -0
- package/dist/tools/questions.controller.d.ts +24 -0
- package/dist/tools/questions.controller.js +58 -0
- package/dist/tools/questions.service.d.ts +103 -0
- package/dist/tools/questions.service.js +295 -0
- package/dist/tools/redact.d.ts +20 -0
- package/dist/tools/redact.js +60 -0
- package/dist/tools/registry.d.ts +246 -0
- package/dist/tools/registry.js +481 -0
- package/dist/tools/resources.d.ts +16 -0
- package/dist/tools/resources.js +76 -0
- package/dist/tools/specs.d.ts +14 -0
- package/dist/tools/specs.js +31 -0
- package/dist/tools/validate.d.ts +20 -0
- package/dist/tools/validate.js +183 -0
- package/dist/tools/view.d.ts +43 -0
- package/dist/tools/view.js +225 -0
- package/dist/ui/embed-token.d.ts +31 -0
- package/dist/ui/embed-token.js +132 -0
- package/dist/ui/registry.d.ts +58 -0
- package/dist/ui/registry.js +90 -0
- package/dist/ui/ui-stream.d.ts +37 -0
- package/dist/ui/ui-stream.js +162 -0
- package/dist/ui/views.controller.d.ts +81 -0
- package/dist/ui/views.controller.js +261 -0
- package/dist/ui/views.d.ts +155 -0
- package/dist/ui/views.js +306 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +6 -0
- package/package.json +69 -3
- package/src/migrations/0001_init.sql +8 -0
- package/src/migrations/0002_secrets.sql +8 -0
- package/src/migrations/0003_identity.sql +117 -0
- package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
- package/src/migrations/0005_agents.sql +27 -0
- package/src/migrations/0006_conversations.sql +37 -0
- package/src/migrations/0007_checkpoints.sql +26 -0
- package/src/migrations/0008_runs_trigger_seq.sql +3 -0
- package/src/migrations/0009_runs_active_unique.sql +4 -0
- package/src/migrations/0010_tools.sql +125 -0
- package/src/migrations/0011_approvals_spec.sql +10 -0
- package/src/migrations/0012_run_waits.sql +24 -0
- package/src/migrations/0013_app_tools_source.sql +4 -0
- package/src/migrations/0014_tool_specs.sql +8 -0
- package/src/migrations/0015_tool_drift.sql +20 -0
- package/src/migrations/0016_plugin_permissions.sql +11 -0
- package/src/migrations/0017_identity_sources.sql +6 -0
- package/src/migrations/0018_channels.sql +74 -0
- package/src/migrations/0019_identity_trust.sql +17 -0
- package/src/migrations/0020_channel_card_lookup.sql +10 -0
- package/src/migrations/0021_org_storage_purge.sql +9 -0
- package/src/migrations/0022_attachments.sql +29 -0
- package/src/migrations/0023_sandboxes.sql +37 -0
- package/src/migrations/0024_skills.sql +46 -0
- package/src/migrations/0025_skills_catalog_idx.sql +6 -0
- package/src/migrations/0026_skill_changes.sql +34 -0
- package/src/migrations/0027_model_prices.sql +18 -0
- package/src/migrations/0028_evals.sql +105 -0
- package/src/migrations/0029_model_purposes.sql +18 -0
- package/src/migrations/0030_plugin_installs.sql +73 -0
- package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
- package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
- package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
- package/src/migrations/0034_directory.sql +49 -0
- package/src/migrations/0035_catalogs.sql +40 -0
- package/src/migrations/0036_app_import_staging.sql +17 -0
- package/src/migrations/0037_directory_installs.sql +92 -0
- package/src/migrations/0038_channel_inbound_mode.sql +6 -0
- package/src/migrations/0039_channel_card_pending.sql +8 -0
- package/src/migrations/0040_usage_report_sweep.sql +10 -0
- package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
- package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
- package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
- package/src/migrations/0044_catalog_one_kind.sql +90 -0
- package/src/migrations/0045_plugin_dependencies.sql +9 -0
- package/src/migrations/0046_git_sources.sql +25 -0
- package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
- package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
- package/src/migrations/0049_plugin_upgrades.sql +37 -0
- package/src/migrations/0050_bootstrap.sql +53 -0
- package/src/migrations/0051_claude_compat.sql +26 -0
- package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
- package/src/migrations/0053_subagents.sql +73 -0
- package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
- package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
- package/src/migrations/0056_approval_reason.sql +3 -0
- package/src/migrations/0057_conversation_titles.sql +11 -0
- package/src/migrations/0058_conversation_selection.sql +4 -0
- package/src/migrations/0059_conversation_queue.sql +22 -0
- package/src/migrations/0060_file_previewers.sql +10 -0
- package/src/migrations/0061_queue_selection.sql +5 -0
- package/src/migrations/0062_queued_skill.sql +8 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { sql } from "kysely";
|
|
2
|
+
import { ApiError } from "../errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* 在调用方事务内取 `capybara.enterprise_admins` 咨询锁(事务结束释放),串行化所有企业管理员写操作
|
|
5
|
+
* (撤销 / 停用 / 新建管理员 / 改部署设置 / CLI 的 `capybara admin grant|revoke`)。只加锁、不鉴权:
|
|
6
|
+
* 没有发起账号的调用方(CLI)用它;有发起账号的用 {@link lockEnterpriseAdminsAndAuthorize}。
|
|
7
|
+
*/
|
|
8
|
+
export async function lockEnterpriseAdmins(trx) {
|
|
9
|
+
await sql `SELECT pg_advisory_xact_lock(hashtext('capybara.enterprise_admins'))`.execute(trx);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 企业管理员写操作的执行期复核(spec 3.6 R5):{@link lockEnterpriseAdmins} 后在锁内实时确认发起人仍是
|
|
13
|
+
* 活跃企业管理员,否则 `forbidden`。鉴权守卫在请求开头读到的身份可能已过期(另一个管理员刚撤销了他),
|
|
14
|
+
* 必须在锁内重读。
|
|
15
|
+
*/
|
|
16
|
+
export async function lockEnterpriseAdminsAndAuthorize(trx, actorAccountId) {
|
|
17
|
+
await lockEnterpriseAdmins(trx);
|
|
18
|
+
const actor = await trx
|
|
19
|
+
.selectFrom("accounts")
|
|
20
|
+
.select("id")
|
|
21
|
+
.where("id", "=", actorAccountId)
|
|
22
|
+
.where("is_enterprise_admin", "=", true)
|
|
23
|
+
.where("status", "=", "active")
|
|
24
|
+
.executeTakeFirst();
|
|
25
|
+
if (!actor)
|
|
26
|
+
throw new ApiError("forbidden", "Enterprise admin required");
|
|
27
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ExternalIdentity } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { type Transaction } from "kysely";
|
|
3
|
+
import type { KernelConfig } from "../config/schema.js";
|
|
4
|
+
import type { KernelDatabase, KernelDb, LinkedVia } from "../db/kernel-schema.js";
|
|
5
|
+
type Trx = Transaction<KernelDatabase>;
|
|
6
|
+
export type { LinkedVia };
|
|
7
|
+
/**
|
|
8
|
+
* 第三方登录拒绝了这个身份(Ruling A18):身份行经 IM 绑定链接建立,而请求没有带着同一账号的会话。
|
|
9
|
+
* 登录页原因码 `sso.identity_not_verified`。
|
|
10
|
+
*/
|
|
11
|
+
export declare class IdentityNotVerified extends Error {
|
|
12
|
+
constructor();
|
|
13
|
+
}
|
|
14
|
+
/** {@link ExternalIdentities.resolve} 的选项。 */
|
|
15
|
+
export interface ResolveOptions {
|
|
16
|
+
/** 只有第三方登录路径传 true(Ruling A9)。 */
|
|
17
|
+
allowMerge?: boolean;
|
|
18
|
+
/** 新建身份行时记下的建立方式:第三方登录 `sso`,通讯录同步 `directory`。已有的行不改。 */
|
|
19
|
+
linkedVia: "sso" | "directory";
|
|
20
|
+
/**
|
|
21
|
+
* 第三方登录路径:已有的身份行须可用于登录(见 {@link ExternalIdentities.resolve})。
|
|
22
|
+
* `sessionAccountId` 为请求已带着的 Web 会话的账号(没有会话时省略)。
|
|
23
|
+
*/
|
|
24
|
+
login?: {
|
|
25
|
+
sessionAccountId?: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** 账号已绑定的一个外部身份(不含本地登录名)。 */
|
|
29
|
+
export interface LinkedIdentity {
|
|
30
|
+
source: string;
|
|
31
|
+
externalId: string;
|
|
32
|
+
email: string | null;
|
|
33
|
+
emailVerified: boolean;
|
|
34
|
+
displayName: string | null;
|
|
35
|
+
avatarUrl: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* 身份行是怎么建立的(Ruling A18):`bind` 只能在 IM 里代表本人,要用于第三方登录须本人登录后完成一次该身份的
|
|
38
|
+
* 第三方登录(网页据此显示「验证」);null 为 0019 之前的旧行(按 sso 处理)。
|
|
39
|
+
*/
|
|
40
|
+
linkedVia: "bind" | "sso" | "directory" | "local" | null;
|
|
41
|
+
createdAt: Date;
|
|
42
|
+
}
|
|
43
|
+
/** 身份源键里的插件名(`source` 中 `:` 之前的部分)。 */
|
|
44
|
+
export declare function identityPlugin(source: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* 外部身份:按 `(source, externalId)` 映射到账号(登录、渠道入站、通讯录共用同一个键)。
|
|
47
|
+
* 首次出现时按「受信任的身份源 + 两侧邮箱均已验证」合并到既有账号,否则新建账号(不建组织)。
|
|
48
|
+
* 同一身份的并发首次解析用事务级咨询锁串行化,只建一个账号。框架无关,由调用方注入依赖。
|
|
49
|
+
*/
|
|
50
|
+
export declare class ExternalIdentities {
|
|
51
|
+
private readonly db;
|
|
52
|
+
private readonly config;
|
|
53
|
+
constructor(db: KernelDb, config: () => {
|
|
54
|
+
auth: Pick<KernelConfig["auth"], "trustedIdentitySources">;
|
|
55
|
+
});
|
|
56
|
+
/** 该外部身份绑定的账号 id;未绑定返回 undefined。 */
|
|
57
|
+
findAccount(source: string, externalId: string, trx?: Trx): Promise<string | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* 解析外部身份到账号。已绑定 → 该账号(顺带刷新身份行上的邮箱与资料);未绑定 → 合并或新建(见类说明),
|
|
60
|
+
* 新身份行记 `linked_via = opts.linkedVia`(合并也是 `sso`)。
|
|
61
|
+
* 合并只在 `opts.allowMerge` 时考虑(Ruling A9:只有第三方登录路径传 true;渠道入站、通讯录不传)。
|
|
62
|
+
* 第三方登录(`opts.login`,Ruling A18 / A23):已有的身份行若经 IM 绑定建立(`bind`),只证明了某个网页登录者
|
|
63
|
+
* 点过绑定链接,不证明他控制该外部身份——此时只有请求已带着**同一账号**的会话(本人在已登录状态下完成第三方登录,
|
|
64
|
+
* 证明自己控制该身份)才放行,并把行升级为 `sso`(审计 `identity.verified`);否则抛 {@link IdentityNotVerified}。
|
|
65
|
+
* 通讯录建立的行(`directory`)不论租户是否受信任都可直接登录:身份源登录本身就证明登录者控制该身份,
|
|
66
|
+
* 而通讯录身份总是指向为它新建的账号(信任只影响合并与 `email_verified`)。旧行(`linked_via` 为 null)按 `sso` 处理。
|
|
67
|
+
* 新建账号的 `email_verified` 只在身份源受信任且身份邮箱已验证时为 true——不受信任的身份源可以声称任意邮箱
|
|
68
|
+
* 「已验证」,不能让它建出的账号成为日后受信任登录的合并目标。
|
|
69
|
+
* 合并写审计 `identity.linked`,新建写 `account.created`。不判断账号状态,由调用方决定(如登录拒绝停用账号)。
|
|
70
|
+
* 传 `trx` 时在调用方事务内执行;与 `link` 取同一把咨询锁,兜底用 `ON CONFLICT DO NOTHING` 后回读,
|
|
71
|
+
* 不抛唯一约束冲突、不中止调用方事务。
|
|
72
|
+
*/
|
|
73
|
+
resolve(identity: ExternalIdentity, trx: Trx | undefined, opts: ResolveOptions): Promise<{
|
|
74
|
+
accountId: string;
|
|
75
|
+
created: boolean;
|
|
76
|
+
}>;
|
|
77
|
+
/** 同一身份的 resolve / link 串行化(事务级咨询锁)。 */
|
|
78
|
+
private lockIdentity;
|
|
79
|
+
/** 身份源键(`<插件名>:<租户 id>`)是否在 `auth.trustedIdentitySources` 中:按完整键比较,信任按租户(Ruling A19)。 */
|
|
80
|
+
private trusted;
|
|
81
|
+
private findRow;
|
|
82
|
+
/** 第三方登录能否用这一行(见 {@link resolve}):只有 `bind` 行需要同一账号的会话,放行时把行改为 `sso`。 */
|
|
83
|
+
private allowLogin;
|
|
84
|
+
private mustFind;
|
|
85
|
+
private refreshIdentity;
|
|
86
|
+
/**
|
|
87
|
+
* 可合并的既有账号:身份源键在 `auth.trustedIdentitySources` 中、身份邮箱已验证,
|
|
88
|
+
* 且恰好有一个邮箱已验证、邮箱相同(不区分大小写)的账号;否则 undefined(多个候选时不猜,新建)。
|
|
89
|
+
*/
|
|
90
|
+
private mergeTarget;
|
|
91
|
+
/** 插入身份行;已存在(主键冲突)时什么都不做并返回 false。 */
|
|
92
|
+
private insertIdentity;
|
|
93
|
+
/**
|
|
94
|
+
* 把外部身份绑定到账号(IM 里点绑定链接等):已绑定本人 → 刷新资料,幂等(不改 `linked_via`);
|
|
95
|
+
* 已绑定他人 → `409 identity.taken`。新行记 `linked_via = bind`:这样绑定的身份只能在 IM 里代表此人,
|
|
96
|
+
* 不能直接用于第三方登录(Ruling A18)。与 `resolve` 取同一把咨询锁。新绑定写审计 `identity.linked`。
|
|
97
|
+
*/
|
|
98
|
+
link(accountId: string, identity: ExternalIdentity, trx?: Trx): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* 解除本人的一个外部身份(本地登录名不可解除);不存在或不属于本人 → `identity.not_found`;
|
|
101
|
+
* 账号没有本地密码且这是最后一个外部身份 → `409 identity.last_login_method`。审计 `identity.unlinked`。
|
|
102
|
+
*/
|
|
103
|
+
unlink(accountId: string, source: string, externalId: string): Promise<void>;
|
|
104
|
+
/** 账号绑定的外部身份(不含本地登录名),按绑定时间升序。 */
|
|
105
|
+
listForAccount(accountId: string): Promise<LinkedIdentity[]>;
|
|
106
|
+
}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
import { ApiError } from "../errors.js";
|
|
4
|
+
import { audit } from "./audit.js";
|
|
5
|
+
/** `<插件名>:<租户 id>`;插件名同清单规则,租户 id 为非空、不含空白的串。 */
|
|
6
|
+
const SOURCE_RE = /^([a-z0-9][a-z0-9._-]{0,213}):(\S{1,256})$/;
|
|
7
|
+
const MAX_EXTERNAL_ID = 256;
|
|
8
|
+
const MAX_DISPLAY_NAME = 200;
|
|
9
|
+
const MAX_EMAIL = 320;
|
|
10
|
+
/**
|
|
11
|
+
* 第三方登录拒绝了这个身份(Ruling A18):身份行经 IM 绑定链接建立,而请求没有带着同一账号的会话。
|
|
12
|
+
* 登录页原因码 `sso.identity_not_verified`。
|
|
13
|
+
*/
|
|
14
|
+
export class IdentityNotVerified extends Error {
|
|
15
|
+
constructor() {
|
|
16
|
+
super("external identity is not verified for sign-in");
|
|
17
|
+
this.name = "IdentityNotVerified";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** 身份源键里的插件名(`source` 中 `:` 之前的部分)。 */
|
|
21
|
+
export function identityPlugin(source) {
|
|
22
|
+
const i = source.indexOf(":");
|
|
23
|
+
return i < 0 ? source : source.slice(0, i);
|
|
24
|
+
}
|
|
25
|
+
const invalid = (message) => new ApiError("validation_failed", "Invalid external identity", [{ path: "identity", message }]);
|
|
26
|
+
/** 校验插件交来的外部身份(键的格式、长度),返回规范化后的副本。 */
|
|
27
|
+
function normalize(identity) {
|
|
28
|
+
const m = SOURCE_RE.exec(identity.source);
|
|
29
|
+
if (!m || m[1] === "local") {
|
|
30
|
+
throw invalid('source must be "<plugin>:<tenant>"');
|
|
31
|
+
}
|
|
32
|
+
// 身份源键的租户必须就是身份的租户(Ruling A19):信任按租户判断,不能让键与租户各说各的
|
|
33
|
+
if (identity.tenantId !== m[2]) {
|
|
34
|
+
throw invalid("source tenant must equal tenantId");
|
|
35
|
+
}
|
|
36
|
+
if (typeof identity.externalId !== "string" ||
|
|
37
|
+
identity.externalId.length === 0 ||
|
|
38
|
+
identity.externalId.length > MAX_EXTERNAL_ID) {
|
|
39
|
+
throw invalid(`externalId must be 1-${MAX_EXTERNAL_ID} characters`);
|
|
40
|
+
}
|
|
41
|
+
const email = typeof identity.email === "string" && identity.email.length > 0
|
|
42
|
+
? identity.email.trim().slice(0, MAX_EMAIL)
|
|
43
|
+
: undefined;
|
|
44
|
+
const displayName = (typeof identity.displayName === "string" ? identity.displayName.trim() : "").slice(0, MAX_DISPLAY_NAME) || identity.externalId.slice(0, MAX_DISPLAY_NAME);
|
|
45
|
+
return {
|
|
46
|
+
source: identity.source,
|
|
47
|
+
externalId: identity.externalId,
|
|
48
|
+
tenantId: identity.tenantId,
|
|
49
|
+
...(email !== undefined && { email }),
|
|
50
|
+
emailVerified: email !== undefined && identity.emailVerified === true,
|
|
51
|
+
displayName,
|
|
52
|
+
...(typeof identity.avatarUrl === "string" && { avatarUrl: identity.avatarUrl.slice(0, 2000) }),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const profileOf = (i) => JSON.stringify({
|
|
56
|
+
tenantId: i.tenantId,
|
|
57
|
+
displayName: i.displayName,
|
|
58
|
+
...(i.avatarUrl !== undefined && { avatarUrl: i.avatarUrl }),
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* 外部身份:按 `(source, externalId)` 映射到账号(登录、渠道入站、通讯录共用同一个键)。
|
|
62
|
+
* 首次出现时按「受信任的身份源 + 两侧邮箱均已验证」合并到既有账号,否则新建账号(不建组织)。
|
|
63
|
+
* 同一身份的并发首次解析用事务级咨询锁串行化,只建一个账号。框架无关,由调用方注入依赖。
|
|
64
|
+
*/
|
|
65
|
+
export class ExternalIdentities {
|
|
66
|
+
db;
|
|
67
|
+
config;
|
|
68
|
+
constructor(db, config) {
|
|
69
|
+
this.db = db;
|
|
70
|
+
this.config = config;
|
|
71
|
+
}
|
|
72
|
+
/** 该外部身份绑定的账号 id;未绑定返回 undefined。 */
|
|
73
|
+
async findAccount(source, externalId, trx) {
|
|
74
|
+
const row = await (trx ?? this.db)
|
|
75
|
+
.selectFrom("identities")
|
|
76
|
+
.select("account_id")
|
|
77
|
+
.where("source", "=", source)
|
|
78
|
+
.where("external_id", "=", externalId)
|
|
79
|
+
.executeTakeFirst();
|
|
80
|
+
return row?.account_id;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 解析外部身份到账号。已绑定 → 该账号(顺带刷新身份行上的邮箱与资料);未绑定 → 合并或新建(见类说明),
|
|
84
|
+
* 新身份行记 `linked_via = opts.linkedVia`(合并也是 `sso`)。
|
|
85
|
+
* 合并只在 `opts.allowMerge` 时考虑(Ruling A9:只有第三方登录路径传 true;渠道入站、通讯录不传)。
|
|
86
|
+
* 第三方登录(`opts.login`,Ruling A18 / A23):已有的身份行若经 IM 绑定建立(`bind`),只证明了某个网页登录者
|
|
87
|
+
* 点过绑定链接,不证明他控制该外部身份——此时只有请求已带着**同一账号**的会话(本人在已登录状态下完成第三方登录,
|
|
88
|
+
* 证明自己控制该身份)才放行,并把行升级为 `sso`(审计 `identity.verified`);否则抛 {@link IdentityNotVerified}。
|
|
89
|
+
* 通讯录建立的行(`directory`)不论租户是否受信任都可直接登录:身份源登录本身就证明登录者控制该身份,
|
|
90
|
+
* 而通讯录身份总是指向为它新建的账号(信任只影响合并与 `email_verified`)。旧行(`linked_via` 为 null)按 `sso` 处理。
|
|
91
|
+
* 新建账号的 `email_verified` 只在身份源受信任且身份邮箱已验证时为 true——不受信任的身份源可以声称任意邮箱
|
|
92
|
+
* 「已验证」,不能让它建出的账号成为日后受信任登录的合并目标。
|
|
93
|
+
* 合并写审计 `identity.linked`,新建写 `account.created`。不判断账号状态,由调用方决定(如登录拒绝停用账号)。
|
|
94
|
+
* 传 `trx` 时在调用方事务内执行;与 `link` 取同一把咨询锁,兜底用 `ON CONFLICT DO NOTHING` 后回读,
|
|
95
|
+
* 不抛唯一约束冲突、不中止调用方事务。
|
|
96
|
+
*/
|
|
97
|
+
async resolve(identity, trx, opts) {
|
|
98
|
+
const id = normalize(identity);
|
|
99
|
+
const run = async (t) => {
|
|
100
|
+
await this.lockIdentity(t, id);
|
|
101
|
+
const existing = await this.findRow(t, id);
|
|
102
|
+
if (existing !== undefined) {
|
|
103
|
+
if (opts.login !== undefined)
|
|
104
|
+
await this.allowLogin(t, id, existing, opts.login);
|
|
105
|
+
await this.refreshIdentity(t, id);
|
|
106
|
+
return { accountId: existing.accountId, created: false };
|
|
107
|
+
}
|
|
108
|
+
const merged = opts.allowMerge === true ? await this.mergeTarget(t, id) : undefined;
|
|
109
|
+
if (merged !== undefined) {
|
|
110
|
+
if (!(await this.insertIdentity(t, merged, id, "sso"))) {
|
|
111
|
+
return { accountId: await this.mustFind(t, id), created: false };
|
|
112
|
+
}
|
|
113
|
+
await audit(t, {
|
|
114
|
+
actorAccountId: merged,
|
|
115
|
+
action: "identity.linked",
|
|
116
|
+
target: merged,
|
|
117
|
+
detail: { source: id.source, externalId: id.externalId, via: "verified_email" },
|
|
118
|
+
});
|
|
119
|
+
return { accountId: merged, created: false };
|
|
120
|
+
}
|
|
121
|
+
const accountId = randomUUID();
|
|
122
|
+
await t
|
|
123
|
+
.insertInto("accounts")
|
|
124
|
+
.values({
|
|
125
|
+
id: accountId,
|
|
126
|
+
display_name: id.displayName,
|
|
127
|
+
email: id.email ?? null,
|
|
128
|
+
email_verified: id.emailVerified && this.trusted(id.source),
|
|
129
|
+
})
|
|
130
|
+
.execute();
|
|
131
|
+
if (!(await this.insertIdentity(t, accountId, id, opts.linkedVia))) {
|
|
132
|
+
// 不走咨询锁的写入方抢先插入了同一身份:撤销刚建的账号,回读
|
|
133
|
+
await t.deleteFrom("accounts").where("id", "=", accountId).execute();
|
|
134
|
+
return { accountId: await this.mustFind(t, id), created: false };
|
|
135
|
+
}
|
|
136
|
+
await audit(t, {
|
|
137
|
+
actorAccountId: accountId,
|
|
138
|
+
action: "account.created",
|
|
139
|
+
target: accountId,
|
|
140
|
+
detail: { source: id.source, externalId: id.externalId },
|
|
141
|
+
});
|
|
142
|
+
return { accountId, created: true };
|
|
143
|
+
};
|
|
144
|
+
return trx ? run(trx) : this.db.transaction().execute(run);
|
|
145
|
+
}
|
|
146
|
+
/** 同一身份的 resolve / link 串行化(事务级咨询锁)。 */
|
|
147
|
+
async lockIdentity(t, id) {
|
|
148
|
+
await sql `SELECT pg_advisory_xact_lock(hashtext(${`capybara.identity:${id.source}:${id.externalId}`}))`.execute(t);
|
|
149
|
+
}
|
|
150
|
+
/** 身份源键(`<插件名>:<租户 id>`)是否在 `auth.trustedIdentitySources` 中:按完整键比较,信任按租户(Ruling A19)。 */
|
|
151
|
+
trusted(source) {
|
|
152
|
+
return this.config().auth.trustedIdentitySources.includes(source);
|
|
153
|
+
}
|
|
154
|
+
async findRow(t, id) {
|
|
155
|
+
const row = await t
|
|
156
|
+
.selectFrom("identities")
|
|
157
|
+
.select(["account_id", "linked_via"])
|
|
158
|
+
.where("source", "=", id.source)
|
|
159
|
+
.where("external_id", "=", id.externalId)
|
|
160
|
+
.executeTakeFirst();
|
|
161
|
+
return row && { accountId: row.account_id, linkedVia: row.linked_via };
|
|
162
|
+
}
|
|
163
|
+
/** 第三方登录能否用这一行(见 {@link resolve}):只有 `bind` 行需要同一账号的会话,放行时把行改为 `sso`。 */
|
|
164
|
+
async allowLogin(t, id, row, login) {
|
|
165
|
+
const via = row.linkedVia ?? "sso";
|
|
166
|
+
if (via !== "bind")
|
|
167
|
+
return;
|
|
168
|
+
if (login.sessionAccountId !== row.accountId)
|
|
169
|
+
throw new IdentityNotVerified();
|
|
170
|
+
await t
|
|
171
|
+
.updateTable("identities")
|
|
172
|
+
.set({ linked_via: "sso" })
|
|
173
|
+
.where("source", "=", id.source)
|
|
174
|
+
.where("external_id", "=", id.externalId)
|
|
175
|
+
.execute();
|
|
176
|
+
await audit(t, {
|
|
177
|
+
actorAccountId: row.accountId,
|
|
178
|
+
action: "identity.verified",
|
|
179
|
+
target: row.accountId,
|
|
180
|
+
detail: { source: id.source, externalId: id.externalId, from: via },
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async mustFind(t, id) {
|
|
184
|
+
const owner = await this.findAccount(id.source, id.externalId, t);
|
|
185
|
+
if (owner === undefined)
|
|
186
|
+
throw new Error("identity vanished after a conflicting insert");
|
|
187
|
+
return owner;
|
|
188
|
+
}
|
|
189
|
+
async refreshIdentity(t, id) {
|
|
190
|
+
await t
|
|
191
|
+
.updateTable("identities")
|
|
192
|
+
.set({ email: id.email ?? null, email_verified: id.emailVerified, profile: profileOf(id) })
|
|
193
|
+
.where("source", "=", id.source)
|
|
194
|
+
.where("external_id", "=", id.externalId)
|
|
195
|
+
.execute();
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 可合并的既有账号:身份源键在 `auth.trustedIdentitySources` 中、身份邮箱已验证,
|
|
199
|
+
* 且恰好有一个邮箱已验证、邮箱相同(不区分大小写)的账号;否则 undefined(多个候选时不猜,新建)。
|
|
200
|
+
*/
|
|
201
|
+
async mergeTarget(t, id) {
|
|
202
|
+
if (!id.emailVerified || id.email === undefined || !this.trusted(id.source))
|
|
203
|
+
return undefined;
|
|
204
|
+
const rows = await t
|
|
205
|
+
.selectFrom("accounts")
|
|
206
|
+
.select("id")
|
|
207
|
+
.where("email_verified", "=", true)
|
|
208
|
+
.where(sql `lower(email)`, "=", id.email.toLowerCase())
|
|
209
|
+
.limit(2)
|
|
210
|
+
.execute();
|
|
211
|
+
return rows.length === 1 ? rows[0]?.id : undefined;
|
|
212
|
+
}
|
|
213
|
+
/** 插入身份行;已存在(主键冲突)时什么都不做并返回 false。 */
|
|
214
|
+
async insertIdentity(t, accountId, id, linkedVia) {
|
|
215
|
+
const row = await t
|
|
216
|
+
.insertInto("identities")
|
|
217
|
+
.values({
|
|
218
|
+
source: id.source,
|
|
219
|
+
external_id: id.externalId,
|
|
220
|
+
account_id: accountId,
|
|
221
|
+
email: id.email ?? null,
|
|
222
|
+
email_verified: id.emailVerified,
|
|
223
|
+
profile: profileOf(id),
|
|
224
|
+
linked_via: linkedVia,
|
|
225
|
+
})
|
|
226
|
+
.onConflict((oc) => oc.columns(["source", "external_id"]).doNothing())
|
|
227
|
+
.returning("account_id")
|
|
228
|
+
.executeTakeFirst();
|
|
229
|
+
return row !== undefined;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 把外部身份绑定到账号(IM 里点绑定链接等):已绑定本人 → 刷新资料,幂等(不改 `linked_via`);
|
|
233
|
+
* 已绑定他人 → `409 identity.taken`。新行记 `linked_via = bind`:这样绑定的身份只能在 IM 里代表此人,
|
|
234
|
+
* 不能直接用于第三方登录(Ruling A18)。与 `resolve` 取同一把咨询锁。新绑定写审计 `identity.linked`。
|
|
235
|
+
*/
|
|
236
|
+
async link(accountId, identity, trx) {
|
|
237
|
+
const id = normalize(identity);
|
|
238
|
+
const run = async (t) => {
|
|
239
|
+
await this.lockIdentity(t, id);
|
|
240
|
+
const owner = await this.findAccount(id.source, id.externalId, t);
|
|
241
|
+
if (owner !== undefined && owner !== accountId)
|
|
242
|
+
throw taken();
|
|
243
|
+
if (owner === accountId) {
|
|
244
|
+
await this.refreshIdentity(t, id);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!(await this.insertIdentity(t, accountId, id, "bind"))) {
|
|
248
|
+
if ((await this.mustFind(t, id)) !== accountId)
|
|
249
|
+
throw taken();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
await audit(t, {
|
|
253
|
+
actorAccountId: accountId,
|
|
254
|
+
action: "identity.linked",
|
|
255
|
+
target: accountId,
|
|
256
|
+
detail: { source: id.source, externalId: id.externalId, via: "bind" },
|
|
257
|
+
});
|
|
258
|
+
};
|
|
259
|
+
return trx ? run(trx) : this.db.transaction().execute(run);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* 解除本人的一个外部身份(本地登录名不可解除);不存在或不属于本人 → `identity.not_found`;
|
|
263
|
+
* 账号没有本地密码且这是最后一个外部身份 → `409 identity.last_login_method`。审计 `identity.unlinked`。
|
|
264
|
+
*/
|
|
265
|
+
async unlink(accountId, source, externalId) {
|
|
266
|
+
if (source === "local")
|
|
267
|
+
throw notFound();
|
|
268
|
+
await this.db.transaction().execute(async (t) => {
|
|
269
|
+
const r = await t
|
|
270
|
+
.deleteFrom("identities")
|
|
271
|
+
.where("source", "=", source)
|
|
272
|
+
.where("external_id", "=", externalId)
|
|
273
|
+
.where("account_id", "=", accountId)
|
|
274
|
+
.executeTakeFirst();
|
|
275
|
+
if (r.numDeletedRows === 0n)
|
|
276
|
+
throw notFound();
|
|
277
|
+
// 没有本地密码时至少还要剩一个外部身份,否则此人再也登录不了(锁账号行,串行化并发解除)
|
|
278
|
+
await t.selectFrom("accounts").select("id").where("id", "=", accountId).forUpdate().execute();
|
|
279
|
+
const password = await t
|
|
280
|
+
.selectFrom("local_passwords")
|
|
281
|
+
.select("account_id")
|
|
282
|
+
.where("account_id", "=", accountId)
|
|
283
|
+
.executeTakeFirst();
|
|
284
|
+
const others = await t
|
|
285
|
+
.selectFrom("identities")
|
|
286
|
+
.select("source")
|
|
287
|
+
.where("account_id", "=", accountId)
|
|
288
|
+
.where("source", "!=", "local")
|
|
289
|
+
.limit(1)
|
|
290
|
+
.execute();
|
|
291
|
+
if (!password && others.length === 0) {
|
|
292
|
+
throw new ApiError("identity.last_login_method", "Cannot unlink the last sign-in method of an account without a password");
|
|
293
|
+
}
|
|
294
|
+
await audit(t, {
|
|
295
|
+
actorAccountId: accountId,
|
|
296
|
+
action: "identity.unlinked",
|
|
297
|
+
target: accountId,
|
|
298
|
+
detail: { source, externalId },
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
/** 账号绑定的外部身份(不含本地登录名),按绑定时间升序。 */
|
|
303
|
+
async listForAccount(accountId) {
|
|
304
|
+
const rows = await this.db
|
|
305
|
+
.selectFrom("identities")
|
|
306
|
+
.select([
|
|
307
|
+
"source",
|
|
308
|
+
"external_id",
|
|
309
|
+
"email",
|
|
310
|
+
"email_verified",
|
|
311
|
+
"profile",
|
|
312
|
+
"linked_via",
|
|
313
|
+
"created_at",
|
|
314
|
+
])
|
|
315
|
+
.where("account_id", "=", accountId)
|
|
316
|
+
.where("source", "!=", "local")
|
|
317
|
+
.orderBy("created_at")
|
|
318
|
+
.orderBy("source")
|
|
319
|
+
.orderBy("external_id")
|
|
320
|
+
.execute();
|
|
321
|
+
return rows.map((r) => {
|
|
322
|
+
const p = (r.profile ?? {});
|
|
323
|
+
return {
|
|
324
|
+
source: r.source,
|
|
325
|
+
externalId: r.external_id,
|
|
326
|
+
email: r.email,
|
|
327
|
+
emailVerified: r.email_verified,
|
|
328
|
+
displayName: typeof p.displayName === "string" ? p.displayName : null,
|
|
329
|
+
avatarUrl: typeof p.avatarUrl === "string" ? p.avatarUrl : null,
|
|
330
|
+
linkedVia: r.linked_via,
|
|
331
|
+
createdAt: r.created_at,
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const taken = () => new ApiError("identity.taken", "This external identity is already linked to another account");
|
|
337
|
+
const notFound = () => new ApiError("identity.not_found", "External identity not found");
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** 规范化登录名(NFKC、去空白、转小写)并校验格式;身份的外部 ID 就是它。 */
|
|
2
|
+
export declare function normalizeLogin(raw: string): string;
|
|
3
|
+
/** 密码长度上限(防止 scrypt 被超长输入拖慢)。 */
|
|
4
|
+
export declare const MAX_PASSWORD_LENGTH = 256;
|
|
5
|
+
/** 密码长度 12–256。 */
|
|
6
|
+
export declare function validatePassword(p: string): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ApiError } from "../errors.js";
|
|
2
|
+
const LOGIN_RE = /^[a-z0-9][a-z0-9._@+-]{2,63}$/;
|
|
3
|
+
/** 规范化登录名(NFKC、去空白、转小写)并校验格式;身份的外部 ID 就是它。 */
|
|
4
|
+
export function normalizeLogin(raw) {
|
|
5
|
+
const login = raw.normalize("NFKC").trim().toLowerCase();
|
|
6
|
+
if (!LOGIN_RE.test(login)) {
|
|
7
|
+
throw new ApiError("validation_failed", "Login must be 3-64 characters: letters, digits, . _ @ + -", [{ path: "login", message: "invalid login format" }]);
|
|
8
|
+
}
|
|
9
|
+
return login;
|
|
10
|
+
}
|
|
11
|
+
/** 密码长度上限(防止 scrypt 被超长输入拖慢)。 */
|
|
12
|
+
export const MAX_PASSWORD_LENGTH = 256;
|
|
13
|
+
/** 密码长度 12–256。 */
|
|
14
|
+
export function validatePassword(p) {
|
|
15
|
+
if (p.length < 12 || p.length > MAX_PASSWORD_LENGTH) {
|
|
16
|
+
throw new ApiError("validation_failed", "Password must be 12-256 characters", [
|
|
17
|
+
{ path: "password", message: "length must be between 12 and 256" },
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Logger } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import type { OrgsService } from "../orgs/orgs.service.js";
|
|
5
|
+
import type { OrgRole } from "../orgs/roles.js";
|
|
6
|
+
import type { Account, AccountsService } from "./accounts.js";
|
|
7
|
+
import { type ApiTokenRecord, type ApiTokenService } from "./api-tokens.js";
|
|
8
|
+
import { type Principal } from "./principal.js";
|
|
9
|
+
import type { LoginRateLimiter } from "./rate-limit.js";
|
|
10
|
+
import type { SessionService } from "./sessions.js";
|
|
11
|
+
declare const ChangePasswordBody: z.ZodObject<{
|
|
12
|
+
currentPassword: z.ZodString;
|
|
13
|
+
newPassword: z.ZodString;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
declare const TokenBody: z.ZodObject<{
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
expiresAt: z.ZodOptional<z.ZodPipe<z.ZodISODateTime, z.ZodTransform<Date, string>>>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
declare const CurrentOrgBody: z.ZodObject<{
|
|
20
|
+
orgId: z.ZodNullable<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
type MembershipView = {
|
|
23
|
+
orgId: string;
|
|
24
|
+
slug: string;
|
|
25
|
+
name: string;
|
|
26
|
+
role: OrgRole;
|
|
27
|
+
};
|
|
28
|
+
/** 当前用户(`/api/v1/me`)。 */
|
|
29
|
+
export declare class MeController {
|
|
30
|
+
private readonly accounts;
|
|
31
|
+
private readonly sessions;
|
|
32
|
+
private readonly orgs;
|
|
33
|
+
private readonly tokens;
|
|
34
|
+
private readonly limiter;
|
|
35
|
+
private readonly log;
|
|
36
|
+
constructor(accounts: AccountsService, sessions: SessionService, orgs: OrgsService, tokens: ApiTokenService, limiter: LoginRateLimiter, log: Logger);
|
|
37
|
+
me(principal: Principal): Promise<{
|
|
38
|
+
account: Account;
|
|
39
|
+
via: "session" | "pat";
|
|
40
|
+
currentOrgId: string | null;
|
|
41
|
+
memberships: MembershipView[];
|
|
42
|
+
}>;
|
|
43
|
+
/** 切换当前组织(仅 Web 会话);`null` 清空。非成员或已软删除的组织 → `org.not_found`。 */
|
|
44
|
+
setCurrentOrg(principal: Principal, body: z.infer<typeof CurrentOrgBody>): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* 改密码:核对旧密码;成功后吊销该账号除当前会话外的所有会话,并吊销其全部个人访问令牌(R24)——
|
|
47
|
+
* 三者在同一个 PG 事务里生效,之后再尽力写 Redis 吊销标记。
|
|
48
|
+
* 核对前先占用限流额度(scope `acct`:按账号 id 10 次、按客户端 IP 50 次,与登录的 IP 额度分开),
|
|
49
|
+
* 防止拿到会话的人无限次猜旧密码;超限 → 429 `auth.rate_limited`,核对成功后清零账号计数。
|
|
50
|
+
*/
|
|
51
|
+
changePassword(principal: Principal, body: z.infer<typeof ChangePasswordBody>, req: FastifyRequest, reply: FastifyReply): Promise<void>;
|
|
52
|
+
createToken(principal: Principal, body: z.infer<typeof TokenBody>): Promise<{
|
|
53
|
+
token: string;
|
|
54
|
+
record: ApiTokenRecord;
|
|
55
|
+
}>;
|
|
56
|
+
listTokens(principal: Principal): Promise<{
|
|
57
|
+
tokens: ApiTokenRecord[];
|
|
58
|
+
}>;
|
|
59
|
+
revokeToken(principal: Principal, tokenId: string): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
export {};
|