@opengeni/api-router 2.3.2-canary.2 → 2.4.2-canary.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/auth/managed-auth-attempt-context.d.ts +4 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +4 -0
- package/dist/{chunk-IBV7Z6F4.js → chunk-L7GVVSSQ.js} +2996 -373
- package/dist/chunk-L7GVVSSQ.js.map +1 -0
- package/dist/fatal-process-boundary.d.ts +25 -0
- package/dist/http/sse.d.ts +2 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +168 -6
- package/dist/index.js.map +1 -1
- package/dist/mcp/receipts.d.ts +9 -0
- package/dist/organization-recovery-notifications.d.ts +41 -0
- package/dist/routes/managed-auth-session-sets.d.ts +19 -0
- package/dist/routes/organization-recovery.d.ts +19 -0
- package/dist/routes/workspaces.d.ts +1 -0
- package/package.json +18 -18
- package/src/app.ts +133 -1
- package/src/auth/managed-auth-attempt-context.ts +24 -0
- package/src/auth/managed-auth-session-adapter.ts +205 -0
- package/src/auth/managed-auth.ts +52 -2
- package/src/fatal-process-boundary.ts +231 -0
- package/src/http/sse.ts +7 -0
- package/src/index.ts +25 -5
- package/src/integrations/slack-interactions.ts +30 -17
- package/src/mcp/receipts.ts +34 -0
- package/src/mcp/server.ts +45 -39
- package/src/organization-recovery-notifications.ts +103 -0
- package/src/routes/canonical-human-identities.ts +29 -14
- package/src/routes/codex.ts +5 -1
- package/src/routes/environments.ts +23 -0
- package/src/routes/interaction-resources.ts +3 -0
- package/src/routes/managed-auth-session-sets.ts +994 -0
- package/src/routes/managed-onboarding.ts +2 -0
- package/src/routes/organization-memberships.ts +2 -0
- package/src/routes/organization-recovery.ts +325 -0
- package/src/routes/sessions.ts +24 -39
- package/src/routes/supergrok.ts +5 -1
- package/src/routes/workspaces.ts +23 -1
- package/dist/chunk-IBV7Z6F4.js.map +0 -1
package/src/mcp/server.ts
CHANGED
|
@@ -186,7 +186,7 @@ import {
|
|
|
186
186
|
import {
|
|
187
187
|
acceptSessionUserMessageWithOutcome,
|
|
188
188
|
controlAgentSessionWorkstream,
|
|
189
|
-
|
|
189
|
+
controlHumanSessionWorkstreamWithOutcome,
|
|
190
190
|
createSessionForRequestWithOutcome,
|
|
191
191
|
SessionSpawnDeniedError,
|
|
192
192
|
sessionSpawnDenialEnvelope,
|
|
@@ -223,7 +223,11 @@ import {
|
|
|
223
223
|
SESSION_WAIT_MAX_TARGETS,
|
|
224
224
|
waitForSessionChanges,
|
|
225
225
|
} from "./session-wait";
|
|
226
|
-
import {
|
|
226
|
+
import {
|
|
227
|
+
mcpMutationReceipt,
|
|
228
|
+
sessionControlMutationReceipt,
|
|
229
|
+
sessionCreateMutationReceipt,
|
|
230
|
+
} from "./receipts";
|
|
227
231
|
import {
|
|
228
232
|
boundScheduledTaskDetailMcp,
|
|
229
233
|
boundScheduledTaskMcpPage,
|
|
@@ -4537,27 +4541,18 @@ function registerWorkspaceOrchestrationTools(
|
|
|
4537
4541
|
controlled.authorization?.relatedSessionAccess ?? "root",
|
|
4538
4542
|
);
|
|
4539
4543
|
return json(
|
|
4540
|
-
|
|
4544
|
+
sessionControlMutationReceipt({
|
|
4541
4545
|
operation: "session_pause",
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
resource: {
|
|
4546
|
-
type: "session",
|
|
4547
|
-
id: sessionId,
|
|
4548
|
-
state: effectiveControl.state,
|
|
4549
|
-
},
|
|
4550
|
-
relatedResources: [{ type: "session_command_receipt", id: controlled.receipt.id }],
|
|
4546
|
+
sessionId,
|
|
4547
|
+
state: effectiveControl.state,
|
|
4548
|
+
receiptId: controlled.receipt.id,
|
|
4551
4549
|
timestamp: controlled.receipt.createdAt.toISOString(),
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
},
|
|
4555
|
-
facts: { interruptionCount: controlled.interruptionCount },
|
|
4556
|
-
nextAction: { tool: "session_get", arguments: { sessionId } },
|
|
4550
|
+
outcome: controlled.outcome,
|
|
4551
|
+
interruptionCount: controlled.interruptionCount,
|
|
4557
4552
|
}),
|
|
4558
4553
|
);
|
|
4559
4554
|
}
|
|
4560
|
-
const controlled = await
|
|
4555
|
+
const controlled = await controlHumanSessionWorkstreamWithOutcome(
|
|
4561
4556
|
deps,
|
|
4562
4557
|
{
|
|
4563
4558
|
accountId: grant.accountId,
|
|
@@ -4572,7 +4567,17 @@ function registerWorkspaceOrchestrationTools(
|
|
|
4572
4567
|
...(reason ? { reason } : {}),
|
|
4573
4568
|
},
|
|
4574
4569
|
);
|
|
4575
|
-
return json(
|
|
4570
|
+
return json(
|
|
4571
|
+
sessionControlMutationReceipt({
|
|
4572
|
+
operation: "session_pause",
|
|
4573
|
+
sessionId,
|
|
4574
|
+
state: controlled.response.effectiveControl.state,
|
|
4575
|
+
receiptId: controlled.response.receipt.id,
|
|
4576
|
+
timestamp: controlled.response.receipt.createdAt,
|
|
4577
|
+
outcome: controlled.outcome,
|
|
4578
|
+
interruptionCount: controlled.response.interruptionCount,
|
|
4579
|
+
}),
|
|
4580
|
+
);
|
|
4576
4581
|
},
|
|
4577
4582
|
);
|
|
4578
4583
|
|
|
@@ -4605,27 +4610,18 @@ function registerWorkspaceOrchestrationTools(
|
|
|
4605
4610
|
controlled.authorization?.relatedSessionAccess ?? "root",
|
|
4606
4611
|
);
|
|
4607
4612
|
return json(
|
|
4608
|
-
|
|
4613
|
+
sessionControlMutationReceipt({
|
|
4609
4614
|
operation: "session_resume",
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
resource: {
|
|
4614
|
-
type: "session",
|
|
4615
|
-
id: sessionId,
|
|
4616
|
-
state: effectiveControl.state,
|
|
4617
|
-
},
|
|
4618
|
-
relatedResources: [{ type: "session_command_receipt", id: controlled.receipt.id }],
|
|
4615
|
+
sessionId,
|
|
4616
|
+
state: effectiveControl.state,
|
|
4617
|
+
receiptId: controlled.receipt.id,
|
|
4619
4618
|
timestamp: controlled.receipt.createdAt.toISOString(),
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
},
|
|
4623
|
-
facts: { interruptionCount: controlled.interruptionCount },
|
|
4624
|
-
nextAction: { tool: "session_get", arguments: { sessionId } },
|
|
4619
|
+
outcome: controlled.outcome,
|
|
4620
|
+
interruptionCount: controlled.interruptionCount,
|
|
4625
4621
|
}),
|
|
4626
4622
|
);
|
|
4627
4623
|
}
|
|
4628
|
-
const controlled = await
|
|
4624
|
+
const controlled = await controlHumanSessionWorkstreamWithOutcome(
|
|
4629
4625
|
deps,
|
|
4630
4626
|
{
|
|
4631
4627
|
accountId: grant.accountId,
|
|
@@ -4640,7 +4636,17 @@ function registerWorkspaceOrchestrationTools(
|
|
|
4640
4636
|
...(reason ? { reason } : {}),
|
|
4641
4637
|
},
|
|
4642
4638
|
);
|
|
4643
|
-
return json(
|
|
4639
|
+
return json(
|
|
4640
|
+
sessionControlMutationReceipt({
|
|
4641
|
+
operation: "session_resume",
|
|
4642
|
+
sessionId,
|
|
4643
|
+
state: controlled.response.effectiveControl.state,
|
|
4644
|
+
receiptId: controlled.response.receipt.id,
|
|
4645
|
+
timestamp: controlled.response.receipt.createdAt,
|
|
4646
|
+
outcome: controlled.outcome,
|
|
4647
|
+
interruptionCount: controlled.response.interruptionCount,
|
|
4648
|
+
}),
|
|
4649
|
+
);
|
|
4644
4650
|
},
|
|
4645
4651
|
);
|
|
4646
4652
|
|
|
@@ -4741,13 +4747,13 @@ function registerWorkspaceOrchestrationTools(
|
|
|
4741
4747
|
});
|
|
4742
4748
|
}
|
|
4743
4749
|
if (accepted.action === "conflict") {
|
|
4744
|
-
throw new Error(
|
|
4750
|
+
throw new Error("human-input request is not currently actionable");
|
|
4745
4751
|
}
|
|
4746
4752
|
return json(
|
|
4747
4753
|
mcpMutationReceipt({
|
|
4748
4754
|
operation: "session_human_input_respond",
|
|
4749
4755
|
committed: true,
|
|
4750
|
-
outcome: accepted.
|
|
4756
|
+
outcome: accepted.action === "completed" ? "replayed" : "updated",
|
|
4751
4757
|
changed: accepted.events.length > 0,
|
|
4752
4758
|
resource: {
|
|
4753
4759
|
type: "session_human_input_request",
|
|
@@ -4757,7 +4763,7 @@ function registerWorkspaceOrchestrationTools(
|
|
|
4757
4763
|
relatedResources: [{ type: "session", id: sessionId }],
|
|
4758
4764
|
timestamp: accepted.request.respondedAt ?? new Date().toISOString(),
|
|
4759
4765
|
idempotency: {
|
|
4760
|
-
status: accepted.
|
|
4766
|
+
status: accepted.action === "completed" ? "replayed" : "applied",
|
|
4761
4767
|
},
|
|
4762
4768
|
facts: { outcome: accepted.request.response?.outcome ?? null },
|
|
4763
4769
|
nextAction: { tool: "session_get", arguments: { sessionId } },
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { Database } from "@opengeni/db";
|
|
2
|
+
import {
|
|
3
|
+
prepareOrganizationRecoveryNotifications,
|
|
4
|
+
settleOrganizationRecoveryNotification,
|
|
5
|
+
type OrganizationRecoveryNotificationClaim,
|
|
6
|
+
type OrganizationRecoveryNotificationSettlement,
|
|
7
|
+
} from "@opengeni/db";
|
|
8
|
+
|
|
9
|
+
export type OrganizationRecoveryNotificationDeliveryResult =
|
|
10
|
+
| { status: "sent"; providerMessageId: string | null }
|
|
11
|
+
| { status: "failed"; errorClass: string }
|
|
12
|
+
| { status: "outcome_unknown" };
|
|
13
|
+
|
|
14
|
+
export interface OrganizationRecoveryNotificationTransport {
|
|
15
|
+
readonly provider: string;
|
|
16
|
+
send(
|
|
17
|
+
claim: OrganizationRecoveryNotificationClaim,
|
|
18
|
+
): Promise<OrganizationRecoveryNotificationDeliveryResult>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type OrganizationRecoveryNotificationLifecycle = {
|
|
22
|
+
prepare: typeof prepareOrganizationRecoveryNotifications;
|
|
23
|
+
settle: typeof settleOrganizationRecoveryNotification;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const productionLifecycle: OrganizationRecoveryNotificationLifecycle = {
|
|
27
|
+
prepare: prepareOrganizationRecoveryNotifications,
|
|
28
|
+
settle: settleOrganizationRecoveryNotification,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export async function dispatchOrganizationRecoveryNotifications(input: {
|
|
32
|
+
db: Database;
|
|
33
|
+
transport: OrganizationRecoveryNotificationTransport;
|
|
34
|
+
claimOwner: string;
|
|
35
|
+
limit?: number;
|
|
36
|
+
leaseSeconds?: number;
|
|
37
|
+
lifecycle?: OrganizationRecoveryNotificationLifecycle;
|
|
38
|
+
}): Promise<OrganizationRecoveryNotificationSettlement[]> {
|
|
39
|
+
const lifecycle = input.lifecycle ?? productionLifecycle;
|
|
40
|
+
const claims = await lifecycle.prepare(input.db, {
|
|
41
|
+
provider: input.transport.provider,
|
|
42
|
+
claimOwner: input.claimOwner,
|
|
43
|
+
limit: input.limit ?? 25,
|
|
44
|
+
leaseSeconds: input.leaseSeconds ?? 60,
|
|
45
|
+
});
|
|
46
|
+
return await Promise.all(
|
|
47
|
+
claims.map(async (claim) => {
|
|
48
|
+
let result: OrganizationRecoveryNotificationDeliveryResult;
|
|
49
|
+
try {
|
|
50
|
+
result = await input.transport.send(claim);
|
|
51
|
+
} catch {
|
|
52
|
+
// The provider may have accepted the stable idempotency key before the
|
|
53
|
+
// transport failed. Preserve ambiguity for explicit reconciliation.
|
|
54
|
+
result = { status: "outcome_unknown" };
|
|
55
|
+
}
|
|
56
|
+
return await lifecycle.settle(input.db, {
|
|
57
|
+
outboxId: claim.outboxId,
|
|
58
|
+
deliveryId: claim.deliveryId,
|
|
59
|
+
claimOwner: claim.claimOwner,
|
|
60
|
+
phase: result.status,
|
|
61
|
+
...(result.status === "sent" ? { providerMessageId: result.providerMessageId } : {}),
|
|
62
|
+
...(result.status === "failed" ? { errorClass: result.errorClass } : {}),
|
|
63
|
+
});
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class InMemoryOrganizationRecoveryNotificationTransport implements OrganizationRecoveryNotificationTransport {
|
|
69
|
+
readonly provider = "fake";
|
|
70
|
+
readonly attempts: Array<{
|
|
71
|
+
idempotencyKey: string;
|
|
72
|
+
payloadDigest: string;
|
|
73
|
+
recipientCanonicalIdentityId: string;
|
|
74
|
+
providerMessageId: string;
|
|
75
|
+
}> = [];
|
|
76
|
+
private readonly deliveries = new Map<string, string>();
|
|
77
|
+
private readonly scripted: OrganizationRecoveryNotificationDeliveryResult[] = [];
|
|
78
|
+
|
|
79
|
+
enqueue(...results: OrganizationRecoveryNotificationDeliveryResult[]): void {
|
|
80
|
+
this.scripted.push(...results);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
logicalDeliveryCount(): number {
|
|
84
|
+
return this.deliveries.size;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async send(
|
|
88
|
+
claim: OrganizationRecoveryNotificationClaim,
|
|
89
|
+
): Promise<OrganizationRecoveryNotificationDeliveryResult> {
|
|
90
|
+
const scripted = this.scripted.shift();
|
|
91
|
+
if (scripted) return scripted;
|
|
92
|
+
const providerMessageId =
|
|
93
|
+
this.deliveries.get(claim.idempotencyKey) ?? `fake:${crypto.randomUUID()}`;
|
|
94
|
+
this.deliveries.set(claim.idempotencyKey, providerMessageId);
|
|
95
|
+
this.attempts.push({
|
|
96
|
+
idempotencyKey: claim.idempotencyKey,
|
|
97
|
+
payloadDigest: claim.payloadDigest,
|
|
98
|
+
recipientCanonicalIdentityId: claim.recipientCanonicalIdentityId,
|
|
99
|
+
providerMessageId,
|
|
100
|
+
});
|
|
101
|
+
return { status: "sent", providerMessageId };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -5,7 +5,11 @@ import {
|
|
|
5
5
|
CanonicalHumanIdentityProjection,
|
|
6
6
|
LinkCanonicalHumanLoginBindingRequest,
|
|
7
7
|
} from "@opengeni/contracts/canonical-human-identities";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getManagedAuthRequestActorLeaseStamp,
|
|
10
|
+
markManagedAuthRequestActorTransitionApplied,
|
|
11
|
+
requireCanonicalHumanRequestIdentity,
|
|
12
|
+
} from "@opengeni/core/canonical-human-identities";
|
|
9
13
|
import type { ApiRouteDeps } from "@opengeni/core";
|
|
10
14
|
import {
|
|
11
15
|
applyCanonicalHumanIdentityOperation,
|
|
@@ -13,6 +17,7 @@ import {
|
|
|
13
17
|
CanonicalHumanIdentityConflictError,
|
|
14
18
|
CanonicalHumanIdentityNotFoundError,
|
|
15
19
|
CanonicalHumanIdentityOperationReuseError,
|
|
20
|
+
CanonicalHumanIdentityMutationInFlightError,
|
|
16
21
|
getCanonicalHumanIdentityProjection,
|
|
17
22
|
} from "@opengeni/db/canonical-human-identities";
|
|
18
23
|
import type { Context, Hono } from "hono";
|
|
@@ -25,6 +30,8 @@ async function requestIdentity(context: Context, deps: ApiRouteDeps) {
|
|
|
25
30
|
return await requireCanonicalHumanRequestIdentity(context, {
|
|
26
31
|
db: deps.db,
|
|
27
32
|
...(deps.managedAuth === undefined ? {} : { managedAuth: deps.managedAuth }),
|
|
33
|
+
managedAuthSessionAdapter: deps.managedAuthSessionAdapter,
|
|
34
|
+
managedAuthSessionSetMode: deps.settings.managedAuthSessionSetMode,
|
|
28
35
|
allowRecovery: true,
|
|
29
36
|
});
|
|
30
37
|
}
|
|
@@ -50,6 +57,9 @@ function identityError(context: Context, error: unknown): Response {
|
|
|
50
57
|
if (error instanceof CanonicalHumanIdentityOperationReuseError) {
|
|
51
58
|
return context.json({ code: error.code, message: error.message }, 409);
|
|
52
59
|
}
|
|
60
|
+
if (error instanceof CanonicalHumanIdentityMutationInFlightError) {
|
|
61
|
+
return context.json({ code: error.code, message: error.message, retryable: true }, 409);
|
|
62
|
+
}
|
|
53
63
|
if (error instanceof CanonicalHumanIdentityNotFoundError) {
|
|
54
64
|
return context.json(
|
|
55
65
|
{ code: "CANONICAL_HUMAN_IDENTITY_NOT_FOUND", message: error.message },
|
|
@@ -79,21 +89,26 @@ async function mutate(
|
|
|
79
89
|
},
|
|
80
90
|
): Promise<Response> {
|
|
81
91
|
const identity = await requestIdentity(context, deps);
|
|
92
|
+
const actorFence = getManagedAuthRequestActorLeaseStamp(context.req.raw);
|
|
93
|
+
if (deps.settings.managedAuthSessionSetMode !== "legacy" && !actorFence) {
|
|
94
|
+
throw new HTTPException(409, { message: "Managed actor mutation fence is unavailable" });
|
|
95
|
+
}
|
|
82
96
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
),
|
|
97
|
+
const response = CanonicalHumanIdentityMutationResponse.parse(
|
|
98
|
+
await applyCanonicalHumanIdentityOperation(deps.db, {
|
|
99
|
+
operationId: input.operationId,
|
|
100
|
+
authUserId: identity.authUserId,
|
|
101
|
+
expectedIdentityRevision: input.expectedIdentityRevision,
|
|
102
|
+
operationType: input.operationType,
|
|
103
|
+
...(input.bindingId ? { bindingId: input.bindingId } : {}),
|
|
104
|
+
...(input.providerId ? { providerId: input.providerId } : {}),
|
|
105
|
+
...(input.providerAccountId ? { providerAccountId: input.providerAccountId } : {}),
|
|
106
|
+
reason: input.reason,
|
|
107
|
+
...(actorFence ? { actorFence } : {}),
|
|
108
|
+
}),
|
|
96
109
|
);
|
|
110
|
+
if (actorFence) markManagedAuthRequestActorTransitionApplied(context.req.raw);
|
|
111
|
+
return context.json(response);
|
|
97
112
|
} catch (error) {
|
|
98
113
|
return identityError(context, error);
|
|
99
114
|
}
|
package/src/routes/codex.ts
CHANGED
|
@@ -195,7 +195,11 @@ async function managedCookieHuman(
|
|
|
195
195
|
) {
|
|
196
196
|
return null;
|
|
197
197
|
}
|
|
198
|
-
const session = await getManagedSession(c, deps.managedAuth
|
|
198
|
+
const session = await getManagedSession(c, deps.managedAuth, {
|
|
199
|
+
db: deps.db,
|
|
200
|
+
sessionAdapter: deps.managedAuthSessionAdapter,
|
|
201
|
+
sessionSetMode: deps.settings.managedAuthSessionSetMode,
|
|
202
|
+
});
|
|
199
203
|
if (!session?.user?.id || !session.session?.id) return null;
|
|
200
204
|
return {
|
|
201
205
|
subjectId: `user:${session.user.id}`,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CreateVariableSetRequest,
|
|
3
|
+
ResolveVariableSetAttachmentsRequest,
|
|
4
|
+
ResolveVariableSetAttachmentsResponse,
|
|
3
5
|
SetVariableSetVariableRequest,
|
|
4
6
|
UpdateVariableSetRequest,
|
|
5
7
|
VariableSetVariableName,
|
|
@@ -14,6 +16,7 @@ import {
|
|
|
14
16
|
getVariableSetByName,
|
|
15
17
|
listVariableSets,
|
|
16
18
|
readVariableSetSecretAtomically,
|
|
19
|
+
resolveVariableSetAttachments,
|
|
17
20
|
setVariableSetVariable,
|
|
18
21
|
updateVariableSet,
|
|
19
22
|
VariableSetAttachedError,
|
|
@@ -135,6 +138,26 @@ export function registerVariableSetRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
135
138
|
return c.json(created, 201);
|
|
136
139
|
});
|
|
137
140
|
|
|
141
|
+
if (prefix.endsWith("/variable-sets")) {
|
|
142
|
+
app.post(`${prefix}/resolve-attachments`, async (c) => {
|
|
143
|
+
const workspaceId = c.req.param("workspaceId")!;
|
|
144
|
+
const grant = await requireAccessGrant(c, deps, workspaceId);
|
|
145
|
+
requirePermission(grant, "variable-sets:attach");
|
|
146
|
+
requirePermission(grant, "variable-sets:use");
|
|
147
|
+
const payload = ResolveVariableSetAttachmentsRequest.parse(await c.req.json());
|
|
148
|
+
const variableSets = await resolveVariableSetAttachments(
|
|
149
|
+
db,
|
|
150
|
+
{
|
|
151
|
+
accountId: grant.accountId,
|
|
152
|
+
workspaceId,
|
|
153
|
+
subjectId: grant.subjectId,
|
|
154
|
+
},
|
|
155
|
+
payload.variableSetIds,
|
|
156
|
+
);
|
|
157
|
+
return c.json(ResolveVariableSetAttachmentsResponse.parse({ variableSets }));
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
138
161
|
app.get(`${prefix}/:variableSetId`, async (c) => {
|
|
139
162
|
const workspaceId = c.req.param("workspaceId")!;
|
|
140
163
|
const grant = await requireAccessGrant(c, deps, workspaceId);
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
updateSiteAuthConnection,
|
|
46
46
|
} from "@opengeni/db";
|
|
47
47
|
import {
|
|
48
|
+
getManagedAuthRequestActorEpoch,
|
|
48
49
|
SessionAuthorizationDeniedError,
|
|
49
50
|
SessionAuthorizationUnavailableError,
|
|
50
51
|
requireAccessGrant,
|
|
@@ -74,6 +75,7 @@ export function registerInteractionResourceRoutes(app: Hono, deps: ApiRouteDeps)
|
|
|
74
75
|
context.req.raw.signal,
|
|
75
76
|
{
|
|
76
77
|
observability: deps.observability,
|
|
78
|
+
actorEpoch: getManagedAuthRequestActorEpoch(context.req.raw) ?? undefined,
|
|
77
79
|
reauthorize: async () => {
|
|
78
80
|
const freshGrant = await requireFreshAccessGrant(
|
|
79
81
|
context,
|
|
@@ -98,6 +100,7 @@ export function registerInteractionResourceRoutes(app: Hono, deps: ApiRouteDeps)
|
|
|
98
100
|
context.req.raw.signal,
|
|
99
101
|
{
|
|
100
102
|
observability: deps.observability,
|
|
103
|
+
actorEpoch: getManagedAuthRequestActorEpoch(context.req.raw) ?? undefined,
|
|
101
104
|
reauthorize: async () => {
|
|
102
105
|
await requireFreshAccessGrant(context, deps, workspaceId, "sessions:read");
|
|
103
106
|
},
|