@tokensrc/codex 1.14.11 → 1.14.13
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/client.d.ts +8 -1
- package/dist/client.js +71 -1
- package/dist/client.js.map +1 -1
- package/dist/commands.js +138 -26
- package/dist/commands.js.map +1 -1
- package/dist/managed-credential-v3-envelope.d.ts +40 -1
- package/dist/managed-credential-v3-envelope.js +113 -1
- package/dist/managed-credential-v3-envelope.js.map +1 -1
- package/dist/managed-credential-v3.d.ts +3 -0
- package/dist/managed-credential-v3.js +9 -5
- package/dist/managed-credential-v3.js.map +1 -1
- package/dist/multi-device-v5-flow.d.ts +21 -0
- package/dist/multi-device-v5-flow.js +322 -0
- package/dist/multi-device-v5-flow.js.map +1 -0
- package/dist/multi-device-v5-state.d.ts +373 -0
- package/dist/multi-device-v5-state.js +218 -0
- package/dist/multi-device-v5-state.js.map +1 -0
- package/dist/profile.d.ts +2 -0
- package/dist/profile.js +24 -1
- package/dist/profile.js.map +1 -1
- package/dist/protocol.d.ts +206 -0
- package/dist/protocol.js +139 -0
- package/dist/protocol.js.map +1 -1
- package/dist/tui.js +2 -1
- package/dist/tui.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { type KeyObject } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { CodexV5CreateDeviceSessionResponseSchema } from "./protocol.js";
|
|
4
|
+
export declare const CodexV5SessionStateSchema: z.ZodObject<{
|
|
5
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
6
|
+
tenantId: z.ZodString;
|
|
7
|
+
subject: z.ZodString;
|
|
8
|
+
assignmentId: z.ZodString;
|
|
9
|
+
managedAccountId: z.ZodString;
|
|
10
|
+
providerAccountId: z.ZodString;
|
|
11
|
+
lineageId: z.ZodString;
|
|
12
|
+
installationId: z.ZodString;
|
|
13
|
+
sessionId: z.ZodString;
|
|
14
|
+
authorityEpoch: z.ZodNumber;
|
|
15
|
+
generationVersion: z.ZodNumber;
|
|
16
|
+
leaseExpiresAt: z.ZodString;
|
|
17
|
+
releaseIdempotencyKey: z.ZodString;
|
|
18
|
+
status: z.ZodEnum<{
|
|
19
|
+
ACTIVE: "ACTIVE";
|
|
20
|
+
RECOVERY_REQUIRED: "RECOVERY_REQUIRED";
|
|
21
|
+
}>;
|
|
22
|
+
updatedAt: z.ZodString;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
export declare const CodexV5AcquireJournalSchema: z.ZodObject<{
|
|
25
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
26
|
+
tenantId: z.ZodString;
|
|
27
|
+
subject: z.ZodString;
|
|
28
|
+
assignmentId: z.ZodString;
|
|
29
|
+
expectedManagedAccountId: z.ZodString;
|
|
30
|
+
expectedProviderAccountId: z.ZodString;
|
|
31
|
+
expectedLineageId: z.ZodString;
|
|
32
|
+
installationId: z.ZodString;
|
|
33
|
+
clientRequestId: z.ZodString;
|
|
34
|
+
idempotencyKey: z.ZodString;
|
|
35
|
+
ackIdempotencyKey: z.ZodString;
|
|
36
|
+
releaseIdempotencyKey: z.ZodString;
|
|
37
|
+
clientKey: z.ZodObject<{
|
|
38
|
+
version: z.ZodLiteral<1>;
|
|
39
|
+
algorithm: z.ZodLiteral<"X25519-HKDF-SHA256-AES-256-GCM">;
|
|
40
|
+
publicKey: z.ZodString;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
privateKeyPkcs8: z.ZodString;
|
|
43
|
+
response: z.ZodNullable<z.ZodObject<{
|
|
44
|
+
schemaVersion: z.ZodLiteral<5>;
|
|
45
|
+
session: z.ZodObject<{
|
|
46
|
+
id: z.ZodString;
|
|
47
|
+
clientRequestId: z.ZodString;
|
|
48
|
+
installationId: z.ZodString;
|
|
49
|
+
assignmentId: z.ZodString;
|
|
50
|
+
managedAccountId: z.ZodString;
|
|
51
|
+
providerAccountId: z.ZodString;
|
|
52
|
+
lineageId: z.ZodString;
|
|
53
|
+
generationVersion: z.ZodNumber;
|
|
54
|
+
issuedAt: z.ZodString;
|
|
55
|
+
leaseExpiresAt: z.ZodString;
|
|
56
|
+
status: z.ZodEnum<{
|
|
57
|
+
ACTIVE: "ACTIVE";
|
|
58
|
+
AWAITING_ACK: "AWAITING_ACK";
|
|
59
|
+
}>;
|
|
60
|
+
authorityEpoch: z.ZodNumber;
|
|
61
|
+
envelope: z.ZodObject<{
|
|
62
|
+
version: z.ZodLiteral<1>;
|
|
63
|
+
algorithm: z.ZodLiteral<"X25519-HKDF-SHA256-AES-256-GCM">;
|
|
64
|
+
ephemeralPublicKey: z.ZodString;
|
|
65
|
+
salt: z.ZodString;
|
|
66
|
+
nonce: z.ZodString;
|
|
67
|
+
ciphertext: z.ZodString;
|
|
68
|
+
authenticationTag: z.ZodString;
|
|
69
|
+
}, z.core.$strict>;
|
|
70
|
+
}, z.core.$strict>;
|
|
71
|
+
replayed: z.ZodBoolean;
|
|
72
|
+
}, z.core.$strict>>;
|
|
73
|
+
createdAt: z.ZodString;
|
|
74
|
+
updatedAt: z.ZodString;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
export declare const CodexV5ReportJournalSchema: z.ZodObject<{
|
|
77
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
78
|
+
tenantId: z.ZodString;
|
|
79
|
+
subject: z.ZodString;
|
|
80
|
+
lineageId: z.ZodString;
|
|
81
|
+
installationId: z.ZodString;
|
|
82
|
+
sessionId: z.ZodString;
|
|
83
|
+
authorityEpoch: z.ZodNumber;
|
|
84
|
+
clientRequestId: z.ZodString;
|
|
85
|
+
idempotencyKey: z.ZodString;
|
|
86
|
+
expectedGenerationVersion: z.ZodNumber;
|
|
87
|
+
rotationMode: z.ZodEnum<{
|
|
88
|
+
RETAINED: "RETAINED";
|
|
89
|
+
ROTATED: "ROTATED";
|
|
90
|
+
}>;
|
|
91
|
+
envelope: z.ZodObject<{
|
|
92
|
+
version: z.ZodLiteral<1>;
|
|
93
|
+
algorithm: z.ZodLiteral<"X25519-HKDF-SHA256-AES-256-GCM">;
|
|
94
|
+
keyId: z.ZodString;
|
|
95
|
+
ephemeralPublicKey: z.ZodString;
|
|
96
|
+
salt: z.ZodString;
|
|
97
|
+
nonce: z.ZodString;
|
|
98
|
+
ciphertext: z.ZodString;
|
|
99
|
+
authenticationTag: z.ZodString;
|
|
100
|
+
}, z.core.$strict>;
|
|
101
|
+
accessTokenHealth: z.ZodEnum<{
|
|
102
|
+
EXPIRED: "EXPIRED";
|
|
103
|
+
HEALTHY: "HEALTHY";
|
|
104
|
+
REJECTED: "REJECTED";
|
|
105
|
+
UNKNOWN: "UNKNOWN";
|
|
106
|
+
}>;
|
|
107
|
+
refreshTokenHealth: z.ZodEnum<{
|
|
108
|
+
HEALTHY: "HEALTHY";
|
|
109
|
+
REJECTED: "REJECTED";
|
|
110
|
+
UNKNOWN: "UNKNOWN";
|
|
111
|
+
}>;
|
|
112
|
+
observedAt: z.ZodString;
|
|
113
|
+
credentialExpiresAt: z.ZodString;
|
|
114
|
+
accessTokenDigest: z.ZodString;
|
|
115
|
+
refreshTokenDigest: z.ZodString;
|
|
116
|
+
idTokenDigest: z.ZodString;
|
|
117
|
+
createdAt: z.ZodString;
|
|
118
|
+
updatedAt: z.ZodString;
|
|
119
|
+
}, z.core.$strict>;
|
|
120
|
+
export type CodexV5SessionState = z.infer<typeof CodexV5SessionStateSchema>;
|
|
121
|
+
export type CodexV5AcquireJournal = z.infer<typeof CodexV5AcquireJournalSchema>;
|
|
122
|
+
export type CodexV5ReportJournal = z.infer<typeof CodexV5ReportJournalSchema>;
|
|
123
|
+
export declare function getOrCreateCodexInstallationId(env?: NodeJS.ProcessEnv, now?: number, newId?: () => string): Promise<string>;
|
|
124
|
+
export declare function readCodexV5SessionState(env?: NodeJS.ProcessEnv): Promise<{
|
|
125
|
+
schemaVersion: 1;
|
|
126
|
+
tenantId: string;
|
|
127
|
+
subject: string;
|
|
128
|
+
assignmentId: string;
|
|
129
|
+
managedAccountId: string;
|
|
130
|
+
providerAccountId: string;
|
|
131
|
+
lineageId: string;
|
|
132
|
+
installationId: string;
|
|
133
|
+
sessionId: string;
|
|
134
|
+
authorityEpoch: number;
|
|
135
|
+
generationVersion: number;
|
|
136
|
+
leaseExpiresAt: string;
|
|
137
|
+
releaseIdempotencyKey: string;
|
|
138
|
+
status: "ACTIVE" | "RECOVERY_REQUIRED";
|
|
139
|
+
updatedAt: string;
|
|
140
|
+
} | undefined>;
|
|
141
|
+
export declare function writeCodexV5SessionState(value: CodexV5SessionState, env?: NodeJS.ProcessEnv): Promise<{
|
|
142
|
+
schemaVersion: 1;
|
|
143
|
+
tenantId: string;
|
|
144
|
+
subject: string;
|
|
145
|
+
assignmentId: string;
|
|
146
|
+
managedAccountId: string;
|
|
147
|
+
providerAccountId: string;
|
|
148
|
+
lineageId: string;
|
|
149
|
+
installationId: string;
|
|
150
|
+
sessionId: string;
|
|
151
|
+
authorityEpoch: number;
|
|
152
|
+
generationVersion: number;
|
|
153
|
+
leaseExpiresAt: string;
|
|
154
|
+
releaseIdempotencyKey: string;
|
|
155
|
+
status: "ACTIVE" | "RECOVERY_REQUIRED";
|
|
156
|
+
updatedAt: string;
|
|
157
|
+
}>;
|
|
158
|
+
export declare function clearCodexV5SessionState(expectedSessionId: string, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
159
|
+
export declare function readCodexV5AcquireJournal(env?: NodeJS.ProcessEnv): Promise<{
|
|
160
|
+
schemaVersion: 1;
|
|
161
|
+
tenantId: string;
|
|
162
|
+
subject: string;
|
|
163
|
+
assignmentId: string;
|
|
164
|
+
expectedManagedAccountId: string;
|
|
165
|
+
expectedProviderAccountId: string;
|
|
166
|
+
expectedLineageId: string;
|
|
167
|
+
installationId: string;
|
|
168
|
+
clientRequestId: string;
|
|
169
|
+
idempotencyKey: string;
|
|
170
|
+
ackIdempotencyKey: string;
|
|
171
|
+
releaseIdempotencyKey: string;
|
|
172
|
+
clientKey: {
|
|
173
|
+
version: 1;
|
|
174
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
175
|
+
publicKey: string;
|
|
176
|
+
};
|
|
177
|
+
privateKeyPkcs8: string;
|
|
178
|
+
response: {
|
|
179
|
+
schemaVersion: 5;
|
|
180
|
+
session: {
|
|
181
|
+
id: string;
|
|
182
|
+
clientRequestId: string;
|
|
183
|
+
installationId: string;
|
|
184
|
+
assignmentId: string;
|
|
185
|
+
managedAccountId: string;
|
|
186
|
+
providerAccountId: string;
|
|
187
|
+
lineageId: string;
|
|
188
|
+
generationVersion: number;
|
|
189
|
+
issuedAt: string;
|
|
190
|
+
leaseExpiresAt: string;
|
|
191
|
+
status: "ACTIVE" | "AWAITING_ACK";
|
|
192
|
+
authorityEpoch: number;
|
|
193
|
+
envelope: {
|
|
194
|
+
version: 1;
|
|
195
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
196
|
+
ephemeralPublicKey: string;
|
|
197
|
+
salt: string;
|
|
198
|
+
nonce: string;
|
|
199
|
+
ciphertext: string;
|
|
200
|
+
authenticationTag: string;
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
replayed: boolean;
|
|
204
|
+
} | null;
|
|
205
|
+
createdAt: string;
|
|
206
|
+
updatedAt: string;
|
|
207
|
+
} | undefined>;
|
|
208
|
+
export declare function writeCodexV5AcquireJournal(value: CodexV5AcquireJournal, env?: NodeJS.ProcessEnv): Promise<{
|
|
209
|
+
schemaVersion: 1;
|
|
210
|
+
tenantId: string;
|
|
211
|
+
subject: string;
|
|
212
|
+
assignmentId: string;
|
|
213
|
+
expectedManagedAccountId: string;
|
|
214
|
+
expectedProviderAccountId: string;
|
|
215
|
+
expectedLineageId: string;
|
|
216
|
+
installationId: string;
|
|
217
|
+
clientRequestId: string;
|
|
218
|
+
idempotencyKey: string;
|
|
219
|
+
ackIdempotencyKey: string;
|
|
220
|
+
releaseIdempotencyKey: string;
|
|
221
|
+
clientKey: {
|
|
222
|
+
version: 1;
|
|
223
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
224
|
+
publicKey: string;
|
|
225
|
+
};
|
|
226
|
+
privateKeyPkcs8: string;
|
|
227
|
+
response: {
|
|
228
|
+
schemaVersion: 5;
|
|
229
|
+
session: {
|
|
230
|
+
id: string;
|
|
231
|
+
clientRequestId: string;
|
|
232
|
+
installationId: string;
|
|
233
|
+
assignmentId: string;
|
|
234
|
+
managedAccountId: string;
|
|
235
|
+
providerAccountId: string;
|
|
236
|
+
lineageId: string;
|
|
237
|
+
generationVersion: number;
|
|
238
|
+
issuedAt: string;
|
|
239
|
+
leaseExpiresAt: string;
|
|
240
|
+
status: "ACTIVE" | "AWAITING_ACK";
|
|
241
|
+
authorityEpoch: number;
|
|
242
|
+
envelope: {
|
|
243
|
+
version: 1;
|
|
244
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
245
|
+
ephemeralPublicKey: string;
|
|
246
|
+
salt: string;
|
|
247
|
+
nonce: string;
|
|
248
|
+
ciphertext: string;
|
|
249
|
+
authenticationTag: string;
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
replayed: boolean;
|
|
253
|
+
} | null;
|
|
254
|
+
createdAt: string;
|
|
255
|
+
updatedAt: string;
|
|
256
|
+
}>;
|
|
257
|
+
export declare function updateCodexV5AcquireJournalResponse(expected: CodexV5AcquireJournal, response: z.infer<typeof CodexV5CreateDeviceSessionResponseSchema>, now: number, env?: NodeJS.ProcessEnv): Promise<{
|
|
258
|
+
schemaVersion: 1;
|
|
259
|
+
tenantId: string;
|
|
260
|
+
subject: string;
|
|
261
|
+
assignmentId: string;
|
|
262
|
+
expectedManagedAccountId: string;
|
|
263
|
+
expectedProviderAccountId: string;
|
|
264
|
+
expectedLineageId: string;
|
|
265
|
+
installationId: string;
|
|
266
|
+
clientRequestId: string;
|
|
267
|
+
idempotencyKey: string;
|
|
268
|
+
ackIdempotencyKey: string;
|
|
269
|
+
releaseIdempotencyKey: string;
|
|
270
|
+
clientKey: {
|
|
271
|
+
version: 1;
|
|
272
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
273
|
+
publicKey: string;
|
|
274
|
+
};
|
|
275
|
+
privateKeyPkcs8: string;
|
|
276
|
+
response: {
|
|
277
|
+
schemaVersion: 5;
|
|
278
|
+
session: {
|
|
279
|
+
id: string;
|
|
280
|
+
clientRequestId: string;
|
|
281
|
+
installationId: string;
|
|
282
|
+
assignmentId: string;
|
|
283
|
+
managedAccountId: string;
|
|
284
|
+
providerAccountId: string;
|
|
285
|
+
lineageId: string;
|
|
286
|
+
generationVersion: number;
|
|
287
|
+
issuedAt: string;
|
|
288
|
+
leaseExpiresAt: string;
|
|
289
|
+
status: "ACTIVE" | "AWAITING_ACK";
|
|
290
|
+
authorityEpoch: number;
|
|
291
|
+
envelope: {
|
|
292
|
+
version: 1;
|
|
293
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
294
|
+
ephemeralPublicKey: string;
|
|
295
|
+
salt: string;
|
|
296
|
+
nonce: string;
|
|
297
|
+
ciphertext: string;
|
|
298
|
+
authenticationTag: string;
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
replayed: boolean;
|
|
302
|
+
} | null;
|
|
303
|
+
createdAt: string;
|
|
304
|
+
updatedAt: string;
|
|
305
|
+
}>;
|
|
306
|
+
export declare function clearCodexV5AcquireJournal(expected: Pick<CodexV5AcquireJournal, "clientRequestId" | "idempotencyKey">, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
307
|
+
export declare function openCodexV5AcquireJournalKey(journal: CodexV5AcquireJournal): KeyObject;
|
|
308
|
+
export declare function readCodexV5ReportJournal(env?: NodeJS.ProcessEnv): Promise<{
|
|
309
|
+
schemaVersion: 1;
|
|
310
|
+
tenantId: string;
|
|
311
|
+
subject: string;
|
|
312
|
+
lineageId: string;
|
|
313
|
+
installationId: string;
|
|
314
|
+
sessionId: string;
|
|
315
|
+
authorityEpoch: number;
|
|
316
|
+
clientRequestId: string;
|
|
317
|
+
idempotencyKey: string;
|
|
318
|
+
expectedGenerationVersion: number;
|
|
319
|
+
rotationMode: "RETAINED" | "ROTATED";
|
|
320
|
+
envelope: {
|
|
321
|
+
version: 1;
|
|
322
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
323
|
+
keyId: string;
|
|
324
|
+
ephemeralPublicKey: string;
|
|
325
|
+
salt: string;
|
|
326
|
+
nonce: string;
|
|
327
|
+
ciphertext: string;
|
|
328
|
+
authenticationTag: string;
|
|
329
|
+
};
|
|
330
|
+
accessTokenHealth: "EXPIRED" | "HEALTHY" | "REJECTED" | "UNKNOWN";
|
|
331
|
+
refreshTokenHealth: "HEALTHY" | "REJECTED" | "UNKNOWN";
|
|
332
|
+
observedAt: string;
|
|
333
|
+
credentialExpiresAt: string;
|
|
334
|
+
accessTokenDigest: string;
|
|
335
|
+
refreshTokenDigest: string;
|
|
336
|
+
idTokenDigest: string;
|
|
337
|
+
createdAt: string;
|
|
338
|
+
updatedAt: string;
|
|
339
|
+
} | undefined>;
|
|
340
|
+
export declare function writeCodexV5ReportJournal(value: CodexV5ReportJournal, env?: NodeJS.ProcessEnv): Promise<{
|
|
341
|
+
schemaVersion: 1;
|
|
342
|
+
tenantId: string;
|
|
343
|
+
subject: string;
|
|
344
|
+
lineageId: string;
|
|
345
|
+
installationId: string;
|
|
346
|
+
sessionId: string;
|
|
347
|
+
authorityEpoch: number;
|
|
348
|
+
clientRequestId: string;
|
|
349
|
+
idempotencyKey: string;
|
|
350
|
+
expectedGenerationVersion: number;
|
|
351
|
+
rotationMode: "RETAINED" | "ROTATED";
|
|
352
|
+
envelope: {
|
|
353
|
+
version: 1;
|
|
354
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM";
|
|
355
|
+
keyId: string;
|
|
356
|
+
ephemeralPublicKey: string;
|
|
357
|
+
salt: string;
|
|
358
|
+
nonce: string;
|
|
359
|
+
ciphertext: string;
|
|
360
|
+
authenticationTag: string;
|
|
361
|
+
};
|
|
362
|
+
accessTokenHealth: "EXPIRED" | "HEALTHY" | "REJECTED" | "UNKNOWN";
|
|
363
|
+
refreshTokenHealth: "HEALTHY" | "REJECTED" | "UNKNOWN";
|
|
364
|
+
observedAt: string;
|
|
365
|
+
credentialExpiresAt: string;
|
|
366
|
+
accessTokenDigest: string;
|
|
367
|
+
refreshTokenDigest: string;
|
|
368
|
+
idTokenDigest: string;
|
|
369
|
+
createdAt: string;
|
|
370
|
+
updatedAt: string;
|
|
371
|
+
}>;
|
|
372
|
+
export declare function clearCodexV5ReportJournal(expected: Pick<CodexV5ReportJournal, "clientRequestId" | "idempotencyKey">, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
373
|
+
export declare function exportCodexV5PrivateKey(privateKey: KeyObject): string;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { createPrivateKey, randomUUID } from "node:crypto";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { CodexShortLivedDeliveryClientKeySchema, CodexV3AccessTokenHealthSchema, CodexV3CredentialEnvelopeSchema, CodexV3RefreshTokenHealthSchema, CodexV5CreateDeviceSessionResponseSchema } from "./protocol.js";
|
|
6
|
+
import { readJsonIfExists, removePrivateFileDurably, withPrivateFileLock, writePrivateJson } from "./private-file.js";
|
|
7
|
+
const Instant = z.string().datetime({ offset: true });
|
|
8
|
+
const Id = z.string().min(1).max(512);
|
|
9
|
+
const Stable = z.string().min(8).max(255);
|
|
10
|
+
const Digest = z.string().length(64).regex(/^[0-9a-f]{64}$/);
|
|
11
|
+
const InstallationId = z.string().min(16).max(200).regex(/^[A-Za-z0-9][A-Za-z0-9._:-]+$/);
|
|
12
|
+
const InstallationSchema = z.strictObject({
|
|
13
|
+
schemaVersion: z.literal(1), installationId: InstallationId, createdAt: Instant
|
|
14
|
+
});
|
|
15
|
+
export const CodexV5SessionStateSchema = z.strictObject({
|
|
16
|
+
schemaVersion: z.literal(1),
|
|
17
|
+
tenantId: Id,
|
|
18
|
+
subject: Id,
|
|
19
|
+
assignmentId: Id,
|
|
20
|
+
managedAccountId: Id,
|
|
21
|
+
providerAccountId: Id,
|
|
22
|
+
lineageId: Id,
|
|
23
|
+
installationId: InstallationId,
|
|
24
|
+
sessionId: Id,
|
|
25
|
+
authorityEpoch: z.number().int().positive(),
|
|
26
|
+
generationVersion: z.number().int().positive(),
|
|
27
|
+
leaseExpiresAt: Instant,
|
|
28
|
+
releaseIdempotencyKey: Stable,
|
|
29
|
+
status: z.enum(["ACTIVE", "RECOVERY_REQUIRED"]),
|
|
30
|
+
updatedAt: Instant
|
|
31
|
+
});
|
|
32
|
+
export const CodexV5AcquireJournalSchema = z.strictObject({
|
|
33
|
+
schemaVersion: z.literal(1),
|
|
34
|
+
tenantId: Id,
|
|
35
|
+
subject: Id,
|
|
36
|
+
assignmentId: Id,
|
|
37
|
+
expectedManagedAccountId: Id,
|
|
38
|
+
expectedProviderAccountId: Id,
|
|
39
|
+
expectedLineageId: Id,
|
|
40
|
+
installationId: InstallationId,
|
|
41
|
+
clientRequestId: Stable,
|
|
42
|
+
idempotencyKey: Stable,
|
|
43
|
+
ackIdempotencyKey: Stable,
|
|
44
|
+
releaseIdempotencyKey: Stable,
|
|
45
|
+
clientKey: CodexShortLivedDeliveryClientKeySchema,
|
|
46
|
+
privateKeyPkcs8: z.string().min(1).max(512).regex(/^[A-Za-z0-9_-]+$/),
|
|
47
|
+
response: CodexV5CreateDeviceSessionResponseSchema.nullable(),
|
|
48
|
+
createdAt: Instant,
|
|
49
|
+
updatedAt: Instant
|
|
50
|
+
});
|
|
51
|
+
export const CodexV5ReportJournalSchema = z.strictObject({
|
|
52
|
+
schemaVersion: z.literal(1),
|
|
53
|
+
tenantId: Id,
|
|
54
|
+
subject: Id,
|
|
55
|
+
lineageId: Id,
|
|
56
|
+
installationId: InstallationId,
|
|
57
|
+
sessionId: Id,
|
|
58
|
+
authorityEpoch: z.number().int().positive(),
|
|
59
|
+
clientRequestId: Stable,
|
|
60
|
+
idempotencyKey: Stable,
|
|
61
|
+
expectedGenerationVersion: z.number().int().positive(),
|
|
62
|
+
rotationMode: z.enum(["ROTATED", "RETAINED"]),
|
|
63
|
+
envelope: CodexV3CredentialEnvelopeSchema,
|
|
64
|
+
accessTokenHealth: CodexV3AccessTokenHealthSchema,
|
|
65
|
+
refreshTokenHealth: CodexV3RefreshTokenHealthSchema,
|
|
66
|
+
observedAt: Instant,
|
|
67
|
+
credentialExpiresAt: Instant,
|
|
68
|
+
accessTokenDigest: Digest,
|
|
69
|
+
refreshTokenDigest: Digest,
|
|
70
|
+
idTokenDigest: Digest,
|
|
71
|
+
createdAt: Instant,
|
|
72
|
+
updatedAt: Instant
|
|
73
|
+
});
|
|
74
|
+
function root(env) {
|
|
75
|
+
return env.CODEX_HOME?.trim() || join(homedir(), ".codex");
|
|
76
|
+
}
|
|
77
|
+
function installationPath(env) { return join(root(env), ".numa-installation.json"); }
|
|
78
|
+
function sessionPath(env) { return join(root(env), ".numa-device-session-v5.json"); }
|
|
79
|
+
function acquirePath(env) { return join(root(env), ".numa-device-acquire-v5.json"); }
|
|
80
|
+
function reportPath(env) { return join(root(env), ".numa-device-report-v5.json"); }
|
|
81
|
+
export async function getOrCreateCodexInstallationId(env = process.env, now = Date.now(), newId = randomUUID) {
|
|
82
|
+
const target = installationPath(env);
|
|
83
|
+
return withPrivateFileLock(target, async () => {
|
|
84
|
+
const current = await readJsonIfExists(target);
|
|
85
|
+
if (current !== undefined)
|
|
86
|
+
return InstallationSchema.parse(current).installationId;
|
|
87
|
+
const value = InstallationSchema.parse({ schemaVersion: 1,
|
|
88
|
+
installationId: `install-${newId()}`, createdAt: new Date(now).toISOString() });
|
|
89
|
+
await writePrivateJson(target, value);
|
|
90
|
+
return value.installationId;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async function readParsed(path, schema) {
|
|
94
|
+
const raw = await readJsonIfExists(path);
|
|
95
|
+
return raw === undefined ? undefined : schema.parse(raw);
|
|
96
|
+
}
|
|
97
|
+
export function readCodexV5SessionState(env = process.env) {
|
|
98
|
+
return readParsed(sessionPath(env), CodexV5SessionStateSchema);
|
|
99
|
+
}
|
|
100
|
+
export async function writeCodexV5SessionState(value, env = process.env) {
|
|
101
|
+
const target = sessionPath(env);
|
|
102
|
+
return withPrivateFileLock(target, async () => {
|
|
103
|
+
const parsed = CodexV5SessionStateSchema.parse(value);
|
|
104
|
+
await writePrivateJson(target, parsed);
|
|
105
|
+
return parsed;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export async function clearCodexV5SessionState(expectedSessionId, env = process.env) {
|
|
109
|
+
const target = sessionPath(env);
|
|
110
|
+
await withPrivateFileLock(target, async () => {
|
|
111
|
+
const current = await readParsed(target, CodexV5SessionStateSchema);
|
|
112
|
+
if (!current)
|
|
113
|
+
return;
|
|
114
|
+
if (current.sessionId !== expectedSessionId)
|
|
115
|
+
throw stateConflict();
|
|
116
|
+
await removePrivateFileDurably(target);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export function readCodexV5AcquireJournal(env = process.env) {
|
|
120
|
+
return readParsed(acquirePath(env), CodexV5AcquireJournalSchema);
|
|
121
|
+
}
|
|
122
|
+
export async function writeCodexV5AcquireJournal(value, env = process.env) {
|
|
123
|
+
const target = acquirePath(env);
|
|
124
|
+
return withPrivateFileLock(target, async () => {
|
|
125
|
+
const parsed = CodexV5AcquireJournalSchema.parse(value);
|
|
126
|
+
const current = await readParsed(target, CodexV5AcquireJournalSchema);
|
|
127
|
+
if (current && JSON.stringify(current) !== JSON.stringify(parsed))
|
|
128
|
+
throw stateConflict();
|
|
129
|
+
if (!current)
|
|
130
|
+
await writePrivateJson(target, parsed);
|
|
131
|
+
return current ?? parsed;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
export async function updateCodexV5AcquireJournalResponse(expected, response, now, env = process.env) {
|
|
135
|
+
const target = acquirePath(env);
|
|
136
|
+
return withPrivateFileLock(target, async () => {
|
|
137
|
+
const current = await readParsed(target, CodexV5AcquireJournalSchema);
|
|
138
|
+
if (!current || current.clientRequestId !== expected.clientRequestId
|
|
139
|
+
|| current.idempotencyKey !== expected.idempotencyKey)
|
|
140
|
+
throw stateConflict();
|
|
141
|
+
const updated = CodexV5AcquireJournalSchema.parse({ ...current, response,
|
|
142
|
+
updatedAt: new Date(now).toISOString() });
|
|
143
|
+
await writePrivateJson(target, updated);
|
|
144
|
+
return updated;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
export async function clearCodexV5AcquireJournal(expected, env = process.env) {
|
|
148
|
+
const target = acquirePath(env);
|
|
149
|
+
await withPrivateFileLock(target, async () => {
|
|
150
|
+
const current = await readParsed(target, CodexV5AcquireJournalSchema);
|
|
151
|
+
if (!current)
|
|
152
|
+
return;
|
|
153
|
+
if (current.clientRequestId !== expected.clientRequestId
|
|
154
|
+
|| current.idempotencyKey !== expected.idempotencyKey)
|
|
155
|
+
throw stateConflict();
|
|
156
|
+
await removePrivateFileDurably(target);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
export function openCodexV5AcquireJournalKey(journal) {
|
|
160
|
+
const encoded = Buffer.from(journal.privateKeyPkcs8, "base64url");
|
|
161
|
+
try {
|
|
162
|
+
if (encoded.toString("base64url") !== journal.privateKeyPkcs8)
|
|
163
|
+
throw stateConflict();
|
|
164
|
+
const key = createPrivateKey({ key: encoded, format: "der", type: "pkcs8" });
|
|
165
|
+
if (key.asymmetricKeyType !== "x25519")
|
|
166
|
+
throw stateConflict();
|
|
167
|
+
return key;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
encoded.fill(0);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export function readCodexV5ReportJournal(env = process.env) {
|
|
174
|
+
return readParsed(reportPath(env), CodexV5ReportJournalSchema);
|
|
175
|
+
}
|
|
176
|
+
export async function writeCodexV5ReportJournal(value, env = process.env) {
|
|
177
|
+
const target = reportPath(env);
|
|
178
|
+
return withPrivateFileLock(target, async () => {
|
|
179
|
+
const parsed = CodexV5ReportJournalSchema.parse(value);
|
|
180
|
+
const current = await readParsed(target, CodexV5ReportJournalSchema);
|
|
181
|
+
if (current && JSON.stringify(current) !== JSON.stringify(parsed))
|
|
182
|
+
throw stateConflict();
|
|
183
|
+
if (!current)
|
|
184
|
+
await writePrivateJson(target, parsed);
|
|
185
|
+
return current ?? parsed;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export async function clearCodexV5ReportJournal(expected, env = process.env) {
|
|
189
|
+
const target = reportPath(env);
|
|
190
|
+
await withPrivateFileLock(target, async () => {
|
|
191
|
+
const current = await readParsed(target, CodexV5ReportJournalSchema);
|
|
192
|
+
if (!current)
|
|
193
|
+
return;
|
|
194
|
+
if (current.clientRequestId !== expected.clientRequestId
|
|
195
|
+
|| current.idempotencyKey !== expected.idempotencyKey)
|
|
196
|
+
throw stateConflict();
|
|
197
|
+
await removePrivateFileDurably(target);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
export function exportCodexV5PrivateKey(privateKey) {
|
|
201
|
+
if (privateKey.asymmetricKeyType !== "x25519")
|
|
202
|
+
throw stateConflict();
|
|
203
|
+
const encoded = privateKey.export({ format: "der", type: "pkcs8" });
|
|
204
|
+
if (!Buffer.isBuffer(encoded))
|
|
205
|
+
throw stateConflict();
|
|
206
|
+
try {
|
|
207
|
+
return encoded.toString("base64url");
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
encoded.fill(0);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function stateConflict() {
|
|
214
|
+
return Object.assign(new Error("The Codex v5 device state changed unexpectedly."), {
|
|
215
|
+
code: "managed_codex_v5_state_conflict"
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=multi-device-v5-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-device-v5-state.js","sourceRoot":"","sources":["../src/multi-device-v5-state.ts"],"names":[],"mappings":"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"}
|
package/dist/profile.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export interface ResolvedCodexProfile {
|
|
|
24
24
|
rotationSync: boolean;
|
|
25
25
|
managedCredentialsV3?: boolean;
|
|
26
26
|
accountTokenPoolV4?: boolean;
|
|
27
|
+
multiDeviceCredentialSync?: boolean;
|
|
27
28
|
};
|
|
28
29
|
stale: boolean;
|
|
29
30
|
}
|
|
@@ -39,3 +40,4 @@ export interface ResolveCodexProfileOptions {
|
|
|
39
40
|
export declare function resolveCodexProfile(options: ResolveCodexProfileOptions): Promise<ResolvedCodexProfile>;
|
|
40
41
|
export declare function profileManagedCredentialsV3Enabled(value: unknown): boolean;
|
|
41
42
|
export declare function profileAccountTokenPoolV4Enabled(value: unknown): boolean;
|
|
43
|
+
export declare function profileMultiDeviceCredentialSyncEnabled(value: unknown): boolean;
|
package/dist/profile.js
CHANGED
|
@@ -27,7 +27,8 @@ const ServiceSchema = z.object({
|
|
|
27
27
|
migrationPlans: z.boolean().optional(),
|
|
28
28
|
rotationSync: z.boolean(),
|
|
29
29
|
managedCredentialsV3: z.boolean().optional(),
|
|
30
|
-
accountTokenPoolV4: z.boolean().optional()
|
|
30
|
+
accountTokenPoolV4: z.boolean().optional(),
|
|
31
|
+
multiDeviceCredentialSync: z.boolean().optional()
|
|
31
32
|
}).passthrough().optional()
|
|
32
33
|
}).passthrough().optional()
|
|
33
34
|
});
|
|
@@ -108,6 +109,8 @@ export async function resolveCodexProfile(options) {
|
|
|
108
109
|
|| cachedProfile?.success === true && profileManagedCredentialsV3Enabled(cachedProfile.data);
|
|
109
110
|
const accountTokenPoolV4Required = cached?.observedAccountTokenPoolV4 === true
|
|
110
111
|
|| cachedProfile?.success === true && profileAccountTokenPoolV4Enabled(cachedProfile.data);
|
|
112
|
+
const multiDeviceCredentialSyncRequired = cached?.observedMultiDeviceCredentialSync === true
|
|
113
|
+
|| cachedProfile?.success === true && profileMultiDeviceCredentialSyncEnabled(cachedProfile.data);
|
|
111
114
|
const cacheMaxAgeMs = cachedProfile?.success
|
|
112
115
|
? (cachedProfile.data.cache?.maxAgeSeconds ?? 300) * 1_000
|
|
113
116
|
: 0;
|
|
@@ -156,6 +159,9 @@ export async function resolveCodexProfile(options) {
|
|
|
156
159
|
if (accountTokenPoolV4Required && !profileAccountTokenPoolV4Enabled(next.data)) {
|
|
157
160
|
throw new CodexError("Client configuration attempted to disable the previously observed v4 account token pool.", "profile_capability_downgrade");
|
|
158
161
|
}
|
|
162
|
+
if (multiDeviceCredentialSyncRequired && !profileMultiDeviceCredentialSyncEnabled(next.data)) {
|
|
163
|
+
throw new CodexError("Client configuration attempted to disable previously observed multi-device credential fencing.", "profile_capability_downgrade");
|
|
164
|
+
}
|
|
159
165
|
const previous = cached ? ProfileSchema.safeParse(cached.profile) : undefined;
|
|
160
166
|
if (previous?.success && next.data.profileId === previous.data.profileId
|
|
161
167
|
&& next.data.revision < previous.data.revision) {
|
|
@@ -174,6 +180,9 @@ export async function resolveCodexProfile(options) {
|
|
|
174
180
|
...((accountTokenPoolV4Required || profileAccountTokenPoolV4Enabled(raw))
|
|
175
181
|
? { observedAccountTokenPoolV4: true }
|
|
176
182
|
: {}),
|
|
183
|
+
...((multiDeviceCredentialSyncRequired || profileMultiDeviceCredentialSyncEnabled(raw))
|
|
184
|
+
? { observedMultiDeviceCredentialSync: true }
|
|
185
|
+
: {}),
|
|
177
186
|
profile: raw
|
|
178
187
|
};
|
|
179
188
|
}
|
|
@@ -202,6 +211,9 @@ export async function resolveCodexProfile(options) {
|
|
|
202
211
|
if (accountTokenPoolV4Required && !profileAccountTokenPoolV4Enabled(profile.data)) {
|
|
203
212
|
throw new CodexError("A cached profile cannot disable the previously observed v4 account token pool.", "profile_capability_downgrade");
|
|
204
213
|
}
|
|
214
|
+
if (multiDeviceCredentialSyncRequired && !profileMultiDeviceCredentialSyncEnabled(profile.data)) {
|
|
215
|
+
throw new CodexError("A cached profile cannot disable previously observed multi-device credential fencing.", "profile_capability_downgrade");
|
|
216
|
+
}
|
|
205
217
|
const minimumVersion = profile.data.minimumClientVersions?.tokensrcCodex;
|
|
206
218
|
if (minimumVersion && compareVersions(PACKAGE_VERSION, minimumVersion) < 0) {
|
|
207
219
|
throw new CodexError(`@tokensrc/codex ${minimumVersion} or newer is required by this profile.`, "client_upgrade_required");
|
|
@@ -277,6 +289,17 @@ export function profileAccountTokenPoolV4Enabled(value) {
|
|
|
277
289
|
return parsed.success
|
|
278
290
|
&& parsed.data.services.codex?.capabilities?.userBoundRefreshTokens?.accountTokenPoolV4 === true;
|
|
279
291
|
}
|
|
292
|
+
export function profileMultiDeviceCredentialSyncEnabled(value) {
|
|
293
|
+
if (value && typeof value === "object"
|
|
294
|
+
&& value
|
|
295
|
+
.userBoundRefreshTokens?.multiDeviceCredentialSync === true) {
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
const parsed = ProfileSchema.safeParse(value);
|
|
299
|
+
return parsed.success
|
|
300
|
+
&& parsed.data.services.codex?.capabilities?.userBoundRefreshTokens
|
|
301
|
+
?.multiDeviceCredentialSync === true;
|
|
302
|
+
}
|
|
280
303
|
function defaultProfileDirectory() {
|
|
281
304
|
const configured = process.env.TOKENSRC_CODEX_CONFIG_DIR?.trim();
|
|
282
305
|
if (configured)
|