@codemem/core 0.36.0 → 0.37.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/better-sqlite-coordinator-store.d.ts.map +1 -1
- package/dist/{coordinator-api-CbONcz8J.js → coordinator-api-hZ1RVJUN.js} +132 -124
- package/dist/coordinator-api-hZ1RVJUN.js.map +1 -0
- package/dist/coordinator-api.d.ts.map +1 -1
- package/dist/coordinator-runtime.d.ts +5 -0
- package/dist/coordinator-runtime.d.ts.map +1 -1
- package/dist/coordinator-store-contract.d.ts +8 -0
- package/dist/coordinator-store-contract.d.ts.map +1 -1
- package/dist/d1-coordinator-store.d.ts.map +1 -1
- package/dist/db.d.ts +10 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/filters.d.ts +11 -0
- package/dist/filters.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4645 -4336
- package/dist/index.js.map +1 -1
- package/dist/internal/cloudflare-coordinator.js +193 -188
- package/dist/internal/cloudflare-coordinator.js.map +1 -1
- package/dist/observer-config.d.ts.map +1 -1
- package/dist/pack.d.ts.map +1 -1
- package/dist/raw-event-sweeper.d.ts.map +1 -1
- package/dist/request-rate-limit.d.ts +11 -0
- package/dist/request-rate-limit.d.ts.map +1 -1
- package/dist/scope-backfill.d.ts +2 -1
- package/dist/scope-backfill.d.ts.map +1 -1
- package/dist/scope-resolution.d.ts +34 -0
- package/dist/scope-resolution.d.ts.map +1 -1
- package/dist/search.d.ts +3 -0
- package/dist/search.d.ts.map +1 -1
- package/dist/store.d.ts +41 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/sync-bootstrap.d.ts +10 -0
- package/dist/sync-bootstrap.d.ts.map +1 -1
- package/dist/sync-pass.d.ts.map +1 -1
- package/dist/sync-replication.d.ts +1 -0
- package/dist/sync-replication.d.ts.map +1 -1
- package/dist/sync-retention-runner.d.ts +1 -0
- package/dist/sync-retention-runner.d.ts.map +1 -1
- package/dist/vectors.d.ts +2 -4
- package/dist/vectors.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/coordinator-api-CbONcz8J.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as e, r as t, t as n } from "../coordinator-api-hZ1RVJUN.js";
|
|
2
2
|
//#region src/d1-coordinator-store.ts
|
|
3
|
-
function
|
|
3
|
+
function r(e) {
|
|
4
4
|
if (e == null) throw Error("expected row");
|
|
5
5
|
return e;
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function i(e) {
|
|
8
8
|
let t = e.trim();
|
|
9
9
|
if (!t) return "";
|
|
10
10
|
let n = t.includes("://") ? t : `http://${t}`;
|
|
@@ -15,7 +15,7 @@ function r(e) {
|
|
|
15
15
|
return "";
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function a(e) {
|
|
19
19
|
if (!e) return "";
|
|
20
20
|
try {
|
|
21
21
|
let t = new URL(e), n = t.hostname.toLowerCase();
|
|
@@ -23,18 +23,18 @@ function i(e) {
|
|
|
23
23
|
} catch {}
|
|
24
24
|
return e;
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
let n = [],
|
|
26
|
+
function o(e, t) {
|
|
27
|
+
let n = [], r = /* @__PURE__ */ new Set();
|
|
28
28
|
for (let o of [...e, ...t]) {
|
|
29
|
-
let e =
|
|
30
|
-
!e ||
|
|
29
|
+
let e = i(o), t = a(e);
|
|
30
|
+
!e || r.has(t) || (r.add(t), n.push(e));
|
|
31
31
|
}
|
|
32
32
|
return n;
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function s() {
|
|
35
35
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function c(e, t) {
|
|
38
38
|
return e <= t ? {
|
|
39
39
|
low: e,
|
|
40
40
|
high: t
|
|
@@ -43,17 +43,17 @@ function s(e, t) {
|
|
|
43
43
|
high: e
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function l(e) {
|
|
47
47
|
return e instanceof Error && /unique|constraint/i.test(e.message);
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function u(e) {
|
|
50
50
|
let t = new Uint8Array(e);
|
|
51
51
|
globalThis.crypto.getRandomValues(t);
|
|
52
52
|
let n = [];
|
|
53
53
|
for (let e of t) n.push("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"[e % 64] ?? "A");
|
|
54
54
|
return n.join("");
|
|
55
55
|
}
|
|
56
|
-
function
|
|
56
|
+
function d(e) {
|
|
57
57
|
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
58
|
if (!t || !n || !r || !i) throw Error("groupId, seedDeviceId, workerDeviceId, and expiresAt are required.");
|
|
59
59
|
return {
|
|
@@ -64,95 +64,95 @@ function u(e) {
|
|
|
64
64
|
createdBy: a
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
-
function
|
|
67
|
+
function f(e) {
|
|
68
68
|
return e?.trim() || null;
|
|
69
69
|
}
|
|
70
|
-
function
|
|
70
|
+
function p(e, t = 0) {
|
|
71
71
|
if (e == null) return t;
|
|
72
72
|
if (!Number.isFinite(e) || e < 0) throw Error("membershipEpoch must be non-negative.");
|
|
73
73
|
return Math.trunc(e);
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
let t =
|
|
75
|
+
function m(e) {
|
|
76
|
+
let t = f(e.scopeId), n = f(e.label);
|
|
77
77
|
if (!t || !n) throw Error("scopeId and label are required.");
|
|
78
78
|
return {
|
|
79
79
|
scopeId: t,
|
|
80
80
|
label: n,
|
|
81
|
-
kind:
|
|
82
|
-
authorityType:
|
|
83
|
-
coordinatorId:
|
|
84
|
-
groupId:
|
|
85
|
-
manifestIssuerDeviceId:
|
|
86
|
-
membershipEpoch:
|
|
87
|
-
manifestHash:
|
|
88
|
-
status:
|
|
81
|
+
kind: f(e.kind) ?? "user",
|
|
82
|
+
authorityType: f(e.authorityType) ?? "coordinator",
|
|
83
|
+
coordinatorId: f(e.coordinatorId),
|
|
84
|
+
groupId: f(e.groupId),
|
|
85
|
+
manifestIssuerDeviceId: f(e.manifestIssuerDeviceId),
|
|
86
|
+
membershipEpoch: p(e.membershipEpoch),
|
|
87
|
+
manifestHash: f(e.manifestHash),
|
|
88
|
+
status: f(e.status) ?? "active"
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
|
-
function
|
|
91
|
+
function h(e, t, n) {
|
|
92
92
|
if (e === void 0) return t;
|
|
93
|
-
let r =
|
|
93
|
+
let r = f(e);
|
|
94
94
|
if (!r) throw Error(`${n} must not be empty.`);
|
|
95
95
|
return r;
|
|
96
96
|
}
|
|
97
|
-
function h(e, t) {
|
|
98
|
-
return e === void 0 ? t : d(e);
|
|
99
|
-
}
|
|
100
97
|
function g(e, t) {
|
|
101
|
-
|
|
98
|
+
return e === void 0 ? t : f(e);
|
|
99
|
+
}
|
|
100
|
+
function _(e, t) {
|
|
101
|
+
let n = f(e.scopeId);
|
|
102
102
|
if (!n) throw Error("scopeId is required.");
|
|
103
|
-
let r = e.membershipEpoch == null ? null :
|
|
103
|
+
let r = e.membershipEpoch == null ? null : p(e.membershipEpoch);
|
|
104
104
|
if (r != null && r < t.membership_epoch) throw Error("membershipEpoch must not move backwards.");
|
|
105
105
|
return {
|
|
106
106
|
scopeId: n,
|
|
107
|
-
label:
|
|
108
|
-
kind:
|
|
109
|
-
authorityType:
|
|
110
|
-
coordinatorId:
|
|
111
|
-
groupId:
|
|
112
|
-
manifestIssuerDeviceId:
|
|
107
|
+
label: h(e.label, t.label, "label"),
|
|
108
|
+
kind: h(e.kind, t.kind, "kind"),
|
|
109
|
+
authorityType: h(e.authorityType, t.authority_type, "authorityType"),
|
|
110
|
+
coordinatorId: g(e.coordinatorId, t.coordinator_id),
|
|
111
|
+
groupId: g(e.groupId, t.group_id),
|
|
112
|
+
manifestIssuerDeviceId: g(e.manifestIssuerDeviceId, t.manifest_issuer_device_id),
|
|
113
113
|
membershipEpoch: r ?? t.membership_epoch,
|
|
114
|
-
manifestHash:
|
|
115
|
-
status:
|
|
114
|
+
manifestHash: g(e.manifestHash, t.manifest_hash),
|
|
115
|
+
status: h(e.status, t.status, "status")
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
-
function
|
|
119
|
-
let r =
|
|
118
|
+
function v(e, t, n) {
|
|
119
|
+
let r = f(e.scopeId), i = f(e.deviceId);
|
|
120
120
|
if (!r || !i) throw Error("scopeId and deviceId are required.");
|
|
121
|
-
let a =
|
|
121
|
+
let a = f(e.coordinatorId), o = f(e.groupId);
|
|
122
122
|
if (a && a !== t?.coordinator_id) throw Error("membership coordinatorId must match the scope coordinatorId.");
|
|
123
123
|
if (o && o !== t?.group_id) throw Error("membership groupId must match the scope groupId.");
|
|
124
|
-
let s = e.membershipEpoch == null ? null :
|
|
124
|
+
let s = e.membershipEpoch == null ? null : p(e.membershipEpoch), c = t?.membership_epoch ?? 0;
|
|
125
125
|
if (s != null && s < c) throw Error("membershipEpoch must not be lower than the scope membershipEpoch.");
|
|
126
126
|
if (s != null && n && s < (n.status === "revoked" ? n.membership_epoch + 1 : n.membership_epoch)) throw Error("membershipEpoch must not move backwards.");
|
|
127
127
|
let l = s ?? (n ? Math.max(c, n.membership_epoch + +(n.status === "revoked")) : c);
|
|
128
128
|
return {
|
|
129
129
|
scopeId: r,
|
|
130
130
|
deviceId: i,
|
|
131
|
-
role:
|
|
131
|
+
role: f(e.role) ?? "member",
|
|
132
132
|
membershipEpoch: l,
|
|
133
133
|
coordinatorId: t?.coordinator_id ?? null,
|
|
134
134
|
groupId: t?.group_id ?? null,
|
|
135
|
-
manifestIssuerDeviceId:
|
|
136
|
-
manifestHash:
|
|
137
|
-
signedManifestJson:
|
|
138
|
-
actorType:
|
|
139
|
-
actorId:
|
|
135
|
+
manifestIssuerDeviceId: f(e.manifestIssuerDeviceId) ?? t?.manifest_issuer_device_id ?? null,
|
|
136
|
+
manifestHash: f(e.manifestHash) ?? t?.manifest_hash ?? null,
|
|
137
|
+
signedManifestJson: f(e.signedManifestJson),
|
|
138
|
+
actorType: f(e.actorType),
|
|
139
|
+
actorId: f(e.actorId)
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
|
-
function
|
|
142
|
+
function y(e) {
|
|
143
143
|
return e == null || !Number.isFinite(e) ? 100 : Math.max(1, Math.min(1e3, Math.trunc(e)));
|
|
144
144
|
}
|
|
145
|
-
function
|
|
145
|
+
function b(e, t) {
|
|
146
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);
|
|
147
147
|
}
|
|
148
|
-
async function
|
|
148
|
+
async function x(e, t) {
|
|
149
149
|
if (!e.batch) throw Error("D1 batch support is required for audited scope membership changes.");
|
|
150
150
|
return await e.batch(t);
|
|
151
151
|
}
|
|
152
|
-
function
|
|
152
|
+
function S(e) {
|
|
153
153
|
return Number(e?.meta?.changes ?? 0);
|
|
154
154
|
}
|
|
155
|
-
function
|
|
155
|
+
function C(e) {
|
|
156
156
|
if (!e) return null;
|
|
157
157
|
let t = String(e.seedDeviceId ?? "").trim(), n = String(e.expiresAt ?? "").trim(), r = String(e.createdBy ?? "").trim() || null;
|
|
158
158
|
if (!t || !n) throw Error("bootstrapGrant.seedDeviceId and expiresAt are required.");
|
|
@@ -164,299 +164,304 @@ function S(e) {
|
|
|
164
164
|
createdBy: r
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
|
-
async function
|
|
167
|
+
async function w(e) {
|
|
168
168
|
let t = await e.all();
|
|
169
169
|
return Array.isArray(t?.results) ? t.results : [];
|
|
170
170
|
}
|
|
171
|
-
async function
|
|
171
|
+
async function T(e) {
|
|
172
172
|
return await e.first();
|
|
173
173
|
}
|
|
174
|
-
async function
|
|
174
|
+
async function E(e) {
|
|
175
175
|
let t = await e.run();
|
|
176
176
|
return Number(t?.meta?.changes ?? 0);
|
|
177
177
|
}
|
|
178
|
-
var
|
|
178
|
+
var D = class {
|
|
179
179
|
db;
|
|
180
180
|
constructor(e) {
|
|
181
181
|
this.db = e;
|
|
182
182
|
}
|
|
183
183
|
async close() {}
|
|
184
184
|
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,
|
|
185
|
+
await this.db.prepare("INSERT OR IGNORE INTO groups(group_id, display_name, archived_at, created_at) VALUES (?, ?, NULL, ?)").bind(e, t ?? null, s()).run();
|
|
186
186
|
}
|
|
187
187
|
async getGroup(e) {
|
|
188
|
-
let t = await
|
|
189
|
-
return t ?
|
|
188
|
+
let t = await T(this.db.prepare("SELECT group_id, display_name, archived_at, created_at FROM groups WHERE group_id = ?").bind(e));
|
|
189
|
+
return t ? r(t) : null;
|
|
190
190
|
}
|
|
191
191
|
async listGroups(e = !1) {
|
|
192
192
|
let t = e ? "" : "WHERE archived_at IS NULL";
|
|
193
|
-
return (await
|
|
193
|
+
return (await w(this.db.prepare(`SELECT group_id, display_name, archived_at, created_at FROM groups ${t} ORDER BY created_at ASC`))).map((e) => r(e));
|
|
194
194
|
}
|
|
195
195
|
async renameGroup(e, t) {
|
|
196
|
-
return await
|
|
196
|
+
return await E(this.db.prepare("UPDATE groups SET display_name = ? WHERE group_id = ?").bind(t, e)) > 0;
|
|
197
197
|
}
|
|
198
|
-
async archiveGroup(e, t =
|
|
199
|
-
return await
|
|
198
|
+
async archiveGroup(e, t = s()) {
|
|
199
|
+
return await E(this.db.prepare("UPDATE groups SET archived_at = ? WHERE group_id = ? AND archived_at IS NULL").bind(t, e)) > 0;
|
|
200
200
|
}
|
|
201
201
|
async unarchiveGroup(e) {
|
|
202
|
-
return await
|
|
202
|
+
return await E(this.db.prepare("UPDATE groups SET archived_at = NULL WHERE group_id = ? AND archived_at IS NOT NULL").bind(e)) > 0;
|
|
203
203
|
}
|
|
204
204
|
async enrollDevice(e, t) {
|
|
205
|
-
await this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, 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 display_name = excluded.display_name,\n enabled = 1").bind(e, t.deviceId, t.publicKey, t.fingerprint, t.displayName ?? null,
|
|
205
|
+
await this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, 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 display_name = excluded.display_name,\n enabled = 1").bind(e, t.deviceId, t.publicKey, t.fingerprint, t.displayName ?? null, s()).run();
|
|
206
206
|
}
|
|
207
207
|
async listEnrolledDevices(e, t) {
|
|
208
|
-
let
|
|
209
|
-
return (await
|
|
208
|
+
let n = t ? "" : "AND enabled = 1";
|
|
209
|
+
return (await w(this.db.prepare(`SELECT group_id, device_id, public_key, fingerprint, display_name, enabled, created_at
|
|
210
210
|
FROM enrolled_devices
|
|
211
|
-
WHERE group_id = ? ${
|
|
212
|
-
ORDER BY created_at ASC, device_id ASC`).bind(e))).map((e) =>
|
|
211
|
+
WHERE group_id = ? ${n}
|
|
212
|
+
ORDER BY created_at ASC, device_id ASC`).bind(e))).map((e) => r(e));
|
|
213
213
|
}
|
|
214
214
|
async getEnrollment(e, t) {
|
|
215
|
-
let
|
|
216
|
-
return
|
|
215
|
+
let n = await T(this.db.prepare("SELECT group_id, device_id, public_key, fingerprint, display_name, enabled, created_at\n FROM enrolled_devices\n WHERE group_id = ? AND device_id = ? AND enabled = 1").bind(e, t));
|
|
216
|
+
return n ? r(n) : null;
|
|
217
217
|
}
|
|
218
218
|
async renameDevice(e, t, n) {
|
|
219
|
-
return await
|
|
219
|
+
return await E(this.db.prepare("UPDATE enrolled_devices SET display_name = ?\n WHERE group_id = ? AND device_id = ?").bind(n, e, t)) > 0;
|
|
220
220
|
}
|
|
221
221
|
async setDeviceEnabled(e, t, n) {
|
|
222
|
-
return await
|
|
222
|
+
return await E(this.db.prepare("UPDATE enrolled_devices SET enabled = ?\n WHERE group_id = ? AND device_id = ?").bind(+!!n, e, t)) > 0;
|
|
223
223
|
}
|
|
224
224
|
async removeDevice(e, t) {
|
|
225
|
-
|
|
225
|
+
if (!this.db.batch) throw Error("D1 batch support is required for atomic device removal.");
|
|
226
|
+
return S((await this.db.batch([
|
|
227
|
+
this.db.prepare("DELETE FROM presence_records WHERE group_id = ? AND device_id = ?").bind(e, t),
|
|
228
|
+
this.db.prepare("DELETE FROM coordinator_reciprocal_approvals WHERE group_id = ? AND (requesting_device_id = ? OR requested_device_id = ?)").bind(e, t, t),
|
|
229
|
+
this.db.prepare("DELETE FROM enrolled_devices WHERE group_id = ? AND device_id = ?").bind(e, t)
|
|
230
|
+
]))[2]) > 0;
|
|
226
231
|
}
|
|
227
232
|
async recordNonce(e, t, n) {
|
|
228
|
-
return await
|
|
233
|
+
return await E(this.db.prepare("INSERT OR IGNORE INTO request_nonces(device_id, nonce, created_at) VALUES (?, ?, ?)").bind(e, t, n)) > 0;
|
|
229
234
|
}
|
|
230
235
|
async cleanupNonces(e) {
|
|
231
236
|
await this.db.prepare("DELETE FROM request_nonces WHERE created_at < ?").bind(e).run();
|
|
232
237
|
}
|
|
233
|
-
async createInvite(
|
|
234
|
-
let
|
|
235
|
-
return await this.db.prepare("INSERT INTO coordinator_invites(\n invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)").bind(
|
|
238
|
+
async createInvite(t) {
|
|
239
|
+
let n = s(), i = u(12), a = u(24), o = e(t.expiresAt), c = await this.getGroup(t.groupId);
|
|
240
|
+
return await this.db.prepare("INSERT INTO coordinator_invites(\n invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)").bind(i, t.groupId, a, t.policy, o, n, t.createdBy ?? null, c?.display_name ?? null).run(), r(await T(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites WHERE invite_id = ?").bind(i)));
|
|
236
241
|
}
|
|
237
242
|
async getInviteByToken(e) {
|
|
238
|
-
let t = await
|
|
239
|
-
return t ?
|
|
243
|
+
let t = await T(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites\n WHERE token = ?\n AND revoked_at IS NULL\n AND expires_at > ?").bind(e, s()));
|
|
244
|
+
return t ? r(t) : null;
|
|
240
245
|
}
|
|
241
246
|
async listInvites(e) {
|
|
242
|
-
return (await
|
|
247
|
+
return (await w(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites WHERE group_id = ?\n ORDER BY created_at DESC").bind(e))).map((e) => r(e));
|
|
243
248
|
}
|
|
244
249
|
async createJoinRequest(e) {
|
|
245
|
-
let t =
|
|
246
|
-
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(
|
|
250
|
+
let t = s(), n = u(12);
|
|
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(), r(await T(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)));
|
|
247
252
|
}
|
|
248
253
|
async listJoinRequests(e, t) {
|
|
249
|
-
let
|
|
250
|
-
return (await
|
|
254
|
+
let n = t ?? "pending";
|
|
255
|
+
return (await w(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) => r(e));
|
|
251
256
|
}
|
|
252
257
|
async reviewJoinRequest(e) {
|
|
253
|
-
let t = await
|
|
258
|
+
let t = await T(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));
|
|
254
259
|
if (!t) return null;
|
|
255
260
|
if (t.status !== "pending") return {
|
|
256
|
-
...
|
|
261
|
+
...r(t),
|
|
257
262
|
_no_transition: !0
|
|
258
263
|
};
|
|
259
|
-
let
|
|
260
|
-
if (e.approved &&
|
|
261
|
-
if (!await
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
...
|
|
264
|
+
let n = C(e.bootstrapGrant), i = s(), a = e.approved ? "approved" : "denied", o = null, c = null;
|
|
265
|
+
if (e.approved && n) {
|
|
266
|
+
if (!await T(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
|
+
if (n.seedDeviceId === t.device_id) throw Error("bootstrap grant seed and worker device ids must differ.");
|
|
268
|
+
o = {
|
|
269
|
+
...n,
|
|
265
270
|
groupId: t.group_id,
|
|
266
271
|
workerDeviceId: t.device_id
|
|
267
272
|
};
|
|
268
273
|
}
|
|
269
274
|
if (this.db.batch) {
|
|
270
275
|
let t = [];
|
|
271
|
-
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(a, i, 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(
|
|
272
|
-
c =
|
|
273
|
-
let n =
|
|
274
|
-
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(c,
|
|
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(a, i, 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(s(), e.requestId, i)), o)) {
|
|
277
|
+
c = u(12);
|
|
278
|
+
let n = s();
|
|
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(c, o.groupId, o.seedDeviceId, o.workerDeviceId, o.expiresAt, n, o.createdBy ?? null, e.requestId, i));
|
|
275
280
|
}
|
|
276
281
|
await this.db.batch(t);
|
|
277
282
|
} else {
|
|
278
|
-
let
|
|
283
|
+
let n = null;
|
|
279
284
|
if (e.approved && (await this.enrollDevice(t.group_id, {
|
|
280
285
|
deviceId: t.device_id,
|
|
281
286
|
fingerprint: t.fingerprint,
|
|
282
287
|
publicKey: t.public_key,
|
|
283
288
|
displayName: (t.display_name ?? "").trim() || null
|
|
284
|
-
}),
|
|
285
|
-
let e = await this.createBootstrapGrant(
|
|
286
|
-
|
|
289
|
+
}), o)) {
|
|
290
|
+
let e = await this.createBootstrapGrant(o);
|
|
291
|
+
n = e.grant_id, c = e.grant_id;
|
|
287
292
|
}
|
|
288
|
-
if (await
|
|
289
|
-
|
|
290
|
-
let t = await
|
|
293
|
+
if (await E(this.db.prepare("UPDATE coordinator_join_requests\n SET status = ?, reviewed_at = ?, reviewed_by = ?\n WHERE request_id = ? AND status = 'pending'").bind(a, i, e.reviewedBy ?? null, e.requestId)) === 0) {
|
|
294
|
+
n && await this.revokeBootstrapGrant(n);
|
|
295
|
+
let t = await T(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));
|
|
291
296
|
return t ? {
|
|
292
|
-
...
|
|
297
|
+
...r(t),
|
|
293
298
|
_no_transition: !0
|
|
294
299
|
} : null;
|
|
295
300
|
}
|
|
296
301
|
}
|
|
297
|
-
let
|
|
298
|
-
if (!
|
|
299
|
-
let d =
|
|
302
|
+
let l = await T(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));
|
|
303
|
+
if (!l) return null;
|
|
304
|
+
let d = o ? c ? await this.getBootstrapGrant(c) : await this.createBootstrapGrant(o) : null;
|
|
300
305
|
return {
|
|
301
|
-
...
|
|
306
|
+
...r(l),
|
|
302
307
|
bootstrap_grant: d
|
|
303
308
|
};
|
|
304
309
|
}
|
|
305
310
|
async createReciprocalApproval(e) {
|
|
306
|
-
let t = e.groupId.trim(),
|
|
307
|
-
if (!t || !
|
|
308
|
-
if (
|
|
309
|
-
let a =
|
|
310
|
-
if (
|
|
311
|
-
let d = await
|
|
311
|
+
let t = e.groupId.trim(), n = e.requestingDeviceId.trim(), i = e.requestedDeviceId.trim();
|
|
312
|
+
if (!t || !n || !i) throw Error("groupId, requestingDeviceId, and requestedDeviceId are required.");
|
|
313
|
+
if (n === i) throw Error("requesting and requested device ids must differ.");
|
|
314
|
+
let a = c(n, i), o = await T(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, i));
|
|
315
|
+
if (o) return r(o);
|
|
316
|
+
let d = await T(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, i, n));
|
|
312
317
|
if (d) {
|
|
313
|
-
let e =
|
|
314
|
-
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, d.request_id).run(),
|
|
318
|
+
let e = s();
|
|
319
|
+
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, d.request_id).run(), r(await T(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(d.request_id)));
|
|
315
320
|
}
|
|
316
|
-
let f =
|
|
321
|
+
let f = u(12), p = s();
|
|
317
322
|
try {
|
|
318
|
-
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(f, t,
|
|
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(f, t, n, i, a.low, a.high, p).run();
|
|
319
324
|
} catch (e) {
|
|
320
|
-
if (!
|
|
321
|
-
let a = await
|
|
322
|
-
if (a) return
|
|
323
|
-
let
|
|
324
|
-
if (
|
|
325
|
-
let e =
|
|
326
|
-
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e,
|
|
325
|
+
if (!l(e)) throw e;
|
|
326
|
+
let a = await T(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, i));
|
|
327
|
+
if (a) return r(a);
|
|
328
|
+
let o = await T(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, i, n));
|
|
329
|
+
if (o) {
|
|
330
|
+
let e = s();
|
|
331
|
+
return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, o.request_id).run(), r(await T(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)));
|
|
327
332
|
}
|
|
328
333
|
throw e;
|
|
329
334
|
}
|
|
330
|
-
return
|
|
335
|
+
return r(await T(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(f)));
|
|
331
336
|
}
|
|
332
337
|
async createBootstrapGrant(e) {
|
|
333
|
-
let t =
|
|
334
|
-
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(
|
|
338
|
+
let t = d(e), n = u(12), i = s();
|
|
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, i, t.createdBy).run(), r(await T(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)));
|
|
335
340
|
}
|
|
336
341
|
async getScope(e) {
|
|
337
|
-
let t = await
|
|
338
|
-
return t ?
|
|
342
|
+
let t = await T(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));
|
|
343
|
+
return t ? r(t) : null;
|
|
339
344
|
}
|
|
340
345
|
async getScopeMembership(e, t) {
|
|
341
|
-
let
|
|
342
|
-
return
|
|
346
|
+
let n = await T(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));
|
|
347
|
+
return n ? r(n) : null;
|
|
343
348
|
}
|
|
344
349
|
async createScope(e) {
|
|
345
|
-
let t =
|
|
350
|
+
let t = m(e);
|
|
346
351
|
if (await this.getScope(t.scopeId)) throw Error("scopeId already exists.");
|
|
347
|
-
let n =
|
|
352
|
+
let n = s();
|
|
348
353
|
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();
|
|
349
354
|
let r = await this.getScope(t.scopeId);
|
|
350
355
|
if (!r) throw Error("scope insert returned no row");
|
|
351
356
|
return r;
|
|
352
357
|
}
|
|
353
358
|
async updateScope(e) {
|
|
354
|
-
let t =
|
|
359
|
+
let t = f(e.scopeId), n = t ? await this.getScope(t) : null;
|
|
355
360
|
if (!n) return null;
|
|
356
|
-
let r =
|
|
357
|
-
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,
|
|
361
|
+
let r = _(e, n);
|
|
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, s(), r.scopeId).run(), await this.getScope(r.scopeId);
|
|
358
363
|
}
|
|
359
364
|
async listScopes(e = {}) {
|
|
360
|
-
let t = [],
|
|
361
|
-
i && (t.push("coordinator_id = ?"),
|
|
365
|
+
let t = [], n = [], i = f(e.coordinatorId), a = f(e.groupId), o = f(e.status);
|
|
366
|
+
i && (t.push("coordinator_id = ?"), n.push(i)), a && (t.push("group_id = ?"), n.push(a)), o ? (t.push("status = ?"), n.push(o)) : e.includeInactive || t.push("status = 'active'");
|
|
362
367
|
let s = t.length ? `WHERE ${t.join(" AND ")}` : "", c = this.db.prepare(`SELECT scope_id, label, kind, authority_type, coordinator_id, group_id,
|
|
363
368
|
manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at
|
|
364
369
|
FROM coordinator_scopes ${s}
|
|
365
370
|
ORDER BY coordinator_id ASC, group_id ASC, scope_id ASC`);
|
|
366
|
-
return (await
|
|
371
|
+
return (await w(n.length ? c.bind(...n) : c)).map((e) => r(e));
|
|
367
372
|
}
|
|
368
373
|
async grantScopeMembership(e) {
|
|
369
|
-
let t =
|
|
374
|
+
let t = f(e.scopeId), n = f(e.deviceId), i = t ? await this.getScope(t) : null;
|
|
370
375
|
if (!i) throw Error("scopeId must reference an existing scope.");
|
|
371
|
-
let a = t &&
|
|
372
|
-
if (
|
|
373
|
-
let c =
|
|
374
|
-
if (
|
|
376
|
+
let a = t && n ? await this.getScopeMembership(t, n) : null, o = v(e, i, a);
|
|
377
|
+
if (o.groupId && !await this.getEnrollment(o.groupId, o.deviceId)) throw Error("device must be enrolled and enabled in the scope group.");
|
|
378
|
+
let c = s();
|
|
379
|
+
if (S((await x(this.db, [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 ) VALUES (?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?)\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(o.scopeId, o.deviceId, o.role, o.membershipEpoch, o.coordinatorId, o.groupId, o.manifestIssuerDeviceId, o.manifestHash, o.signedManifestJson, c), b(this.db, {
|
|
375
380
|
action: "grant",
|
|
376
381
|
previous: a,
|
|
377
|
-
scopeId:
|
|
378
|
-
deviceId:
|
|
382
|
+
scopeId: o.scopeId,
|
|
383
|
+
deviceId: o.deviceId,
|
|
379
384
|
status: "active",
|
|
380
|
-
membershipEpoch:
|
|
385
|
+
membershipEpoch: o.membershipEpoch,
|
|
381
386
|
updatedAt: c,
|
|
382
|
-
actorType:
|
|
383
|
-
actorId:
|
|
387
|
+
actorType: o.actorType,
|
|
388
|
+
actorId: o.actorId,
|
|
384
389
|
createdAt: c
|
|
385
390
|
})]))[0]) <= 0) throw Error("scope membership grant was not applied.");
|
|
386
|
-
return
|
|
391
|
+
return r(await T(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(o.scopeId, o.deviceId)));
|
|
387
392
|
}
|
|
388
393
|
async revokeScopeMembership(e) {
|
|
389
|
-
let t =
|
|
394
|
+
let t = f(e.scopeId), n = f(e.deviceId);
|
|
390
395
|
if (!t || !n) throw Error("scopeId and deviceId are required.");
|
|
391
|
-
let r = e.membershipEpoch == null ? null :
|
|
396
|
+
let r = e.membershipEpoch == null ? null : p(e.membershipEpoch), i = await this.getScopeMembership(t, n);
|
|
392
397
|
if (!i) return !1;
|
|
393
398
|
if (r != null && i && r <= i.membership_epoch) throw Error("membershipEpoch must increase on revoke.");
|
|
394
|
-
let a =
|
|
399
|
+
let a = s(), o = r ?? i.membership_epoch + 1, c = 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 = ?").bind(r, r, f(e.manifestHash), f(e.signedManifestJson), a, t, n, i.membership_epoch, i.status), l = b(this.db, {
|
|
395
400
|
action: "revoke",
|
|
396
401
|
previous: i,
|
|
397
402
|
scopeId: t,
|
|
398
403
|
deviceId: n,
|
|
399
404
|
status: "revoked",
|
|
400
|
-
membershipEpoch:
|
|
405
|
+
membershipEpoch: o,
|
|
401
406
|
updatedAt: a,
|
|
402
|
-
actorType:
|
|
403
|
-
actorId:
|
|
407
|
+
actorType: f(e.actorType),
|
|
408
|
+
actorId: f(e.actorId),
|
|
404
409
|
createdAt: a
|
|
405
410
|
}), u;
|
|
406
411
|
try {
|
|
407
|
-
u = await
|
|
412
|
+
u = await x(this.db, [c, l]);
|
|
408
413
|
} catch (e) {
|
|
409
414
|
let r = await this.getScopeMembership(t, n);
|
|
410
415
|
if (!r || r.membership_epoch !== i.membership_epoch || r.status !== i.status) return !1;
|
|
411
416
|
throw e;
|
|
412
417
|
}
|
|
413
|
-
return !(
|
|
418
|
+
return !(S(u[0]) <= 0);
|
|
414
419
|
}
|
|
415
420
|
async listScopeMemberships(e, t = !1) {
|
|
416
|
-
let
|
|
417
|
-
if (!
|
|
421
|
+
let n = f(e);
|
|
422
|
+
if (!n) throw Error("scopeId is required.");
|
|
418
423
|
let i = t ? "" : "AND status = 'active'";
|
|
419
|
-
return (await
|
|
424
|
+
return (await w(this.db.prepare(`SELECT scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,
|
|
420
425
|
manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at
|
|
421
426
|
FROM coordinator_scope_memberships
|
|
422
427
|
WHERE scope_id = ? ${i}
|
|
423
|
-
ORDER BY device_id ASC`).bind(
|
|
428
|
+
ORDER BY device_id ASC`).bind(n))).map((e) => r(e));
|
|
424
429
|
}
|
|
425
430
|
async listScopeMembershipAuditEvents(e) {
|
|
426
|
-
let t =
|
|
431
|
+
let t = f(e.scopeId);
|
|
427
432
|
if (!t) throw Error("scopeId is required.");
|
|
428
|
-
let
|
|
433
|
+
let n = f(e.deviceId), i = y(e.limit), a = n ? "scope_id = ? AND device_id = ?" : "scope_id = ?", o = n ? [
|
|
429
434
|
t,
|
|
430
|
-
|
|
435
|
+
n,
|
|
431
436
|
i
|
|
432
437
|
] : [t, i];
|
|
433
|
-
return (await
|
|
438
|
+
return (await w(this.db.prepare(`SELECT event_id, action, scope_id, device_id, role, status, membership_epoch,
|
|
434
439
|
previous_role, previous_status, previous_membership_epoch,
|
|
435
440
|
coordinator_id, group_id, actor_type, actor_id, manifest_hash, created_at
|
|
436
441
|
FROM coordinator_scope_membership_audit_log
|
|
437
442
|
WHERE ${a}
|
|
438
443
|
ORDER BY event_id ASC
|
|
439
|
-
LIMIT ?`).bind(...o))).map((e) =>
|
|
444
|
+
LIMIT ?`).bind(...o))).map((e) => r(e));
|
|
440
445
|
}
|
|
441
446
|
async getBootstrapGrant(e) {
|
|
442
|
-
let t = await
|
|
443
|
-
return t ?
|
|
447
|
+
let t = await T(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));
|
|
448
|
+
return t ? r(t) : null;
|
|
444
449
|
}
|
|
445
450
|
async listBootstrapGrants(e) {
|
|
446
|
-
return (await
|
|
451
|
+
return (await w(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) => r(e));
|
|
447
452
|
}
|
|
448
|
-
async revokeBootstrapGrant(e, t =
|
|
449
|
-
return await
|
|
453
|
+
async revokeBootstrapGrant(e, t = s()) {
|
|
454
|
+
return await E(this.db.prepare("UPDATE coordinator_bootstrap_grants\n SET revoked_at = COALESCE(revoked_at, ?)\n WHERE grant_id = ?").bind(t, e)) > 0;
|
|
450
455
|
}
|
|
451
456
|
async listReciprocalApprovals(e) {
|
|
452
|
-
let t = e.direction === "incoming" ? "requested_device_id" : "requesting_device_id",
|
|
453
|
-
return (await
|
|
457
|
+
let t = e.direction === "incoming" ? "requested_device_id" : "requesting_device_id", n = e.status?.trim() || "pending";
|
|
458
|
+
return (await w(this.db.prepare(`SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at
|
|
454
459
|
FROM coordinator_reciprocal_approvals
|
|
455
460
|
WHERE group_id = ? AND ${t} = ? AND status = ?
|
|
456
|
-
ORDER BY created_at ASC, request_id ASC`).bind(e.groupId, e.deviceId,
|
|
461
|
+
ORDER BY created_at ASC, request_id ASC`).bind(e.groupId, e.deviceId, n))).map((e) => r(e));
|
|
457
462
|
}
|
|
458
463
|
async upsertPresence(e) {
|
|
459
|
-
let t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() + e.ttlS * 1e3).toISOString(), r =
|
|
464
|
+
let t = /* @__PURE__ */ new Date(), n = new Date(t.getTime() + e.ttlS * 1e3).toISOString(), r = o([], e.addresses);
|
|
460
465
|
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(), {
|
|
461
466
|
group_id: e.groupId,
|
|
462
467
|
device_id: e.deviceId,
|
|
@@ -465,14 +470,14 @@ var E = class {
|
|
|
465
470
|
};
|
|
466
471
|
}
|
|
467
472
|
async listGroupPeers(e, t) {
|
|
468
|
-
let n =
|
|
469
|
-
return (await
|
|
473
|
+
let n = s();
|
|
474
|
+
return (await w(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) => {
|
|
470
475
|
let t = String(e.expires_at ?? "").trim(), r = !0;
|
|
471
476
|
if (t) {
|
|
472
477
|
let e = new Date(t);
|
|
473
478
|
r = Number.isNaN(e.getTime()) || e.toISOString() <= n;
|
|
474
479
|
}
|
|
475
|
-
let i = r ? [] :
|
|
480
|
+
let i = r ? [] : o([], JSON.parse(String(e.addresses_json ?? "[]")));
|
|
476
481
|
return {
|
|
477
482
|
device_id: String(e.device_id ?? ""),
|
|
478
483
|
public_key: String(e.public_key ?? ""),
|
|
@@ -489,9 +494,9 @@ var E = class {
|
|
|
489
494
|
};
|
|
490
495
|
//#endregion
|
|
491
496
|
//#region src/d1-coordinator-runtime.ts
|
|
492
|
-
function
|
|
493
|
-
return
|
|
494
|
-
storeFactory: () => new
|
|
497
|
+
function O(e) {
|
|
498
|
+
return n({
|
|
499
|
+
storeFactory: () => new D(e.db),
|
|
495
500
|
runtime: {
|
|
496
501
|
adminSecret: () => String(e.adminSecret ?? "").trim() || null,
|
|
497
502
|
now: e.now ?? (() => (/* @__PURE__ */ new Date()).toISOString())
|
|
@@ -500,6 +505,6 @@ function D(e) {
|
|
|
500
505
|
});
|
|
501
506
|
}
|
|
502
507
|
//#endregion
|
|
503
|
-
export {
|
|
508
|
+
export { D as D1CoordinatorStore, t as DEFAULT_TIME_WINDOW_S, O as createD1CoordinatorApp };
|
|
504
509
|
|
|
505
510
|
//# sourceMappingURL=cloudflare-coordinator.js.map
|