@indigoai-us/hq-cloud 6.18.99 → 6.18.100

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.
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Push identity fence (feedback_3bf773c5).
3
+ *
4
+ * The sync root is one folder on disk. When a different person signs in on the
5
+ * same machine, files the previous person left in that folder look like new
6
+ * local files to the new person's first push, and would be uploaded into the
7
+ * new person's vault (the personal vault) or under the new person's name (a
8
+ * shared company vault). hq-cloud#1028 binds the personal journal to the
9
+ * signed-in identity so a switch cannot delete files; this fence covers the
10
+ * other direction.
11
+ *
12
+ * Contract:
13
+ * - A machine switch marker is written whenever the personal journal bind sees
14
+ * a different person (or an interrupted or unproven switch). It carries a new
15
+ * id each time.
16
+ * - One record per sync scope (journal slug) names the person who last pushed
17
+ * it: the personal vault uid, or the Cognito sub for a company vault, plus
18
+ * the Cognito sub when known, and the id of the last machine switch the scope
19
+ * has seen.
20
+ * - A scope is fenced for the pushing person when: its record names someone
21
+ * else; its record is unreadable; a machine switch happened since the scope
22
+ * last pushed (this covers every company scope, not only the personal one);
23
+ * or the scope has no record and this machine shows any sign of another
24
+ * person (a switch marker, another scope's record naming a different person,
25
+ * or the caller's evidence from the personal journal identity state). So
26
+ * deleting the fence state does not lift a fence on a machine that more than
27
+ * one person has used.
28
+ * - A company scope is also fenced when this machine's personal sync belongs
29
+ * to someone (hq-cloud#1028 owner record) and the pusher cannot be proven to
30
+ * be that person: the runner records each signed-in person's Cognito sub and
31
+ * personal vault uid before any push, so a company push that runs before the
32
+ * new person's personal sync still fails closed.
33
+ * - A push with no identity at all is held whenever this machine has seen a
34
+ * switch (see share.ts); it cannot be released, and the next push with an
35
+ * identity is admitted normally.
36
+ * - While a scope is fenced, its push uploads nothing and deletes nothing
37
+ * remotely. Local files are never touched. This does not depend on file
38
+ * timestamps, so clock skew, future modification times and coarse
39
+ * filesystem timestamps (FAT, exFAT) cannot let a file through. The cost is
40
+ * that the signed-in person's own new files also wait until they decide.
41
+ * - A fence ends only by an explicit release from the person it was written
42
+ * for ({@link releasePushIdentityFence}). A single-person machine never sees
43
+ * the fence.
44
+ */
45
+ import * as crypto from "crypto";
46
+ import * as fs from "fs";
47
+ import * as path from "path";
48
+ import { fsyncWithCompatibility } from "./sync/fsync-compat.js";
49
+ const RECORD_FORMAT = "hq-push-identity@2";
50
+ const MACHINE_FORMAT = "hq-push-identity-machine@1";
51
+ const PERSON_FORMAT = "hq-push-identity-person@1";
52
+ const HELD_SAMPLE_CAP = 50;
53
+ /**
54
+ * Record that Cognito `sub` signs in as personal vault `personalUid` on this
55
+ * machine. The sync runner writes it before any scope pushes; a personal push
56
+ * writes it too. Company pushes use it to check the pusher against the
57
+ * personal vault owner.
58
+ */
59
+ export function recordSignedInPerson(stateDir, sub, personalUid) {
60
+ if (!sub || !personalUid)
61
+ return;
62
+ const filePath = personPath(stateDir, sub);
63
+ const current = readPerson(filePath);
64
+ if (current.kind === "ok" && current.value === personalUid)
65
+ return;
66
+ writeJsonAtomic(filePath, { format: PERSON_FORMAT, sub, personalUid });
67
+ }
68
+ /** True when a switch marker exists (or cannot be read) on this machine. */
69
+ export function machineIdentitySwitchRecorded(stateDir) {
70
+ return readMachine(stateDir).kind !== "none";
71
+ }
72
+ /**
73
+ * Record that a different person signed in on this machine. Every scope is
74
+ * fenced on its next push.
75
+ */
76
+ export function recordMachineIdentitySwitch(stateDir, now = Date.now()) {
77
+ const marker = {
78
+ format: MACHINE_FORMAT,
79
+ id: `${now}-${process.pid}-${crypto.randomBytes(4).toString("hex")}`,
80
+ sinceMs: now,
81
+ };
82
+ writeJsonAtomic(machinePath(stateDir), marker);
83
+ }
84
+ /**
85
+ * Admit `uid` as the pusher for `journalSlug` and return the fence that
86
+ * applies to this push, if any. Fails closed on unreadable state.
87
+ */
88
+ export function admitPushIdentity(stateDir, journalSlug, uid, options = {}) {
89
+ const now = options.now ?? Date.now();
90
+ const sub = options.sub;
91
+ let marker = readMachine(stateDir);
92
+ if (marker.kind === "unreadable") {
93
+ recordMachineIdentitySwitch(stateDir, now);
94
+ marker = readMachine(stateDir);
95
+ }
96
+ const machine = marker.kind === "ok" ? marker.value : undefined;
97
+ const personalOwner = options.personalOwnerUid;
98
+ if (options.personalScope === true && sub)
99
+ recordSignedInPerson(stateDir, sub, uid);
100
+ const fenceNow = (previous) => {
101
+ const fence = { uid, sinceMs: machine?.sinceMs ?? now };
102
+ const recordSub = sub ?? previous?.sub;
103
+ writeRecord(stateDir, {
104
+ format: RECORD_FORMAT,
105
+ slug: journalSlug,
106
+ owner: uid,
107
+ ...(recordSub ? { sub: recordSub } : {}),
108
+ ...(machine ? { machineSwitchId: machine.id } : {}),
109
+ ...(typeof personalOwner === "string" ? { personalOwnerSeen: personalOwner } : {}),
110
+ fence,
111
+ });
112
+ return fence;
113
+ };
114
+ const read = readRecord(stateDir, journalSlug);
115
+ // A company pusher must be provably the person this machine's personal sync
116
+ // belongs to. When the signed-in person's personal uid is unknown, unreadable
117
+ // or different, fence the scope once for this owner state.
118
+ if (options.personalScope !== true && typeof personalOwner === "string") {
119
+ const seen = read.kind === "ok" ? read.value.personalOwnerSeen : undefined;
120
+ if (seen !== personalOwner) {
121
+ const mapped = sub ? readPerson(personPath(stateDir, sub)) : { kind: "none" };
122
+ const proven = personalOwner !== "unreadable" && mapped.kind === "ok" && mapped.value === personalOwner;
123
+ if (!proven)
124
+ return fenceNow(read.kind === "ok" ? read.value : undefined);
125
+ }
126
+ }
127
+ if (read.kind === "unreadable")
128
+ return fenceNow();
129
+ if (read.kind === "none") {
130
+ if (machine || options.otherIdentityEvidence === true || (sub && anotherPersonPushedHere(stateDir, sub))) {
131
+ return fenceNow();
132
+ }
133
+ writeRecord(stateDir, { format: RECORD_FORMAT, slug: journalSlug, owner: uid, ...(sub ? { sub } : {}) });
134
+ return undefined;
135
+ }
136
+ const record = read.value;
137
+ if (record.owner !== uid || (sub && record.sub && record.sub !== sub))
138
+ return fenceNow();
139
+ if (machine && record.machineSwitchId !== machine.id)
140
+ return fenceNow(record);
141
+ if (sub && !record.sub)
142
+ writeRecord(stateDir, { ...record, sub });
143
+ return record.fence?.uid === uid ? record.fence : undefined;
144
+ }
145
+ /** Remember how many files the last fenced push held, with a short sample. */
146
+ export function notePushIdentityHeld(stateDir, journalSlug, count, paths) {
147
+ const read = readRecord(stateDir, journalSlug);
148
+ if (read.kind !== "ok")
149
+ return;
150
+ writeRecord(stateDir, {
151
+ ...read.value,
152
+ held: { count, samplePaths: paths.slice(0, HELD_SAMPLE_CAP), at: new Date().toISOString() },
153
+ });
154
+ }
155
+ /** Every scope on this machine whose pushes are held, with its last held sample. */
156
+ export function listPushIdentityFences(stateDir) {
157
+ const out = [];
158
+ for (const filePath of recordFiles(stateDir)) {
159
+ const read = parseRecord(filePath);
160
+ if (read.kind !== "ok" || !read.value.fence)
161
+ continue;
162
+ out.push({
163
+ slug: read.value.slug,
164
+ uid: read.value.fence.uid,
165
+ sinceMs: read.value.fence.sinceMs,
166
+ ...(read.value.held ? { held: read.value.held } : {}),
167
+ });
168
+ }
169
+ return out.sort((a, b) => a.slug.localeCompare(b.slug));
170
+ }
171
+ /**
172
+ * The signed-in person confirms the files held after a switch are theirs to
173
+ * push. Only the person the fence was written for can release it.
174
+ */
175
+ export function releasePushIdentityFence(stateDir, journalSlug, uid) {
176
+ const read = readRecord(stateDir, journalSlug);
177
+ if (read.kind !== "ok" || read.value.owner !== uid || read.value.fence?.uid !== uid)
178
+ return false;
179
+ const released = {
180
+ format: RECORD_FORMAT,
181
+ slug: read.value.slug,
182
+ owner: read.value.owner,
183
+ ...(read.value.sub ? { sub: read.value.sub } : {}),
184
+ ...(read.value.machineSwitchId ? { machineSwitchId: read.value.machineSwitchId } : {}),
185
+ ...(read.value.personalOwnerSeen ? { personalOwnerSeen: read.value.personalOwnerSeen } : {}),
186
+ };
187
+ writeRecord(stateDir, released);
188
+ return true;
189
+ }
190
+ /**
191
+ * Release every fenced scope that belongs to one of `identities` (the
192
+ * signed-in person's personal vault uid and Cognito sub). Optionally limited
193
+ * to `slugs`. Returns the released scope slugs.
194
+ */
195
+ export function releasePushIdentityFences(stateDir, identities, slugs) {
196
+ const allowed = new Set(identities.filter((identity) => identity.length > 0));
197
+ const only = slugs ? new Set(slugs) : undefined;
198
+ const released = [];
199
+ for (const listing of listPushIdentityFences(stateDir)) {
200
+ if (!allowed.has(listing.uid))
201
+ continue;
202
+ if (only && !only.has(listing.slug))
203
+ continue;
204
+ if (releasePushIdentityFence(stateDir, listing.slug, listing.uid))
205
+ released.push(listing.slug);
206
+ }
207
+ return released;
208
+ }
209
+ /** True when any scope's record on this machine names a different person, or cannot be read. */
210
+ function anotherPersonPushedHere(stateDir, sub) {
211
+ for (const filePath of recordFiles(stateDir)) {
212
+ const read = parseRecord(filePath);
213
+ if (read.kind === "unreadable")
214
+ return true;
215
+ if (read.kind === "ok" && read.value.sub && read.value.sub !== sub)
216
+ return true;
217
+ }
218
+ return false;
219
+ }
220
+ function recordFiles(stateDir) {
221
+ const dir = path.join(stateDir, "push-identity");
222
+ let names;
223
+ try {
224
+ names = fs.readdirSync(dir);
225
+ }
226
+ catch (error) {
227
+ if (error.code === "ENOENT")
228
+ return [];
229
+ throw error;
230
+ }
231
+ return names
232
+ .filter((name) => name.startsWith("scope-") && name.endsWith(".json"))
233
+ .map((name) => path.join(dir, name));
234
+ }
235
+ function personPath(stateDir, sub) {
236
+ const id = crypto.createHash("sha256").update(sub).digest("hex").slice(0, 32);
237
+ return path.join(stateDir, "push-identity", `person-${id}.json`);
238
+ }
239
+ function readPerson(filePath) {
240
+ const raw = readText(filePath);
241
+ if (raw.kind !== "ok")
242
+ return raw;
243
+ try {
244
+ const parsed = JSON.parse(raw.value);
245
+ if (parsed?.format !== PERSON_FORMAT || typeof parsed.personalUid !== "string" || !parsed.personalUid) {
246
+ return { kind: "unreadable" };
247
+ }
248
+ return { kind: "ok", value: parsed.personalUid };
249
+ }
250
+ catch {
251
+ return { kind: "unreadable" };
252
+ }
253
+ }
254
+ function machinePath(stateDir) {
255
+ return path.join(stateDir, "push-identity", "machine.json");
256
+ }
257
+ function recordPath(stateDir, journalSlug) {
258
+ const id = crypto.createHash("sha256").update(journalSlug).digest("hex").slice(0, 32);
259
+ return path.join(stateDir, "push-identity", `scope-${id}.json`);
260
+ }
261
+ function readMachine(stateDir) {
262
+ const raw = readText(machinePath(stateDir));
263
+ if (raw.kind !== "ok")
264
+ return raw;
265
+ try {
266
+ const parsed = JSON.parse(raw.value);
267
+ if (parsed?.format !== MACHINE_FORMAT || typeof parsed.id !== "string" || typeof parsed.sinceMs !== "number") {
268
+ return { kind: "unreadable" };
269
+ }
270
+ return { kind: "ok", value: { format: MACHINE_FORMAT, id: parsed.id, sinceMs: parsed.sinceMs } };
271
+ }
272
+ catch {
273
+ return { kind: "unreadable" };
274
+ }
275
+ }
276
+ function readRecord(stateDir, journalSlug) {
277
+ const read = parseRecord(recordPath(stateDir, journalSlug));
278
+ // A record filed under this slug's name but naming another slug was moved
279
+ // or edited by hand: do not trust it.
280
+ if (read.kind === "ok" && read.value.slug !== journalSlug)
281
+ return { kind: "unreadable" };
282
+ return read;
283
+ }
284
+ function parseRecord(filePath) {
285
+ const raw = readText(filePath);
286
+ if (raw.kind !== "ok")
287
+ return raw;
288
+ try {
289
+ const parsed = JSON.parse(raw.value);
290
+ if (parsed?.format !== RECORD_FORMAT ||
291
+ typeof parsed.slug !== "string" ||
292
+ typeof parsed.owner !== "string" ||
293
+ !parsed.owner ||
294
+ (parsed.sub !== undefined && typeof parsed.sub !== "string") ||
295
+ (parsed.machineSwitchId !== undefined && typeof parsed.machineSwitchId !== "string") ||
296
+ (parsed.personalOwnerSeen !== undefined && typeof parsed.personalOwnerSeen !== "string")) {
297
+ return { kind: "unreadable" };
298
+ }
299
+ const fence = parsed.fence;
300
+ if (fence !== undefined && (typeof fence?.uid !== "string" || typeof fence.sinceMs !== "number")) {
301
+ return { kind: "unreadable" };
302
+ }
303
+ return { kind: "ok", value: parsed };
304
+ }
305
+ catch {
306
+ return { kind: "unreadable" };
307
+ }
308
+ }
309
+ function readText(filePath) {
310
+ try {
311
+ return { kind: "ok", value: fs.readFileSync(filePath, "utf8") };
312
+ }
313
+ catch (error) {
314
+ if (error.code === "ENOENT")
315
+ return { kind: "none" };
316
+ return { kind: "unreadable" };
317
+ }
318
+ }
319
+ function writeRecord(stateDir, record) {
320
+ writeJsonAtomic(recordPath(stateDir, record.slug), record);
321
+ }
322
+ function writeJsonAtomic(filePath, value) {
323
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
324
+ const tmp = `${filePath}.${process.pid}.tmp`;
325
+ const fd = fs.openSync(tmp, "w");
326
+ try {
327
+ fs.writeSync(fd, JSON.stringify(value));
328
+ fs.fsyncSync(fd);
329
+ }
330
+ finally {
331
+ fs.closeSync(fd);
332
+ }
333
+ fs.renameSync(tmp, filePath);
334
+ // Persist the rename itself, so a power loss cannot drop a switch marker or
335
+ // fence while later journal renames survive. Windows cannot open a
336
+ // directory for fsync; unsupported directory fsyncs elsewhere are skipped
337
+ // and logged by fsyncWithCompatibility.
338
+ if (process.platform === "win32")
339
+ return;
340
+ const dirFd = fs.openSync(path.dirname(filePath), "r");
341
+ try {
342
+ fsyncWithCompatibility(dirFd, { site: "push-identity-fence", handleKind: "directory" });
343
+ }
344
+ finally {
345
+ fs.closeSync(dirFd);
346
+ }
347
+ }
348
+ //# sourceMappingURL=push-identity-fence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push-identity-fence.js","sourceRoot":"","sources":["../src/push-identity-fence.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cloud",
3
- "version": "6.18.99",
3
+ "version": "6.18.100",
4
4
  "description": "HQ by Indigo cloud sync engine — bidirectional S3 sync for mobile access",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",