@codemem/core 0.39.1 → 0.40.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/api-types.d.ts +35 -1
- package/dist/api-types.d.ts.map +1 -1
- package/dist/attribution-assessment.d.ts +78 -0
- package/dist/attribution-assessment.d.ts.map +1 -0
- package/dist/attribution-diagnostics.d.ts +53 -0
- package/dist/attribution-diagnostics.d.ts.map +1 -0
- package/dist/better-sqlite-coordinator-store.d.ts +6 -2
- package/dist/better-sqlite-coordinator-store.d.ts.map +1 -1
- package/dist/coordinator-actions.d.ts +81 -0
- package/dist/coordinator-actions.d.ts.map +1 -1
- package/dist/coordinator-api-DJVH2jw5.js +21107 -0
- package/dist/coordinator-api-DJVH2jw5.js.map +1 -0
- package/dist/coordinator-api.d.ts.map +1 -1
- package/dist/coordinator-enrollment-reconciler.d.ts +24 -0
- package/dist/coordinator-enrollment-reconciler.d.ts.map +1 -0
- package/dist/coordinator-enrollment-reconciliation-issues.d.ts +34 -0
- package/dist/coordinator-enrollment-reconciliation-issues.d.ts.map +1 -0
- package/dist/coordinator-invites.d.ts +14 -1
- package/dist/coordinator-invites.d.ts.map +1 -1
- package/dist/coordinator-membership-effects.d.ts +31 -0
- package/dist/coordinator-membership-effects.d.ts.map +1 -0
- package/dist/coordinator-runtime.d.ts +14 -0
- package/dist/coordinator-runtime.d.ts.map +1 -1
- package/dist/coordinator-store-contract.d.ts +134 -1
- package/dist/coordinator-store-contract.d.ts.map +1 -1
- package/dist/coordinator-store-test-harness.d.ts +4 -0
- package/dist/coordinator-store-test-harness.d.ts.map +1 -1
- package/dist/coordinator-store.d.ts +1 -1
- package/dist/coordinator-store.d.ts.map +1 -1
- package/dist/d1-coordinator-store.d.ts +6 -2
- package/dist/d1-coordinator-store.d.ts.map +1 -1
- package/dist/db.d.ts +2 -19
- package/dist/db.d.ts.map +1 -1
- package/dist/embeddings.d.ts +2 -0
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/extraction-benchmark-scoring.d.ts +99 -0
- package/dist/extraction-benchmark-scoring.d.ts.map +1 -0
- package/dist/extraction-benchmarks.d.ts +29 -0
- package/dist/extraction-benchmarks.d.ts.map +1 -1
- package/dist/extraction-eval.d.ts +5 -0
- package/dist/extraction-eval.d.ts.map +1 -1
- package/dist/extraction-model-pricing.d.ts +21 -0
- package/dist/extraction-model-pricing.d.ts.map +1 -0
- package/dist/extraction-replay.d.ts +30 -3
- package/dist/extraction-replay.d.ts.map +1 -1
- package/dist/extraction-tier-routing.d.ts.map +1 -1
- package/dist/index.d.ts +65 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10684 -18254
- package/dist/index.js.map +1 -1
- package/dist/ingest-pipeline.d.ts.map +1 -1
- package/dist/ingest-prompts.d.ts +5 -0
- package/dist/ingest-prompts.d.ts.map +1 -1
- package/dist/ingest-xml-parser.d.ts +21 -0
- package/dist/ingest-xml-parser.d.ts.map +1 -1
- package/dist/internal/cloudflare-coordinator.js +528 -213
- package/dist/internal/cloudflare-coordinator.js.map +1 -1
- package/dist/legacy-recipient-policy-projection.d.ts +122 -0
- package/dist/legacy-recipient-policy-projection.d.ts.map +1 -0
- package/dist/maintenance/relink.d.ts +1 -1
- package/dist/maintenance/relink.d.ts.map +1 -1
- package/dist/observer-client.d.ts +15 -6
- package/dist/observer-client.d.ts.map +1 -1
- package/dist/observer-config.d.ts +2 -0
- package/dist/observer-config.d.ts.map +1 -1
- package/dist/outcome-evidence.d.ts +193 -0
- package/dist/outcome-evidence.d.ts.map +1 -0
- package/dist/pack.d.ts +8 -0
- package/dist/pack.d.ts.map +1 -1
- package/dist/project-invite-acceptance.d.ts +10 -0
- package/dist/project-invite-acceptance.d.ts.map +1 -0
- package/dist/project-invite-identity.d.ts +14 -0
- package/dist/project-invite-identity.d.ts.map +1 -0
- package/dist/project-scope-settings.d.ts.map +1 -1
- package/dist/prompt-pack-ledger.d.ts +21 -0
- package/dist/prompt-pack-ledger.d.ts.map +1 -0
- package/dist/raw-event-flush.d.ts.map +1 -1
- package/dist/recipient-policy-contract.d.ts +153 -0
- package/dist/recipient-policy-contract.d.ts.map +1 -0
- package/dist/recipient-policy-edges.d.ts +85 -0
- package/dist/recipient-policy-edges.d.ts.map +1 -0
- package/dist/recipient-policy-intent.d.ts +12 -0
- package/dist/recipient-policy-intent.d.ts.map +1 -0
- package/dist/recipient-policy-migration.d.ts +22 -0
- package/dist/recipient-policy-migration.d.ts.map +1 -0
- package/dist/recipient-policy-onboarding.d.ts +111 -0
- package/dist/recipient-policy-onboarding.d.ts.map +1 -0
- package/dist/recipient-policy-reconciler.d.ts +83 -0
- package/dist/recipient-policy-reconciler.d.ts.map +1 -0
- package/dist/recipient-policy-reconciliation.d.ts +221 -0
- package/dist/recipient-policy-reconciliation.d.ts.map +1 -0
- package/dist/recipient-policy-review.d.ts +47 -0
- package/dist/recipient-policy-review.d.ts.map +1 -0
- package/dist/recipient-reviewed-intent.d.ts +63 -0
- package/dist/recipient-reviewed-intent.d.ts.map +1 -0
- package/dist/retrieval-ledger.d.ts +216 -0
- package/dist/retrieval-ledger.d.ts.map +1 -0
- package/dist/retrieval-surface-ledger.d.ts +17 -0
- package/dist/retrieval-surface-ledger.d.ts.map +1 -0
- package/dist/schema-bootstrap.d.ts +2 -0
- package/dist/schema-bootstrap.d.ts.map +1 -1
- package/dist/schema.d.ts +11830 -3158
- package/dist/schema.d.ts.map +1 -1
- package/dist/scope-membership-cache.d.ts +1 -1
- package/dist/scope-membership-cache.d.ts.map +1 -1
- package/dist/share-operation-lifecycle.d.ts +46 -0
- package/dist/share-operation-lifecycle.d.ts.map +1 -0
- package/dist/share-operation.d.ts +87 -0
- package/dist/share-operation.d.ts.map +1 -0
- package/dist/share-provisioning.d.ts +57 -0
- package/dist/share-provisioning.d.ts.map +1 -0
- package/dist/store.d.ts +9 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/sync-bootstrap.d.ts +3 -2
- package/dist/sync-bootstrap.d.ts.map +1 -1
- package/dist/sync-capability.d.ts +7 -0
- package/dist/sync-capability.d.ts.map +1 -1
- package/dist/sync-daemon.d.ts +14 -1
- package/dist/sync-daemon.d.ts.map +1 -1
- package/dist/sync-pass.d.ts +1 -0
- package/dist/sync-pass.d.ts.map +1 -1
- package/dist/sync-replication.d.ts +24 -0
- package/dist/sync-replication.d.ts.map +1 -1
- package/dist/sync-scope-protocol.d.ts.map +1 -1
- package/dist/test-schema.generated.d.ts +1 -1
- package/dist/test-schema.generated.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/coordinator-api-hZ1RVJUN.js +0 -2111
- package/dist/coordinator-api-hZ1RVJUN.js.map +0 -1
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Qa as e, Xa as t, ao as n, co as r, do as i, eo as a, fo as o, lo as s, ma as c, oo as l, po as u, qa as d, so as f, t as p, uo as m } from "../coordinator-api-DJVH2jw5.js";
|
|
2
2
|
//#region src/d1-coordinator-store.ts
|
|
3
|
-
function
|
|
3
|
+
function h(e) {
|
|
4
4
|
if (e == null) throw Error("expected row");
|
|
5
5
|
return e;
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function g(e) {
|
|
8
|
+
let { presence_capabilities_json: t, presence_expires_at: n, ...r } = h(e);
|
|
9
|
+
if (typeof n != "string" || typeof t != "string") return r;
|
|
10
|
+
try {
|
|
11
|
+
let e = JSON.parse(t);
|
|
12
|
+
if (!e || typeof e != "object" || Array.isArray(e)) return r;
|
|
13
|
+
let i = e;
|
|
14
|
+
return {
|
|
15
|
+
...r,
|
|
16
|
+
presence_expires_at: n,
|
|
17
|
+
presence_capabilities: {
|
|
18
|
+
sync_capability: i.sync_capability,
|
|
19
|
+
sync_features: i.sync_features
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
} catch {
|
|
23
|
+
return r;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function _(e) {
|
|
8
27
|
let t = e.trim();
|
|
9
28
|
if (!t) return "";
|
|
10
29
|
let n = t.includes("://") ? t : `http://${t}`;
|
|
@@ -15,7 +34,7 @@ function i(e) {
|
|
|
15
34
|
return "";
|
|
16
35
|
}
|
|
17
36
|
}
|
|
18
|
-
function
|
|
37
|
+
function v(e) {
|
|
19
38
|
if (!e) return "";
|
|
20
39
|
try {
|
|
21
40
|
let t = new URL(e), n = t.hostname.toLowerCase();
|
|
@@ -23,18 +42,18 @@ function a(e) {
|
|
|
23
42
|
} catch {}
|
|
24
43
|
return e;
|
|
25
44
|
}
|
|
26
|
-
function
|
|
45
|
+
function y(e, t) {
|
|
27
46
|
let n = [], r = /* @__PURE__ */ new Set();
|
|
28
|
-
for (let
|
|
29
|
-
let e = i
|
|
47
|
+
for (let i of [...e, ...t]) {
|
|
48
|
+
let e = _(i), t = v(e);
|
|
30
49
|
!e || r.has(t) || (r.add(t), n.push(e));
|
|
31
50
|
}
|
|
32
51
|
return n;
|
|
33
52
|
}
|
|
34
|
-
function
|
|
53
|
+
function b() {
|
|
35
54
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
36
55
|
}
|
|
37
|
-
function
|
|
56
|
+
function x(e, t) {
|
|
38
57
|
return e <= t ? {
|
|
39
58
|
low: e,
|
|
40
59
|
high: t
|
|
@@ -43,17 +62,22 @@ function c(e, t) {
|
|
|
43
62
|
high: e
|
|
44
63
|
};
|
|
45
64
|
}
|
|
46
|
-
function
|
|
65
|
+
function S(e) {
|
|
47
66
|
return e instanceof Error && /unique|constraint/i.test(e.message);
|
|
48
67
|
}
|
|
49
|
-
function
|
|
68
|
+
function C(e) {
|
|
50
69
|
let t = new Uint8Array(e);
|
|
51
70
|
globalThis.crypto.getRandomValues(t);
|
|
52
71
|
let n = [];
|
|
53
72
|
for (let e of t) n.push("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"[e % 64] ?? "A");
|
|
54
73
|
return n.join("");
|
|
55
74
|
}
|
|
56
|
-
function
|
|
75
|
+
async function w(e) {
|
|
76
|
+
let t = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(e));
|
|
77
|
+
return Array.from(new Uint8Array(t), (e) => e.toString(16).padStart(2, "0")).join("");
|
|
78
|
+
}
|
|
79
|
+
var T = "invite_id, group_id, token, policy, expires_at, created_at, created_by,\n team_name_snapshot, revoked_at, operation_id, reviewed_project_set_digest, token_digest,\n inviter_actor_id, inviter_display_name, inviter_device_id, pending_person_id,\n project_summaries_json, project_intent_json, consumed_at, bound_device_id, bound_public_key, bound_fingerprint,\n recipient_actor_id, recipient_display_name, recipient_device_display_name, trust_state,\n bootstrap_grant_id, invite_kind, policy_team_id, target_identity_id, assigned_identity_id,\n reviewed_preview_digest, reviewed_intent_json", E = "group_id, device_id, public_key, fingerprint, identity_id, display_name, enabled, created_at", D = "enrolled_devices.group_id, enrolled_devices.device_id,\n enrolled_devices.public_key, enrolled_devices.fingerprint, enrolled_devices.identity_id,\n enrolled_devices.display_name, enrolled_devices.enabled, enrolled_devices.created_at,\n presence_records.expires_at AS presence_expires_at,\n presence_records.capabilities_json AS presence_capabilities_json";
|
|
80
|
+
function O(e) {
|
|
57
81
|
let t = String(e.groupId ?? "").trim(), n = String(e.seedDeviceId ?? "").trim(), r = String(e.workerDeviceId ?? "").trim(), i = String(e.expiresAt ?? "").trim(), a = String(e.createdBy ?? "").trim() || null;
|
|
58
82
|
if (!t || !n || !r || !i) throw Error("groupId, seedDeviceId, workerDeviceId, and expiresAt are required.");
|
|
59
83
|
return {
|
|
@@ -64,95 +88,194 @@ function d(e) {
|
|
|
64
88
|
createdBy: a
|
|
65
89
|
};
|
|
66
90
|
}
|
|
67
|
-
function
|
|
91
|
+
function k(e) {
|
|
68
92
|
return e?.trim() || null;
|
|
69
93
|
}
|
|
70
|
-
function
|
|
94
|
+
async function A(e) {
|
|
95
|
+
let n = e.inviteKind ?? (k(e.operationId) ? "project_share" : "legacy_enrollment"), r = k(e.policyTeamId), i = k(e.targetIdentityId), o = k(e.reviewedPreviewDigest);
|
|
96
|
+
if (![
|
|
97
|
+
"legacy_enrollment",
|
|
98
|
+
"project_share",
|
|
99
|
+
"team_member",
|
|
100
|
+
"add_device"
|
|
101
|
+
].includes(n)) throw Error("inviteKind is invalid.");
|
|
102
|
+
if ([r, i].filter((e) => !!e).some((e) => e.length > 256 || /[\p{Cc}\p{Cf}]/u.test(e))) throw Error("recipient invite identifier is invalid.");
|
|
103
|
+
if (o && !/^[a-f0-9]{64}$/u.test(o)) throw Error("reviewedPreviewDigest must be a SHA-256 digest.");
|
|
104
|
+
if (n === "project_share") {
|
|
105
|
+
if (!k(e.operationId)) throw Error("project_share invite requires operationId.");
|
|
106
|
+
if (r || i || o) throw Error("recipient invite metadata requires a recipient invite kind.");
|
|
107
|
+
} else if (n === "legacy_enrollment") {
|
|
108
|
+
if (k(e.operationId)) throw Error("legacy_enrollment invite cannot reference an operation.");
|
|
109
|
+
if (r || i || o) throw Error("recipient invite metadata requires a recipient invite kind.");
|
|
110
|
+
} else if (n === "team_member") {
|
|
111
|
+
if (!r || !o || i || k(e.operationId)) throw Error("team_member invite metadata is invalid.");
|
|
112
|
+
} else if (n === "add_device" && (!i || !o || r || k(e.operationId))) throw Error("add_device invite metadata is invalid.");
|
|
113
|
+
if (!(e.reviewedIntent !== void 0 && e.reviewedIntent !== null)) {
|
|
114
|
+
if (n === "team_member" || n === "add_device") throw Error("recipient_invite_review_unavailable");
|
|
115
|
+
return {
|
|
116
|
+
inviteKind: n,
|
|
117
|
+
policyTeamId: r,
|
|
118
|
+
targetIdentityId: i,
|
|
119
|
+
reviewedPreviewDigest: o,
|
|
120
|
+
reviewedIntentJson: null
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
let s;
|
|
124
|
+
if (n === "team_member" && r && o) s = {
|
|
125
|
+
kind: "team_member",
|
|
126
|
+
policyTeamId: r
|
|
127
|
+
};
|
|
128
|
+
else if (n === "add_device" && i && o) s = {
|
|
129
|
+
kind: "add_device",
|
|
130
|
+
targetIdentityId: i
|
|
131
|
+
};
|
|
132
|
+
else throw Error("recipient invite metadata requires a recipient invite kind.");
|
|
133
|
+
return await a(e.reviewedIntent, {
|
|
134
|
+
target: s,
|
|
135
|
+
digest: o
|
|
136
|
+
}), {
|
|
137
|
+
inviteKind: n,
|
|
138
|
+
policyTeamId: r,
|
|
139
|
+
targetIdentityId: i,
|
|
140
|
+
reviewedPreviewDigest: o,
|
|
141
|
+
reviewedIntentJson: t(e.reviewedIntent, s)
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
async function j(t) {
|
|
145
|
+
if (t.invite_kind === "team_member") {
|
|
146
|
+
if (!t.policy_team_id || !n(t.assigned_identity_id) || !t.reviewed_preview_digest) throw Error("invite_invalid");
|
|
147
|
+
let r = await e(t.reviewed_intent_json, {
|
|
148
|
+
target: {
|
|
149
|
+
kind: "team_member",
|
|
150
|
+
policyTeamId: t.policy_team_id
|
|
151
|
+
},
|
|
152
|
+
digest: t.reviewed_preview_digest
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
kind: "team_member",
|
|
156
|
+
invite: t,
|
|
157
|
+
policy_team_id: t.policy_team_id,
|
|
158
|
+
assigned_identity_id: t.assigned_identity_id,
|
|
159
|
+
reviewed_preview_digest: t.reviewed_preview_digest,
|
|
160
|
+
reviewed_intent: r,
|
|
161
|
+
bound: !!t.consumed_at
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (t.invite_kind === "add_device") {
|
|
165
|
+
if (!t.target_identity_id || !t.reviewed_preview_digest) throw Error("invite_invalid");
|
|
166
|
+
let n = await e(t.reviewed_intent_json, {
|
|
167
|
+
target: {
|
|
168
|
+
kind: "add_device",
|
|
169
|
+
targetIdentityId: t.target_identity_id
|
|
170
|
+
},
|
|
171
|
+
digest: t.reviewed_preview_digest
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
kind: "add_device",
|
|
175
|
+
invite: t,
|
|
176
|
+
target_identity_id: t.target_identity_id,
|
|
177
|
+
reviewed_preview_digest: t.reviewed_preview_digest,
|
|
178
|
+
reviewed_intent: n,
|
|
179
|
+
bound: !!t.consumed_at
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
function M(e, t = 0) {
|
|
71
185
|
if (e == null) return t;
|
|
72
186
|
if (!Number.isFinite(e) || e < 0) throw Error("membershipEpoch must be non-negative.");
|
|
73
187
|
return Math.trunc(e);
|
|
74
188
|
}
|
|
75
|
-
function
|
|
76
|
-
let t =
|
|
189
|
+
function N(e) {
|
|
190
|
+
let t = k(e.scopeId), n = k(e.label);
|
|
77
191
|
if (!t || !n) throw Error("scopeId and label are required.");
|
|
78
192
|
return {
|
|
79
193
|
scopeId: t,
|
|
80
194
|
label: n,
|
|
81
|
-
kind:
|
|
82
|
-
authorityType:
|
|
83
|
-
coordinatorId:
|
|
84
|
-
groupId:
|
|
85
|
-
manifestIssuerDeviceId:
|
|
86
|
-
membershipEpoch:
|
|
87
|
-
manifestHash:
|
|
88
|
-
status:
|
|
195
|
+
kind: k(e.kind) ?? "user",
|
|
196
|
+
authorityType: k(e.authorityType) ?? "coordinator",
|
|
197
|
+
coordinatorId: k(e.coordinatorId),
|
|
198
|
+
groupId: k(e.groupId),
|
|
199
|
+
manifestIssuerDeviceId: k(e.manifestIssuerDeviceId),
|
|
200
|
+
membershipEpoch: M(e.membershipEpoch),
|
|
201
|
+
manifestHash: k(e.manifestHash),
|
|
202
|
+
status: k(e.status) ?? "active"
|
|
89
203
|
};
|
|
90
204
|
}
|
|
91
|
-
function
|
|
205
|
+
function P(e, t, n) {
|
|
92
206
|
if (e === void 0) return t;
|
|
93
|
-
let r =
|
|
207
|
+
let r = k(e);
|
|
94
208
|
if (!r) throw Error(`${n} must not be empty.`);
|
|
95
209
|
return r;
|
|
96
210
|
}
|
|
97
|
-
function
|
|
98
|
-
return e === void 0 ? t :
|
|
211
|
+
function F(e, t) {
|
|
212
|
+
return e === void 0 ? t : k(e);
|
|
99
213
|
}
|
|
100
|
-
function
|
|
101
|
-
let n =
|
|
214
|
+
function I(e, t) {
|
|
215
|
+
let n = k(e.scopeId);
|
|
102
216
|
if (!n) throw Error("scopeId is required.");
|
|
103
|
-
let r = e.membershipEpoch == null ? null :
|
|
217
|
+
let r = e.membershipEpoch == null ? null : M(e.membershipEpoch);
|
|
104
218
|
if (r != null && r < t.membership_epoch) throw Error("membershipEpoch must not move backwards.");
|
|
105
219
|
return {
|
|
106
220
|
scopeId: n,
|
|
107
|
-
label:
|
|
108
|
-
kind:
|
|
109
|
-
authorityType:
|
|
110
|
-
coordinatorId:
|
|
111
|
-
groupId:
|
|
112
|
-
manifestIssuerDeviceId:
|
|
221
|
+
label: P(e.label, t.label, "label"),
|
|
222
|
+
kind: P(e.kind, t.kind, "kind"),
|
|
223
|
+
authorityType: P(e.authorityType, t.authority_type, "authorityType"),
|
|
224
|
+
coordinatorId: F(e.coordinatorId, t.coordinator_id),
|
|
225
|
+
groupId: F(e.groupId, t.group_id),
|
|
226
|
+
manifestIssuerDeviceId: F(e.manifestIssuerDeviceId, t.manifest_issuer_device_id),
|
|
113
227
|
membershipEpoch: r ?? t.membership_epoch,
|
|
114
|
-
manifestHash:
|
|
115
|
-
status:
|
|
228
|
+
manifestHash: F(e.manifestHash, t.manifest_hash),
|
|
229
|
+
status: P(e.status, t.status, "status")
|
|
116
230
|
};
|
|
117
231
|
}
|
|
118
|
-
function
|
|
119
|
-
let
|
|
120
|
-
if (!
|
|
121
|
-
let
|
|
122
|
-
if (
|
|
123
|
-
if (
|
|
124
|
-
let
|
|
125
|
-
if (
|
|
126
|
-
if (
|
|
127
|
-
let
|
|
232
|
+
function L(e, t, n) {
|
|
233
|
+
let i = k(e.scopeId), a = k(e.deviceId);
|
|
234
|
+
if (!i || !a) throw Error("scopeId and deviceId are required.");
|
|
235
|
+
let o = k(e.coordinatorId), s = k(e.groupId);
|
|
236
|
+
if (o && o !== t?.coordinator_id) throw Error("membership coordinatorId must match the scope coordinatorId.");
|
|
237
|
+
if (s && s !== t?.group_id) throw new r("scope_group_mismatch");
|
|
238
|
+
let c = e.membershipEpoch == null ? null : M(e.membershipEpoch), l = t?.membership_epoch ?? 0;
|
|
239
|
+
if (c != null && c < l) throw Error("membershipEpoch must not be lower than the scope membershipEpoch.");
|
|
240
|
+
if (c != null && n && c < (n.status === "revoked" ? n.membership_epoch + 1 : n.membership_epoch)) throw Error("membershipEpoch must not move backwards.");
|
|
241
|
+
let u = c ?? (n ? Math.max(l, n.membership_epoch + +(n.status === "revoked")) : l);
|
|
128
242
|
return {
|
|
129
|
-
scopeId:
|
|
130
|
-
deviceId:
|
|
131
|
-
role:
|
|
132
|
-
membershipEpoch:
|
|
243
|
+
scopeId: i,
|
|
244
|
+
deviceId: a,
|
|
245
|
+
role: k(e.role) ?? "member",
|
|
246
|
+
membershipEpoch: u,
|
|
133
247
|
coordinatorId: t?.coordinator_id ?? null,
|
|
134
248
|
groupId: t?.group_id ?? null,
|
|
135
|
-
manifestIssuerDeviceId:
|
|
136
|
-
manifestHash:
|
|
137
|
-
signedManifestJson:
|
|
138
|
-
actorType:
|
|
139
|
-
actorId:
|
|
249
|
+
manifestIssuerDeviceId: k(e.manifestIssuerDeviceId) ?? t?.manifest_issuer_device_id ?? null,
|
|
250
|
+
manifestHash: k(e.manifestHash) ?? t?.manifest_hash ?? null,
|
|
251
|
+
signedManifestJson: k(e.signedManifestJson),
|
|
252
|
+
actorType: k(e.actorType),
|
|
253
|
+
actorId: k(e.actorId)
|
|
140
254
|
};
|
|
141
255
|
}
|
|
142
|
-
function
|
|
256
|
+
function R(e) {
|
|
143
257
|
return e == null || !Number.isFinite(e) ? 100 : Math.max(1, Math.min(1e3, Math.trunc(e)));
|
|
144
258
|
}
|
|
145
|
-
function
|
|
146
|
-
return e.prepare("INSERT INTO coordinator_scope_membership_audit_log(\n action, scope_id, device_id, role, status, membership_epoch,\n previous_role, previous_status, previous_membership_epoch,\n coordinator_id, group_id, actor_type, actor_id, manifest_hash, created_at\n )\n SELECT ?, membership.scope_id, membership.device_id, membership.role, membership.status,\n membership.membership_epoch, ?, ?, ?, membership.coordinator_id, membership.group_id,\n ?, ?, membership.manifest_hash, ?\n FROM (SELECT 1 WHERE changes() > 0) AS required\n LEFT JOIN coordinator_scope_memberships AS membership\n ON membership.scope_id = ?\n AND membership.device_id = ?\n AND membership.status = ?\n AND membership.membership_epoch = ?\n AND membership.updated_at = ?").bind(t.action, t.previous?.role ?? null, t.previous?.status ?? null, t.previous?.membership_epoch ?? null, t.actorType, t.actorId, t.createdAt, t.scopeId, t.deviceId, t.status, t.membershipEpoch, t.updatedAt);
|
|
259
|
+
function z(e, t) {
|
|
260
|
+
return e.prepare("INSERT INTO coordinator_scope_membership_audit_log(\n effect_id, action, scope_id, device_id, role, status, membership_epoch,\n previous_role, previous_status, previous_membership_epoch,\n coordinator_id, group_id, actor_type, actor_id, manifest_hash, created_at\n )\n SELECT receipt.effect_id, ?, membership.scope_id, membership.device_id, membership.role, membership.status,\n membership.membership_epoch, ?, ?, ?, membership.coordinator_id, membership.group_id,\n ?, ?, membership.manifest_hash, ?\n FROM (SELECT 1 WHERE changes() > 0) AS required\n JOIN coordinator_scope_membership_effect_receipts AS receipt\n ON receipt.effect_id = ? AND receipt.action = ? AND receipt.request_json = ?\n AND receipt.outcome_applied = 1\n LEFT JOIN coordinator_scope_memberships AS membership\n ON membership.scope_id = ?\n AND membership.device_id = ?\n AND membership.status = ?\n AND membership.membership_epoch = ?\n AND membership.updated_at = ?").bind(t.action, t.previous?.role ?? null, t.previous?.status ?? null, t.previous?.membership_epoch ?? null, t.actorType, t.actorId, t.createdAt, t.effectId, t.action, t.requestJson, t.scopeId, t.deviceId, t.status, t.membershipEpoch, t.updatedAt);
|
|
261
|
+
}
|
|
262
|
+
async function B(e, t) {
|
|
263
|
+
return await q(e.prepare("SELECT effect_id, action, request_json, outcome_applied, scope_id, device_id,\n role, status, membership_epoch, coordinator_id, group_id, manifest_issuer_device_id,\n manifest_hash, signed_manifest_json, updated_at, created_at\n FROM coordinator_scope_membership_effect_receipts WHERE effect_id = ?").bind(t));
|
|
264
|
+
}
|
|
265
|
+
function V(e, t) {
|
|
266
|
+
return e.prepare("INSERT INTO coordinator_scope_membership_effect_receipts(\n effect_id, action, request_json, outcome_applied, scope_id, device_id,\n role, status, membership_epoch, coordinator_id, group_id, manifest_issuer_device_id,\n manifest_hash, signed_manifest_json, updated_at, created_at\n )\n SELECT ?, 'grant', ?, 1, membership.scope_id, membership.device_id,\n membership.role, membership.status, membership.membership_epoch,\n membership.coordinator_id, membership.group_id, membership.manifest_issuer_device_id,\n membership.manifest_hash, membership.signed_manifest_json, membership.updated_at, ?\n FROM coordinator_scope_memberships AS membership\n WHERE changes() > 0 AND membership.scope_id = ? AND membership.device_id = ?").bind(t.effectId, t.requestJson, t.createdAt, t.scopeId, t.deviceId);
|
|
267
|
+
}
|
|
268
|
+
function H(e, t) {
|
|
269
|
+
return e.prepare("INSERT INTO coordinator_scope_membership_effect_receipts(\n effect_id, action, request_json, outcome_applied, scope_id, device_id,\n role, status, membership_epoch, coordinator_id, group_id, manifest_issuer_device_id,\n manifest_hash, signed_manifest_json, updated_at, created_at\n )\n SELECT ?, 'revoke', ?, changed.applied, ?, ?, membership.role, membership.status,\n membership.membership_epoch, membership.coordinator_id, membership.group_id,\n membership.manifest_issuer_device_id, membership.manifest_hash,\n membership.signed_manifest_json, membership.updated_at, ?\n FROM (SELECT CASE WHEN changes() > 0 THEN 1 ELSE 0 END AS applied) AS changed\n LEFT JOIN coordinator_scope_memberships AS membership\n ON changed.applied = 1 AND membership.scope_id = ? AND membership.device_id = ?\n WHERE NOT EXISTS (\n SELECT 1 FROM coordinator_scope_membership_effect_receipts WHERE effect_id = ?\n )").bind(t.effectId, t.requestJson, t.scopeId, t.deviceId, t.createdAt, t.scopeId, t.deviceId, t.effectId);
|
|
147
270
|
}
|
|
148
|
-
async function
|
|
271
|
+
async function U(e, t) {
|
|
149
272
|
if (!e.batch) throw Error("D1 batch support is required for audited scope membership changes.");
|
|
150
273
|
return await e.batch(t);
|
|
151
274
|
}
|
|
152
|
-
function
|
|
275
|
+
function W(e) {
|
|
153
276
|
return Number(e?.meta?.changes ?? 0);
|
|
154
277
|
}
|
|
155
|
-
function
|
|
278
|
+
function G(e) {
|
|
156
279
|
if (!e) return null;
|
|
157
280
|
let t = String(e.seedDeviceId ?? "").trim(), n = String(e.expiresAt ?? "").trim(), r = String(e.createdBy ?? "").trim() || null;
|
|
158
281
|
if (!t || !n) throw Error("bootstrapGrant.seedDeviceId and expiresAt are required.");
|
|
@@ -164,108 +287,266 @@ function C(e) {
|
|
|
164
287
|
createdBy: r
|
|
165
288
|
};
|
|
166
289
|
}
|
|
167
|
-
async function
|
|
290
|
+
async function K(e) {
|
|
168
291
|
let t = await e.all();
|
|
169
292
|
return Array.isArray(t?.results) ? t.results : [];
|
|
170
293
|
}
|
|
171
|
-
async function
|
|
294
|
+
async function q(e) {
|
|
172
295
|
return await e.first();
|
|
173
296
|
}
|
|
174
|
-
async function
|
|
297
|
+
async function J(e) {
|
|
175
298
|
let t = await e.run();
|
|
176
299
|
return Number(t?.meta?.changes ?? 0);
|
|
177
300
|
}
|
|
178
|
-
var
|
|
301
|
+
var Y = class {
|
|
179
302
|
db;
|
|
180
303
|
constructor(e) {
|
|
181
304
|
this.db = e;
|
|
182
305
|
}
|
|
183
306
|
async close() {}
|
|
184
307
|
async createGroup(e, t) {
|
|
185
|
-
await this.db.prepare("INSERT OR IGNORE INTO groups(group_id, display_name, archived_at, created_at) VALUES (?, ?, NULL, ?)").bind(e, t ?? null,
|
|
308
|
+
await this.db.prepare("INSERT OR IGNORE INTO groups(group_id, display_name, archived_at, created_at) VALUES (?, ?, NULL, ?)").bind(e, t ?? null, b()).run();
|
|
186
309
|
}
|
|
187
310
|
async getGroup(e) {
|
|
188
|
-
let t = await
|
|
189
|
-
return t ?
|
|
311
|
+
let t = await q(this.db.prepare("SELECT group_id, display_name, archived_at, created_at FROM groups WHERE group_id = ?").bind(e));
|
|
312
|
+
return t ? h(t) : null;
|
|
190
313
|
}
|
|
191
314
|
async listGroups(e = !1) {
|
|
192
315
|
let t = e ? "" : "WHERE archived_at IS NULL";
|
|
193
|
-
return (await
|
|
316
|
+
return (await K(this.db.prepare(`SELECT group_id, display_name, archived_at, created_at FROM groups ${t} ORDER BY created_at ASC`))).map((e) => h(e));
|
|
194
317
|
}
|
|
195
318
|
async renameGroup(e, t) {
|
|
196
|
-
return await
|
|
319
|
+
return await J(this.db.prepare("UPDATE groups SET display_name = ? WHERE group_id = ?").bind(t, e)) > 0;
|
|
197
320
|
}
|
|
198
|
-
async archiveGroup(e, t =
|
|
199
|
-
return await
|
|
321
|
+
async archiveGroup(e, t = b()) {
|
|
322
|
+
return await J(this.db.prepare("UPDATE groups SET archived_at = ? WHERE group_id = ? AND archived_at IS NULL").bind(t, e)) > 0;
|
|
200
323
|
}
|
|
201
324
|
async unarchiveGroup(e) {
|
|
202
|
-
return await
|
|
325
|
+
return await J(this.db.prepare("UPDATE groups SET archived_at = NULL WHERE group_id = ? AND archived_at IS NOT NULL").bind(e)) > 0;
|
|
203
326
|
}
|
|
204
327
|
async enrollDevice(e, t) {
|
|
205
|
-
await this.db.prepare("INSERT INTO enrolled_devices(\n
|
|
328
|
+
if (await J(this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, identity_id, display_name, enabled, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, 1, ?)\n ON CONFLICT(group_id, device_id) DO UPDATE SET\n public_key = excluded.public_key,\n fingerprint = excluded.fingerprint,\n identity_id = COALESCE(enrolled_devices.identity_id, excluded.identity_id),\n display_name = excluded.display_name,\n enabled = 1\n WHERE excluded.identity_id IS NULL\n OR enrolled_devices.identity_id IS NULL\n OR enrolled_devices.identity_id = excluded.identity_id").bind(e, t.deviceId, t.publicKey, t.fingerprint, t.identityId ?? null, t.displayName ?? null, b())) === 0) throw Error("invite_identity_conflict");
|
|
206
329
|
}
|
|
207
330
|
async listEnrolledDevices(e, t) {
|
|
208
|
-
let n = t ? "" : "AND enabled = 1";
|
|
209
|
-
return (await
|
|
331
|
+
let n = t ? "" : "AND enrolled_devices.enabled = 1";
|
|
332
|
+
return (await K(this.db.prepare(`SELECT ${D}
|
|
210
333
|
FROM enrolled_devices
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
334
|
+
LEFT JOIN presence_records
|
|
335
|
+
ON presence_records.group_id = enrolled_devices.group_id
|
|
336
|
+
AND presence_records.device_id = enrolled_devices.device_id
|
|
337
|
+
WHERE enrolled_devices.group_id = ? ${n}
|
|
338
|
+
ORDER BY enrolled_devices.created_at ASC, enrolled_devices.device_id ASC`).bind(e))).map(g);
|
|
339
|
+
}
|
|
340
|
+
async getEnrollment(e, t, n = !1) {
|
|
341
|
+
let r = n ? "" : "AND enabled = 1", i = await q(this.db.prepare(`SELECT ${E}
|
|
342
|
+
FROM enrolled_devices
|
|
343
|
+
WHERE group_id = ? AND device_id = ? ${r}`).bind(e, t));
|
|
344
|
+
return i ? h(i) : null;
|
|
217
345
|
}
|
|
218
346
|
async renameDevice(e, t, n) {
|
|
219
|
-
return await
|
|
347
|
+
return await J(this.db.prepare("UPDATE enrolled_devices SET display_name = ?\n WHERE group_id = ? AND device_id = ?").bind(n, e, t)) > 0;
|
|
220
348
|
}
|
|
221
349
|
async setDeviceEnabled(e, t, n) {
|
|
222
|
-
return await
|
|
350
|
+
return await J(this.db.prepare("UPDATE enrolled_devices SET enabled = ?\n WHERE group_id = ? AND device_id = ?").bind(+!!n, e, t)) > 0;
|
|
223
351
|
}
|
|
224
352
|
async removeDevice(e, t) {
|
|
225
353
|
if (!this.db.batch) throw Error("D1 batch support is required for atomic device removal.");
|
|
226
|
-
return
|
|
354
|
+
return W((await this.db.batch([
|
|
227
355
|
this.db.prepare("DELETE FROM presence_records WHERE group_id = ? AND device_id = ?").bind(e, t),
|
|
228
356
|
this.db.prepare("DELETE FROM coordinator_reciprocal_approvals WHERE group_id = ? AND (requesting_device_id = ? OR requested_device_id = ?)").bind(e, t, t),
|
|
229
357
|
this.db.prepare("DELETE FROM enrolled_devices WHERE group_id = ? AND device_id = ?").bind(e, t)
|
|
230
358
|
]))[2]) > 0;
|
|
231
359
|
}
|
|
232
360
|
async recordNonce(e, t, n) {
|
|
233
|
-
return await
|
|
361
|
+
return await J(this.db.prepare("INSERT OR IGNORE INTO request_nonces(device_id, nonce, created_at) VALUES (?, ?, ?)").bind(e, t, n)) > 0;
|
|
234
362
|
}
|
|
235
363
|
async cleanupNonces(e) {
|
|
236
364
|
await this.db.prepare("DELETE FROM request_nonces WHERE created_at < ?").bind(e).run();
|
|
237
365
|
}
|
|
238
|
-
async createInvite(
|
|
239
|
-
let
|
|
240
|
-
|
|
366
|
+
async createInvite(e) {
|
|
367
|
+
let t = b(), n = C(12), r = C(24), i = await w(r), a = l(e.expiresAt), o = await this.getGroup(e.groupId), s = String(e.operationId ?? "").trim() || null, c = String(e.reviewedProjectSetDigest ?? "").trim() || null, u = await A(e), d = u.inviteKind === "team_member" ? `identity:${C(18)}` : null;
|
|
368
|
+
if (!!s != !!c) throw Error("operationId and reviewedProjectSetDigest must be provided together.");
|
|
369
|
+
let f = async () => {
|
|
370
|
+
if (!s) return null;
|
|
371
|
+
let t = await q(this.db.prepare(`SELECT ${T} FROM coordinator_invites WHERE operation_id = ?`).bind(s));
|
|
372
|
+
if (!t) return null;
|
|
373
|
+
if (t.consumed_at) throw Error("invite_already_bound");
|
|
374
|
+
if (t.group_id !== e.groupId || t.policy !== e.policy || t.invite_kind !== u.inviteKind || t.reviewed_project_set_digest !== c || t.inviter_actor_id !== (String(e.inviterActorId ?? "").trim() || null) || t.inviter_display_name !== (String(e.inviterDisplayName ?? "").trim() || null) || t.inviter_device_id !== (String(e.inviterDeviceId ?? "").trim() || null) || t.pending_person_id !== (String(e.pendingPersonId ?? "").trim() || null) || t.project_summaries_json !== (e.projectSummaries ? JSON.stringify(e.projectSummaries) : null) || t.project_intent_json !== (e.projectIntent ? JSON.stringify(e.projectIntent) : null) || t.policy_team_id !== u.policyTeamId || t.target_identity_id !== u.targetIdentityId || t.reviewed_preview_digest !== u.reviewedPreviewDigest || t.reviewed_intent_json !== u.reviewedIntentJson) throw Error("invite_operation_intent_conflict");
|
|
375
|
+
return h(t);
|
|
376
|
+
}, p = async (n) => {
|
|
377
|
+
if (!n.revoked_at && n.expires_at > t) return n;
|
|
378
|
+
await J(this.db.prepare("UPDATE coordinator_invites\n SET token = ?, token_digest = ?, expires_at = ?, created_at = ?, created_by = ?,\n team_name_snapshot = ?, revoked_at = NULL\n WHERE operation_id = ? AND token = ?\n AND (revoked_at IS NOT NULL OR expires_at <= ?)").bind(r, i, a, t, e.createdBy ?? null, o?.display_name ?? null, s, n.token, t));
|
|
379
|
+
let c = await f();
|
|
380
|
+
if (!c) throw Error("invite_operation_reissue_failed");
|
|
381
|
+
return c;
|
|
382
|
+
};
|
|
383
|
+
if (s) {
|
|
384
|
+
let e = await f();
|
|
385
|
+
if (e) return await p(e);
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
await this.db.prepare("INSERT INTO coordinator_invites(\n invite_id, group_id, token, policy, expires_at, created_at, created_by,\n team_name_snapshot, revoked_at, operation_id, reviewed_project_set_digest,\n token_digest, inviter_actor_id, inviter_display_name, inviter_device_id,\n pending_person_id, project_summaries_json, project_intent_json, trust_state,\n invite_kind, policy_team_id, target_identity_id, assigned_identity_id,\n reviewed_preview_digest, reviewed_intent_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").bind(n, e.groupId, r, e.policy, a, t, e.createdBy ?? null, o?.display_name ?? null, s, c, i, String(e.inviterActorId ?? "").trim() || null, String(e.inviterDisplayName ?? "").trim() || null, String(e.inviterDeviceId ?? "").trim() || null, String(e.pendingPersonId ?? "").trim() || null, e.projectSummaries ? JSON.stringify(e.projectSummaries) : null, e.projectIntent ? JSON.stringify(e.projectIntent) : null, s ? "pending" : null, u.inviteKind, u.policyTeamId, u.targetIdentityId, d, u.reviewedPreviewDigest, u.reviewedIntentJson).run();
|
|
389
|
+
} catch (e) {
|
|
390
|
+
if (s) {
|
|
391
|
+
let e = await f();
|
|
392
|
+
if (e) return await p(e);
|
|
393
|
+
}
|
|
394
|
+
throw e;
|
|
395
|
+
}
|
|
396
|
+
return h(await q(this.db.prepare(`SELECT ${T} FROM coordinator_invites WHERE invite_id = ?`).bind(n)));
|
|
241
397
|
}
|
|
242
398
|
async getInviteByToken(e) {
|
|
243
|
-
let t = await
|
|
244
|
-
|
|
399
|
+
let t = await w(e), n = await q(this.db.prepare(`SELECT ${T}
|
|
400
|
+
FROM coordinator_invites
|
|
401
|
+
WHERE (token_digest = ? OR token = ?)
|
|
402
|
+
AND revoked_at IS NULL
|
|
403
|
+
AND expires_at > ?`).bind(t, e, b()));
|
|
404
|
+
return n ? h(n) : null;
|
|
405
|
+
}
|
|
406
|
+
async getInviteByTokenForInspection(e) {
|
|
407
|
+
let t = await w(e), n = await q(this.db.prepare(`SELECT ${T} FROM coordinator_invites WHERE token_digest = ? OR token = ?`).bind(t, e));
|
|
408
|
+
return n ? h(n) : null;
|
|
409
|
+
}
|
|
410
|
+
async inspectRecipientInvite(e) {
|
|
411
|
+
let t = await this.getInviteByTokenForInspection(e.token);
|
|
412
|
+
if (!t) return null;
|
|
413
|
+
let n = await j(t);
|
|
414
|
+
if (!n) return null;
|
|
415
|
+
if (t.revoked_at) throw Error("invite_invalid");
|
|
416
|
+
if (!t.consumed_at && new Date(t.expires_at) <= new Date(l(e.now))) throw Error("invite_expired");
|
|
417
|
+
let r = await this.getGroup(t.group_id);
|
|
418
|
+
if (!r) throw Error("group_not_found");
|
|
419
|
+
if (r.archived_at) throw Error("group_archived");
|
|
420
|
+
return n;
|
|
421
|
+
}
|
|
422
|
+
async consumeRecipientInvite(e) {
|
|
423
|
+
let t = l(e.now), n = e.recipientDisplayName ?? null, r = e.deviceDisplayName ?? null;
|
|
424
|
+
if (!e.identityId || !e.deviceId || !e.publicKey || !e.fingerprint || e.identityId !== e.identityId.trim() || e.deviceId !== e.deviceId.trim() || e.identityId.length > 256 || e.deviceId.length > 256 || /[\p{Cc}\p{Cf}]/u.test(e.identityId) || /[\p{Cc}\p{Cf}]/u.test(e.deviceId)) throw Error("invite_identity_conflict");
|
|
425
|
+
let i = await w(e.token), a = await this.getInviteByTokenForInspection(e.token), o = a ? await j(a) : null;
|
|
426
|
+
if (!a || !o || o.kind !== e.inviteKind || a.revoked_at) throw Error("invite_invalid");
|
|
427
|
+
let s = await this.getGroup(a.group_id);
|
|
428
|
+
if (!s) throw Error("group_not_found");
|
|
429
|
+
if (s.archived_at) throw Error("group_archived");
|
|
430
|
+
if (!a.consumed_at && new Date(a.expires_at) <= new Date(t)) throw Error("invite_expired");
|
|
431
|
+
if (d(e.publicKey) !== e.fingerprint) throw Error("fingerprint_mismatch");
|
|
432
|
+
let c = f(o);
|
|
433
|
+
if (c !== e.identityId) throw Error("invite_identity_conflict");
|
|
434
|
+
let u = a.bound_device_id === e.deviceId && a.bound_public_key === e.publicKey && a.bound_fingerprint === e.fingerprint;
|
|
435
|
+
if (a.consumed_at && !u) throw Error("invite_already_bound");
|
|
436
|
+
if (a.consumed_at && a.recipient_actor_id !== c) throw Error("invite_identity_conflict");
|
|
437
|
+
let p = await q(this.db.prepare(`SELECT ${E}
|
|
438
|
+
FROM enrolled_devices WHERE group_id = ? AND device_id = ?`).bind(a.group_id, e.deviceId));
|
|
439
|
+
if (p && (p.public_key !== e.publicKey || p.fingerprint !== e.fingerprint || p.identity_id !== null && p.identity_id !== c)) throw Error("invite_identity_conflict");
|
|
440
|
+
let m = 0, h = C(12);
|
|
441
|
+
if (!a.consumed_at) {
|
|
442
|
+
if (!this.db.batch) throw Error("D1 batch support is required for atomic invite consume.");
|
|
443
|
+
m = W((await this.db.batch([
|
|
444
|
+
this.db.prepare("UPDATE coordinator_invites SET token = ?, consumed_at = ?, bound_device_id = ?,\n bound_public_key = ?, bound_fingerprint = ?, recipient_actor_id = ?,\n recipient_display_name = ?, recipient_device_display_name = ?\n WHERE (token_digest = ? OR token = ?) AND consumed_at IS NULL\n AND revoked_at IS NULL AND expires_at > ? AND invite_kind = ?\n AND reviewed_intent_json = ? AND reviewed_preview_digest = ?\n AND ((invite_kind = 'team_member' AND assigned_identity_id = ?)\n OR (invite_kind = 'add_device' AND target_identity_id = ?))\n AND NOT EXISTS (\n SELECT 1 FROM enrolled_devices e\n WHERE e.group_id = coordinator_invites.group_id AND e.device_id = ?\n AND (e.public_key <> ? OR e.fingerprint <> ?\n OR (e.identity_id IS NOT NULL AND e.identity_id <> ?))\n )\n AND EXISTS (SELECT 1 FROM groups g WHERE g.group_id = coordinator_invites.group_id\n AND g.archived_at IS NULL)").bind(`consumed:${a.invite_id}`, t, e.deviceId, e.publicKey, e.fingerprint, c, n, r, i, e.token, t, e.inviteKind, a.reviewed_intent_json, a.reviewed_preview_digest, c, c, e.deviceId, e.publicKey, e.fingerprint, c),
|
|
445
|
+
this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, identity_id, display_name, enabled, created_at\n ) SELECT i.group_id, i.bound_device_id, i.bound_public_key, i.bound_fingerprint,\n i.recipient_actor_id, i.recipient_device_display_name, 1, ? FROM coordinator_invites i\n JOIN groups g ON g.group_id = i.group_id AND g.archived_at IS NULL\n WHERE (i.token_digest = ? OR i.token = ?) AND i.bound_device_id = ?\n AND i.bound_public_key = ? AND i.bound_fingerprint = ?\n AND i.recipient_actor_id = ?\n ON CONFLICT(group_id, device_id) DO UPDATE SET\n identity_id = COALESCE(enrolled_devices.identity_id, excluded.identity_id),\n display_name = COALESCE(enrolled_devices.display_name, excluded.display_name),\n enabled = 1\n WHERE enrolled_devices.identity_id IS NULL\n OR enrolled_devices.identity_id = excluded.identity_id").bind(t, i, e.token, e.deviceId, e.publicKey, e.fingerprint, c),
|
|
446
|
+
this.db.prepare("UPDATE coordinator_invites SET bootstrap_grant_id = ?,\n trust_state = 'bootstrap_grant_created'\n WHERE (token_digest = ? OR token = ?) AND invite_kind = 'add_device'\n AND bootstrap_grant_id IS NULL AND inviter_device_id IS NOT NULL\n AND expires_at > ?\n AND EXISTS (SELECT 1 FROM enrolled_devices e\n WHERE e.group_id = coordinator_invites.group_id\n AND e.device_id = coordinator_invites.inviter_device_id AND e.enabled = 1)").bind(h, i, e.token, t),
|
|
447
|
+
this.db.prepare("INSERT OR IGNORE INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at,\n created_at, created_by, revoked_at\n ) SELECT i.bootstrap_grant_id, i.group_id, i.inviter_device_id, i.bound_device_id,\n i.expires_at, ?, i.recipient_actor_id, NULL FROM coordinator_invites i\n JOIN enrolled_devices e ON e.group_id = i.group_id\n AND e.device_id = i.inviter_device_id AND e.enabled = 1\n WHERE (i.token_digest = ? OR i.token = ?) AND i.invite_kind = 'add_device'\n AND i.bootstrap_grant_id IS NOT NULL AND i.bound_device_id = ?").bind(t, i, e.token, e.deviceId)
|
|
448
|
+
]))[0]);
|
|
449
|
+
}
|
|
450
|
+
let g = await this.getGroup(a.group_id);
|
|
451
|
+
if (!g) throw Error("group_not_found");
|
|
452
|
+
if (g.archived_at) throw Error("group_archived");
|
|
453
|
+
let _ = await q(this.db.prepare(`SELECT ${E}
|
|
454
|
+
FROM enrolled_devices WHERE group_id = ? AND device_id = ?`).bind(a.group_id, e.deviceId));
|
|
455
|
+
if (_ && (_.public_key !== e.publicKey || _.fingerprint !== e.fingerprint || _.identity_id !== null && _.identity_id !== c)) throw Error("invite_identity_conflict");
|
|
456
|
+
let v = await this.getInviteByTokenForInspection(e.token);
|
|
457
|
+
if (!v || v.revoked_at || !v.consumed_at && new Date(v.expires_at) <= new Date(t)) throw Error("invite_invalid");
|
|
458
|
+
let y = await j(v);
|
|
459
|
+
if (!y || y.kind !== e.inviteKind) throw Error("invite_invalid");
|
|
460
|
+
if (f(y) !== c) throw Error("invite_identity_conflict");
|
|
461
|
+
if (v.bound_device_id !== e.deviceId || v.bound_public_key !== e.publicKey || v.bound_fingerprint !== e.fingerprint) throw Error("invite_already_bound");
|
|
462
|
+
if (v.recipient_actor_id !== c) throw Error("invite_identity_conflict");
|
|
463
|
+
await this.db.prepare("UPDATE enrolled_devices SET identity_id = ?\n WHERE group_id = ? AND device_id = ? AND identity_id IS NULL\n AND public_key = ? AND fingerprint = ?").bind(c, v.group_id, e.deviceId, e.publicKey, e.fingerprint).run();
|
|
464
|
+
let b = await this.getEnrollment(v.group_id, e.deviceId);
|
|
465
|
+
if (!b) throw Error("invite_acceptance_incomplete");
|
|
466
|
+
if (b.public_key !== e.publicKey || b.fingerprint !== e.fingerprint || b.identity_id !== c) throw Error("invite_identity_conflict");
|
|
467
|
+
let x = v;
|
|
468
|
+
if (y.kind === "add_device" && v.inviter_device_id && !v.bootstrap_grant_id && new Date(v.expires_at) > new Date(t)) {
|
|
469
|
+
if (!this.db.batch) throw Error("D1 batch support is required for atomic bootstrap grant recovery.");
|
|
470
|
+
let n = C(12);
|
|
471
|
+
await this.db.batch([this.db.prepare("UPDATE coordinator_invites SET bootstrap_grant_id = ?,\n trust_state = 'bootstrap_grant_created'\n WHERE invite_id = ? AND invite_kind = 'add_device'\n AND bootstrap_grant_id IS NULL AND inviter_device_id IS NOT NULL\n AND bound_device_id = ? AND recipient_actor_id = ? AND expires_at > ?\n AND EXISTS (SELECT 1 FROM enrolled_devices e\n WHERE e.group_id = coordinator_invites.group_id\n AND e.device_id = coordinator_invites.inviter_device_id AND e.enabled = 1)").bind(n, v.invite_id, e.deviceId, c, t), this.db.prepare("INSERT OR IGNORE INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at,\n created_at, created_by, revoked_at\n ) SELECT i.bootstrap_grant_id, i.group_id, i.inviter_device_id, i.bound_device_id,\n i.expires_at, ?, i.recipient_actor_id, NULL FROM coordinator_invites i\n JOIN enrolled_devices e ON e.group_id = i.group_id\n AND e.device_id = i.inviter_device_id AND e.enabled = 1\n WHERE i.invite_id = ? AND i.invite_kind = 'add_device'\n AND i.bootstrap_grant_id IS NOT NULL AND i.bound_device_id = ?").bind(t, v.invite_id, e.deviceId)]);
|
|
472
|
+
let r = await this.getInviteByTokenForInspection(e.token);
|
|
473
|
+
if (!r) throw Error("invite_invalid");
|
|
474
|
+
x = r;
|
|
475
|
+
}
|
|
476
|
+
let S = x.bootstrap_grant_id ? await this.getBootstrapGrant(x.bootstrap_grant_id) : null;
|
|
477
|
+
return {
|
|
478
|
+
status: m === 1 ? "accepted" : "existing",
|
|
479
|
+
invite: x,
|
|
480
|
+
reviewed_intent: y.reviewed_intent,
|
|
481
|
+
bootstrap_grant: S
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
async consumeProjectInvite(e) {
|
|
485
|
+
if (!this.db.batch) throw Error("D1 batch support is required for atomic invite consume.");
|
|
486
|
+
let t = l(e.now), n = await w(e.token), r = await this.getInviteByTokenForInspection(e.token);
|
|
487
|
+
if (!r?.operation_id || !r.project_intent_json || r.revoked_at) throw Error("invite_invalid");
|
|
488
|
+
let i = await this.getGroup(r.group_id);
|
|
489
|
+
if (!i) throw Error("group_not_found");
|
|
490
|
+
if (i.archived_at) throw Error("group_archived");
|
|
491
|
+
if (r.operation_id !== e.operationId) throw Error("invite_invalid");
|
|
492
|
+
if (d(e.publicKey) !== e.fingerprint) throw Error("fingerprint_mismatch");
|
|
493
|
+
if (!r.consumed_at && new Date(r.expires_at) <= new Date(t)) throw Error("invite_expired");
|
|
494
|
+
let a = r.bound_device_id === e.deviceId && r.bound_public_key === e.publicKey && r.bound_fingerprint === e.fingerprint;
|
|
495
|
+
if (r.consumed_at && !a) throw Error("invite_already_bound");
|
|
496
|
+
if (r.consumed_at && (r.recipient_actor_id !== e.recipientActorId || r.recipient_display_name !== e.recipientDisplayName || r.recipient_device_display_name !== e.deviceDisplayName)) throw Error("invite_identity_conflict");
|
|
497
|
+
let o = await q(this.db.prepare(`SELECT ${E}
|
|
498
|
+
FROM enrolled_devices WHERE group_id = ? AND device_id = ?`).bind(r.group_id, e.deviceId));
|
|
499
|
+
if (o && (o.public_key !== e.publicKey || o.fingerprint !== e.fingerprint || o.identity_id != null && o.identity_id !== e.recipientActorId)) throw Error("invite_identity_conflict");
|
|
500
|
+
let s = C(12), c = W((await this.db.batch([
|
|
501
|
+
this.db.prepare("UPDATE coordinator_invites SET token = ?, consumed_at = ?, bound_device_id = ?,\n bound_public_key = ?, bound_fingerprint = ?, recipient_actor_id = ?,\n recipient_display_name = ?, recipient_device_display_name = ?,\n trust_state = 'pending_inviter_device'\n WHERE (token_digest = ? OR token = ?) AND consumed_at IS NULL\n AND EXISTS (SELECT 1 FROM groups g WHERE g.group_id = coordinator_invites.group_id\n AND g.archived_at IS NULL)").bind(`consumed:${r.invite_id}`, t, e.deviceId, e.publicKey, e.fingerprint, e.recipientActorId, e.recipientDisplayName, e.deviceDisplayName, n, e.token),
|
|
502
|
+
this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, identity_id, display_name, enabled, created_at\n ) SELECT i.group_id, i.bound_device_id, i.bound_public_key, i.bound_fingerprint,\n i.recipient_actor_id, i.recipient_device_display_name, 1, ? FROM coordinator_invites i\n JOIN groups g ON g.group_id = i.group_id AND g.archived_at IS NULL\n WHERE (i.token_digest = ? OR i.token = ?) AND i.bound_device_id = ? AND ? = 1\n ON CONFLICT(group_id, device_id) DO UPDATE SET\n identity_id = COALESCE(enrolled_devices.identity_id, excluded.identity_id),\n display_name = excluded.display_name, enabled = 1\n WHERE enrolled_devices.identity_id IS NULL\n OR enrolled_devices.identity_id = excluded.identity_id").bind(t, n, e.token, e.deviceId, +!r.consumed_at),
|
|
503
|
+
this.db.prepare("UPDATE coordinator_invites SET bootstrap_grant_id = ?,\n trust_state = 'bootstrap_grant_created'\n WHERE (token_digest = ? OR token = ?) AND bootstrap_grant_id IS NULL\n AND bound_device_id = ?\n AND EXISTS (SELECT 1 FROM groups g WHERE g.group_id = coordinator_invites.group_id\n AND g.archived_at IS NULL)\n AND expires_at > ?\n AND EXISTS (SELECT 1 FROM enrolled_devices e WHERE e.group_id = coordinator_invites.group_id\n AND e.device_id = coordinator_invites.inviter_device_id AND e.enabled = 1)").bind(s, n, e.token, e.deviceId, t),
|
|
504
|
+
this.db.prepare("INSERT OR IGNORE INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at,\n created_by, revoked_at\n ) SELECT i.bootstrap_grant_id, i.group_id, i.inviter_device_id, i.bound_device_id,\n i.expires_at, ?, i.inviter_actor_id, NULL FROM coordinator_invites i\n JOIN groups g ON g.group_id = i.group_id AND g.archived_at IS NULL\n JOIN enrolled_devices e ON e.group_id = i.group_id AND e.device_id = i.inviter_device_id\n WHERE (i.token_digest = ? OR i.token = ?) AND i.bootstrap_grant_id IS NOT NULL\n AND i.bound_device_id = ? AND e.enabled = 1").bind(t, n, e.token, e.deviceId)
|
|
505
|
+
]))[0]) === 1, u = await this.getGroup(r.group_id);
|
|
506
|
+
if (!u) throw Error("group_not_found");
|
|
507
|
+
if (u.archived_at) throw Error("group_archived");
|
|
508
|
+
let f = await this.getInviteByTokenForInspection(e.token);
|
|
509
|
+
if (!f) throw Error("invite_invalid");
|
|
510
|
+
if (f.bound_device_id !== e.deviceId || f.bound_public_key !== e.publicKey || f.bound_fingerprint !== e.fingerprint) throw Error("invite_already_bound");
|
|
511
|
+
if (f.recipient_actor_id !== e.recipientActorId || f.recipient_display_name !== e.recipientDisplayName || f.recipient_device_display_name !== e.deviceDisplayName) throw Error("invite_identity_conflict");
|
|
512
|
+
c || await this.db.prepare("UPDATE enrolled_devices SET identity_id = ?\n WHERE group_id = ? AND device_id = ? AND identity_id IS NULL AND enabled = 1\n AND public_key = ? AND fingerprint = ?").bind(e.recipientActorId, f.group_id, e.deviceId, e.publicKey, e.fingerprint).run();
|
|
513
|
+
let p = await this.getEnrollment(f.group_id, e.deviceId);
|
|
514
|
+
if (!p) throw Error("invite_acceptance_incomplete");
|
|
515
|
+
if (p.identity_id !== e.recipientActorId) throw Error("invite_identity_conflict");
|
|
516
|
+
let m = f.inviter_device_id ? await this.getEnrollment(f.group_id, f.inviter_device_id) : null, h = f.bootstrap_grant_id ? await this.getBootstrapGrant(f.bootstrap_grant_id) : null;
|
|
517
|
+
return {
|
|
518
|
+
status: c ? "accepted" : "existing",
|
|
519
|
+
invite: f,
|
|
520
|
+
enrollment: p,
|
|
521
|
+
seed_enrollment: m,
|
|
522
|
+
bootstrap_grant: h
|
|
523
|
+
};
|
|
245
524
|
}
|
|
246
525
|
async listInvites(e) {
|
|
247
|
-
return (await
|
|
526
|
+
return (await K(this.db.prepare(`SELECT ${T}
|
|
527
|
+
FROM coordinator_invites WHERE group_id = ?
|
|
528
|
+
ORDER BY created_at DESC`).bind(e))).map((e) => h(e));
|
|
248
529
|
}
|
|
249
530
|
async createJoinRequest(e) {
|
|
250
|
-
let t =
|
|
251
|
-
return await this.db.prepare("INSERT INTO coordinator_join_requests(\n request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, NULL, NULL)").bind(n, e.groupId, e.deviceId, e.publicKey, e.fingerprint, e.displayName ?? null, e.token, t).run(),
|
|
531
|
+
let t = b(), n = C(12);
|
|
532
|
+
return await this.db.prepare("INSERT INTO coordinator_join_requests(\n request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, NULL, NULL)").bind(n, e.groupId, e.deviceId, e.publicKey, e.fingerprint, e.displayName ?? null, e.token, t).run(), h(await q(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(n)));
|
|
252
533
|
}
|
|
253
534
|
async listJoinRequests(e, t) {
|
|
254
535
|
let n = t ?? "pending";
|
|
255
|
-
return (await
|
|
536
|
+
return (await K(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests\n WHERE group_id = ? AND status = ?\n ORDER BY created_at ASC, device_id ASC").bind(e, n))).map((e) => h(e));
|
|
256
537
|
}
|
|
257
538
|
async reviewJoinRequest(e) {
|
|
258
|
-
let t = await
|
|
539
|
+
let t = await q(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status,\n created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
|
|
259
540
|
if (!t) return null;
|
|
260
541
|
if (t.status !== "pending") return {
|
|
261
|
-
...
|
|
542
|
+
...h(t),
|
|
262
543
|
_no_transition: !0
|
|
263
544
|
};
|
|
264
|
-
let n =
|
|
545
|
+
let n = G(e.bootstrapGrant), r = b(), i = e.approved ? "approved" : "denied", a = null, o = null;
|
|
265
546
|
if (e.approved && n) {
|
|
266
|
-
if (!await
|
|
547
|
+
if (!await q(this.db.prepare("SELECT device_id FROM enrolled_devices WHERE group_id = ? AND device_id = ? AND enabled = 1").bind(t.group_id, n.seedDeviceId))) throw Error("bootstrap grant seed device is not enrolled in the group.");
|
|
267
548
|
if (n.seedDeviceId === t.device_id) throw Error("bootstrap grant seed and worker device ids must differ.");
|
|
268
|
-
|
|
549
|
+
a = {
|
|
269
550
|
...n,
|
|
270
551
|
groupId: t.group_id,
|
|
271
552
|
workerDeviceId: t.device_id
|
|
@@ -273,10 +554,10 @@ var D = class {
|
|
|
273
554
|
}
|
|
274
555
|
if (this.db.batch) {
|
|
275
556
|
let t = [];
|
|
276
|
-
if (t.push(this.db.prepare("UPDATE coordinator_join_requests\n SET status = ?, reviewed_at = ?, reviewed_by = ?\n WHERE request_id = ? AND status = 'pending'").bind(
|
|
277
|
-
|
|
278
|
-
let n =
|
|
279
|
-
t.push(this.db.prepare("INSERT INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n ) SELECT ?, ?, ?, ?, ?, ?, ?, NULL\n WHERE EXISTS (\n SELECT 1 FROM coordinator_join_requests\n WHERE request_id = ? AND status = 'approved' AND reviewed_at = ?\n )").bind(
|
|
557
|
+
if (t.push(this.db.prepare("UPDATE coordinator_join_requests\n SET status = ?, reviewed_at = ?, reviewed_by = ?\n WHERE request_id = ? AND status = 'pending'").bind(i, r, e.reviewedBy ?? null, e.requestId)), e.approved && (t.push(this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, display_name, enabled, created_at\n )\n SELECT group_id, device_id, public_key, fingerprint, display_name, 1, ?\n FROM coordinator_join_requests\n WHERE request_id = ?\n AND status = 'approved'\n AND reviewed_at = ?\n ON CONFLICT(group_id, device_id) DO UPDATE SET\n public_key = excluded.public_key,\n fingerprint = excluded.fingerprint,\n display_name = excluded.display_name,\n enabled = 1").bind(b(), e.requestId, r)), a)) {
|
|
558
|
+
o = C(12);
|
|
559
|
+
let n = b();
|
|
560
|
+
t.push(this.db.prepare("INSERT INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n ) SELECT ?, ?, ?, ?, ?, ?, ?, NULL\n WHERE EXISTS (\n SELECT 1 FROM coordinator_join_requests\n WHERE request_id = ? AND status = 'approved' AND reviewed_at = ?\n )").bind(o, a.groupId, a.seedDeviceId, a.workerDeviceId, a.expiresAt, n, a.createdBy ?? null, e.requestId, r));
|
|
280
561
|
}
|
|
281
562
|
await this.db.batch(t);
|
|
282
563
|
} else {
|
|
@@ -286,182 +567,216 @@ var D = class {
|
|
|
286
567
|
fingerprint: t.fingerprint,
|
|
287
568
|
publicKey: t.public_key,
|
|
288
569
|
displayName: (t.display_name ?? "").trim() || null
|
|
289
|
-
}),
|
|
290
|
-
let e = await this.createBootstrapGrant(
|
|
291
|
-
n = e.grant_id,
|
|
570
|
+
}), a)) {
|
|
571
|
+
let e = await this.createBootstrapGrant(a);
|
|
572
|
+
n = e.grant_id, o = e.grant_id;
|
|
292
573
|
}
|
|
293
|
-
if (await
|
|
574
|
+
if (await J(this.db.prepare("UPDATE coordinator_join_requests\n SET status = ?, reviewed_at = ?, reviewed_by = ?\n WHERE request_id = ? AND status = 'pending'").bind(i, r, e.reviewedBy ?? null, e.requestId)) === 0) {
|
|
294
575
|
n && await this.revokeBootstrapGrant(n);
|
|
295
|
-
let t = await
|
|
576
|
+
let t = await q(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
|
|
296
577
|
return t ? {
|
|
297
|
-
...
|
|
578
|
+
...h(t),
|
|
298
579
|
_no_transition: !0
|
|
299
580
|
} : null;
|
|
300
581
|
}
|
|
301
582
|
}
|
|
302
|
-
let
|
|
303
|
-
if (!
|
|
304
|
-
let
|
|
583
|
+
let s = await q(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
|
|
584
|
+
if (!s) return null;
|
|
585
|
+
let c = a ? o ? await this.getBootstrapGrant(o) : await this.createBootstrapGrant(a) : null;
|
|
305
586
|
return {
|
|
306
|
-
...
|
|
307
|
-
bootstrap_grant:
|
|
587
|
+
...h(s),
|
|
588
|
+
bootstrap_grant: c
|
|
308
589
|
};
|
|
309
590
|
}
|
|
310
591
|
async createReciprocalApproval(e) {
|
|
311
|
-
let t = e.groupId.trim(), n = e.requestingDeviceId.trim(),
|
|
312
|
-
if (!t || !n || !
|
|
313
|
-
if (n ===
|
|
314
|
-
let
|
|
315
|
-
if (
|
|
316
|
-
let
|
|
317
|
-
if (
|
|
318
|
-
let e =
|
|
319
|
-
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e,
|
|
592
|
+
let t = e.groupId.trim(), n = e.requestingDeviceId.trim(), r = e.requestedDeviceId.trim();
|
|
593
|
+
if (!t || !n || !r) throw Error("groupId, requestingDeviceId, and requestedDeviceId are required.");
|
|
594
|
+
if (n === r) throw Error("requesting and requested device ids must differ.");
|
|
595
|
+
let i = x(n, r), a = await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, n, r));
|
|
596
|
+
if (a) return h(a);
|
|
597
|
+
let o = await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, r, n));
|
|
598
|
+
if (o) {
|
|
599
|
+
let e = b();
|
|
600
|
+
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, o.request_id).run(), h(await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(o.request_id)));
|
|
320
601
|
}
|
|
321
|
-
let
|
|
602
|
+
let s = C(12), c = b();
|
|
322
603
|
try {
|
|
323
|
-
await this.db.prepare("INSERT INTO coordinator_reciprocal_approvals(\n request_id,\n group_id,\n requesting_device_id,\n requested_device_id,\n pending_pair_low_device_id,\n pending_pair_high_device_id,\n status,\n created_at,\n resolved_at\n ) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, NULL)").bind(
|
|
604
|
+
await this.db.prepare("INSERT INTO coordinator_reciprocal_approvals(\n request_id,\n group_id,\n requesting_device_id,\n requested_device_id,\n pending_pair_low_device_id,\n pending_pair_high_device_id,\n status,\n created_at,\n resolved_at\n ) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, NULL)").bind(s, t, n, r, i.low, i.high, c).run();
|
|
324
605
|
} catch (e) {
|
|
325
|
-
if (!
|
|
326
|
-
let
|
|
327
|
-
if (
|
|
328
|
-
let
|
|
329
|
-
if (
|
|
330
|
-
let e =
|
|
331
|
-
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e,
|
|
606
|
+
if (!S(e)) throw e;
|
|
607
|
+
let i = await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, n, r));
|
|
608
|
+
if (i) return h(i);
|
|
609
|
+
let a = await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, r, n));
|
|
610
|
+
if (a) {
|
|
611
|
+
let e = b();
|
|
612
|
+
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, a.request_id).run(), h(await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(a.request_id)));
|
|
332
613
|
}
|
|
333
614
|
throw e;
|
|
334
615
|
}
|
|
335
|
-
return
|
|
616
|
+
return h(await q(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(s)));
|
|
336
617
|
}
|
|
337
618
|
async createBootstrapGrant(e) {
|
|
338
|
-
let t =
|
|
339
|
-
return await this.db.prepare("INSERT INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, NULL)").bind(n, t.groupId, t.seedDeviceId, t.workerDeviceId, t.expiresAt,
|
|
619
|
+
let t = O(e), n = C(12), r = b();
|
|
620
|
+
return await this.db.prepare("INSERT INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, NULL)").bind(n, t.groupId, t.seedDeviceId, t.workerDeviceId, t.expiresAt, r, t.createdBy).run(), h(await q(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE grant_id = ?").bind(n)));
|
|
340
621
|
}
|
|
341
622
|
async getScope(e) {
|
|
342
|
-
let t = await
|
|
343
|
-
return t ?
|
|
623
|
+
let t = await q(this.db.prepare("SELECT scope_id, label, kind, authority_type, coordinator_id, group_id,\n manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at\n FROM coordinator_scopes WHERE scope_id = ?").bind(e));
|
|
624
|
+
return t ? h(t) : null;
|
|
344
625
|
}
|
|
345
626
|
async getScopeMembership(e, t) {
|
|
346
|
-
let n = await
|
|
347
|
-
return n ?
|
|
627
|
+
let n = await q(this.db.prepare("SELECT scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,\n manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at\n FROM coordinator_scope_memberships\n WHERE scope_id = ? AND device_id = ?").bind(e, t));
|
|
628
|
+
return n ? h(n) : null;
|
|
348
629
|
}
|
|
349
630
|
async createScope(e) {
|
|
350
|
-
let t =
|
|
631
|
+
let t = N(e);
|
|
351
632
|
if (await this.getScope(t.scopeId)) throw Error("scopeId already exists.");
|
|
352
|
-
let n =
|
|
633
|
+
let n = b();
|
|
353
634
|
await this.db.prepare("INSERT INTO coordinator_scopes(\n scope_id, label, kind, authority_type, coordinator_id, group_id,\n manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").bind(t.scopeId, t.label, t.kind, t.authorityType, t.coordinatorId, t.groupId, t.manifestIssuerDeviceId, t.membershipEpoch, t.manifestHash, t.status, n, n).run();
|
|
354
635
|
let r = await this.getScope(t.scopeId);
|
|
355
636
|
if (!r) throw Error("scope insert returned no row");
|
|
356
637
|
return r;
|
|
357
638
|
}
|
|
358
639
|
async updateScope(e) {
|
|
359
|
-
let t =
|
|
640
|
+
let t = k(e.scopeId), n = t ? await this.getScope(t) : null;
|
|
360
641
|
if (!n) return null;
|
|
361
|
-
let r =
|
|
362
|
-
return await this.db.prepare("UPDATE coordinator_scopes\n SET label = ?,\n kind = ?,\n authority_type = ?,\n coordinator_id = ?,\n group_id = ?,\n manifest_issuer_device_id = ?,\n membership_epoch = ?,\n manifest_hash = ?,\n status = ?,\n updated_at = ?\n WHERE scope_id = ?").bind(r.label, r.kind, r.authorityType, r.coordinatorId, r.groupId, r.manifestIssuerDeviceId, r.membershipEpoch, r.manifestHash, r.status,
|
|
642
|
+
let r = I(e, n);
|
|
643
|
+
return await this.db.prepare("UPDATE coordinator_scopes\n SET label = ?,\n kind = ?,\n authority_type = ?,\n coordinator_id = ?,\n group_id = ?,\n manifest_issuer_device_id = ?,\n membership_epoch = ?,\n manifest_hash = ?,\n status = ?,\n updated_at = ?\n WHERE scope_id = ?").bind(r.label, r.kind, r.authorityType, r.coordinatorId, r.groupId, r.manifestIssuerDeviceId, r.membershipEpoch, r.manifestHash, r.status, b(), r.scopeId).run(), await this.getScope(r.scopeId);
|
|
363
644
|
}
|
|
364
645
|
async listScopes(e = {}) {
|
|
365
|
-
let t = [], n = [],
|
|
366
|
-
|
|
367
|
-
let
|
|
646
|
+
let t = [], n = [], r = k(e.coordinatorId), i = k(e.groupId), a = k(e.status);
|
|
647
|
+
r && (t.push("coordinator_id = ?"), n.push(r)), i && (t.push("group_id = ?"), n.push(i)), a ? (t.push("status = ?"), n.push(a)) : e.includeInactive || t.push("status = 'active'");
|
|
648
|
+
let o = t.length ? `WHERE ${t.join(" AND ")}` : "", s = this.db.prepare(`SELECT scope_id, label, kind, authority_type, coordinator_id, group_id,
|
|
368
649
|
manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at
|
|
369
|
-
FROM coordinator_scopes ${
|
|
650
|
+
FROM coordinator_scopes ${o}
|
|
370
651
|
ORDER BY coordinator_id ASC, group_id ASC, scope_id ASC`);
|
|
371
|
-
return (await
|
|
652
|
+
return (await K(n.length ? s.bind(...n) : s)).map((e) => h(e));
|
|
372
653
|
}
|
|
373
654
|
async grantScopeMembership(e) {
|
|
374
|
-
let t =
|
|
375
|
-
if (
|
|
376
|
-
let
|
|
377
|
-
if (
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
655
|
+
let t = o(e.effectId), n = m(e), a = await B(this.db, t);
|
|
656
|
+
if (a) return s(a, "grant", n), i(a);
|
|
657
|
+
let c = k(e.scopeId), l = k(e.deviceId), u = c ? await this.getScope(c) : null;
|
|
658
|
+
if (!u) throw new r("scope_not_found");
|
|
659
|
+
if (u.status !== "active") throw new r("scope_inactive");
|
|
660
|
+
let d = c && l ? await this.getScopeMembership(c, l) : null, f = L(e, u, d);
|
|
661
|
+
if (f.groupId && !await this.getEnrollment(f.groupId, f.deviceId)) throw new r("device_not_enrolled");
|
|
662
|
+
let p = b();
|
|
663
|
+
await U(this.db, [
|
|
664
|
+
this.db.prepare("INSERT INTO coordinator_scope_memberships(\n scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,\n manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at\n ) SELECT ?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?\n WHERE NOT EXISTS (\n SELECT 1 FROM coordinator_scope_membership_effect_receipts WHERE effect_id = ?\n )\n ON CONFLICT(scope_id, device_id) DO UPDATE SET\n role = excluded.role,\n status = 'active',\n membership_epoch = excluded.membership_epoch,\n coordinator_id = excluded.coordinator_id,\n group_id = excluded.group_id,\n manifest_issuer_device_id = excluded.manifest_issuer_device_id,\n manifest_hash = excluded.manifest_hash,\n signed_manifest_json = excluded.signed_manifest_json,\n updated_at = excluded.updated_at\n WHERE excluded.membership_epoch > coordinator_scope_memberships.membership_epoch\n OR (\n excluded.membership_epoch = coordinator_scope_memberships.membership_epoch\n AND coordinator_scope_memberships.status != 'revoked'\n )").bind(f.scopeId, f.deviceId, f.role, f.membershipEpoch, f.coordinatorId, f.groupId, f.manifestIssuerDeviceId, f.manifestHash, f.signedManifestJson, p, t),
|
|
665
|
+
V(this.db, {
|
|
666
|
+
effectId: t,
|
|
667
|
+
requestJson: n,
|
|
668
|
+
scopeId: f.scopeId,
|
|
669
|
+
deviceId: f.deviceId,
|
|
670
|
+
createdAt: p
|
|
671
|
+
}),
|
|
672
|
+
z(this.db, {
|
|
673
|
+
effectId: t,
|
|
674
|
+
requestJson: n,
|
|
675
|
+
action: "grant",
|
|
676
|
+
previous: d,
|
|
677
|
+
scopeId: f.scopeId,
|
|
678
|
+
deviceId: f.deviceId,
|
|
679
|
+
status: "active",
|
|
680
|
+
membershipEpoch: f.membershipEpoch,
|
|
681
|
+
updatedAt: p,
|
|
682
|
+
actorType: f.actorType,
|
|
683
|
+
actorId: f.actorId,
|
|
684
|
+
createdAt: p
|
|
685
|
+
})
|
|
686
|
+
]);
|
|
687
|
+
let h = await B(this.db, t);
|
|
688
|
+
if (!h) throw Error("scope membership grant was not applied.");
|
|
689
|
+
return s(h, "grant", n), i(h);
|
|
392
690
|
}
|
|
393
691
|
async revokeScopeMembership(e) {
|
|
394
|
-
let t =
|
|
692
|
+
let t = k(e.scopeId), n = k(e.deviceId);
|
|
395
693
|
if (!t || !n) throw Error("scopeId and deviceId are required.");
|
|
396
|
-
let
|
|
397
|
-
if (
|
|
398
|
-
|
|
399
|
-
|
|
694
|
+
let i = o(e.effectId), a = u(e), c = await B(this.db, i);
|
|
695
|
+
if (c) return s(c, "revoke", a), c.outcome_applied === 1;
|
|
696
|
+
let l = e.membershipEpoch == null ? null : M(e.membershipEpoch), d = k(e.groupId), f = d ? await this.getScope(t) : null;
|
|
697
|
+
if (d && d !== f?.group_id) throw new r("scope_group_mismatch");
|
|
698
|
+
let p = await this.getScopeMembership(t, n);
|
|
699
|
+
if (l != null && p && l <= p.membership_epoch) throw Error("membershipEpoch must increase on revoke.");
|
|
700
|
+
let m = b(), h = l ?? (p?.membership_epoch ?? -1) + 1, g = this.db.prepare("UPDATE coordinator_scope_memberships\n SET status = 'revoked',\n membership_epoch = CASE WHEN ? IS NULL THEN membership_epoch + 1 ELSE ? END,\n manifest_hash = COALESCE(?, manifest_hash),\n signed_manifest_json = COALESCE(?, signed_manifest_json),\n updated_at = ?\n WHERE scope_id = ? AND device_id = ? AND membership_epoch = ? AND status = ?\n AND NOT EXISTS (\n SELECT 1 FROM coordinator_scope_membership_effect_receipts WHERE effect_id = ?\n )").bind(l, l, k(e.manifestHash), k(e.signedManifestJson), m, t, n, p?.membership_epoch ?? -1, p?.status ?? "", i), _ = H(this.db, {
|
|
701
|
+
effectId: i,
|
|
702
|
+
requestJson: a,
|
|
703
|
+
scopeId: t,
|
|
704
|
+
deviceId: n,
|
|
705
|
+
createdAt: m
|
|
706
|
+
}), v = z(this.db, {
|
|
707
|
+
effectId: i,
|
|
708
|
+
requestJson: a,
|
|
400
709
|
action: "revoke",
|
|
401
|
-
previous:
|
|
710
|
+
previous: p,
|
|
402
711
|
scopeId: t,
|
|
403
712
|
deviceId: n,
|
|
404
713
|
status: "revoked",
|
|
405
|
-
membershipEpoch:
|
|
406
|
-
updatedAt:
|
|
407
|
-
actorType:
|
|
408
|
-
actorId:
|
|
409
|
-
createdAt:
|
|
410
|
-
})
|
|
714
|
+
membershipEpoch: h,
|
|
715
|
+
updatedAt: m,
|
|
716
|
+
actorType: k(e.actorType),
|
|
717
|
+
actorId: k(e.actorId),
|
|
718
|
+
createdAt: m
|
|
719
|
+
});
|
|
411
720
|
try {
|
|
412
|
-
|
|
721
|
+
await U(this.db, [
|
|
722
|
+
g,
|
|
723
|
+
_,
|
|
724
|
+
v
|
|
725
|
+
]);
|
|
413
726
|
} catch (e) {
|
|
414
727
|
let r = await this.getScopeMembership(t, n);
|
|
415
|
-
if (!r || r.membership_epoch !==
|
|
728
|
+
if (p && (!r || r.membership_epoch !== p.membership_epoch || r.status !== p.status)) return !1;
|
|
416
729
|
throw e;
|
|
417
730
|
}
|
|
418
|
-
|
|
731
|
+
let y = await B(this.db, i);
|
|
732
|
+
if (!y) throw Error("scope membership revoke receipt was not persisted.");
|
|
733
|
+
return s(y, "revoke", a), y.outcome_applied === 1;
|
|
419
734
|
}
|
|
420
735
|
async listScopeMemberships(e, t = !1) {
|
|
421
|
-
let n =
|
|
736
|
+
let n = k(e);
|
|
422
737
|
if (!n) throw Error("scopeId is required.");
|
|
423
|
-
let
|
|
424
|
-
return (await
|
|
738
|
+
let r = t ? "" : "AND status = 'active'";
|
|
739
|
+
return (await K(this.db.prepare(`SELECT scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,
|
|
425
740
|
manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at
|
|
426
741
|
FROM coordinator_scope_memberships
|
|
427
|
-
WHERE scope_id = ? ${
|
|
428
|
-
ORDER BY device_id ASC`).bind(n))).map((e) =>
|
|
742
|
+
WHERE scope_id = ? ${r}
|
|
743
|
+
ORDER BY device_id ASC`).bind(n))).map((e) => h(e));
|
|
429
744
|
}
|
|
430
745
|
async listScopeMembershipAuditEvents(e) {
|
|
431
|
-
let t =
|
|
746
|
+
let t = k(e.scopeId);
|
|
432
747
|
if (!t) throw Error("scopeId is required.");
|
|
433
|
-
let n =
|
|
748
|
+
let n = k(e.deviceId), r = R(e.limit), i = n ? "scope_id = ? AND device_id = ?" : "scope_id = ?", a = n ? [
|
|
434
749
|
t,
|
|
435
750
|
n,
|
|
436
|
-
|
|
437
|
-
] : [t,
|
|
438
|
-
return (await
|
|
751
|
+
r
|
|
752
|
+
] : [t, r];
|
|
753
|
+
return (await K(this.db.prepare(`SELECT event_id, effect_id, action, scope_id, device_id, role, status, membership_epoch,
|
|
439
754
|
previous_role, previous_status, previous_membership_epoch,
|
|
440
755
|
coordinator_id, group_id, actor_type, actor_id, manifest_hash, created_at
|
|
441
756
|
FROM coordinator_scope_membership_audit_log
|
|
442
|
-
WHERE ${
|
|
757
|
+
WHERE ${i}
|
|
443
758
|
ORDER BY event_id ASC
|
|
444
|
-
LIMIT ?`).bind(...
|
|
759
|
+
LIMIT ?`).bind(...a))).map((e) => h(e));
|
|
445
760
|
}
|
|
446
761
|
async getBootstrapGrant(e) {
|
|
447
|
-
let t = await
|
|
448
|
-
return t ?
|
|
762
|
+
let t = await q(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE grant_id = ?").bind(e));
|
|
763
|
+
return t ? h(t) : null;
|
|
449
764
|
}
|
|
450
765
|
async listBootstrapGrants(e) {
|
|
451
|
-
return (await
|
|
766
|
+
return (await K(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE group_id = ?\n ORDER BY created_at DESC, grant_id DESC").bind(e))).map((e) => h(e));
|
|
452
767
|
}
|
|
453
|
-
async revokeBootstrapGrant(e, t =
|
|
454
|
-
return await
|
|
768
|
+
async revokeBootstrapGrant(e, t = b()) {
|
|
769
|
+
return await J(this.db.prepare("UPDATE coordinator_bootstrap_grants\n SET revoked_at = COALESCE(revoked_at, ?)\n WHERE grant_id = ?").bind(t, e)) > 0;
|
|
455
770
|
}
|
|
456
771
|
async listReciprocalApprovals(e) {
|
|
457
772
|
let t = e.direction === "incoming" ? "requested_device_id" : "requesting_device_id", n = e.status?.trim() || "pending";
|
|
458
|
-
return (await
|
|
773
|
+
return (await K(this.db.prepare(`SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at
|
|
459
774
|
FROM coordinator_reciprocal_approvals
|
|
460
775
|
WHERE group_id = ? AND ${t} = ? AND status = ?
|
|
461
|
-
ORDER BY created_at ASC, request_id ASC`).bind(e.groupId, e.deviceId, n))).map((e) =>
|
|
776
|
+
ORDER BY created_at ASC, request_id ASC`).bind(e.groupId, e.deviceId, n))).map((e) => h(e));
|
|
462
777
|
}
|
|
463
778
|
async upsertPresence(e) {
|
|
464
|
-
let t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() + e.ttlS * 1e3).toISOString(), r =
|
|
779
|
+
let t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() + e.ttlS * 1e3).toISOString(), r = y([], e.addresses);
|
|
465
780
|
return await this.db.prepare("INSERT INTO presence_records(group_id, device_id, addresses_json, last_seen_at, expires_at, capabilities_json)\n VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT(group_id, device_id) DO UPDATE SET\n addresses_json = excluded.addresses_json,\n last_seen_at = excluded.last_seen_at,\n expires_at = excluded.expires_at,\n capabilities_json = excluded.capabilities_json").bind(e.groupId, e.deviceId, JSON.stringify(r), t.toISOString(), n, JSON.stringify(e.capabilities ?? {})).run(), {
|
|
466
781
|
group_id: e.groupId,
|
|
467
782
|
device_id: e.deviceId,
|
|
@@ -470,14 +785,14 @@ var D = class {
|
|
|
470
785
|
};
|
|
471
786
|
}
|
|
472
787
|
async listGroupPeers(e, t) {
|
|
473
|
-
let n =
|
|
474
|
-
return (await
|
|
788
|
+
let n = b();
|
|
789
|
+
return (await K(this.db.prepare("SELECT enrolled_devices.device_id, enrolled_devices.public_key, enrolled_devices.fingerprint, enrolled_devices.display_name,\n presence_records.addresses_json, presence_records.last_seen_at, presence_records.expires_at,\n presence_records.capabilities_json\n FROM enrolled_devices\n LEFT JOIN presence_records\n ON presence_records.group_id = enrolled_devices.group_id\n AND presence_records.device_id = enrolled_devices.device_id\n WHERE enrolled_devices.group_id = ?\n AND enrolled_devices.enabled = 1\n AND enrolled_devices.device_id != ?\n ORDER BY enrolled_devices.device_id ASC").bind(e, t))).map((e) => {
|
|
475
790
|
let t = String(e.expires_at ?? "").trim(), r = !0;
|
|
476
791
|
if (t) {
|
|
477
792
|
let e = new Date(t);
|
|
478
793
|
r = Number.isNaN(e.getTime()) || e.toISOString() <= n;
|
|
479
794
|
}
|
|
480
|
-
let i = r ? [] :
|
|
795
|
+
let i = r ? [] : y([], JSON.parse(String(e.addresses_json ?? "[]")));
|
|
481
796
|
return {
|
|
482
797
|
device_id: String(e.device_id ?? ""),
|
|
483
798
|
public_key: String(e.public_key ?? ""),
|
|
@@ -494,9 +809,9 @@ var D = class {
|
|
|
494
809
|
};
|
|
495
810
|
//#endregion
|
|
496
811
|
//#region src/d1-coordinator-runtime.ts
|
|
497
|
-
function
|
|
498
|
-
return
|
|
499
|
-
storeFactory: () => new
|
|
812
|
+
function X(e) {
|
|
813
|
+
return p({
|
|
814
|
+
storeFactory: () => new Y(e.db),
|
|
500
815
|
runtime: {
|
|
501
816
|
adminSecret: () => String(e.adminSecret ?? "").trim() || null,
|
|
502
817
|
now: e.now ?? (() => (/* @__PURE__ */ new Date()).toISOString())
|
|
@@ -505,6 +820,6 @@ function O(e) {
|
|
|
505
820
|
});
|
|
506
821
|
}
|
|
507
822
|
//#endregion
|
|
508
|
-
export {
|
|
823
|
+
export { Y as D1CoordinatorStore, c as DEFAULT_TIME_WINDOW_S, X as createD1CoordinatorApp };
|
|
509
824
|
|
|
510
825
|
//# sourceMappingURL=cloudflare-coordinator.js.map
|