@capybara-hq/kernel 0.1.0-rc.6 → 0.1.0-rc.8
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/bootstrap.json +27 -3
- package/dist/admin/admin.controller.d.ts +8 -72
- package/dist/admin/admin.controller.js +21 -46
- package/dist/admin/admin.schemas.d.ts +57 -0
- package/dist/admin/admin.schemas.js +50 -0
- package/dist/admin/extensions.controller.d.ts +10 -0
- package/dist/admin/extensions.controller.js +18 -0
- package/dist/admin/extensions.schemas.d.ts +7 -0
- package/dist/admin/extensions.schemas.js +10 -0
- package/dist/admin/limit-defaults.d.ts +20 -0
- package/dist/admin/limit-defaults.js +10 -0
- package/dist/agents/agent-profile.service.d.ts +7 -5
- package/dist/agents/agent-profile.service.js +14 -9
- package/dist/agents/agents.controller.d.ts +7 -287
- package/dist/agents/agents.controller.js +7 -67
- package/dist/agents/agents.schemas.d.ts +389 -0
- package/dist/agents/agents.schemas.js +126 -0
- package/dist/agents/agents.service.d.ts +13 -5
- package/dist/agents/agents.service.js +67 -13
- package/dist/agents/definition.d.ts +47 -19
- package/dist/agents/definition.js +119 -38
- package/dist/agents/from-template.d.ts +2 -2
- package/dist/agents/from-template.js +76 -45
- package/dist/agents/from-template.service.d.ts +12 -0
- package/dist/agents/from-template.service.js +20 -3
- package/dist/agents/models.controller.d.ts +1 -2
- package/dist/agents/models.controller.js +1 -1
- package/dist/agents/org-templates.d.ts +13 -3
- package/dist/agents/org-templates.js +69 -28
- package/dist/agents/pending-connector-requests.d.ts +2 -0
- package/dist/agents/pending-connector-requests.js +1 -1
- package/dist/agents/pending-connectors.controller.d.ts +1 -1
- package/dist/agents/pending-connectors.controller.js +2 -2
- package/dist/agents/pending-connectors.service.d.ts +2 -2
- package/dist/agents/pending-connectors.service.js +19 -19
- package/dist/agents/profile.d.ts +18 -0
- package/dist/agents/profile.js +5 -1
- package/dist/agents/templates.controller.d.ts +8 -17
- package/dist/agents/templates.controller.js +13 -31
- package/dist/agents/templates.schemas.d.ts +20 -0
- package/dist/agents/templates.schemas.js +45 -0
- package/dist/background/background.controller.js +3 -2
- package/dist/background/background.schemas.d.ts +10 -0
- package/dist/background/background.schemas.js +16 -0
- package/dist/background/tasks.service.d.ts +1 -1
- package/dist/background/tasks.service.js +7 -2
- package/dist/catalog/admin-catalog.controller.d.ts +4 -57
- package/dist/catalog/admin-catalog.controller.js +8 -45
- package/dist/catalog/admin-catalog.schemas.d.ts +72 -0
- package/dist/catalog/admin-catalog.schemas.js +92 -0
- package/dist/catalog/catalog-content.d.ts +12 -2
- package/dist/catalog/catalog-scope.service.js +8 -2
- package/dist/catalog/catalog.service.d.ts +2 -0
- package/dist/catalog/catalog.service.js +3 -0
- package/dist/catalog/component-scope.controller.d.ts +3 -65
- package/dist/catalog/component-scope.controller.js +3 -56
- package/dist/catalog/component-scope.schemas.d.ts +114 -0
- package/dist/catalog/component-scope.schemas.js +97 -0
- package/dist/catalog/component-scope.service.d.ts +28 -4
- package/dist/catalog/component-scope.service.js +55 -3
- package/dist/catalog/component-state.d.ts +9 -2
- package/dist/catalog/component-state.js +22 -13
- package/dist/catalog/marketplaces.controller.d.ts +5 -35
- package/dist/catalog/marketplaces.controller.js +6 -34
- package/dist/catalog/marketplaces.schemas.d.ts +48 -0
- package/dist/catalog/marketplaces.schemas.js +53 -0
- package/dist/catalog/marketplaces.service.d.ts +15 -1
- package/dist/catalog/marketplaces.service.js +22 -1
- package/dist/catalog/org-catalog.controller.d.ts +6 -62
- package/dist/catalog/org-catalog.controller.js +12 -66
- package/dist/catalog/org-catalog.schemas.d.ts +79 -0
- package/dist/catalog/org-catalog.schemas.js +82 -0
- package/dist/catalog/org-catalog.service.d.ts +9 -2
- package/dist/catalog/org-catalog.service.js +38 -5
- package/dist/catalog/org-extension.controller.d.ts +1 -12
- package/dist/catalog/org-extension.controller.js +1 -10
- package/dist/catalog/org-extension.schemas.d.ts +15 -0
- package/dist/catalog/org-extension.schemas.js +22 -0
- package/dist/catalog/org-plugin-uploads.controller.d.ts +2 -19
- package/dist/catalog/org-plugin-uploads.controller.js +15 -28
- package/dist/catalog/org-plugin-uploads.schemas.d.ts +20 -0
- package/dist/catalog/org-plugin-uploads.schemas.js +32 -0
- package/dist/catalog/owned-items.d.ts +6 -2
- package/dist/catalog/owned-items.js +16 -4
- package/dist/catalog/platform-components.d.ts +2 -0
- package/dist/catalog/platform-components.js +2 -0
- package/dist/catalog/plugin-import.js +1 -0
- package/dist/catalog/plugin-install.js +1 -1
- package/dist/catalog/requests.service.d.ts +2 -1
- package/dist/catalog/requests.service.js +6 -2
- package/dist/channels/channels.schemas.d.ts +33 -0
- package/dist/channels/channels.schemas.js +34 -0
- package/dist/channels/connections.controller.d.ts +2 -29
- package/dist/channels/connections.controller.js +1 -23
- package/dist/channels/connections.service.d.ts +8 -2
- package/dist/channels/connections.service.js +23 -5
- package/dist/channels/inbound.js +4 -0
- package/dist/conversations/conversations.controller.d.ts +16 -37
- package/dist/conversations/conversations.controller.js +16 -56
- package/dist/conversations/conversations.schemas.d.ts +52 -0
- package/dist/conversations/conversations.schemas.js +79 -0
- package/dist/conversations/conversations.service.d.ts +9 -1
- package/dist/conversations/conversations.service.js +23 -18
- package/dist/conversations/events.d.ts +80 -6
- package/dist/conversations/events.js +60 -5
- package/dist/conversations/message-context.d.ts +28 -0
- package/dist/conversations/message-context.js +56 -0
- package/dist/conversations/queue.d.ts +2 -1
- package/dist/conversations/queue.js +11 -2
- package/dist/db/kernel-schema.d.ts +20 -0
- package/dist/environments/environments.schemas.d.ts +3 -0
- package/dist/environments/environments.schemas.js +14 -0
- package/dist/environments/environments.service.d.ts +16 -4
- package/dist/environments/environments.service.js +58 -13
- package/dist/errors.d.ts +3 -0
- package/dist/errors.js +3 -0
- package/dist/evals/evals.schemas.d.ts +110 -0
- package/dist/evals/evals.schemas.js +107 -0
- package/dist/evals/reconstruct.js +18 -11
- package/dist/evals/recorded-tools.d.ts +2 -1
- package/dist/evals/recorded-tools.js +11 -3
- package/dist/evals/run-replay.d.ts +8 -1
- package/dist/evals/run-replay.js +13 -0
- package/dist/evals/runs.controller.d.ts +2 -57
- package/dist/evals/runs.controller.js +1 -42
- package/dist/evals/runs.service.d.ts +6 -6
- package/dist/evals/runs.service.js +32 -18
- package/dist/evals/sets.controller.d.ts +2 -28
- package/dist/evals/sets.controller.js +1 -31
- package/dist/evals/sets.service.d.ts +7 -7
- package/dist/evals/sets.service.js +23 -17
- package/dist/evals/snapshot.d.ts +3 -2
- package/dist/evals/snapshot.js +17 -4
- package/dist/extensions/admin-ops.d.ts +5 -3
- package/dist/extensions/admin-ops.js +17 -12
- package/dist/extensions/deployment-config.d.ts +16 -1
- package/dist/extensions/deployment-config.js +83 -0
- package/dist/extensions/extensions.module.js +3 -0
- package/dist/extensions/host.d.ts +33 -2
- package/dist/extensions/host.js +107 -1
- package/dist/extensions/installs.d.ts +5 -0
- package/dist/extensions/installs.js +12 -0
- package/dist/extensions/org-config.d.ts +17 -2
- package/dist/extensions/org-config.js +23 -4
- package/dist/extensions/point-defaults.controller.d.ts +2 -8
- package/dist/extensions/point-defaults.controller.js +1 -3
- package/dist/extensions/point-defaults.d.ts +3 -1
- package/dist/extensions/point-defaults.js +4 -2
- package/dist/extensions/point-defaults.schemas.d.ts +9 -0
- package/dist/extensions/point-defaults.schemas.js +14 -0
- package/dist/extensions/unavailable.d.ts +49 -0
- package/dist/extensions/unavailable.js +113 -0
- package/dist/files/previewers.controller.js +2 -3
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +4 -4
- package/dist/files/previewers.schemas.d.ts +10 -0
- package/dist/files/previewers.schemas.js +9 -0
- package/dist/http/api.module.js +2 -0
- package/dist/identity/accounts.d.ts +43 -4
- package/dist/identity/accounts.js +74 -6
- package/dist/identity/auth.guard.js +10 -1
- package/dist/identity/cookies.d.ts +6 -0
- package/dist/identity/cookies.js +14 -0
- package/dist/identity/identity.module.js +3 -0
- package/dist/identity/initial-passwords.controller.d.ts +22 -0
- package/dist/identity/initial-passwords.controller.js +49 -0
- package/dist/identity/initial-passwords.d.ts +61 -0
- package/dist/identity/initial-passwords.job.d.ts +16 -0
- package/dist/identity/initial-passwords.job.js +46 -0
- package/dist/identity/initial-passwords.js +159 -0
- package/dist/identity/me.controller.d.ts +12 -0
- package/dist/identity/me.controller.js +31 -1
- package/dist/identity/me.schemas.d.ts +14 -0
- package/dist/identity/me.schemas.js +17 -0
- package/dist/identity/principal.d.ts +8 -0
- package/dist/identity/principal.js +8 -0
- package/dist/identity/settings.d.ts +3 -1
- package/dist/identity/settings.js +6 -4
- package/dist/inbox/inbox.schemas.d.ts +8 -0
- package/dist/inbox/inbox.schemas.js +11 -0
- package/dist/inbox/platform-inbox.controller.d.ts +1 -1
- package/dist/inbox/platform-inbox.controller.js +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/lifecycle/kernel-lifecycle.js +4 -0
- package/dist/models/enablement.d.ts +2 -0
- package/dist/models/enablement.js +1 -0
- package/dist/models/org-models.schemas.d.ts +8 -0
- package/dist/models/org-models.schemas.js +22 -0
- package/dist/models/prices.d.ts +3 -1
- package/dist/models/prices.js +7 -5
- package/dist/models/purposes.d.ts +12 -2
- package/dist/models/purposes.js +22 -8
- package/dist/orgs/orgs.controller.d.ts +2 -5
- package/dist/orgs/orgs.controller.js +3 -6
- package/dist/orgs/orgs.schemas.d.ts +8 -0
- package/dist/orgs/orgs.schemas.js +16 -0
- package/dist/orgs/orgs.service.d.ts +3 -1
- package/dist/orgs/orgs.service.js +6 -4
- package/dist/orgs/settings.service.d.ts +9 -1
- package/dist/orgs/settings.service.js +20 -5
- package/dist/overrides.d.ts +4 -0
- package/dist/overrides.js +2 -0
- package/dist/platform/errors.d.ts +21 -4
- package/dist/platform/errors.js +45 -6
- package/dist/platform/exclusions.d.ts +2 -3
- package/dist/platform/exclusions.js +58 -849
- package/dist/platform/method.js +1 -1
- package/dist/platform/operation.d.ts +82 -5
- package/dist/platform/operation.js +63 -8
- package/dist/platform/ops/accounts.ops.d.ts +32 -0
- package/dist/platform/ops/accounts.ops.js +291 -0
- package/dist/platform/ops/admin.ops.d.ts +36 -0
- package/dist/platform/ops/admin.ops.js +389 -0
- package/dist/platform/ops/agent-skills.ops.d.ts +24 -0
- package/dist/platform/ops/agent-skills.ops.js +226 -0
- package/dist/platform/ops/agent-templates.ops.d.ts +4 -1
- package/dist/platform/ops/agent-templates.ops.js +194 -14
- package/dist/platform/ops/agents.ops.d.ts +19 -1
- package/dist/platform/ops/agents.ops.js +481 -58
- package/dist/platform/ops/approvals.ops.d.ts +30 -0
- package/dist/platform/ops/approvals.ops.js +116 -0
- package/dist/platform/ops/background.ops.d.ts +14 -0
- package/dist/platform/ops/background.ops.js +134 -0
- package/dist/platform/ops/catalog-admin.ops.d.ts +74 -0
- package/dist/platform/ops/catalog-admin.ops.js +587 -0
- package/dist/platform/ops/channels.ops.d.ts +16 -0
- package/dist/platform/ops/channels.ops.js +195 -0
- package/dist/platform/ops/components.ops.d.ts +46 -0
- package/dist/platform/ops/components.ops.js +853 -0
- package/dist/platform/ops/connectors.ops.d.ts +4 -2
- package/dist/platform/ops/connectors.ops.js +68 -6
- package/dist/platform/ops/conversations.ops.d.ts +30 -0
- package/dist/platform/ops/conversations.ops.js +470 -0
- package/dist/platform/ops/environments.ops.d.ts +26 -0
- package/dist/platform/ops/environments.ops.js +289 -0
- package/dist/platform/ops/errors.d.ts +10 -5
- package/dist/platform/ops/errors.js +19 -11
- package/dist/platform/ops/evals.ops.d.ts +28 -0
- package/dist/platform/ops/evals.ops.js +783 -0
- package/dist/platform/ops/extensions-admin.ops.d.ts +25 -0
- package/dist/platform/ops/extensions-admin.ops.js +344 -0
- package/dist/platform/ops/extensions.ops.d.ts +7 -1
- package/dist/platform/ops/extensions.ops.js +248 -17
- package/dist/platform/ops/inbox.ops.d.ts +25 -0
- package/dist/platform/ops/inbox.ops.js +378 -0
- package/dist/platform/ops/marketplaces.ops.d.ts +7 -1
- package/dist/platform/ops/marketplaces.ops.js +326 -17
- package/dist/platform/ops/models.ops.d.ts +25 -0
- package/dist/platform/ops/models.ops.js +232 -0
- package/dist/platform/ops/org-plugins.ops.d.ts +29 -0
- package/dist/platform/ops/org-plugins.ops.js +329 -0
- package/dist/platform/ops/org-settings.ops.d.ts +16 -0
- package/dist/platform/ops/org-settings.ops.js +102 -0
- package/dist/platform/ops/orgs.ops.d.ts +28 -0
- package/dist/platform/ops/orgs.ops.js +295 -0
- package/dist/platform/ops/other-orgs.d.ts +20 -0
- package/dist/platform/ops/other-orgs.js +72 -0
- package/dist/platform/ops/platform.ops.d.ts +11 -6
- package/dist/platform/ops/platform.ops.js +73 -27
- package/dist/platform/ops/plugins.ops.d.ts +10 -8
- package/dist/platform/ops/plugins.ops.js +176 -77
- package/dist/platform/ops/previewers.ops.d.ts +14 -0
- package/dist/platform/ops/previewers.ops.js +109 -0
- package/dist/platform/ops/requests.ops.js +57 -19
- package/dist/platform/ops/skills.ops.d.ts +5 -1
- package/dist/platform/ops/skills.ops.js +129 -11
- package/dist/platform/ops/unavailable.d.ts +23 -0
- package/dist/platform/ops/unavailable.js +111 -0
- package/dist/platform/parity.d.ts +33 -0
- package/dist/platform/parity.js +272 -0
- package/dist/platform/platform-ops.module.d.ts +32 -0
- package/dist/platform/platform-ops.module.js +78 -11
- package/dist/platform/route-schemas.d.ts +18 -0
- package/dist/platform/route-schemas.js +63 -0
- package/dist/roles/worker.module.js +2 -0
- package/dist/runtime/context/build.d.ts +2 -0
- package/dist/runtime/context/build.js +28 -2
- package/dist/runtime/context/compaction.js +10 -1
- package/dist/runtime/context/run-context.d.ts +65 -0
- package/dist/runtime/context/run-context.js +215 -0
- package/dist/runtime/model-call.js +2 -1
- package/dist/runtime/providers.js +8 -1
- package/dist/runtime/run-context.service.d.ts +65 -0
- package/dist/runtime/run-context.service.js +220 -0
- package/dist/runtime/run-worker.d.ts +5 -0
- package/dist/runtime/run-worker.js +31 -6
- package/dist/runtime/runtime.module.js +2 -0
- package/dist/runtime/subagents/definition.d.ts +15 -15
- package/dist/runtime/subagents/definition.js +46 -115
- package/dist/skills/changes.controller.js +2 -1
- package/dist/skills/changes.service.d.ts +1 -1
- package/dist/skills/changes.service.js +4 -4
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +2 -2
- package/dist/skills/invoke.d.ts +2 -2
- package/dist/skills/invoke.js +8 -1
- package/dist/skills/skills.controller.d.ts +4 -13
- package/dist/skills/skills.controller.js +8 -24
- package/dist/skills/skills.schemas.d.ts +48 -0
- package/dist/skills/skills.schemas.js +61 -0
- package/dist/skills/skills.service.d.ts +11 -1
- package/dist/skills/skills.service.js +37 -14
- package/dist/time-zone.d.ts +5 -0
- package/dist/time-zone.js +19 -0
- package/dist/tools/approvals.controller.js +2 -3
- package/dist/tools/approvals.schemas.d.ts +21 -0
- package/dist/tools/approvals.schemas.js +15 -0
- package/dist/tools/builtin-names.d.ts +10 -8
- package/dist/tools/builtin-names.js +16 -11
- package/dist/tools/builtins/builtin-tools.d.ts +3 -1
- package/dist/tools/builtins/builtin-tools.js +15 -3
- package/dist/tools/builtins/current-time.d.ts +26 -0
- package/dist/tools/builtins/current-time.js +99 -0
- package/dist/tools/builtins/platform.d.ts +19 -2
- package/dist/tools/builtins/platform.js +105 -16
- package/dist/tools/connectors.controller.d.ts +1 -2
- package/dist/tools/connectors.controller.js +1 -4
- package/dist/tools/connectors.schemas.d.ts +12 -0
- package/dist/tools/connectors.schemas.js +19 -0
- package/dist/tools/connectors.service.d.ts +5 -2
- package/dist/tools/connectors.service.js +7 -5
- package/dist/tools/org-tool-switches.d.ts +16 -2
- package/dist/tools/org-tool-switches.js +26 -9
- package/dist/tools/pipeline.js +3 -1
- package/dist/tools/registry.d.ts +48 -51
- package/dist/tools/registry.js +222 -233
- package/package.json +3 -3
- package/src/migrations/0090_initial_passwords.sql +27 -0
- package/src/migrations/0091_account_time_zone.sql +4 -0
- package/src/migrations/0092_tools_default_on.sql +27 -0
- package/dist/platform/redact-orgs.d.ts +0 -7
- package/dist/platform/redact-orgs.js +0 -52
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { randomInt } from "node:crypto";
|
|
11
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
12
|
+
import { sql } from "kysely";
|
|
13
|
+
import { ApiError } from "../errors.js";
|
|
14
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
15
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
16
|
+
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
17
|
+
import { KEYRING } from "../infra/tokens.js";
|
|
18
|
+
import { AccountsService } from "./accounts.js";
|
|
19
|
+
import { audit } from "./audit.js";
|
|
20
|
+
/** Letters and digits without the look-alikes (0 O 1 l I): read off a screen and typed by hand. */
|
|
21
|
+
const ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";
|
|
22
|
+
/** 20 characters of 56: about 116 bits. */
|
|
23
|
+
const LENGTH = 20;
|
|
24
|
+
/**
|
|
25
|
+
* How long a generated password waits for its reader. The approving person reads it right after
|
|
26
|
+
* the call runs; one that is never read expires (the account can still be disabled and recreated).
|
|
27
|
+
*/
|
|
28
|
+
export const INITIAL_PASSWORD_TTL_MS = 24 * 60 * 60 * 1000;
|
|
29
|
+
/** The tool key of the approval a generated password belongs to. */
|
|
30
|
+
export const CREATE_ACCOUNT_TOOL_KEY = "Platform:accounts.create";
|
|
31
|
+
/** A one-time initial password, cryptographically random. */
|
|
32
|
+
export function generateInitialPassword() {
|
|
33
|
+
let out = "";
|
|
34
|
+
for (let i = 0; i < LENGTH; i++)
|
|
35
|
+
out += ALPHABET[randomInt(ALPHABET.length)];
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/** The AAD binding a sealed password to its account (a row moved to another account fails). */
|
|
39
|
+
const aadOf = (accountId) => `capybara:initial-password:${accountId}`;
|
|
40
|
+
/**
|
|
41
|
+
* Accounts created with a kernel-generated one-time password (Platform tool spec §14.5 item 2).
|
|
42
|
+
* The password never leaves the kernel except through {@link reveal}: it is not returned to the
|
|
43
|
+
* caller, not written to the audit, the event log or the logs. It is sealed with the master keyring
|
|
44
|
+
* in the creation's transaction and read once, on the web, by the person who approved the call.
|
|
45
|
+
*/
|
|
46
|
+
let InitialPasswords = class InitialPasswords {
|
|
47
|
+
db;
|
|
48
|
+
txHost;
|
|
49
|
+
keyring;
|
|
50
|
+
accounts;
|
|
51
|
+
constructor(db, txHost, keyring, accounts) {
|
|
52
|
+
this.db = db;
|
|
53
|
+
this.txHost = txHost;
|
|
54
|
+
this.keyring = keyring;
|
|
55
|
+
this.accounts = accounts;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Creates a local account (never a super admin) with a generated password it must change at
|
|
59
|
+
* first sign-in, and seals the password for `to`. Returns the account only.
|
|
60
|
+
*/
|
|
61
|
+
async createAccount(input, actorAccountId, to, auditDetail) {
|
|
62
|
+
const password = generateInitialPassword();
|
|
63
|
+
return this.accounts.createByAdmin({ ...input, password, superAdmin: false, mustChangePassword: true }, actorAccountId, undefined, {
|
|
64
|
+
...(auditDetail !== undefined && { auditDetail }),
|
|
65
|
+
inTransaction: (account) => this.seal(account.id, password, to),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Stores the sealed password in the creation's transaction (the hourly job drops expired ones). */
|
|
69
|
+
async seal(accountId, password, to) {
|
|
70
|
+
const { data, masterKeyId } = this.keyring.wrap(Buffer.from(password, "utf8"), aadOf(accountId));
|
|
71
|
+
await this.db
|
|
72
|
+
.insertInto("account_initial_passwords")
|
|
73
|
+
.values({
|
|
74
|
+
account_id: accountId,
|
|
75
|
+
recipient_account_id: to.recipientAccountId,
|
|
76
|
+
conversation_id: to.conversationId,
|
|
77
|
+
run_id: to.runId,
|
|
78
|
+
call_id: to.callId,
|
|
79
|
+
master_key_id: masterKeyId,
|
|
80
|
+
ciphertext: data,
|
|
81
|
+
expires_at: new Date(Date.now() + INITIAL_PASSWORD_TTL_MS),
|
|
82
|
+
})
|
|
83
|
+
.execute();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The password created by an approved `accounts.create` call, read once by the person who
|
|
87
|
+
* approved it (`approvalId` in `orgId`, decided by `accountId`), then deleted. Anything else (not
|
|
88
|
+
* that person, not approved, not run yet, read already, expired) is
|
|
89
|
+
* `account.initial_password_unavailable`, saying nothing about which. Audits the read (without
|
|
90
|
+
* the password).
|
|
91
|
+
*/
|
|
92
|
+
async reveal(orgId, approvalId, accountId) {
|
|
93
|
+
const unavailable = () => new ApiError("account.initial_password_unavailable", "No initial password to show: it was shown already, has expired, or the account was not created by a call you approved");
|
|
94
|
+
const approval = await this.db
|
|
95
|
+
.selectFrom("approvals")
|
|
96
|
+
.select(["conversation_id", "run_id", "call_id", "tool_key", "status", "decided_by"])
|
|
97
|
+
.where("id", "=", approvalId)
|
|
98
|
+
.where("org_id", "=", orgId)
|
|
99
|
+
.executeTakeFirst();
|
|
100
|
+
if (approval === undefined ||
|
|
101
|
+
approval.tool_key !== CREATE_ACCOUNT_TOOL_KEY ||
|
|
102
|
+
approval.status !== "approved" ||
|
|
103
|
+
approval.decided_by !== accountId) {
|
|
104
|
+
throw unavailable();
|
|
105
|
+
}
|
|
106
|
+
// exactly the row of this approval's call: locked, then deleted by its key
|
|
107
|
+
const found = await this.db
|
|
108
|
+
.selectFrom("account_initial_passwords")
|
|
109
|
+
.select("account_id")
|
|
110
|
+
.where("conversation_id", "=", approval.conversation_id)
|
|
111
|
+
.where("run_id", "=", approval.run_id)
|
|
112
|
+
.where("call_id", "=", approval.call_id)
|
|
113
|
+
.where("recipient_account_id", "=", accountId)
|
|
114
|
+
.where("expires_at", ">", sql `now()`)
|
|
115
|
+
.limit(1)
|
|
116
|
+
.forUpdate()
|
|
117
|
+
.executeTakeFirst();
|
|
118
|
+
if (found === undefined)
|
|
119
|
+
throw unavailable();
|
|
120
|
+
const row = await this.db
|
|
121
|
+
.deleteFrom("account_initial_passwords")
|
|
122
|
+
.where("account_id", "=", found.account_id)
|
|
123
|
+
.returning(["account_id", "master_key_id", "ciphertext"])
|
|
124
|
+
.executeTakeFirst();
|
|
125
|
+
if (row === undefined)
|
|
126
|
+
throw unavailable();
|
|
127
|
+
const password = this.keyring
|
|
128
|
+
.unwrap(row.master_key_id, row.ciphertext, aadOf(row.account_id))
|
|
129
|
+
.toString("utf8");
|
|
130
|
+
const login = (await this.accounts.localLogins([row.account_id])).get(row.account_id) ?? null;
|
|
131
|
+
await audit(this.db.db, {
|
|
132
|
+
actorAccountId: accountId,
|
|
133
|
+
orgId,
|
|
134
|
+
action: "account.initial_password_shown",
|
|
135
|
+
target: row.account_id,
|
|
136
|
+
detail: { approvalId },
|
|
137
|
+
});
|
|
138
|
+
return { accountId: row.account_id, login, password };
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
__decorate([
|
|
142
|
+
Transactional()
|
|
143
|
+
], InitialPasswords.prototype, "reveal", null);
|
|
144
|
+
InitialPasswords = __decorate([
|
|
145
|
+
Injectable(),
|
|
146
|
+
__param(0, Inject(KernelDb)),
|
|
147
|
+
__param(1, Inject(TransactionHost)),
|
|
148
|
+
__param(2, Inject(KEYRING)),
|
|
149
|
+
__param(3, Inject(AccountsService))
|
|
150
|
+
], InitialPasswords);
|
|
151
|
+
export { InitialPasswords };
|
|
152
|
+
/** Deletes the sealed passwords past `expires_at`; returns how many. */
|
|
153
|
+
export async function deleteExpiredInitialPasswords(db) {
|
|
154
|
+
const r = await db
|
|
155
|
+
.deleteFrom("account_initial_passwords")
|
|
156
|
+
.where("expires_at", "<=", sql `now()`)
|
|
157
|
+
.executeTakeFirst();
|
|
158
|
+
return Number(r.numDeletedRows);
|
|
159
|
+
}
|
|
@@ -6,6 +6,7 @@ import { OrgsService } from "../orgs/orgs.service.js";
|
|
|
6
6
|
import type { OrgRole } from "../orgs/roles.js";
|
|
7
7
|
import { type Account, AccountsService } from "./accounts.js";
|
|
8
8
|
import { type ApiTokenRecord, ApiTokenService } from "./api-tokens.js";
|
|
9
|
+
import { type PreferencesSchema } from "./me.schemas.js";
|
|
9
10
|
import { type Principal } from "./principal.js";
|
|
10
11
|
import { SessionService } from "./sessions.js";
|
|
11
12
|
import { SettingsService } from "./settings.js";
|
|
@@ -44,6 +45,17 @@ export declare class MeController {
|
|
|
44
45
|
/** Whether `POST /api/v1/orgs` would accept this account (the `orgCreation` setting). */
|
|
45
46
|
canCreateOrg: boolean;
|
|
46
47
|
}>;
|
|
48
|
+
/**
|
|
49
|
+
* The person's preferences (run context spec §3.4): `timeZone` null = follow the browser's time
|
|
50
|
+
* zone sent with each message; a set zone overrides it for the messages sent afterwards.
|
|
51
|
+
*/
|
|
52
|
+
preferences(principal: Principal): Promise<{
|
|
53
|
+
timeZone: string | null;
|
|
54
|
+
}>;
|
|
55
|
+
/** Replaces the person's preferences; an unknown time zone → 400 `validation_failed`. */
|
|
56
|
+
setPreferences(principal: Principal, body: z.infer<typeof PreferencesSchema>): Promise<{
|
|
57
|
+
timeZone: string | null;
|
|
58
|
+
}>;
|
|
47
59
|
/** 切换当前组织(仅 Web 会话);`null` 清空。非成员或已软删除的组织 → `org.not_found`。 */
|
|
48
60
|
setCurrentOrg(principal: Principal, body: z.infer<typeof CurrentOrgSchema>): Promise<void>;
|
|
49
61
|
/**
|
|
@@ -18,7 +18,8 @@ import { OrgsService } from "../orgs/orgs.service.js";
|
|
|
18
18
|
import { AccountsService } from "./accounts.js";
|
|
19
19
|
import { ApiTokenService, FutureIsoDate } from "./api-tokens.js";
|
|
20
20
|
import { MAX_PASSWORD_LENGTH } from "./login.js";
|
|
21
|
-
import {
|
|
21
|
+
import { PreferencesBody } from "./me.schemas.js";
|
|
22
|
+
import { AllowPendingPasswordChange, CurrentPrincipal, requireUser, SessionOnly, } from "./principal.js";
|
|
22
23
|
import { SessionService } from "./sessions.js";
|
|
23
24
|
import { SettingsService } from "./settings.js";
|
|
24
25
|
/** The credential throttlers of a password change (per account, per client IP). */
|
|
@@ -72,6 +73,19 @@ let MeController = class MeController {
|
|
|
72
73
|
const canCreateOrg = orgCreation === "anyone" || p.account.isSuperAdmin;
|
|
73
74
|
return { account: p.account, via: p.via, currentOrgId: current, memberships, canCreateOrg };
|
|
74
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* The person's preferences (run context spec §3.4): `timeZone` null = follow the browser's time
|
|
78
|
+
* zone sent with each message; a set zone overrides it for the messages sent afterwards.
|
|
79
|
+
*/
|
|
80
|
+
async preferences(principal) {
|
|
81
|
+
return this.accounts.preferences(requireUser(principal).account.id);
|
|
82
|
+
}
|
|
83
|
+
/** Replaces the person's preferences; an unknown time zone → 400 `validation_failed`. */
|
|
84
|
+
async setPreferences(principal, body) {
|
|
85
|
+
return this.accounts.setPreferences(requireUser(principal).account.id, {
|
|
86
|
+
timeZone: body.timeZone,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
75
89
|
/** 切换当前组织(仅 Web 会话);`null` 清空。非成员或已软删除的组织 → `org.not_found`。 */
|
|
76
90
|
async setCurrentOrg(principal, body) {
|
|
77
91
|
const p = requireUser(principal);
|
|
@@ -97,6 +111,11 @@ let MeController = class MeController {
|
|
|
97
111
|
throw new ApiError("auth.invalid_credentials", "Current password is incorrect");
|
|
98
112
|
}
|
|
99
113
|
await this.throttler.succeeded(CHANGE_PASSWORD_THROTTLERS, req);
|
|
114
|
+
if (p.account.mustChangePassword && body.newPassword === body.currentPassword) {
|
|
115
|
+
throw new ApiError("validation_failed", "Choose a password other than the initial one", [
|
|
116
|
+
{ path: "newPassword", message: "must differ from the initial password" },
|
|
117
|
+
]);
|
|
118
|
+
}
|
|
100
119
|
// 新密码、吊销其他会话(PG revoked_at)与个人令牌在同一个 PG 事务里完成
|
|
101
120
|
const revoked = await this.accounts.changePassword(p.account.id, body.newPassword, p.sessionId);
|
|
102
121
|
try {
|
|
@@ -125,8 +144,18 @@ let MeController = class MeController {
|
|
|
125
144
|
};
|
|
126
145
|
__decorate([
|
|
127
146
|
Get(),
|
|
147
|
+
AllowPendingPasswordChange(),
|
|
128
148
|
__param(0, CurrentPrincipal())
|
|
129
149
|
], MeController.prototype, "me", null);
|
|
150
|
+
__decorate([
|
|
151
|
+
Get("preferences"),
|
|
152
|
+
__param(0, CurrentPrincipal())
|
|
153
|
+
], MeController.prototype, "preferences", null);
|
|
154
|
+
__decorate([
|
|
155
|
+
Put("preferences"),
|
|
156
|
+
__param(0, CurrentPrincipal()),
|
|
157
|
+
__param(1, ZBody(PreferencesBody))
|
|
158
|
+
], MeController.prototype, "setPreferences", null);
|
|
130
159
|
__decorate([
|
|
131
160
|
Put("current-org"),
|
|
132
161
|
SessionOnly(),
|
|
@@ -137,6 +166,7 @@ __decorate([
|
|
|
137
166
|
__decorate([
|
|
138
167
|
Put("password"),
|
|
139
168
|
SessionOnly(),
|
|
169
|
+
AllowPendingPasswordChange(),
|
|
140
170
|
HttpCode(204),
|
|
141
171
|
__param(0, CurrentPrincipal()),
|
|
142
172
|
__param(1, ZBody(ChangePasswordBody)),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RouteSchemas } from "../platform/route-schemas.js";
|
|
3
|
+
/** `PUT /me/preferences`: the person's preferences (run context spec §3.4). */
|
|
4
|
+
export declare const PreferencesSchema: z.ZodObject<{
|
|
5
|
+
timeZone: z.ZodNullable<z.ZodString>;
|
|
6
|
+
}, z.core.$strict>;
|
|
7
|
+
declare const PreferencesBody_base: import("../infra/validation/create-zod-dto.js").ZodDtoClass<z.ZodObject<{
|
|
8
|
+
timeZone: z.ZodNullable<z.ZodString>;
|
|
9
|
+
}, z.core.$strict>>;
|
|
10
|
+
export declare class PreferencesBody extends PreferencesBody_base {
|
|
11
|
+
}
|
|
12
|
+
/** The `/me` routes the Platform operations mirror (`check:platform-ops` keys). */
|
|
13
|
+
export declare const ME_ROUTES: readonly RouteSchemas[];
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
3
|
+
import { IanaTimeZone } from "../time-zone.js";
|
|
4
|
+
/** `PUT /me/preferences`: the person's preferences (run context spec §3.4). */
|
|
5
|
+
export const PreferencesSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
/** The person's time zone (IANA); null = follow the browser (run context spec §3.4). */
|
|
8
|
+
timeZone: IanaTimeZone.nullable(),
|
|
9
|
+
})
|
|
10
|
+
.strict();
|
|
11
|
+
export class PreferencesBody extends createZodDto(PreferencesSchema, "PreferencesBody") {
|
|
12
|
+
}
|
|
13
|
+
/** The `/me` routes the Platform operations mirror (`check:platform-ops` keys). */
|
|
14
|
+
export const ME_ROUTES = [
|
|
15
|
+
{ route: "GET /api/v1/me/preferences" },
|
|
16
|
+
{ route: "PUT /api/v1/me/preferences", body: PreferencesSchema },
|
|
17
|
+
];
|
|
@@ -30,6 +30,7 @@ export declare const PUBLIC_KEY = "capybara:auth:public";
|
|
|
30
30
|
export declare const SESSION_ONLY_KEY = "capybara:auth:session-only";
|
|
31
31
|
export declare const SUPER_ADMIN_KEY = "capybara:auth:super-admin";
|
|
32
32
|
export declare const ALLOW_SERVICE_KEY = "capybara:auth:allow-service";
|
|
33
|
+
export declare const PASSWORD_CHANGE_KEY = "capybara:auth:password-change";
|
|
33
34
|
/**
|
|
34
35
|
* 不要求凭据:无凭据时放行(principal 为 undefined);带了有效凭据仍解析,无效凭据按无凭据处理。
|
|
35
36
|
* 非安全方法照样要求 `X-Capybara-Csrf: 1`(防登录 CSRF)。新增公开路由必须同时更新 public-routes 元测试的清单。
|
|
@@ -39,6 +40,13 @@ export declare const Public: () => MethodDecorator & ClassDecorator;
|
|
|
39
40
|
export declare const SessionOnly: () => MethodDecorator;
|
|
40
41
|
/** 仅超级管理员(user principal 且 `isSuperAdmin`);否则 `forbidden`。 */
|
|
41
42
|
export declare const SuperAdmin: () => MethodDecorator & ClassDecorator;
|
|
43
|
+
/**
|
|
44
|
+
* Reachable by an account that must change its generated initial password first
|
|
45
|
+
* (`Account.mustChangePassword`): the guard refuses every other route with
|
|
46
|
+
* `auth.password_change_required`. Only `GET /me` and `PUT /me/password` carry it (public routes
|
|
47
|
+
* such as logout are reachable anyway).
|
|
48
|
+
*/
|
|
49
|
+
export declare const AllowPendingPasswordChange: () => MethodDecorator;
|
|
42
50
|
/**
|
|
43
51
|
* 允许服务令牌(service principal)访问。默认拒绝:未标注的路由只接受 user principal,service → `forbidden`。
|
|
44
52
|
* 组织级路由由 OrgGuard 再核对令牌所属组织与角色。
|
|
@@ -4,6 +4,7 @@ export const PUBLIC_KEY = "capybara:auth:public";
|
|
|
4
4
|
export const SESSION_ONLY_KEY = "capybara:auth:session-only";
|
|
5
5
|
export const SUPER_ADMIN_KEY = "capybara:auth:super-admin";
|
|
6
6
|
export const ALLOW_SERVICE_KEY = "capybara:auth:allow-service";
|
|
7
|
+
export const PASSWORD_CHANGE_KEY = "capybara:auth:password-change";
|
|
7
8
|
/**
|
|
8
9
|
* 不要求凭据:无凭据时放行(principal 为 undefined);带了有效凭据仍解析,无效凭据按无凭据处理。
|
|
9
10
|
* 非安全方法照样要求 `X-Capybara-Csrf: 1`(防登录 CSRF)。新增公开路由必须同时更新 public-routes 元测试的清单。
|
|
@@ -13,6 +14,13 @@ export const Public = () => SetMetadata(PUBLIC_KEY, true);
|
|
|
13
14
|
export const SessionOnly = () => SetMetadata(SESSION_ONLY_KEY, true);
|
|
14
15
|
/** 仅超级管理员(user principal 且 `isSuperAdmin`);否则 `forbidden`。 */
|
|
15
16
|
export const SuperAdmin = () => SetMetadata(SUPER_ADMIN_KEY, true);
|
|
17
|
+
/**
|
|
18
|
+
* Reachable by an account that must change its generated initial password first
|
|
19
|
+
* (`Account.mustChangePassword`): the guard refuses every other route with
|
|
20
|
+
* `auth.password_change_required`. Only `GET /me` and `PUT /me/password` carry it (public routes
|
|
21
|
+
* such as logout are reachable anyway).
|
|
22
|
+
*/
|
|
23
|
+
export const AllowPendingPasswordChange = () => SetMetadata(PASSWORD_CHANGE_KEY, true);
|
|
16
24
|
/**
|
|
17
25
|
* 允许服务令牌(service principal)访问。默认拒绝:未标注的路由只接受 user principal,service → `forbidden`。
|
|
18
26
|
* 组织级路由由 OrgGuard 再核对令牌所属组织与角色。
|
|
@@ -133,6 +133,8 @@ export declare class SettingsService {
|
|
|
133
133
|
*/
|
|
134
134
|
get(): Promise<DeploymentSettings>;
|
|
135
135
|
/** Updates settings under the super admin lock, re-checking the actor (else `forbidden`). */
|
|
136
|
-
update(patch: DeploymentSettingsPatch, actorAccountId: string, actorTokenId?: string
|
|
136
|
+
update(patch: DeploymentSettingsPatch, actorAccountId: string, actorTokenId?: string,
|
|
137
|
+
/** Merged into the audit detail (the Platform tool's `via: "agent"`). */
|
|
138
|
+
auditDetail?: Record<string, unknown>): Promise<DeploymentSettings>;
|
|
137
139
|
private write;
|
|
138
140
|
}
|
|
@@ -241,15 +241,17 @@ let SettingsService = class SettingsService {
|
|
|
241
241
|
return out;
|
|
242
242
|
}
|
|
243
243
|
/** Updates settings under the super admin lock, re-checking the actor (else `forbidden`). */
|
|
244
|
-
async update(patch, actorAccountId, actorTokenId
|
|
244
|
+
async update(patch, actorAccountId, actorTokenId,
|
|
245
|
+
/** Merged into the audit detail (the Platform tool's `via: "agent"`). */
|
|
246
|
+
auditDetail) {
|
|
245
247
|
const check = DEPLOYMENT_SETTINGS_PATCH.safeParse(patch);
|
|
246
248
|
if (!check.success) {
|
|
247
249
|
throw new ApiError("validation_failed", "Invalid deployment settings", check.error.issues.map((i) => ({ path: i.path.join("."), message: i.message })));
|
|
248
250
|
}
|
|
249
|
-
await this.write(check.data, actorAccountId, actorTokenId);
|
|
251
|
+
await this.write(check.data, actorAccountId, actorTokenId, auditDetail);
|
|
250
252
|
return this.get();
|
|
251
253
|
}
|
|
252
|
-
async write(patch, actorAccountId, actorTokenId) {
|
|
254
|
+
async write(patch, actorAccountId, actorTokenId, auditDetail) {
|
|
253
255
|
await this.adminLock.lockAndAuthorize(actorAccountId);
|
|
254
256
|
// The super admin lock serializes every settings write: the current overrides are read
|
|
255
257
|
// and merged under it, so no concurrent change is lost
|
|
@@ -294,7 +296,7 @@ let SettingsService = class SettingsService {
|
|
|
294
296
|
actorAccountId,
|
|
295
297
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
296
298
|
action: "deployment.settings.updated",
|
|
297
|
-
detail: patch,
|
|
299
|
+
detail: { ...patch, ...auditDetail },
|
|
298
300
|
});
|
|
299
301
|
}
|
|
300
302
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RouteSchemas } from "../platform/route-schemas.js";
|
|
3
|
+
/** `:id` of a notice dismissal (the org's and the platform's inbox). */
|
|
4
|
+
export declare const InboxNoticeParams: z.ZodObject<{
|
|
5
|
+
id: z.ZodString;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
/** The inbox routes (the org's and the super admin's) the Platform inbox operations mirror. */
|
|
8
|
+
export declare const INBOX_ROUTES: readonly RouteSchemas[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** `:id` of a notice dismissal (the org's and the platform's inbox). */
|
|
3
|
+
export const InboxNoticeParams = z.object({ id: z.string().min(1).max(100) });
|
|
4
|
+
/** The inbox routes (the org's and the super admin's) the Platform inbox operations mirror. */
|
|
5
|
+
export const INBOX_ROUTES = [
|
|
6
|
+
{ route: "GET /api/v1/orgs/:orgId/inbox" },
|
|
7
|
+
{ route: "POST /api/v1/orgs/:orgId/inbox/notices/:id/dismiss", params: InboxNoticeParams },
|
|
8
|
+
{ route: "GET /api/v1/admin/inbox" },
|
|
9
|
+
{ route: "GET /api/v1/admin/inbox/count" },
|
|
10
|
+
{ route: "POST /api/v1/admin/inbox/notices/:id/dismiss", params: InboxNoticeParams },
|
|
11
|
+
];
|
|
@@ -8,12 +8,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
10
|
import { Controller, Get, HttpCode, Inject, Post } from "@nestjs/common";
|
|
11
|
-
import { z } from "zod";
|
|
12
11
|
import { CurrentPrincipal, requireUser, SuperAdmin, } from "../identity/principal.js";
|
|
13
12
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
14
13
|
import { ZParam } from "../infra/validation/zod-params.js";
|
|
14
|
+
import { InboxNoticeParams } from "./inbox.schemas.js";
|
|
15
15
|
import { PlatformInboxService } from "./platform-inbox.service.js";
|
|
16
|
-
const NoticeParamsSchema =
|
|
16
|
+
const NoticeParamsSchema = InboxNoticeParams;
|
|
17
17
|
class NoticeParams extends createZodDto(NoticeParamsSchema, "PlatformInboxNoticeParams") {
|
|
18
18
|
}
|
|
19
19
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,10 @@ export { type ContextJob, type JobWrapper, type LogContext, logContext, setJobWr
|
|
|
63
63
|
export { type Org, OrgsService } from "./orgs/orgs.service.js";
|
|
64
64
|
export type { KernelOverride } from "./overrides.js";
|
|
65
65
|
export { fetchNpmPackage, IntegrityMismatchError, type NpmFetchConfig, NpmFetchError, PackageTooLargeError, } from "./packages/npm.js";
|
|
66
|
+
export { checkInputParity, inputParity, type ParityFinding, type ParityOperation, } from "./platform/parity.js";
|
|
67
|
+
export { PLATFORM_OPERATION_PROVIDERS } from "./platform/platform-ops.module.js";
|
|
68
|
+
export { PlatformOperations } from "./platform/registry.js";
|
|
69
|
+
export { ROUTE_SCHEMAS, type RouteSchemas } from "./platform/route-schemas.js";
|
|
66
70
|
export { UNKNOWN_RESULT_TEXT } from "./runtime/context/pairing.js";
|
|
67
71
|
export type { AgentLoop, LoopContext, LoopOutcome } from "./runtime/loop.js";
|
|
68
72
|
export { MAINTENANCE_QUEUE_NAME } from "./runtime/maintenance-queue.js";
|
package/dist/index.js
CHANGED
|
@@ -60,6 +60,12 @@ export { createConfiguredLogger, loggerOptionsFromConfig } from "./log-config.js
|
|
|
60
60
|
export { logContext, setJobWrapper, setTraceContextSource, withJobContext, withLogContext, } from "./log-context.js";
|
|
61
61
|
export { OrgsService } from "./orgs/orgs.service.js";
|
|
62
62
|
export { fetchNpmPackage, IntegrityMismatchError, NpmFetchError, PackageTooLargeError, } from "./packages/npm.js";
|
|
63
|
+
// Test seam: the Platform input-parity test in tools/checks (no runtime caller).
|
|
64
|
+
export { checkInputParity, inputParity, } from "./platform/parity.js";
|
|
65
|
+
// Test seam (the parity test builds every operation from these without a Nest app).
|
|
66
|
+
export { PLATFORM_OPERATION_PROVIDERS } from "./platform/platform-ops.module.js";
|
|
67
|
+
export { PlatformOperations } from "./platform/registry.js";
|
|
68
|
+
export { ROUTE_SCHEMAS } from "./platform/route-schemas.js";
|
|
63
69
|
export { UNKNOWN_RESULT_TEXT } from "./runtime/context/pairing.js";
|
|
64
70
|
export { MAINTENANCE_QUEUE_NAME } from "./runtime/maintenance-queue.js";
|
|
65
71
|
export { runJobId } from "./runtime/run-queue.js";
|
|
@@ -26,6 +26,7 @@ import { ExtensionRegistry } from "../extensions/registry.js";
|
|
|
26
26
|
import { ReplicaStatusStore } from "../extensions/sources.js";
|
|
27
27
|
import { syncPackage } from "../extensions/sync.js";
|
|
28
28
|
import { AccountsService } from "../identity/accounts.js";
|
|
29
|
+
import { insecurePublicUrlWarning } from "../identity/cookies.js";
|
|
29
30
|
import { waitWithin } from "../infra/close-within.js";
|
|
30
31
|
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
31
32
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
@@ -277,6 +278,9 @@ let KernelLifecycle = class KernelLifecycle {
|
|
|
277
278
|
this.listening = await this.shutdown.trackInFlight(this.http.listen(port));
|
|
278
279
|
this.checkpoint();
|
|
279
280
|
this.log.info("kernel started", { roles: this.config.roles, port: this.listening });
|
|
281
|
+
const insecure = insecurePublicUrlWarning(this.config);
|
|
282
|
+
if (insecure !== null)
|
|
283
|
+
this.log.warn(insecure);
|
|
280
284
|
await this.warnIfSetupPending();
|
|
281
285
|
return this.listening;
|
|
282
286
|
}
|
|
@@ -36,6 +36,8 @@ export interface ModelDisableChange {
|
|
|
36
36
|
export interface ModelDisableActor {
|
|
37
37
|
accountId: string;
|
|
38
38
|
tokenId?: string | undefined;
|
|
39
|
+
/** Merged into the audit detail (a write made through the Platform tool). */
|
|
40
|
+
auditDetail?: Record<string, unknown>;
|
|
39
41
|
}
|
|
40
42
|
/**
|
|
41
43
|
* Models disabled on two layers (spec B §5.3, table `model_disabled`): the platform's list (the
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RouteSchemas } from "../platform/route-schemas.js";
|
|
3
|
+
/** `:purpose` as the org purpose route takes it (`@Param`). */
|
|
4
|
+
export declare const ModelPurposePathParams: z.ZodObject<{
|
|
5
|
+
purpose: z.ZodString;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
/** The org's model routes (the admin console's are the platform-admin domain's). */
|
|
8
|
+
export declare const ORG_MODEL_ROUTES: readonly RouteSchemas[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ModelsQuery } from "../agents/models.controller.js";
|
|
3
|
+
import { ModelDisabledPatch, ModelProviderParams } from "./enablement.controller.js";
|
|
4
|
+
import { PURPOSE_PUT } from "./purposes.js";
|
|
5
|
+
/** `:purpose` as the org purpose route takes it (`@Param`). */
|
|
6
|
+
export const ModelPurposePathParams = z.object({ purpose: z.string().min(1) });
|
|
7
|
+
/** The org's model routes (the admin console's are the platform-admin domain's). */
|
|
8
|
+
export const ORG_MODEL_ROUTES = [
|
|
9
|
+
{ route: "GET /api/v1/orgs/:orgId/models", query: ModelsQuery },
|
|
10
|
+
{ route: "GET /api/v1/orgs/:orgId/models/catalog" },
|
|
11
|
+
{ route: "GET /api/v1/orgs/:orgId/model-purposes" },
|
|
12
|
+
{
|
|
13
|
+
route: "PUT /api/v1/orgs/:orgId/model-purposes/:purpose",
|
|
14
|
+
params: ModelPurposePathParams,
|
|
15
|
+
body: PURPOSE_PUT,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
route: "PATCH /api/v1/orgs/:orgId/models/:provider/disabled",
|
|
19
|
+
params: ModelProviderParams,
|
|
20
|
+
body: ModelDisabledPatch,
|
|
21
|
+
},
|
|
22
|
+
];
|
package/dist/models/prices.d.ts
CHANGED
|
@@ -53,7 +53,9 @@ export declare class PricesService {
|
|
|
53
53
|
provider: string;
|
|
54
54
|
model: string;
|
|
55
55
|
price: null;
|
|
56
|
-
}, actorAccountId: string, actorTokenId?: string
|
|
56
|
+
}, actorAccountId: string, actorTokenId?: string,
|
|
57
|
+
/** Merged into the audit detail (the Platform tool's `via: "agent"`). */
|
|
58
|
+
auditDetail?: Record<string, unknown>): Promise<void>;
|
|
57
59
|
/** The write of {@link put}, under the super admin lock. */
|
|
58
60
|
private write;
|
|
59
61
|
}
|
package/dist/models/prices.js
CHANGED
|
@@ -90,15 +90,17 @@ let PricesService = class PricesService {
|
|
|
90
90
|
* 设置或删除(`price: null`)一个模型的价格:事务内取超级管理员锁并复核发起人仍是活跃超级管理员
|
|
91
91
|
* (否则 `forbidden`),写审计 `model_price.updated` / `model_price.deleted`。
|
|
92
92
|
*/
|
|
93
|
-
async put(input, actorAccountId, actorTokenId
|
|
93
|
+
async put(input, actorAccountId, actorTokenId,
|
|
94
|
+
/** Merged into the audit detail (the Platform tool's `via: "agent"`). */
|
|
95
|
+
auditDetail) {
|
|
94
96
|
const check = MODEL_PRICE_PUT.safeParse(input);
|
|
95
97
|
if (!check.success) {
|
|
96
98
|
throw new ApiError("validation_failed", "Invalid model price", check.error.issues.map((i) => ({ path: i.path.join("."), message: i.message })));
|
|
97
99
|
}
|
|
98
|
-
await this.write(check.data, actorAccountId, actorTokenId);
|
|
100
|
+
await this.write(check.data, actorAccountId, actorTokenId, auditDetail);
|
|
99
101
|
}
|
|
100
102
|
/** The write of {@link put}, under the super admin lock. */
|
|
101
|
-
async write(v, actorAccountId, actorTokenId) {
|
|
103
|
+
async write(v, actorAccountId, actorTokenId, auditDetail) {
|
|
102
104
|
await this.adminLock.lockAndAuthorize(actorAccountId);
|
|
103
105
|
const target = `${v.provider}/${v.model}`;
|
|
104
106
|
if ("price" in v) {
|
|
@@ -112,7 +114,7 @@ let PricesService = class PricesService {
|
|
|
112
114
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
113
115
|
action: "model_price.deleted",
|
|
114
116
|
target,
|
|
115
|
-
detail: { provider: v.provider, model: v.model },
|
|
117
|
+
detail: { provider: v.provider, model: v.model, ...auditDetail },
|
|
116
118
|
});
|
|
117
119
|
return;
|
|
118
120
|
}
|
|
@@ -133,7 +135,7 @@ let PricesService = class PricesService {
|
|
|
133
135
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
134
136
|
action: "model_price.updated",
|
|
135
137
|
target,
|
|
136
|
-
detail: { ...v },
|
|
138
|
+
detail: { ...v, ...auditDetail },
|
|
137
139
|
});
|
|
138
140
|
}
|
|
139
141
|
};
|
|
@@ -155,12 +155,22 @@ export declare class ModelPurposesService {
|
|
|
155
155
|
*/
|
|
156
156
|
private check;
|
|
157
157
|
private set;
|
|
158
|
+
/**
|
|
159
|
+
* The checks {@link set} runs before writing, nothing written: an unknown purpose, and a target
|
|
160
|
+
* model the scope cannot use, of another kind, or with invalid params (the Platform tool's
|
|
161
|
+
* precheck, so a known failure never reaches the confirmation card).
|
|
162
|
+
*/
|
|
163
|
+
validate(orgId: string | null, purpose: string, target: PurposeTarget | null): Promise<void>;
|
|
158
164
|
/** The mapping write of {@link set}, under the super admin or org lock. */
|
|
159
165
|
private write;
|
|
160
166
|
/** 设置(或 `null` 清除)部署默认;只有超级管理员(事务内复核)。 */
|
|
161
|
-
setDefault(purpose: string, target: PurposeTarget | null, actor: string, actorTokenId?: string
|
|
167
|
+
setDefault(purpose: string, target: PurposeTarget | null, actor: string, actorTokenId?: string,
|
|
168
|
+
/** Merged into the audit detail (a write made through the Platform tool). */
|
|
169
|
+
auditDetail?: Record<string, unknown>): Promise<PurposeView>;
|
|
162
170
|
/** 设置(或 `null` 清除)组织覆盖;事务内锁组织并复核 `org.models.manage`。 */
|
|
163
|
-
setOrg(orgId: string, purpose: string, target: PurposeTarget | null, actor: string, actorTokenId?: string
|
|
171
|
+
setOrg(orgId: string, purpose: string, target: PurposeTarget | null, actor: string, actorTokenId?: string,
|
|
172
|
+
/** Merged into the audit detail (a write made through the Platform tool). */
|
|
173
|
+
auditDetail?: Record<string, unknown>): Promise<PurposeView>;
|
|
164
174
|
/**
|
|
165
175
|
* 生效的映射:组织覆盖,否则部署默认;都没有 → `model.unconfigured`;用途未声明 → `model.purpose_unknown`。
|
|
166
176
|
* An effective target the org cannot use counts as unconfigured there (spec B §5.3): checked in
|