@agent-native/core 0.227.0 → 0.228.0-nightly-20261111004142
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/dist/action.d.ts +6 -2
- package/dist/agent/engine/builder-engine.js +6 -1
- package/dist/agent/engine/tool-call-journal-seed.d.ts +2 -0
- package/dist/agent/engine/tool-call-journal-seed.js +14 -0
- package/dist/agent/harness/store.js +14 -0
- package/dist/agent/production-agent.js +257 -17
- package/dist/agent/reaped-run-thread.js +6 -0
- package/dist/agent/run-manager.js +6 -0
- package/dist/agent/tool-call-journal.d.ts +4 -0
- package/dist/agent/tool-call-journal.js +12 -0
- package/dist/agent/types.d.ts +7 -1
- package/dist/app-config/agent.d.ts +3 -0
- package/dist/app-config/agent.js +7 -0
- package/dist/app-config/schema.d.ts +3 -0
- package/dist/application-state/handlers.d.ts +3 -3
- package/dist/application-state/handlers.js +6 -1
- package/dist/application-state/index.d.ts +3 -2
- package/dist/application-state/index.js +3 -2
- package/dist/application-state/last-used-tab.d.ts +11 -0
- package/dist/application-state/last-used-tab.js +43 -0
- package/dist/application-state/script-helpers.d.ts +26 -0
- package/dist/application-state/script-helpers.js +83 -15
- package/dist/application-state/store.d.ts +8 -0
- package/dist/application-state/store.js +16 -0
- package/dist/cli/agent.js +7 -3
- package/dist/cli/code-agent-executor.d.ts +1 -0
- package/dist/cli/code-agent-executor.js +37 -2
- package/dist/cli/code.js +3 -1
- package/dist/client/agent-sidebar-state.d.ts +2 -0
- package/dist/client/browser-tab-use.d.ts +9 -0
- package/dist/client/browser-tab-use.js +112 -0
- package/dist/client/chat/runtime.js +3 -1
- package/dist/client/error-capture.js +33 -1
- package/dist/client/navigation/index.d.ts +1 -0
- package/dist/client/navigation/index.js +1 -0
- package/dist/client/resources/mcp-integration-logos.js +16 -0
- package/dist/client/review/use-review.d.ts +28 -0
- package/dist/client/review/use-review.js +41 -12
- package/dist/client/route-state.js +2 -0
- package/dist/client/sse-event-processor.d.ts +1 -0
- package/dist/client/sse-event-processor.js +7 -1
- package/dist/client/use-db-sync.d.ts +8 -1
- package/dist/client/use-db-sync.js +6 -5
- package/dist/coding-tools/run-code.js +12 -2
- package/dist/coding-tools/sandbox/executions-store.d.ts +1 -1
- package/dist/coding-tools/sandbox/executions-store.js +9 -3
- package/dist/collab/routes.d.ts +1 -1
- package/dist/data-programs/execute.js +1 -1
- package/dist/db/schema-snapshot.generated.js +17 -3
- package/dist/extensions/url-safety.d.ts +1 -3
- package/dist/extensions/url-safety.js +23 -23
- package/dist/file-upload/actions/upload-image.d.ts +5 -5
- package/dist/file-upload/index.d.ts +1 -1
- package/dist/file-upload/index.js +1 -1
- package/dist/file-upload/s3-client.d.ts +1 -0
- package/dist/file-upload/s3-client.js +70 -13
- package/dist/file-upload/s3.d.ts +9 -0
- package/dist/file-upload/s3.js +14 -1
- package/dist/framework-package-versions.json +8 -8
- package/dist/jobs/run-history.js +10 -3
- package/dist/jobs/scheduler.js +5 -36
- package/dist/localization/core-messages/supplemental/ar-SA.js +35 -0
- package/dist/localization/core-messages/supplemental/de-DE.js +35 -0
- package/dist/localization/core-messages/supplemental/en-US.js +35 -0
- package/dist/localization/core-messages/supplemental/es-ES.js +35 -0
- package/dist/localization/core-messages/supplemental/fr-FR.js +35 -0
- package/dist/localization/core-messages/supplemental/hi-IN.js +35 -0
- package/dist/localization/core-messages/supplemental/ja-JP.js +35 -0
- package/dist/localization/core-messages/supplemental/ko-KR.js +35 -0
- package/dist/localization/core-messages/supplemental/pt-BR.js +35 -0
- package/dist/localization/core-messages/supplemental/zh-CN.js +35 -0
- package/dist/localization/core-messages/supplemental/zh-TW.js +35 -0
- package/dist/localization/default-messages.d.ts +35 -0
- package/dist/localization/default-messages.js +35 -0
- package/dist/localization/mcp-settings-messages.d.ts +35 -0
- package/dist/mcp/actions/list-mcp-client-connections.d.ts +8 -0
- package/dist/mcp/actions/list-mcp-client-connections.js +39 -0
- package/dist/mcp/browser-tab-target.d.ts +16 -0
- package/dist/mcp/browser-tab-target.js +58 -0
- package/dist/mcp/build-server.d.ts +1 -0
- package/dist/mcp/build-server.js +38 -7
- package/dist/mcp/call-attribution.d.ts +4 -1
- package/dist/mcp/call-attribution.js +3 -1
- package/dist/mcp/client-connections.d.ts +6 -0
- package/dist/mcp/client-connections.js +91 -0
- package/dist/mcp/connect-route.js +12 -2
- package/dist/mcp/connect-store.d.ts +3 -0
- package/dist/mcp/connect-store.js +10 -1
- package/dist/mcp/direct-action-call.js +1 -0
- package/dist/mcp/oauth-store.d.ts +6 -0
- package/dist/mcp/oauth-store.js +23 -0
- package/dist/mcp/oauth-token.d.ts +1 -0
- package/dist/mcp/oauth-token.js +1 -0
- package/dist/mcp/server.js +9 -20
- package/dist/mcp-client/config.d.ts +2 -0
- package/dist/mcp-client/manager.js +23 -0
- package/dist/mcp-client/workspace-servers.js +42 -10
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/handlers.js +21 -17
- package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +17 -36
- package/dist/review/actions/create-review-comment.d.ts +7 -0
- package/dist/review/actions/create-review-comment.js +29 -3
- package/dist/review/actions/delete-review-comment.js +2 -2
- package/dist/review/actions/list-review-comments.d.ts +3 -0
- package/dist/review/actions/list-review-comments.js +41 -17
- package/dist/review/actions/react-to-review-comment.js +2 -2
- package/dist/review/actions/reply-review-comment.d.ts +4 -0
- package/dist/review/actions/reply-review-comment.js +15 -6
- package/dist/review/actions/update-review-comment-anchor.d.ts +6 -0
- package/dist/review/actions/update-review-comment-anchor.js +39 -10
- package/dist/review/actions/update-review-comment.d.ts +3 -0
- package/dist/review/actions/update-review-comment.js +28 -3
- package/dist/review/errors.d.ts +33 -0
- package/dist/review/errors.js +51 -0
- package/dist/review/index.d.ts +5 -4
- package/dist/review/index.js +3 -2
- package/dist/review/registry.d.ts +51 -1
- package/dist/review/registry.js +117 -0
- package/dist/review/store.d.ts +59 -14
- package/dist/review/store.js +622 -101
- package/dist/review/suggestions/actions.js +65 -10
- package/dist/review/suggestions/actor-kind.d.ts +5 -0
- package/dist/review/suggestions/actor-kind.js +20 -0
- package/dist/review/suggestions/store.js +16 -2
- package/dist/review/suggestions/types.d.ts +13 -0
- package/dist/review/types.d.ts +89 -0
- package/dist/scripts/db/dev-query-proxy.d.ts +2 -0
- package/dist/scripts/db/dev-query-proxy.js +4 -1
- package/dist/scripts/db/query.js +3 -0
- package/dist/scripts/dev/shell.js +4 -0
- package/dist/scripts/dev-session.d.ts +31 -0
- package/dist/scripts/dev-session.js +58 -0
- package/dist/scripts/resources/list.js +53 -4
- package/dist/scripts/runner.js +22 -4
- package/dist/search/query.d.ts +11 -5
- package/dist/search/query.js +52 -15
- package/dist/search/tokenize.d.ts +1 -0
- package/dist/search/tokenize.js +3 -0
- package/dist/secrets/api-keys.d.ts +4 -0
- package/dist/secrets/api-keys.js +5 -0
- package/dist/secrets/register.d.ts +2 -0
- package/dist/secrets/routes.d.ts +2 -2
- package/dist/secrets/routes.js +85 -6
- package/dist/secrets/storage.d.ts +2 -0
- package/dist/secrets/storage.js +34 -9
- package/dist/secrets/substitution.d.ts +3 -2
- package/dist/secrets/substitution.js +56 -7
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/action-routes.js +8 -6
- package/dist/server/agent-chat/prompt-resources.js +117 -79
- package/dist/server/agent-chat/script-entries.js +15 -8
- package/dist/server/agent-chat-plugin.js +9 -4
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/agents-bundle.d.ts +3 -1
- package/dist/server/agents-bundle.js +4 -4
- package/dist/server/csrf.js +1 -0
- package/dist/server/dev-action-bridge.d.ts +2 -0
- package/dist/server/dev-action-bridge.js +34 -5
- package/dist/server/first-touch-route.d.ts +1 -1
- package/dist/server/http-response-telemetry.js +4 -0
- package/dist/server/loopback.js +3 -1
- package/dist/server/request-context.d.ts +26 -0
- package/dist/shared/app-state-routes.d.ts +7 -0
- package/dist/shared/app-state-routes.js +7 -0
- package/dist/shared/mcp-client-connections.d.ts +41 -0
- package/dist/shared/mcp-client-connections.js +18 -0
- package/dist/shared/mcp-connect-content.d.ts +18 -0
- package/dist/shared/mcp-connect-content.js +200 -172
- package/dist/shared/runtime-config.js +5 -1
- package/dist/templates/chat/.agents/skills/context-awareness/SKILL.md +13 -0
- package/dist/templates/default/.agents/skills/context-awareness/SKILL.md +13 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +13 -0
- package/dist/tracking/providers.d.ts +7 -0
- package/dist/tracking/providers.js +39 -17
- package/dist/triggers/condition-evaluator.d.ts +2 -0
- package/dist/triggers/condition-evaluator.js +93 -3
- package/dist/triggers/dispatcher.js +24 -6
- package/docs/AGENTS.md +16 -16
- package/docs/content/create-with-an-agent.mdx +10 -4
- package/docs/content/durable-resume.mdx +11 -2
- package/docs/content/toolkit-comments-review.mdx +54 -1
- package/package.json +5 -4
- package/src/templates/chat/.agents/skills/context-awareness/SKILL.md +13 -0
- package/src/templates/default/.agents/skills/context-awareness/SKILL.md +13 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +13 -0
package/dist/mcp/server.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getRequestHeader, } from "h3";
|
|
2
2
|
import { getAppConfig } from "../app-config/store.js";
|
|
3
3
|
import { getConfiguredAppBasePath } from "../server/app-base-path.js";
|
|
4
|
-
import { isLoopbackRequest } from "../server/auth.js";
|
|
5
4
|
import { describeBearerCredentialRefusal, } from "../server/bearer-credential-refusal.js";
|
|
6
5
|
import { CREDENTIAL_MEMBERSHIP_UNAVAILABLE_MESSAGE } from "../server/credential-membership-unavailable.js";
|
|
7
6
|
import { resolveEmbedRequestOrigin } from "../server/embed-request-origin.js";
|
|
8
7
|
import { getH3App } from "../server/framework-request-handler.js";
|
|
9
8
|
import { getOrigin } from "../server/google-oauth.js";
|
|
10
9
|
import { readBody } from "../server/h3-helpers.js";
|
|
10
|
+
import { isDirectLoopbackRequest } from "../server/loopback.js";
|
|
11
11
|
import { registerMcpAppCardsLab } from "./app-cards-lab.js";
|
|
12
12
|
import { mcpApprovalRoute, mountMcpApprovalRoute } from "./approval-route.js";
|
|
13
13
|
import { mcpApprovalAppId } from "./approval-store.js";
|
|
@@ -55,21 +55,6 @@ function deriveRequestMeta(event) {
|
|
|
55
55
|
...(inlineAppsRequested ? { inlineMcpApps: true } : {}),
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
function isLoopbackOrigin(origin) {
|
|
59
|
-
if (!origin)
|
|
60
|
-
return false;
|
|
61
|
-
try {
|
|
62
|
-
const hostname = new URL(origin).hostname;
|
|
63
|
-
return (hostname === "localhost" ||
|
|
64
|
-
hostname === "127.0.0.1" ||
|
|
65
|
-
hostname === "::1" ||
|
|
66
|
-
hostname === "[::1]" ||
|
|
67
|
-
hostname.startsWith("127."));
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
58
|
function buildWebRequest(event, method, routePath = MCP_PUBLIC_ROUTE_PREFIX) {
|
|
74
59
|
const src = event.req;
|
|
75
60
|
const headers = new Headers();
|
|
@@ -232,7 +217,11 @@ async function handleMcpRequestInternal(event, config, routePath, approvalRoute,
|
|
|
232
217
|
const authHeader = getRequestHeader(event, "authorization");
|
|
233
218
|
const ownerEmailHeader = getRequestHeader(event, "x-agent-native-owner-email");
|
|
234
219
|
const requestMeta = deriveRequestMeta(event);
|
|
235
|
-
const
|
|
220
|
+
const requestOrigin = getRequestHeader(event, "origin");
|
|
221
|
+
const directLocalRequest = isDirectLoopbackRequest(event) &&
|
|
222
|
+
(requestOrigin === undefined || requestOrigin === requestMeta.origin);
|
|
223
|
+
const localOwnerHint = directLocalRequest ? ownerEmailHeader : undefined;
|
|
224
|
+
const hasLocalOwnerHint = Boolean(localOwnerHint?.trim());
|
|
236
225
|
const directoryProfile = routePath === MCP_DIRECTORY_ROUTE_PREFIX &&
|
|
237
226
|
config.directoryProfile?.directoryRoute !== false
|
|
238
227
|
? config.directoryProfile
|
|
@@ -255,9 +244,9 @@ async function handleMcpRequestInternal(event, config, routePath, approvalRoute,
|
|
|
255
244
|
: config;
|
|
256
245
|
let authResult;
|
|
257
246
|
try {
|
|
258
|
-
authResult = await verifyAuth(authHeader,
|
|
259
|
-
|
|
260
|
-
|
|
247
|
+
authResult = await verifyAuth(authHeader, localOwnerHint, {
|
|
248
|
+
allowLocalOwnerHint: hasLocalOwnerHint,
|
|
249
|
+
allowDevOpen: directLocalRequest &&
|
|
261
250
|
(hasLocalOwnerHint || getAppConfig().mcp.allowDevOpen),
|
|
262
251
|
resourceUrl: getMcpOAuthAudiences(event, routePath),
|
|
263
252
|
requestOrigin: getOrigin(event),
|
|
@@ -15,6 +15,8 @@ export interface McpHttpServerConfig {
|
|
|
15
15
|
type: "http";
|
|
16
16
|
url: string;
|
|
17
17
|
headers?: Record<string, string>;
|
|
18
|
+
/** Exact runtime origin for requests carrying a substituted vault key. */
|
|
19
|
+
secretRequestOrigin?: string;
|
|
18
20
|
oauthAccessRefresh?: McpOAuthAccessRefresh;
|
|
19
21
|
/** Internal failure marker for a server whose saved settings could not be materialized. */
|
|
20
22
|
configurationError?: Error;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE, noteExternalWrite, } from "../action.js";
|
|
2
|
+
import { ssrfSafeFetch } from "../extensions/url-safety.js";
|
|
2
3
|
import { isJsonSchemaObject } from "../json-schema/subschemas.js";
|
|
3
4
|
import { plainJsonSnapshot, UnusableSchemaError, } from "../json-schema/unusable-schema.js";
|
|
4
5
|
import { assertUsableSchema } from "../json-schema/usable-schema.js";
|
|
@@ -102,6 +103,7 @@ function sameServerConfig(a, b) {
|
|
|
102
103
|
};
|
|
103
104
|
return (a.url === b.url &&
|
|
104
105
|
JSON.stringify(a.headers ?? {}) === JSON.stringify(b.headers ?? {}) &&
|
|
106
|
+
a.secretRequestOrigin === b.secretRequestOrigin &&
|
|
105
107
|
a.oauthAccessRefresh?.identity === b.oauthAccessRefresh?.identity &&
|
|
106
108
|
errorIdentity(a.configurationError) ===
|
|
107
109
|
errorIdentity(b.configurationError) &&
|
|
@@ -357,6 +359,27 @@ export class McpClientManager {
|
|
|
357
359
|
transportOptions.fetch = async (input, init) => nativeFetch(input, await buildFirstPartyRequestInit(staticHeaders, init, this.firstPartyTrust(entry)));
|
|
358
360
|
}
|
|
359
361
|
}
|
|
362
|
+
else if (cfg.secretRequestOrigin) {
|
|
363
|
+
requestInit.headers = staticHeaders;
|
|
364
|
+
transportOptions.fetch = async (input, init) => {
|
|
365
|
+
const request = new Request(input, init);
|
|
366
|
+
const requestOptions = {
|
|
367
|
+
method: request.method,
|
|
368
|
+
headers: request.headers,
|
|
369
|
+
body: request.body,
|
|
370
|
+
signal: request.signal,
|
|
371
|
+
...(request.body ? { duplex: "half" } : {}),
|
|
372
|
+
};
|
|
373
|
+
return ssrfSafeFetch(request.url, requestOptions, {
|
|
374
|
+
followRedirects: false,
|
|
375
|
+
assertUrlAllowed: (candidate) => {
|
|
376
|
+
if (new URL(candidate).origin !== cfg.secretRequestOrigin) {
|
|
377
|
+
throw new Error("Workspace MCP destination changed origin");
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
};
|
|
382
|
+
}
|
|
360
383
|
else if (Object.keys(staticHeaders).length > 0) {
|
|
361
384
|
requestInit.headers = staticHeaders;
|
|
362
385
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { getDbExec } from "../db/client.js";
|
|
3
3
|
import { readAppSecret } from "../secrets/storage.js";
|
|
4
|
+
import { getResolvedKeyAllowlist, validateUrlAllowlist, } from "../secrets/substitution.js";
|
|
4
5
|
import { getRequestOrgId, getRequestUserEmail, } from "../server/request-context.js";
|
|
5
6
|
import { hashEmail, normalizeServerName, validateRemoteUrl, } from "./remote-store.js";
|
|
6
7
|
const WORKSPACE_MCP_KIND = "mcp-server";
|
|
@@ -56,10 +57,13 @@ function secretCandidates(row) {
|
|
|
56
57
|
async function resolveKeyReferencesForRow(text, row) {
|
|
57
58
|
const matches = Array.from(text.matchAll(KEY_REFERENCE_REGEX));
|
|
58
59
|
if (matches.length === 0)
|
|
59
|
-
return text;
|
|
60
|
+
return { value: text, refs: [] };
|
|
60
61
|
const values = new Map();
|
|
62
|
+
const refs = [];
|
|
61
63
|
for (const match of matches) {
|
|
62
64
|
const key = match[1];
|
|
65
|
+
if (!key)
|
|
66
|
+
throw new Error("Invalid workspace MCP key reference");
|
|
63
67
|
if (values.has(key))
|
|
64
68
|
continue;
|
|
65
69
|
let value = null;
|
|
@@ -67,6 +71,7 @@ async function resolveKeyReferencesForRow(text, row) {
|
|
|
67
71
|
const secret = await readAppSecret({ key, ...ref });
|
|
68
72
|
if (secret) {
|
|
69
73
|
value = secret.value;
|
|
74
|
+
refs.push({ name: key, ...ref });
|
|
70
75
|
break;
|
|
71
76
|
}
|
|
72
77
|
}
|
|
@@ -75,13 +80,14 @@ async function resolveKeyReferencesForRow(text, row) {
|
|
|
75
80
|
}
|
|
76
81
|
values.set(key, value);
|
|
77
82
|
}
|
|
78
|
-
|
|
83
|
+
const value = text.replace(KEY_REFERENCE_REGEX, (_match, key) => {
|
|
79
84
|
const value = values.get(key);
|
|
80
85
|
if (value === undefined) {
|
|
81
86
|
throw new Error(`Referenced key "${key}" was not resolved.`);
|
|
82
87
|
}
|
|
83
88
|
return value;
|
|
84
89
|
});
|
|
90
|
+
return { value, refs };
|
|
85
91
|
}
|
|
86
92
|
function objectRecord(value) {
|
|
87
93
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
@@ -142,18 +148,27 @@ async function normalizeWorkspaceMcpConfig(row, parsed) {
|
|
|
142
148
|
if (typeof rawUrl !== "string" || !rawUrl.trim()) {
|
|
143
149
|
throw new Error("Workspace MCP server resource is missing a URL.");
|
|
144
150
|
}
|
|
145
|
-
const
|
|
146
|
-
const urlCheck = validateRemoteUrl(
|
|
147
|
-
if (!urlCheck.ok) {
|
|
151
|
+
const resolvedUrl = await resolveKeyReferencesForRow(rawUrl, row);
|
|
152
|
+
const urlCheck = validateRemoteUrl(resolvedUrl.value);
|
|
153
|
+
if (!urlCheck.ok || !urlCheck.url) {
|
|
148
154
|
throw new Error(urlCheck.error ?? "Workspace MCP server URL is not allowed.");
|
|
149
155
|
}
|
|
150
156
|
const headersInput = objectRecord(parsed.config.headers);
|
|
151
157
|
const headers = {};
|
|
158
|
+
const refs = [...resolvedUrl.refs];
|
|
152
159
|
if (headersInput) {
|
|
153
160
|
for (const [name, value] of Object.entries(headersInput)) {
|
|
154
161
|
if (typeof value !== "string")
|
|
155
162
|
continue;
|
|
156
|
-
|
|
163
|
+
const resolved = await resolveKeyReferencesForRow(value, row);
|
|
164
|
+
headers[name] = resolved.value;
|
|
165
|
+
refs.push(...resolved.refs);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const ref of refs) {
|
|
169
|
+
const allowlist = await getResolvedKeyAllowlist(ref);
|
|
170
|
+
if (!validateUrlAllowlist(urlCheck.url.href, allowlist)) {
|
|
171
|
+
throw new Error(`Workspace MCP destination is not approved for key "${ref.name}".`);
|
|
157
172
|
}
|
|
158
173
|
}
|
|
159
174
|
const description = typeof parsed.config.description === "string"
|
|
@@ -162,6 +177,7 @@ async function normalizeWorkspaceMcpConfig(row, parsed) {
|
|
|
162
177
|
return {
|
|
163
178
|
type: "http",
|
|
164
179
|
url: urlCheck.url.toString(),
|
|
180
|
+
...(refs.length > 0 ? { secretRequestOrigin: urlCheck.url.origin } : {}),
|
|
165
181
|
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
166
182
|
description,
|
|
167
183
|
};
|
|
@@ -272,16 +288,32 @@ export async function loadWorkspaceMcpServers(options) {
|
|
|
272
288
|
}
|
|
273
289
|
const servers = {};
|
|
274
290
|
for (const row of rows) {
|
|
291
|
+
let parsedServers;
|
|
275
292
|
try {
|
|
276
|
-
|
|
293
|
+
parsedServers = parseWorkspaceMcpServers(row);
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
servers[resourceServerKey(row, defaultNameFromPath(row.path))] = {
|
|
297
|
+
type: "http",
|
|
298
|
+
url: "https://invalid.invalid",
|
|
299
|
+
configurationError: error instanceof Error ? error : new Error(String(error)),
|
|
300
|
+
};
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
for (const parsed of parsedServers) {
|
|
304
|
+
try {
|
|
277
305
|
const config = await normalizeWorkspaceMcpConfig(row, parsed);
|
|
278
306
|
if (!config)
|
|
279
307
|
continue;
|
|
280
308
|
servers[resourceServerKey(row, parsed.name)] = config;
|
|
281
309
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
310
|
+
catch (error) {
|
|
311
|
+
servers[resourceServerKey(row, parsed.name)] = {
|
|
312
|
+
type: "http",
|
|
313
|
+
url: "https://invalid.invalid",
|
|
314
|
+
configurationError: error instanceof Error ? error : new Error(String(error)),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
285
317
|
}
|
|
286
318
|
}
|
|
287
319
|
return servers;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
2
|
+
error?: undefined;
|
|
2
3
|
count: number;
|
|
3
4
|
updated?: undefined;
|
|
4
|
-
error?: undefined;
|
|
5
5
|
ok?: undefined;
|
|
6
6
|
} | {
|
|
7
|
+
error?: undefined;
|
|
7
8
|
count?: undefined;
|
|
8
9
|
updated: number;
|
|
9
|
-
error?: undefined;
|
|
10
10
|
ok?: undefined;
|
|
11
11
|
} | {
|
|
12
12
|
count?: undefined;
|
|
@@ -14,8 +14,8 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
14
14
|
error: string;
|
|
15
15
|
ok?: undefined;
|
|
16
16
|
} | {
|
|
17
|
+
error?: undefined;
|
|
17
18
|
count?: undefined;
|
|
18
19
|
updated?: undefined;
|
|
19
|
-
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
21
21
|
}>>;
|
package/dist/org/handlers.d.ts
CHANGED
|
@@ -90,9 +90,9 @@ export declare const setWorkspaceAppDefaultVisibilityHandler: import("h3").Event
|
|
|
90
90
|
visibility: WorkspaceAppDefaultVisibility;
|
|
91
91
|
}>>;
|
|
92
92
|
export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
93
|
+
name?: undefined;
|
|
93
94
|
success: boolean;
|
|
94
95
|
id?: undefined;
|
|
95
|
-
name?: undefined;
|
|
96
96
|
role?: undefined;
|
|
97
97
|
} | {
|
|
98
98
|
success?: undefined;
|
package/dist/org/handlers.js
CHANGED
|
@@ -139,6 +139,16 @@ function requireAuthEmail(session) {
|
|
|
139
139
|
}
|
|
140
140
|
return email;
|
|
141
141
|
}
|
|
142
|
+
function requireVerifiedEmail(session) {
|
|
143
|
+
const email = requireAuthEmail(session);
|
|
144
|
+
if (session?.emailVerified !== true) {
|
|
145
|
+
throw createError({
|
|
146
|
+
statusCode: 403,
|
|
147
|
+
message: "Verify your email before joining an organization.",
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return email;
|
|
151
|
+
}
|
|
142
152
|
async function getSessionForEvent(event) {
|
|
143
153
|
const { getSession } = await import("../server/auth.js");
|
|
144
154
|
return getSession(event);
|
|
@@ -147,6 +157,8 @@ export const getMyOrgHandler = defineEventHandler(async (event) => {
|
|
|
147
157
|
const ctx = await getOrgContext(event);
|
|
148
158
|
const requestContext = getRequestContext();
|
|
149
159
|
const delegatedOrgMember = requestContext?.a2aIdentityAssurance === "org-member";
|
|
160
|
+
const emailVerified = !delegatedOrgMember &&
|
|
161
|
+
(await getSessionForEvent(event))?.emailVerified === true;
|
|
150
162
|
const delegatedEmail = requestContext?.userEmail?.trim().toLowerCase();
|
|
151
163
|
const delegatedOrgId = delegatedOrgMember
|
|
152
164
|
? requestContext.orgId?.trim()
|
|
@@ -218,9 +230,9 @@ export const getMyOrgHandler = defineEventHandler(async (event) => {
|
|
|
218
230
|
orgName: String(r.orgName ?? r.org_name),
|
|
219
231
|
}));
|
|
220
232
|
let domainMatches = [];
|
|
221
|
-
const domain =
|
|
222
|
-
?
|
|
223
|
-
:
|
|
233
|
+
const domain = emailVerified
|
|
234
|
+
? ctx.email.split("@")[1]?.toLowerCase()
|
|
235
|
+
: undefined;
|
|
224
236
|
if (domain) {
|
|
225
237
|
try {
|
|
226
238
|
const dmRes = await e.execute({
|
|
@@ -278,23 +290,15 @@ export const getMyOrgHandler = defineEventHandler(async (event) => {
|
|
|
278
290
|
const setting = await getOrgSetting(visibleOrgId, WORKSPACE_APP_DEFAULT_VISIBILITY_KEY);
|
|
279
291
|
workspaceAppDefaultVisibility = normalizeWorkspaceAppDefaultVisibility(setting?.visibility);
|
|
280
292
|
}
|
|
281
|
-
const invitesRes =
|
|
282
|
-
?
|
|
283
|
-
? await e.execute({
|
|
284
|
-
sql: `SELECT i.id AS id, i.org_id AS "orgId", o.name AS "orgName", i.invited_by AS "invitedBy"
|
|
285
|
-
FROM org_invitations i
|
|
286
|
-
INNER JOIN organizations o ON i.org_id = o.id
|
|
287
|
-
WHERE LOWER(i.email) = ? AND i.org_id = ? AND i.status = 'pending'`,
|
|
288
|
-
args: [ctx.email.toLowerCase(), scopedDelegatedOrgId],
|
|
289
|
-
})
|
|
290
|
-
: { rows: [] }
|
|
291
|
-
: await e.execute({
|
|
293
|
+
const invitesRes = emailVerified
|
|
294
|
+
? await e.execute({
|
|
292
295
|
sql: `SELECT i.id AS id, i.org_id AS "orgId", o.name AS "orgName", i.invited_by AS "invitedBy"
|
|
293
296
|
FROM org_invitations i
|
|
294
297
|
INNER JOIN organizations o ON i.org_id = o.id
|
|
295
298
|
WHERE LOWER(i.email) = ? AND i.status = 'pending'`,
|
|
296
299
|
args: [ctx.email.toLowerCase()],
|
|
297
|
-
})
|
|
300
|
+
})
|
|
301
|
+
: { rows: [] };
|
|
298
302
|
const pendingInvitations = invitesRes.rows.map((r) => ({
|
|
299
303
|
id: String(r.id),
|
|
300
304
|
orgId: String(r.orgId ?? r.org_id),
|
|
@@ -836,7 +840,7 @@ export const listInvitationsHandler = defineEventHandler(async (event) => {
|
|
|
836
840
|
});
|
|
837
841
|
export const acceptInvitationHandler = defineEventHandler(async (event) => {
|
|
838
842
|
const session = await getSessionForEvent(event);
|
|
839
|
-
const email =
|
|
843
|
+
const email = requireVerifiedEmail(session);
|
|
840
844
|
const invitationId = extractInvitationId(event);
|
|
841
845
|
if (!invitationId) {
|
|
842
846
|
throw createError({
|
|
@@ -1449,7 +1453,7 @@ export const switchOrgHandler = defineEventHandler(async (event) => {
|
|
|
1449
1453
|
});
|
|
1450
1454
|
export const joinByDomainHandler = defineEventHandler(async (event) => {
|
|
1451
1455
|
const session = await getSessionForEvent(event);
|
|
1452
|
-
const email =
|
|
1456
|
+
const email = requireVerifiedEmail(session);
|
|
1453
1457
|
const body = await readBody(event);
|
|
1454
1458
|
const orgId = body?.orgId;
|
|
1455
1459
|
if (!orgId) {
|
|
@@ -76,7 +76,7 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
76
76
|
}>>;
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
78
|
id?: undefined;
|
|
79
|
-
|
|
79
|
+
deleted?: undefined;
|
|
80
80
|
providers: {
|
|
81
81
|
id: string;
|
|
82
82
|
label: string;
|
|
@@ -89,45 +89,45 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
89
89
|
count: number;
|
|
90
90
|
provider?: undefined;
|
|
91
91
|
found?: undefined;
|
|
92
|
-
deleted?: undefined;
|
|
93
92
|
registered?: undefined;
|
|
94
93
|
label?: undefined;
|
|
94
|
+
message?: undefined;
|
|
95
95
|
} | {
|
|
96
96
|
id?: undefined;
|
|
97
|
-
|
|
98
|
-
message?: undefined;
|
|
97
|
+
deleted?: undefined;
|
|
99
98
|
providers?: undefined;
|
|
99
|
+
count?: undefined;
|
|
100
100
|
found: boolean;
|
|
101
101
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
102
|
-
deleted?: undefined;
|
|
103
102
|
registered?: undefined;
|
|
104
103
|
label?: undefined;
|
|
105
|
-
} | {
|
|
106
|
-
count?: undefined;
|
|
107
104
|
message?: undefined;
|
|
105
|
+
} | {
|
|
106
|
+
deleted?: undefined;
|
|
108
107
|
providers?: undefined;
|
|
108
|
+
count?: undefined;
|
|
109
109
|
provider?: undefined;
|
|
110
110
|
found: boolean;
|
|
111
111
|
id: string;
|
|
112
|
-
deleted?: undefined;
|
|
113
112
|
registered?: undefined;
|
|
114
113
|
label?: undefined;
|
|
115
|
-
} | {
|
|
116
|
-
count?: undefined;
|
|
117
114
|
message?: undefined;
|
|
115
|
+
} | {
|
|
118
116
|
providers?: undefined;
|
|
117
|
+
count?: undefined;
|
|
119
118
|
provider?: undefined;
|
|
120
119
|
found?: undefined;
|
|
121
120
|
deleted: boolean;
|
|
122
121
|
id: string;
|
|
123
122
|
registered?: undefined;
|
|
124
123
|
label?: undefined;
|
|
124
|
+
message?: undefined;
|
|
125
125
|
} | {
|
|
126
|
-
|
|
126
|
+
deleted?: undefined;
|
|
127
127
|
providers?: undefined;
|
|
128
|
+
count?: undefined;
|
|
128
129
|
provider?: undefined;
|
|
129
130
|
found?: undefined;
|
|
130
|
-
deleted?: undefined;
|
|
131
131
|
registered: boolean;
|
|
132
132
|
id: string;
|
|
133
133
|
label: string;
|
|
@@ -318,6 +318,7 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
318
318
|
}, {
|
|
319
319
|
id?: undefined;
|
|
320
320
|
provider?: undefined;
|
|
321
|
+
deleted?: undefined;
|
|
321
322
|
message?: undefined;
|
|
322
323
|
providers: {
|
|
323
324
|
id: string;
|
|
@@ -330,34 +331,33 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
330
331
|
}[];
|
|
331
332
|
count: number;
|
|
332
333
|
found?: undefined;
|
|
333
|
-
deleted?: undefined;
|
|
334
334
|
registered?: undefined;
|
|
335
335
|
label?: undefined;
|
|
336
336
|
} | {
|
|
337
337
|
id?: undefined;
|
|
338
|
+
deleted?: undefined;
|
|
339
|
+
count?: undefined;
|
|
338
340
|
message?: undefined;
|
|
339
341
|
providers?: undefined;
|
|
340
|
-
count?: undefined;
|
|
341
342
|
found: boolean;
|
|
342
343
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
343
|
-
deleted?: undefined;
|
|
344
344
|
registered?: undefined;
|
|
345
345
|
label?: undefined;
|
|
346
346
|
} | {
|
|
347
347
|
provider?: undefined;
|
|
348
|
+
deleted?: undefined;
|
|
349
|
+
count?: undefined;
|
|
348
350
|
message?: undefined;
|
|
349
351
|
providers?: undefined;
|
|
350
|
-
count?: undefined;
|
|
351
352
|
found: boolean;
|
|
352
353
|
id: string;
|
|
353
|
-
deleted?: undefined;
|
|
354
354
|
registered?: undefined;
|
|
355
355
|
label?: undefined;
|
|
356
356
|
} | {
|
|
357
357
|
provider?: undefined;
|
|
358
|
+
count?: undefined;
|
|
358
359
|
message?: undefined;
|
|
359
360
|
providers?: undefined;
|
|
360
|
-
count?: undefined;
|
|
361
361
|
found?: undefined;
|
|
362
362
|
deleted: boolean;
|
|
363
363
|
id: string;
|
|
@@ -365,10 +365,10 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
365
365
|
label?: undefined;
|
|
366
366
|
} | {
|
|
367
367
|
provider?: undefined;
|
|
368
|
-
|
|
368
|
+
deleted?: undefined;
|
|
369
369
|
count?: undefined;
|
|
370
|
+
providers?: undefined;
|
|
370
371
|
found?: undefined;
|
|
371
|
-
deleted?: undefined;
|
|
372
372
|
registered: boolean;
|
|
373
373
|
id: string;
|
|
374
374
|
label: string;
|
|
@@ -73,7 +73,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
73
73
|
offset?: unknown;
|
|
74
74
|
limit?: unknown;
|
|
75
75
|
}, {
|
|
76
|
-
deleted?: undefined;
|
|
77
76
|
jobs: {
|
|
78
77
|
id: string;
|
|
79
78
|
name: string;
|
|
@@ -84,6 +83,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
84
83
|
updatedAt: string;
|
|
85
84
|
}[];
|
|
86
85
|
total: number;
|
|
86
|
+
deleted?: undefined;
|
|
87
87
|
jobId?: undefined;
|
|
88
88
|
} | {
|
|
89
89
|
jobs?: undefined;
|
|
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
|
|
|
91
91
|
deleted: boolean;
|
|
92
92
|
jobId: string;
|
|
93
93
|
} | {
|
|
94
|
-
deleted?: undefined;
|
|
95
94
|
jobs?: undefined;
|
|
96
95
|
total?: undefined;
|
|
96
|
+
deleted?: undefined;
|
|
97
97
|
jobId?: undefined;
|
|
98
98
|
hits: Record<string, unknown>[];
|
|
99
99
|
offset: number;
|
|
@@ -4728,7 +4728,10 @@ async function fetchWithTimeout(optionsUrl, options) {
|
|
|
4728
4728
|
const method = options.method ?? "GET";
|
|
4729
4729
|
const secretValues = options.secretValues ?? [];
|
|
4730
4730
|
try {
|
|
4731
|
-
const dispatcher =
|
|
4731
|
+
const dispatcher = await createSsrfSafeDispatcher();
|
|
4732
|
+
if (!dispatcher) {
|
|
4733
|
+
throw new Error("SSRF protection is unavailable because the server dispatcher is empty.");
|
|
4734
|
+
}
|
|
4732
4735
|
const fetchOptions = {
|
|
4733
4736
|
method,
|
|
4734
4737
|
headers: options.headers,
|
|
@@ -4738,29 +4741,19 @@ async function fetchWithTimeout(optionsUrl, options) {
|
|
|
4738
4741
|
: controller.signal,
|
|
4739
4742
|
redirect: "manual",
|
|
4740
4743
|
};
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
delete fallbackOptions.dispatcher;
|
|
4755
|
-
return await fetchProviderResponse(optionsUrl, fallbackOptions, {
|
|
4756
|
-
maxBytes: options.maxBytes,
|
|
4757
|
-
maxResponseBytes: options.maxResponseBytes,
|
|
4758
|
-
secretValues,
|
|
4759
|
-
discardRedirectBody: options.discardRedirectBody,
|
|
4760
|
-
});
|
|
4761
|
-
}
|
|
4762
|
-
throw error;
|
|
4763
|
-
}
|
|
4744
|
+
fetchOptions.dispatcher = dispatcher;
|
|
4745
|
+
return await fetchProviderResponse(optionsUrl, fetchOptions, {
|
|
4746
|
+
...(options.maxBytes !== undefined
|
|
4747
|
+
? { maxBytes: options.maxBytes }
|
|
4748
|
+
: {}),
|
|
4749
|
+
...(options.maxResponseBytes !== undefined
|
|
4750
|
+
? { maxResponseBytes: options.maxResponseBytes }
|
|
4751
|
+
: {}),
|
|
4752
|
+
secretValues,
|
|
4753
|
+
...(options.discardRedirectBody !== undefined
|
|
4754
|
+
? { discardRedirectBody: options.discardRedirectBody }
|
|
4755
|
+
: {}),
|
|
4756
|
+
});
|
|
4764
4757
|
}
|
|
4765
4758
|
catch (error) {
|
|
4766
4759
|
throw normalizeFetchError(error, {
|
|
@@ -4898,18 +4891,6 @@ async function fetchProviderResponse(url, fetchOptions, options) {
|
|
|
4898
4891
|
json: parsed,
|
|
4899
4892
|
};
|
|
4900
4893
|
}
|
|
4901
|
-
function isDispatcherCompatibilityError(error) {
|
|
4902
|
-
const err = error;
|
|
4903
|
-
const code = typeof err?.cause?.code === "string" ? err.cause.code : "";
|
|
4904
|
-
const detail = [
|
|
4905
|
-
typeof err?.message === "string" ? err.message : "",
|
|
4906
|
-
typeof err?.cause?.message === "string" ? err.cause.message : "",
|
|
4907
|
-
]
|
|
4908
|
-
.join(" ")
|
|
4909
|
-
.toLowerCase();
|
|
4910
|
-
return (code === "UND_ERR_INVALID_ARG" &&
|
|
4911
|
-
detail.includes("invalid onrequeststart method"));
|
|
4912
|
-
}
|
|
4913
4894
|
function normalizeFetchError(error, options) {
|
|
4914
4895
|
const target = describeProviderRequestTarget(options.url, options.secretValues);
|
|
4915
4896
|
const err = error;
|
|
@@ -3,8 +3,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
3
3
|
resourceType: string;
|
|
4
4
|
resourceId: string;
|
|
5
5
|
targetId?: string | null | undefined;
|
|
6
|
+
surfaceId?: string | null | undefined;
|
|
6
7
|
kind?: "annotation" | "comment" | "correction" | "decision" | "question" | "review" | undefined;
|
|
7
8
|
anchor?: unknown;
|
|
9
|
+
anchorKind?: string | null | undefined;
|
|
10
|
+
anchorVersion?: number | null | undefined;
|
|
8
11
|
body: string;
|
|
9
12
|
authorName?: string | null | undefined;
|
|
10
13
|
resolutionTarget?: "agent" | "human" | null | undefined;
|
|
@@ -22,9 +25,13 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
22
25
|
threadId: string;
|
|
23
26
|
parentCommentId: string | null;
|
|
24
27
|
targetId: string | null;
|
|
28
|
+
surfaceId?: string | null;
|
|
25
29
|
kind: ReviewCommentKind;
|
|
26
30
|
status: import("../types.js").ReviewCommentStatus;
|
|
27
31
|
anchor: unknown;
|
|
32
|
+
anchorKind?: string | null;
|
|
33
|
+
anchorVersion?: number | null;
|
|
34
|
+
revision?: number;
|
|
28
35
|
body: string;
|
|
29
36
|
authorEmail: string | null;
|
|
30
37
|
authorName: string | null;
|