@opengeni/api-router 3.2.2 → 3.3.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/app.js +1 -1
- package/dist/{chunk-PQBHZ2YH.js → chunk-6CECHDZP.js} +481 -333
- package/dist/{chunk-PQBHZ2YH.js.map → chunk-6CECHDZP.js.map} +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/scheduled-task-view.d.ts +4 -4
- package/dist/sandbox/channel-a.d.ts +10 -1
- package/dist/site-publishing/agent-data-tools.d.ts +5 -5
- package/dist/site-publishing/agent-session.d.ts +3 -2
- package/dist/site-publishing/runtime.d.ts +7 -6
- package/dist/site-publishing/service.d.ts +8 -11
- package/dist/site-publishing/session-request-authority.d.ts +3 -0
- package/package.json +24 -24
- package/src/access-grant-rls.ts +1 -0
- package/src/http/sse.ts +5 -1
- package/src/routes/browser-sessions.ts +61 -17
- package/src/routes/computer-sessions.ts +102 -39
- package/src/routes/insights-usage.ts +22 -0
- package/src/routes/sessions.ts +22 -4
- package/src/routes/site-runtime.ts +62 -20
- package/src/sandbox/channel-a.ts +18 -1
- package/src/sandbox/metrics-ingestion.ts +1 -0
- package/src/site-frame-guard.ts +11 -2
- package/src/site-publishing/agent-data-tools.ts +16 -8
- package/src/site-publishing/agent-session.ts +24 -6
- package/src/site-publishing/runtime.ts +29 -7
- package/src/site-publishing/service.ts +65 -77
- package/src/site-publishing/session-request-authority.ts +14 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-OGQDXVXY.js";
|
|
4
4
|
|
|
5
5
|
// src/app.ts
|
|
6
|
-
import { AsyncLocalStorage as
|
|
6
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
7
7
|
|
|
8
8
|
// src/routes/claude-subscription-accounts.ts
|
|
9
9
|
import { createHmac as createHmac2 } from "crypto";
|
|
@@ -4435,7 +4435,7 @@ import {
|
|
|
4435
4435
|
setMcpOAuthRequestOrganizationAccess
|
|
4436
4436
|
} from "@opengeni/db";
|
|
4437
4437
|
import {
|
|
4438
|
-
hasPermission as
|
|
4438
|
+
hasPermission as hasPermission15,
|
|
4439
4439
|
requireAccessContext as requireAccessContext2,
|
|
4440
4440
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization6
|
|
4441
4441
|
} from "@opengeni/core";
|
|
@@ -4631,7 +4631,7 @@ import {
|
|
|
4631
4631
|
buildApiIntegrationMcpServers,
|
|
4632
4632
|
expandApiIntegrationAccountRoutes,
|
|
4633
4633
|
expandMcpAccountRoutes,
|
|
4634
|
-
hasPermission as
|
|
4634
|
+
hasPermission as hasPermission14,
|
|
4635
4635
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization5,
|
|
4636
4636
|
isVerifiedOrganizationServiceAuthorization as isVerifiedOrganizationServiceAuthorization2,
|
|
4637
4637
|
externalContinuationCommitAuthorizer,
|
|
@@ -7916,9 +7916,11 @@ async function deleteSiteDataFile(deps, grant, siteId3, fileId, surface3 = {}) {
|
|
|
7916
7916
|
|
|
7917
7917
|
// src/site-publishing/agent-data-tools.ts
|
|
7918
7918
|
import {
|
|
7919
|
-
siteHostname as siteHostname3
|
|
7919
|
+
siteHostname as siteHostname3,
|
|
7920
|
+
permissionsRequiredByFirstPartyTools
|
|
7920
7921
|
} from "@opengeni/contracts";
|
|
7921
7922
|
import { resolveFirstPartyMcpToolPolicy } from "@opengeni/config";
|
|
7923
|
+
import { hasPermission as hasPermission5 } from "@opengeni/core";
|
|
7922
7924
|
import {
|
|
7923
7925
|
consumeSiteRuntimeRate as consumeSiteRuntimeRate2,
|
|
7924
7926
|
findSiteRuntimeAgentConversation,
|
|
@@ -8033,7 +8035,10 @@ import {
|
|
|
8033
8035
|
siteHostname as siteHostname2,
|
|
8034
8036
|
SITE_NOT_AVAILABLE_FOR_VIEWER_ERROR_CODE
|
|
8035
8037
|
} from "@opengeni/contracts";
|
|
8036
|
-
import {
|
|
8038
|
+
import {
|
|
8039
|
+
sessionUsageLimitsProducerEnabled,
|
|
8040
|
+
stampSiteViewerSessionAuthorization
|
|
8041
|
+
} from "@opengeni/core";
|
|
8037
8042
|
import {
|
|
8038
8043
|
consumeSiteRuntimeRate,
|
|
8039
8044
|
findSiteHostname,
|
|
@@ -8056,6 +8061,15 @@ import {
|
|
|
8056
8061
|
withWorkspaceSessionActivityRls
|
|
8057
8062
|
} from "@opengeni/db";
|
|
8058
8063
|
|
|
8064
|
+
// src/site-publishing/session-request-authority.ts
|
|
8065
|
+
var authorities = /* @__PURE__ */ new WeakMap();
|
|
8066
|
+
function bindSiteSessionRequestAuthority(request, reauthorize) {
|
|
8067
|
+
authorities.set(request, reauthorize);
|
|
8068
|
+
}
|
|
8069
|
+
async function reauthorizeSiteSessionRequest(request) {
|
|
8070
|
+
await authorities.get(request)?.();
|
|
8071
|
+
}
|
|
8072
|
+
|
|
8059
8073
|
// src/site-publishing/limits.ts
|
|
8060
8074
|
import {
|
|
8061
8075
|
DEFAULT_SITE_LIMITS,
|
|
@@ -8251,6 +8265,7 @@ function storedSiteLimitProfileKind(kind) {
|
|
|
8251
8265
|
|
|
8252
8266
|
// src/site-publishing/service.ts
|
|
8253
8267
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
8268
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
8254
8269
|
import {
|
|
8255
8270
|
normalizeSitesDomain,
|
|
8256
8271
|
OPENGENI_API_CONTRACT_HEADER,
|
|
@@ -8282,7 +8297,7 @@ import {
|
|
|
8282
8297
|
readSiteRuntimeUsage,
|
|
8283
8298
|
recordSitePublicationScan,
|
|
8284
8299
|
getPublishedSite as getPublishedSite2,
|
|
8285
|
-
|
|
8300
|
+
listSiteRuntimeCancellationCandidates,
|
|
8286
8301
|
revokeSiteViewerSessions,
|
|
8287
8302
|
SitePublishingError,
|
|
8288
8303
|
SITE_RUNTIME_SITE_PRINCIPAL,
|
|
@@ -10014,12 +10029,9 @@ async function runSitePublishing(fn) {
|
|
|
10014
10029
|
var SITE_EFFECT_CONCURRENCY = 4;
|
|
10015
10030
|
var SITE_EFFECT_QUEUE_LIMIT = 2e3;
|
|
10016
10031
|
var effectsBySettings = /* @__PURE__ */ new WeakMap();
|
|
10017
|
-
var
|
|
10018
|
-
function
|
|
10019
|
-
|
|
10020
|
-
}
|
|
10021
|
-
function sitePublishingDispatch(settings) {
|
|
10022
|
-
return dispatchBySettings.get(settings) ?? null;
|
|
10032
|
+
var cancellationBySettings = /* @__PURE__ */ new WeakMap();
|
|
10033
|
+
function setSitePublishingCancellation(settings, cancel) {
|
|
10034
|
+
cancellationBySettings.set(settings, cancel);
|
|
10023
10035
|
}
|
|
10024
10036
|
function createEffects(settings, options = {}) {
|
|
10025
10037
|
const queueLimit = options.queueLimit ?? SITE_EFFECT_QUEUE_LIMIT;
|
|
@@ -10297,14 +10309,18 @@ async function siteServiceSessionRequest(deps, scope, site, input) {
|
|
|
10297
10309
|
"x-opengeni-site-id": site.id
|
|
10298
10310
|
});
|
|
10299
10311
|
if (site.versionId) headers.set("x-opengeni-site-version", site.versionId);
|
|
10300
|
-
|
|
10312
|
+
const body5 = input.body === void 0 ? void 0 : JSON.stringify(input.body);
|
|
10313
|
+
if (body5 !== void 0) {
|
|
10314
|
+
headers.set("content-type", "application/json");
|
|
10315
|
+
headers.set("content-length", String(Buffer.byteLength(body5)));
|
|
10316
|
+
}
|
|
10301
10317
|
return new Request(new URL(input.path, input.origin), {
|
|
10302
10318
|
method: input.method,
|
|
10303
10319
|
headers,
|
|
10304
|
-
...
|
|
10320
|
+
...body5 === void 0 ? {} : { body: body5 }
|
|
10305
10321
|
});
|
|
10306
10322
|
}
|
|
10307
|
-
var
|
|
10323
|
+
var STOP_CONVERSATIONS_PAGE_SIZE = 200;
|
|
10308
10324
|
async function stopSiteViewers(deps, scope, siteId3, options) {
|
|
10309
10325
|
let revokedSessions = 0;
|
|
10310
10326
|
if (options.revokeSessions !== false) {
|
|
@@ -10318,67 +10334,53 @@ async function stopSiteViewers(deps, scope, siteId3, options) {
|
|
|
10318
10334
|
}
|
|
10319
10335
|
}
|
|
10320
10336
|
if (options.cancelConversations === false) return { revokedSessions };
|
|
10321
|
-
const
|
|
10322
|
-
if (!
|
|
10323
|
-
console.warn("[site-publishing] conversation cancel
|
|
10337
|
+
const cancel = cancellationBySettings.get(deps.settings);
|
|
10338
|
+
if (!cancel) {
|
|
10339
|
+
console.warn("[site-publishing] conversation cancel unavailable: no lifecycle adapter", {
|
|
10324
10340
|
siteId: siteId3
|
|
10325
10341
|
});
|
|
10326
10342
|
return { revokedSessions };
|
|
10327
10343
|
}
|
|
10328
10344
|
const effects = sitePublishingEffects(deps.settings);
|
|
10329
|
-
const
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10345
|
+
const runInContext = AsyncLocalStorage.snapshot();
|
|
10346
|
+
const operation = crypto.randomUUID();
|
|
10347
|
+
const startedBefore = /* @__PURE__ */ new Date();
|
|
10348
|
+
const run2 = () => runInContext(async () => {
|
|
10349
|
+
let after;
|
|
10350
|
+
let failed = 0;
|
|
10351
|
+
for (; ; ) {
|
|
10352
|
+
const sessionIds = await listSiteRuntimeCancellationCandidates(deps.db, scope, {
|
|
10353
|
+
siteId: siteId3,
|
|
10354
|
+
limit: STOP_CONVERSATIONS_PAGE_SIZE,
|
|
10355
|
+
startedBefore,
|
|
10356
|
+
...after ? { after } : {},
|
|
10357
|
+
...options.toolsNarrowedTo ? { toolsNarrowedTo: options.toolsNarrowedTo } : {}
|
|
10341
10358
|
});
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
method: "POST",
|
|
10355
|
-
path: `/v1/workspaces/${scope.workspaceId}/sessions/${sessionId}/control`,
|
|
10356
|
-
body: {
|
|
10357
|
-
action: "cancel",
|
|
10358
|
-
clientEventId: `site-stop:${operation}:${sessionId}`.slice(0, 200),
|
|
10359
|
-
reason: options.reason.slice(0, 500)
|
|
10360
|
-
},
|
|
10361
|
-
label: "Published Site"
|
|
10362
|
-
}
|
|
10363
|
-
)
|
|
10364
|
-
);
|
|
10365
|
-
if (!response.ok)
|
|
10359
|
+
if (sessionIds.length === 0) break;
|
|
10360
|
+
for (const sessionId of sessionIds) {
|
|
10361
|
+
try {
|
|
10362
|
+
await cancel({
|
|
10363
|
+
...scope,
|
|
10364
|
+
siteId: siteId3,
|
|
10365
|
+
sessionId,
|
|
10366
|
+
operationKey: `site-stop:${operation}:${sessionId}`,
|
|
10367
|
+
reason: options.reason.slice(0, 500)
|
|
10368
|
+
});
|
|
10369
|
+
} catch (error) {
|
|
10370
|
+
failed += 1;
|
|
10366
10371
|
console.warn("[site-publishing] could not cancel a Site conversation", {
|
|
10367
10372
|
siteId: siteId3,
|
|
10368
10373
|
sessionId,
|
|
10369
|
-
|
|
10370
|
-
body: (await response.text().catch(() => "")).slice(0, 300)
|
|
10374
|
+
error: error instanceof Error ? error.message : String(error)
|
|
10371
10375
|
});
|
|
10372
|
-
|
|
10373
|
-
} catch (error) {
|
|
10374
|
-
console.warn("[site-publishing] could not cancel a Site conversation", {
|
|
10375
|
-
siteId: siteId3,
|
|
10376
|
-
sessionId,
|
|
10377
|
-
error: error instanceof Error ? error.message : String(error)
|
|
10378
|
-
});
|
|
10376
|
+
}
|
|
10379
10377
|
}
|
|
10378
|
+
after = sessionIds.at(-1);
|
|
10380
10379
|
}
|
|
10380
|
+
if (failed > 0)
|
|
10381
|
+
throw new Error(`Site lifecycle cancellation failed for ${failed} conversations`);
|
|
10381
10382
|
});
|
|
10383
|
+
if (!effects.schedule("cancel conversations", run2)) await run2();
|
|
10382
10384
|
return { revokedSessions };
|
|
10383
10385
|
}
|
|
10384
10386
|
var abuseNoticeHours = /* @__PURE__ */ new Map();
|
|
@@ -11192,12 +11194,24 @@ async function meterSiteRuntime(deps, host, event) {
|
|
|
11192
11194
|
}
|
|
11193
11195
|
}
|
|
11194
11196
|
async function siteRuntimeSessionRequest(deps, host, viewer, input) {
|
|
11195
|
-
|
|
11197
|
+
const request = await siteServiceSessionRequest(
|
|
11196
11198
|
deps,
|
|
11197
11199
|
host.scope,
|
|
11198
11200
|
{ id: host.site.id, versionId: host.versionId },
|
|
11199
11201
|
{ ...input, label: `${siteRuntimeViewerLabel(viewer)} on ${host.hostname}` }
|
|
11200
11202
|
);
|
|
11203
|
+
bindSiteSessionRequestAuthority(request, input.reauthorize);
|
|
11204
|
+
if (viewer.kind === "member" && viewer.subjectId && viewer.sessionId) {
|
|
11205
|
+
stampSiteViewerSessionAuthorization(request, {
|
|
11206
|
+
organizationId: host.scope.accountId,
|
|
11207
|
+
subjectId: viewer.subjectId,
|
|
11208
|
+
permissions: [
|
|
11209
|
+
.../* @__PURE__ */ new Set([...SITE_RUNTIME_AGENT_PERMISSIONS, ...input.extraPermissions ?? []])
|
|
11210
|
+
],
|
|
11211
|
+
workspaceId: host.scope.workspaceId
|
|
11212
|
+
});
|
|
11213
|
+
}
|
|
11214
|
+
return request;
|
|
11201
11215
|
}
|
|
11202
11216
|
function siteRuntimeForwardedResponse(response) {
|
|
11203
11217
|
const headers = new Headers(response.headers);
|
|
@@ -11217,10 +11231,6 @@ var SITE_AGENT_SQL_TOOLS = Object.freeze([
|
|
|
11217
11231
|
var SITE_AGENT_MEMBER_SQL_TOOLS = Object.freeze([
|
|
11218
11232
|
"site_sql_query"
|
|
11219
11233
|
]);
|
|
11220
|
-
var SITE_AGENT_DATA_TOOL_PERMISSIONS = Object.freeze([
|
|
11221
|
-
"artifacts:read",
|
|
11222
|
-
"artifacts:publish"
|
|
11223
|
-
]);
|
|
11224
11234
|
var SITE_AGENT_OTHER_SITE_MESSAGE2 = "This Site's assistant can only use this Site's data";
|
|
11225
11235
|
var SITE_AGENT_MANAGEMENT_MESSAGE = "This Site's assistant can use the Site's data, not manage the Site";
|
|
11226
11236
|
function siteAgentDataToolNames(input) {
|
|
@@ -11229,18 +11239,23 @@ function siteAgentDataToolNames(input) {
|
|
|
11229
11239
|
...input.siteSql ? SITE_AGENT_SQL_TOOLS : [],
|
|
11230
11240
|
...input.siteSql && input.viewerKind === "member" ? SITE_AGENT_MEMBER_SQL_TOOLS : []
|
|
11231
11241
|
];
|
|
11232
|
-
return names.filter(
|
|
11242
|
+
return names.filter(
|
|
11243
|
+
(name) => input.allowed.includes(name) && (input.viewerKind !== "member" || input.memberPermissions === void 0 || permissionsRequiredByFirstPartyTools([name]).every(
|
|
11244
|
+
(permission) => hasPermission5(input.memberPermissions, permission)
|
|
11245
|
+
))
|
|
11246
|
+
);
|
|
11233
11247
|
}
|
|
11234
11248
|
async function siteAgentSiteSqlOn(deps, scope, siteId3) {
|
|
11235
11249
|
if (!siteSqlOffered(deps.settings)) return false;
|
|
11236
11250
|
const database = await getSiteSqlDatabase2(deps.db, { ...scope, siteId: siteId3 }).catch(() => null);
|
|
11237
11251
|
return database?.enabled === true;
|
|
11238
11252
|
}
|
|
11239
|
-
async function siteAgentDataToolsForStart(deps, scope, siteId3, viewerKind) {
|
|
11253
|
+
async function siteAgentDataToolsForStart(deps, scope, siteId3, viewerKind, memberPermissions) {
|
|
11240
11254
|
return siteAgentDataToolNames({
|
|
11241
11255
|
viewerKind,
|
|
11242
11256
|
siteSql: await siteAgentSiteSqlOn(deps, scope, siteId3),
|
|
11243
|
-
allowed: resolveFirstPartyMcpToolPolicy(deps.settings).allowed
|
|
11257
|
+
allowed: resolveFirstPartyMcpToolPolicy(deps.settings).allowed,
|
|
11258
|
+
...memberPermissions === void 0 ? {} : { memberPermissions }
|
|
11244
11259
|
});
|
|
11245
11260
|
}
|
|
11246
11261
|
function sitePublishedDataViewer(host, principal, guest) {
|
|
@@ -12533,7 +12548,7 @@ import {
|
|
|
12533
12548
|
editableArtifactId,
|
|
12534
12549
|
editableArtifactReplicaId,
|
|
12535
12550
|
editableArtifactScope,
|
|
12536
|
-
hasPermission as
|
|
12551
|
+
hasPermission as hasPermission6,
|
|
12537
12552
|
requireAccessGrant as requireAccessGrant10,
|
|
12538
12553
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization2,
|
|
12539
12554
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization2,
|
|
@@ -12606,6 +12621,7 @@ async function withAccessGrantSessionRlsContext(deps, grant, fn) {
|
|
|
12606
12621
|
{
|
|
12607
12622
|
subjectId: actor.subjectId,
|
|
12608
12623
|
initiatingHumanSubjectId: actor.initiatingHumanSubjectId,
|
|
12624
|
+
agentRootSessionId: actor.callerRootSessionId,
|
|
12609
12625
|
privateFileOwnerSubjectId: learning.defaultScope === "personal" ? learning.subjectId : null
|
|
12610
12626
|
},
|
|
12611
12627
|
fn
|
|
@@ -12846,7 +12862,7 @@ function registerEditableArtifactRoutes(app, deps) {
|
|
|
12846
12862
|
app.post(`${collection}/imports`, async (context) => {
|
|
12847
12863
|
const workspaceId = context.req.param("workspaceId");
|
|
12848
12864
|
const grant = await requireAccessGrant10(context, deps, workspaceId, "artifacts:publish");
|
|
12849
|
-
if (!
|
|
12865
|
+
if (!hasPermission6(grant.permissions, "files:read")) {
|
|
12850
12866
|
throw applicationHttpError("forbidden");
|
|
12851
12867
|
}
|
|
12852
12868
|
const body5 = await parseBoundedImportRequest(context);
|
|
@@ -12943,7 +12959,7 @@ function registerEditableArtifactRoutes(app, deps) {
|
|
|
12943
12959
|
snapshotVersion: body5.snapshotVersion,
|
|
12944
12960
|
commandProtocolVersion: body5.commandProtocolVersion,
|
|
12945
12961
|
committedTransactionProtocolVersion: body5.committedTransactionProtocolVersion,
|
|
12946
|
-
allowEdit:
|
|
12962
|
+
allowEdit: hasPermission6(grant.permissions, "artifacts:publish"),
|
|
12947
12963
|
...body5.sourceSessionId ? {
|
|
12948
12964
|
sourceSessionAuthority: {
|
|
12949
12965
|
sessionId: body5.sourceSessionId,
|
|
@@ -12970,7 +12986,7 @@ function registerEditableArtifactRoutes(app, deps) {
|
|
|
12970
12986
|
permissions: [
|
|
12971
12987
|
"sessions:read",
|
|
12972
12988
|
"artifacts:read",
|
|
12973
|
-
...
|
|
12989
|
+
...hasPermission6(grant.permissions, "artifacts:publish") ? ["artifacts:publish"] : []
|
|
12974
12990
|
]
|
|
12975
12991
|
},
|
|
12976
12992
|
...externalContinuation ? { externalContinuation } : {}
|
|
@@ -13896,7 +13912,7 @@ import {
|
|
|
13896
13912
|
createWorkspaceVaultProviderRegistry,
|
|
13897
13913
|
createRemoteExternalVaultFactories,
|
|
13898
13914
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization4,
|
|
13899
|
-
hasPermission as
|
|
13915
|
+
hasPermission as hasPermission7,
|
|
13900
13916
|
isVaultError,
|
|
13901
13917
|
VaultError,
|
|
13902
13918
|
providerSecretName,
|
|
@@ -14223,8 +14239,8 @@ function isAccountAdmin(authorization) {
|
|
|
14223
14239
|
}
|
|
14224
14240
|
function canManageOnePasswordConnection(authorization, connection, metadata) {
|
|
14225
14241
|
const { grant } = authorization;
|
|
14226
|
-
if (!
|
|
14227
|
-
if (!
|
|
14242
|
+
if (!hasPermission7(grant.permissions, "connections:write", grant.permissionMode)) return false;
|
|
14243
|
+
if (!hasPermission7(grant.permissions, "secrets:write", grant.permissionMode)) return false;
|
|
14228
14244
|
if (connection.subjectId !== null) return connection.subjectId === grant.subjectId;
|
|
14229
14245
|
if (metadata.ownership === "organization") return isAccountAdmin(authorization);
|
|
14230
14246
|
return true;
|
|
@@ -15075,7 +15091,7 @@ function registerVaultProviderRoutes(app, deps, options = {}) {
|
|
|
15075
15091
|
}
|
|
15076
15092
|
function canManageExternal(authorization, connection, details) {
|
|
15077
15093
|
const grant = authorization.grant;
|
|
15078
|
-
return
|
|
15094
|
+
return hasPermission7(grant.permissions, "connections:write", grant.permissionMode) && hasPermission7(grant.permissions, "secrets:write", grant.permissionMode) && (connection.subjectId !== null ? connection.subjectId === grant.subjectId && isPersonalConnectionOwnerPrincipal(authorization) : details.ownership !== "organization" || isAccountAdmin(authorization));
|
|
15079
15095
|
}
|
|
15080
15096
|
function catalogVault(provider, vault, linkedVaultId) {
|
|
15081
15097
|
return {
|
|
@@ -15803,12 +15819,12 @@ import { isVaultError as isVaultError3, vaultErrorFromDatabase as vaultErrorFrom
|
|
|
15803
15819
|
// src/mcp/first-party-tool-permissions.ts
|
|
15804
15820
|
import {
|
|
15805
15821
|
FIRST_PARTY_TOOL_AUTHORIZATION,
|
|
15806
|
-
permissionsRequiredByFirstPartyTools
|
|
15822
|
+
permissionsRequiredByFirstPartyTools as permissionsRequiredByFirstPartyTools2
|
|
15807
15823
|
} from "@opengeni/contracts";
|
|
15808
15824
|
|
|
15809
15825
|
// src/mcp/server.ts
|
|
15810
15826
|
import {
|
|
15811
|
-
hasPermission as
|
|
15827
|
+
hasPermission as hasPermission11,
|
|
15812
15828
|
authorizedSocialConnectionsForGrant,
|
|
15813
15829
|
buildCapabilityCatalog,
|
|
15814
15830
|
CONNECTED_MACHINE_CAPABILITY_ID,
|
|
@@ -16032,10 +16048,10 @@ async function listWorkspaceGitHubRepositoryBranches(deps, input, services = wor
|
|
|
16032
16048
|
}
|
|
16033
16049
|
|
|
16034
16050
|
// src/github-browser-flow.ts
|
|
16035
|
-
import { hasPermission as
|
|
16051
|
+
import { hasPermission as hasPermission8 } from "@opengeni/core";
|
|
16036
16052
|
var githubBrowserGrantMaxAgeSeconds = 10 * 60;
|
|
16037
16053
|
function githubBrowserGrantClaims(settings, grant, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
16038
|
-
if (settings.productAccessMode !== "configured" || !
|
|
16054
|
+
if (settings.productAccessMode !== "configured" || !hasPermission8(grant.permissions, "github:manage")) {
|
|
16039
16055
|
return {};
|
|
16040
16056
|
}
|
|
16041
16057
|
return {
|
|
@@ -16773,7 +16789,7 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
|
|
|
16773
16789
|
hasGitHubRepositorySelection(session.resources) ? githubAppBotIdentity(settings) : null
|
|
16774
16790
|
);
|
|
16775
16791
|
}
|
|
16776
|
-
const runEstablished = async (routed, lease, homeSession) => {
|
|
16792
|
+
const runEstablished = async (routed, lease, homeSession, pinnedMachine = null) => {
|
|
16777
16793
|
const emit = async (events) => {
|
|
16778
16794
|
await appendAndPublishEvents2(
|
|
16779
16795
|
db,
|
|
@@ -16804,6 +16820,7 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
|
|
|
16804
16820
|
homeSession,
|
|
16805
16821
|
routingSession,
|
|
16806
16822
|
machineAuthority,
|
|
16823
|
+
pinnedMachine,
|
|
16807
16824
|
requestId
|
|
16808
16825
|
});
|
|
16809
16826
|
await routingSession.finalizeOpStreamOps().catch(() => void 0);
|
|
@@ -16892,6 +16909,7 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
|
|
|
16892
16909
|
operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
|
|
16893
16910
|
operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
|
|
16894
16911
|
transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
|
|
16912
|
+
browserControlHttpSupported: enrollment.agentCapabilities.browserControlHttp === true,
|
|
16895
16913
|
...settings.agentOpStreamEnabled === true && enrollment?.opStream === true && bus.getOpStreamConnection ? {
|
|
16896
16914
|
opStream: {
|
|
16897
16915
|
transport: new NatsOpStreamTransport(
|
|
@@ -16930,7 +16948,11 @@ async function withChannelAOperation(services, ctx, readOnly, fn) {
|
|
|
16930
16948
|
},
|
|
16931
16949
|
established2
|
|
16932
16950
|
);
|
|
16933
|
-
return await runEstablished(routed, null, established2.session
|
|
16951
|
+
return await runEstablished(routed, null, established2.session, {
|
|
16952
|
+
sandboxId: sandbox.id,
|
|
16953
|
+
sandboxWorkspaceId: originWorkspaceId,
|
|
16954
|
+
enrollment
|
|
16955
|
+
});
|
|
16934
16956
|
} catch (error) {
|
|
16935
16957
|
observeChannelAOperationFailure(services, {
|
|
16936
16958
|
workspaceId,
|
|
@@ -21275,7 +21297,7 @@ import { parseSocialOauthClientsJson } from "@opengeni/config";
|
|
|
21275
21297
|
import {
|
|
21276
21298
|
OAuthStartResponse as OAuthStartResponse2
|
|
21277
21299
|
} from "@opengeni/contracts";
|
|
21278
|
-
import { hasPermission as
|
|
21300
|
+
import { hasPermission as hasPermission9, requireEnvironmentEncryption as requireEnvironmentEncryption5 } from "@opengeni/core";
|
|
21279
21301
|
import {
|
|
21280
21302
|
consumeIntegrationOAuthStateNonce as consumeIntegrationOAuthStateNonce2,
|
|
21281
21303
|
decryptEnvironmentValue as decryptEnvironmentValue2,
|
|
@@ -21445,7 +21467,7 @@ async function completeSocialOAuthCallback(deps, input) {
|
|
|
21445
21467
|
throw new HTTPException28(422, { message: PERSONAL_CONNECTION_PRINCIPAL_MESSAGE });
|
|
21446
21468
|
}
|
|
21447
21469
|
const grant = await getWorkspaceGrant2(db, state.subjectId, state.workspaceId);
|
|
21448
|
-
if (!grant || grant.accountId !== state.accountId || state.ownership === "workspace" && !
|
|
21470
|
+
if (!grant || grant.accountId !== state.accountId || state.ownership === "workspace" && !hasPermission9(grant.permissions, "workspace:admin")) {
|
|
21449
21471
|
throw new HTTPException28(403, {
|
|
21450
21472
|
message: "OAuth subject no longer has permission to connect social accounts"
|
|
21451
21473
|
});
|
|
@@ -27708,7 +27730,7 @@ import {
|
|
|
27708
27730
|
} from "@opengeni/contracts";
|
|
27709
27731
|
import {
|
|
27710
27732
|
fileOwnerContextForAgent as fileOwnerContextForAgent3,
|
|
27711
|
-
hasPermission as
|
|
27733
|
+
hasPermission as hasPermission10,
|
|
27712
27734
|
requireOpenGeniSlackBotConnection as requireOpenGeniSlackBotConnection2,
|
|
27713
27735
|
requirePermission as requirePermission3
|
|
27714
27736
|
} from "@opengeni/core";
|
|
@@ -28007,7 +28029,7 @@ async function uploadSlackTaskFile(deps, input) {
|
|
|
28007
28029
|
});
|
|
28008
28030
|
}
|
|
28009
28031
|
function slackTaskRequesterCanReceiveFile(permissions) {
|
|
28010
|
-
return
|
|
28032
|
+
return hasPermission10(permissions, "files:read") && hasPermission10(permissions, "sessions:read");
|
|
28011
28033
|
}
|
|
28012
28034
|
function assertSlackTaskUploadTarget(interaction) {
|
|
28013
28035
|
if (interaction.visibility === "private" && (!interaction.slackChannelId.startsWith("D") || interaction.routeKey !== `${interaction.slackChannelId}:${interaction.slackThreadTs}` || interaction.ackSlackMessageTs !== null && interaction.ackSlackMessageTs !== interaction.slackThreadTs)) {
|
|
@@ -43299,7 +43321,7 @@ var PolicyMcpServer = class extends McpServer3 {
|
|
|
43299
43321
|
holdsSelectableTool(toolName) {
|
|
43300
43322
|
const policy = FIRST_PARTY_TOOL_AUTHORIZATION[toolName];
|
|
43301
43323
|
if (policy.adminAccessRequired) return false;
|
|
43302
|
-
const authorized = (policy.allOf?.every((permission) =>
|
|
43324
|
+
const authorized = (policy.allOf?.every((permission) => hasPermission11(this.grant.permissions, permission)) ?? true) && (policy.anyOf?.some((permission) => hasPermission11(this.grant.permissions, permission)) ?? true);
|
|
43303
43325
|
return authorized && (this.selectedTools === null || this.selectedTools.has(toolName));
|
|
43304
43326
|
}
|
|
43305
43327
|
registerTool(name, config, cb) {
|
|
@@ -43407,7 +43429,7 @@ function buildOpenGeniMcpServer(deps, grant, options = {}) {
|
|
|
43407
43429
|
const json2 = (value) => ({
|
|
43408
43430
|
content: [{ type: "text", text: JSON.stringify(value, null, 2) }]
|
|
43409
43431
|
});
|
|
43410
|
-
const can = (permission) =>
|
|
43432
|
+
const can = (permission) => hasPermission11(grant.permissions, permission);
|
|
43411
43433
|
let socialConnectionsPromise;
|
|
43412
43434
|
const authorizedSocialConnections = () => socialConnectionsPromise ??= authorizedSocialConnectionsForGrant({
|
|
43413
43435
|
db: deps.db,
|
|
@@ -48524,7 +48546,7 @@ function registerGitHubConnectTool(server, deps, grant, options, json2) {
|
|
|
48524
48546
|
const installations = await listWorkspaceGitHubInstallationBindings(deps, grant.workspaceId);
|
|
48525
48547
|
const status = githubBindingStatus(true, installations);
|
|
48526
48548
|
const baseUrl = githubBrowserBaseUrl(settings, options.requestOrigin);
|
|
48527
|
-
const state = baseUrl &&
|
|
48549
|
+
const state = baseUrl && hasPermission11(grant.permissions, "github:manage") ? createSignedState7(deps.githubStateSecret, {
|
|
48528
48550
|
accountId: grant.accountId,
|
|
48529
48551
|
workspaceId: grant.workspaceId,
|
|
48530
48552
|
intent: "installation_authority",
|
|
@@ -49065,18 +49087,18 @@ function startWorkspaceToolGatewayObservation(observability, input) {
|
|
|
49065
49087
|
}
|
|
49066
49088
|
|
|
49067
49089
|
// src/workspace-tool-gateway-secrets.ts
|
|
49068
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
49090
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
49069
49091
|
import { environmentsEncryptionKeyBytes as environmentsEncryptionKeyBytes5 } from "@opengeni/config";
|
|
49070
49092
|
import {
|
|
49071
49093
|
SecretReferenceError,
|
|
49072
49094
|
collectReferencesDeep
|
|
49073
49095
|
} from "@opengeni/contracts";
|
|
49074
|
-
import { createSecretResolver, hasPermission as
|
|
49096
|
+
import { createSecretResolver, hasPermission as hasPermission12 } from "@opengeni/core";
|
|
49075
49097
|
import {
|
|
49076
49098
|
createSecretArgumentResolver,
|
|
49077
49099
|
secretArgumentMode
|
|
49078
49100
|
} from "@opengeni/runtime/workspace-tool-gateway";
|
|
49079
|
-
var siteSecretContexts = new
|
|
49101
|
+
var siteSecretContexts = new AsyncLocalStorage2();
|
|
49080
49102
|
function withSiteSecretContext(context, run2) {
|
|
49081
49103
|
return siteSecretContexts.run(context, run2);
|
|
49082
49104
|
}
|
|
@@ -49107,7 +49129,7 @@ function workspaceGatewaySecretArguments(input) {
|
|
|
49107
49129
|
if (secretArgumentMode(call.entry) !== "literal") return call.arguments;
|
|
49108
49130
|
const site = siteSecretContexts.getStore() ?? null;
|
|
49109
49131
|
const references = collectReferencesDeep(call.arguments);
|
|
49110
|
-
if (!site && references.length > 0 && !
|
|
49132
|
+
if (!site && references.length > 0 && !hasPermission12(input.grant.permissions, "secrets:use", input.grant.permissionMode)) {
|
|
49111
49133
|
throw new SecretReferenceError(
|
|
49112
49134
|
references.map((reference) => ({
|
|
49113
49135
|
raw: reference.raw,
|
|
@@ -49217,7 +49239,7 @@ function workspaceToolGatewayIdentityKey(identity2) {
|
|
|
49217
49239
|
}
|
|
49218
49240
|
|
|
49219
49241
|
// src/site-publishing/page-tool-authority.ts
|
|
49220
|
-
import { hasPermission as
|
|
49242
|
+
import { hasPermission as hasPermission13 } from "@opengeni/core";
|
|
49221
49243
|
import {
|
|
49222
49244
|
getPublishedSiteVersion as getPublishedSiteVersion4,
|
|
49223
49245
|
getWorkspaceGrant as getWorkspaceGrant3,
|
|
@@ -49225,12 +49247,12 @@ import {
|
|
|
49225
49247
|
withWorkspaceSubjectRls as withWorkspaceSubjectRls3
|
|
49226
49248
|
} from "@opengeni/db";
|
|
49227
49249
|
import { HTTPException as HTTPException37 } from "hono/http-exception";
|
|
49228
|
-
var
|
|
49250
|
+
var authorities2 = /* @__PURE__ */ new WeakMap();
|
|
49229
49251
|
function isPublishedSiteToolAuthorization(value) {
|
|
49230
|
-
return
|
|
49252
|
+
return authorities2.has(value);
|
|
49231
49253
|
}
|
|
49232
49254
|
function publishedSiteToolAuthority(value) {
|
|
49233
|
-
const authority =
|
|
49255
|
+
const authority = authorities2.get(value);
|
|
49234
49256
|
if (!authority) throw new HTTPException37(403, { message: "site_tool_not_authorized" });
|
|
49235
49257
|
return authority;
|
|
49236
49258
|
}
|
|
@@ -49252,7 +49274,7 @@ async function authorizePublishedSiteTools(deps, domain, fields2) {
|
|
|
49252
49274
|
});
|
|
49253
49275
|
}
|
|
49254
49276
|
);
|
|
49255
|
-
if (!grant2 || !
|
|
49277
|
+
if (!grant2 || !hasPermission13(grant2.permissions, "workspace:read")) throw denied2();
|
|
49256
49278
|
return { host: host2, viewer, grant: grant2 };
|
|
49257
49279
|
};
|
|
49258
49280
|
const initial = await read();
|
|
@@ -49261,7 +49283,7 @@ async function authorizePublishedSiteTools(deps, domain, fields2) {
|
|
|
49261
49283
|
if (!version2) throw new HTTPException37(403, { message: "site_tool_not_authorized" });
|
|
49262
49284
|
const reauthorize = async () => {
|
|
49263
49285
|
const live = await read();
|
|
49264
|
-
if (live.host.site.id !== host.site.id || live.host.versionId !== version2.id || live.grant.accountId !== grant.accountId || live.grant.workspaceId !== grant.workspaceId || live.grant.subjectId !== grant.subjectId || live.viewer.sessionId !== initial.viewer.sessionId || grant.permissions.some((permission) => !
|
|
49286
|
+
if (live.host.site.id !== host.site.id || live.host.versionId !== version2.id || live.grant.accountId !== grant.accountId || live.grant.workspaceId !== grant.workspaceId || live.grant.subjectId !== grant.subjectId || live.viewer.sessionId !== initial.viewer.sessionId || grant.permissions.some((permission) => !hasPermission13(live.grant.permissions, permission)))
|
|
49265
49287
|
throw new HTTPException37(403, { message: "site_tool_access_changed" });
|
|
49266
49288
|
};
|
|
49267
49289
|
Object.freeze(grant.permissions);
|
|
@@ -49270,7 +49292,7 @@ async function authorizePublishedSiteTools(deps, domain, fields2) {
|
|
|
49270
49292
|
kind: "published_site_tools",
|
|
49271
49293
|
grant
|
|
49272
49294
|
});
|
|
49273
|
-
|
|
49295
|
+
authorities2.set(authorization, {
|
|
49274
49296
|
requestedTools: version2.requestedTools,
|
|
49275
49297
|
origin: { siteId: host.site.id, versionId: version2.id, title: host.site.title },
|
|
49276
49298
|
reauthorize,
|
|
@@ -49372,7 +49394,7 @@ async function prepareWorkspaceToolGateway(routeDeps, authorization, options = {
|
|
|
49372
49394
|
);
|
|
49373
49395
|
const workspace = await requireWorkspace2(tx, scope.workspaceId);
|
|
49374
49396
|
if (!live || permissions.some(
|
|
49375
|
-
(permission) => !
|
|
49397
|
+
(permission) => !hasPermission14(live.permissions, permission, live.permissionMode)
|
|
49376
49398
|
) || workspace.accountId !== scope.accountId || workspace.kind !== "shared")
|
|
49377
49399
|
throw new HTTPException38(403, { message: "service gateway authority changed" });
|
|
49378
49400
|
}
|
|
@@ -49761,7 +49783,7 @@ async function prepareWorkspaceToolGatewayForGrantInternal(routeDeps, grant, all
|
|
|
49761
49783
|
const firstPartyServers = await Promise.all([
|
|
49762
49784
|
...gatewayServerIds.has("opengeni") ? [inMemoryMcpRegistration("opengeni", buildOpenGeniMcpServer(deps, grant))] : [],
|
|
49763
49785
|
...gatewayServerIds.has("files") ? [inMemoryMcpRegistration("files", buildFilesMcpServer(deps, grant))] : [],
|
|
49764
|
-
...gatewayServerIds.has("docs") &&
|
|
49786
|
+
...gatewayServerIds.has("docs") && hasPermission14(grant.permissions, "documents:search") ? [
|
|
49765
49787
|
inMemoryMcpRegistration(
|
|
49766
49788
|
"docs",
|
|
49767
49789
|
buildDocumentsMcpServer(
|
|
@@ -49986,10 +50008,10 @@ function workspaceToolGatewaySettingsForGrant(settings, grant, allowedIdentities
|
|
|
49986
50008
|
...settings,
|
|
49987
50009
|
mcpServers: settings.mcpServers.filter((server) => {
|
|
49988
50010
|
if (allowedServerIds && !allowedServerIds.has(server.id)) return false;
|
|
49989
|
-
if (server.id === "docs" && !
|
|
50011
|
+
if (server.id === "docs" && !hasPermission14(grant.permissions, "documents:search")) {
|
|
49990
50012
|
return false;
|
|
49991
50013
|
}
|
|
49992
|
-
if (server.id === "files" && !
|
|
50014
|
+
if (server.id === "files" && !hasPermission14(grant.permissions, "files:read")) return false;
|
|
49993
50015
|
return true;
|
|
49994
50016
|
})
|
|
49995
50017
|
};
|
|
@@ -51044,10 +51066,10 @@ function renderMcpOAuthExpiredPage(message) {
|
|
|
51044
51066
|
async function listConsentWorkspaces(deps, context) {
|
|
51045
51067
|
const readableWorkspaceIds = [
|
|
51046
51068
|
...new Set(
|
|
51047
|
-
context.workspaceGrants.filter((grant) =>
|
|
51069
|
+
context.workspaceGrants.filter((grant) => hasPermission15(grant.permissions, "workspace:read")).map((grant) => grant.workspaceId)
|
|
51048
51070
|
)
|
|
51049
51071
|
];
|
|
51050
|
-
const readableAccountIds = context.accountGrants.filter((grant) =>
|
|
51072
|
+
const readableAccountIds = context.accountGrants.filter((grant) => hasPermission15(grant.permissions, "workspace:read")).map((grant) => grant.accountId);
|
|
51051
51073
|
const [fromGrants, memberships, shared] = await Promise.all([
|
|
51052
51074
|
Promise.all(readableWorkspaceIds.map((workspaceId) => getWorkspace2(deps.db, workspaceId))),
|
|
51053
51075
|
listWorkspacesForSubject(deps.db, context.subjectId),
|
|
@@ -51154,7 +51176,7 @@ async function consentOrganizations(deps, context) {
|
|
|
51154
51176
|
personal: workspace.kind === "personal"
|
|
51155
51177
|
})),
|
|
51156
51178
|
grantable: canonical.filter(
|
|
51157
|
-
(permission) => accountGrant !== void 0 &&
|
|
51179
|
+
(permission) => accountGrant !== void 0 && hasPermission15(accountGrant.permissions, permission) || workspaceGrants.some((grant) => hasPermission15(grant.permissions, permission))
|
|
51158
51180
|
)
|
|
51159
51181
|
};
|
|
51160
51182
|
});
|
|
@@ -53019,7 +53041,7 @@ import { HTTPException as HTTPException45 } from "hono/http-exception";
|
|
|
53019
53041
|
import {
|
|
53020
53042
|
accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority2,
|
|
53021
53043
|
organizationApiKeyAccess,
|
|
53022
|
-
hasPermission as
|
|
53044
|
+
hasPermission as hasPermission16,
|
|
53023
53045
|
organizationWorkspaceInScope,
|
|
53024
53046
|
requireAccessContext as requireAccessContext4,
|
|
53025
53047
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization7,
|
|
@@ -53254,7 +53276,7 @@ function ensureOrganizationPolicyDelegable(context, policy, legacy = false) {
|
|
|
53254
53276
|
const authority = accountScopedApiKeyWorkspaceAuthority2(context);
|
|
53255
53277
|
const source = context.credential?.policy;
|
|
53256
53278
|
if (!authority || authority.permissionMode !== "explicit" || !source) return;
|
|
53257
|
-
const requested = legacy ? Permission2.options.filter((permission) =>
|
|
53279
|
+
const requested = legacy ? Permission2.options.filter((permission) => hasPermission16(policy.permissions, permission)) : policy.permissions;
|
|
53258
53280
|
if (requested.some((permission) => !source.permissions.includes(permission)))
|
|
53259
53281
|
throw new HTTPException45(403, {
|
|
53260
53282
|
message: "cannot delegate permissions beyond organization key policy"
|
|
@@ -53572,7 +53594,7 @@ import { HTTPException as HTTPException48 } from "hono/http-exception";
|
|
|
53572
53594
|
// src/workspace-tool-target-fence.ts
|
|
53573
53595
|
import {
|
|
53574
53596
|
externalContinuationCommitAuthorizer as externalContinuationCommitAuthorizer2,
|
|
53575
|
-
hasPermission as
|
|
53597
|
+
hasPermission as hasPermission17,
|
|
53576
53598
|
isVerifiedOrganizationServiceAuthorization as isVerifiedOrganizationServiceAuthorization3
|
|
53577
53599
|
} from "@opengeni/core";
|
|
53578
53600
|
import {
|
|
@@ -53627,7 +53649,7 @@ function targetFenceCaller(deps, authorization, reauthorize) {
|
|
|
53627
53649
|
grant.workspaceId
|
|
53628
53650
|
);
|
|
53629
53651
|
if (!live || permissions.some(
|
|
53630
|
-
(permission) => !
|
|
53652
|
+
(permission) => !hasPermission17(live.permissions, permission, live.permissionMode)
|
|
53631
53653
|
))
|
|
53632
53654
|
throw new HTTPException47(403, { message: "service gateway authority changed" });
|
|
53633
53655
|
}
|
|
@@ -54182,7 +54204,7 @@ import {
|
|
|
54182
54204
|
CodemodeCallRequest,
|
|
54183
54205
|
CodemodeCallSubmission
|
|
54184
54206
|
} from "@opengeni/contracts";
|
|
54185
|
-
import { hasPermission as
|
|
54207
|
+
import { hasPermission as hasPermission18, isDeveloperSetupGrant, requireSessionAuthorization as requireSessionAuthorization6 } from "@opengeni/core";
|
|
54186
54208
|
import {
|
|
54187
54209
|
CodemodeToolApprovalRequiredError,
|
|
54188
54210
|
getActiveSessionTurnForExecution,
|
|
@@ -54226,7 +54248,7 @@ function codemodeSessionProxyPermissions(settings, session) {
|
|
|
54226
54248
|
const selection = allowedFirstPartyMcpToolsForSession2(settings, session.firstPartyMcpTools);
|
|
54227
54249
|
const requiredBySelection = /* @__PURE__ */ new Set([
|
|
54228
54250
|
"workspace:read",
|
|
54229
|
-
...
|
|
54251
|
+
...permissionsRequiredByFirstPartyTools2(selection)
|
|
54230
54252
|
]);
|
|
54231
54253
|
return CODEMODE_SESSION_PROXY_PERMISSION_CEILING.filter(
|
|
54232
54254
|
(permission) => requiredBySelection.has(permission) && sessionPermissions.includes(permission)
|
|
@@ -54347,7 +54369,7 @@ function codemodeAuthorityForGrant(grant) {
|
|
|
54347
54369
|
};
|
|
54348
54370
|
}
|
|
54349
54371
|
function isCodemodeGrant(grant) {
|
|
54350
|
-
return
|
|
54372
|
+
return hasPermission18(grant.permissions, "codemode:call") && codemodeAuthorityForGrant(grant) !== null;
|
|
54351
54373
|
}
|
|
54352
54374
|
function requireMatchingCodemodeCatalog(authority, catalog) {
|
|
54353
54375
|
if (!catalog) throw new CodemodeCatalogNotReadyError();
|
|
@@ -54718,7 +54740,7 @@ import {
|
|
|
54718
54740
|
siteSessionOriginFromMetadata,
|
|
54719
54741
|
withSiteSessionOrigin as withSiteSessionOrigin4
|
|
54720
54742
|
} from "@opengeni/core";
|
|
54721
|
-
import { getSession as getSession7 } from "@opengeni/db";
|
|
54743
|
+
import { getSession as getSession7, getSessionAuthorityProjection as getSessionAuthorityProjection2 } from "@opengeni/db";
|
|
54722
54744
|
import { HTTPException as HTTPException50 } from "hono/http-exception";
|
|
54723
54745
|
var CODEMODE_SDK_PROXY = /^\/v1\/workspaces\/[^/]+\/codemode\/sdk(?:\/|$)/u;
|
|
54724
54746
|
var SITE_DATA = /^\/v1\/workspaces\/[^/]+\/published-artifacts\/([^/]+)\/(?:data|files)(?:\/|$)/u;
|
|
@@ -54750,10 +54772,15 @@ function siteFrameGuard(deps) {
|
|
|
54750
54772
|
throw new HTTPException50(404, { message: "Unsupported Site session API path" });
|
|
54751
54773
|
}
|
|
54752
54774
|
if (match.sessionId !== null) {
|
|
54775
|
+
const authority = await getSessionAuthorityProjection2(
|
|
54776
|
+
deps.db,
|
|
54777
|
+
grant.workspaceId,
|
|
54778
|
+
match.sessionId
|
|
54779
|
+
);
|
|
54753
54780
|
const session = await getSession7(deps.db, grant.workspaceId, match.sessionId).catch(
|
|
54754
54781
|
() => null
|
|
54755
54782
|
);
|
|
54756
|
-
if (!session || !siteOriginsMatch(origin, siteSessionOriginFromMetadata(session.metadata)))
|
|
54783
|
+
if (!authority?.siteAccessRootId || !session || !siteOriginsMatch(origin, siteSessionOriginFromMetadata(session.metadata)))
|
|
54757
54784
|
throw new HTTPException50(404, { message: "session not found" });
|
|
54758
54785
|
}
|
|
54759
54786
|
if (c.req.method !== "GET" && match.operation.id !== "sessions.create") {
|
|
@@ -55587,7 +55614,7 @@ import { sessionUsageLimitsProducerEnabled as sessionUsageLimitsProducerEnabled2
|
|
|
55587
55614
|
import {
|
|
55588
55615
|
CodexCompactionV2ProviderLockedError,
|
|
55589
55616
|
ManagedAuthActorLeaseOutcomeUnknownError,
|
|
55590
|
-
hasPermission as
|
|
55617
|
+
hasPermission as hasPermission44,
|
|
55591
55618
|
requireAccessGrant as requireAccessGrant64,
|
|
55592
55619
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization42,
|
|
55593
55620
|
requireFreshAccessGrant as requireFreshAccessGrant5,
|
|
@@ -55605,7 +55632,7 @@ import {
|
|
|
55605
55632
|
validateManagedAuthRequestActorLease,
|
|
55606
55633
|
requireSessionAuthorization as requireSessionAuthorization21,
|
|
55607
55634
|
SessionAuthorizationDeniedError as SessionAuthorizationDeniedError21,
|
|
55608
|
-
withSessionAuthorizationReadReuse,
|
|
55635
|
+
withSessionAuthorizationReadReuse as withSessionAuthorizationReadReuse3,
|
|
55609
55636
|
SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError19,
|
|
55610
55637
|
createUserPresenceRecorder,
|
|
55611
55638
|
registerProductUsageMetricBaselines,
|
|
@@ -57060,9 +57087,9 @@ import {
|
|
|
57060
57087
|
import { getOAuthState } from "better-auth/api";
|
|
57061
57088
|
|
|
57062
57089
|
// src/auth/managed-auth-attempt-context.ts
|
|
57063
|
-
import { AsyncLocalStorage as
|
|
57064
|
-
var managedAuthAttemptStorage = new
|
|
57065
|
-
var managedLinkIntentStorage = new
|
|
57090
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
57091
|
+
var managedAuthAttemptStorage = new AsyncLocalStorage3();
|
|
57092
|
+
var managedLinkIntentStorage = new AsyncLocalStorage3();
|
|
57066
57093
|
function runManagedSignInConnect(intentId, action) {
|
|
57067
57094
|
return managedLinkIntentStorage.run(intentId, action);
|
|
57068
57095
|
}
|
|
@@ -89503,7 +89530,7 @@ import {
|
|
|
89503
89530
|
isPersonalGitHubConnection as isPersonalGitHubConnection2
|
|
89504
89531
|
} from "@opengeni/contracts/personal-github";
|
|
89505
89532
|
import {
|
|
89506
|
-
hasPermission as
|
|
89533
|
+
hasPermission as hasPermission19,
|
|
89507
89534
|
listOwnConnectionAccountsForGrant,
|
|
89508
89535
|
hasReservedFikenMetadata,
|
|
89509
89536
|
ONEPASSWORD_CREDENTIAL_ROLE as ONEPASSWORD_CREDENTIAL_ROLE2,
|
|
@@ -91488,7 +91515,7 @@ function registerConnectionRoutes(app, deps) {
|
|
|
91488
91515
|
connectionId: c.req.param("connectionId"),
|
|
91489
91516
|
payload: await c.req.json(),
|
|
91490
91517
|
canManageOrganizationDestination: authorization.accountGrant?.permissions.includes("account:admin") === true,
|
|
91491
|
-
canManageWorkspaceDestination:
|
|
91518
|
+
canManageWorkspaceDestination: hasPermission19(grant.permissions, "workspace:admin"),
|
|
91492
91519
|
canManagePersonalDestination: authorization.contextIntegrity && authorization.authenticatedSubjectId === grant.subjectId
|
|
91493
91520
|
});
|
|
91494
91521
|
return c.json(ConnectionResponse.parse({ connection }));
|
|
@@ -91566,7 +91593,7 @@ function registerConnectionRoutes(app, deps) {
|
|
|
91566
91593
|
connectionId: c.req.param("connectionId"),
|
|
91567
91594
|
payload: await c.req.json(),
|
|
91568
91595
|
canManageOrganizationDestination: authorization.accountGrant?.permissions.includes("account:admin") === true,
|
|
91569
|
-
canManageWorkspaceDestination:
|
|
91596
|
+
canManageWorkspaceDestination: hasPermission19(grant.permissions, "workspace:admin"),
|
|
91570
91597
|
canManagePersonalDestination: authorization.contextIntegrity && authorization.authenticatedSubjectId === grant.subjectId
|
|
91571
91598
|
});
|
|
91572
91599
|
return c.json(ConnectionResponse.parse({ connection }));
|
|
@@ -91644,7 +91671,7 @@ function registerConnectionRoutes(app, deps) {
|
|
|
91644
91671
|
if (destinationSelection.authorityKind === "organization" && authorization.accountGrant?.permissions.includes("account:admin") !== true) {
|
|
91645
91672
|
throw new HTTPException64(403, { message: "missing permission: account:admin" });
|
|
91646
91673
|
}
|
|
91647
|
-
if (destinationSelection.authorityKind === "workspace" && !
|
|
91674
|
+
if (destinationSelection.authorityKind === "workspace" && !hasPermission19(grant.permissions, "workspace:admin")) {
|
|
91648
91675
|
throw new HTTPException64(403, { message: "missing permission: workspace:admin" });
|
|
91649
91676
|
}
|
|
91650
91677
|
if (destinationSelection.authorityKind === "personal" && (!authorization.contextIntegrity || authorization.authenticatedSubjectId !== grant.subjectId)) {
|
|
@@ -92422,7 +92449,7 @@ import {
|
|
|
92422
92449
|
import {
|
|
92423
92450
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization10,
|
|
92424
92451
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization11,
|
|
92425
|
-
hasPermission as
|
|
92452
|
+
hasPermission as hasPermission21,
|
|
92426
92453
|
requireEnvironmentEncryption as requireEnvironmentEncryption15,
|
|
92427
92454
|
isFikenConnection as isFikenConnection2,
|
|
92428
92455
|
isOpenGeniSlackBotConnection as isOpenGeniSlackBotConnection4,
|
|
@@ -93931,7 +93958,7 @@ import {
|
|
|
93931
93958
|
import { withOrganizationIntegrationPolicyFence as withOrganizationIntegrationPolicyFence6 } from "@opengeni/db/organization-integration-policy";
|
|
93932
93959
|
import {
|
|
93933
93960
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization9,
|
|
93934
|
-
hasPermission as
|
|
93961
|
+
hasPermission as hasPermission20,
|
|
93935
93962
|
isDeveloperSetupGrant as isDeveloperSetupGrant2,
|
|
93936
93963
|
requireSessionAuthorization as requireSessionAuthorization8
|
|
93937
93964
|
} from "@opengeni/core";
|
|
@@ -93957,7 +93984,7 @@ async function connectRequestActor(deps, authorization) {
|
|
|
93957
93984
|
preparedOnly: false
|
|
93958
93985
|
};
|
|
93959
93986
|
const authority = codemodeAuthorityForGrant(grant);
|
|
93960
|
-
if (!authority || isDeveloperSetupGrant2(grant) || PREPARED_MCP_PERMISSIONS.some((permission) => !
|
|
93987
|
+
if (!authority || isDeveloperSetupGrant2(grant) || PREPARED_MCP_PERMISSIONS.some((permission) => !hasPermission20(grant.permissions, permission)))
|
|
93961
93988
|
throw new HTTPException68(403, { message: "Prepared MCP setup authority required" });
|
|
93962
93989
|
await requireSessionAuthorization8(deps, grant, {
|
|
93963
93990
|
sessionId: authority.sessionId,
|
|
@@ -94019,7 +94046,7 @@ function assertAgentPreparedConnect(actor, attempt) {
|
|
|
94019
94046
|
|
|
94020
94047
|
// src/routes/connect.ts
|
|
94021
94048
|
function registerConnectRoutes(app, deps) {
|
|
94022
|
-
const canReadAttempt = (permissions, providerId) => ["x", "reddit", "mcp-install"].includes(providerId) ?
|
|
94049
|
+
const canReadAttempt = (permissions, providerId) => ["x", "reddit", "mcp-install"].includes(providerId) ? hasPermission21(permissions, "workspace:read") : providerId === "github-app" ? hasPermission21(permissions, "github:use") || hasPermission21(permissions, "github:manage") : providerId === "github-lens" ? hasPermission21(permissions, "workspace:read") : hasPermission21(permissions, "connections:read");
|
|
94023
94050
|
app.get("/v1/workspaces/:workspaceId/connect/catalog", async (c) => {
|
|
94024
94051
|
const authorization = await requireAccessGrantAuthorization11(
|
|
94025
94052
|
c,
|
|
@@ -94033,7 +94060,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94033
94060
|
authorization.grant,
|
|
94034
94061
|
async (_tx, current) => current
|
|
94035
94062
|
);
|
|
94036
|
-
const canWrite2 =
|
|
94063
|
+
const canWrite2 = hasPermission21(authorization.grant.permissions, "connections:write");
|
|
94037
94064
|
const personal = isPersonalConnectionOwnerPrincipal(authorization);
|
|
94038
94065
|
let mcpConfigured = false;
|
|
94039
94066
|
let credentialConfigured = false;
|
|
@@ -94053,7 +94080,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94053
94080
|
configured2 = false;
|
|
94054
94081
|
}
|
|
94055
94082
|
const ownership = [
|
|
94056
|
-
...
|
|
94083
|
+
...hasPermission21(authorization.grant.permissions, "workspace:admin") ? ["workspace"] : [],
|
|
94057
94084
|
...personal ? ["personal"] : []
|
|
94058
94085
|
];
|
|
94059
94086
|
return ConnectProvider.parse({
|
|
@@ -94069,7 +94096,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94069
94096
|
id: "mcp-install",
|
|
94070
94097
|
label: "Install MCP capability",
|
|
94071
94098
|
family: "mcp",
|
|
94072
|
-
readiness: !external || !
|
|
94099
|
+
readiness: !external || !hasPermission21(authorization.grant.permissions, "capabilities:manage") ? "unsupported" : deps.settings.integrationsEnabled ? "available" : "needs_configuration",
|
|
94073
94100
|
ownership: ["workspace"],
|
|
94074
94101
|
setup: ["installation"]
|
|
94075
94102
|
}),
|
|
@@ -94131,7 +94158,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94131
94158
|
id: "github-app",
|
|
94132
94159
|
label: "GitHub App installation",
|
|
94133
94160
|
family: "github",
|
|
94134
|
-
readiness: !external || !
|
|
94161
|
+
readiness: !external || !hasPermission21(authorization.grant.permissions, "github:manage") ? "unsupported" : githubAppMissingSettings3(deps.settings).length === 0 && deps.settings.githubAppSlug?.trim() ? "available" : "needs_configuration",
|
|
94135
94162
|
ownership: ["workspace"],
|
|
94136
94163
|
setup: ["oauth", "installation"]
|
|
94137
94164
|
}),
|
|
@@ -94139,7 +94166,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94139
94166
|
id: "github-lens",
|
|
94140
94167
|
label: "Opengeni Lens PR review",
|
|
94141
94168
|
family: "github-lens",
|
|
94142
|
-
readiness: !external || !
|
|
94169
|
+
readiness: !external || !hasPermission21(authorization.grant.permissions, "workspace:admin") || !hasPermission21(authorization.grant.permissions, "secrets:write") ? "unsupported" : credentialConfigured && deps.settings.sandboxBackend !== "selfhosted" && prReviewGitHubAppMissingSettings2(deps.settings).length === 0 ? "available" : "needs_configuration",
|
|
94143
94170
|
ownership: ["workspace"],
|
|
94144
94171
|
setup: ["oauth", "installation"]
|
|
94145
94172
|
}),
|
|
@@ -94205,8 +94232,8 @@ function registerConnectRoutes(app, deps) {
|
|
|
94205
94232
|
app.get("/v1/workspaces/:workspaceId/connect/accounts", async (c) => {
|
|
94206
94233
|
const workspaceId = c.req.param("workspaceId");
|
|
94207
94234
|
const { grant } = await requireAccessGrantAuthorization11(c, deps, workspaceId, "workspace:read");
|
|
94208
|
-
const connections =
|
|
94209
|
-
const githubInstallations =
|
|
94235
|
+
const connections = hasPermission21(grant.permissions, "connections:read") ? await listConnectionsMetadata6(deps.db, workspaceId, grant.subjectId) : [];
|
|
94236
|
+
const githubInstallations = hasPermission21(grant.permissions, "github:use") || hasPermission21(grant.permissions, "github:manage") ? await listGitHubInstallationAccessForWorkspace2(deps.db, workspaceId) : [];
|
|
94210
94237
|
const lensRegistrations = await listPrReviewAppRegistrations(
|
|
94211
94238
|
deps.db,
|
|
94212
94239
|
grant.accountId,
|
|
@@ -94355,9 +94382,9 @@ function registerConnectRoutes(app, deps) {
|
|
|
94355
94382
|
const before = stored.attempt;
|
|
94356
94383
|
assertAgentPreparedConnect(actor, before);
|
|
94357
94384
|
const advancePermission = before.providerId === "mcp-install" ? "capabilities:manage" : permission;
|
|
94358
|
-
if (!
|
|
94385
|
+
if (!hasPermission21(authorization.grant.permissions, advancePermission))
|
|
94359
94386
|
throw new HTTPException69(403, { message: `${advancePermission} required` });
|
|
94360
|
-
if (before.mcpSetup && !
|
|
94387
|
+
if (before.mcpSetup && !hasPermission21(authorization.grant.permissions, "capabilities:manage"))
|
|
94361
94388
|
throw new HTTPException69(403, { message: "capabilities:manage required" });
|
|
94362
94389
|
if (before.providerId === "mcp-install") {
|
|
94363
94390
|
if (action.type !== "credentials")
|
|
@@ -94403,7 +94430,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94403
94430
|
}
|
|
94404
94431
|
if (["github-app", "github-lens"].includes(before.providerId)) {
|
|
94405
94432
|
const installationPermission = before.providerId === "github-lens" ? "workspace:admin" : "github:manage";
|
|
94406
|
-
if (!
|
|
94433
|
+
if (!hasPermission21(authorization.grant.permissions, installationPermission) || before.providerId === "github-lens" && !hasPermission21(authorization.grant.permissions, "secrets:write"))
|
|
94407
94434
|
throw new HTTPException69(403, { message: "Installation management permission required" });
|
|
94408
94435
|
return c.json(
|
|
94409
94436
|
await executeConnectOperation({
|
|
@@ -94894,7 +94921,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94894
94921
|
authorize: async (tx, attempt, origin) => {
|
|
94895
94922
|
assertAgentPreparedConnect(actor, attempt);
|
|
94896
94923
|
const permission = attempt.providerId === "mcp-install" ? "capabilities:manage" : ["x", "reddit"].includes(attempt.providerId) ? attempt.ownership === "workspace" ? "workspace:admin" : "workspace:read" : attempt.providerId === "github-app" ? "github:manage" : attempt.providerId === "github-lens" ? "workspace:admin" : "connections:write";
|
|
94897
|
-
if (!
|
|
94924
|
+
if (!hasPermission21(authorization.grant.permissions, permission) || attempt.providerId === "github-lens" && !hasPermission21(authorization.grant.permissions, "secrets:write"))
|
|
94898
94925
|
throw new HTTPException69(403, { message: "Connect management permission required" });
|
|
94899
94926
|
await requireConnectOwnerAuthority(tx, scope, permission, origin);
|
|
94900
94927
|
if (attempt.providerId === "github-lens")
|
|
@@ -94928,7 +94955,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
94928
94955
|
throw new HTTPException69(403, {
|
|
94929
94956
|
message: "Verified Connect authority required"
|
|
94930
94957
|
});
|
|
94931
|
-
if (input.mcpSetup && !
|
|
94958
|
+
if (input.mcpSetup && !hasPermission21(authorization.grant.permissions, "capabilities:manage"))
|
|
94932
94959
|
throw new HTTPException69(403, { message: "capabilities:manage required" });
|
|
94933
94960
|
if (input.providerId === "atlassian")
|
|
94934
94961
|
throw new HTTPException69(410, { message: ATLASSIAN_NATIVE_RETIRED_MESSAGE2 });
|
|
@@ -95110,7 +95137,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
95110
95137
|
message: "GitHub App setup requires workspace ownership and explicit installation selection"
|
|
95111
95138
|
});
|
|
95112
95139
|
if (input.providerId === "github-lens") {
|
|
95113
|
-
if (!
|
|
95140
|
+
if (!hasPermission21(authorization.grant.permissions, "secrets:write"))
|
|
95114
95141
|
throw new HTTPException69(403, { message: "secrets:write required" });
|
|
95115
95142
|
await requireConnectOwnerAuthority(tx, scope, "secrets:write");
|
|
95116
95143
|
await requireGitHubLensConnect({ ...deps, db: tx });
|
|
@@ -95149,7 +95176,7 @@ function registerConnectRoutes(app, deps) {
|
|
|
95149
95176
|
throw new HTTPException69(422, { message: "Select the service connection during setup" });
|
|
95150
95177
|
if (input.ownership === "personal" && !scope.personalOwnerVerified)
|
|
95151
95178
|
throw new HTTPException69(403, { message: "personal ownership unavailable" });
|
|
95152
|
-
const choices =
|
|
95179
|
+
const choices = hasPermission21(authorization.grant.permissions, "connections:read") ? (await listConnectionsMetadata6(tx, workspaceId, scope.subjectId)).filter(
|
|
95153
95180
|
(connection) => connection.status === "active" && (input.ownership === "workspace" ? connection.subjectId === null : connection.subjectId === scope.subjectId)
|
|
95154
95181
|
).map((connection) => ({
|
|
95155
95182
|
value: connection.id,
|
|
@@ -95486,7 +95513,7 @@ import {
|
|
|
95486
95513
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization12,
|
|
95487
95514
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization11,
|
|
95488
95515
|
externalContinuationCommitAuthorizer as externalContinuationCommitAuthorizer4,
|
|
95489
|
-
hasPermission as
|
|
95516
|
+
hasPermission as hasPermission22
|
|
95490
95517
|
} from "@opengeni/core";
|
|
95491
95518
|
function nativeConfirmation(authorization) {
|
|
95492
95519
|
if (!authorization.contextIntegrity || !authorization.canonicalManagedHumanSession || authorization.authenticatedSubjectId !== authorization.grant.subjectId || !authorization.grant.subjectId.startsWith("user:"))
|
|
@@ -95600,7 +95627,7 @@ function registerExternalIdentityLinkRoutes(app, deps) {
|
|
|
95600
95627
|
principalKind: "human_session"
|
|
95601
95628
|
});
|
|
95602
95629
|
if (!current || current.accountId !== grant.accountId || request.permissions.some(
|
|
95603
|
-
(permission) => !
|
|
95630
|
+
(permission) => !hasPermission22(grant.permissions, permission) || !hasPermission22(current.permissions, permission)
|
|
95604
95631
|
))
|
|
95605
95632
|
throw new HTTPException70(403, {
|
|
95606
95633
|
message: "Link permissions exceed your authority in this workspace"
|
|
@@ -96475,7 +96502,7 @@ import {
|
|
|
96475
96502
|
KnowledgeVectorCreditsDisabledError,
|
|
96476
96503
|
KnowledgeVectorFundingError,
|
|
96477
96504
|
KnowledgeVectorQueryRejectedError,
|
|
96478
|
-
hasPermission as
|
|
96505
|
+
hasPermission as hasPermission23,
|
|
96479
96506
|
knowledgeContextForAccess as knowledgeContextForAccess2,
|
|
96480
96507
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization14,
|
|
96481
96508
|
requireSessionAuthorization as requireSessionAuthorization9,
|
|
@@ -96571,7 +96598,7 @@ function registerKnowledgeRoutes(app, deps) {
|
|
|
96571
96598
|
c.req.param("workspaceId"),
|
|
96572
96599
|
write ? "documents:manage" : readPermission === "workspace:read" ? void 0 : readPermission
|
|
96573
96600
|
);
|
|
96574
|
-
const permission = write ? "documents:manage" : readPermission === "workspace:read" &&
|
|
96601
|
+
const permission = write ? "documents:manage" : readPermission === "workspace:read" && hasPermission23(access.grant.permissions, "documents:search") ? "documents:search" : readPermission;
|
|
96575
96602
|
return await withAccessGrantSessionRlsContext(deps, access.grant, async () => {
|
|
96576
96603
|
const context = await knowledgeContextForAccess2(deps, access, permission);
|
|
96577
96604
|
c.header("cache-control", "private, no-store");
|
|
@@ -96901,7 +96928,7 @@ function registerKnowledgeRoutes(app, deps) {
|
|
|
96901
96928
|
throw new HTTPException72(403, { message: "Agents cannot change learning settings" });
|
|
96902
96929
|
const access = await requireAccessGrantAuthorization14(c, deps, context.workspaceId);
|
|
96903
96930
|
if (request.source?.kind === "chat") {
|
|
96904
|
-
if (!
|
|
96931
|
+
if (!hasPermission23(access.grant.permissions, "sessions:control"))
|
|
96905
96932
|
throw new HTTPException72(403, { message: "Chat settings require session control" });
|
|
96906
96933
|
await requireSessionAuthorization9(deps, access.grant, {
|
|
96907
96934
|
sessionId: request.source.id,
|
|
@@ -96910,7 +96937,7 @@ function registerKnowledgeRoutes(app, deps) {
|
|
|
96910
96937
|
});
|
|
96911
96938
|
context.actor.settingsScopes = [request.scope];
|
|
96912
96939
|
} else if (request.source?.kind === "scheduled_task") {
|
|
96913
|
-
if (!
|
|
96940
|
+
if (!hasPermission23(access.grant.permissions, "scheduled_tasks:manage"))
|
|
96914
96941
|
throw new HTTPException72(403, {
|
|
96915
96942
|
message: "Scheduled task settings require task management"
|
|
96916
96943
|
});
|
|
@@ -99032,7 +99059,7 @@ import {
|
|
|
99032
99059
|
revokeOrganizationMcpConnection,
|
|
99033
99060
|
updateOrganizationMcpConnectionAccess
|
|
99034
99061
|
} from "@opengeni/db";
|
|
99035
|
-
import { hasPermission as
|
|
99062
|
+
import { hasPermission as hasPermission24, requireAccessContext as requireAccessContext8 } from "@opengeni/core";
|
|
99036
99063
|
import { HTTPException as HTTPException77 } from "hono/http-exception";
|
|
99037
99064
|
import { z as z49 } from "zod";
|
|
99038
99065
|
function registerOrganizationMcpConnectionRoutes(app, deps) {
|
|
@@ -99117,7 +99144,7 @@ async function requireOrganizationPerson2(c, deps) {
|
|
|
99117
99144
|
if (context.mode !== "managed" || !context.subjectId.startsWith("user:") || !grant) {
|
|
99118
99145
|
throw new HTTPException77(404, { message: "organization not found" });
|
|
99119
99146
|
}
|
|
99120
|
-
return { context, organizationId: organizationId2, admin:
|
|
99147
|
+
return { context, organizationId: organizationId2, admin: hasPermission24(grant.permissions, "account:admin") };
|
|
99121
99148
|
}
|
|
99122
99149
|
async function requireConnection(deps, organizationId2, connectionId) {
|
|
99123
99150
|
if (!z49.string().uuid().safeParse(connectionId).success) {
|
|
@@ -99185,7 +99212,7 @@ import {
|
|
|
99185
99212
|
revokePersonalApiKey
|
|
99186
99213
|
} from "@opengeni/db";
|
|
99187
99214
|
import {
|
|
99188
|
-
hasPermission as
|
|
99215
|
+
hasPermission as hasPermission25,
|
|
99189
99216
|
PERSONAL_API_KEY_TOKEN_PREFIX,
|
|
99190
99217
|
requireAccessContext as requireAccessContext9
|
|
99191
99218
|
} from "@opengeni/core";
|
|
@@ -99275,7 +99302,7 @@ async function requireOrganizationPerson3(c, deps, mutation) {
|
|
|
99275
99302
|
if (context.mode !== "managed" || !context.subjectId.startsWith("user:") || !grant) {
|
|
99276
99303
|
throw new HTTPException78(404, { message: "organization not found" });
|
|
99277
99304
|
}
|
|
99278
|
-
return { context, organizationId: organizationId2, admin:
|
|
99305
|
+
return { context, organizationId: organizationId2, admin: hasPermission25(grant.permissions, "account:admin") };
|
|
99279
99306
|
}
|
|
99280
99307
|
async function projectKeys(deps, keys2) {
|
|
99281
99308
|
const userIds = [...new Set(keys2.map((key2) => key2.ownerSubjectId.slice("user:".length)))];
|
|
@@ -100633,6 +100660,7 @@ import {
|
|
|
100633
100660
|
import {
|
|
100634
100661
|
requireAccessGrant as requireAccessGrant31,
|
|
100635
100662
|
requireSessionAuthorization as requireSessionAuthorization13,
|
|
100663
|
+
withSessionAuthorizationReadReuse,
|
|
100636
100664
|
recordWorkspaceUsage as recordWorkspaceUsage5,
|
|
100637
100665
|
requireLimit as requireLimit6,
|
|
100638
100666
|
relayConfigFromSettings as relayConfigFromSettings3,
|
|
@@ -102643,7 +102671,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
|
|
|
102643
102671
|
fileIds: workspaceFileIds
|
|
102644
102672
|
});
|
|
102645
102673
|
const ordered = requireAuthorizedBrowserUploadFiles(workspaceFileIds, files);
|
|
102646
|
-
const
|
|
102674
|
+
const authorities3 = await Promise.all(
|
|
102647
102675
|
ordered.map(async (file) => {
|
|
102648
102676
|
const signed = await deps.objectStorage.createGetUrl({
|
|
102649
102677
|
key: file.objectKey,
|
|
@@ -102664,7 +102692,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
|
|
|
102664
102692
|
);
|
|
102665
102693
|
await sessionClient.stageWorkspaceFiles({
|
|
102666
102694
|
operationId: request.operationId,
|
|
102667
|
-
files:
|
|
102695
|
+
files: authorities3
|
|
102668
102696
|
});
|
|
102669
102697
|
}
|
|
102670
102698
|
}
|
|
@@ -104137,6 +104165,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
|
|
|
104137
104165
|
operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
|
|
104138
104166
|
operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
|
|
104139
104167
|
transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
|
|
104168
|
+
browserControlHttpSupported: enrollment.agentCapabilities.browserControlHttp === true,
|
|
104140
104169
|
...deps.settings.agentOpStreamEnabled === true && enrollment.opStream === true && deps.bus.getOpStreamConnection ? {
|
|
104141
104170
|
opStream: {
|
|
104142
104171
|
transport: new NatsOpStreamTransport2(
|
|
@@ -104380,6 +104409,22 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
|
|
|
104380
104409
|
});
|
|
104381
104410
|
}
|
|
104382
104411
|
async function withActiveBrowserController(context, grant, workspaceId, browserSessionId, authorizationOperation, channelOperation, callback, recoverMissing = true, stages) {
|
|
104412
|
+
return await withSessionAuthorizationReadReuse(
|
|
104413
|
+
(authorizationReads) => withActiveBrowserControllerReads(
|
|
104414
|
+
context,
|
|
104415
|
+
grant,
|
|
104416
|
+
workspaceId,
|
|
104417
|
+
browserSessionId,
|
|
104418
|
+
authorizationOperation,
|
|
104419
|
+
channelOperation,
|
|
104420
|
+
callback,
|
|
104421
|
+
recoverMissing,
|
|
104422
|
+
stages,
|
|
104423
|
+
authorizationReads
|
|
104424
|
+
)
|
|
104425
|
+
);
|
|
104426
|
+
}
|
|
104427
|
+
async function withActiveBrowserControllerReads(context, grant, workspaceId, browserSessionId, authorizationOperation, channelOperation, callback, recoverMissing, stages, authorizationReads) {
|
|
104383
104428
|
try {
|
|
104384
104429
|
const record8 = await getBrowserSessionControlRecord(deps.db, {
|
|
104385
104430
|
accountId: grant.accountId,
|
|
@@ -104387,17 +104432,18 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
|
|
|
104387
104432
|
browserSessionId
|
|
104388
104433
|
});
|
|
104389
104434
|
stages?.mark("record");
|
|
104390
|
-
const
|
|
104391
|
-
|
|
104392
|
-
grant,
|
|
104393
|
-
record8.sourceSessionId
|
|
104394
|
-
|
|
104395
|
-
);
|
|
104435
|
+
const sourceSessionNeeded = record8.session.placement?.kind === "connected_machine" || !record8.controllerHostSandboxGroupId;
|
|
104436
|
+
const [authorized, sourceRead] = await Promise.allSettled([
|
|
104437
|
+
authorizeSourceSession2(deps, grant, record8.sourceSessionId, authorizationOperation),
|
|
104438
|
+
sourceSessionNeeded ? requireSourceSession(deps, workspaceId, record8.sourceSessionId) : Promise.resolve(null)
|
|
104439
|
+
]);
|
|
104440
|
+
if (authorized.status === "rejected") throw authorized.reason;
|
|
104441
|
+
if (sourceRead.status === "rejected") throw sourceRead.reason;
|
|
104442
|
+
const sourceAuthorization = authorized.value;
|
|
104396
104443
|
stages?.mark("authorize");
|
|
104397
|
-
let sourceSession =
|
|
104444
|
+
let sourceSession = sourceRead.value;
|
|
104398
104445
|
if (record8.session.placement?.kind === "connected_machine") {
|
|
104399
|
-
|
|
104400
|
-
if (sourceSession.activeSandboxId !== record8.session.placement.sandboxId) {
|
|
104446
|
+
if (sourceSession?.activeSandboxId !== record8.session.placement.sandboxId) {
|
|
104401
104447
|
return await throwBrowserSourcePlacementChanged(
|
|
104402
104448
|
grant,
|
|
104403
104449
|
record8.sourceSessionId,
|
|
@@ -104424,6 +104470,7 @@ function registerBrowserSessionRoutes(app, deps, options = {}) {
|
|
|
104424
104470
|
let controllerTransportFailed = false;
|
|
104425
104471
|
const controllerRecoveryState = { attempted: false };
|
|
104426
104472
|
const run2 = async (placement, provisionedClient) => {
|
|
104473
|
+
authorizationReads.handOffToToolDispatch();
|
|
104427
104474
|
const client = provisionedClient ?? connectController(deps, grant, record8, placement);
|
|
104428
104475
|
const tokens = (0, browser_controller_authority_exports.deriveBrowserSessionControllerTokens)({
|
|
104429
104476
|
rootSecret: browserAuthorityRoot(deps),
|
|
@@ -106098,9 +106145,10 @@ import {
|
|
|
106098
106145
|
touchComputerSessionController
|
|
106099
106146
|
} from "@opengeni/db";
|
|
106100
106147
|
import {
|
|
106101
|
-
hasPermission as
|
|
106148
|
+
hasPermission as hasPermission26,
|
|
106102
106149
|
requireAccessGrant as requireAccessGrant32,
|
|
106103
106150
|
requireSessionAuthorization as requireSessionAuthorization14,
|
|
106151
|
+
withSessionAuthorizationReadReuse as withSessionAuthorizationReadReuse2,
|
|
106104
106152
|
relayConfigFromSettings as relayConfigFromSettings4,
|
|
106105
106153
|
resolveChannelAMachineConnection as resolveChannelAMachineConnection2,
|
|
106106
106154
|
resolveSessionSandboxRuntime as resolveSessionSandboxRuntime4,
|
|
@@ -106823,7 +106871,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
|
|
|
106823
106871
|
}
|
|
106824
106872
|
);
|
|
106825
106873
|
async function authorizeHumanFrameInput(grant, record8, placement) {
|
|
106826
|
-
if ((record8.session.placement.kind === "connected_machine" || record8.session.placement.kind === "attached_device") && placement.screenControlAllowed !== true || record8.session.placement.kind === "sandbox_group" && deps.settings.sandboxDesktopInteractive === false || grant.principalKind === "agent_attempt" || !
|
|
106874
|
+
if ((record8.session.placement.kind === "connected_machine" || record8.session.placement.kind === "attached_device") && placement.screenControlAllowed !== true || record8.session.placement.kind === "sandbox_group" && deps.settings.sandboxDesktopInteractive === false || grant.principalKind === "agent_attempt" || !hasPermission26(grant.permissions, "sessions:control"))
|
|
106827
106875
|
return false;
|
|
106828
106876
|
try {
|
|
106829
106877
|
await requireSessionAuthorization14(deps, grant, {
|
|
@@ -106994,6 +107042,32 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
|
|
|
106994
107042
|
}
|
|
106995
107043
|
}
|
|
106996
107044
|
);
|
|
107045
|
+
async function routedMachineConnection(handle, grant, sourceSession, sandboxId) {
|
|
107046
|
+
const machineAuthority = await handle.machineAuthority();
|
|
107047
|
+
const sandbox = await getSandbox5(
|
|
107048
|
+
deps.db,
|
|
107049
|
+
{
|
|
107050
|
+
accountId: grant.accountId,
|
|
107051
|
+
workspaceId: sourceSession.workspaceId,
|
|
107052
|
+
subjectId: machineAuthority.subjectId
|
|
107053
|
+
},
|
|
107054
|
+
sandboxId
|
|
107055
|
+
);
|
|
107056
|
+
if (sandbox?.kind !== "selfhosted" || !sandbox.enrollmentId) {
|
|
107057
|
+
throw new ComputerSessionStateError("Connected Machine placement is unavailable");
|
|
107058
|
+
}
|
|
107059
|
+
return await resolveChannelAMachineConnection2(
|
|
107060
|
+
deps.db,
|
|
107061
|
+
{
|
|
107062
|
+
accountId: grant.accountId,
|
|
107063
|
+
workspaceId: sourceSession.workspaceId,
|
|
107064
|
+
sessionId: sourceSession.id,
|
|
107065
|
+
machineWorkspaceId: sandbox.workspaceId,
|
|
107066
|
+
enrollmentId: sandbox.enrollmentId
|
|
107067
|
+
},
|
|
107068
|
+
machineAuthority
|
|
107069
|
+
);
|
|
107070
|
+
}
|
|
106997
107071
|
async function withComputerPlacement(sourceSession, grant, expectedPlacement, expectedPlacementInstanceId, operation, waitSignal, callback) {
|
|
106998
107072
|
if (expectedPlacement?.kind === "external_provider") {
|
|
106999
107073
|
throw new BrowserControlUnsupportedError3(
|
|
@@ -107041,6 +107115,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
|
|
|
107041
107115
|
operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
|
|
107042
107116
|
operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
|
|
107043
107117
|
transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
|
|
107118
|
+
browserControlHttpSupported: enrollment.agentCapabilities.browserControlHttp === true,
|
|
107044
107119
|
...deps.settings.agentOpStreamEnabled === true && enrollment.opStream === true && deps.bus.getOpStreamConnection ? {
|
|
107045
107120
|
opStream: {
|
|
107046
107121
|
transport: new NatsOpStreamTransport3(
|
|
@@ -107088,30 +107163,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
|
|
|
107088
107163
|
const resolved = await handle.routingSession.prime();
|
|
107089
107164
|
let screenControlAllowed = false;
|
|
107090
107165
|
if (operation !== "computer.end" && resolved.kind === "selfhosted" && resolved.sandboxId) {
|
|
107091
|
-
const
|
|
107092
|
-
const sandbox = await getSandbox5(
|
|
107093
|
-
deps.db,
|
|
107094
|
-
{
|
|
107095
|
-
accountId: grant.accountId,
|
|
107096
|
-
workspaceId: sourceSession.workspaceId,
|
|
107097
|
-
subjectId: machineAuthority.subjectId
|
|
107098
|
-
},
|
|
107099
|
-
resolved.sandboxId
|
|
107100
|
-
);
|
|
107101
|
-
if (sandbox?.kind !== "selfhosted" || !sandbox.enrollmentId) {
|
|
107102
|
-
throw new ComputerSessionStateError("Connected Machine placement is unavailable");
|
|
107103
|
-
}
|
|
107104
|
-
const enrollment = await resolveChannelAMachineConnection2(
|
|
107105
|
-
deps.db,
|
|
107106
|
-
{
|
|
107107
|
-
accountId: grant.accountId,
|
|
107108
|
-
workspaceId: sourceSession.workspaceId,
|
|
107109
|
-
sessionId: sourceSession.id,
|
|
107110
|
-
machineWorkspaceId: sandbox.workspaceId,
|
|
107111
|
-
enrollmentId: sandbox.enrollmentId
|
|
107112
|
-
},
|
|
107113
|
-
machineAuthority
|
|
107114
|
-
);
|
|
107166
|
+
const enrollment = handle.pinnedMachine?.sandboxId === resolved.sandboxId ? handle.pinnedMachine.enrollment : await routedMachineConnection(handle, grant, sourceSession, resolved.sandboxId);
|
|
107115
107167
|
if (!enrollment?.connectionInstanceId) {
|
|
107116
107168
|
throw new ComputerSessionStateError("Connected Machine is unavailable");
|
|
107117
107169
|
}
|
|
@@ -107273,17 +107325,37 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
|
|
|
107273
107325
|
});
|
|
107274
107326
|
}
|
|
107275
107327
|
async function withActiveComputerController(context, grant, workspaceId, computerSessionId, authorizationOperation, channelOperation, callback, recoverMissing = true) {
|
|
107328
|
+
return await withSessionAuthorizationReadReuse2(
|
|
107329
|
+
(authorizationReads) => withActiveComputerControllerReads(
|
|
107330
|
+
context,
|
|
107331
|
+
grant,
|
|
107332
|
+
workspaceId,
|
|
107333
|
+
computerSessionId,
|
|
107334
|
+
authorizationOperation,
|
|
107335
|
+
channelOperation,
|
|
107336
|
+
callback,
|
|
107337
|
+
recoverMissing,
|
|
107338
|
+
authorizationReads
|
|
107339
|
+
)
|
|
107340
|
+
);
|
|
107341
|
+
}
|
|
107342
|
+
async function withActiveComputerControllerReads(context, grant, workspaceId, computerSessionId, authorizationOperation, channelOperation, callback, recoverMissing, authorizationReads) {
|
|
107276
107343
|
try {
|
|
107277
107344
|
const record8 = await getComputerSessionControlRecord2(deps.db, {
|
|
107278
107345
|
accountId: grant.accountId,
|
|
107279
107346
|
workspaceId,
|
|
107280
107347
|
computerSessionId
|
|
107281
107348
|
});
|
|
107282
|
-
|
|
107283
|
-
|
|
107349
|
+
const sourceSessionNeeded = record8.session.placement?.kind !== "sandbox_group";
|
|
107350
|
+
const [authorized, sourceRead] = await Promise.allSettled([
|
|
107351
|
+
authorizeSourceSession3(deps, grant, record8.sourceSessionId, authorizationOperation),
|
|
107352
|
+
sourceSessionNeeded ? requireSourceSession2(deps, workspaceId, record8.sourceSessionId) : Promise.resolve(null)
|
|
107353
|
+
]);
|
|
107354
|
+
if (authorized.status === "rejected") throw authorized.reason;
|
|
107355
|
+
if (sourceRead.status === "rejected") throw sourceRead.reason;
|
|
107356
|
+
let sourceSession = sourceRead.value;
|
|
107284
107357
|
if (record8.session.placement?.kind === "connected_machine") {
|
|
107285
|
-
|
|
107286
|
-
if (sourceSession.activeSandboxId !== record8.session.placement.sandboxId) {
|
|
107358
|
+
if (sourceSession?.activeSandboxId !== record8.session.placement.sandboxId) {
|
|
107287
107359
|
return await throwComputerSourcePlacementChanged(
|
|
107288
107360
|
grant,
|
|
107289
107361
|
record8.sourceSessionId,
|
|
@@ -107305,6 +107377,7 @@ function registerComputerSessionRoutes(app, deps, options = {}) {
|
|
|
107305
107377
|
throw new ComputerSessionStateError("ComputerSession controller authority changed");
|
|
107306
107378
|
}
|
|
107307
107379
|
const run2 = async (placement) => {
|
|
107380
|
+
authorizationReads.handOffToToolDispatch();
|
|
107308
107381
|
const client = connectController2(grant, record8, placement);
|
|
107309
107382
|
const tokens = (0, browser_controller_authority_exports.deriveComputerSessionControllerTokens)({
|
|
107310
107383
|
rootSecret: controllerAuthorityRoot(deps),
|
|
@@ -107994,7 +108067,7 @@ import { deleteCookie, setCookie } from "hono/cookie";
|
|
|
107994
108067
|
import { HTTPException as HTTPException87 } from "hono/http-exception";
|
|
107995
108068
|
import {
|
|
107996
108069
|
githubAppActionPolicyActor,
|
|
107997
|
-
hasPermission as
|
|
108070
|
+
hasPermission as hasPermission28,
|
|
107998
108071
|
listGitHubActionPolicyActors,
|
|
107999
108072
|
personalGitHubActionPolicyActor,
|
|
108000
108073
|
requireAccessGrant as requireAccessGrant33,
|
|
@@ -108010,7 +108083,7 @@ import { HTTPException as HTTPException86 } from "hono/http-exception";
|
|
|
108010
108083
|
import {
|
|
108011
108084
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization12,
|
|
108012
108085
|
requireConnectOwnerAuthority as requireConnectOwnerAuthority3,
|
|
108013
|
-
hasPermission as
|
|
108086
|
+
hasPermission as hasPermission27
|
|
108014
108087
|
} from "@opengeni/core";
|
|
108015
108088
|
async function integrationCommitGrant(authorization, permissions, request) {
|
|
108016
108089
|
const grant = structuredClone(authorization.grant);
|
|
@@ -108027,7 +108100,7 @@ async function integrationCommitGrant(authorization, permissions, request) {
|
|
|
108027
108100
|
const secret = resolveFirstPartyDelegationSecret6(request.settings);
|
|
108028
108101
|
const signed = token && secret ? await verifyDelegatedAccessToken2(secret, token) : null;
|
|
108029
108102
|
if (signed) {
|
|
108030
|
-
const matches = (value) => value.accountId === state.accountId && value.workspaceId === state.workspaceId && value.subjectId === state.subjectId && required.every((permission) =>
|
|
108103
|
+
const matches = (value) => value.accountId === state.accountId && value.workspaceId === state.workspaceId && value.subjectId === state.subjectId && required.every((permission) => hasPermission27(value.permissions, permission));
|
|
108031
108104
|
if (!matches(signed))
|
|
108032
108105
|
throw new HTTPException86(403, { message: "Integration bearer authority mismatch" });
|
|
108033
108106
|
return {
|
|
@@ -108105,7 +108178,7 @@ function registerGitHubRoutes(app, deps) {
|
|
|
108105
108178
|
const installations = missing.length === 0 ? await listWorkspaceGitHubInstallationBindings(deps, grant.workspaceId) : [];
|
|
108106
108179
|
const status = githubBindingStatus(missing.length === 0, installations);
|
|
108107
108180
|
const setupMode = settings.productAccessMode === "managed" ? "platform" : "operator";
|
|
108108
|
-
const canManage = !externalActorContinuationForAuthorization13(access) &&
|
|
108181
|
+
const canManage = !externalActorContinuationForAuthorization13(access) && hasPermission28(grant.permissions, "github:manage");
|
|
108109
108182
|
const returnPath = githubSessionReturnPath(c.req.query("returnPath"), grant.workspaceId);
|
|
108110
108183
|
const connectState = missing.length === 0 && slug && canManage ? createSignedState13(githubStateSecret, {
|
|
108111
108184
|
accountId: grant.accountId,
|
|
@@ -108899,7 +108972,7 @@ function githubRepositoryBranchesRouteError(error) {
|
|
|
108899
108972
|
return new HTTPException87(502, { message: "GitHub branch discovery is unavailable" });
|
|
108900
108973
|
}
|
|
108901
108974
|
function requirePublicGitHubRepositoryVerificationPermission(grant) {
|
|
108902
|
-
if (
|
|
108975
|
+
if (hasPermission28(grant.permissions, "sessions:create") || hasPermission28(grant.permissions, "sessions:control")) {
|
|
108903
108976
|
return;
|
|
108904
108977
|
}
|
|
108905
108978
|
throw new HTTPException87(403, {
|
|
@@ -109774,7 +109847,7 @@ import {
|
|
|
109774
109847
|
buildConnectionTokenResolver as buildConnectionTokenResolver8,
|
|
109775
109848
|
getConnectionMetadata as getConnectionMetadata13,
|
|
109776
109849
|
getPersonalGitHubRepositorySelectionState as getPersonalGitHubRepositorySelectionState3,
|
|
109777
|
-
getSessionAuthorityProjection as
|
|
109850
|
+
getSessionAuthorityProjection as getSessionAuthorityProjection3,
|
|
109778
109851
|
getSessionTurnForAttempt,
|
|
109779
109852
|
resolveAcceptedConnectionUse
|
|
109780
109853
|
} from "@opengeni/db";
|
|
@@ -109957,7 +110030,7 @@ async function resolveBrokerAuthority(deps, secret, claims, routeId) {
|
|
|
109957
110030
|
claims.sessionId,
|
|
109958
110031
|
claims.attemptId
|
|
109959
110032
|
);
|
|
109960
|
-
const session = await
|
|
110033
|
+
const session = await getSessionAuthorityProjection3(
|
|
109961
110034
|
deps.db,
|
|
109962
110035
|
claims.workspaceId,
|
|
109963
110036
|
claims.sessionId
|
|
@@ -110297,7 +110370,7 @@ import {
|
|
|
110297
110370
|
import { withOrganizationIntegrationPolicyFence as withOrganizationIntegrationPolicyFence8 } from "@opengeni/db/organization-integration-policy";
|
|
110298
110371
|
import { CORE_INTEGRATION_DEFINITIONS as CORE_INTEGRATION_DEFINITIONS5 } from "@opengeni/capabilities";
|
|
110299
110372
|
import {
|
|
110300
|
-
hasPermission as
|
|
110373
|
+
hasPermission as hasPermission29,
|
|
110301
110374
|
requireAccessGrant as requireAccessGrant35,
|
|
110302
110375
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization20
|
|
110303
110376
|
} from "@opengeni/core";
|
|
@@ -110363,7 +110436,7 @@ function registerIntegrationFacetRoutes(app, deps) {
|
|
|
110363
110436
|
facetKey: decoded(c.req.param("facetKey")),
|
|
110364
110437
|
payload: await c.req.json(),
|
|
110365
110438
|
canManageOrganizationDestination: authorization.accountGrant?.permissions.includes("account:admin") === true,
|
|
110366
|
-
canManageWorkspaceDestination:
|
|
110439
|
+
canManageWorkspaceDestination: hasPermission29(
|
|
110367
110440
|
grant.permissions,
|
|
110368
110441
|
"capabilities:manage"
|
|
110369
110442
|
),
|
|
@@ -110634,6 +110707,7 @@ import {
|
|
|
110634
110707
|
getWorkspaceInteractionRevisionState,
|
|
110635
110708
|
listSessionEventPage as listSessionEventPage2,
|
|
110636
110709
|
listWorkspaceControlEvents,
|
|
110710
|
+
getWorkspaceControlEvent,
|
|
110637
110711
|
readSessionEventStorageGapEnd
|
|
110638
110712
|
} from "@opengeni/db";
|
|
110639
110713
|
import {
|
|
@@ -111163,7 +111237,8 @@ async function sseWorkspaceControlStream(db, bus, workspaceId, after, signal, op
|
|
|
111163
111237
|
}
|
|
111164
111238
|
}
|
|
111165
111239
|
}
|
|
111166
|
-
await
|
|
111240
|
+
const visible = await getWorkspaceControlEvent(db, workspaceId, event.id);
|
|
111241
|
+
if (visible) await writeFrame(formatWorkspaceControlEventSse(visible));
|
|
111167
111242
|
lastSent = event.sequence;
|
|
111168
111243
|
};
|
|
111169
111244
|
delivery = createLatestWinsDelivery(send, fail);
|
|
@@ -112384,7 +112459,7 @@ import {
|
|
|
112384
112459
|
} from "@opengeni/contracts";
|
|
112385
112460
|
import {
|
|
112386
112461
|
automationRequestDigest as automationRequestDigest2,
|
|
112387
|
-
hasPermission as
|
|
112462
|
+
hasPermission as hasPermission30,
|
|
112388
112463
|
requireAutomationAdapter as requireAutomationAdapter2,
|
|
112389
112464
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization21,
|
|
112390
112465
|
externalActorContinuationForAuthorization as externalActorContinuationForAuthorization14,
|
|
@@ -113189,7 +113264,7 @@ function registerPrReviewGitHubRoutes(app, deps) {
|
|
|
113189
113264
|
grant.accountId,
|
|
113190
113265
|
workspaceId
|
|
113191
113266
|
);
|
|
113192
|
-
const canManage = !externalActorContinuationForAuthorization14(access) &&
|
|
113267
|
+
const canManage = !externalActorContinuationForAuthorization14(access) && hasPermission30(grant.permissions, "workspace:admin") && hasPermission30(grant.permissions, "secrets:write");
|
|
113193
113268
|
const connectState = configured2 && canManage ? createSignedState14(deps.githubStateSecret, {
|
|
113194
113269
|
accountId: grant.accountId,
|
|
113195
113270
|
workspaceId,
|
|
@@ -113555,7 +113630,7 @@ async function requirePrReviewManageGrant(c, deps, workspaceId, state) {
|
|
|
113555
113630
|
return grant;
|
|
113556
113631
|
}
|
|
113557
113632
|
function prReviewBrowserGrantClaims(deps, grant) {
|
|
113558
|
-
if (deps.settings.productAccessMode !== "configured" || !
|
|
113633
|
+
if (deps.settings.productAccessMode !== "configured" || !hasPermission30(grant.permissions, "workspace:admin") || !hasPermission30(grant.permissions, "secrets:write")) {
|
|
113559
113634
|
return {};
|
|
113560
113635
|
}
|
|
113561
113636
|
return {
|
|
@@ -115196,7 +115271,7 @@ import {
|
|
|
115196
115271
|
SupersedePreferenceRegistryRequest as SupersedePreferenceRegistryRequest2
|
|
115197
115272
|
} from "@opengeni/contracts";
|
|
115198
115273
|
import {
|
|
115199
|
-
hasPermission as
|
|
115274
|
+
hasPermission as hasPermission31,
|
|
115200
115275
|
requireAccessGrant as requireAccessGrant40,
|
|
115201
115276
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization24
|
|
115202
115277
|
} from "@opengeni/core";
|
|
@@ -115276,7 +115351,7 @@ function authorizePreferenceRegistryScopeMutation(access, scope) {
|
|
|
115276
115351
|
}
|
|
115277
115352
|
return;
|
|
115278
115353
|
}
|
|
115279
|
-
if (scope === "workspace" && !
|
|
115354
|
+
if (scope === "workspace" && !hasPermission31(grant.permissions, "workspace:admin")) {
|
|
115280
115355
|
throw new HTTPException98(403, { message: "missing permission: workspace:admin" });
|
|
115281
115356
|
}
|
|
115282
115357
|
}
|
|
@@ -116543,7 +116618,7 @@ function registerScheduledTaskRoutes(app, deps) {
|
|
|
116543
116618
|
settings: catalogSettings,
|
|
116544
116619
|
authorization,
|
|
116545
116620
|
tasks,
|
|
116546
|
-
permissionsRequiredByTools:
|
|
116621
|
+
permissionsRequiredByTools: permissionsRequiredByFirstPartyTools2,
|
|
116547
116622
|
onError: (error) => {
|
|
116548
116623
|
deps.observability?.warn("Scheduled task access drift could not be computed", {
|
|
116549
116624
|
errorClass: error instanceof Error ? error.name : "ScheduledTaskPolicyDriftError",
|
|
@@ -116729,7 +116804,7 @@ function registerScheduledTaskRoutes(app, deps) {
|
|
|
116729
116804
|
authorization,
|
|
116730
116805
|
taskId: c.req.param("taskId"),
|
|
116731
116806
|
request: parsed.data,
|
|
116732
|
-
permissionsRequiredByTools:
|
|
116807
|
+
permissionsRequiredByTools: permissionsRequiredByFirstPartyTools2,
|
|
116733
116808
|
sessionAuthorization: deps.sessionAuthorization,
|
|
116734
116809
|
authorizationSurface: "http"
|
|
116735
116810
|
});
|
|
@@ -117496,7 +117571,12 @@ import {
|
|
|
117496
117571
|
SITE_FRAME_SESSION_CREATE_FIELDS,
|
|
117497
117572
|
siteFrameBodyRefusal as siteFrameBodyRefusal2
|
|
117498
117573
|
} from "@opengeni/contracts/site-session-http";
|
|
117499
|
-
import {
|
|
117574
|
+
import {
|
|
117575
|
+
requireWorkspace as requireWorkspace5,
|
|
117576
|
+
scheduledSessionIds,
|
|
117577
|
+
currentSiteViewerRlsContext,
|
|
117578
|
+
nestedPostgresSqlState as nestedPostgresSqlState12
|
|
117579
|
+
} from "@opengeni/db";
|
|
117500
117580
|
import {
|
|
117501
117581
|
currentSiteSessionOrigin as currentSiteSessionOrigin4,
|
|
117502
117582
|
isVerifiedDelegatedHumanAuthorization as isVerifiedDelegatedHumanAuthorization4,
|
|
@@ -117988,7 +118068,7 @@ import {
|
|
|
117988
118068
|
import { HTTPException as HTTPException105 } from "hono/http-exception";
|
|
117989
118069
|
import {
|
|
117990
118070
|
getManagedAuthRequestActorEpoch as getManagedAuthRequestActorEpoch2,
|
|
117991
|
-
hasPermission as
|
|
118071
|
+
hasPermission as hasPermission32,
|
|
117992
118072
|
requireAccessGrant as requireAccessGrant46,
|
|
117993
118073
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization29,
|
|
117994
118074
|
requireFreshAccessGrant as requireFreshAccessGrant3,
|
|
@@ -118330,7 +118410,7 @@ function childRequiresActionRespondedByKindForGrant(grant) {
|
|
|
118330
118410
|
return "human";
|
|
118331
118411
|
}
|
|
118332
118412
|
function requireViewerLifecyclePermission(grant) {
|
|
118333
|
-
if (VIEWER_LIFECYCLE_PERMISSIONS.some((permission) =>
|
|
118413
|
+
if (VIEWER_LIFECYCLE_PERMISSIONS.some((permission) => hasPermission32(grant.permissions, permission))) {
|
|
118334
118414
|
return;
|
|
118335
118415
|
}
|
|
118336
118416
|
throw new HTTPException105(403, {
|
|
@@ -118596,7 +118676,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
118596
118676
|
)
|
|
118597
118677
|
);
|
|
118598
118678
|
const siteOrigin = origin ?? currentSiteSessionOrigin4();
|
|
118599
|
-
if (siteOrigin &&
|
|
118679
|
+
if (siteOrigin && currentSiteViewerRlsContext()?.siteId !== siteOrigin.siteId) {
|
|
118600
118680
|
const refused4 = siteFrameBodyRefusal2("sessions.create", "/sessions", payload);
|
|
118601
118681
|
if (refused4)
|
|
118602
118682
|
return c.json(
|
|
@@ -118612,6 +118692,8 @@ function registerSessionRoutes(app, deps) {
|
|
|
118612
118692
|
siteId: siteOrigin.siteId,
|
|
118613
118693
|
versionId: siteOrigin.versionId ?? null
|
|
118614
118694
|
});
|
|
118695
|
+
if (grant.principalKind !== "agent_attempt")
|
|
118696
|
+
payload.visibility = "private";
|
|
118615
118697
|
}
|
|
118616
118698
|
const create = () => createSessionForRequest(deps, grant, workspaceId, payload, authorization);
|
|
118617
118699
|
session = await measureSessionCreatePhase(
|
|
@@ -118849,7 +118931,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
118849
118931
|
workspaceId,
|
|
118850
118932
|
sessionIds: [...page2.pinned, ...page2.sessions].map((session) => session.id)
|
|
118851
118933
|
});
|
|
118852
|
-
const scheduleTargets =
|
|
118934
|
+
const scheduleTargets = hasPermission32(grant.permissions, "scheduled_tasks:run") && hasPermission32(grant.permissions, "sessions:control") ? await scheduledSessionIds(
|
|
118853
118935
|
db,
|
|
118854
118936
|
workspaceId,
|
|
118855
118937
|
[...page2.pinned, ...page2.sessions].map((session) => session.id)
|
|
@@ -119085,7 +119167,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
119085
119167
|
workspaceId,
|
|
119086
119168
|
sessionIds: [sessionId]
|
|
119087
119169
|
}),
|
|
119088
|
-
|
|
119170
|
+
hasPermission32(grant.permissions, "scheduled_tasks:run") && hasPermission32(grant.permissions, "sessions:control") ? scheduledSessionIds(db, workspaceId, [sessionId]) : Promise.resolve(/* @__PURE__ */ new Set()),
|
|
119089
119171
|
loadEffectivePolicyContext(deps, workspaceId, grant.subjectId, [session])
|
|
119090
119172
|
]);
|
|
119091
119173
|
const usageLimit = await sessionUsageLimitForRead(db, session, {
|
|
@@ -120156,7 +120238,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
120156
120238
|
}
|
|
120157
120239
|
};
|
|
120158
120240
|
collect(lineage.children);
|
|
120159
|
-
const targets =
|
|
120241
|
+
const targets = hasPermission32(grant.permissions, "scheduled_tasks:run") && hasPermission32(grant.permissions, "sessions:control") ? await scheduledSessionIds(db, workspaceId, sessionIds) : /* @__PURE__ */ new Set();
|
|
120160
120242
|
const decorateNodes = (nodes) => nodes.map((node) => ({
|
|
120161
120243
|
...node,
|
|
120162
120244
|
session: { ...node.session, hasSchedules: targets.has(node.session.id) },
|
|
@@ -121159,6 +121241,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
121159
121241
|
actorEpoch: getManagedAuthRequestActorEpoch2(c.req.raw) ?? void 0,
|
|
121160
121242
|
reauthorizeAfterMs: authorization?.reauthorizeAfterMs ?? SESSION_AUTHORIZATION_DEFAULT_REAUTHORIZE_MS,
|
|
121161
121243
|
reauthorize: async () => {
|
|
121244
|
+
await reauthorizeSiteSessionRequest(c.req.raw);
|
|
121162
121245
|
const freshGrant = await requireFreshAccessGrant3(c, deps, workspaceId, "sessions:read");
|
|
121163
121246
|
await requireSessionAuthorization16(deps, freshGrant, {
|
|
121164
121247
|
sessionId,
|
|
@@ -122879,7 +122962,7 @@ function sessionTenancyHttpError(error) {
|
|
|
122879
122962
|
retryable: false
|
|
122880
122963
|
});
|
|
122881
122964
|
}
|
|
122882
|
-
if (error instanceof SessionTenancyNotActivatedError2) {
|
|
122965
|
+
if (error instanceof SessionTenancyNotActivatedError2 || nestedPostgresSqlState12(error) === "P0793") {
|
|
122883
122966
|
return new ApiHttpError(409, {
|
|
122884
122967
|
code: "conflict",
|
|
122885
122968
|
message: "Only-me chats are not enabled for this organization.",
|
|
@@ -123505,7 +123588,7 @@ function sessionCreateErrorResponse(c, error) {
|
|
|
123505
123588
|
403
|
|
123506
123589
|
);
|
|
123507
123590
|
}
|
|
123508
|
-
if (error instanceof SessionTenancyNotActivatedError2) {
|
|
123591
|
+
if (error instanceof SessionTenancyNotActivatedError2 || nestedPostgresSqlState12(error) === "P0793") {
|
|
123509
123592
|
return c.json(
|
|
123510
123593
|
{
|
|
123511
123594
|
code: "SESSION_TENANCY_NOT_ACTIVATED",
|
|
@@ -123622,7 +123705,7 @@ var ARCHIVE_LIVE_WORK_STATUSES = /* @__PURE__ */ new Set([
|
|
|
123622
123705
|
async function pauseOwnArchivedWork(deps, grant, workspaceId, session) {
|
|
123623
123706
|
if (session.createdBy.kind !== "subject" || session.createdBy.subjectId !== grant.subjectId)
|
|
123624
123707
|
return session;
|
|
123625
|
-
if (!
|
|
123708
|
+
if (!hasPermission32(grant.permissions, "sessions:control")) return session;
|
|
123626
123709
|
if (session.effectiveControl.directState === "paused") return session;
|
|
123627
123710
|
const liveWork = ARCHIVE_LIVE_WORK_STATUSES.has(session.status) || session.activeTurnId !== null || Boolean(session.inputWait) || (await getSessionGoal2(deps.db, workspaceId, session.id))?.status === "active";
|
|
123628
123711
|
if (!liveWork) return session;
|
|
@@ -123982,7 +124065,7 @@ import {
|
|
|
123982
124065
|
replayWorkspaceGatewayCustomModelCreate,
|
|
123983
124066
|
replayWorkspaceOpenRouterCustomModelCreate,
|
|
123984
124067
|
listWorkspacesForSubject as listWorkspacesForSubject3,
|
|
123985
|
-
nestedPostgresSqlState as
|
|
124068
|
+
nestedPostgresSqlState as nestedPostgresSqlState14,
|
|
123986
124069
|
removeWorkspaceMember,
|
|
123987
124070
|
requireWorkspace as requireWorkspace6,
|
|
123988
124071
|
updateWorkspaceSettings,
|
|
@@ -124014,7 +124097,7 @@ import {
|
|
|
124014
124097
|
getManagedAuthRequestActorEpoch as getManagedAuthRequestActorEpoch3,
|
|
124015
124098
|
accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority5,
|
|
124016
124099
|
organizationWorkspaceInScope as organizationWorkspaceInScope2,
|
|
124017
|
-
hasPermission as
|
|
124100
|
+
hasPermission as hasPermission33,
|
|
124018
124101
|
requireAccessContext as requireAccessContext12,
|
|
124019
124102
|
requireApiKeyDelegationContext,
|
|
124020
124103
|
requireExplicitPermissionDelegation as requireExplicitPermissionDelegation2,
|
|
@@ -124045,7 +124128,7 @@ import {
|
|
|
124045
124128
|
// src/workspace-deletion.ts
|
|
124046
124129
|
import {
|
|
124047
124130
|
deleteWorkspaceIfQuiescent,
|
|
124048
|
-
nestedPostgresSqlState as
|
|
124131
|
+
nestedPostgresSqlState as nestedPostgresSqlState13,
|
|
124049
124132
|
safeDatabaseErrorFacts
|
|
124050
124133
|
} from "@opengeni/db";
|
|
124051
124134
|
import { HTTPException as HTTPException107 } from "hono/http-exception";
|
|
@@ -124138,7 +124221,7 @@ async function deleteWorkspaceForRequest(deps, input) {
|
|
|
124138
124221
|
...observer ? { observer } : {}
|
|
124139
124222
|
});
|
|
124140
124223
|
} catch (error) {
|
|
124141
|
-
const state =
|
|
124224
|
+
const state = nestedPostgresSqlState13(error);
|
|
124142
124225
|
if (state === "42501") {
|
|
124143
124226
|
throw new HTTPException107(403, { message: "organization administration is not authorized" });
|
|
124144
124227
|
}
|
|
@@ -124295,7 +124378,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
124295
124378
|
return c.json(externalWorkspaces.map((workspace) => Workspace.parse(workspace)));
|
|
124296
124379
|
const accountScopedAuthority = accountScopedApiKeyWorkspaceAuthority5(context);
|
|
124297
124380
|
if (accountScopedAuthority) {
|
|
124298
|
-
if (!
|
|
124381
|
+
if (!hasPermission33(accountScopedAuthority.permissions, "workspace:read")) return c.json([]);
|
|
124299
124382
|
return c.json(
|
|
124300
124383
|
(await listSharedWorkspacesForAccount2(deps.db, accountScopedAuthority.accountId)).filter(
|
|
124301
124384
|
(workspace) => organizationWorkspaceInScope2(accountScopedAuthority.workspaceScope, workspace.id)
|
|
@@ -124304,7 +124387,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
124304
124387
|
}
|
|
124305
124388
|
const readableWorkspaceIds = [
|
|
124306
124389
|
...new Set(
|
|
124307
|
-
context.workspaceGrants.filter((grant) =>
|
|
124390
|
+
context.workspaceGrants.filter((grant) => hasPermission33(grant.permissions, "workspace:read")).map((grant) => grant.workspaceId)
|
|
124308
124391
|
)
|
|
124309
124392
|
];
|
|
124310
124393
|
if (readableWorkspaceIds.length > 0) {
|
|
@@ -124495,7 +124578,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
124495
124578
|
);
|
|
124496
124579
|
return c.json(Workspace.parse(workspace));
|
|
124497
124580
|
} catch (error) {
|
|
124498
|
-
if (
|
|
124581
|
+
if (nestedPostgresSqlState14(error) === "0A000") {
|
|
124499
124582
|
throw new HTTPException108(409, {
|
|
124500
124583
|
message: "Memory settings moved to Settings > Agent learning. Refresh the app to change them."
|
|
124501
124584
|
});
|
|
@@ -124745,7 +124828,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
124745
124828
|
if (error instanceof WorkspaceGatewayCustomModelLimitError || error instanceof WorkspaceGatewayCustomModelHistoryLimitError) {
|
|
124746
124829
|
throw new HTTPException108(422, { message: error.message });
|
|
124747
124830
|
}
|
|
124748
|
-
if (
|
|
124831
|
+
if (nestedPostgresSqlState14(error) === "23505") {
|
|
124749
124832
|
throw new HTTPException108(422, {
|
|
124750
124833
|
message: "Gateway custom model already exists"
|
|
124751
124834
|
});
|
|
@@ -124874,7 +124957,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
124874
124957
|
if (error instanceof WorkspaceOpenRouterCustomModelLimitError || error instanceof WorkspaceOpenRouterCustomModelHistoryLimitError) {
|
|
124875
124958
|
throw new HTTPException108(422, { message: error.message });
|
|
124876
124959
|
}
|
|
124877
|
-
if (
|
|
124960
|
+
if (nestedPostgresSqlState14(error) === "23505") {
|
|
124878
124961
|
throw new HTTPException108(422, {
|
|
124879
124962
|
message: "OpenRouter custom model already exists"
|
|
124880
124963
|
});
|
|
@@ -125006,7 +125089,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
125006
125089
|
if (error instanceof WorkspaceOpperCustomModelLimitError || error instanceof WorkspaceOpperCustomModelHistoryLimitError) {
|
|
125007
125090
|
throw new HTTPException108(422, { message: error.message });
|
|
125008
125091
|
}
|
|
125009
|
-
if (
|
|
125092
|
+
if (nestedPostgresSqlState14(error) === "23505") {
|
|
125010
125093
|
throw new HTTPException108(422, {
|
|
125011
125094
|
message: "Opper custom model already exists"
|
|
125012
125095
|
});
|
|
@@ -125494,7 +125577,7 @@ function rethrowWorkspaceMemberCandidateError(error) {
|
|
|
125494
125577
|
message: "the workspace must keep at least one administrator"
|
|
125495
125578
|
});
|
|
125496
125579
|
}
|
|
125497
|
-
const sqlState =
|
|
125580
|
+
const sqlState = nestedPostgresSqlState14(error);
|
|
125498
125581
|
if (sqlState === "P0002") {
|
|
125499
125582
|
throw new HTTPException108(404, { message: "workspace not found" });
|
|
125500
125583
|
}
|
|
@@ -125559,7 +125642,7 @@ import {
|
|
|
125559
125642
|
getWorkspace as getWorkspace7,
|
|
125560
125643
|
getWorkspaceUsage,
|
|
125561
125644
|
grantWorkspaceCredits,
|
|
125562
|
-
nestedPostgresSqlState as
|
|
125645
|
+
nestedPostgresSqlState as nestedPostgresSqlState15,
|
|
125563
125646
|
setMemberAllowance,
|
|
125564
125647
|
setWorkspaceAllowance,
|
|
125565
125648
|
withAccountRls as withAccountRls4,
|
|
@@ -125694,7 +125777,7 @@ async function lifecycle2(operation) {
|
|
|
125694
125777
|
} catch (error) {
|
|
125695
125778
|
if (error instanceof UsageAllowanceVersionConflictError)
|
|
125696
125779
|
throw new HTTPException109(409, { message: error.message });
|
|
125697
|
-
const state =
|
|
125780
|
+
const state = nestedPostgresSqlState15(error);
|
|
125698
125781
|
if (state === "40001" || state === "23505")
|
|
125699
125782
|
throw new HTTPException109(409, { message: "Allowance version or operation conflicts" });
|
|
125700
125783
|
if (state === "42501")
|
|
@@ -126617,7 +126700,7 @@ import {
|
|
|
126617
126700
|
WORKSPACE_STATE_KNOWLEDGE_SAMPLE_LIMIT as WORKSPACE_STATE_KNOWLEDGE_SAMPLE_LIMIT2
|
|
126618
126701
|
} from "@opengeni/contracts";
|
|
126619
126702
|
import {
|
|
126620
|
-
hasPermission as
|
|
126703
|
+
hasPermission as hasPermission34,
|
|
126621
126704
|
requireAccessGrant as requireAccessGrant52,
|
|
126622
126705
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization33,
|
|
126623
126706
|
knowledgeContextForAccess as knowledgeContextForAccess3
|
|
@@ -127234,7 +127317,7 @@ function registerCompanyBrainRoutes(app, deps) {
|
|
|
127234
127317
|
workspaceId,
|
|
127235
127318
|
accountId: grant.accountId,
|
|
127236
127319
|
subjectId: grant.subjectId,
|
|
127237
|
-
canInspectKnowledge:
|
|
127320
|
+
canInspectKnowledge: hasPermission34(grant.permissions, "documents:search"),
|
|
127238
127321
|
access
|
|
127239
127322
|
});
|
|
127240
127323
|
context.header("cache-control", "private, no-store");
|
|
@@ -127253,7 +127336,7 @@ function registerCompanyBrainRoutes(app, deps) {
|
|
|
127253
127336
|
workspaceId,
|
|
127254
127337
|
accountId: grant.accountId,
|
|
127255
127338
|
subjectId: grant.subjectId,
|
|
127256
|
-
canInspectKnowledge:
|
|
127339
|
+
canInspectKnowledge: hasPermission34(grant.permissions, "documents:search"),
|
|
127257
127340
|
access
|
|
127258
127341
|
});
|
|
127259
127342
|
context.header("cache-control", "private, no-store");
|
|
@@ -127446,7 +127529,7 @@ import {
|
|
|
127446
127529
|
} from "@opengeni/core";
|
|
127447
127530
|
import {
|
|
127448
127531
|
availableSlackBotConnectionMetadata as availableSlackBotConnectionMetadata2,
|
|
127449
|
-
nestedPostgresSqlState as
|
|
127532
|
+
nestedPostgresSqlState as nestedPostgresSqlState16,
|
|
127450
127533
|
readOrganizationSlackBotAccess,
|
|
127451
127534
|
setOrganizationSlackBotAccess,
|
|
127452
127535
|
sharedOrganizationSlackBots as sharedOrganizationSlackBots2
|
|
@@ -127476,7 +127559,7 @@ function registerSlackBotAccessRoutes(app, deps) {
|
|
|
127476
127559
|
)
|
|
127477
127560
|
);
|
|
127478
127561
|
} catch (error) {
|
|
127479
|
-
if (
|
|
127562
|
+
if (nestedPostgresSqlState16(error) === "42501")
|
|
127480
127563
|
throw new HTTPException115(404, { message: "Local bot installation unavailable" });
|
|
127481
127564
|
throw error;
|
|
127482
127565
|
}
|
|
@@ -127530,7 +127613,7 @@ function registerSlackBotAccessRoutes(app, deps) {
|
|
|
127530
127613
|
return context.json(OpenGeniSlackBotOrganizationAccess.parse(result2));
|
|
127531
127614
|
} catch (error) {
|
|
127532
127615
|
if (error instanceof HTTPException115) throw error;
|
|
127533
|
-
if (
|
|
127616
|
+
if (nestedPostgresSqlState16(error) === "42501")
|
|
127534
127617
|
throw new HTTPException115(403, {
|
|
127535
127618
|
message: "Organization administrator and a verified local bot installation required"
|
|
127536
127619
|
});
|
|
@@ -127546,7 +127629,7 @@ import {
|
|
|
127546
127629
|
WorkspaceStateResponse as WorkspaceStateResponse2
|
|
127547
127630
|
} from "@opengeni/contracts";
|
|
127548
127631
|
import {
|
|
127549
|
-
hasPermission as
|
|
127632
|
+
hasPermission as hasPermission35,
|
|
127550
127633
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization35,
|
|
127551
127634
|
knowledgeContextForAccess as knowledgeContextForAccess4
|
|
127552
127635
|
} from "@opengeni/core";
|
|
@@ -127605,7 +127688,7 @@ async function readWorkspaceState(deps, input) {
|
|
|
127605
127688
|
const { workspaceId, query, access } = input;
|
|
127606
127689
|
const { grant } = access;
|
|
127607
127690
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
127608
|
-
const canInspectKnowledge =
|
|
127691
|
+
const canInspectKnowledge = hasPermission35(grant.permissions, "documents:search");
|
|
127609
127692
|
const [workspace, policies, knowledge, currentPreferences, acceptedAttempt] = await Promise.all([
|
|
127610
127693
|
getWorkspace9(deps.db, workspaceId),
|
|
127611
127694
|
listWorkspaceInstructionPolicyRevisions3(deps.db, workspaceId, { limit: 1 }),
|
|
@@ -127732,7 +127815,7 @@ import {
|
|
|
127732
127815
|
getWorkspaceArtifact as getWorkspaceArtifact3,
|
|
127733
127816
|
getWorkspaceArtifactContentRef as getWorkspaceArtifactContentRef4,
|
|
127734
127817
|
listWorkspaceArtifacts as listWorkspaceArtifacts2,
|
|
127735
|
-
nestedPostgresSqlState as
|
|
127818
|
+
nestedPostgresSqlState as nestedPostgresSqlState17,
|
|
127736
127819
|
publishWorkspaceArtifactVersion as publishWorkspaceArtifactVersion2,
|
|
127737
127820
|
rollbackWorkspaceArtifact as rollbackWorkspaceArtifact2,
|
|
127738
127821
|
setWorkspaceArtifactStatus as setWorkspaceArtifactStatus2,
|
|
@@ -127784,7 +127867,7 @@ function workspaceArtifactErrorResponse(context, error) {
|
|
|
127784
127867
|
422
|
|
127785
127868
|
);
|
|
127786
127869
|
}
|
|
127787
|
-
if (
|
|
127870
|
+
if (nestedPostgresSqlState17(error) === "23505") {
|
|
127788
127871
|
return context.json(
|
|
127789
127872
|
{
|
|
127790
127873
|
code: "WORKSPACE_ARTIFACT_CONFLICT",
|
|
@@ -128685,6 +128768,9 @@ function registerSitePublishingRoutes(app, deps) {
|
|
|
128685
128768
|
// src/routes/site-runtime.ts
|
|
128686
128769
|
import { createHash as createHash37, randomBytes as randomBytes15, randomUUID as randomUUID16, timingSafeEqual as timingSafeEqual5 } from "crypto";
|
|
128687
128770
|
import {
|
|
128771
|
+
ReasoningEffort,
|
|
128772
|
+
LatencyMode,
|
|
128773
|
+
permissionsRequiredByFirstPartyTools as permissionsRequiredByFirstPartyTools4,
|
|
128688
128774
|
DeleteSessionQueueItemRequest as DeleteSessionQueueItemRequest3,
|
|
128689
128775
|
EditSessionQueueItemRequest as EditSessionQueueItemRequest3,
|
|
128690
128776
|
matchSiteOperation,
|
|
@@ -128709,17 +128795,19 @@ import {
|
|
|
128709
128795
|
ToolGatewayInvokeRequest
|
|
128710
128796
|
} from "@opengeni/contracts";
|
|
128711
128797
|
import {
|
|
128798
|
+
cancelPublishedSiteSession,
|
|
128712
128799
|
withHostSessionUsageLimit,
|
|
128713
128800
|
withSiteSessionOrigin as withSiteSessionOrigin6,
|
|
128714
128801
|
admissibleWorkspaceModel as admissibleWorkspaceModel2,
|
|
128715
128802
|
loadWorkspaceModelSelectionInput as loadWorkspaceModelSelectionInput2,
|
|
128716
128803
|
resolveWorkspaceModelSelection as resolveWorkspaceModelSelection4,
|
|
128717
|
-
hasPermission as
|
|
128804
|
+
hasPermission as hasPermission36
|
|
128718
128805
|
} from "@opengeni/core";
|
|
128719
128806
|
import {
|
|
128720
128807
|
consumeSiteAuthCode,
|
|
128721
128808
|
finishSiteRuntimeAdmission,
|
|
128722
128809
|
withSiteRuntimeAdmission,
|
|
128810
|
+
withSiteViewerRlsContext,
|
|
128723
128811
|
createSiteAbuseReport,
|
|
128724
128812
|
getSiteWorkspaceMemberPermissions,
|
|
128725
128813
|
readSitePlatformUsage as readSitePlatformUsage2,
|
|
@@ -128742,13 +128830,16 @@ import {
|
|
|
128742
128830
|
} from "@opengeni/db";
|
|
128743
128831
|
|
|
128744
128832
|
// src/site-publishing/agent-session.ts
|
|
128745
|
-
import {
|
|
128833
|
+
import {
|
|
128834
|
+
permissionsRequiredByFirstPartyTools as permissionsRequiredByFirstPartyTools3,
|
|
128835
|
+
resolveAgentConfig
|
|
128836
|
+
} from "@opengeni/contracts";
|
|
128746
128837
|
import { agentConfigDeploymentPolicy as agentConfigDeploymentPolicy2, resolveFirstPartyMcpToolPolicy as resolveFirstPartyMcpToolPolicy3 } from "@opengeni/config";
|
|
128747
128838
|
import { siteSessionOriginFromMetadata as siteSessionOriginFromMetadata2 } from "@opengeni/core";
|
|
128748
128839
|
import { appendSessionEventsWithLockedSessionUpdate, getSiteSqlDatabase as getSiteSqlDatabase3 } from "@opengeni/db";
|
|
128749
128840
|
import { publishDurableSessionEvents as publishDurableSessionEvents5 } from "@opengeni/events";
|
|
128750
|
-
var SITE_AGENT_DEFAULTS_VERSION =
|
|
128751
|
-
async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retainedToolIds) {
|
|
128841
|
+
var SITE_AGENT_DEFAULTS_VERSION = 2;
|
|
128842
|
+
async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retainedToolIds, memberPermissions) {
|
|
128752
128843
|
const data = await resolveSiteAgentDataContext(deps, host.scope, sessionId);
|
|
128753
128844
|
if (data.kind !== "site" || data.siteId !== host.site.id || data.viewer.principal !== viewer.principal)
|
|
128754
128845
|
throw sitePublishingError(
|
|
@@ -128761,8 +128852,10 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
|
|
|
128761
128852
|
const dataTools = siteAgentDataToolNames({
|
|
128762
128853
|
viewerKind: viewer.kind,
|
|
128763
128854
|
siteSql: sqlEnabled,
|
|
128764
|
-
allowed: resolveFirstPartyMcpToolPolicy3(deps.settings).allowed
|
|
128855
|
+
allowed: resolveFirstPartyMcpToolPolicy3(deps.settings).allowed,
|
|
128856
|
+
...memberPermissions === void 0 ? {} : { memberPermissions }
|
|
128765
128857
|
});
|
|
128858
|
+
const dataToolPermissions = permissionsRequiredByFirstPartyTools3(dataTools);
|
|
128766
128859
|
const config = resolveAgentConfig({
|
|
128767
128860
|
creator: "api",
|
|
128768
128861
|
request: {
|
|
@@ -128788,7 +128881,7 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
|
|
|
128788
128881
|
host.scope.workspaceId,
|
|
128789
128882
|
sessionId,
|
|
128790
128883
|
(session) => {
|
|
128791
|
-
if (session.parentSessionId || session.createdBy.subjectId !== `site:${host.site.id}` || siteSessionOriginFromMetadata2(session.metadata)?.siteId !== host.site.id)
|
|
128884
|
+
if (session.parentSessionId || session.createdBy.subjectId !== `site:${host.site.id}` && !(viewer.kind === "member" && session.createdBy.kind === "subject" && session.createdBy.subjectId === viewer.subjectId) || siteSessionOriginFromMetadata2(session.metadata)?.siteId !== host.site.id)
|
|
128792
128885
|
throw sitePublishingError(
|
|
128793
128886
|
403,
|
|
128794
128887
|
"forbidden",
|
|
@@ -128797,7 +128890,8 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
|
|
|
128797
128890
|
);
|
|
128798
128891
|
const raw = session.metadata.opengeniPublishedSite;
|
|
128799
128892
|
const stamp = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
128800
|
-
if (stamp.agentDefaultsVersion === SITE_AGENT_DEFAULTS_VERSION)
|
|
128893
|
+
if (stamp.agentDefaultsVersion === SITE_AGENT_DEFAULTS_VERSION && session.firstPartyMcpTools.join(",") === dataTools.join(",") && session.firstPartyMcpPermissions?.join(",") === dataToolPermissions.join(","))
|
|
128894
|
+
return { events: [] };
|
|
128801
128895
|
const allowed2 = /* @__PURE__ */ new Set(["opengeni", ...retainedToolIds]);
|
|
128802
128896
|
const tools = session.tools.filter((tool) => allowed2.has(tool.id));
|
|
128803
128897
|
const toolPolicy = {
|
|
@@ -128824,7 +128918,7 @@ async function normalizeSiteAgentSession(deps, host, viewer, sessionId, retained
|
|
|
128824
128918
|
],
|
|
128825
128919
|
update: {
|
|
128826
128920
|
firstPartyMcpTools: dataTools,
|
|
128827
|
-
firstPartyMcpPermissions:
|
|
128921
|
+
firstPartyMcpPermissions: dataToolPermissions,
|
|
128828
128922
|
agentConfig: config,
|
|
128829
128923
|
instructions,
|
|
128830
128924
|
tools,
|
|
@@ -129342,7 +129436,10 @@ var VersionId = z66.string().uuid();
|
|
|
129342
129436
|
var ClientEventId = z66.string().min(1).max(200).optional();
|
|
129343
129437
|
var CreateConversationRequest = z66.object({
|
|
129344
129438
|
initialMessage: z66.string().trim().min(1).max(MESSAGE_MAX_CHARS),
|
|
129345
|
-
idempotencyKey: z66.string().min(1).max(200).optional()
|
|
129439
|
+
idempotencyKey: z66.string().min(1).max(200).optional(),
|
|
129440
|
+
model: z66.string().min(1).optional(),
|
|
129441
|
+
reasoningEffort: ReasoningEffort.optional(),
|
|
129442
|
+
latencyMode: LatencyMode.optional()
|
|
129346
129443
|
}).passthrough();
|
|
129347
129444
|
var SendMessageRequest = z66.object({
|
|
129348
129445
|
type: z66.literal("user.message"),
|
|
@@ -129531,7 +129628,7 @@ function idempotentSessionId(seed) {
|
|
|
129531
129628
|
}
|
|
129532
129629
|
function registerSiteRuntimeRoutes(app, deps) {
|
|
129533
129630
|
const dispatch = async (request) => await app.fetch(markLocalInternalDispatch(request));
|
|
129534
|
-
|
|
129631
|
+
setSitePublishingCancellation(deps.settings, (input) => cancelPublishedSiteSession(deps, input));
|
|
129535
129632
|
const handler = async (context) => {
|
|
129536
129633
|
const domain = configuredSitesDomain(deps.settings);
|
|
129537
129634
|
if (!domain || !deps.settings.sitesGatewaySecret)
|
|
@@ -129919,7 +130016,7 @@ function registerSiteRuntimeRoutes(app, deps) {
|
|
|
129919
130016
|
agent = choice !== null && choice.kind !== "unavailable";
|
|
129920
130017
|
}
|
|
129921
130018
|
const version2 = host.site.currentVersionId ? await getPublishedSiteVersion6(deps.db, host.scope, host.site.id, host.site.currentVersionId) : null;
|
|
129922
|
-
const workspaceTools = base.workspaceTools && (version2?.requestedTools.length ?? 0) > 0 && viewer.subjectId !== null && viewer.subjectId !== void 0 &&
|
|
130019
|
+
const workspaceTools = base.workspaceTools && (version2?.requestedTools.length ?? 0) > 0 && viewer.subjectId !== null && viewer.subjectId !== void 0 && hasPermission36(
|
|
129923
130020
|
await getSiteWorkspaceMemberPermissions(deps.db, host.scope, viewer.subjectId) ?? [],
|
|
129924
130021
|
"workspace:read"
|
|
129925
130022
|
);
|
|
@@ -130125,18 +130222,32 @@ function registerSiteRuntimeRoutes(app, deps) {
|
|
|
130125
130222
|
const { context, url } = request;
|
|
130126
130223
|
const base = `/v1/workspaces/${host.scope.workspaceId}/sessions`;
|
|
130127
130224
|
const siteOrigin = { siteId: host.site.id, title: host.site.title, versionId: host.versionId };
|
|
130225
|
+
const reauthorizeViewer = async () => {
|
|
130226
|
+
const liveHost = await requireServedSiteRuntimeHost(deps, host.domain, request.fields.host);
|
|
130227
|
+
const liveViewer = await resolveSiteRuntimeViewer(deps, liveHost, request.fields);
|
|
130228
|
+
if (liveHost.site.id !== host.site.id || liveViewer.principal !== viewer.principal || liveViewer.kind !== viewer.kind || liveViewer.sessionId !== viewer.sessionId)
|
|
130229
|
+
throw siteNotAvailableForViewer(
|
|
130230
|
+
"agent",
|
|
130231
|
+
"This conversation is no longer available to this viewer"
|
|
130232
|
+
);
|
|
130233
|
+
};
|
|
130128
130234
|
let pendingAdmission;
|
|
130129
130235
|
const send = async (method, path, body5, extraPermissions) => {
|
|
130130
|
-
|
|
130131
|
-
|
|
130132
|
-
|
|
130133
|
-
|
|
130134
|
-
|
|
130135
|
-
|
|
130136
|
-
|
|
130137
|
-
|
|
130138
|
-
|
|
130139
|
-
|
|
130236
|
+
await reauthorizeViewer();
|
|
130237
|
+
const execute = () => withSiteViewerRlsContext(
|
|
130238
|
+
{ siteId: host.site.id, principal: viewer.principal },
|
|
130239
|
+
() => withSiteSessionOrigin6(
|
|
130240
|
+
siteOrigin,
|
|
130241
|
+
async () => dispatch(
|
|
130242
|
+
await siteRuntimeSessionRequest(deps, host, viewer, {
|
|
130243
|
+
origin: url.origin,
|
|
130244
|
+
method,
|
|
130245
|
+
path,
|
|
130246
|
+
reauthorize: reauthorizeViewer,
|
|
130247
|
+
...body5 === void 0 ? {} : { body: body5 },
|
|
130248
|
+
...extraPermissions ? { extraPermissions } : {}
|
|
130249
|
+
})
|
|
130250
|
+
)
|
|
130140
130251
|
)
|
|
130141
130252
|
);
|
|
130142
130253
|
const pending2 = pendingAdmission;
|
|
@@ -130200,6 +130311,11 @@ function registerSiteRuntimeRoutes(app, deps) {
|
|
|
130200
130311
|
if (viewer.kind === "guest" || viewer.kind === "user")
|
|
130201
130312
|
await requireSitePlatformOpen(deps, "guest_agent");
|
|
130202
130313
|
const models = await siteViewerModels(host, viewer, limits);
|
|
130314
|
+
if (input.model && !models.allowed.includes(input.model))
|
|
130315
|
+
throw siteNotAvailableForViewer(
|
|
130316
|
+
"agent_model",
|
|
130317
|
+
"This model is not available to you on this Site"
|
|
130318
|
+
);
|
|
130203
130319
|
if (models.unavailable)
|
|
130204
130320
|
throw siteNotAvailableForViewer(
|
|
130205
130321
|
"agent_model",
|
|
@@ -130248,6 +130364,11 @@ ${input.idempotencyKey}`) : randomUUID16();
|
|
|
130248
130364
|
}
|
|
130249
130365
|
}
|
|
130250
130366
|
}
|
|
130367
|
+
if (!repair && viewer.kind !== "member" && deps.settings.privacyOnlyMeAllowed === false)
|
|
130368
|
+
throw siteNotAvailableForViewer(
|
|
130369
|
+
"private_conversations",
|
|
130370
|
+
"Private Site conversations are disabled by this deployment"
|
|
130371
|
+
);
|
|
130251
130372
|
for (const conversation2 of await listOwnedSiteRuntimeConversations(deps.db, host.scope, {
|
|
130252
130373
|
siteId: host.site.id,
|
|
130253
130374
|
viewerPrincipal: viewer.principal,
|
|
@@ -130286,8 +130407,10 @@ ${input.idempotencyKey}`) : randomUUID16();
|
|
|
130286
130407
|
deps,
|
|
130287
130408
|
host.scope,
|
|
130288
130409
|
host.site.id,
|
|
130289
|
-
viewer.kind
|
|
130410
|
+
viewer.kind,
|
|
130411
|
+
viewer.kind === "member" ? memberPermissions ?? [] : void 0
|
|
130290
130412
|
);
|
|
130413
|
+
const dataToolPermissions = permissionsRequiredByFirstPartyTools4(dataTools);
|
|
130291
130414
|
const admissionId = randomUUID16();
|
|
130292
130415
|
const reservation = await reserve(
|
|
130293
130416
|
() => repair ? reserveSiteRuntimeConversationWork(deps.db, host.scope, {
|
|
@@ -130316,13 +130439,14 @@ ${input.idempotencyKey}`) : randomUUID16();
|
|
|
130316
130439
|
const body5 = {
|
|
130317
130440
|
initialMessage: input.initialMessage,
|
|
130318
130441
|
requestedSessionId,
|
|
130442
|
+
...viewer.kind === "member" ? { visibility: "private" } : {},
|
|
130319
130443
|
startMode: "standard",
|
|
130320
130444
|
agentAccess: "session",
|
|
130321
130445
|
memoryScope: "off",
|
|
130322
130446
|
rigId: null,
|
|
130323
130447
|
// Only this Site's data tools; never management or workspace tools.
|
|
130324
130448
|
firstPartyMcpTools: dataTools,
|
|
130325
|
-
...dataTools.length > 0 ? { firstPartyMcpPermissions:
|
|
130449
|
+
...dataTools.length > 0 ? { firstPartyMcpPermissions: dataToolPermissions } : {},
|
|
130326
130450
|
agent: {
|
|
130327
130451
|
capabilities: {
|
|
130328
130452
|
from: "none",
|
|
@@ -130334,7 +130458,9 @@ ${input.idempotencyKey}`) : randomUUID16();
|
|
|
130334
130458
|
// No sandbox: a Site's agent answers from the page and the Site's
|
|
130335
130459
|
// data, with no shell or workspace files.
|
|
130336
130460
|
sandboxBackend: "none",
|
|
130337
|
-
...repair ? { model: repair.model } : models.default ? { model: models.default } : {},
|
|
130461
|
+
...repair ? { model: repair.model } : input.model || models.default ? { model: input.model ?? models.default } : {},
|
|
130462
|
+
...input.reasoningEffort === void 0 ? {} : { reasoningEffort: input.reasoningEffort },
|
|
130463
|
+
...input.latencyMode === void 0 ? {} : { latencyMode: input.latencyMode },
|
|
130338
130464
|
instructions: siteAgentInstructions(host, viewer, dataTools, agent.instructions),
|
|
130339
130465
|
// Always explicit: an empty list means no workspace tools at all.
|
|
130340
130466
|
tools: mcpTools,
|
|
@@ -130348,7 +130474,7 @@ ${input.idempotencyKey}`) : randomUUID16();
|
|
|
130348
130474
|
},
|
|
130349
130475
|
...input.idempotencyKey ? { idempotencyKey: `site-runtime:${requestedSessionId}` } : {}
|
|
130350
130476
|
};
|
|
130351
|
-
const start = () => send("POST", base, body5,
|
|
130477
|
+
const start = () => send("POST", base, body5, dataToolPermissions);
|
|
130352
130478
|
const usageLimitMicros = viewer.kind === "member" || repair ? null : reservation.executionLimitMicros;
|
|
130353
130479
|
let created;
|
|
130354
130480
|
try {
|
|
@@ -130462,7 +130588,8 @@ ${input.idempotencyKey}`) : randomUUID16();
|
|
|
130462
130588
|
host,
|
|
130463
130589
|
viewer,
|
|
130464
130590
|
conversation.sessionId,
|
|
130465
|
-
conversation.toolIds
|
|
130591
|
+
conversation.toolIds,
|
|
130592
|
+
viewer.kind === "member" ? memberPermissions ?? [] : void 0
|
|
130466
130593
|
);
|
|
130467
130594
|
const usage = await settleSiteRuntimeSpend(deps, host, conversation);
|
|
130468
130595
|
if (viewer.kind === "member" && conversation.limitMicros !== null)
|
|
@@ -130687,7 +130814,7 @@ import {
|
|
|
130687
130814
|
editableArtifactScope as editableArtifactScope2,
|
|
130688
130815
|
fileOwnerContextForAccess as fileOwnerContextForAccess5,
|
|
130689
130816
|
grantHasAgentAttemptAuthority as grantHasAgentAttemptAuthority5,
|
|
130690
|
-
hasPermission as
|
|
130817
|
+
hasPermission as hasPermission37,
|
|
130691
130818
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization37,
|
|
130692
130819
|
requireLiveAgentAttemptAuthorization as requireLiveAgentAttemptAuthorization8,
|
|
130693
130820
|
requireSessionAuthorization as requireSessionAuthorization18,
|
|
@@ -130698,10 +130825,10 @@ import {
|
|
|
130698
130825
|
import {
|
|
130699
130826
|
getFilesForSubject as getFilesForSubject3,
|
|
130700
130827
|
getGeneratedImageArtifact as getGeneratedImageArtifact2,
|
|
130701
|
-
getSessionAuthorityProjection as
|
|
130828
|
+
getSessionAuthorityProjection as getSessionAuthorityProjection4,
|
|
130702
130829
|
isWorkspaceArtifactVisible,
|
|
130703
130830
|
listArtifactCatalogCandidates,
|
|
130704
|
-
nestedPostgresSqlState as
|
|
130831
|
+
nestedPostgresSqlState as nestedPostgresSqlState18,
|
|
130705
130832
|
updateArtifactPin,
|
|
130706
130833
|
withSessionRlsActorContext as withSessionRlsActorContext10
|
|
130707
130834
|
} from "@opengeni/db";
|
|
@@ -130782,7 +130909,7 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
130782
130909
|
"artifacts:publish"
|
|
130783
130910
|
);
|
|
130784
130911
|
const grant = authorization.grant;
|
|
130785
|
-
if (!
|
|
130912
|
+
if (!hasPermission37(grant.permissions, "artifacts:publish"))
|
|
130786
130913
|
throw new HTTPException119(403, { message: "Artifact publish access required" });
|
|
130787
130914
|
const kind = ArtifactCatalogKind3.safeParse(context.req.param("kind"));
|
|
130788
130915
|
const body5 = UpdateArtifactPinRequest.safeParse(await context.req.json().catch(() => null));
|
|
@@ -130791,7 +130918,7 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
130791
130918
|
throw new HTTPException119(422, { message: "Invalid artifact pin request" });
|
|
130792
130919
|
const artifactId2 = editableKinds.has(kind.data) ? requestedId : requestedId.toLowerCase();
|
|
130793
130920
|
const fileKind = kind.data === "file" || kind.data === "image";
|
|
130794
|
-
if (!
|
|
130921
|
+
if (!hasPermission37(grant.permissions, fileKind ? "files:read" : "artifacts:read"))
|
|
130795
130922
|
throw new HTTPException119(403, { message: "Artifact read access required" });
|
|
130796
130923
|
const actor = fileKind ? await fileOwnerContextForAccess5(deps, authorization, "files:read") : { subjectId: grant.subjectId, privateFileOwnerSubjectId: null };
|
|
130797
130924
|
context.header("cache-control", "private, no-store");
|
|
@@ -130843,7 +130970,7 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
130843
130970
|
}
|
|
130844
130971
|
);
|
|
130845
130972
|
} catch (error) {
|
|
130846
|
-
if (
|
|
130973
|
+
if (nestedPostgresSqlState18(error) === "42501")
|
|
130847
130974
|
throw new HTTPException119(404, { message: "Artifact not found" });
|
|
130848
130975
|
throw error;
|
|
130849
130976
|
}
|
|
@@ -130860,8 +130987,8 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
130860
130987
|
if (!parsed.success)
|
|
130861
130988
|
throw new HTTPException119(422, { message: "Invalid artifact catalog query" });
|
|
130862
130989
|
const query = parsed.data;
|
|
130863
|
-
const artifactsAllowed =
|
|
130864
|
-
const filesAllowed =
|
|
130990
|
+
const artifactsAllowed = hasPermission37(grant.permissions, "artifacts:read");
|
|
130991
|
+
const filesAllowed = hasPermission37(grant.permissions, "files:read");
|
|
130865
130992
|
if (!artifactsAllowed && !filesAllowed)
|
|
130866
130993
|
throw new HTTPException119(403, { message: "Artifact catalog read access required" });
|
|
130867
130994
|
let kinds = ArtifactCatalogKind3.options.filter(
|
|
@@ -130889,7 +131016,7 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
130889
131016
|
}
|
|
130890
131017
|
const sourceDecisions = /* @__PURE__ */ new Map();
|
|
130891
131018
|
const canReadSession = async (sessionId) => {
|
|
130892
|
-
if (!
|
|
131019
|
+
if (!hasPermission37(grant.permissions, "sessions:read")) return false;
|
|
130893
131020
|
if (sourceDecisions.has(sessionId)) return sourceDecisions.get(sessionId);
|
|
130894
131021
|
try {
|
|
130895
131022
|
await requireSessionAuthorization18(deps, grant, {
|
|
@@ -130897,7 +131024,7 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
130897
131024
|
operation: "session.read",
|
|
130898
131025
|
surface: "http"
|
|
130899
131026
|
});
|
|
130900
|
-
if (!await
|
|
131027
|
+
if (!await getSessionAuthorityProjection4(deps.db, workspaceId, sessionId)) {
|
|
130901
131028
|
sourceDecisions.set(sessionId, false);
|
|
130902
131029
|
return false;
|
|
130903
131030
|
}
|
|
@@ -131176,6 +131303,8 @@ function registerInsightsRoutes(app, deps) {
|
|
|
131176
131303
|
import {
|
|
131177
131304
|
InsightsCallsResponse,
|
|
131178
131305
|
InsightsUsageResponse,
|
|
131306
|
+
InsightsSiteUsageQuery,
|
|
131307
|
+
InsightsSiteUsageResponse,
|
|
131179
131308
|
OrganizationInsightsCallsQuery,
|
|
131180
131309
|
OrganizationInsightsUsageQuery,
|
|
131181
131310
|
WorkspaceInsightsCallsQuery,
|
|
@@ -131184,10 +131313,12 @@ import {
|
|
|
131184
131313
|
import {
|
|
131185
131314
|
accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority7,
|
|
131186
131315
|
getInsightsUsage,
|
|
131187
|
-
|
|
131316
|
+
getInsightsSiteUsage,
|
|
131317
|
+
hasPermission as hasPermission38,
|
|
131188
131318
|
listInsightsCalls,
|
|
131189
131319
|
requireAccessContext as requireAccessContext15,
|
|
131190
|
-
requireAccessGrant as requireAccessGrant58
|
|
131320
|
+
requireAccessGrant as requireAccessGrant58,
|
|
131321
|
+
siteViewerForGrant as siteViewerForGrant10
|
|
131191
131322
|
} from "@opengeni/core";
|
|
131192
131323
|
import {
|
|
131193
131324
|
currentSessionRlsActorIdentityKey as currentSessionRlsActorIdentityKey2,
|
|
@@ -131325,7 +131456,7 @@ function insightsUsageCoalesceKey(scope, query, actor) {
|
|
|
131325
131456
|
function organizationInsightsScope(context, accountId) {
|
|
131326
131457
|
const authority = accountScopedApiKeyWorkspaceAuthority7(context);
|
|
131327
131458
|
if (authority?.accountId === accountId) {
|
|
131328
|
-
const readable =
|
|
131459
|
+
const readable = hasPermission38(
|
|
131329
131460
|
authority.permissions,
|
|
131330
131461
|
"sessions:read",
|
|
131331
131462
|
authority.permissionMode
|
|
@@ -131343,7 +131474,7 @@ function organizationInsightsScope(context, accountId) {
|
|
|
131343
131474
|
detailsWorkspaceIds: [
|
|
131344
131475
|
...new Set(
|
|
131345
131476
|
context.workspaceGrants.filter(
|
|
131346
|
-
(grant) => grant.accountId === accountId && grant.subjectId === context.subjectId &&
|
|
131477
|
+
(grant) => grant.accountId === accountId && grant.subjectId === context.subjectId && hasPermission38(grant.permissions, "sessions:read", grant.permissionMode)
|
|
131347
131478
|
).map((grant) => grant.workspaceId)
|
|
131348
131479
|
)
|
|
131349
131480
|
].sort(),
|
|
@@ -131389,6 +131520,23 @@ function registerInsightsUsageRoutes(app, deps) {
|
|
|
131389
131520
|
return response;
|
|
131390
131521
|
});
|
|
131391
131522
|
}
|
|
131523
|
+
app.get("/v1/workspaces/:workspaceId/insights/sites", async (c) => {
|
|
131524
|
+
const workspaceId = c.req.param("workspaceId");
|
|
131525
|
+
const grant = await requireAccessGrant58(c, deps, workspaceId, "workspace:admin");
|
|
131526
|
+
const query = InsightsSiteUsageQuery.safeParse(insightsQueryParameters(c.req.queries()));
|
|
131527
|
+
if (!query.success) throw new HTTPException122(400, { message: "invalid Site Insights query" });
|
|
131528
|
+
const viewer = await siteViewerForGrant10(deps.db, grant);
|
|
131529
|
+
const response = await insightsWithFriendlyTimeout(
|
|
131530
|
+
() => getInsightsSiteUsage(deps.db, {
|
|
131531
|
+
accountId: grant.accountId,
|
|
131532
|
+
workspaceId,
|
|
131533
|
+
query: query.data,
|
|
131534
|
+
viewerSubjectId: viewer.subjectId
|
|
131535
|
+
})
|
|
131536
|
+
);
|
|
131537
|
+
c.header("cache-control", "private, no-store");
|
|
131538
|
+
return c.json(InsightsSiteUsageResponse.parse(response));
|
|
131539
|
+
});
|
|
131392
131540
|
app.get("/v1/workspaces/:workspaceId/insights/usage", async (c) => {
|
|
131393
131541
|
const workspaceId = c.req.param("workspaceId");
|
|
131394
131542
|
const grant = await requireAccessGrant58(c, deps, workspaceId, "workspace:admin");
|
|
@@ -131400,7 +131548,7 @@ function registerInsightsUsageRoutes(app, deps) {
|
|
|
131400
131548
|
const scope = {
|
|
131401
131549
|
accountId: grant.accountId,
|
|
131402
131550
|
workspaceId,
|
|
131403
|
-
detailsWorkspaceIds:
|
|
131551
|
+
detailsWorkspaceIds: hasPermission38(grant.permissions, "sessions:read", grant.permissionMode) ? [workspaceId] : []
|
|
131404
131552
|
};
|
|
131405
131553
|
const response = await cached(
|
|
131406
131554
|
c,
|
|
@@ -131426,7 +131574,7 @@ function registerInsightsUsageRoutes(app, deps) {
|
|
|
131426
131574
|
const scope = {
|
|
131427
131575
|
accountId: grant.accountId,
|
|
131428
131576
|
workspaceId,
|
|
131429
|
-
detailsWorkspaceIds:
|
|
131577
|
+
detailsWorkspaceIds: hasPermission38(grant.permissions, "sessions:read", grant.permissionMode) ? [workspaceId] : []
|
|
131430
131578
|
};
|
|
131431
131579
|
const response = await cached(
|
|
131432
131580
|
c,
|
|
@@ -132674,7 +132822,7 @@ import {
|
|
|
132674
132822
|
} from "@opengeni/core";
|
|
132675
132823
|
|
|
132676
132824
|
// src/model-calls/chat-completions.ts
|
|
132677
|
-
import { ReasoningEffort } from "@opengeni/contracts";
|
|
132825
|
+
import { ReasoningEffort as ReasoningEffort2 } from "@opengeni/contracts";
|
|
132678
132826
|
import { ModelCallError } from "@opengeni/core";
|
|
132679
132827
|
import {
|
|
132680
132828
|
normalizeModelCallUsage
|
|
@@ -132715,7 +132863,7 @@ var ChatCompletionRequest = z69.object({
|
|
|
132715
132863
|
temperature: z69.number().min(0).max(2).nullish(),
|
|
132716
132864
|
top_p: z69.number().min(0).max(1).nullish(),
|
|
132717
132865
|
stop: z69.union([z69.string(), z69.array(z69.string()).max(4)]).nullish(),
|
|
132718
|
-
reasoning_effort:
|
|
132866
|
+
reasoning_effort: ReasoningEffort2.nullish(),
|
|
132719
132867
|
verbosity: z69.enum(["low", "medium", "high"]).nullish(),
|
|
132720
132868
|
response_format: z69.object({ type: z69.string() }).passthrough().nullish(),
|
|
132721
132869
|
stream: z69.boolean().nullish(),
|
|
@@ -133784,7 +133932,7 @@ import {
|
|
|
133784
133932
|
requireSessionAuthorization as requireSessionAuthorization19,
|
|
133785
133933
|
SessionAuthorizationDeniedError as SessionAuthorizationDeniedError18,
|
|
133786
133934
|
SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError16,
|
|
133787
|
-
siteViewerForGrant as
|
|
133935
|
+
siteViewerForGrant as siteViewerForGrant11
|
|
133788
133936
|
} from "@opengeni/core";
|
|
133789
133937
|
import {
|
|
133790
133938
|
getGeneratedImageArtifact as getGeneratedImageArtifact3,
|
|
@@ -133838,7 +133986,7 @@ function registerSessionArtifactAssociationRoutes(app, deps) {
|
|
|
133838
133986
|
) : await hasWorkspaceArtifactSessionLink(
|
|
133839
133987
|
deps.db,
|
|
133840
133988
|
workspaceId,
|
|
133841
|
-
await
|
|
133989
|
+
await siteViewerForGrant11(deps.db, grant),
|
|
133842
133990
|
sessionId,
|
|
133843
133991
|
artifactId2
|
|
133844
133992
|
);
|
|
@@ -134140,7 +134288,7 @@ import {
|
|
|
134140
134288
|
StartManagedAuthSocialTransactionRequest,
|
|
134141
134289
|
StartManagedAuthSocialTransactionResponse
|
|
134142
134290
|
} from "@opengeni/contracts/managed-auth-session-sets";
|
|
134143
|
-
import { hasPermission as
|
|
134291
|
+
import { hasPermission as hasPermission39, requireSessionAuthorization as requireSessionAuthorization20 } from "@opengeni/core";
|
|
134144
134292
|
import {
|
|
134145
134293
|
authenticateAndAdoptManagedAuthSession,
|
|
134146
134294
|
isolatedManagedAuthHeaders,
|
|
@@ -134823,7 +134971,7 @@ async function resolveCanonicalDeepLink(deps, authority, path, expectedActorEpoc
|
|
|
134823
134971
|
const grants = target.workspaceId ? access.workspaceGrants.filter((grant) => grant.workspaceId === target.workspaceId) : access.workspaceGrants;
|
|
134824
134972
|
let authorized = false;
|
|
134825
134973
|
for (const grant of grants) {
|
|
134826
|
-
if (!
|
|
134974
|
+
if (!hasPermission39(grant.permissions, target.sessionId ? "sessions:read" : target.permission)) {
|
|
134827
134975
|
continue;
|
|
134828
134976
|
}
|
|
134829
134977
|
if (target.sessionId) {
|
|
@@ -135679,7 +135827,7 @@ import {
|
|
|
135679
135827
|
getManagedSession as getManagedSession5,
|
|
135680
135828
|
accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority8,
|
|
135681
135829
|
organizationWorkspaceInScope as organizationWorkspaceInScope3,
|
|
135682
|
-
hasPermission as
|
|
135830
|
+
hasPermission as hasPermission40,
|
|
135683
135831
|
requireAccessContext as requireAccessContext16,
|
|
135684
135832
|
organizationMembershipHttpStatus,
|
|
135685
135833
|
requireCanonicalLocalAccountAdministrator as requireCanonicalLocalAccountAdministrator4,
|
|
@@ -135703,7 +135851,7 @@ import {
|
|
|
135703
135851
|
listOrganizationAdministrationMembers as listOrganizationAdministrationMembers2,
|
|
135704
135852
|
listOrganizationInvitations,
|
|
135705
135853
|
listSelfOrganizationInvitations,
|
|
135706
|
-
nestedPostgresSqlState as
|
|
135854
|
+
nestedPostgresSqlState as nestedPostgresSqlState19,
|
|
135707
135855
|
prepareOrganizationUserSetupDelivery,
|
|
135708
135856
|
revokeOrganizationInvitation,
|
|
135709
135857
|
settleOrganizationUserSetupDelivery,
|
|
@@ -135747,7 +135895,7 @@ async function requirePrivateSessionAdministrator(context, deps, organizationId2
|
|
|
135747
135895
|
async function requireOrganizationKeyWorkspaceDeletion(context, deps, organizationId2, workspaceId) {
|
|
135748
135896
|
const access = await requireAccessContext16(context, deps);
|
|
135749
135897
|
const key2 = accountScopedApiKeyWorkspaceAuthority8(access);
|
|
135750
|
-
if (!key2 || key2.accountId !== organizationId2 || !
|
|
135898
|
+
if (!key2 || key2.accountId !== organizationId2 || !hasPermission40(key2.permissions, "workspace:admin")) {
|
|
135751
135899
|
throw new HTTPException128(403, {
|
|
135752
135900
|
message: "deleting an organization workspace requires an organization owner session or an organization API key with workspace:admin"
|
|
135753
135901
|
});
|
|
@@ -135820,7 +135968,7 @@ function parseId3(schema, value, label) {
|
|
|
135820
135968
|
return parsed.data;
|
|
135821
135969
|
}
|
|
135822
135970
|
function rethrowMembershipError(error, resourceLimitMessage) {
|
|
135823
|
-
const sqlState =
|
|
135971
|
+
const sqlState = nestedPostgresSqlState19(error);
|
|
135824
135972
|
if (sqlState === "54000" && resourceLimitMessage) {
|
|
135825
135973
|
throw new HTTPException128(409, {
|
|
135826
135974
|
message: resourceLimitMessage
|
|
@@ -135926,7 +136074,7 @@ function registerOrganizationMembershipRoutes(app, deps) {
|
|
|
135926
136074
|
})
|
|
135927
136075
|
);
|
|
135928
136076
|
} catch (error) {
|
|
135929
|
-
if (
|
|
136077
|
+
if (nestedPostgresSqlState19(error) === "42501") {
|
|
135930
136078
|
throw new HTTPException128(403, {
|
|
135931
136079
|
message: "organization membership is not active"
|
|
135932
136080
|
});
|
|
@@ -136615,7 +136763,7 @@ import {
|
|
|
136615
136763
|
import {
|
|
136616
136764
|
accountScopedApiKeyWorkspaceAuthority as accountScopedApiKeyWorkspaceAuthority9,
|
|
136617
136765
|
organizationWorkspaceInScope as organizationWorkspaceInScope4,
|
|
136618
|
-
hasPermission as
|
|
136766
|
+
hasPermission as hasPermission41,
|
|
136619
136767
|
requireAccessContext as requireAccessContext17,
|
|
136620
136768
|
requireAccessGrantAuthorization as requireAccessGrantAuthorization40,
|
|
136621
136769
|
requireSessionAuthorizationListScope as requireSessionAuthorizationListScope3,
|
|
@@ -136660,7 +136808,7 @@ function decodeOrganizationSessionListCursor(value) {
|
|
|
136660
136808
|
function requireOrganizationSessionReadAuthority(context, organizationId2) {
|
|
136661
136809
|
const authority = accountScopedApiKeyWorkspaceAuthority9(context);
|
|
136662
136810
|
if (authority) {
|
|
136663
|
-
if (authority.accountId === organizationId2 &&
|
|
136811
|
+
if (authority.accountId === organizationId2 && hasPermission41(authority.permissions, "sessions:read")) {
|
|
136664
136812
|
return "organization_api_key";
|
|
136665
136813
|
}
|
|
136666
136814
|
throw new HTTPException129(403, { message: "organization session read authority required" });
|
|
@@ -137125,7 +137273,7 @@ import {
|
|
|
137125
137273
|
completeSelfServiceOrganizationSetup,
|
|
137126
137274
|
completeOrganizationUserSetup,
|
|
137127
137275
|
getSelfServiceOrganizationOnboardingState,
|
|
137128
|
-
nestedPostgresSqlState as
|
|
137276
|
+
nestedPostgresSqlState as nestedPostgresSqlState20,
|
|
137129
137277
|
preflightOrganizationUserSetup,
|
|
137130
137278
|
previewOrganizationUserSetup,
|
|
137131
137279
|
recordOrganizationSignupUseCase
|
|
@@ -137183,14 +137331,14 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
137183
137331
|
useCase: parsed.data.useCase
|
|
137184
137332
|
}).catch((error) => {
|
|
137185
137333
|
console.warn("[api] could not record the signup use case", {
|
|
137186
|
-
sqlState:
|
|
137334
|
+
sqlState: nestedPostgresSqlState20(error) ?? null
|
|
137187
137335
|
});
|
|
137188
137336
|
});
|
|
137189
137337
|
}
|
|
137190
137338
|
return context.json(completed);
|
|
137191
137339
|
} catch (error) {
|
|
137192
137340
|
recordOrganizationSetupOutcome(deps.observability, "failed");
|
|
137193
|
-
const sqlState =
|
|
137341
|
+
const sqlState = nestedPostgresSqlState20(error);
|
|
137194
137342
|
if (sqlState === "22023") {
|
|
137195
137343
|
throw new HTTPException131(422, {
|
|
137196
137344
|
message: "invalid organization setup request"
|
|
@@ -137270,7 +137418,7 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
137270
137418
|
)
|
|
137271
137419
|
);
|
|
137272
137420
|
} catch (error) {
|
|
137273
|
-
const sqlState =
|
|
137421
|
+
const sqlState = nestedPostgresSqlState20(error);
|
|
137274
137422
|
if (sqlState === "22023") {
|
|
137275
137423
|
throw new HTTPException131(422, {
|
|
137276
137424
|
message: "invalid account setup request"
|
|
@@ -137635,7 +137783,7 @@ import {
|
|
|
137635
137783
|
SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError18,
|
|
137636
137784
|
SessionTenancyManagedHumanRequiredError as SessionTenancyManagedHumanRequiredError3
|
|
137637
137785
|
} from "@opengeni/core";
|
|
137638
|
-
import { nestedPostgresSqlState as
|
|
137786
|
+
import { nestedPostgresSqlState as nestedPostgresSqlState21, SessionTenancyNotActivatedError as SessionTenancyNotActivatedError3 } from "@opengeni/db";
|
|
137639
137787
|
import { HTTPException as HTTPException133 } from "hono/http-exception";
|
|
137640
137788
|
import { z as z78 } from "zod";
|
|
137641
137789
|
async function body4(context, schema) {
|
|
@@ -137650,10 +137798,10 @@ function lifecycleError(error) {
|
|
|
137650
137798
|
if (error instanceof SessionAuthorizationUnavailableError18) {
|
|
137651
137799
|
throw new HTTPException133(503, { message: "session authorization unavailable" });
|
|
137652
137800
|
}
|
|
137653
|
-
if (
|
|
137801
|
+
if (nestedPostgresSqlState21(error) === "42501") {
|
|
137654
137802
|
throw new HTTPException133(403, { message: "user-resource authority denied" });
|
|
137655
137803
|
}
|
|
137656
|
-
if (
|
|
137804
|
+
if (nestedPostgresSqlState21(error) === "22023") {
|
|
137657
137805
|
throw new HTTPException133(422, { message: "invalid user-resource request" });
|
|
137658
137806
|
}
|
|
137659
137807
|
throw error;
|
|
@@ -138964,7 +139112,7 @@ import {
|
|
|
138964
139112
|
controlHumanSessionWorkstream as controlHumanSessionWorkstream2,
|
|
138965
139113
|
createSessionForRequest as createSessionForRequest2,
|
|
138966
139114
|
getActorNewSessionModelChoice,
|
|
138967
|
-
hasPermission as
|
|
139115
|
+
hasPermission as hasPermission43,
|
|
138968
139116
|
requireAccessContext as requireAccessContext18,
|
|
138969
139117
|
requireAccessGrant as requireAccessGrant63,
|
|
138970
139118
|
requireSessionAuthorizationListScope as requireSessionAuthorizationListScope4,
|
|
@@ -138978,7 +139126,7 @@ import {
|
|
|
138978
139126
|
resourceMountPathCollisionKey
|
|
138979
139127
|
} from "@opengeni/contracts";
|
|
138980
139128
|
import { listRecentSessionRepositoryResources } from "@opengeni/db";
|
|
138981
|
-
import { hasPermission as
|
|
139129
|
+
import { hasPermission as hasPermission42 } from "@opengeni/core";
|
|
138982
139130
|
var SLACK_SESSION_RECENT_REPOSITORY_LIMIT = 5;
|
|
138983
139131
|
var SLACK_SESSION_RECENT_REPOSITORY_WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
138984
139132
|
function githubUriKey(uri) {
|
|
@@ -139043,7 +139191,7 @@ function selectRecentRepositoryResources(recent, catalog, limit = SLACK_SESSION_
|
|
|
139043
139191
|
return resources;
|
|
139044
139192
|
}
|
|
139045
139193
|
async function slackRecentRepositoryResources(deps, grant, workspaceId, now = /* @__PURE__ */ new Date()) {
|
|
139046
|
-
if (!
|
|
139194
|
+
if (!hasPermission42(grant.permissions, "github:use")) return [];
|
|
139047
139195
|
const recent = await listRecentSessionRepositoryResources(deps.db, {
|
|
139048
139196
|
workspaceId,
|
|
139049
139197
|
subjectId: grant.subjectId,
|
|
@@ -140346,7 +140494,7 @@ function registerSlackInteractionRoutes(app, deps) {
|
|
|
140346
140494
|
targetAccountId: grant.accountId,
|
|
140347
140495
|
targetWorkspaceId: route2.targetWorkspaceId
|
|
140348
140496
|
});
|
|
140349
|
-
if (!authorized || !
|
|
140497
|
+
if (!authorized || !hasPermission43(authorized.permissions, "sessions:create")) {
|
|
140350
140498
|
throw new HTTPException134(403, {
|
|
140351
140499
|
message: `you cannot start work in the workspace chosen for ${route2.slackChannelId}`
|
|
140352
140500
|
});
|
|
@@ -140429,7 +140577,7 @@ async function publishSlackAppHome(deps, installation, refresh, renewLease) {
|
|
|
140429
140577
|
const grant = link ? await getWorkspaceGrant5(deps.db, link.subjectId, installation.workspaceId, {
|
|
140430
140578
|
principalKind: "human_session"
|
|
140431
140579
|
}) : null;
|
|
140432
|
-
if (!grant || grant.accountId !== installation.accountId || !
|
|
140580
|
+
if (!grant || grant.accountId !== installation.accountId || !hasPermission43(grant.permissions, "sessions:read")) {
|
|
140433
140581
|
const client2 = await createOpenGeniSlackBotInteractionClient(deps, {
|
|
140434
140582
|
accountId: installation.accountId,
|
|
140435
140583
|
workspaceId: installation.workspaceId,
|
|
@@ -140507,7 +140655,7 @@ async function publishSlackAppHome(deps, installation, refresh, renewLease) {
|
|
|
140507
140655
|
const currentGrant = currentLink ? await getWorkspaceGrant5(deps.db, currentLink.subjectId, installation.workspaceId, {
|
|
140508
140656
|
principalKind: "human_session"
|
|
140509
140657
|
}) : null;
|
|
140510
|
-
if (!currentLink || currentLink.subjectId !== grant.subjectId || !currentGrant || currentGrant.accountId !== installation.accountId || !
|
|
140658
|
+
if (!currentLink || currentLink.subjectId !== grant.subjectId || !currentGrant || currentGrant.accountId !== installation.accountId || !hasPermission43(currentGrant.permissions, "sessions:read")) {
|
|
140511
140659
|
await publishSlackAppHomeAccessView(
|
|
140512
140660
|
client,
|
|
140513
140661
|
refresh,
|
|
@@ -141060,7 +141208,7 @@ async function handleSlackRouteChoice(deps, home, entry2, actionId, optionId) {
|
|
|
141060
141208
|
targetAccountId: chosen.candidateAccountId,
|
|
141061
141209
|
targetWorkspaceId: chosen.candidateWorkspaceId
|
|
141062
141210
|
}) : null;
|
|
141063
|
-
if (!grant || !
|
|
141211
|
+
if (!grant || !hasPermission43(grant.permissions, "sessions:create")) {
|
|
141064
141212
|
await client.postMessage({
|
|
141065
141213
|
operationId: deterministicUuid2(`slack-route-denied:${prompt.id}:${chosen.id}`),
|
|
141066
141214
|
userId: entry2.slackUserId,
|
|
@@ -141269,7 +141417,7 @@ async function processSlackInboxEntry(deps, entry2) {
|
|
|
141269
141417
|
});
|
|
141270
141418
|
return;
|
|
141271
141419
|
}
|
|
141272
|
-
if (!
|
|
141420
|
+
if (!hasPermission43(grant.permissions, "sessions:create")) {
|
|
141273
141421
|
throw new SlackInteractionPermanentError("sessions_create_denied");
|
|
141274
141422
|
}
|
|
141275
141423
|
const { interaction } = await getOrCreateSlackInteraction(deps.db, {
|
|
@@ -141719,7 +141867,7 @@ async function processSlackReactionInboxEntry(deps, entry2) {
|
|
|
141719
141867
|
if (!resolved) {
|
|
141720
141868
|
throw new SlackInteractionPermanentError("identity_access_revoked");
|
|
141721
141869
|
}
|
|
141722
|
-
if (!
|
|
141870
|
+
if (!hasPermission43(resolved.permissions, "sessions:create") || !hasPermission43(resolved.permissions, "sessions:control")) {
|
|
141723
141871
|
throw new SlackInteractionPermanentError("reaction_session_permissions_denied");
|
|
141724
141872
|
}
|
|
141725
141873
|
return resolved;
|
|
@@ -142264,7 +142412,7 @@ async function continueSlackSession(deps, grant, interaction, entry2, resources
|
|
|
142264
142412
|
const sessionId = interaction.sessionId;
|
|
142265
142413
|
await reopenSlackInteractionDelivery(deps.db, interaction);
|
|
142266
142414
|
if (entry2.text.trim().toLowerCase() === "stop") {
|
|
142267
|
-
if (!
|
|
142415
|
+
if (!hasPermission43(grant.permissions, "sessions:control")) {
|
|
142268
142416
|
throw new SlackInteractionPermanentError("sessions_control_denied");
|
|
142269
142417
|
}
|
|
142270
142418
|
await controlHumanSessionWorkstream2(
|
|
@@ -142343,7 +142491,7 @@ async function continueSlackSession(deps, grant, interaction, entry2, resources
|
|
|
142343
142491
|
}
|
|
142344
142492
|
}
|
|
142345
142493
|
}
|
|
142346
|
-
if (!
|
|
142494
|
+
if (!hasPermission43(grant.permissions, "sessions:control")) {
|
|
142347
142495
|
throw new SlackInteractionPermanentError("sessions_control_denied");
|
|
142348
142496
|
}
|
|
142349
142497
|
await withSlackAllowanceAdmissionNotice(deps, entry2, interaction, async () => {
|
|
@@ -142455,7 +142603,7 @@ async function processSlackBlockAction(deps, entry2) {
|
|
|
142455
142603
|
targetAccountId: target.accountId,
|
|
142456
142604
|
targetWorkspaceId: target.workspaceId
|
|
142457
142605
|
});
|
|
142458
|
-
if (!grant || !
|
|
142606
|
+
if (!grant || !hasPermission43(grant.permissions, "sessions:control")) {
|
|
142459
142607
|
throw new SlackInteractionPermanentError("sessions_control_denied");
|
|
142460
142608
|
}
|
|
142461
142609
|
const client = await createOpenGeniSlackBotInteractionClient(deps, {
|
|
@@ -142815,7 +142963,7 @@ async function executeSlackAction(deps, grant, interaction, handle) {
|
|
|
142815
142963
|
}
|
|
142816
142964
|
const session = await getSession18(deps.db, grant.workspaceId, handle.sessionId);
|
|
142817
142965
|
if (!session) throw new SlackInteractionPermanentError("slack_action_session_missing");
|
|
142818
|
-
const recurring =
|
|
142966
|
+
const recurring = hasPermission43(grant.permissions, "sessions:read") && hasPermission43(grant.permissions, "scheduled_tasks:manage") ? makeRecurringText(deps, grant.workspaceId, handle.sessionId) : null;
|
|
142819
142967
|
return {
|
|
142820
142968
|
result: "status",
|
|
142821
142969
|
text: `${mention}Opengeni task status: *${session.status.replaceAll("_", " ")}*.${recurring ? `
|
|
@@ -143902,7 +144050,7 @@ async function slackInfoCommandResponse(deps, installation, entry2) {
|
|
|
143902
144050
|
const grant = link ? await getWorkspaceGrant5(deps.db, link.subjectId, installation.workspaceId, {
|
|
143903
144051
|
principalKind: "human_session"
|
|
143904
144052
|
}) : null;
|
|
143905
|
-
if (!grant || grant.accountId !== installation.accountId || !
|
|
144053
|
+
if (!grant || grant.accountId !== installation.accountId || !hasPermission43(grant.permissions, "sessions:read")) {
|
|
143906
144054
|
return ephemeralSlackResponse(
|
|
143907
144055
|
link ? `Your Slack identity is linked, but it does not currently have access to this Opengeni workspace. Request access: ${linkUrl(deps, identity2)}. No session was created.` : `Link your Slack identity to Opengeni before starting work: ${linkUrl(deps, identity2)}. No session was created.`
|
|
143908
144056
|
);
|
|
@@ -143910,9 +144058,9 @@ async function slackInfoCommandResponse(deps, installation, entry2) {
|
|
|
143910
144058
|
const workspace = await getWorkspace15(deps.db, installation.workspaceId);
|
|
143911
144059
|
const command = deps.settings.slackCommand;
|
|
143912
144060
|
const botMention = slackBotMention(installation.botUserId);
|
|
143913
|
-
const canControl =
|
|
143914
|
-
const canCreate =
|
|
143915
|
-
const canSchedule =
|
|
144061
|
+
const canControl = hasPermission43(grant.permissions, "sessions:control");
|
|
144062
|
+
const canCreate = hasPermission43(grant.permissions, "sessions:create");
|
|
144063
|
+
const canSchedule = hasPermission43(grant.permissions, "scheduled_tasks:manage");
|
|
143916
144064
|
const schedules = canSchedule ? slackSchedulesUrl(deps, installation.workspaceId) : null;
|
|
143917
144065
|
const agentSchedules = canSchedule && canControl && slackTaskFirstPartyMcpTools(deps.settings, workspace?.settings).includes(
|
|
143918
144066
|
"scheduled_tasks_create"
|
|
@@ -145058,7 +145206,7 @@ function createAppComposition(deps) {
|
|
|
145058
145206
|
{ accountId: grant.accountId, workspaceId, subjectId: grant.subjectId },
|
|
145059
145207
|
{ observeAvailability: true }
|
|
145060
145208
|
);
|
|
145061
|
-
if (!
|
|
145209
|
+
if (!hasPermission44(grant.permissions, "sessions:create")) {
|
|
145062
145210
|
modelSelectionForbidden = true;
|
|
145063
145211
|
selections = [];
|
|
145064
145212
|
}
|
|
@@ -145072,7 +145220,7 @@ function createAppComposition(deps) {
|
|
|
145072
145220
|
preferredProvider: voicePreferences?.preferredProvider,
|
|
145073
145221
|
fallbackEnabled: voicePreferences?.fallbackEnabled
|
|
145074
145222
|
};
|
|
145075
|
-
if (
|
|
145223
|
+
if (hasPermission44(grant.permissions, "sessions:create") && transcription) {
|
|
145076
145224
|
voiceInputProviders = await transcription.availableProviderIds?.(voiceContext) ?? [];
|
|
145077
145225
|
voiceInputAvailable = voiceInputProviders.length > 0 && await Promise.resolve(transcription.available(voiceContext)).catch(() => false);
|
|
145078
145226
|
}
|
|
@@ -145367,8 +145515,8 @@ function createAppComposition(deps) {
|
|
|
145367
145515
|
throw error;
|
|
145368
145516
|
}
|
|
145369
145517
|
const grant = authorization.grant;
|
|
145370
|
-
const outsideAgentContext =
|
|
145371
|
-
return await
|
|
145518
|
+
const outsideAgentContext = AsyncLocalStorage4.snapshot();
|
|
145519
|
+
return await withSessionAuthorizationReadReuse3(
|
|
145372
145520
|
(reads) => withAccessGrantSessionRlsContext(routeDeps, grant, async () => {
|
|
145373
145521
|
const boundSessionId = grant.metadata?.sessionId;
|
|
145374
145522
|
if (typeof boundSessionId === "string") {
|
|
@@ -145465,7 +145613,7 @@ function createAppComposition(deps) {
|
|
|
145465
145613
|
reauthorize: async () => {
|
|
145466
145614
|
const live = await requireFreshAccessGrant5(c, routeDeps, workspaceId, "workspace:read");
|
|
145467
145615
|
const original = authorization.grant;
|
|
145468
|
-
if (live.accountId !== original.accountId || live.subjectId !== original.subjectId || live.principalKind !== original.principalKind || original.permissions.some((permission) => !
|
|
145616
|
+
if (live.accountId !== original.accountId || live.subjectId !== original.subjectId || live.principalKind !== original.principalKind || original.permissions.some((permission) => !hasPermission44(live.permissions, permission)))
|
|
145469
145617
|
throw new HTTPException135(403, { message: "tool_access_changed" });
|
|
145470
145618
|
},
|
|
145471
145619
|
onFence: (created) => {
|
|
@@ -145919,7 +146067,7 @@ async function validateCodexAccountTarget(request) {
|
|
|
145919
146067
|
async function requireMcpAccessGrantAuthorization(c, deps, workspaceId) {
|
|
145920
146068
|
const authorization = await requireAccessGrantAuthorization42(c, deps, workspaceId);
|
|
145921
146069
|
const grant = authorization.grant;
|
|
145922
|
-
if (
|
|
146070
|
+
if (hasPermission44(grant.permissions, "workspace:read")) {
|
|
145923
146071
|
return authorization;
|
|
145924
146072
|
}
|
|
145925
146073
|
if (isCodemodeGrant(grant)) {
|
|
@@ -147351,4 +147499,4 @@ export {
|
|
|
147351
147499
|
withDefaultEnabledCapabilityMcpTools,
|
|
147352
147500
|
workflowIdForSession4 as workflowIdForSession
|
|
147353
147501
|
};
|
|
147354
|
-
//# sourceMappingURL=chunk-
|
|
147502
|
+
//# sourceMappingURL=chunk-6CECHDZP.js.map
|