@tinycloud/courier 0.5.1-beta.2 → 0.5.1-beta.4

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/profile.js CHANGED
@@ -3,6 +3,8 @@ import path from 'node:path';
3
3
  import { randomBytes } from 'node:crypto';
4
4
  import { cmd } from './program.js';
5
5
  import { CourierError } from './errors.js';
6
+ import { canonicalJson } from './canonical.js';
7
+ import { acquireLock } from './file-lock.js';
6
8
  /**
7
9
  * Courier home: `COURIER_HOME` when set, else `$HOME/.courier`. Refuses an unset or empty `HOME`
8
10
  * rather than guessing a home directory.
@@ -72,6 +74,27 @@ export function writeSecure(file, obj) {
72
74
  catch { /* renamed or absent */ }
73
75
  }
74
76
  }
77
+ /**
78
+ * The text of a regular file of this user, or undefined when there is none: a symlink is never followed (O_NOFOLLOW), a FIFO or device
79
+ * never blocks the open (O_NONBLOCK) and is refused by `fstat` before any read. Read-only callers use it; it never changes the file.
80
+ */
81
+ export function readRegularFile(file) {
82
+ let fd;
83
+ try {
84
+ fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
85
+ const stat = fs.fstatSync(fd);
86
+ if (!stat.isFile() || stat.uid !== process.getuid?.())
87
+ return undefined;
88
+ return fs.readFileSync(fd, 'utf8');
89
+ }
90
+ catch {
91
+ return undefined;
92
+ }
93
+ finally {
94
+ if (fd !== undefined)
95
+ fs.closeSync(fd);
96
+ }
97
+ }
75
98
  export function readSecure(name, required, home = profileDir()) {
76
99
  const file = profilePath(name, home);
77
100
  if (!fs.existsSync(file)) {
@@ -90,14 +113,19 @@ export function readSecure(name, required, home = profileDir()) {
90
113
  try {
91
114
  return JSON.parse(fs.readFileSync(file, 'utf8'));
92
115
  }
93
- catch (e) {
94
- throw new CourierError('bad-profile', `Invalid ${name}: ${e.message}`);
116
+ catch {
117
+ // A parser error quotes the text around the failure, and these files can hold private keys: say which file, never what was in it.
118
+ throw new CourierError('bad-profile', `Invalid ${name}: the file is unreadable or corrupt.`);
95
119
  }
96
120
  }
97
- export function loadProfile(home = profileDir()) {
121
+ /** The fields `loadProfile` requires of a current (version 3) profile. */
122
+ export function hasProfileFields(profile) {
123
+ return !!profile && typeof profile === 'object' && profile.version === 3 && !!profile.courierDid && !!profile.host && !!profile.openkeyHost;
124
+ }
125
+ function readProfile(home) {
98
126
  const loaded = readSecure('profile.json', true, home);
99
127
  if (!loaded || typeof loaded !== 'object' || !('version' in loaded)) {
100
- throw new CourierError('bad-profile', `Corrupt profile at ${profilePath('profile.json')}`);
128
+ throw new CourierError('bad-profile', `Corrupt profile at ${profilePath('profile.json', home)}`);
101
129
  }
102
130
  if (loaded.version === 2) {
103
131
  throw new CourierError('profile-outdated', `This profile stores Courier data in the applications space. Courier now uses your agents space: run \`${cmd('init --rotate-key')}\`, then re-pair peers.`);
@@ -105,17 +133,224 @@ export function loadProfile(home = profileDir()) {
105
133
  if (loaded.version !== 3)
106
134
  throw new CourierError('bad-profile', `Unsupported profile version ${String(loaded.version)}; run \`${cmd('init --rotate-key')}\`.`);
107
135
  const profile = loaded;
108
- if (!profile.courierDid || !profile.host || !profile.openkeyHost)
109
- throw new CourierError('bad-profile', `Corrupt profile at ${profilePath('profile.json')}`);
136
+ if (!hasProfileFields(profile))
137
+ throw new CourierError('bad-profile', `Corrupt profile at ${profilePath('profile.json', home)}`);
110
138
  profile.peers ??= {};
111
139
  return profile;
112
140
  }
141
+ /** A pairing that was started or half-completed and never finished is forgotten after this long (the peer delegation itself lives 7 days). */
142
+ export const PENDING_PAIRING_TTL_MS = 7 * 24 * 3600 * 1000;
143
+ function expiredPending(peer, now) {
144
+ if (peer.status === 'paired')
145
+ return false;
146
+ const started = Date.parse(peer.pairedAt);
147
+ return Number.isFinite(started) && now - started > PENDING_PAIRING_TTL_MS;
148
+ }
149
+ function dropExpiredPending(peers) {
150
+ const now = Date.now();
151
+ for (const [handle, peer] of Object.entries(peers))
152
+ if (expiredPending(peer, now))
153
+ delete peers[handle];
154
+ }
155
+ /** What each loaded or saved profile looked like on disk, so a later `saveProfile` can tell what THIS command changed. */
156
+ const baselines = new WeakMap();
157
+ function remember(profile) {
158
+ baselines.set(profile, JSON.parse(canonicalJson(profile)));
159
+ }
160
+ /** Expired pending pairings are not returned; they leave the file with the next save. */
161
+ export function loadProfile(home = profileDir()) {
162
+ const profile = readProfile(home);
163
+ dropExpiredPending(profile.peers);
164
+ remember(profile);
165
+ return profile;
166
+ }
167
+ const same = (a, b) => canonicalJson(a ?? null) === canonicalJson(b ?? null);
168
+ /** Three-way merge of one peer's fields: what this command changed wins, anything it left alone keeps the current file's value. */
169
+ function mergePeer(handle, base, mine, disk) {
170
+ if (same(mine, base))
171
+ return disk; // not touched by this command
172
+ if (!mine)
173
+ return undefined; // revoked here
174
+ if (!disk) {
175
+ if (!base)
176
+ return mine; // a new peer is added
177
+ throw new CourierError('peer-revoked', `${handle} was revoked while this command was running. Nothing was saved and nothing was published.`);
178
+ }
179
+ if (disk.status === 'paired' && mine.status !== 'paired') {
180
+ throw new CourierError('usage', `Already paired with ${handle}.`);
181
+ }
182
+ if (!base) {
183
+ // Another command added this handle meanwhile: replacing it would drop that command's delegations.
184
+ if (same(mine, disk))
185
+ return disk;
186
+ throw new CourierError('profile-changed', `Another command started a pairing with ${handle} while this one ran. Nothing was saved; run the command again.`);
187
+ }
188
+ const merged = {};
189
+ const m = mine;
190
+ const b = base;
191
+ const d = disk;
192
+ for (const key of new Set([...Object.keys(m), ...Object.keys(b), ...Object.keys(d)])) {
193
+ let value;
194
+ if (same(m[key], b[key]))
195
+ value = d[key];
196
+ else if (same(d[key], b[key]) || same(d[key], m[key]))
197
+ value = m[key];
198
+ else if (key === 'outbound') {
199
+ const byCid = new Map();
200
+ for (const entry of [...d.outbound, ...m.outbound])
201
+ byCid.set(entry.cid, entry);
202
+ value = [...byCid.values()].sort((x, y) => Date.parse(x.issuedAt) - Date.parse(y.issuedAt));
203
+ }
204
+ else if (key === 'inbound') {
205
+ // Two imports raced: the longer-lived delegation stays, never the one that happened to save last.
206
+ value = Date.parse(d.inbound.expiresAt) > Date.parse(m.inbound.expiresAt) ? d.inbound : m.inbound;
207
+ }
208
+ else if (key === 'status')
209
+ value = d.status === 'paired' ? 'paired' : m.status;
210
+ else
211
+ value = m[key];
212
+ if (value !== undefined)
213
+ merged[key] = value;
214
+ }
215
+ return merged;
216
+ }
217
+ function mergeProfile(base, mine, disk) {
218
+ assertSameAgent(base, disk);
219
+ const merged = {};
220
+ const m = mine;
221
+ const b = base;
222
+ const d = disk;
223
+ for (const key of new Set([...Object.keys(m), ...Object.keys(b), ...Object.keys(d)])) {
224
+ if (key === 'peers')
225
+ continue;
226
+ const value = same(m[key], b[key]) ? d[key] : m[key];
227
+ if (value !== undefined)
228
+ merged[key] = value;
229
+ }
230
+ const peers = {};
231
+ for (const handle of new Set([...Object.keys(mine.peers), ...Object.keys(base.peers), ...Object.keys(disk.peers)])) {
232
+ const peer = mergePeer(handle, base.peers[handle], mine.peers[handle], disk.peers[handle]);
233
+ if (peer)
234
+ peers[handle] = peer;
235
+ }
236
+ merged.peers = peers;
237
+ return merged;
238
+ }
239
+ /** Make `target` hold `source`'s values without replacing nested objects the caller still points at (for example a peer it just updated). */
240
+ function adopt(target, source) {
241
+ for (const key of Object.keys(target))
242
+ if (!(key in source))
243
+ delete target[key];
244
+ for (const [key, value] of Object.entries(source)) {
245
+ const current = target[key];
246
+ if (key === 'peers' && current && typeof current === 'object' && value && typeof value === 'object')
247
+ adoptPeers(current, value);
248
+ else
249
+ target[key] = value;
250
+ }
251
+ }
252
+ function adoptPeers(target, source) {
253
+ for (const handle of Object.keys(target))
254
+ if (!(handle in source))
255
+ delete target[handle];
256
+ for (const [handle, peer] of Object.entries(source)) {
257
+ const current = target[handle];
258
+ if (current && typeof current === 'object')
259
+ adopt(current, peer);
260
+ else
261
+ target[handle] = peer;
262
+ }
263
+ }
264
+ const LOCK_WAIT_MS = 10_000;
265
+ function sleepSync(ms) {
266
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
267
+ }
268
+ /**
269
+ * Exclusive, held only while a save reads, merges and writes (milliseconds). The lock is intake's: created whole with a `{pid, nonce}` owner
270
+ * record, released only by its nonce, and broken only when its holder is established dead (a true boot-id change on the same host, or its pid is absent; on Linux the record and this process must name the same pid namespace).
271
+ * A live holder, or one whose liveness cannot be established, is waited for and then refused: age alone never breaks a lock.
272
+ */
273
+ function withProfileLock(fn) {
274
+ ensureSecureDir();
275
+ const lock = `${profilePath('profile.json')}.lock`;
276
+ const deadline = performance.now() + LOCK_WAIT_MS;
277
+ let release;
278
+ for (;;) {
279
+ try {
280
+ release = acquireLock(lock);
281
+ break;
282
+ }
283
+ catch (error) {
284
+ if (!(error instanceof CourierError) || error.code !== 'locked')
285
+ throw error;
286
+ if (performance.now() >= deadline)
287
+ throw new CourierError('profile-locked', error.message);
288
+ }
289
+ sleepSync(10);
290
+ }
291
+ try {
292
+ return fn();
293
+ }
294
+ finally {
295
+ release?.();
296
+ }
297
+ }
298
+ function assertSameAgent(base, disk) {
299
+ if (disk.courierDid !== base.courierDid) {
300
+ throw new CourierError('profile-changed', 'The agent key changed while this command was running (`init --rotate-key`). Nothing was saved; run the command again.');
301
+ }
302
+ }
303
+ /**
304
+ * Writes grant.json for a profile loaded earlier, under the profile lock and only while profile.json still holds the agent key that
305
+ * grant is for, so a command that outlived `init --rotate-key` never leaves the old key's grant beside the new profile.
306
+ */
307
+ export function saveGrantIfCurrent(profile, grant) {
308
+ withProfileLock(() => {
309
+ const base = baselines.get(profile);
310
+ if (base && fs.existsSync(profilePath('profile.json')))
311
+ assertSameAgent(base, readProfile(profileDir()));
312
+ saveGrant(grant);
313
+ });
314
+ }
315
+ /** Refuses a pairing start for `handle` when this copy or the file as it is now already has it paired. Reads, does not lock: it only avoids work that save would refuse. */
316
+ export function assertNotPaired(profile, handle) {
317
+ const current = fs.existsSync(profilePath('profile.json')) ? readProfile(profileDir()) : undefined;
318
+ if (profile.peers[handle]?.status === 'paired' || current?.peers[handle]?.status === 'paired') {
319
+ throw new CourierError('usage', `Already paired with ${handle}.`);
320
+ }
321
+ }
322
+ /**
323
+ * Saves under a lock. A profile that came from `loadProfile` (or an earlier save) is merged with the file as it is NOW: only what
324
+ * this command changed is written, so a pairing, revocation or key rotation made by another command meanwhile is kept. `profile` is
325
+ * updated to the saved result. A profile built from scratch overwrites the file (first init, key rotation).
326
+ */
113
327
  export function saveProfile(profile) {
114
- writeSecure(profilePath('profile.json'), profile);
328
+ const file = profilePath('profile.json');
329
+ withProfileLock(() => {
330
+ const base = baselines.get(profile);
331
+ let result = profile;
332
+ if (base && fs.existsSync(file)) {
333
+ const disk = readProfile(profileDir());
334
+ dropExpiredPending(disk.peers); // an expired pairing is not another command's: it must not block starting that handle again
335
+ result = mergeProfile(base, profile, disk);
336
+ }
337
+ dropExpiredPending(result.peers);
338
+ writeSecure(file, result);
339
+ if (result !== profile)
340
+ adopt(profile, result);
341
+ else
342
+ dropExpiredPending(profile.peers);
343
+ remember(profile);
344
+ });
345
+ }
346
+ /** The shape `loadKey` accepts: version 1, a JWK and a `did:key:` identifier. */
347
+ export function isAgentKey(value) {
348
+ const key = value;
349
+ return !!key && typeof key === 'object' && key.v === 1 && !!key.jwk && typeof key.did === 'string' && key.did.startsWith('did:key:');
115
350
  }
116
351
  export function loadKey(home = profileDir()) {
117
352
  const key = readSecure('key.json', true, home);
118
- if (key.v !== 1 || !key.jwk || !key.did?.startsWith('did:key:')) {
353
+ if (!isAgentKey(key)) {
119
354
  throw new CourierError('bad-profile', `Corrupt agent key at ${profilePath('key.json')}`);
120
355
  }
121
356
  return key;
@@ -1 +1 @@
1
- {"version":3,"file":"profile.js","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { AgentKey, Profile } from './profile.js';
2
+ export type ApprovalState = 'none' | 'open' | 'held' | 'committed' | 'unreadable' | 'corrupt';
3
+ /** `unreadable`: profile.json exists and cannot be read (permissions or content). It is never the same as `absent`. */
4
+ export type ProfileStatus = 'absent' | 'unreadable' | Profile['status'];
5
+ export interface StateInputs {
6
+ profile: ProfileStatus;
7
+ spacePending: boolean;
8
+ grant: boolean;
9
+ key: boolean;
10
+ pendingGrant: boolean;
11
+ approval: ApprovalState;
12
+ rotation: boolean;
13
+ rotationTemp: boolean;
14
+ }
15
+ export type StateAction = 'finish-rotation' | 'refuse' | 'fix-profile' | 'init' | 'rotate-key' | 'wait' | 'resume' | 'request' | 'fix-approval' | 'none';
16
+ export type StateName = 'rotation-interrupted' | 'profile-unreadable' | 'approval-orphaned' | 'new' | 'key-only' | 'key-missing' | 'approval-held' | 'saved-delegation' | 'saved-grant' | 'approval-open' | 'approval-unreadable' | 'awaiting-grant' | 'grant-missing' | 'space-pending' | 'space-missing' | 'ready-approval' | 'ready';
17
+ export interface DerivedState {
18
+ inputs: StateInputs;
19
+ state: StateName;
20
+ action: StateAction;
21
+ /** A stray key-bearing temp file whose writer is gone is on disk and `recoverInterrupted` removes it. */
22
+ cleanTemp: boolean;
23
+ /** `init --wait` goes on; when false it advises `adviceFor(state)`. */
24
+ wait: boolean;
25
+ /** Warnings about files that were read and not used (printed once by the init mode). */
26
+ notes: string[];
27
+ /** Set (octal mode) when grant.json is a regular file that is not owner-only: it is a saved grant, unusable until its mode is fixed. */
28
+ grantMode?: string;
29
+ }
30
+ export declare const heldApproval: (approval: ApprovalState) => boolean;
31
+ export declare function classifyState(i: StateInputs): Omit<DerivedState, 'inputs' | 'notes'>;
32
+ /** The one place the inputs are read. Reads only. `notes` are warnings the init mode prints once; nothing is repaired or removed. */
33
+ export declare function readInputs(notes?: string[]): StateInputs;
34
+ export declare function deriveState(): DerivedState;
35
+ /** The next command for the person or agent running init. */
36
+ export declare function adviceFor(d: Pick<DerivedState, 'state' | 'inputs'>): string;
37
+ /**
38
+ * Explicit recovery, run once at the start of an init mode: roll an interrupted rotation forward (only after the journal validated), then
39
+ * remove stray key-bearing temp files. A refusal in the first step happens before anything is changed.
40
+ */
41
+ export declare function recoverInterrupted(): void;
42
+ /** Steps 1-5. `profile` is the complete new profile. */
43
+ export declare function rotateKey(key: AgentKey, profile: Profile): Promise<void>;
44
+ /** Roll an interrupted rotation forward. Returns whether one was found. Refuses, changing nothing, when the record is not a valid rotation. */
45
+ export declare function finishRotation(): boolean;