@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.
- package/dist/bin/sync-runner-company.d.ts +2 -0
- package/dist/bin/sync-runner-company.d.ts.map +1 -1
- package/dist/bin/sync-runner-company.js +8 -0
- package/dist/bin/sync-runner-company.js.map +1 -1
- package/dist/bin/sync-runner.d.ts +10 -0
- package/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js +10 -0
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/cli/share.d.ts +6 -0
- package/dist/cli/share.d.ts.map +1 -1
- package/dist/cli/share.js +74 -7
- package/dist/cli/share.js.map +1 -1
- package/dist/cli/sync.d.ts +11 -0
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +6 -0
- package/dist/cli/sync.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/journal.d.ts +21 -0
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +83 -0
- package/dist/journal.js.map +1 -1
- package/dist/push-identity-fence.d.ts +71 -0
- package/dist/push-identity-fence.d.ts.map +1 -0
- package/dist/push-identity-fence.js +348 -0
- package/dist/push-identity-fence.js.map +1 -0
- package/package.json +1 -1
|
@@ -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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"}
|