@opengeni/db 3.4.0-canary.2 → 3.6.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/canonical-human-identities.d.ts +20 -0
- package/dist/canonical-human-identities.js +7 -3
- package/dist/{chunk-ZWRIPCTR.js → chunk-2NT476HD.js} +2 -2
- package/dist/{chunk-PYMY3AJW.js → chunk-744DFC65.js} +202 -7
- package/dist/chunk-744DFC65.js.map +1 -0
- package/dist/{chunk-O6FTELKH.js → chunk-CDMMSUWJ.js} +3 -3
- package/dist/chunk-G3732M3T.js +299 -0
- package/dist/chunk-G3732M3T.js.map +1 -0
- package/dist/{chunk-TRBOWUG3.js → chunk-IW6O6G7R.js} +2 -2
- package/dist/{chunk-HY3F5Q4E.js → chunk-Q5YUGQVK.js} +3 -3
- package/dist/{chunk-V3TRUXFJ.js → chunk-UGDVSQ6U.js} +72 -19
- package/dist/chunk-UGDVSQ6U.js.map +1 -0
- package/dist/{chunk-C2AFP7SB.js → chunk-UJ2EW3QI.js} +6664 -6051
- package/dist/chunk-UJ2EW3QI.js.map +1 -0
- package/dist/{chunk-H7MXYG7R.js → chunk-WW7AJ5IC.js} +2 -2
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +44 -6
- package/dist/index.js +2914 -1535
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-set-schema.d.ts +1399 -0
- package/dist/managed-auth-session-sets.d.ts +145 -0
- package/dist/managed-auth-session-sets.js +50 -0
- package/dist/managed-auth-session-sets.js.map +1 -0
- package/dist/organization-recovery-schema.d.ts +2144 -0
- package/dist/organization-recovery.d.ts +186 -0
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +7 -4
- package/dist/schema.d.ts +9 -6
- package/dist/schema.js +43 -1
- package/dist/session-background-commands.js +3 -3
- package/dist/session-control.d.ts +5 -3
- package/dist/session-queue-commands.d.ts +2 -0
- package/dist/session-tenancy.js +3 -3
- package/dist/video-generation.js +3 -3
- package/dist/work-claims-schema.d.ts +975 -0
- package/dist/work-claims.d.ts +83 -0
- package/drizzle/0362_managed_auth_session_sets.sql +2347 -0
- package/drizzle/0363_organization_recovery_custody.sql +2418 -0
- package/drizzle/0364_workspace_learning_policy_snapshot_lock_order.sql +221 -0
- package/drizzle/0365_permission_scoped_work_claims.sql +1306 -0
- package/drizzle/0366_session_discovery_title_search_index.sql +5 -0
- package/drizzle/0367_session_discovery_goal_search_index.sql +5 -0
- package/drizzle/0368_session_discovery_claim_search_index.sql +6 -0
- package/package.json +10 -6
- package/src/canonical-human-identities.ts +105 -27
- package/src/index.ts +1471 -433
- package/src/managed-auth-session-set-schema.ts +176 -0
- package/src/managed-auth-session-sets.ts +430 -0
- package/src/organization-recovery-schema.ts +277 -0
- package/src/organization-recovery.ts +424 -0
- package/src/provision-roles.ts +67 -0
- package/src/runtime-posture.ts +144 -6
- package/src/schema.ts +3 -0
- package/src/session-control.ts +255 -16
- package/src/session-queue-commands.ts +10 -1
- package/src/session-tool-call-settlement.ts +6 -1
- package/src/work-claims-schema.ts +148 -0
- package/src/work-claims.ts +200 -0
- package/dist/chunk-C2AFP7SB.js.map +0 -1
- package/dist/chunk-PYMY3AJW.js.map +0 -1
- package/dist/chunk-V3TRUXFJ.js.map +0 -1
- /package/dist/{chunk-ZWRIPCTR.js.map → chunk-2NT476HD.js.map} +0 -0
- /package/dist/{chunk-O6FTELKH.js.map → chunk-CDMMSUWJ.js.map} +0 -0
- /package/dist/{chunk-TRBOWUG3.js.map → chunk-IW6O6G7R.js.map} +0 -0
- /package/dist/{chunk-HY3F5Q4E.js.map → chunk-Q5YUGQVK.js.map} +0 -0
- /package/dist/{chunk-H7MXYG7R.js.map → chunk-WW7AJ5IC.js.map} +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- opengeni:concurrent-index lock-timeout=5s
|
|
3
|
+
CREATE INDEX CONCURRENTLY IF NOT EXISTS session_work_claims_discovery_text_fts_idx
|
|
4
|
+
ON session_work_claims USING gin (
|
|
5
|
+
to_tsvector('simple', canonical_key || ' ' || coalesce(display_label, ''))
|
|
6
|
+
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/db",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "OpenGeni persistence: Drizzle schema, RLS-scoped query layer, the SQL migration runner, and role provisioning.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -51,6 +51,10 @@
|
|
|
51
51
|
"types": "./dist/canonical-human-identities.d.ts",
|
|
52
52
|
"import": "./dist/canonical-human-identities.js"
|
|
53
53
|
},
|
|
54
|
+
"./managed-auth-session-sets": {
|
|
55
|
+
"types": "./dist/managed-auth-session-sets.d.ts",
|
|
56
|
+
"import": "./dist/managed-auth-session-sets.js"
|
|
57
|
+
},
|
|
54
58
|
"./session-tenancy": {
|
|
55
59
|
"types": "./dist/session-tenancy.d.ts",
|
|
56
60
|
"import": "./dist/session-tenancy.js"
|
|
@@ -74,11 +78,11 @@
|
|
|
74
78
|
"prepublishOnly": "bash ../../scripts/prepublish-guard"
|
|
75
79
|
},
|
|
76
80
|
"dependencies": {
|
|
77
|
-
"@opengeni/codemode": "^0.4.
|
|
78
|
-
"@opengeni/codex": "^0.2.19
|
|
79
|
-
"@opengeni/config": "^0.
|
|
80
|
-
"@opengeni/contracts": "^2.
|
|
81
|
-
"@opengeni/network": "^0.2.3
|
|
81
|
+
"@opengeni/codemode": "^0.4.17",
|
|
82
|
+
"@opengeni/codex": "^0.2.19",
|
|
83
|
+
"@opengeni/config": "^0.22.0",
|
|
84
|
+
"@opengeni/contracts": "^2.7.0",
|
|
85
|
+
"@opengeni/network": "^0.2.3",
|
|
82
86
|
"drizzle-orm": "^0.45.2",
|
|
83
87
|
"postgres": "^3.4.7"
|
|
84
88
|
},
|
|
@@ -18,6 +18,37 @@ export type CanonicalHumanSessionAuthority = {
|
|
|
18
18
|
identityStatus: "active" | "recovery_required" | "disputed" | "disabled";
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
export type CanonicalHumanExactLoginBinding = {
|
|
22
|
+
id: string;
|
|
23
|
+
identityId: string;
|
|
24
|
+
revision: number;
|
|
25
|
+
status: "active" | "recovery_pending" | "stale" | "disputed" | "revoked";
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export async function getCanonicalHumanExactLoginBindingForAuthUser(
|
|
29
|
+
db: Database,
|
|
30
|
+
input: { authUserId: string; providerId: string },
|
|
31
|
+
): Promise<CanonicalHumanExactLoginBinding> {
|
|
32
|
+
const [row] = await rawRows<{
|
|
33
|
+
result:
|
|
34
|
+
| (Omit<CanonicalHumanExactLoginBinding, "revision"> & { revision: number | string })
|
|
35
|
+
| null;
|
|
36
|
+
}>(
|
|
37
|
+
db,
|
|
38
|
+
sql`
|
|
39
|
+
select get_canonical_human_exact_login_binding(
|
|
40
|
+
${input.authUserId}, ${input.providerId}
|
|
41
|
+
) as result
|
|
42
|
+
`,
|
|
43
|
+
);
|
|
44
|
+
if (!row?.result) {
|
|
45
|
+
throw new CanonicalHumanIdentityAuthorityError(
|
|
46
|
+
"Authentication did not prove exactly one canonical login binding",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return { ...row.result, revision: Number(row.result.revision) };
|
|
50
|
+
}
|
|
51
|
+
|
|
21
52
|
export class CanonicalHumanIdentityConflictError extends Error {
|
|
22
53
|
readonly name = "CanonicalHumanIdentityConflictError";
|
|
23
54
|
readonly code = "CANONICAL_HUMAN_IDENTITY_CONFLICT";
|
|
@@ -36,6 +67,15 @@ export class CanonicalHumanIdentityOperationReuseError extends Error {
|
|
|
36
67
|
}
|
|
37
68
|
}
|
|
38
69
|
|
|
70
|
+
export class CanonicalHumanIdentityMutationInFlightError extends Error {
|
|
71
|
+
readonly name = "CanonicalHumanIdentityMutationInFlightError";
|
|
72
|
+
readonly code = "CANONICAL_HUMAN_IDENTITY_MUTATION_IN_FLIGHT";
|
|
73
|
+
|
|
74
|
+
constructor() {
|
|
75
|
+
super("Another request is still using this browser actor");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
39
79
|
export class CanonicalHumanIdentityNotFoundError extends Error {
|
|
40
80
|
readonly name = "CanonicalHumanIdentityNotFoundError";
|
|
41
81
|
|
|
@@ -65,6 +105,7 @@ function mapSqlError(error: unknown): never {
|
|
|
65
105
|
const state = nestedPostgresSqlState(error);
|
|
66
106
|
if (state === "40001") throw new CanonicalHumanIdentityConflictError();
|
|
67
107
|
if (state === "23505") throw new CanonicalHumanIdentityOperationReuseError();
|
|
108
|
+
if (state === "55P03") throw new CanonicalHumanIdentityMutationInFlightError();
|
|
68
109
|
if (state === "P0002") throw new CanonicalHumanIdentityNotFoundError();
|
|
69
110
|
if (state === "42501") {
|
|
70
111
|
throw new CanonicalHumanIdentityAuthorityError(
|
|
@@ -111,6 +152,17 @@ export async function ensureCanonicalHumanIdentityForAuthUser(
|
|
|
111
152
|
db: Database,
|
|
112
153
|
authUserId: string,
|
|
113
154
|
): Promise<CanonicalHumanSessionAuthority> {
|
|
155
|
+
try {
|
|
156
|
+
const existing = await getCanonicalHumanIdentityProjection(db, authUserId);
|
|
157
|
+
return {
|
|
158
|
+
identityId: existing.activeIdentity.id,
|
|
159
|
+
identityRevision: existing.activeIdentity.identityRevision,
|
|
160
|
+
authRevision: existing.activeIdentity.authRevision,
|
|
161
|
+
identityStatus: existing.activeIdentity.status,
|
|
162
|
+
};
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (!(error instanceof CanonicalHumanIdentityNotFoundError)) throw error;
|
|
165
|
+
}
|
|
114
166
|
const [user] = await rawRows<{ displayName: string }>(
|
|
115
167
|
db,
|
|
116
168
|
sql`
|
|
@@ -264,6 +316,11 @@ export type ApplyCanonicalHumanIdentityOperationInput = {
|
|
|
264
316
|
providerId?: string | null;
|
|
265
317
|
providerAccountId?: string | null;
|
|
266
318
|
reason: string;
|
|
319
|
+
actorFence?: {
|
|
320
|
+
authorityHash: string;
|
|
321
|
+
actorEpoch: string;
|
|
322
|
+
requestId: string;
|
|
323
|
+
};
|
|
267
324
|
};
|
|
268
325
|
|
|
269
326
|
export async function applyCanonicalHumanIdentityOperation(
|
|
@@ -271,14 +328,46 @@ export async function applyCanonicalHumanIdentityOperation(
|
|
|
271
328
|
input: ApplyCanonicalHumanIdentityOperationInput,
|
|
272
329
|
): Promise<CanonicalHumanIdentityMutationResponseType> {
|
|
273
330
|
try {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
331
|
+
if (input.actorFence) {
|
|
332
|
+
return await db.transaction(async (tx) => {
|
|
333
|
+
const txDb = tx as unknown as Database;
|
|
334
|
+
await rawRows(
|
|
335
|
+
txDb,
|
|
336
|
+
sql`select managed_auth_actor_mutation_fence(
|
|
337
|
+
${input.actorFence!.authorityHash}, ${input.actorFence!.actorEpoch}::bigint,
|
|
338
|
+
${input.actorFence!.requestId}::uuid
|
|
339
|
+
)`,
|
|
340
|
+
);
|
|
341
|
+
return await applyCanonicalHumanIdentityOperationInner(txDb, input);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return await applyCanonicalHumanIdentityOperationInner(db, input);
|
|
345
|
+
} catch (error) {
|
|
346
|
+
if (
|
|
347
|
+
error instanceof CanonicalHumanIdentityConflictError ||
|
|
348
|
+
error instanceof CanonicalHumanIdentityOperationReuseError ||
|
|
349
|
+
error instanceof CanonicalHumanIdentityMutationInFlightError ||
|
|
350
|
+
error instanceof CanonicalHumanIdentityNotFoundError ||
|
|
351
|
+
error instanceof CanonicalHumanIdentityAuthorityError
|
|
352
|
+
) {
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
mapSqlError(error);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
async function applyCanonicalHumanIdentityOperationInner(
|
|
360
|
+
db: Database,
|
|
361
|
+
input: ApplyCanonicalHumanIdentityOperationInput,
|
|
362
|
+
): Promise<CanonicalHumanIdentityMutationResponseType> {
|
|
363
|
+
const [row] = await rawRows<{
|
|
364
|
+
outcome: CanonicalHumanIdentityMutationOutcome;
|
|
365
|
+
identityId: string;
|
|
366
|
+
identityRevision: number | string;
|
|
367
|
+
authRevision: number | string;
|
|
368
|
+
}>(
|
|
369
|
+
db,
|
|
370
|
+
sql`
|
|
282
371
|
select
|
|
283
372
|
outcome,
|
|
284
373
|
identity_id as "identityId",
|
|
@@ -295,23 +384,12 @@ export async function applyCanonicalHumanIdentityOperation(
|
|
|
295
384
|
${input.reason}
|
|
296
385
|
)
|
|
297
386
|
`,
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
} catch (error) {
|
|
307
|
-
if (
|
|
308
|
-
error instanceof CanonicalHumanIdentityConflictError ||
|
|
309
|
-
error instanceof CanonicalHumanIdentityOperationReuseError ||
|
|
310
|
-
error instanceof CanonicalHumanIdentityNotFoundError ||
|
|
311
|
-
error instanceof CanonicalHumanIdentityAuthorityError
|
|
312
|
-
) {
|
|
313
|
-
throw error;
|
|
314
|
-
}
|
|
315
|
-
mapSqlError(error);
|
|
316
|
-
}
|
|
387
|
+
);
|
|
388
|
+
if (!row) throw new CanonicalHumanIdentityNotFoundError();
|
|
389
|
+
const identity = await getCanonicalHumanIdentityProjection(db, input.authUserId);
|
|
390
|
+
return CanonicalHumanIdentityMutationResponse.parse({
|
|
391
|
+
outcome: row.outcome,
|
|
392
|
+
operationId: input.operationId,
|
|
393
|
+
identity,
|
|
394
|
+
});
|
|
317
395
|
}
|