@opengeni/api-router 1.0.2 → 1.2.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/artifact-catalog-cursor.d.ts +1 -0
- package/dist/{chunk-6TZ5LG3O.js → chunk-BAZXDFT2.js} +353 -161
- package/dist/{chunk-6TZ5LG3O.js.map → chunk-BAZXDFT2.js.map} +1 -1
- package/dist/credit-promotion-snapshot.d.ts +6 -0
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/integrations/marketplace-plugin.d.ts +43 -43
- package/dist/mcp/server.d.ts +1 -1
- package/dist/routes/billing.d.ts +3 -1
- package/package.json +20 -20
- package/src/app.ts +8 -2
- package/src/artifact-catalog-cursor.ts +1 -0
- package/src/credit-promotion-snapshot.ts +36 -0
- package/src/index.ts +0 -2
- package/src/mcp/action-catalog.gen.ts +35 -16
- package/src/mcp/server.ts +3 -0
- package/src/mcp-oauth.ts +8 -2
- package/src/model-catalog.ts +1 -0
- package/src/routes/artifact-catalog.ts +92 -0
- package/src/routes/billing.ts +72 -15
- package/src/routes/managed-onboarding.ts +2 -0
- package/src/routes/organization-memberships.ts +2 -5
- package/src/routes/sessions.ts +11 -1
- package/src/routes/workspaces.ts +27 -12
|
@@ -3803,8 +3803,8 @@ async function sendIntegrationEndpointTest(input) {
|
|
|
3803
3803
|
// src/routes/workspace-integrations.ts
|
|
3804
3804
|
import { HTTPException as HTTPException14 } from "hono/http-exception";
|
|
3805
3805
|
import { z as z10 } from "zod";
|
|
3806
|
-
function newIntegrationSecret(
|
|
3807
|
-
return `${
|
|
3806
|
+
function newIntegrationSecret(prefix2) {
|
|
3807
|
+
return `${prefix2}_${randomBytes2(32).toString("base64url")}`;
|
|
3808
3808
|
}
|
|
3809
3809
|
function iso(value) {
|
|
3810
3810
|
return value ? value.toISOString() : null;
|
|
@@ -4378,13 +4378,13 @@ function registerApiKeyRoutes(app, deps) {
|
|
|
4378
4378
|
quantity: 1
|
|
4379
4379
|
});
|
|
4380
4380
|
const token = generateApiKeyToken();
|
|
4381
|
-
const
|
|
4381
|
+
const prefix2 = token.slice(0, 14);
|
|
4382
4382
|
const apiKey = await createApiKey(deps.db, {
|
|
4383
4383
|
accountId: grant.accountId,
|
|
4384
4384
|
workspaceId: grant.workspaceId,
|
|
4385
4385
|
name: body3.name,
|
|
4386
4386
|
description: body3.description ?? null,
|
|
4387
|
-
prefix,
|
|
4387
|
+
prefix: prefix2,
|
|
4388
4388
|
keyHash: await sha256Hex(token),
|
|
4389
4389
|
permissions,
|
|
4390
4390
|
expiresAt: body3.expiresAt ? new Date(body3.expiresAt) : null
|
|
@@ -5843,6 +5843,7 @@ function projectClientModel(model) {
|
|
|
5843
5843
|
id: model.id,
|
|
5844
5844
|
label: model.label,
|
|
5845
5845
|
...model.shortLabel ? { shortLabel: model.shortLabel } : {},
|
|
5846
|
+
...model.logoUrl ? { logoUrl: model.logoUrl } : {},
|
|
5846
5847
|
...publicProvider,
|
|
5847
5848
|
...source === void 0 ? {} : { source },
|
|
5848
5849
|
api: model.api,
|
|
@@ -9756,6 +9757,7 @@ import {
|
|
|
9756
9757
|
setSessionChannel
|
|
9757
9758
|
} from "@opengeni/db";
|
|
9758
9759
|
import { createHash as createHash15, randomUUID as randomUUID5 } from "crypto";
|
|
9760
|
+
import { assertGoalResumeAllowed } from "@opengeni/core";
|
|
9759
9761
|
|
|
9760
9762
|
// src/sandbox/enrollment.ts
|
|
9761
9763
|
import { createPublicKey, randomBytes as randomBytes3, verify } from "crypto";
|
|
@@ -14802,7 +14804,7 @@ var PKCE_CHALLENGE = /^[A-Za-z0-9_-]{43}$/u;
|
|
|
14802
14804
|
var WORKSPACE_MCP_PATH = /^\/v1\/workspaces\/([0-9a-f-]{36})\/mcp(?:\/(docs|files))?$/u;
|
|
14803
14805
|
var ORGANIZATION_MCP_PATH = "/v1/mcp";
|
|
14804
14806
|
function registerMcpOAuthRoutes(app, deps) {
|
|
14805
|
-
|
|
14807
|
+
const authorizationServerMetadata = (c) => {
|
|
14806
14808
|
requireMcpOAuthEnabled(deps);
|
|
14807
14809
|
const issuer = mcpOAuthIssuer(deps);
|
|
14808
14810
|
c.header("cache-control", "public, max-age=300");
|
|
@@ -14820,7 +14822,9 @@ function registerMcpOAuthRoutes(app, deps) {
|
|
|
14820
14822
|
authorization_response_iss_parameter_supported: true
|
|
14821
14823
|
})
|
|
14822
14824
|
);
|
|
14823
|
-
}
|
|
14825
|
+
};
|
|
14826
|
+
app.get("/.well-known/oauth-authorization-server", authorizationServerMetadata);
|
|
14827
|
+
app.get("/.well-known/oauth-authorization-server/*", authorizationServerMetadata);
|
|
14824
14828
|
app.get("/.well-known/oauth-protected-resource/*", (c) => {
|
|
14825
14829
|
requireMcpOAuthEnabled(deps);
|
|
14826
14830
|
const pathname = new URL(c.req.url).pathname.replace(
|
|
@@ -15242,7 +15246,7 @@ function mcpOAuthConsentToolIdentities(catalog) {
|
|
|
15242
15246
|
return catalog.entries.map((entry2) => entry2.identity);
|
|
15243
15247
|
}
|
|
15244
15248
|
function isMcpOAuthPublicProtocolPath(pathname) {
|
|
15245
|
-
return pathname === "/.well-known/oauth-authorization-server" || pathname.startsWith("/.well-known/oauth-protected-resource/") || pathname === "/oauth/register" || pathname === "/oauth/authorize" || pathname === "/oauth/token";
|
|
15249
|
+
return pathname === "/.well-known/oauth-authorization-server" || pathname.startsWith("/.well-known/oauth-authorization-server/") || pathname.startsWith("/.well-known/oauth-protected-resource/") || pathname === "/oauth/register" || pathname === "/oauth/authorize" || pathname === "/oauth/token";
|
|
15246
15250
|
}
|
|
15247
15251
|
function mcpOAuthAuthenticateHeader(deps, pathname) {
|
|
15248
15252
|
return `Bearer resource_metadata="${mcpOAuthIssuer(deps)}/.well-known/oauth-protected-resource${pathname}", scope="${MCP_OAUTH_SCOPE}"`;
|
|
@@ -15380,8 +15384,8 @@ function boundedState(value) {
|
|
|
15380
15384
|
function pkceChallenge(verifier) {
|
|
15381
15385
|
return createHash4("sha256").update(verifier, "ascii").digest("base64url");
|
|
15382
15386
|
}
|
|
15383
|
-
function opaque(
|
|
15384
|
-
return `${
|
|
15387
|
+
function opaque(prefix2) {
|
|
15388
|
+
return `${prefix2}${randomBytes5(32).toString("base64url")}`;
|
|
15385
15389
|
}
|
|
15386
15390
|
function tokenHash(value) {
|
|
15387
15391
|
return createHash4("sha256").update(value, "utf8").digest("hex");
|
|
@@ -21617,21 +21621,21 @@ function projectScheduledTaskUtf8(value, maxBytes) {
|
|
|
21617
21621
|
return { value, originalBytes, deliveredBytes: originalBytes, truncated: false };
|
|
21618
21622
|
}
|
|
21619
21623
|
let marker = "";
|
|
21620
|
-
let
|
|
21624
|
+
let prefix2 = "";
|
|
21621
21625
|
let omittedBytes = originalBytes;
|
|
21622
21626
|
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
21623
21627
|
marker = `\u2026[${omittedBytes} UTF-8 bytes omitted]`;
|
|
21624
21628
|
if (Buffer.byteLength(marker, "utf8") > byteLimit) {
|
|
21625
21629
|
marker = utf8Prefix2(marker, byteLimit);
|
|
21626
|
-
|
|
21630
|
+
prefix2 = "";
|
|
21627
21631
|
break;
|
|
21628
21632
|
}
|
|
21629
|
-
|
|
21630
|
-
const nextOmitted = originalBytes - Buffer.byteLength(
|
|
21633
|
+
prefix2 = utf8Prefix2(value, byteLimit - Buffer.byteLength(marker, "utf8"));
|
|
21634
|
+
const nextOmitted = originalBytes - Buffer.byteLength(prefix2, "utf8");
|
|
21631
21635
|
if (nextOmitted === omittedBytes) break;
|
|
21632
21636
|
omittedBytes = nextOmitted;
|
|
21633
21637
|
}
|
|
21634
|
-
const projected = `${
|
|
21638
|
+
const projected = `${prefix2}${marker}`;
|
|
21635
21639
|
return {
|
|
21636
21640
|
value: projected,
|
|
21637
21641
|
originalBytes,
|
|
@@ -25078,8 +25082,8 @@ function sniffSlackReactionImageMime(bytes) {
|
|
|
25078
25082
|
return null;
|
|
25079
25083
|
}
|
|
25080
25084
|
function hasMarkupPrefix(bytes) {
|
|
25081
|
-
const
|
|
25082
|
-
return
|
|
25085
|
+
const prefix2 = new TextDecoder("utf-8", { fatal: false }).decode(bytes.subarray(0, Math.min(bytes.byteLength, 256))).replace(/^\uFEFF/u, "").trimStart().toLowerCase();
|
|
25086
|
+
return prefix2.startsWith("<svg") || prefix2.startsWith("<html") || prefix2.startsWith("<!doctype") || prefix2.startsWith("<?xml");
|
|
25083
25087
|
}
|
|
25084
25088
|
function isCompletePng(bytes) {
|
|
25085
25089
|
const signature = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
@@ -33429,6 +33433,7 @@ function registerGoalTools(server, deps, grant, sessionId, json2) {
|
|
|
33429
33433
|
sessionId,
|
|
33430
33434
|
{
|
|
33431
33435
|
status: "active",
|
|
33436
|
+
beforeResume: (tx, session, causalTurn) => assertGoalResumeAllowed({ ...deps, db: tx }, session, causalTurn),
|
|
33432
33437
|
event: { type: "goal.resumed", actor: "agent" }
|
|
33433
33438
|
}
|
|
33434
33439
|
);
|
|
@@ -38564,14 +38569,9 @@ var ACTION_CATALOG = [
|
|
|
38564
38569
|
"method": "GET",
|
|
38565
38570
|
"path": "/v1/organizations/:accountId/insights/calls",
|
|
38566
38571
|
"request": [],
|
|
38567
|
-
"response": [
|
|
38568
|
-
|
|
38569
|
-
|
|
38570
|
-
"id": "GET /v1/organizations/:accountId/insights/usage",
|
|
38571
|
-
"method": "GET",
|
|
38572
|
-
"path": "/v1/organizations/:accountId/insights/usage",
|
|
38573
|
-
"request": [],
|
|
38574
|
-
"response": []
|
|
38572
|
+
"response": [
|
|
38573
|
+
"InsightsCallsResponse"
|
|
38574
|
+
]
|
|
38575
38575
|
},
|
|
38576
38576
|
{
|
|
38577
38577
|
"id": "GET /v1/organizations/:organizationId/codex/accounts",
|
|
@@ -38724,14 +38724,9 @@ var ACTION_CATALOG = [
|
|
|
38724
38724
|
"method": "GET",
|
|
38725
38725
|
"path": "/v1/workspaces/:workspaceId/insights/calls",
|
|
38726
38726
|
"request": [],
|
|
38727
|
-
"response": [
|
|
38728
|
-
|
|
38729
|
-
|
|
38730
|
-
"id": "GET /v1/workspaces/:workspaceId/insights/usage",
|
|
38731
|
-
"method": "GET",
|
|
38732
|
-
"path": "/v1/workspaces/:workspaceId/insights/usage",
|
|
38733
|
-
"request": [],
|
|
38734
|
-
"response": []
|
|
38727
|
+
"response": [
|
|
38728
|
+
"InsightsCallsResponse"
|
|
38729
|
+
]
|
|
38735
38730
|
},
|
|
38736
38731
|
{
|
|
38737
38732
|
"id": "GET /v1/workspaces/:workspaceId/instruction-policies/:revisionId",
|
|
@@ -39292,6 +39287,15 @@ var ACTION_CATALOG = [
|
|
|
39292
39287
|
"GetOrganizationCredentialProviderResponse"
|
|
39293
39288
|
]
|
|
39294
39289
|
},
|
|
39290
|
+
{
|
|
39291
|
+
"id": "getOrganizationInsightsUsage",
|
|
39292
|
+
"method": "GET",
|
|
39293
|
+
"path": "/v1/organizations/:accountId/insights/usage",
|
|
39294
|
+
"request": [],
|
|
39295
|
+
"response": [
|
|
39296
|
+
"InsightsUsageResponse"
|
|
39297
|
+
]
|
|
39298
|
+
},
|
|
39295
39299
|
{
|
|
39296
39300
|
"id": "getOrganizationIntegrationCatalog",
|
|
39297
39301
|
"method": "GET",
|
|
@@ -39747,6 +39751,15 @@ var ACTION_CATALOG = [
|
|
|
39747
39751
|
"WorkspaceInsightsResponse"
|
|
39748
39752
|
]
|
|
39749
39753
|
},
|
|
39754
|
+
{
|
|
39755
|
+
"id": "getWorkspaceInsightsUsage",
|
|
39756
|
+
"method": "GET",
|
|
39757
|
+
"path": "/v1/workspaces/:workspaceId/insights/usage",
|
|
39758
|
+
"request": [],
|
|
39759
|
+
"response": [
|
|
39760
|
+
"InsightsUsageResponse"
|
|
39761
|
+
]
|
|
39762
|
+
},
|
|
39750
39763
|
{
|
|
39751
39764
|
"id": "getWorkspaceLearningHistory",
|
|
39752
39765
|
"method": "GET",
|
|
@@ -42907,6 +42920,17 @@ var ACTION_CATALOG = [
|
|
|
42907
42920
|
"PrReviewAppRegistration"
|
|
42908
42921
|
]
|
|
42909
42922
|
},
|
|
42923
|
+
{
|
|
42924
|
+
"id": "updateArtifactPin",
|
|
42925
|
+
"method": "PUT",
|
|
42926
|
+
"path": "/v1/workspaces/:workspaceId/artifact-catalog/:kind/:artifactId/pin",
|
|
42927
|
+
"request": [
|
|
42928
|
+
"ArtifactCatalogKind"
|
|
42929
|
+
],
|
|
42930
|
+
"response": [
|
|
42931
|
+
"ArtifactPinResponse"
|
|
42932
|
+
]
|
|
42933
|
+
},
|
|
42910
42934
|
{
|
|
42911
42935
|
"id": "updateBrowserIdentity",
|
|
42912
42936
|
"method": "PATCH",
|
|
@@ -73484,13 +73508,13 @@ function registerCatalogAssetRoutes(app, deps) {
|
|
|
73484
73508
|
});
|
|
73485
73509
|
}
|
|
73486
73510
|
function catalogAssetKeyFromPath(pathname) {
|
|
73487
|
-
const
|
|
73488
|
-
if (!pathname.startsWith(
|
|
73511
|
+
const prefix2 = "/v1/";
|
|
73512
|
+
if (!pathname.startsWith(prefix2)) {
|
|
73489
73513
|
return null;
|
|
73490
73514
|
}
|
|
73491
73515
|
let key;
|
|
73492
73516
|
try {
|
|
73493
|
-
key = decodeURIComponent(pathname.slice(
|
|
73517
|
+
key = decodeURIComponent(pathname.slice(prefix2.length));
|
|
73494
73518
|
} catch {
|
|
73495
73519
|
return null;
|
|
73496
73520
|
}
|
|
@@ -82430,8 +82454,8 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82430
82454
|
"/v1/workspaces/:workspaceId/variable-sets",
|
|
82431
82455
|
"/v1/workspaces/:workspaceId/environments"
|
|
82432
82456
|
];
|
|
82433
|
-
for (const
|
|
82434
|
-
app.get(`${
|
|
82457
|
+
for (const prefix2 of prefixes) {
|
|
82458
|
+
app.get(`${prefix2}`, async (c) => {
|
|
82435
82459
|
const workspaceId = c.req.param("workspaceId");
|
|
82436
82460
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82437
82461
|
requirePermission4(grant, "variable-sets:list");
|
|
@@ -82444,14 +82468,14 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82444
82468
|
})
|
|
82445
82469
|
);
|
|
82446
82470
|
});
|
|
82447
|
-
app.post(`${
|
|
82471
|
+
app.post(`${prefix2}`, async (c) => {
|
|
82448
82472
|
const workspaceId = c.req.param("workspaceId");
|
|
82449
82473
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82450
82474
|
const grant = authorization.grant;
|
|
82451
82475
|
requirePermission4(grant, "variable-sets:write");
|
|
82452
82476
|
const key = requireVariableSetEncryption2(settings);
|
|
82453
82477
|
const payload = await parseRequestJson(c, CreateVariableSetRequest);
|
|
82454
|
-
if (
|
|
82478
|
+
if (prefix2.endsWith("/environments") && payload.scope !== "workspace") {
|
|
82455
82479
|
throw new HTTPException61(422, {
|
|
82456
82480
|
message: "the legacy environments route only creates workspace-scoped variable sets"
|
|
82457
82481
|
});
|
|
@@ -82515,8 +82539,8 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82515
82539
|
});
|
|
82516
82540
|
return c.json(created, 201);
|
|
82517
82541
|
});
|
|
82518
|
-
if (
|
|
82519
|
-
app.post(`${
|
|
82542
|
+
if (prefix2.endsWith("/variable-sets")) {
|
|
82543
|
+
app.post(`${prefix2}/resolve-attachments`, async (c) => {
|
|
82520
82544
|
const workspaceId = c.req.param("workspaceId");
|
|
82521
82545
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82522
82546
|
requirePermission4(grant, "variable-sets:attach");
|
|
@@ -82534,15 +82558,15 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82534
82558
|
return c.json(ResolveVariableSetAttachmentsResponse.parse({ variableSets }));
|
|
82535
82559
|
});
|
|
82536
82560
|
}
|
|
82537
|
-
app.get(`${
|
|
82561
|
+
app.get(`${prefix2}/:variableSetId`, async (c) => {
|
|
82538
82562
|
const workspaceId = c.req.param("workspaceId");
|
|
82539
82563
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82540
82564
|
requirePermission4(grant, "variable-sets:read");
|
|
82541
82565
|
requirePermission4(grant, "secrets:list");
|
|
82542
82566
|
return c.json(await requireVariableSetForApi(db, grant, c.req.param("variableSetId")));
|
|
82543
82567
|
});
|
|
82544
|
-
if (
|
|
82545
|
-
app.get(`${
|
|
82568
|
+
if (prefix2.endsWith("/variable-sets")) {
|
|
82569
|
+
app.get(`${prefix2}/:variableSetId/variables/:name`, async (c) => {
|
|
82546
82570
|
const workspaceId = c.req.param("workspaceId");
|
|
82547
82571
|
const grant = await requireAccessGrant20(c, deps, workspaceId);
|
|
82548
82572
|
requirePermission4(grant, "variable-sets:read");
|
|
@@ -82566,7 +82590,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82566
82590
|
return c.json(secret);
|
|
82567
82591
|
});
|
|
82568
82592
|
}
|
|
82569
|
-
app.patch(`${
|
|
82593
|
+
app.patch(`${prefix2}/:variableSetId`, async (c) => {
|
|
82570
82594
|
const workspaceId = c.req.param("workspaceId");
|
|
82571
82595
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82572
82596
|
const grant = authorization.grant;
|
|
@@ -82614,7 +82638,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82614
82638
|
});
|
|
82615
82639
|
return c.json(updated);
|
|
82616
82640
|
});
|
|
82617
|
-
app.delete(`${
|
|
82641
|
+
app.delete(`${prefix2}/:variableSetId`, async (c) => {
|
|
82618
82642
|
const workspaceId = c.req.param("workspaceId");
|
|
82619
82643
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82620
82644
|
const grant = authorization.grant;
|
|
@@ -82651,7 +82675,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82651
82675
|
});
|
|
82652
82676
|
return c.json({ ok: true });
|
|
82653
82677
|
});
|
|
82654
|
-
app.put(`${
|
|
82678
|
+
app.put(`${prefix2}/:variableSetId/variables/:name`, async (c) => {
|
|
82655
82679
|
const workspaceId = c.req.param("workspaceId");
|
|
82656
82680
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82657
82681
|
const grant = authorization.grant;
|
|
@@ -82690,7 +82714,7 @@ function registerVariableSetRoutes(app, deps) {
|
|
|
82690
82714
|
});
|
|
82691
82715
|
return c.json(metadata);
|
|
82692
82716
|
});
|
|
82693
|
-
app.delete(`${
|
|
82717
|
+
app.delete(`${prefix2}/:variableSetId/variables/:name`, async (c) => {
|
|
82694
82718
|
const workspaceId = c.req.param("workspaceId");
|
|
82695
82719
|
const authorization = await requireAccessGrantAuthorization15(c, deps, workspaceId);
|
|
82696
82720
|
const grant = authorization.grant;
|
|
@@ -83006,10 +83030,43 @@ import {
|
|
|
83006
83030
|
OrganizationUsageWorkspacePageQuery
|
|
83007
83031
|
} from "@opengeni/contracts";
|
|
83008
83032
|
import { OrganizationModelUsageQuery } from "@opengeni/contracts/organization-model-usage";
|
|
83009
|
-
import { configuredEntitlements } from "@opengeni/config";
|
|
83033
|
+
import { configuredEntitlements, promotionalCreditScope } from "@opengeni/config";
|
|
83034
|
+
|
|
83035
|
+
// src/credit-promotion-snapshot.ts
|
|
83036
|
+
import { PromotionalCreditScope } from "@opengeni/contracts";
|
|
83037
|
+
var prefix = "opengeni_credit_scope_";
|
|
83038
|
+
var countKey = `${prefix}v1`;
|
|
83039
|
+
function creditScopeMetadata(scope) {
|
|
83040
|
+
if (!scope) return {};
|
|
83041
|
+
const encoded = JSON.stringify(PromotionalCreditScope.parse(scope));
|
|
83042
|
+
const chunks = encoded.match(/[\s\S]{1,400}/g);
|
|
83043
|
+
if (chunks.length > 24)
|
|
83044
|
+
throw new Error("Promotional credit policy exceeds checkout metadata limits");
|
|
83045
|
+
return Object.fromEntries([
|
|
83046
|
+
[countKey, String(chunks.length)],
|
|
83047
|
+
...chunks.map((chunk, index) => [`${prefix}${index}`, chunk])
|
|
83048
|
+
]);
|
|
83049
|
+
}
|
|
83050
|
+
function creditScopeFromMetadata(metadata) {
|
|
83051
|
+
if (!metadata || !Object.keys(metadata).some((key) => key.startsWith(prefix))) return void 0;
|
|
83052
|
+
const count = Number(metadata[countKey]);
|
|
83053
|
+
if (!Number.isInteger(count) || count < 1 || count > 24) {
|
|
83054
|
+
throw new Error("Invalid promotional credit snapshot");
|
|
83055
|
+
}
|
|
83056
|
+
let encoded = "";
|
|
83057
|
+
for (let index = 0; index < count; index++) {
|
|
83058
|
+
const chunk = metadata[`${prefix}${index}`];
|
|
83059
|
+
if (!chunk) throw new Error("Incomplete promotional credit snapshot");
|
|
83060
|
+
encoded += chunk;
|
|
83061
|
+
}
|
|
83062
|
+
return PromotionalCreditScope.parse(JSON.parse(encoded));
|
|
83063
|
+
}
|
|
83064
|
+
|
|
83065
|
+
// src/routes/billing.ts
|
|
83010
83066
|
import {
|
|
83011
83067
|
applyCreditLedgerEntry,
|
|
83012
83068
|
getBillingBalance,
|
|
83069
|
+
readCreditPromotionPolicy,
|
|
83013
83070
|
getBillingCustomer,
|
|
83014
83071
|
getCreditLedgerEntry,
|
|
83015
83072
|
hasCreditLedgerEntry,
|
|
@@ -83019,6 +83076,7 @@ import {
|
|
|
83019
83076
|
getOrganizationUsageSummary,
|
|
83020
83077
|
getOrganizationUsageWorkspacePage,
|
|
83021
83078
|
withSessionRlsActorContext as withSessionRlsActorContext8,
|
|
83079
|
+
withRlsContext as withRlsContext2,
|
|
83022
83080
|
getManagedAccount as getManagedAccount2,
|
|
83023
83081
|
markStripeWebhookProcessed,
|
|
83024
83082
|
recordStripeWebhookEvent,
|
|
@@ -83124,6 +83182,12 @@ function registerBillingRoutes(app, deps) {
|
|
|
83124
83182
|
const accountId = requireSelectedAccount(context, body3.accountId, "billing:manage");
|
|
83125
83183
|
const stripe = stripeClient(deps);
|
|
83126
83184
|
const promotion = body3.promotionCode ? await resolveCheckoutPromotionCode(stripe, body3.promotionCode) : null;
|
|
83185
|
+
const promotionalScope = promotion ? promotionalCreditScope(
|
|
83186
|
+
{
|
|
83187
|
+
creditPromotionPolicy: await readCreditPromotionPolicy(deps.db) ?? deps.settings.creditPromotionPolicy
|
|
83188
|
+
},
|
|
83189
|
+
promotion.couponId
|
|
83190
|
+
) : void 0;
|
|
83127
83191
|
const amountCents = body3.amountUsd !== void 0 ? usdToCents(body3.amountUsd) : promotion?.amountOffCents ?? null;
|
|
83128
83192
|
if (amountCents === null) {
|
|
83129
83193
|
throw new HTTPException64(422, {
|
|
@@ -83135,6 +83199,11 @@ function registerBillingRoutes(app, deps) {
|
|
|
83135
83199
|
message: "Credits must be between $5 and $10,000."
|
|
83136
83200
|
});
|
|
83137
83201
|
}
|
|
83202
|
+
if (promotionalScope && (!promotion?.amountOffCents || amountCents !== promotion.amountOffCents)) {
|
|
83203
|
+
throw new HTTPException64(422, {
|
|
83204
|
+
message: "Redeem this offer for its exact credit amount. Buy additional credits separately."
|
|
83205
|
+
});
|
|
83206
|
+
}
|
|
83138
83207
|
const amountMicros = centsToMicros(amountCents);
|
|
83139
83208
|
const customerId = await getOrCreateStripeCustomer(deps, stripe, context, accountId);
|
|
83140
83209
|
const idempotencyKey = `checkout:${accountId}:${amountMicros}:${crypto.randomUUID()}`;
|
|
@@ -83152,8 +83221,10 @@ function registerBillingRoutes(app, deps) {
|
|
|
83152
83221
|
successUrl: body3.successUrl,
|
|
83153
83222
|
cancelUrl: body3.cancelUrl,
|
|
83154
83223
|
idempotencyKey,
|
|
83224
|
+
promotionalScope,
|
|
83155
83225
|
...promotion ? {
|
|
83156
83226
|
promotionCodeId: promotion.id,
|
|
83227
|
+
couponId: promotion.couponId,
|
|
83157
83228
|
fullyDiscounted: promotion.percentOff === 100 || (promotion.amountOffCents ?? 0) >= amountCents
|
|
83158
83229
|
} : {}
|
|
83159
83230
|
}),
|
|
@@ -83172,7 +83243,8 @@ function registerBillingRoutes(app, deps) {
|
|
|
83172
83243
|
CreateCheckoutResponse.parse({
|
|
83173
83244
|
checkoutSessionId: session.id,
|
|
83174
83245
|
url: session.url,
|
|
83175
|
-
amountUsd: amountCents / 100
|
|
83246
|
+
amountUsd: amountCents / 100,
|
|
83247
|
+
promotionalScope
|
|
83176
83248
|
})
|
|
83177
83249
|
);
|
|
83178
83250
|
});
|
|
@@ -83216,6 +83288,7 @@ function registerBillingRoutes(app, deps) {
|
|
|
83216
83288
|
state: entry2 ? "granted" : "pending",
|
|
83217
83289
|
amountMicros: entry2?.amountMicros ?? credit.amountMicros,
|
|
83218
83290
|
currency: "usd",
|
|
83291
|
+
promotionalScope: creditScopeFromMetadata(session.metadata),
|
|
83219
83292
|
free: entry2 ? entry2.sourceType === "stripe_checkout_coupon" : isFreeCouponCheckout(session)
|
|
83220
83293
|
},
|
|
83221
83294
|
balance: entry2 ? await getBillingBalance(deps.db, accountId) : null
|
|
@@ -83315,7 +83388,7 @@ function stripeCheckoutSessionCreateParams(input) {
|
|
|
83315
83388
|
return {
|
|
83316
83389
|
mode: "payment",
|
|
83317
83390
|
// Stripe takes either a code field on its page or one discount up front.
|
|
83318
|
-
...input.promotionCodeId ? { discounts: [{ promotion_code: input.promotionCodeId }] } : { allow_promotion_codes:
|
|
83391
|
+
...input.promotionCodeId ? { discounts: [{ promotion_code: input.promotionCodeId }] } : { allow_promotion_codes: false },
|
|
83319
83392
|
customer: input.customerId,
|
|
83320
83393
|
customer_update: {
|
|
83321
83394
|
address: "auto",
|
|
@@ -83344,6 +83417,8 @@ function stripeCheckoutSessionCreateParams(input) {
|
|
|
83344
83417
|
}
|
|
83345
83418
|
],
|
|
83346
83419
|
metadata: {
|
|
83420
|
+
...creditScopeMetadata(input.promotionalScope),
|
|
83421
|
+
...input.couponId ? { opengeni_credit_offer_id: input.couponId } : {},
|
|
83347
83422
|
opengeni_account_id: input.accountId,
|
|
83348
83423
|
opengeni_credit_amount_usd: (input.amountCents / 100).toFixed(2),
|
|
83349
83424
|
opengeni_credit_micros: String(input.amountMicros),
|
|
@@ -83485,6 +83560,10 @@ async function grantCheckoutSessionCredits(deps, session, source) {
|
|
|
83485
83560
|
}
|
|
83486
83561
|
const credit = decision.credit;
|
|
83487
83562
|
const freeCouponCheckout = isFreeCouponCheckout(session);
|
|
83563
|
+
const promotionalScope = creditScopeFromMetadata(session.metadata);
|
|
83564
|
+
if (promotionalScope && !freeCouponCheckout) {
|
|
83565
|
+
throw new Error("Scoped promotional credits require a fully discounted checkout");
|
|
83566
|
+
}
|
|
83488
83567
|
if (!await getManagedAccount2(deps.db, credit.accountId)) {
|
|
83489
83568
|
console.info(
|
|
83490
83569
|
"[api] stripe webhook ignored a checkout session for an account not in this deployment",
|
|
@@ -83511,10 +83590,13 @@ async function grantCheckoutSessionCredits(deps, session, source) {
|
|
|
83511
83590
|
accountId: credit.accountId,
|
|
83512
83591
|
type: freeCouponCheckout ? "grant" : "credit_topup",
|
|
83513
83592
|
amountMicros: credit.amountMicros,
|
|
83593
|
+
eligibleModelIds: promotionalScope?.eligibleModelIds,
|
|
83514
83594
|
sourceType: freeCouponCheckout ? "stripe_checkout_coupon" : "stripe_checkout_session",
|
|
83515
83595
|
sourceId: session.id,
|
|
83516
83596
|
idempotencyKey: credit.idempotencyKey,
|
|
83517
83597
|
metadata: {
|
|
83598
|
+
...promotionalScope ? { creditOfferLabel: promotionalScope.label } : {},
|
|
83599
|
+
creditOfferId: session.metadata?.opengeni_credit_offer_id ?? null,
|
|
83518
83600
|
stripeEventId: source.stripeEventId,
|
|
83519
83601
|
stripePaymentIntentId: typeof session.payment_intent === "string" ? session.payment_intent : session.payment_intent?.id ?? null,
|
|
83520
83602
|
stripePackageId: credit.packageId,
|
|
@@ -83540,7 +83622,12 @@ async function resolveCheckoutPromotionCode(stripe, code) {
|
|
|
83540
83622
|
throw new HTTPException64(422, { message: "That code isn't valid or has expired." });
|
|
83541
83623
|
}
|
|
83542
83624
|
const amountOffCents = coupon.amount_off && coupon.currency === "usd" ? coupon.amount_off : coupon.currency_options?.usd?.amount_off ?? null;
|
|
83543
|
-
return {
|
|
83625
|
+
return {
|
|
83626
|
+
id: promotionCode.id,
|
|
83627
|
+
couponId: coupon.id,
|
|
83628
|
+
amountOffCents,
|
|
83629
|
+
percentOff: coupon.percent_off ?? null
|
|
83630
|
+
};
|
|
83544
83631
|
}
|
|
83545
83632
|
async function mirrorPaymentIntentCustomer(deps, event) {
|
|
83546
83633
|
const intent = event.data.object;
|
|
@@ -83622,18 +83709,26 @@ async function releaseDisputedCredits(deps, stripe, event) {
|
|
|
83622
83709
|
return;
|
|
83623
83710
|
}
|
|
83624
83711
|
const holdIdempotencyKey = `stripe:dispute_hold:${dispute.id}`;
|
|
83625
|
-
if (!await hasCreditLedgerEntry(deps.db, accountId, holdIdempotencyKey)) {
|
|
83626
|
-
return;
|
|
83627
|
-
}
|
|
83628
83712
|
const debitMicros = await creditAdjustmentMicros(deps, metadata, dispute.amount);
|
|
83629
|
-
await
|
|
83630
|
-
|
|
83631
|
-
|
|
83632
|
-
|
|
83633
|
-
|
|
83634
|
-
|
|
83635
|
-
|
|
83636
|
-
|
|
83713
|
+
await withRlsContext2(deps.db, { accountId }, async (tx) => {
|
|
83714
|
+
await applyCreditLedgerEntry(tx, {
|
|
83715
|
+
accountId,
|
|
83716
|
+
type: "credit_dispute_hold",
|
|
83717
|
+
amountMicros: -debitMicros,
|
|
83718
|
+
sourceType: "stripe_dispute",
|
|
83719
|
+
sourceId: dispute.id,
|
|
83720
|
+
idempotencyKey: holdIdempotencyKey,
|
|
83721
|
+
metadata: { stripeDisputeId: dispute.id, stripeEventType: event.type }
|
|
83722
|
+
});
|
|
83723
|
+
await applyCreditLedgerEntry(tx, {
|
|
83724
|
+
accountId,
|
|
83725
|
+
type: "credit_dispute_release",
|
|
83726
|
+
amountMicros: debitMicros,
|
|
83727
|
+
sourceType: "stripe_dispute",
|
|
83728
|
+
sourceId: dispute.id,
|
|
83729
|
+
idempotencyKey: `stripe:dispute_release:${dispute.id}`,
|
|
83730
|
+
metadata: { stripeDisputeId: dispute.id, stripeEventType: event.type }
|
|
83731
|
+
});
|
|
83637
83732
|
});
|
|
83638
83733
|
}
|
|
83639
83734
|
async function creditAdjustmentMicros(deps, metadata, amountCents) {
|
|
@@ -91687,9 +91782,9 @@ async function requireGitHubManageGrant(c, deps, workspaceId, expectedState) {
|
|
|
91687
91782
|
}
|
|
91688
91783
|
}
|
|
91689
91784
|
function allCookieValues(c, name) {
|
|
91690
|
-
const
|
|
91691
|
-
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(
|
|
91692
|
-
const raw = part.slice(
|
|
91785
|
+
const prefix2 = `${name}=`;
|
|
91786
|
+
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(prefix2)).map((part) => {
|
|
91787
|
+
const raw = part.slice(prefix2.length);
|
|
91693
91788
|
try {
|
|
91694
91789
|
return decodeURIComponent(raw);
|
|
91695
91790
|
} catch {
|
|
@@ -96457,12 +96552,12 @@ function requireStateCookie(c, state) {
|
|
|
96457
96552
|
}
|
|
96458
96553
|
}
|
|
96459
96554
|
function allCookieValues2(c, name) {
|
|
96460
|
-
const
|
|
96461
|
-
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(
|
|
96555
|
+
const prefix2 = `${name}=`;
|
|
96556
|
+
return (c.req.header("cookie") ?? "").split(";").map((part) => part.trim()).filter((part) => part.startsWith(prefix2)).map((part) => {
|
|
96462
96557
|
try {
|
|
96463
|
-
return decodeURIComponent(part.slice(
|
|
96558
|
+
return decodeURIComponent(part.slice(prefix2.length));
|
|
96464
96559
|
} catch {
|
|
96465
|
-
return part.slice(
|
|
96560
|
+
return part.slice(prefix2.length);
|
|
96466
96561
|
}
|
|
96467
96562
|
});
|
|
96468
96563
|
}
|
|
@@ -99677,6 +99772,7 @@ function registerScheduledTaskRoutes(app, deps) {
|
|
|
99677
99772
|
|
|
99678
99773
|
// src/routes/sessions.ts
|
|
99679
99774
|
import { getRetainedProviderCommand } from "@opengeni/db/retained-provider-commands";
|
|
99775
|
+
import { assertGoalResumeAllowed as assertGoalResumeAllowed2, GoalResumeBlockedError } from "@opengeni/core";
|
|
99680
99776
|
import { UnsupportedLatencyModeError } from "@opengeni/config";
|
|
99681
99777
|
import { searchSessionMessagesForSubject, SessionMessageSearchCursorError } from "@opengeni/db";
|
|
99682
99778
|
import { listSessionEventSlices } from "@opengeni/db/session-event-slices";
|
|
@@ -100083,9 +100179,9 @@ function openGeniRealtimeInstructions(additional) {
|
|
|
100083
100179
|
const trimmed = additional?.trim();
|
|
100084
100180
|
if (!trimmed) return OPENGENI_REALTIME_BASE_INSTRUCTIONS;
|
|
100085
100181
|
const heading = "\n\n## Additional realtime guidance\nFollow the guidance below for this conversation unless it conflicts with the operating, delegation, safety, permission, or context-handling rules above.\n";
|
|
100086
|
-
const
|
|
100087
|
-
const remaining = REALTIME_INSTRUCTIONS_MAX_BYTES - Buffer.byteLength(
|
|
100088
|
-
return `${
|
|
100182
|
+
const prefix2 = `${OPENGENI_REALTIME_BASE_INSTRUCTIONS}${heading}`;
|
|
100183
|
+
const remaining = REALTIME_INSTRUCTIONS_MAX_BYTES - Buffer.byteLength(prefix2, "utf8");
|
|
100184
|
+
return `${prefix2}${takeUtf8Head(trimmed, Math.max(0, remaining))}`;
|
|
100089
100185
|
}
|
|
100090
100186
|
function takeUtf8Head(value, maximumBytes) {
|
|
100091
100187
|
if (Buffer.byteLength(value, "utf8") <= maximumBytes) return value;
|
|
@@ -103151,6 +103247,14 @@ function registerSessionRoutes(app, deps) {
|
|
|
103151
103247
|
sessionId,
|
|
103152
103248
|
{
|
|
103153
103249
|
status: "active",
|
|
103250
|
+
beforeResume: (tx, session, causalTurn) => assertGoalResumeAllowed2({ ...deps, db: tx }, session, causalTurn).catch(
|
|
103251
|
+
(error) => {
|
|
103252
|
+
if (error instanceof GoalResumeBlockedError) {
|
|
103253
|
+
throw new HTTPException88(422, { message: error.message, cause: error });
|
|
103254
|
+
}
|
|
103255
|
+
throw error;
|
|
103256
|
+
}
|
|
103257
|
+
),
|
|
103154
103258
|
event: { type: "goal.resumed", actor: "api" }
|
|
103155
103259
|
}
|
|
103156
103260
|
);
|
|
@@ -105149,7 +105253,7 @@ function sessionTenancyHttpError(error) {
|
|
|
105149
105253
|
if (error instanceof SessionTenancyNotActivatedError) {
|
|
105150
105254
|
return new ApiHttpError(409, {
|
|
105151
105255
|
code: "conflict",
|
|
105152
|
-
message: "
|
|
105256
|
+
message: "Only-me chats are not enabled for this organization.",
|
|
105153
105257
|
retryable: false,
|
|
105154
105258
|
details: { reason: "not_activated" }
|
|
105155
105259
|
});
|
|
@@ -106287,6 +106391,8 @@ import {
|
|
|
106287
106391
|
import { loadWorkspaceCodexModelAvailability } from "@opengeni/core";
|
|
106288
106392
|
import {
|
|
106289
106393
|
allWorkspacePermissions,
|
|
106394
|
+
getBillingBalance as getBillingBalance2,
|
|
106395
|
+
spendableCreditMicros,
|
|
106290
106396
|
createWorkspace,
|
|
106291
106397
|
ensureWorkspaceByExternalIdentity,
|
|
106292
106398
|
findWorkspaceByExternalIdentity as findWorkspaceByExternalIdentity2,
|
|
@@ -106881,25 +106987,31 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
106881
106987
|
organizationOpenRouterCustomModels: organizationProviders.openrouter.models
|
|
106882
106988
|
});
|
|
106883
106989
|
const workspaceSettings = workspace?.settings ?? {};
|
|
106990
|
+
const creditBalance = deps.settings.billingMode === "stripe" ? await getBillingBalance2(deps.db, grant.accountId) : void 0;
|
|
106884
106991
|
const defaultSelection = await resolveDefaultSessionModelForSelections(deps.db, {
|
|
106885
106992
|
settings: workspaceCatalogSettings,
|
|
106886
106993
|
accountId: grant.accountId,
|
|
106887
106994
|
workspaceSettings,
|
|
106888
106995
|
selections
|
|
106889
106996
|
});
|
|
106997
|
+
const catalog = projectWorkspaceModelCatalog(selections, {
|
|
106998
|
+
defaultSelection,
|
|
106999
|
+
creditsSelection: creditsDefaultSessionModel({
|
|
107000
|
+
settings: workspaceCatalogSettings,
|
|
107001
|
+
selections,
|
|
107002
|
+
workspaceSettings
|
|
107003
|
+
})
|
|
107004
|
+
});
|
|
107005
|
+
if (creditBalance) {
|
|
107006
|
+
for (const model of catalog.models) {
|
|
107007
|
+
if (model.cost !== "credits") continue;
|
|
107008
|
+
model.creditFunding = creditBalance.promotionalCredits?.some(
|
|
107009
|
+
(credit) => credit.remainingMicros > 0 && credit.eligibleModelIds.includes(model.id)
|
|
107010
|
+
) ? "promotional" : spendableCreditMicros(creditBalance, model.id) > 0 ? "general" : "unavailable";
|
|
107011
|
+
}
|
|
107012
|
+
}
|
|
106890
107013
|
c.header("cache-control", "private, no-store");
|
|
106891
|
-
return c.json(
|
|
106892
|
-
WorkspaceModelCatalogResponse2.parse(
|
|
106893
|
-
projectWorkspaceModelCatalog(selections, {
|
|
106894
|
-
defaultSelection,
|
|
106895
|
-
creditsSelection: creditsDefaultSessionModel({
|
|
106896
|
-
settings: workspaceCatalogSettings,
|
|
106897
|
-
selections,
|
|
106898
|
-
workspaceSettings
|
|
106899
|
-
})
|
|
106900
|
-
})
|
|
106901
|
-
)
|
|
106902
|
-
);
|
|
107014
|
+
return c.json(WorkspaceModelCatalogResponse2.parse(catalog));
|
|
106903
107015
|
});
|
|
106904
107016
|
app.get("/v1/workspaces/:workspaceId/gateway-custom-models", async (c) => {
|
|
106905
107017
|
const workspaceId = c.req.param("workspaceId");
|
|
@@ -110062,6 +110174,8 @@ import {
|
|
|
110062
110174
|
ArtifactCatalogKind as ArtifactCatalogKind2,
|
|
110063
110175
|
ArtifactCatalogListQuery,
|
|
110064
110176
|
ArtifactCatalogListResponse,
|
|
110177
|
+
ArtifactPinResponse,
|
|
110178
|
+
UpdateArtifactPinRequest,
|
|
110065
110179
|
retainedArtifactReferenceFromFile as retainedArtifactReferenceFromFile3,
|
|
110066
110180
|
retainedGeneratedImageReferenceFromFile as retainedGeneratedImageReferenceFromFile2
|
|
110067
110181
|
} from "@opengeni/contracts";
|
|
@@ -110082,9 +110196,12 @@ import {
|
|
|
110082
110196
|
getGeneratedImageArtifact as getGeneratedImageArtifact2,
|
|
110083
110197
|
getSessionAuthorityProjection as getSessionAuthorityProjection3,
|
|
110084
110198
|
listArtifactCatalogCandidates,
|
|
110199
|
+
nestedPostgresSqlState as nestedPostgresSqlState14,
|
|
110200
|
+
updateArtifactPin,
|
|
110085
110201
|
withSessionRlsActorContext as withSessionRlsActorContext9
|
|
110086
110202
|
} from "@opengeni/db";
|
|
110087
110203
|
import { HTTPException as HTTPException102 } from "hono/http-exception";
|
|
110204
|
+
import { z as z53 } from "zod";
|
|
110088
110205
|
|
|
110089
110206
|
// src/artifact-catalog-cursor.ts
|
|
110090
110207
|
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, createHash as createHash29, randomBytes as randomBytes12 } from "crypto";
|
|
@@ -110098,7 +110215,8 @@ var Cursor = z52.object({
|
|
|
110098
110215
|
after: z52.object({
|
|
110099
110216
|
key: z52.string().max(4096),
|
|
110100
110217
|
kind: ArtifactCatalogKind,
|
|
110101
|
-
id: z52.string().min(1).max(128)
|
|
110218
|
+
id: z52.string().min(1).max(128),
|
|
110219
|
+
pinned: z52.boolean().optional()
|
|
110102
110220
|
}).strict()
|
|
110103
110221
|
}).strict();
|
|
110104
110222
|
function artifactCatalogCursorCodec(secret, binding) {
|
|
@@ -110146,9 +110264,82 @@ var iso2 = (value) => new Date(value).toISOString();
|
|
|
110146
110264
|
var position = (row) => ({
|
|
110147
110265
|
key: row.sort_key,
|
|
110148
110266
|
kind: row.kind,
|
|
110149
|
-
id: row.id
|
|
110267
|
+
id: row.id,
|
|
110268
|
+
pinned: row.pinned ?? false
|
|
110150
110269
|
});
|
|
110151
110270
|
function registerArtifactCatalogRoutes(app, deps) {
|
|
110271
|
+
app.put("/v1/workspaces/:workspaceId/artifact-catalog/:kind/:artifactId/pin", async (context) => {
|
|
110272
|
+
const workspaceId = context.req.param("workspaceId");
|
|
110273
|
+
const authorization = await requireAccessGrantAuthorization36(
|
|
110274
|
+
context,
|
|
110275
|
+
deps,
|
|
110276
|
+
workspaceId,
|
|
110277
|
+
"artifacts:publish"
|
|
110278
|
+
);
|
|
110279
|
+
const grant = authorization.grant;
|
|
110280
|
+
if (!hasPermission27(grant.permissions, "artifacts:publish"))
|
|
110281
|
+
throw new HTTPException102(403, { message: "Artifact publish access required" });
|
|
110282
|
+
const kind = ArtifactCatalogKind2.safeParse(context.req.param("kind"));
|
|
110283
|
+
const body3 = UpdateArtifactPinRequest.safeParse(await context.req.json().catch(() => null));
|
|
110284
|
+
const requestedId = context.req.param("artifactId");
|
|
110285
|
+
if (!kind.success || !body3.success || !(editableKinds.has(kind.data) ? /^[0-9a-f]{32}$/.test(requestedId) : z53.string().uuid().safeParse(requestedId).success))
|
|
110286
|
+
throw new HTTPException102(422, { message: "Invalid artifact pin request" });
|
|
110287
|
+
const artifactId2 = editableKinds.has(kind.data) ? requestedId : requestedId.toLowerCase();
|
|
110288
|
+
const fileKind = kind.data === "file" || kind.data === "image";
|
|
110289
|
+
if (!hasPermission27(grant.permissions, fileKind ? "files:read" : "artifacts:read"))
|
|
110290
|
+
throw new HTTPException102(403, { message: "Artifact read access required" });
|
|
110291
|
+
const actor = fileKind ? await fileOwnerContextForAccess5(deps, authorization, "files:read") : { subjectId: grant.subjectId, privateFileOwnerSubjectId: null };
|
|
110292
|
+
context.header("cache-control", "private, no-store");
|
|
110293
|
+
return withSessionRlsActorContext9(actor, async () => {
|
|
110294
|
+
if (editableKinds.has(kind.data)) {
|
|
110295
|
+
if (!deps.editableArtifacts)
|
|
110296
|
+
throw new HTTPException102(503, { message: "Editable artifacts are unavailable" });
|
|
110297
|
+
try {
|
|
110298
|
+
const scope = editableArtifactScope2({ accountId: grant.accountId, workspaceId });
|
|
110299
|
+
const artifact = await deps.editableArtifacts.readArtifact({
|
|
110300
|
+
scope,
|
|
110301
|
+
actor: editableArtifactActorForGrant(grant, "0000000000000001"),
|
|
110302
|
+
artifactId: editableArtifactId3(artifactId2)
|
|
110303
|
+
});
|
|
110304
|
+
if (artifact.scope.accountId !== scope.accountId || artifact.scope.workspaceId !== scope.workspaceId || artifact.id !== artifactId2 || artifact.modality !== kind.data)
|
|
110305
|
+
throw new HTTPException102(404, { message: "Artifact not found" });
|
|
110306
|
+
} catch (error) {
|
|
110307
|
+
if (isInvisibleListCandidate(error))
|
|
110308
|
+
throw new HTTPException102(404, { message: "Artifact not found" });
|
|
110309
|
+
throw editableArtifactHttpError(error);
|
|
110310
|
+
}
|
|
110311
|
+
}
|
|
110312
|
+
if (fileKind) {
|
|
110313
|
+
const subjectId = await fileAuthoritySubjectIdForGrant(deps, grant);
|
|
110314
|
+
const [file] = await getFilesForSubject3(deps.db, {
|
|
110315
|
+
accountId: grant.accountId,
|
|
110316
|
+
workspaceId,
|
|
110317
|
+
subjectId,
|
|
110318
|
+
fileIds: [artifactId2]
|
|
110319
|
+
});
|
|
110320
|
+
if (!file || file.status !== "ready")
|
|
110321
|
+
throw new HTTPException102(404, { message: "Artifact not found" });
|
|
110322
|
+
}
|
|
110323
|
+
try {
|
|
110324
|
+
await updateArtifactPin(
|
|
110325
|
+
deps.db,
|
|
110326
|
+
{ accountId: grant.accountId, workspaceId },
|
|
110327
|
+
{
|
|
110328
|
+
kind: kind.data,
|
|
110329
|
+
artifactId: artifactId2,
|
|
110330
|
+
pinned: body3.data.pinned
|
|
110331
|
+
}
|
|
110332
|
+
);
|
|
110333
|
+
} catch (error) {
|
|
110334
|
+
if (nestedPostgresSqlState14(error) === "42501")
|
|
110335
|
+
throw new HTTPException102(404, { message: "Artifact not found" });
|
|
110336
|
+
throw error;
|
|
110337
|
+
}
|
|
110338
|
+
return context.json(
|
|
110339
|
+
ArtifactPinResponse.parse({ kind: kind.data, artifactId: artifactId2, pinned: body3.data.pinned })
|
|
110340
|
+
);
|
|
110341
|
+
});
|
|
110342
|
+
});
|
|
110152
110343
|
app.get("/v1/workspaces/:workspaceId/artifact-catalog", async (context) => {
|
|
110153
110344
|
const workspaceId = context.req.param("workspaceId");
|
|
110154
110345
|
const authorization = await requireAccessGrantAuthorization36(context, deps, workspaceId);
|
|
@@ -110282,7 +110473,8 @@ async function projectCandidate(deps, grant, row, fileSubject) {
|
|
|
110282
110473
|
title: row.title,
|
|
110283
110474
|
status: row.status,
|
|
110284
110475
|
createdAt: iso2(row.created_at),
|
|
110285
|
-
updatedAt: iso2(row.updated_at)
|
|
110476
|
+
updatedAt: iso2(row.updated_at),
|
|
110477
|
+
...row.pinned !== void 0 ? { pinned: row.pinned } : {}
|
|
110286
110478
|
};
|
|
110287
110479
|
if (row.version_id) item.versionId = row.version_id;
|
|
110288
110480
|
if (editableKinds.has(row.kind)) {
|
|
@@ -111870,12 +112062,12 @@ import {
|
|
|
111870
112062
|
hasEditableArtifactSessionLink as hasEditableArtifactSessionLink2,
|
|
111871
112063
|
hasWorkspaceArtifactSessionLink,
|
|
111872
112064
|
transactionallyAuthorizeEditableArtifactActor,
|
|
111873
|
-
withRlsContext as
|
|
112065
|
+
withRlsContext as withRlsContext3
|
|
111874
112066
|
} from "@opengeni/db";
|
|
111875
112067
|
import { HTTPException as HTTPException106 } from "hono/http-exception";
|
|
111876
|
-
import { z as
|
|
111877
|
-
var SessionId2 =
|
|
111878
|
-
var EditableArtifactId =
|
|
112068
|
+
import { z as z54 } from "zod";
|
|
112069
|
+
var SessionId2 = z54.string().uuid();
|
|
112070
|
+
var EditableArtifactId = z54.string().regex(/^(?!0{32}$)[0-9a-f]{32}$/u);
|
|
111879
112071
|
function registerSessionArtifactAssociationRoutes(app, deps) {
|
|
111880
112072
|
app.get(
|
|
111881
112073
|
"/v1/workspaces/:workspaceId/sessions/:sessionId/artifact-associations/:artifactId",
|
|
@@ -111901,7 +112093,7 @@ function registerSessionArtifactAssociationRoutes(app, deps) {
|
|
|
111901
112093
|
const linked = kind === "editable" ? await hasEditableArtifactSessionLink2(deps.db, scope, sessionId, artifactId2) : await hasWorkspaceArtifactSessionLink(deps.db, workspaceId, sessionId, artifactId2);
|
|
111902
112094
|
if (!linked) throw new HTTPException106(404, { message: "Artifact association not found" });
|
|
111903
112095
|
if (kind === "editable") {
|
|
111904
|
-
const decision = await
|
|
112096
|
+
const decision = await withRlsContext3(
|
|
111905
112097
|
deps.db,
|
|
111906
112098
|
scope,
|
|
111907
112099
|
(tx) => transactionallyAuthorizeEditableArtifactActor(tx, {
|
|
@@ -112099,7 +112291,7 @@ import {
|
|
|
112099
112291
|
getCanonicalHumanIdentityProjection as getCanonicalHumanIdentityProjection3
|
|
112100
112292
|
} from "@opengeni/db/canonical-human-identities";
|
|
112101
112293
|
import { HTTPException as HTTPException110 } from "hono/http-exception";
|
|
112102
|
-
import { z as
|
|
112294
|
+
import { z as z57 } from "zod";
|
|
112103
112295
|
|
|
112104
112296
|
// src/routes/managed-sign-in-methods.ts
|
|
112105
112297
|
import {
|
|
@@ -112123,7 +112315,7 @@ import { getManagedAuthSessionSetSnapshot as getManagedAuthSessionSetSnapshot2 }
|
|
|
112123
112315
|
import { getCanonicalHumanIdentityProjection as getCanonicalHumanIdentityProjection2 } from "@opengeni/db/canonical-human-identities";
|
|
112124
112316
|
import { getCookie as getCookie2 } from "hono/cookie";
|
|
112125
112317
|
import { HTTPException as HTTPException109 } from "hono/http-exception";
|
|
112126
|
-
import { z as
|
|
112318
|
+
import { z as z56 } from "zod";
|
|
112127
112319
|
|
|
112128
112320
|
// src/routes/managed-auth-session-sets.ts
|
|
112129
112321
|
import { assertManagedUserAdmission as assertManagedUserAdmission2, getManagedSession as getManagedSession3 } from "@opengeni/core";
|
|
@@ -112189,12 +112381,12 @@ import {
|
|
|
112189
112381
|
import { ensureManagedAccessForUser as ensureManagedAccessForUser2, getSession as getSession10 } from "@opengeni/db";
|
|
112190
112382
|
import { deleteCookie as deleteCookie3, getCookie, setCookie as setCookie3 } from "hono/cookie";
|
|
112191
112383
|
import { HTTPException as HTTPException108 } from "hono/http-exception";
|
|
112192
|
-
import { z as
|
|
112193
|
-
var ManagedAuthSocialStartReceipt =
|
|
112194
|
-
version:
|
|
112195
|
-
requestDigest:
|
|
112196
|
-
url:
|
|
112197
|
-
stateCookie:
|
|
112384
|
+
import { z as z55 } from "zod";
|
|
112385
|
+
var ManagedAuthSocialStartReceipt = z55.object({
|
|
112386
|
+
version: z55.literal(1),
|
|
112387
|
+
requestDigest: z55.string().regex(/^[0-9a-f]{64}$/u),
|
|
112388
|
+
url: z55.string().url().max(4096),
|
|
112389
|
+
stateCookie: z55.string().min(1).max(4096)
|
|
112198
112390
|
}).strict();
|
|
112199
112391
|
function registerManagedAuthSessionSetRoutes(app, deps) {
|
|
112200
112392
|
const noStore = async (context, next) => {
|
|
@@ -113034,8 +113226,8 @@ function setTransactionCookie(context, deps, transactionId, transactionSecret) {
|
|
|
113034
113226
|
}
|
|
113035
113227
|
function requireTransactionSecret(context, transactionId) {
|
|
113036
113228
|
const value = getCookie(context, MANAGED_AUTH_LOGIN_TRANSACTION_COOKIE);
|
|
113037
|
-
const
|
|
113038
|
-
const secret = value?.startsWith(
|
|
113229
|
+
const prefix2 = `${transactionId}.`;
|
|
113230
|
+
const secret = value?.startsWith(prefix2) ? value.slice(prefix2.length) : null;
|
|
113039
113231
|
if (!secret || !/^[A-Za-z0-9_-]{43}$/.test(secret)) {
|
|
113040
113232
|
throw managedAuthApiError(401, "invalid_transaction");
|
|
113041
113233
|
}
|
|
@@ -113130,23 +113322,23 @@ function setCookieHeaders(headers) {
|
|
|
113130
113322
|
}
|
|
113131
113323
|
|
|
113132
113324
|
// src/routes/managed-sign-in-methods.ts
|
|
113133
|
-
var ConnectState =
|
|
113134
|
-
opengeniSignInMethod:
|
|
113135
|
-
intentId:
|
|
113136
|
-
provider:
|
|
113325
|
+
var ConnectState = z56.object({
|
|
113326
|
+
opengeniSignInMethod: z56.object({
|
|
113327
|
+
intentId: z56.string().uuid(),
|
|
113328
|
+
provider: z56.enum(["google", "github"])
|
|
113137
113329
|
}),
|
|
113138
|
-
link:
|
|
113139
|
-
callbackURL:
|
|
113140
|
-
errorURL:
|
|
113330
|
+
link: z56.object({ userId: z56.string().min(1), email: z56.string().email() }),
|
|
113331
|
+
callbackURL: z56.string().url(),
|
|
113332
|
+
errorURL: z56.string().url()
|
|
113141
113333
|
});
|
|
113142
|
-
var ConnectIntent =
|
|
113143
|
-
authUserId:
|
|
113144
|
-
authSessionId:
|
|
113145
|
-
expectedIdentityId:
|
|
113146
|
-
actorFence:
|
|
113147
|
-
authorityHash:
|
|
113148
|
-
actorEpoch:
|
|
113149
|
-
requestId:
|
|
113334
|
+
var ConnectIntent = z56.object({
|
|
113335
|
+
authUserId: z56.string().min(1),
|
|
113336
|
+
authSessionId: z56.string().min(1),
|
|
113337
|
+
expectedIdentityId: z56.string().uuid(),
|
|
113338
|
+
actorFence: z56.object({
|
|
113339
|
+
authorityHash: z56.string().regex(/^[0-9a-f]{64}$/),
|
|
113340
|
+
actorEpoch: z56.string().regex(/^[1-9][0-9]*$/),
|
|
113341
|
+
requestId: z56.string().uuid()
|
|
113150
113342
|
}).optional()
|
|
113151
113343
|
});
|
|
113152
113344
|
async function rows(deps, query) {
|
|
@@ -113466,7 +113658,7 @@ async function handleManagedSignInConnectCallback(context, deps, provider) {
|
|
|
113466
113658
|
|
|
113467
113659
|
// src/routes/canonical-human-identities.ts
|
|
113468
113660
|
import { managedAuthSecretRequestDigest as managedAuthSecretRequestDigest3 } from "@opengeni/core/managed-auth-session-sets";
|
|
113469
|
-
var BindingId =
|
|
113661
|
+
var BindingId = z57.string().uuid();
|
|
113470
113662
|
async function requestIdentity(context, deps) {
|
|
113471
113663
|
return await requireCanonicalHumanRequestIdentity2(context, {
|
|
113472
113664
|
db: deps.db,
|
|
@@ -113635,6 +113827,7 @@ function registerCanonicalHumanIdentityRoutes(app, deps) {
|
|
|
113635
113827
|
}
|
|
113636
113828
|
|
|
113637
113829
|
// src/routes/organization-memberships.ts
|
|
113830
|
+
import { signupCreditModelIds } from "@opengeni/config";
|
|
113638
113831
|
import {
|
|
113639
113832
|
lookupExternalIdentityForRequest,
|
|
113640
113833
|
cancelExternalWorkspaceMemberGrantForRequest,
|
|
@@ -113702,7 +113895,7 @@ import {
|
|
|
113702
113895
|
listOrganizationAdministrationMembers,
|
|
113703
113896
|
listOrganizationInvitations,
|
|
113704
113897
|
listSelfOrganizationInvitations,
|
|
113705
|
-
nestedPostgresSqlState as
|
|
113898
|
+
nestedPostgresSqlState as nestedPostgresSqlState15,
|
|
113706
113899
|
prepareOrganizationUserSetupDelivery,
|
|
113707
113900
|
revokeOrganizationInvitation,
|
|
113708
113901
|
settleOrganizationUserSetupDelivery,
|
|
@@ -113716,11 +113909,11 @@ import {
|
|
|
113716
113909
|
updateOrganizationRetentionPolicy
|
|
113717
113910
|
} from "@opengeni/db";
|
|
113718
113911
|
import { HTTPException as HTTPException111 } from "hono/http-exception";
|
|
113719
|
-
import { z as
|
|
113720
|
-
var OrganizationId2 =
|
|
113721
|
-
var WorkspaceId =
|
|
113722
|
-
var MembershipId =
|
|
113723
|
-
var InvitationId =
|
|
113912
|
+
import { z as z58 } from "zod";
|
|
113913
|
+
var OrganizationId2 = z58.string().uuid();
|
|
113914
|
+
var WorkspaceId = z58.string().uuid();
|
|
113915
|
+
var MembershipId = z58.string().uuid();
|
|
113916
|
+
var InvitationId = z58.string().uuid();
|
|
113724
113917
|
async function requirePrivateSessionAdministrator(context, deps, organizationId2) {
|
|
113725
113918
|
const agent = agentActingAsPerson(
|
|
113726
113919
|
context,
|
|
@@ -113819,7 +114012,7 @@ function parseId(schema, value, label) {
|
|
|
113819
114012
|
return parsed.data;
|
|
113820
114013
|
}
|
|
113821
114014
|
function rethrowMembershipError(error, resourceLimitMessage) {
|
|
113822
|
-
const sqlState =
|
|
114015
|
+
const sqlState = nestedPostgresSqlState15(error);
|
|
113823
114016
|
if (sqlState === "54000" && resourceLimitMessage) {
|
|
113824
114017
|
throw new HTTPException111(409, {
|
|
113825
114018
|
message: resourceLimitMessage
|
|
@@ -113881,6 +114074,7 @@ function registerOrganizationMembershipRoutes(app, deps) {
|
|
|
113881
114074
|
subjectId,
|
|
113882
114075
|
subjectLabel: session.user.email || session.user.name,
|
|
113883
114076
|
...payload,
|
|
114077
|
+
trialCreditModelIds: signupCreditModelIds(deps.settings),
|
|
113884
114078
|
trialCreditsEnabled: deps.settings.productAccessMode === "managed" && deps.settings.verifiedSignupTrialCreditsEnabled
|
|
113885
114079
|
})
|
|
113886
114080
|
),
|
|
@@ -113924,7 +114118,7 @@ function registerOrganizationMembershipRoutes(app, deps) {
|
|
|
113924
114118
|
})
|
|
113925
114119
|
);
|
|
113926
114120
|
} catch (error) {
|
|
113927
|
-
if (
|
|
114121
|
+
if (nestedPostgresSqlState15(error) === "42501") {
|
|
113928
114122
|
throw new HTTPException111(403, {
|
|
113929
114123
|
message: "organization membership is not active"
|
|
113930
114124
|
});
|
|
@@ -114232,11 +114426,6 @@ function registerOrganizationMembershipRoutes(app, deps) {
|
|
|
114232
114426
|
)
|
|
114233
114427
|
);
|
|
114234
114428
|
} catch (error) {
|
|
114235
|
-
if (nestedPostgresSqlState14(error) === "55000") {
|
|
114236
|
-
throw new HTTPException111(409, {
|
|
114237
|
-
message: "private-session readiness is not activated for this organization"
|
|
114238
|
-
});
|
|
114239
|
-
}
|
|
114240
114429
|
rethrowMembershipError(error);
|
|
114241
114430
|
}
|
|
114242
114431
|
});
|
|
@@ -114584,13 +114773,13 @@ import {
|
|
|
114584
114773
|
SessionListCursorExpiredError as SessionListCursorExpiredError2
|
|
114585
114774
|
} from "@opengeni/db";
|
|
114586
114775
|
import { HTTPException as HTTPException112 } from "hono/http-exception";
|
|
114587
|
-
import { z as
|
|
114776
|
+
import { z as z59 } from "zod";
|
|
114588
114777
|
var ORGANIZATION_SESSION_LIST_MAX_WORKSPACE_READS = 25;
|
|
114589
|
-
var OrganizationId3 =
|
|
114590
|
-
var OrganizationSessionListCursorEnvelope =
|
|
114591
|
-
workspaceId:
|
|
114592
|
-
cursor:
|
|
114593
|
-
pinnedOffset:
|
|
114778
|
+
var OrganizationId3 = z59.string().uuid();
|
|
114779
|
+
var OrganizationSessionListCursorEnvelope = z59.object({
|
|
114780
|
+
workspaceId: z59.string().uuid(),
|
|
114781
|
+
cursor: z59.string().min(1).nullable(),
|
|
114782
|
+
pinnedOffset: z59.number().int().nonnegative().max(1e4).optional()
|
|
114594
114783
|
}).strict();
|
|
114595
114784
|
function encodeOrganizationSessionListCursor(cursor) {
|
|
114596
114785
|
return Buffer.from(JSON.stringify(cursor)).toString("base64url");
|
|
@@ -114818,9 +115007,9 @@ import {
|
|
|
114818
115007
|
startOrganizationRecoveryOperation
|
|
114819
115008
|
} from "@opengeni/db";
|
|
114820
115009
|
import { HTTPException as HTTPException113 } from "hono/http-exception";
|
|
114821
|
-
import { z as
|
|
114822
|
-
var OrganizationId4 =
|
|
114823
|
-
var RecoveryOperationId =
|
|
115010
|
+
import { z as z60 } from "zod";
|
|
115011
|
+
var OrganizationId4 = z60.string().uuid();
|
|
115012
|
+
var RecoveryOperationId = z60.string().uuid();
|
|
114824
115013
|
var productionServices = {
|
|
114825
115014
|
requireCanonicalHumanRequestIdentity: requireCanonicalHumanRequestIdentity3,
|
|
114826
115015
|
getManagedAuthRequestActorAdmissionStamp,
|
|
@@ -115057,6 +115246,7 @@ function registerOrganizationRecoveryRoutes(app, deps, services = productionServ
|
|
|
115057
115246
|
}
|
|
115058
115247
|
|
|
115059
115248
|
// src/routes/managed-onboarding.ts
|
|
115249
|
+
import { signupCreditModelIds as signupCreditModelIds2 } from "@opengeni/config";
|
|
115060
115250
|
import {
|
|
115061
115251
|
CompleteSelfServiceOrganizationSetupRequest,
|
|
115062
115252
|
CompleteSelfServiceOrganizationSetupResponse,
|
|
@@ -115071,7 +115261,7 @@ import {
|
|
|
115071
115261
|
completeSelfServiceOrganizationSetup,
|
|
115072
115262
|
completeOrganizationUserSetup,
|
|
115073
115263
|
getSelfServiceOrganizationOnboardingState,
|
|
115074
|
-
nestedPostgresSqlState as
|
|
115264
|
+
nestedPostgresSqlState as nestedPostgresSqlState16,
|
|
115075
115265
|
preflightOrganizationUserSetup,
|
|
115076
115266
|
previewOrganizationUserSetup,
|
|
115077
115267
|
recordOrganizationSignupUseCase
|
|
@@ -115117,6 +115307,7 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
115117
115307
|
organizationName,
|
|
115118
115308
|
operationId: parsed.data.operationId,
|
|
115119
115309
|
requestFingerprint,
|
|
115310
|
+
trialCreditModelIds: signupCreditModelIds2(deps.settings),
|
|
115120
115311
|
trialCreditsEnabled: deps.settings.productAccessMode === "managed" && deps.settings.verifiedSignupTrialCreditsEnabled
|
|
115121
115312
|
})
|
|
115122
115313
|
);
|
|
@@ -115128,14 +115319,14 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
115128
115319
|
useCase: parsed.data.useCase
|
|
115129
115320
|
}).catch((error) => {
|
|
115130
115321
|
console.warn("[api] could not record the signup use case", {
|
|
115131
|
-
sqlState:
|
|
115322
|
+
sqlState: nestedPostgresSqlState16(error) ?? null
|
|
115132
115323
|
});
|
|
115133
115324
|
});
|
|
115134
115325
|
}
|
|
115135
115326
|
return context.json(completed);
|
|
115136
115327
|
} catch (error) {
|
|
115137
115328
|
recordOrganizationSetupOutcome(deps.observability, "failed");
|
|
115138
|
-
const sqlState =
|
|
115329
|
+
const sqlState = nestedPostgresSqlState16(error);
|
|
115139
115330
|
if (sqlState === "22023") {
|
|
115140
115331
|
throw new HTTPException114(422, {
|
|
115141
115332
|
message: "invalid organization setup request"
|
|
@@ -115215,7 +115406,7 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
115215
115406
|
)
|
|
115216
115407
|
);
|
|
115217
115408
|
} catch (error) {
|
|
115218
|
-
const sqlState =
|
|
115409
|
+
const sqlState = nestedPostgresSqlState16(error);
|
|
115219
115410
|
if (sqlState === "22023") {
|
|
115220
115411
|
throw new HTTPException114(422, {
|
|
115221
115412
|
message: "invalid account setup request"
|
|
@@ -115336,9 +115527,9 @@ import {
|
|
|
115336
115527
|
SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError15,
|
|
115337
115528
|
SessionTenancyManagedHumanRequiredError as SessionTenancyManagedHumanRequiredError3
|
|
115338
115529
|
} from "@opengeni/core";
|
|
115339
|
-
import { nestedPostgresSqlState as
|
|
115530
|
+
import { nestedPostgresSqlState as nestedPostgresSqlState17, SessionTenancyNotActivatedError as SessionTenancyNotActivatedError3 } from "@opengeni/db";
|
|
115340
115531
|
import { HTTPException as HTTPException115 } from "hono/http-exception";
|
|
115341
|
-
import { z as
|
|
115532
|
+
import { z as z61 } from "zod";
|
|
115342
115533
|
async function body2(context, schema) {
|
|
115343
115534
|
const parsed = schema.safeParse(await context.req.json().catch(() => null));
|
|
115344
115535
|
if (!parsed.success) throw new HTTPException115(422, { message: "invalid user-resource request" });
|
|
@@ -115351,10 +115542,10 @@ function lifecycleError(error) {
|
|
|
115351
115542
|
if (error instanceof SessionAuthorizationUnavailableError15) {
|
|
115352
115543
|
throw new HTTPException115(503, { message: "session authorization unavailable" });
|
|
115353
115544
|
}
|
|
115354
|
-
if (
|
|
115545
|
+
if (nestedPostgresSqlState17(error) === "42501") {
|
|
115355
115546
|
throw new HTTPException115(403, { message: "user-resource authority denied" });
|
|
115356
115547
|
}
|
|
115357
|
-
if (
|
|
115548
|
+
if (nestedPostgresSqlState17(error) === "22023") {
|
|
115358
115549
|
throw new HTTPException115(422, { message: "invalid user-resource request" });
|
|
115359
115550
|
}
|
|
115360
115551
|
throw error;
|
|
@@ -115395,7 +115586,7 @@ function registerUserResourceAuthorityRoutes(app, deps) {
|
|
|
115395
115586
|
});
|
|
115396
115587
|
app.post(`${base}/:authorityId/grants`, async (context) => {
|
|
115397
115588
|
const workspaceId = context.req.param("workspaceId");
|
|
115398
|
-
const authorityId =
|
|
115589
|
+
const authorityId = z61.string().uuid().safeParse(context.req.param("authorityId"));
|
|
115399
115590
|
if (!authorityId.success) throw new HTTPException115(422, { message: "invalid authority id" });
|
|
115400
115591
|
const request = await body2(context, IssueUserResourceGrantRequest);
|
|
115401
115592
|
const access = await requireAccessGrantAuthorization39(
|
|
@@ -115425,7 +115616,7 @@ function registerUserResourceAuthorityRoutes(app, deps) {
|
|
|
115425
115616
|
app.delete(`${base}/grants/:grantId`, async (context) => {
|
|
115426
115617
|
const query = RevokeUserResourceGrantQuery.safeParse({ scope: context.req.query("scope") });
|
|
115427
115618
|
if (!query.success) throw new HTTPException115(422, { message: "explicit scope=user required" });
|
|
115428
|
-
const grantId =
|
|
115619
|
+
const grantId = z61.string().uuid().safeParse(context.req.param("grantId"));
|
|
115429
115620
|
if (!grantId.success) throw new HTTPException115(422, { message: "invalid grant id" });
|
|
115430
115621
|
const workspaceId = context.req.param("workspaceId");
|
|
115431
115622
|
const access = await requireAccessGrantAuthorization39(
|
|
@@ -116432,14 +116623,14 @@ function resolveSlackWorkspaceRoute(input) {
|
|
|
116432
116623
|
source: "thread"
|
|
116433
116624
|
};
|
|
116434
116625
|
}
|
|
116435
|
-
const
|
|
116436
|
-
if (
|
|
116437
|
-
const named = matchCandidate(candidates,
|
|
116626
|
+
const prefix2 = AUTHORED_BY_INVOKER.has(input.entry.triggerKind) ? parseSlackWorkspacePrefix(splitSlackLeadingMention(input.entry.text, input.botUserId).rest) : null;
|
|
116627
|
+
if (prefix2) {
|
|
116628
|
+
const named = matchCandidate(candidates, prefix2.requested);
|
|
116438
116629
|
if (named === "ambiguous" || !named) {
|
|
116439
116630
|
return {
|
|
116440
116631
|
kind: "denied",
|
|
116441
116632
|
reason: "no_access_to_named",
|
|
116442
|
-
requested:
|
|
116633
|
+
requested: prefix2.requested,
|
|
116443
116634
|
candidates
|
|
116444
116635
|
};
|
|
116445
116636
|
}
|
|
@@ -122068,7 +122259,8 @@ function createAppComposition(deps) {
|
|
|
122068
122259
|
await next();
|
|
122069
122260
|
return;
|
|
122070
122261
|
}
|
|
122071
|
-
const
|
|
122262
|
+
const permission = c.req.method === "PUT" && /^\/v1\/workspaces\/[^/]+\/artifact-catalog\/[^/]+\/[^/]+\/pin$/.test(c.req.path) ? "artifacts:publish" : void 0;
|
|
122263
|
+
const grant = await requireAccessGrant53(c, routeDeps, workspaceId, permission);
|
|
122072
122264
|
await withAccessGrantSessionRlsContext(routeDeps, grant, next);
|
|
122073
122265
|
});
|
|
122074
122266
|
app.all("/v1/workspaces/:workspaceId/mcp", async (c) => {
|
|
@@ -122315,10 +122507,10 @@ function createAppComposition(deps) {
|
|
|
122315
122507
|
const workspaceId = c.req.param("workspaceId");
|
|
122316
122508
|
const grant = await requireAccessGrant53(c, routeDeps, workspaceId);
|
|
122317
122509
|
const url = new URL(c.req.url);
|
|
122318
|
-
const
|
|
122510
|
+
const prefix2 = `/v1/workspaces/${workspaceId}/codemode/sdk`;
|
|
122319
122511
|
let forwarded;
|
|
122320
122512
|
try {
|
|
122321
|
-
const path = url.pathname.slice(
|
|
122513
|
+
const path = url.pathname.slice(prefix2.length) + url.search;
|
|
122322
122514
|
forwarded = await codemodeSessionRequest(routeDeps, grant, c.req.raw, path, (session) => {
|
|
122323
122515
|
assertConfiguredCodemodeSessionProxyPath(session, path, c.req.method);
|
|
122324
122516
|
const proxyTools = configuredCodemodeSessionProxyTools(routeDeps.settings, session);
|
|
@@ -122938,7 +123130,7 @@ async function withTimeout(promise, timeoutMs) {
|
|
|
122938
123130
|
}
|
|
122939
123131
|
var routeLabelPatterns = [
|
|
122940
123132
|
{
|
|
122941
|
-
pattern: /^\/\.well-known\/oauth-authorization-server
|
|
123133
|
+
pattern: /^\/\.well-known\/oauth-authorization-server(?:\/.*)?$/,
|
|
122942
123134
|
label: "/.well-known/oauth-authorization-server"
|
|
122943
123135
|
},
|
|
122944
123136
|
{
|
|
@@ -123945,4 +124137,4 @@ export {
|
|
|
123945
124137
|
withDefaultEnabledCapabilityMcpTools,
|
|
123946
124138
|
workflowIdForSession4 as workflowIdForSession
|
|
123947
124139
|
};
|
|
123948
|
-
//# sourceMappingURL=chunk-
|
|
124140
|
+
//# sourceMappingURL=chunk-BAZXDFT2.js.map
|