@agent-native/core 0.206.0-nightly-20261009153146 → 0.206.0
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 +7 -1
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/embed-auth.d.ts +2 -0
- package/dist/client/embed-auth.js +160 -12
- package/dist/client/host/index.d.ts +1 -1
- package/dist/client/host/index.js +1 -1
- package/dist/client/mcp-app-host.d.ts +1 -0
- package/dist/client/mcp-app-host.js +4 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/mcp/build-server.d.ts +15 -0
- package/dist/mcp/build-server.js +307 -91
- package/dist/mcp/connect-route.js +1 -0
- package/dist/mcp/embed-app.js +291 -31
- package/dist/mcp/oauth-route.js +3 -0
- package/dist/mcp/oauth-store.d.ts +2 -1
- package/dist/mcp/oauth-store.js +5 -6
- package/dist/mcp/oauth-token.d.ts +5 -0
- package/dist/mcp/oauth-token.js +17 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/workspace-app-access-request.d.ts +8 -0
- package/dist/org/workspace-app-access-request.js +20 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +11 -11
- package/dist/server/action-routes.d.ts +2 -0
- package/dist/server/action-routes.js +187 -31
- package/dist/server/agent-chat/mcp-options.d.ts +3 -1
- package/dist/server/agent-chat-plugin.js +26 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/auth.js +11 -20
- package/dist/server/embed-route.js +5 -3
- package/dist/server/embed-session.d.ts +30 -1
- package/dist/server/embed-session.js +376 -30
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +2 -0
- package/dist/server/request-context.js +25 -1
- package/dist/shared/embed-auth.d.ts +74 -0
- package/dist/shared/embed-auth.js +379 -10
- package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
- package/dist/triggers/actions/manage-automation.d.ts +3 -3
- package/package.json +4 -4
|
@@ -9,18 +9,20 @@ import { isTransientDatabaseError } from "../db/client.js";
|
|
|
9
9
|
import { declaresFeatureFlagDelegation } from "../feature-flags/a2a-action-route.js";
|
|
10
10
|
import { isFeatureFlagAdminEmail } from "../feature-flags/permissions.js";
|
|
11
11
|
import { isFederationMembershipValidatedForEvent, resolveOrgIdForEmail, } from "../org/context.js";
|
|
12
|
+
import { checkWorkspaceAppAccessForRequest } from "../org/workspace-app-access-request.js";
|
|
13
|
+
import { WORKSPACE_APP_ACCESS_UNAVAILABLE, WORKSPACE_APP_ACCESS_UNAVAILABLE_MESSAGE, } from "../org/workspace-app-access.js";
|
|
12
14
|
import { LLM_PROVIDER_MISSING_ERROR_CODE, LLM_PROVIDER_MISSING_STATUS, } from "../shared/action-error-codes.js";
|
|
13
15
|
import { agentNativeMcpInstructions, agentNativeToolTitle, } from "../shared/agent-mcp-metadata.js";
|
|
14
|
-
import { EMBED_TARGET_HEADER, EMBED_TARGET_QUERY_PARAM, EMBED_TOKEN_QUERY_PARAM, allowsMcpDirectoryWidgetReadAction, isMcpDirectoryWidgetReadCapabilityScope, normalizeMcpDirectoryWidgetReadActionArguments, } from "../shared/embed-auth.js";
|
|
16
|
+
import { EMBED_TARGET_HEADER, EMBED_TARGET_QUERY_PARAM, EMBED_TOKEN_QUERY_PARAM, MCP_DIRECTORY_WIDGET_SESSION_EXPIRED_HEADER, allowsMcpDirectoryWidgetReadAction, getMcpDirectoryWidgetWriteCapabilityGrant, isExpiredMcpDirectoryWidgetWriteCapability, isMcpDirectoryWidgetCapabilityScope, isMcpDirectoryWidgetReadCapabilityScope, isMcpDirectoryWidgetWriteCapabilityScope, normalizeMcpDirectoryWidgetReadActionArguments, normalizeMcpDirectoryWidgetWriteActionArguments, } from "../shared/embed-auth.js";
|
|
15
17
|
import { isMcpEmbedCorsOrigin, MCP_EMBED_CORS_ALLOW_HEADERS, shouldAllowMcpEmbedCredentials, } from "../shared/mcp-embed-headers.js";
|
|
16
18
|
import { countActionFailure, countCredentialState, } from "../tracking/failure-counters.js";
|
|
17
19
|
import { redact, redactErrorStack } from "../tracking/redaction.js";
|
|
18
20
|
import { notifyActionChange } from "./action-change.js";
|
|
19
|
-
import { readBrowserSessionIdHeader, readBrowserTabIdHeader, readAnalyticsClientPlatformHeader, readSyntheticTrafficHeader, seedAgentRunOwnerContext, } from "./agent-run-context.js";
|
|
21
|
+
import { readBrowserSessionIdHeader, readBrowserTabIdHeader, readAnalyticsClientPlatformHeader, readSyntheticTrafficHeader, resolveAgentRunOrgId, seedAgentRunOwnerContext, } from "./agent-run-context.js";
|
|
20
22
|
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
21
23
|
import { captureError } from "./capture-error.js";
|
|
22
24
|
import { getAllowedCorsOrigin as resolveAllowedCorsOrigin, readCorsAllowedOrigins, } from "./cors-origins.js";
|
|
23
|
-
import { resolveEmbedSessionFromRequest, resolvedEmbedCapabilityScope, } from "./embed-session.js";
|
|
25
|
+
import { hasExplicitEmbedSessionCredential, isExpiredMcpDirectoryWidgetSessionRequest, resolveEmbedSessionFromRequest, resolvedEmbedCapabilityScope, } from "./embed-session.js";
|
|
24
26
|
import { readBodyWithSizeLimit } from "./h3-helpers.js";
|
|
25
27
|
import { getHttpRequestTelemetryId, registerHttpRequestTelemetryActionRoute, setHttpRequestTelemetryActionName, } from "./http-response-telemetry.js";
|
|
26
28
|
import { consumeOneTimeJti } from "./identity-sso-store.js";
|
|
@@ -47,6 +49,7 @@ import { getVerifiedServiceIdentityFromEvent, getRequestIdentityAuthenticatedAtM
|
|
|
47
49
|
const ROUTE_PREFIX = "/_agent-native/actions";
|
|
48
50
|
const WEBMCP_ACTION_ROUTE_PREFIX = "/_agent-native/webmcp/actions";
|
|
49
51
|
const MAX_MCP_DIRECTORY_WIDGET_SCHEMA_ARGUMENT_BYTES = 32 * 1024;
|
|
52
|
+
const MAX_MCP_DIRECTORY_WIDGET_WRITE_SCHEMA_ARGUMENT_BYTES = 1024 * 1024;
|
|
50
53
|
const FRONTEND_MUTATION_METHODS = new Set(["POST", "PUT", "DELETE"]);
|
|
51
54
|
const EMBED_ACTION_QUERY_PARAMS = new Set([
|
|
52
55
|
EMBED_TARGET_QUERY_PARAM,
|
|
@@ -307,13 +310,14 @@ function allowsWebMcpCapabilityResource(authCapability, params) {
|
|
|
307
310
|
}
|
|
308
311
|
}
|
|
309
312
|
async function resolveRequestAuthCapability(event) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
const session = await resolveEmbedSessionFromRequest(event);
|
|
314
|
+
if (!session && hasExplicitEmbedSessionCredential(event)) {
|
|
315
|
+
if (await isExpiredMcpDirectoryWidgetSessionRequest(event)) {
|
|
316
|
+
setResponseHeader(event, MCP_DIRECTORY_WIDGET_SESSION_EXPIRED_HEADER, "1");
|
|
317
|
+
}
|
|
318
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
316
319
|
}
|
|
320
|
+
return resolvedEmbedCapabilityScope(session);
|
|
317
321
|
}
|
|
318
322
|
function resolveRequestEmbedSession(event) {
|
|
319
323
|
return resolveEmbedSessionFromRequest(event);
|
|
@@ -335,7 +339,9 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
335
339
|
(Array.isArray(entry.capabilityScopes) &&
|
|
336
340
|
entry.capabilityScopes.length) ||
|
|
337
341
|
(!options?.caller &&
|
|
338
|
-
options?.mcpDirectoryWidgetReadActionArguments?.[name] !== undefined
|
|
342
|
+
(options?.mcpDirectoryWidgetReadActionArguments?.[name] !== undefined ||
|
|
343
|
+
options?.mcpDirectoryWidgetWriteActionArguments?.[name] !==
|
|
344
|
+
undefined))) {
|
|
339
345
|
registerAuthPublicPaths([routePath], app);
|
|
340
346
|
}
|
|
341
347
|
if (!options?.caller &&
|
|
@@ -351,7 +357,7 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
351
357
|
return handleOptionsRequest(event);
|
|
352
358
|
}
|
|
353
359
|
setResponseHeader(event, "Cache-Control", "no-store");
|
|
354
|
-
setResponseHeader(event, "Access-Control-Expose-Headers",
|
|
360
|
+
setResponseHeader(event, "Access-Control-Expose-Headers", `X-Agent-Native-Client-Mismatch,X-Agent-Native-Build-Id,X-Agent-Native-Client-Compatibility,Retry-After,${MCP_DIRECTORY_WIDGET_SESSION_EXPIRED_HEADER}`);
|
|
355
361
|
const isFrontendMutation = isFrontendActionRequest(event) &&
|
|
356
362
|
FRONTEND_MUTATION_METHODS.has(method) &&
|
|
357
363
|
FRONTEND_MUTATION_METHODS.has(effectiveMethod);
|
|
@@ -387,14 +393,23 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
387
393
|
let userName;
|
|
388
394
|
let authUserId;
|
|
389
395
|
const authCapability = await resolveRequestAuthCapability(event);
|
|
390
|
-
const
|
|
391
|
-
const
|
|
396
|
+
const directoryWidgetWriteCapability = isMcpDirectoryWidgetWriteCapabilityScope(authCapability);
|
|
397
|
+
const directoryWidgetCapability = isMcpDirectoryWidgetCapabilityScope(authCapability);
|
|
398
|
+
const embedSession = directoryWidgetCapability
|
|
392
399
|
? await resolveRequestEmbedSession(event)
|
|
393
400
|
: null;
|
|
401
|
+
const directoryWidgetWriteGrant = directoryWidgetWriteCapability && embedSession
|
|
402
|
+
? getMcpDirectoryWidgetWriteCapabilityGrant(authCapability, {
|
|
403
|
+
appId: options?.mcpDirectoryWidgetAppId ?? options?.appId ?? "",
|
|
404
|
+
resourceUri: options?.mcpDirectoryWidgetResourceUri ?? "",
|
|
405
|
+
userEmail: embedSession.email,
|
|
406
|
+
orgId: embedSession.orgId,
|
|
407
|
+
})
|
|
408
|
+
: undefined;
|
|
394
409
|
const directoryWidgetReadRequest = isFrontendActionRequest(event) ||
|
|
395
410
|
(options?.caller === "webmcp" &&
|
|
396
411
|
options.routePrefix === WEBMCP_ACTION_ROUTE_PREFIX);
|
|
397
|
-
const directoryWidgetReadAllowed =
|
|
412
|
+
const directoryWidgetReadAllowed = directoryWidgetCapability &&
|
|
398
413
|
embedSession !== null &&
|
|
399
414
|
directoryWidgetReadRequest &&
|
|
400
415
|
entry.http !== false &&
|
|
@@ -411,19 +426,34 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
411
426
|
actionName: name,
|
|
412
427
|
appId: options.mcpDirectoryWidgetAppId ?? options.appId,
|
|
413
428
|
resourceUri: options.mcpDirectoryWidgetResourceUri,
|
|
429
|
+
userEmail: embedSession?.email,
|
|
430
|
+
orgId: embedSession?.orgId,
|
|
414
431
|
allowedArgumentNames: options.mcpDirectoryWidgetReadActionArguments[name],
|
|
415
432
|
requireArgumentMatch: false,
|
|
416
433
|
});
|
|
434
|
+
const directoryWidgetWriteAllowed = directoryWidgetWriteCapability &&
|
|
435
|
+
embedSession !== null &&
|
|
436
|
+
isFrontendActionRequest(event) &&
|
|
437
|
+
entry.http !== false &&
|
|
438
|
+
entry.http?.method !== "GET" &&
|
|
439
|
+
entry.readOnly !== true &&
|
|
440
|
+
entry.requiresAuth !== false &&
|
|
441
|
+
options?.mcpDirectoryWidgetWriteActionArguments?.[name] !== undefined;
|
|
442
|
+
let directoryWidgetWriteResourceIds;
|
|
417
443
|
const directoryWidgetReadRoute = options?.mcpDirectoryWidgetReadActionArguments?.[name] !==
|
|
418
444
|
undefined &&
|
|
419
445
|
options?.mcpDirectoryWidgetReadPublicActions?.includes(name) !== true;
|
|
420
|
-
|
|
446
|
+
const directoryWidgetWriteRoute = options?.mcpDirectoryWidgetWriteActionArguments?.[name] !== undefined;
|
|
447
|
+
if (directoryWidgetCapability &&
|
|
448
|
+
!directoryWidgetReadAllowed &&
|
|
449
|
+
!directoryWidgetWriteAllowed) {
|
|
421
450
|
setResponseStatus(event, 403);
|
|
422
451
|
return {
|
|
423
452
|
error: "This widget capability only permits its scoped data routes.",
|
|
424
453
|
};
|
|
425
454
|
}
|
|
426
|
-
if (directoryWidgetReadAllowed
|
|
455
|
+
if ((directoryWidgetReadAllowed || directoryWidgetWriteAllowed) &&
|
|
456
|
+
embedSession) {
|
|
427
457
|
userEmail = embedSession.email;
|
|
428
458
|
if (embedSession.orgId == null)
|
|
429
459
|
markExplicitPersonalOrgScope(event);
|
|
@@ -446,9 +476,11 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
446
476
|
let directoryWidgetReadAuthenticatedFallback = false;
|
|
447
477
|
const capabilityAllowed = (options?.caller === "webmcp" || isFrontendActionRequest(event)) &&
|
|
448
478
|
(allowsWebMcpCapability(entry, authCapability) ||
|
|
449
|
-
directoryWidgetReadAllowed
|
|
479
|
+
directoryWidgetReadAllowed ||
|
|
480
|
+
directoryWidgetWriteAllowed);
|
|
450
481
|
if (options?.allowDelegatedCaller !== false &&
|
|
451
|
-
!directoryWidgetReadAllowed
|
|
482
|
+
!directoryWidgetReadAllowed &&
|
|
483
|
+
!directoryWidgetWriteAllowed) {
|
|
452
484
|
let caller;
|
|
453
485
|
try {
|
|
454
486
|
caller = options?.actionRouteAuth?.resolveCaller
|
|
@@ -512,9 +544,71 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
512
544
|
}
|
|
513
545
|
}
|
|
514
546
|
}
|
|
547
|
+
if (directoryWidgetWriteRoute && !directoryWidgetWriteAllowed) {
|
|
548
|
+
let ownerContext;
|
|
549
|
+
if (resolvedCaller) {
|
|
550
|
+
if (resolvedCaller.anonymous) {
|
|
551
|
+
setResponseStatus(event, 401);
|
|
552
|
+
return { error: "Unauthorized" };
|
|
553
|
+
}
|
|
554
|
+
ownerContext = resolvedCaller;
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
if (!options?.getOwnerContextFromEvent) {
|
|
558
|
+
setResponseStatus(event, 401);
|
|
559
|
+
return { error: "Unauthorized" };
|
|
560
|
+
}
|
|
561
|
+
try {
|
|
562
|
+
ownerContext = await options.getOwnerContextFromEvent(event);
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
if (!isAuthResolutionFailure(error))
|
|
566
|
+
throw error;
|
|
567
|
+
setResponseStatus(event, 401);
|
|
568
|
+
return { error: "Unauthorized" };
|
|
569
|
+
}
|
|
570
|
+
if (ownerContext.anonymous) {
|
|
571
|
+
setResponseStatus(event, 401);
|
|
572
|
+
return { error: "Unauthorized" };
|
|
573
|
+
}
|
|
574
|
+
userEmail = ownerContext.owner;
|
|
575
|
+
userName = ownerContext.name;
|
|
576
|
+
authUserId = ownerContext.authUserId;
|
|
577
|
+
ownerContextResolved = true;
|
|
578
|
+
}
|
|
579
|
+
const workspaceOrgId = resolvedCaller
|
|
580
|
+
? resolvedCaller.orgId === null
|
|
581
|
+
? undefined
|
|
582
|
+
: (normalizeOrgId(resolvedCaller.orgId) ??
|
|
583
|
+
(resolvedCaller.owner && !resolvedCaller.anonymous
|
|
584
|
+
? await storedActiveOrgId(resolvedCaller.owner)
|
|
585
|
+
: undefined))
|
|
586
|
+
: await resolveAgentRunOrgId({
|
|
587
|
+
event,
|
|
588
|
+
ownerContext,
|
|
589
|
+
resolveOrgId: options?.resolveOrgId,
|
|
590
|
+
});
|
|
591
|
+
const workspaceAppAccess = await checkWorkspaceAppAccessForRequest({
|
|
592
|
+
path: `/_agent-native/actions/${name}`,
|
|
593
|
+
method: getMethod(event),
|
|
594
|
+
email: ownerContext.owner,
|
|
595
|
+
orgId: workspaceOrgId,
|
|
596
|
+
});
|
|
597
|
+
if (workspaceAppAccess === WORKSPACE_APP_ACCESS_UNAVAILABLE) {
|
|
598
|
+
setResponseStatus(event, 503);
|
|
599
|
+
return { error: WORKSPACE_APP_ACCESS_UNAVAILABLE_MESSAGE };
|
|
600
|
+
}
|
|
601
|
+
if (workspaceAppAccess === false) {
|
|
602
|
+
setResponseStatus(event, 403);
|
|
603
|
+
return {
|
|
604
|
+
error: "You do not have access to this workspace app.",
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
}
|
|
515
608
|
if (!resolvedCaller &&
|
|
516
609
|
!ownerContextResolved &&
|
|
517
610
|
!directoryWidgetReadAllowed &&
|
|
611
|
+
!directoryWidgetWriteAllowed &&
|
|
518
612
|
options?.caller === "webmcp" &&
|
|
519
613
|
options?.getOwnerContextFromEvent) {
|
|
520
614
|
ownerContextResolved = true;
|
|
@@ -549,6 +643,7 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
549
643
|
if (!resolvedCaller &&
|
|
550
644
|
!ownerContextResolved &&
|
|
551
645
|
!directoryWidgetReadAllowed &&
|
|
646
|
+
!directoryWidgetWriteAllowed &&
|
|
552
647
|
options?.getOwnerFromEvent) {
|
|
553
648
|
try {
|
|
554
649
|
userEmail = await options.getOwnerFromEvent(event);
|
|
@@ -574,6 +669,7 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
574
669
|
!resolvedCaller &&
|
|
575
670
|
!directoryWidgetReadAuthenticatedFallback &&
|
|
576
671
|
!directoryWidgetReadAllowed &&
|
|
672
|
+
!directoryWidgetWriteAllowed &&
|
|
577
673
|
options?.getAuthUserIdFromEvent) {
|
|
578
674
|
try {
|
|
579
675
|
authUserId = await options.getAuthUserIdFromEvent(event);
|
|
@@ -593,7 +689,8 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
593
689
|
// token caller's actions execute under. Non-adapter callers keep the
|
|
594
690
|
// original resolveOrgId-only behavior.
|
|
595
691
|
let orgId;
|
|
596
|
-
if (directoryWidgetReadAllowed
|
|
692
|
+
if ((directoryWidgetReadAllowed || directoryWidgetWriteAllowed) &&
|
|
693
|
+
embedSession) {
|
|
597
694
|
orgId = normalizeOrgId(embedSession.orgId);
|
|
598
695
|
}
|
|
599
696
|
else if (resolvedCaller) {
|
|
@@ -746,6 +843,8 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
746
843
|
appId: options.mcpDirectoryWidgetAppId ?? options.appId,
|
|
747
844
|
resourceUri: options.mcpDirectoryWidgetResourceUri,
|
|
748
845
|
args: params,
|
|
846
|
+
userEmail: embedSession?.email,
|
|
847
|
+
orgId: embedSession?.orgId,
|
|
749
848
|
allowedArgumentNames: options.mcpDirectoryWidgetReadActionArguments?.[name],
|
|
750
849
|
});
|
|
751
850
|
if (!normalizedArgs) {
|
|
@@ -756,6 +855,42 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
756
855
|
}
|
|
757
856
|
params = normalizedArgs;
|
|
758
857
|
}
|
|
858
|
+
if (directoryWidgetWriteAllowed) {
|
|
859
|
+
const normalizedArgs = normalizeMcpDirectoryWidgetWriteActionArguments(authCapability, {
|
|
860
|
+
actionName: name,
|
|
861
|
+
appId: options.mcpDirectoryWidgetAppId ?? options.appId,
|
|
862
|
+
resourceUri: options.mcpDirectoryWidgetResourceUri,
|
|
863
|
+
userEmail: embedSession?.email,
|
|
864
|
+
orgId: embedSession?.orgId,
|
|
865
|
+
args: params,
|
|
866
|
+
allowedArgumentNames: options.mcpDirectoryWidgetWriteActionArguments?.[name],
|
|
867
|
+
});
|
|
868
|
+
directoryWidgetWriteResourceIds =
|
|
869
|
+
getMcpDirectoryWidgetWriteCapabilityGrant(authCapability, {
|
|
870
|
+
appId: options.mcpDirectoryWidgetAppId ?? options.appId ?? "",
|
|
871
|
+
resourceUri: options.mcpDirectoryWidgetResourceUri ?? "",
|
|
872
|
+
userEmail: embedSession?.email ?? "",
|
|
873
|
+
orgId: embedSession?.orgId,
|
|
874
|
+
})?.resourceIds;
|
|
875
|
+
if (!normalizedArgs || !directoryWidgetWriteResourceIds) {
|
|
876
|
+
const expired = isExpiredMcpDirectoryWidgetWriteCapability(authCapability, {
|
|
877
|
+
appId: options.mcpDirectoryWidgetAppId ?? options.appId ?? "",
|
|
878
|
+
resourceUri: options.mcpDirectoryWidgetResourceUri ?? "",
|
|
879
|
+
userEmail: embedSession?.email ?? "",
|
|
880
|
+
orgId: embedSession?.orgId,
|
|
881
|
+
});
|
|
882
|
+
if (expired) {
|
|
883
|
+
setResponseHeader(event, MCP_DIRECTORY_WIDGET_SESSION_EXPIRED_HEADER, "1");
|
|
884
|
+
}
|
|
885
|
+
throw createError({
|
|
886
|
+
statusCode: expired ? 401 : 403,
|
|
887
|
+
statusMessage: expired
|
|
888
|
+
? "Unauthorized"
|
|
889
|
+
: "This widget write capability is scoped to a different user, app resource, or action.",
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
params = normalizedArgs;
|
|
893
|
+
}
|
|
759
894
|
if (capabilityAllowed &&
|
|
760
895
|
!userEmail &&
|
|
761
896
|
!allowsWebMcpCapabilityResource(authCapability, params)) {
|
|
@@ -766,12 +901,14 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
766
901
|
}
|
|
767
902
|
const caller = directoryWidgetReadAllowed
|
|
768
903
|
? "mcp-widget"
|
|
769
|
-
:
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
? "
|
|
774
|
-
:
|
|
904
|
+
: directoryWidgetWriteAllowed
|
|
905
|
+
? "mcp-widget-write"
|
|
906
|
+
: (options?.caller ??
|
|
907
|
+
(resolvedCaller
|
|
908
|
+
? "a2a"
|
|
909
|
+
: isFrontendActionRequest(event)
|
|
910
|
+
? "frontend"
|
|
911
|
+
: "http"));
|
|
775
912
|
const runContext = {
|
|
776
913
|
userEmail,
|
|
777
914
|
orgId: orgId ?? null,
|
|
@@ -781,6 +918,18 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
781
918
|
...(directoryWidgetReadAllowed
|
|
782
919
|
? { mcpDirectoryWidgetReadOnly: true }
|
|
783
920
|
: {}),
|
|
921
|
+
...(directoryWidgetWriteGrant &&
|
|
922
|
+
(directoryWidgetWriteAllowed || directoryWidgetReadAllowed)
|
|
923
|
+
? {
|
|
924
|
+
mcpDirectoryWidgetWrite: {
|
|
925
|
+
appId: options?.mcpDirectoryWidgetAppId ??
|
|
926
|
+
options?.appId ??
|
|
927
|
+
"",
|
|
928
|
+
resourceIds: directoryWidgetWriteGrant.resourceIds,
|
|
929
|
+
actionNames: directoryWidgetWriteGrant.actionNames,
|
|
930
|
+
},
|
|
931
|
+
}
|
|
932
|
+
: {}),
|
|
784
933
|
...(event.req?.signal ? { signal: event.req.signal } : {}),
|
|
785
934
|
actionName: name,
|
|
786
935
|
...(resolvedCaller?.delegationJti
|
|
@@ -816,16 +965,23 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
816
965
|
throw new ActionContractError(`"${name}" requires human approval for these arguments. WebMCP tool calls cannot grant that approval themselves — ask the user to confirm this action in chat, then call it there.`, { errorCode: "approval_required", statusCode: 409 });
|
|
817
966
|
}
|
|
818
967
|
}
|
|
819
|
-
else if (directoryWidgetReadAllowed &&
|
|
820
|
-
(
|
|
821
|
-
?.
|
|
822
|
-
|
|
968
|
+
else if ((directoryWidgetReadAllowed || directoryWidgetWriteAllowed) &&
|
|
969
|
+
((directoryWidgetReadAllowed
|
|
970
|
+
? options?.mcpDirectoryWidgetReadActionSchemaArguments?.[name]
|
|
971
|
+
: options?.mcpDirectoryWidgetWriteActionSchemaArguments?.[name])?.length ?? 0) > 0) {
|
|
972
|
+
const schemaArguments = directoryWidgetReadAllowed
|
|
973
|
+
? options?.mcpDirectoryWidgetReadActionSchemaArguments?.[name]
|
|
974
|
+
: options?.mcpDirectoryWidgetWriteActionSchemaArguments?.[name];
|
|
975
|
+
const maxSchemaArgumentBytes = directoryWidgetWriteAllowed
|
|
976
|
+
? MAX_MCP_DIRECTORY_WIDGET_WRITE_SCHEMA_ARGUMENT_BYTES
|
|
977
|
+
: MAX_MCP_DIRECTORY_WIDGET_SCHEMA_ARGUMENT_BYTES;
|
|
978
|
+
const oversizedSchemaArgument = schemaArguments?.find((argumentName) => {
|
|
823
979
|
if (!Object.hasOwn(params, argumentName))
|
|
824
980
|
return false;
|
|
825
981
|
const serialized = JSON.stringify(params[argumentName]);
|
|
826
982
|
return (typeof serialized !== "string" ||
|
|
827
983
|
new TextEncoder().encode(serialized).byteLength >
|
|
828
|
-
|
|
984
|
+
maxSchemaArgumentBytes);
|
|
829
985
|
});
|
|
830
986
|
if (oversizedSchemaArgument) {
|
|
831
987
|
throw new ActionContractError("MCP directory widget query arguments exceed the supported size.", {
|
|
@@ -836,7 +992,7 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
836
992
|
if (!entry.schema ||
|
|
837
993
|
typeof entry.schema !== "object" ||
|
|
838
994
|
!("~standard" in entry.schema)) {
|
|
839
|
-
throw new Error(`MCP directory widget
|
|
995
|
+
throw new Error(`MCP directory widget action "${name}" requires an input schema.`);
|
|
840
996
|
}
|
|
841
997
|
params = await validateActionArgs(entry.schema, params, entry.tool.parameters, runContext);
|
|
842
998
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpDirectoryWidgetTarget } from "../../mcp/build-server.js";
|
|
1
|
+
import type { MCPConfig, McpDirectoryWidgetTarget } from "../../mcp/build-server.js";
|
|
2
2
|
import type { ExternalAgentPolicy } from "../../mcp/external-agent-policy.js";
|
|
3
3
|
import type { McpDirectoryWidgetReadArgument } from "../../shared/embed-auth.js";
|
|
4
4
|
export interface AgentChatMcpIcon {
|
|
@@ -16,7 +16,9 @@ export interface AgentChatMcpOptions {
|
|
|
16
16
|
instructions?: string;
|
|
17
17
|
widgets?: boolean;
|
|
18
18
|
widgetTargets?: Record<string, (args: Record<string, unknown>, result: unknown) => McpDirectoryWidgetTarget | null>;
|
|
19
|
+
authorizeWidgetWrite?: NonNullable<MCPConfig["directoryProfile"]>["authorizeWidgetWrite"];
|
|
19
20
|
widgetReadActionArguments?: Record<string, Record<string, McpDirectoryWidgetReadArgument>>;
|
|
21
|
+
widgetWriteActionArguments?: Record<string, Record<string, McpDirectoryWidgetReadArgument>>;
|
|
20
22
|
/** Actions whose capability-backed `mcp-widget` execution is strictly read-only. */
|
|
21
23
|
widgetReadOnlyActions?: readonly string[];
|
|
22
24
|
/** Unlisted public reads that are available only through a scoped widget ticket. */
|
|
@@ -2330,7 +2330,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2330
2330
|
};
|
|
2331
2331
|
if (mcpOptions.enabled) {
|
|
2332
2332
|
// Mount MCP remote server — same action registry as A2A + agent chat
|
|
2333
|
-
const { mountMCP, selectMcpDirectoryWidgetReadActions } = await import("../mcp/server.js");
|
|
2333
|
+
const { mountMCP, selectMcpDirectoryWidgetReadActions, selectMcpDirectoryWidgetWriteActions, } = await import("../mcp/server.js");
|
|
2334
2334
|
mountMCP(nitroApp, {
|
|
2335
2335
|
name: mcpServerName,
|
|
2336
2336
|
title: mcpOptions.title,
|
|
@@ -2345,6 +2345,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2345
2345
|
actions: externalActions,
|
|
2346
2346
|
productionActions: externalFullActions,
|
|
2347
2347
|
widgetReadActions: selectMcpDirectoryWidgetReadActions(mcpOptions.directoryProfile, templateScriptsAll),
|
|
2348
|
+
widgetWriteActions: selectMcpDirectoryWidgetWriteActions(mcpOptions.directoryProfile, templateScriptsAll),
|
|
2348
2349
|
...(mcpOptions.catalog ? { catalogMode: mcpOptions.catalog } : {}),
|
|
2349
2350
|
...(mcpOptions.builtinCrossAppTools !== undefined
|
|
2350
2351
|
? { builtinCrossAppTools: mcpOptions.builtinCrossAppTools }
|
|
@@ -2605,6 +2606,29 @@ export function createAgentChatPlugin(options) {
|
|
|
2605
2606
|
mcpDirectoryWidgetResourceUri: getMcpDirectoryWidgetResourceUri(options?.appId ?? mcpServerName),
|
|
2606
2607
|
}
|
|
2607
2608
|
: {};
|
|
2609
|
+
const mcpDirectoryWidgetWriteOptions = directoryProfile
|
|
2610
|
+
? {
|
|
2611
|
+
mcpDirectoryWidgetWriteActionArguments: Object.fromEntries(Object.entries(directoryProfile.widgetWriteActionArguments ?? {})
|
|
2612
|
+
.filter(([name]) => httpActions[name] &&
|
|
2613
|
+
httpActions[name]?.http !== false &&
|
|
2614
|
+
httpActions[name]?.http?.method !== "GET" &&
|
|
2615
|
+
httpActions[name]?.requiresAuth !== false &&
|
|
2616
|
+
httpActions[name]?.readOnly !== true)
|
|
2617
|
+
.map(([name, args]) => [name, Object.keys(args)])),
|
|
2618
|
+
mcpDirectoryWidgetWriteActionSchemaArguments: Object.fromEntries(Object.entries(directoryProfile.widgetWriteActionArguments ?? {})
|
|
2619
|
+
.map(([name, args]) => [
|
|
2620
|
+
name,
|
|
2621
|
+
Object.entries(args)
|
|
2622
|
+
.filter(([, argument]) => typeof argument !== "string" &&
|
|
2623
|
+
(argument.type === "actionSchema" ||
|
|
2624
|
+
argument.type === "actionSchemaResourceBound"))
|
|
2625
|
+
.map(([argumentName]) => argumentName),
|
|
2626
|
+
])
|
|
2627
|
+
.filter(([, argumentNames]) => argumentNames.length > 0)),
|
|
2628
|
+
mcpDirectoryWidgetAppId: options?.appId ?? mcpServerName,
|
|
2629
|
+
mcpDirectoryWidgetResourceUri: getMcpDirectoryWidgetResourceUri(options?.appId ?? mcpServerName),
|
|
2630
|
+
}
|
|
2631
|
+
: {};
|
|
2608
2632
|
if (Object.keys(httpActions).length > 0) {
|
|
2609
2633
|
if (options?.actionRoutePublicPaths?.length) {
|
|
2610
2634
|
registerAuthPublicPaths(options.actionRoutePublicPaths, getH3App(nitroApp));
|
|
@@ -2619,6 +2643,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2619
2643
|
resolveOrgId: options?.resolveOrgId,
|
|
2620
2644
|
actionRouteAuth: options?.actionRouteAuth,
|
|
2621
2645
|
...mcpDirectoryWidgetReadOptions,
|
|
2646
|
+
...mcpDirectoryWidgetWriteOptions,
|
|
2622
2647
|
});
|
|
2623
2648
|
}
|
|
2624
2649
|
// Dev-only loopback endpoint `pnpm action` forwards to so it doesn't
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
2
2
|
error: string;
|
|
3
|
-
models?: undefined;
|
|
4
3
|
ok?: undefined;
|
|
4
|
+
models?: undefined;
|
|
5
5
|
} | {
|
|
6
|
+
error?: undefined;
|
|
6
7
|
ok: boolean;
|
|
7
8
|
models: string[];
|
|
8
|
-
error?: undefined;
|
|
9
9
|
}>>;
|
package/dist/server/auth.js
CHANGED
|
@@ -3,9 +3,9 @@ import { defineEventHandler, getMethod, getQuery, setResponseHeader, setResponse
|
|
|
3
3
|
import { getAppConfig, resolveAppHomePath } from "../app-config/index.js";
|
|
4
4
|
import { acceptPendingInvitationsForEmail } from "../org/accept-pending.js";
|
|
5
5
|
import { newOrgSelection, ORG_SELECTION_COOKIE, } from "../org/request-org-cache.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TARGET_HEADER,
|
|
6
|
+
import { checkWorkspaceAppAccessForRequest } from "../org/workspace-app-access-request.js";
|
|
7
|
+
import { WORKSPACE_APP_ACCESS_UNAVAILABLE, WORKSPACE_APP_ACCESS_UNAVAILABLE_MESSAGE, } from "../org/workspace-app-access.js";
|
|
8
|
+
import { EMBED_SESSION_COOKIE, EMBED_START_PATH, EMBED_TARGET_HEADER, isMcpDirectoryWidgetCapabilityScope, } from "../shared/embed-auth.js";
|
|
9
9
|
import { FIRST_RUN_ONBOARDING_COOKIE, FIRST_RUN_ONBOARDING_MAX_AGE, } from "../shared/first-run-onboarding.js";
|
|
10
10
|
import { isGoogleProfileImageUrl } from "../shared/google-profile-image.js";
|
|
11
11
|
import { EMBED_TRANSPLANT_HEADER, isMcpEmbedCorsOrigin, MCP_EMBED_CORS_ALLOW_HEADERS, shouldAllowMcpEmbedCredentials, } from "../shared/mcp-embed-headers.js";
|
|
@@ -3038,20 +3038,11 @@ function createAuthGuardFn(app) {
|
|
|
3038
3038
|
}
|
|
3039
3039
|
const session = await getSession(event);
|
|
3040
3040
|
if (session) {
|
|
3041
|
-
const workspaceAppId = resolveWorkspaceAccessAppId();
|
|
3042
3041
|
const method = getMethod(event);
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
(method === "POST" &&
|
|
3048
|
-
p === "/_agent-native/actions/set-workspace-app-access");
|
|
3049
|
-
// Keep org-owned repair controls reachable when this app is disabled;
|
|
3050
|
-
// each action or handler still enforces its org membership and role.
|
|
3051
|
-
if (workspaceAppId &&
|
|
3052
|
-
!sharedWorkspaceAccessPath &&
|
|
3053
|
-
(p.startsWith("/api/") || p.startsWith("/_agent-native/"))) {
|
|
3054
|
-
const workspaceAppAccess = await isWorkspaceAppAccessAllowed(workspaceAppId, {
|
|
3042
|
+
if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
|
|
3043
|
+
const workspaceAppAccess = await checkWorkspaceAppAccessForRequest({
|
|
3044
|
+
path: p,
|
|
3045
|
+
method,
|
|
3055
3046
|
email: session.email,
|
|
3056
3047
|
orgId: session.orgId,
|
|
3057
3048
|
});
|
|
@@ -3059,7 +3050,7 @@ function createAuthGuardFn(app) {
|
|
|
3059
3050
|
setResponseStatus(event, 503);
|
|
3060
3051
|
return { error: WORKSPACE_APP_ACCESS_UNAVAILABLE_MESSAGE };
|
|
3061
3052
|
}
|
|
3062
|
-
if (
|
|
3053
|
+
if (workspaceAppAccess === false) {
|
|
3063
3054
|
setResponseStatus(event, 403);
|
|
3064
3055
|
return { error: "You do not have access to this workspace app." };
|
|
3065
3056
|
}
|
|
@@ -3416,7 +3407,7 @@ async function resolveSessionUncached(event, options = {}) {
|
|
|
3416
3407
|
const cookieOnlyDesktopCheck = isDesktopSessionCookieOnlyCheck(event);
|
|
3417
3408
|
if (!options.ignoreEmbedSession) {
|
|
3418
3409
|
const embedSession = await resolveEmbedSessionFromRequest(event);
|
|
3419
|
-
if (
|
|
3410
|
+
if (isMcpDirectoryWidgetCapabilityApplicationStateRequest(event, embedSession?.scope)) {
|
|
3420
3411
|
return null;
|
|
3421
3412
|
}
|
|
3422
3413
|
if (embedSession && !isEmbedCapabilityScope(embedSession.scope)) {
|
|
@@ -3498,8 +3489,8 @@ async function resolveSessionUncached(event, options = {}) {
|
|
|
3498
3489
|
return authDisabledSession;
|
|
3499
3490
|
return null;
|
|
3500
3491
|
}
|
|
3501
|
-
function
|
|
3502
|
-
if (!
|
|
3492
|
+
function isMcpDirectoryWidgetCapabilityApplicationStateRequest(event, scope) {
|
|
3493
|
+
if (!isMcpDirectoryWidgetCapabilityScope(scope))
|
|
3503
3494
|
return false;
|
|
3504
3495
|
const rawUrl = event.node?.req?.url ?? event.path ?? "/";
|
|
3505
3496
|
const base = "http://agent-native.invalid";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineEventHandler, getHeader, getMethod, getQuery, setResponseHeader, } from "h3";
|
|
2
2
|
import { withCollapsedAgentSidebarParam } from "../shared/agent-sidebar-url.js";
|
|
3
|
-
import { EMBED_MODE_QUERY_PARAM, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM,
|
|
3
|
+
import { EMBED_MODE_QUERY_PARAM, EMBED_START_PATH, EMBED_TOKEN_QUERY_PARAM, isMcpDirectoryWidgetCapabilityScope, MCP_APP_CHAT_BRIDGE_QUERY_PARAM, MCP_DIRECTORY_WIDGET_QUERY_PARAM, } from "../shared/embed-auth.js";
|
|
4
4
|
import { isMcpEmbedTransplantOrigin, MCP_EMBED_CORS_ALLOW_HEADERS, } from "../shared/mcp-embed-headers.js";
|
|
5
5
|
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
6
6
|
import { readCorsAllowedOrigins } from "./cors-origins.js";
|
|
@@ -283,9 +283,11 @@ export function createEmbedStartRouteHandler(options = {}) {
|
|
|
283
283
|
audienceHost: getForwardedRequestHostname(event),
|
|
284
284
|
scope: consumed.scope,
|
|
285
285
|
...(consumed.ticketCreatedAtMs != null &&
|
|
286
|
-
!isEmbedCapabilityScope(consumed.scope)
|
|
286
|
+
(!isEmbedCapabilityScope(consumed.scope) ||
|
|
287
|
+
isMcpDirectoryWidgetCapabilityScope(consumed.scope))
|
|
287
288
|
? { ticketCreatedAtMs: consumed.ticketCreatedAtMs }
|
|
288
289
|
: {}),
|
|
290
|
+
...(consumed.sessionId ? { sessionId: consumed.sessionId } : {}),
|
|
289
291
|
...(isEmbedCapabilityScope(consumed.scope)
|
|
290
292
|
? {
|
|
291
293
|
ttlSeconds: Math.max(1, Math.floor((consumed.expiresAt - Date.now()) / 1000)),
|
|
@@ -298,7 +300,7 @@ export function createEmbedStartRouteHandler(options = {}) {
|
|
|
298
300
|
// its document is a widget whether or not the start URL carried the flag.
|
|
299
301
|
const chatBridgeActive = firstQueryValue(query[MCP_APP_CHAT_BRIDGE_QUERY_PARAM]) === "1" ||
|
|
300
302
|
firstQueryValue(query[MCP_APP_CHAT_BRIDGE_QUERY_PARAM]) === "true" ||
|
|
301
|
-
|
|
303
|
+
isMcpDirectoryWidgetCapabilityScope(consumed.scope);
|
|
302
304
|
const location = withConfiguredBasePath(withCollapsedAgentSidebarParam(appendEmbedParams(target, token, chatBridgeActive)));
|
|
303
305
|
const transplant = wantsTransplantLocationResponse(event);
|
|
304
306
|
if (consumeDiagnostic) {
|
|
@@ -7,12 +7,26 @@ export interface EmbedSessionTicketInput {
|
|
|
7
7
|
targetPath: string;
|
|
8
8
|
scope?: string | null;
|
|
9
9
|
ttlSeconds?: number;
|
|
10
|
+
renewalExpiresAtMs?: number;
|
|
11
|
+
revocationAnchorCreatedAtMs?: number;
|
|
10
12
|
}
|
|
11
13
|
export interface EmbedSessionTicket {
|
|
12
14
|
ticket: string;
|
|
13
15
|
ticketHash: string;
|
|
14
16
|
expiresAt: number;
|
|
15
17
|
}
|
|
18
|
+
export interface McpDirectoryWidgetRenewalTicket {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
ownerEmail: string;
|
|
21
|
+
orgId?: string;
|
|
22
|
+
targetPath: string;
|
|
23
|
+
scope: string;
|
|
24
|
+
createdAtMs: number;
|
|
25
|
+
expiresAtMs: number;
|
|
26
|
+
consumedAtMs: number | null;
|
|
27
|
+
renewalExpiresAtMs: number;
|
|
28
|
+
sessionActiveUntilMs: number | null;
|
|
29
|
+
}
|
|
16
30
|
export type EmbedSessionTicketConsumeOutcome = "missing-ticket" | "not-found" | "already-consumed" | "expired" | "identity-mismatch" | "org-mismatch" | "consumption-race" | "invalid-row" | "revoked" | "consumed";
|
|
17
31
|
export interface EmbedSessionTicketConsumeDiagnostic {
|
|
18
32
|
outcome: EmbedSessionTicketConsumeOutcome;
|
|
@@ -38,6 +52,7 @@ export interface ConsumedEmbedSessionTicket {
|
|
|
38
52
|
scope?: string;
|
|
39
53
|
expiresAt: number;
|
|
40
54
|
ticketCreatedAtMs: number;
|
|
55
|
+
sessionId?: string;
|
|
41
56
|
}
|
|
42
57
|
export interface EmbedSessionTokenClaims {
|
|
43
58
|
kind: typeof TOKEN_KIND;
|
|
@@ -49,6 +64,7 @@ export interface EmbedSessionTokenClaims {
|
|
|
49
64
|
iat: number;
|
|
50
65
|
issuedAtMs?: number;
|
|
51
66
|
ticketCreatedAtMs?: number;
|
|
67
|
+
sessionId?: string;
|
|
52
68
|
exp: number;
|
|
53
69
|
}
|
|
54
70
|
export type VerifyEmbedSessionTokenResult = {
|
|
@@ -73,7 +89,16 @@ export declare function revokeEmbedSessionsForOwners(ownerEmails: string[], inTr
|
|
|
73
89
|
export declare function requestMatchesEmbedTarget(event: H3Event, targetPath: string): boolean;
|
|
74
90
|
export declare function normalizeEmbedTargetPath(raw: string | undefined | null, requestOrigin?: string): string | null;
|
|
75
91
|
export declare function createEmbedSessionTicket(input: EmbedSessionTicketInput): Promise<EmbedSessionTicket>;
|
|
92
|
+
export declare function readMcpDirectoryWidgetRenewalTicket(ticket: string): Promise<McpDirectoryWidgetRenewalTicket | null>;
|
|
93
|
+
export declare function renewMcpDirectoryWidgetSession(input: {
|
|
94
|
+
sourceTicket: string;
|
|
95
|
+
ownerEmail: string;
|
|
96
|
+
orgId?: string | null;
|
|
97
|
+
expectedScope: string;
|
|
98
|
+
renewedScope: string;
|
|
99
|
+
}): Promise<number | null>;
|
|
76
100
|
export declare function resolveEmbedSessionTokenForHost(token: string | undefined, hostname: string): Promise<EmbedSessionTokenClaims | null>;
|
|
101
|
+
export declare function isExpiredMcpDirectoryWidgetSessionRequest(event: H3Event): Promise<boolean>;
|
|
77
102
|
export declare function resolveEmbedSessionCookieOwners(tokens: string[]): Promise<string[]>;
|
|
78
103
|
export declare function consumeEmbedSessionTicket(ticket: string | undefined | null, options?: ConsumeEmbedSessionTicketOptions): Promise<ConsumedEmbedSessionTicket | null>;
|
|
79
104
|
export declare function signEmbedSessionToken(input: {
|
|
@@ -83,11 +108,15 @@ export declare function signEmbedSessionToken(input: {
|
|
|
83
108
|
audienceHost?: string;
|
|
84
109
|
scope?: string | null;
|
|
85
110
|
ticketCreatedAtMs?: number;
|
|
111
|
+
sessionId?: string;
|
|
86
112
|
ttlSeconds?: number;
|
|
87
113
|
}): string;
|
|
88
|
-
export declare function verifyEmbedSessionToken(token: string | undefined | null
|
|
114
|
+
export declare function verifyEmbedSessionToken(token: string | undefined | null, options?: {
|
|
115
|
+
allowExpired?: boolean;
|
|
116
|
+
}): VerifyEmbedSessionTokenResult;
|
|
89
117
|
export declare function setEmbedSessionCookie(event: H3Event, token: string): void;
|
|
90
118
|
export declare function resolveEmbedSessionFromRequest(event: H3Event): Promise<ResolvedEmbedSession | null>;
|
|
119
|
+
export declare function hasExplicitEmbedSessionCredential(event: H3Event): boolean;
|
|
91
120
|
export declare function requestHasEmbedAuthMarker(event: H3Event): boolean;
|
|
92
121
|
export declare function isEmbedModeRequest(event: H3Event): boolean;
|
|
93
122
|
export {};
|