@tokensrc/codex 1.14.2 → 1.14.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/client.d.ts +6 -1
- package/dist/client.js +40 -1
- package/dist/client.js.map +1 -1
- package/dist/command-directory.js +1 -1
- package/dist/command-directory.js.map +1 -1
- package/dist/commands.js +85 -40
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/managed-credential-v3-assignment.d.ts +38 -0
- package/dist/managed-credential-v3-assignment.js +68 -0
- package/dist/managed-credential-v3-assignment.js.map +1 -0
- package/dist/managed-credential-v3-envelope.d.ts +18 -1
- package/dist/managed-credential-v3-envelope.js +34 -1
- package/dist/managed-credential-v3-envelope.js.map +1 -1
- package/dist/protocol.d.ts +148 -0
- package/dist/protocol.js +102 -2
- package/dist/protocol.js.map +1 -1
- package/dist/token-pool-v4-upload-flow.d.ts +29 -0
- package/dist/token-pool-v4-upload-flow.js +162 -0
- package/dist/token-pool-v4-upload-flow.js.map +1 -0
- package/dist/token-pool-v4-upload-journal.d.ts +36 -0
- package/dist/token-pool-v4-upload-journal.js +76 -0
- package/dist/token-pool-v4-upload-journal.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { withOneShotCodexLogin } from "./enrollment-login.js";
|
|
3
|
+
import { CodexServiceError } from "./errors.js";
|
|
4
|
+
import { codexTokenPoolV4AssignmentTarget } from "./managed-credential-v3-assignment.js";
|
|
5
|
+
import { sealCodexTokenPoolV4Upload } from "./managed-credential-v3-envelope.js";
|
|
6
|
+
import { clearCodexTokenPoolV4UploadJournal, readCodexTokenPoolV4UploadJournal, writeCodexTokenPoolV4UploadJournal } from "./token-pool-v4-upload-journal.js";
|
|
7
|
+
export async function executeCodexTokenPoolV4Login(input) {
|
|
8
|
+
const target = codexTokenPoolV4AssignmentTarget(input.target);
|
|
9
|
+
const pending = await readCodexTokenPoolV4UploadJournal(input.env);
|
|
10
|
+
if (pending) {
|
|
11
|
+
const currentUploaderSubject = await input.client.getCurrentActorSubject();
|
|
12
|
+
if (pending.tenantId !== input.tenantId || pending.uploaderSubject !== currentUploaderSubject
|
|
13
|
+
|| JSON.stringify(pending.target) !== JSON.stringify(target)) {
|
|
14
|
+
throw new CodexServiceError("A different token-pool upload is pending; reconcile it before changing the target.", "codex_token_pool_v4_state_conflict", 409);
|
|
15
|
+
}
|
|
16
|
+
return completeCodexTokenPoolV4Upload({ ...input, journal: pending });
|
|
17
|
+
}
|
|
18
|
+
const configuration = await input.client.getTokenPoolV4EnrollmentConfiguration();
|
|
19
|
+
const uploaderSubject = await input.client.getCurrentActorSubject();
|
|
20
|
+
const resolvedUserSubject = target.mode === "UNBOUND_POOL"
|
|
21
|
+
? null
|
|
22
|
+
: target.mode === "SUBJECT"
|
|
23
|
+
? target.userSubject
|
|
24
|
+
: (await input.client.resolveTokenPoolV4DirectoryUser(target.principal)).user.userSubject;
|
|
25
|
+
const newId = input.newId ?? randomUUID;
|
|
26
|
+
const now = input.now ?? Date.now;
|
|
27
|
+
return withOneShotCodexLogin({
|
|
28
|
+
mode: input.deviceAuth ? "device" : "browser",
|
|
29
|
+
env: input.env
|
|
30
|
+
}, async (credentials) => {
|
|
31
|
+
if (!credentials.providerAccountId) {
|
|
32
|
+
throw new CodexServiceError("Official Codex login did not expose a provider account id.", "invalid_managed_codex_v3_credentials");
|
|
33
|
+
}
|
|
34
|
+
const expiresAt = tokenExpiry(credentials.accessToken);
|
|
35
|
+
if (expiresAt === undefined) {
|
|
36
|
+
throw new CodexServiceError("Official Codex login did not expose a usable access-token expiry.", "invalid_managed_codex_v3_credentials");
|
|
37
|
+
}
|
|
38
|
+
const clientRequestId = newId();
|
|
39
|
+
const idempotencyKey = newId();
|
|
40
|
+
const envelope = sealCodexTokenPoolV4Upload({
|
|
41
|
+
tenantId: input.tenantId,
|
|
42
|
+
uploaderSubject,
|
|
43
|
+
target,
|
|
44
|
+
clientRequestId,
|
|
45
|
+
idempotencyKey,
|
|
46
|
+
ingress: configuration.ingress,
|
|
47
|
+
credentials: {
|
|
48
|
+
refreshToken: credentials.refreshToken,
|
|
49
|
+
accessToken: credentials.accessToken,
|
|
50
|
+
idToken: credentials.idToken,
|
|
51
|
+
providerAccountId: credentials.providerAccountId,
|
|
52
|
+
expiresAt: new Date(expiresAt).toISOString()
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const timestamp = new Date(now()).toISOString();
|
|
56
|
+
const journal = await writeCodexTokenPoolV4UploadJournal({
|
|
57
|
+
schemaVersion: 4,
|
|
58
|
+
kind: "TOKEN_POOL_UPLOAD",
|
|
59
|
+
tenantId: input.tenantId,
|
|
60
|
+
uploaderSubject,
|
|
61
|
+
target,
|
|
62
|
+
resolvedUserSubject,
|
|
63
|
+
providerAccountId: credentials.providerAccountId,
|
|
64
|
+
clientRequestId,
|
|
65
|
+
idempotencyKey,
|
|
66
|
+
envelope,
|
|
67
|
+
createdAt: timestamp,
|
|
68
|
+
updatedAt: timestamp
|
|
69
|
+
}, input.env);
|
|
70
|
+
return completeCodexTokenPoolV4Upload({ ...input, journal });
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async function completeCodexTokenPoolV4Upload(input) {
|
|
74
|
+
const request = {
|
|
75
|
+
schemaVersion: 4,
|
|
76
|
+
clientRequestId: input.journal.clientRequestId,
|
|
77
|
+
target: input.journal.target,
|
|
78
|
+
envelope: input.journal.envelope
|
|
79
|
+
};
|
|
80
|
+
const expectedSubject = input.journal.resolvedUserSubject ?? undefined;
|
|
81
|
+
let response = await postResolveReplay({
|
|
82
|
+
post: () => input.client.createTokenPoolV4Upload(request, input.journal.idempotencyKey, expectedSubject),
|
|
83
|
+
resolve: () => input.client.resolveTokenPoolV4Upload(input.journal.clientRequestId, input.journal.target, expectedSubject)
|
|
84
|
+
});
|
|
85
|
+
const wait = input.wait ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
86
|
+
for (let attempt = 0; response.upload.status === "VALIDATING" && attempt < 120; attempt += 1) {
|
|
87
|
+
await wait(1_000);
|
|
88
|
+
response = await input.client.resolveTokenPoolV4Upload(input.journal.clientRequestId, input.journal.target, expectedSubject);
|
|
89
|
+
}
|
|
90
|
+
if (response.upload.status === "VALIDATING") {
|
|
91
|
+
throw new CodexServiceError("Token-pool upload is still validating; retry the same command to resolve it without another login.", "codex_token_pool_v4_result_unknown");
|
|
92
|
+
}
|
|
93
|
+
if (response.upload.status !== "POOLED" && response.upload.status !== "RESERVED") {
|
|
94
|
+
await clearCodexTokenPoolV4UploadJournal(input.journal, input.env);
|
|
95
|
+
throw new CodexServiceError(`Token-pool upload did not succeed (${response.upload.status}).`, response.upload.safeErrorCode ?? "codex_token_pool_v4_upload_failed", 409);
|
|
96
|
+
}
|
|
97
|
+
const upload = response.upload;
|
|
98
|
+
if (upload.providerAccountId !== input.journal.providerAccountId
|
|
99
|
+
|| upload.managedAccountId == null || upload.poolEntryId == null || upload.completedAt == null
|
|
100
|
+
|| (upload.status === "RESERVED" && (upload.assignmentId == null
|
|
101
|
+
|| upload.assignedUserSubject !== input.journal.resolvedUserSubject
|
|
102
|
+
|| upload.reservedLineageId == null))) {
|
|
103
|
+
throw new CodexServiceError("Token-pool upload evidence does not match the encrypted candidate.", "invalid_codex_service_response");
|
|
104
|
+
}
|
|
105
|
+
await clearCodexTokenPoolV4UploadJournal(input.journal, input.env);
|
|
106
|
+
return {
|
|
107
|
+
uploadId: upload.id,
|
|
108
|
+
status: upload.status,
|
|
109
|
+
placement: upload.placement,
|
|
110
|
+
managedAccountId: upload.managedAccountId,
|
|
111
|
+
providerAccountId: upload.providerAccountId,
|
|
112
|
+
poolEntryId: upload.poolEntryId,
|
|
113
|
+
assignmentId: upload.assignmentId,
|
|
114
|
+
assignedUserSubject: upload.assignedUserSubject,
|
|
115
|
+
reservedLineageId: upload.reservedLineageId,
|
|
116
|
+
target: upload.target,
|
|
117
|
+
completedAt: upload.completedAt,
|
|
118
|
+
replayed: response.replayed
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function postResolveReplay(input) {
|
|
122
|
+
try {
|
|
123
|
+
return await input.post();
|
|
124
|
+
}
|
|
125
|
+
catch (postError) {
|
|
126
|
+
if (!resultMayBeUnknown(postError))
|
|
127
|
+
throw postError;
|
|
128
|
+
try {
|
|
129
|
+
return await input.resolve();
|
|
130
|
+
}
|
|
131
|
+
catch (resolveError) {
|
|
132
|
+
if (resolveError instanceof CodexServiceError && resolveError.status === 404) {
|
|
133
|
+
try {
|
|
134
|
+
return await input.post();
|
|
135
|
+
}
|
|
136
|
+
catch (replayError) {
|
|
137
|
+
throw new CodexServiceError("Token-pool upload remains unknown after exact replay.", "codex_token_pool_v4_result_unknown", undefined, { cause: replayError });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw new CodexServiceError("Token-pool upload outcome is unknown; retry with the persisted local operation.", "codex_token_pool_v4_result_unknown", undefined, { cause: postError });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function resultMayBeUnknown(error) {
|
|
145
|
+
if (!(error instanceof CodexServiceError))
|
|
146
|
+
return true;
|
|
147
|
+
return error.status === undefined || error.status >= 500
|
|
148
|
+
|| error.code === "invalid_codex_service_response";
|
|
149
|
+
}
|
|
150
|
+
function tokenExpiry(token) {
|
|
151
|
+
try {
|
|
152
|
+
const payload = token.split(".")[1];
|
|
153
|
+
if (!payload)
|
|
154
|
+
return undefined;
|
|
155
|
+
const value = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
156
|
+
return typeof value.exp === "number" && Number.isFinite(value.exp) ? value.exp * 1_000 : undefined;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=token-pool-v4-upload-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-pool-v4-upload-flow.js","sourceRoot":"","sources":["../src/token-pool-v4-upload-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const CodexTokenPoolV4UploadJournalSchema: z.ZodObject<{
|
|
3
|
+
schemaVersion: z.ZodLiteral<4>;
|
|
4
|
+
kind: z.ZodLiteral<"TOKEN_POOL_UPLOAD">;
|
|
5
|
+
tenantId: z.ZodString;
|
|
6
|
+
uploaderSubject: z.ZodString;
|
|
7
|
+
target: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
8
|
+
mode: z.ZodLiteral<"UNBOUND_POOL">;
|
|
9
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
10
|
+
mode: z.ZodLiteral<"DIRECTORY_PRINCIPAL">;
|
|
11
|
+
principal: z.ZodString;
|
|
12
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
13
|
+
mode: z.ZodLiteral<"SUBJECT">;
|
|
14
|
+
userSubject: z.ZodString;
|
|
15
|
+
}, z.core.$strict>], "mode">;
|
|
16
|
+
resolvedUserSubject: z.ZodNullable<z.ZodString>;
|
|
17
|
+
providerAccountId: z.ZodString;
|
|
18
|
+
clientRequestId: z.ZodString;
|
|
19
|
+
idempotencyKey: z.ZodString;
|
|
20
|
+
envelope: z.ZodObject<{
|
|
21
|
+
version: z.ZodLiteral<1>;
|
|
22
|
+
algorithm: z.ZodLiteral<"X25519-HKDF-SHA256-AES-256-GCM">;
|
|
23
|
+
keyId: z.ZodString;
|
|
24
|
+
ephemeralPublicKey: z.ZodString;
|
|
25
|
+
salt: z.ZodString;
|
|
26
|
+
nonce: z.ZodString;
|
|
27
|
+
ciphertext: z.ZodString;
|
|
28
|
+
authenticationTag: z.ZodString;
|
|
29
|
+
}, z.core.$strict>;
|
|
30
|
+
createdAt: z.ZodString;
|
|
31
|
+
updatedAt: z.ZodString;
|
|
32
|
+
}, z.core.$strict>;
|
|
33
|
+
export type CodexTokenPoolV4UploadJournal = z.infer<typeof CodexTokenPoolV4UploadJournalSchema>;
|
|
34
|
+
export declare function readCodexTokenPoolV4UploadJournal(env?: NodeJS.ProcessEnv): Promise<CodexTokenPoolV4UploadJournal | undefined>;
|
|
35
|
+
export declare function writeCodexTokenPoolV4UploadJournal(value: CodexTokenPoolV4UploadJournal, env?: NodeJS.ProcessEnv): Promise<CodexTokenPoolV4UploadJournal>;
|
|
36
|
+
export declare function clearCodexTokenPoolV4UploadJournal(expected: Pick<CodexTokenPoolV4UploadJournal, "clientRequestId" | "idempotencyKey">, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { CodexTokenPoolV4AssignmentTargetSchema, CodexTokenPoolV4IdempotencyKeySchema, CodexV3CredentialEnvelopeSchema } from "./protocol.js";
|
|
5
|
+
import { readJsonIfExists, removePrivateFileDurably, withPrivateFileLock, writePrivateJson } from "./private-file.js";
|
|
6
|
+
const Id = z.string().min(1).max(512).refine((value) => value === value.trim());
|
|
7
|
+
const Instant = z.string().datetime({ offset: true });
|
|
8
|
+
export const CodexTokenPoolV4UploadJournalSchema = z.strictObject({
|
|
9
|
+
schemaVersion: z.literal(4),
|
|
10
|
+
kind: z.literal("TOKEN_POOL_UPLOAD"),
|
|
11
|
+
tenantId: Id,
|
|
12
|
+
uploaderSubject: z.string().min(1).max(255).refine((value) => value === value.trim()),
|
|
13
|
+
target: CodexTokenPoolV4AssignmentTargetSchema,
|
|
14
|
+
resolvedUserSubject: z.string().min(1).max(255).nullable(),
|
|
15
|
+
providerAccountId: Id,
|
|
16
|
+
clientRequestId: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{7,199}$/u),
|
|
17
|
+
idempotencyKey: CodexTokenPoolV4IdempotencyKeySchema,
|
|
18
|
+
envelope: CodexV3CredentialEnvelopeSchema,
|
|
19
|
+
createdAt: Instant,
|
|
20
|
+
updatedAt: Instant
|
|
21
|
+
}).superRefine((value, context) => {
|
|
22
|
+
const valid = value.target.mode === "UNBOUND_POOL"
|
|
23
|
+
? value.resolvedUserSubject == null
|
|
24
|
+
: value.target.mode === "SUBJECT"
|
|
25
|
+
? value.resolvedUserSubject === value.target.userSubject
|
|
26
|
+
: value.resolvedUserSubject != null;
|
|
27
|
+
if (!valid)
|
|
28
|
+
context.addIssue({ code: "custom", message: "Token-pool target evidence is inconsistent." });
|
|
29
|
+
});
|
|
30
|
+
function journalPath(env) {
|
|
31
|
+
const home = env.CODEX_HOME?.trim() || join(homedir(), ".codex");
|
|
32
|
+
return join(home, ".numa-token-pool-v4-upload.json");
|
|
33
|
+
}
|
|
34
|
+
export async function readCodexTokenPoolV4UploadJournal(env = process.env) {
|
|
35
|
+
const raw = await readJsonIfExists(journalPath(env));
|
|
36
|
+
if (raw === undefined)
|
|
37
|
+
return undefined;
|
|
38
|
+
const parsed = CodexTokenPoolV4UploadJournalSchema.safeParse(raw);
|
|
39
|
+
if (!parsed.success)
|
|
40
|
+
throw Object.assign(new Error("The private token-pool upload journal is invalid."), {
|
|
41
|
+
code: "codex_token_pool_v4_journal_invalid"
|
|
42
|
+
});
|
|
43
|
+
return parsed.data;
|
|
44
|
+
}
|
|
45
|
+
export async function writeCodexTokenPoolV4UploadJournal(value, env = process.env) {
|
|
46
|
+
const target = journalPath(env);
|
|
47
|
+
return withPrivateFileLock(target, async () => {
|
|
48
|
+
const parsed = CodexTokenPoolV4UploadJournalSchema.parse(value);
|
|
49
|
+
const current = await readCodexTokenPoolV4UploadJournal(env);
|
|
50
|
+
if (current) {
|
|
51
|
+
if (JSON.stringify(current) === JSON.stringify(parsed))
|
|
52
|
+
return current;
|
|
53
|
+
throw Object.assign(new Error("Another token-pool upload is already pending."), {
|
|
54
|
+
code: "codex_token_pool_v4_state_conflict"
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
await writePrivateJson(target, parsed);
|
|
58
|
+
return parsed;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export async function clearCodexTokenPoolV4UploadJournal(expected, env = process.env) {
|
|
62
|
+
const target = journalPath(env);
|
|
63
|
+
await withPrivateFileLock(target, async () => {
|
|
64
|
+
const current = await readCodexTokenPoolV4UploadJournal(env);
|
|
65
|
+
if (!current)
|
|
66
|
+
return;
|
|
67
|
+
if (current.clientRequestId !== expected.clientRequestId
|
|
68
|
+
|| current.idempotencyKey !== expected.idempotencyKey) {
|
|
69
|
+
throw Object.assign(new Error("The token-pool upload journal changed unexpectedly."), {
|
|
70
|
+
code: "codex_token_pool_v4_state_conflict"
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
await removePrivateFileDurably(target);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=token-pool-v4-upload-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-pool-v4-upload-journal.js","sourceRoot":"","sources":["../src/token-pool-v4-upload-journal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokensrc/codex",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.4",
|
|
4
4
|
"description": "Standalone Codex account selection, authentication and launcher module.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@clack/prompts": "^1.7.0",
|
|
78
|
-
"@numa-tech/cli-auth": "1.14.
|
|
78
|
+
"@numa-tech/cli-auth": "1.14.4",
|
|
79
79
|
"@openai/codex": "^0.146.0",
|
|
80
80
|
"codex-multi-auth": "^2.8.0",
|
|
81
81
|
"commander": "^14.0.3",
|