@tokensrc/codex 1.14.16 → 1.14.17
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/README.md +73 -1
- package/dist/client.d.ts +21 -1
- package/dist/client.js +198 -3
- package/dist/client.js.map +1 -1
- package/dist/command-directory.js +3 -2
- package/dist/command-directory.js.map +1 -1
- package/dist/commands.js +478 -12
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/managed-credential-v3-envelope.d.ts +40 -1
- package/dist/managed-credential-v3-envelope.js +118 -1
- package/dist/managed-credential-v3-envelope.js.map +1 -1
- package/dist/managed-credential-v3-flow.js +105 -21
- package/dist/managed-credential-v3-flow.js.map +1 -1
- package/dist/profile.d.ts +2 -0
- package/dist/profile.js +26 -1
- package/dist/profile.js.map +1 -1
- package/dist/protocol.d.ts +1107 -0
- package/dist/protocol.js +494 -0
- package/dist/protocol.js.map +1 -1
- package/dist/request-bound-device-v6-flow.d.ts +42 -0
- package/dist/request-bound-device-v6-flow.js +403 -0
- package/dist/request-bound-device-v6-flow.js.map +1 -0
- package/dist/request-bound-device-v6-state.d.ts +397 -0
- package/dist/request-bound-device-v6-state.js +221 -0
- package/dist/request-bound-device-v6-state.js.map +1 -0
- package/dist/selection.d.ts +5 -0
- package/dist/selection.js +20 -2
- package/dist/selection.js.map +1 -1
- package/dist/token-pool-v4-upload-flow.js +5 -1
- package/dist/token-pool-v4-upload-flow.js.map +1 -1
- package/package.json +2 -2
package/dist/protocol.js
CHANGED
|
@@ -33,6 +33,14 @@ export const CODEX_MULTI_DEVICE_V5_RUNTIME_PATH = "/v5/codex";
|
|
|
33
33
|
export const CODEX_MULTI_DEVICE_V5_CREDENTIAL_ASSIGNMENTS_PATH = `${CODEX_MULTI_DEVICE_V5_RUNTIME_PATH}/credential-assignments`;
|
|
34
34
|
export const CODEX_MULTI_DEVICE_V5_DEVICE_SESSIONS_PATH = `${CODEX_MULTI_DEVICE_V5_RUNTIME_PATH}/device-sessions`;
|
|
35
35
|
export const CODEX_MULTI_DEVICE_V5_CREDENTIAL_LINEAGES_PATH = `${CODEX_MULTI_DEVICE_V5_RUNTIME_PATH}/credential-lineages`;
|
|
36
|
+
export const CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION = 6;
|
|
37
|
+
export const CODEX_REQUEST_BOUND_DEVICE_V6_RUNTIME_PATH = "/v6/codex";
|
|
38
|
+
export const CODEX_V6_ACCOUNT_REQUESTS_PATH = `${CODEX_REQUEST_BOUND_DEVICE_V6_RUNTIME_PATH}/account-requests`;
|
|
39
|
+
export const CODEX_V6_DEVICE_ACCESS_RECONCILIATIONS_PATH = `${CODEX_REQUEST_BOUND_DEVICE_V6_RUNTIME_PATH}/device-access/reconciliations`;
|
|
40
|
+
export const CODEX_V6_DEVICE_BINDINGS_PATH = `${CODEX_REQUEST_BOUND_DEVICE_V6_RUNTIME_PATH}/device-bindings`;
|
|
41
|
+
export const CODEX_REQUEST_BOUND_DEVICE_V6_ADMIN_PATH = "/v6/admin/codex";
|
|
42
|
+
export const CODEX_V6_ADMIN_ACCOUNT_REQUESTS_PATH = `${CODEX_REQUEST_BOUND_DEVICE_V6_ADMIN_PATH}/account-requests`;
|
|
43
|
+
export const CODEX_V6_ADMIN_DEVICE_BINDINGS_PATH = `${CODEX_REQUEST_BOUND_DEVICE_V6_ADMIN_PATH}/device-bindings`;
|
|
36
44
|
export const CODEX_MIGRATION_CAPACITY = {
|
|
37
45
|
verifiedMinimum: 2,
|
|
38
46
|
verifiedLimit: null,
|
|
@@ -895,6 +903,436 @@ export const CodexV5GenerationReportResponseSchema = z.strictObject({
|
|
|
895
903
|
message: "Generation did not advance exactly once." });
|
|
896
904
|
}
|
|
897
905
|
});
|
|
906
|
+
/**
|
|
907
|
+
* v6 makes one complete upstream token set the property of exactly one
|
|
908
|
+
* request/device binding. A request may own several bindings for the same
|
|
909
|
+
* user, but lineages and installation ids may never be shared by bindings.
|
|
910
|
+
*/
|
|
911
|
+
export const CodexV6DeviceDescriptorSchema = z.strictObject({
|
|
912
|
+
installationId: CodexV5InstallationIdSchema,
|
|
913
|
+
label: z.string().trim().min(1).max(128),
|
|
914
|
+
platform: z.enum(["darwin", "linux", "win32", "unknown"])
|
|
915
|
+
});
|
|
916
|
+
export const CodexV6AccountRequestStatusSchema = z.enum([
|
|
917
|
+
"SUBMITTED",
|
|
918
|
+
"APPROVED",
|
|
919
|
+
"REJECTED",
|
|
920
|
+
"CANCELLED",
|
|
921
|
+
"EXPIRED"
|
|
922
|
+
]);
|
|
923
|
+
export const CodexV6AccountRequestAvailabilitySchema = z.enum([
|
|
924
|
+
"PENDING_APPROVAL",
|
|
925
|
+
"WAITING_FOR_BINDING",
|
|
926
|
+
"PARTIALLY_AVAILABLE",
|
|
927
|
+
"AVAILABLE",
|
|
928
|
+
"UNAVAILABLE",
|
|
929
|
+
"EXPIRED"
|
|
930
|
+
]);
|
|
931
|
+
export const CodexV6AccountRequestSchema = z.strictObject({
|
|
932
|
+
id: CodexV3IdSchema,
|
|
933
|
+
userSubject: CodexV3IdSchema,
|
|
934
|
+
username: z.string().trim().min(1).max(255),
|
|
935
|
+
userEmail: z.email().nullable(),
|
|
936
|
+
status: CodexV6AccountRequestStatusSchema,
|
|
937
|
+
availability: CodexV6AccountRequestAvailabilitySchema,
|
|
938
|
+
reason: z.string().trim().min(5).max(1_000),
|
|
939
|
+
requestedDeviceCount: z.number().int().min(1).max(32),
|
|
940
|
+
approvedDeviceLimit: z.number().int().min(1).max(32).nullable(),
|
|
941
|
+
activeBindingCount: z.number().int().min(0).max(32),
|
|
942
|
+
pendingBindingCount: z.number().int().min(0).max(32),
|
|
943
|
+
requestedValidUntil: CodexV3InstantSchema,
|
|
944
|
+
validFrom: CodexV3InstantSchema.nullable(),
|
|
945
|
+
validUntil: CodexV3InstantSchema.nullable(),
|
|
946
|
+
version: z.number().int().nonnegative(),
|
|
947
|
+
createdAt: CodexV3InstantSchema,
|
|
948
|
+
submittedAt: CodexV3InstantSchema,
|
|
949
|
+
reviewedAt: CodexV3InstantSchema.nullable(),
|
|
950
|
+
safeErrorCode: z.string().min(1).max(128).regex(/^[a-z][a-z0-9_.-]*$/u).nullable(),
|
|
951
|
+
allowedActions: z.array(z.enum(["CANCEL", "CLAIM_DEVICE", "VIEW_BINDINGS"])).max(3)
|
|
952
|
+
}).superRefine((value, context) => {
|
|
953
|
+
const approved = ["APPROVED", "EXPIRED"].includes(value.status);
|
|
954
|
+
if (approved !== (value.approvedDeviceLimit !== null && value.validFrom !== null
|
|
955
|
+
&& value.validUntil !== null)) {
|
|
956
|
+
context.addIssue({ code: "custom", message: "Request approval evidence is inconsistent." });
|
|
957
|
+
}
|
|
958
|
+
if (value.approvedDeviceLimit !== null
|
|
959
|
+
&& value.activeBindingCount + value.pendingBindingCount > value.approvedDeviceLimit) {
|
|
960
|
+
context.addIssue({ code: "custom", message: "Request binding counts exceed the approved limit." });
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
export const CodexV6CreateAccountRequestInputSchema = z.strictObject({
|
|
964
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
965
|
+
clientRequestId: CodexV3ClientRequestIdSchema,
|
|
966
|
+
reason: z.string().trim().min(5).max(1_000),
|
|
967
|
+
requestedDeviceCount: z.number().int().min(1).max(32),
|
|
968
|
+
requestedValidUntil: CodexV3InstantSchema,
|
|
969
|
+
initialDevice: CodexV6DeviceDescriptorSchema
|
|
970
|
+
});
|
|
971
|
+
export const CodexV6AccountRequestResponseSchema = z.strictObject({
|
|
972
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
973
|
+
request: CodexV6AccountRequestSchema,
|
|
974
|
+
replayed: z.boolean()
|
|
975
|
+
});
|
|
976
|
+
export const CodexV6AccountRequestListResponseSchema = z.strictObject({
|
|
977
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
978
|
+
items: z.array(CodexV6AccountRequestSchema).max(256),
|
|
979
|
+
total: z.number().int().min(0).max(256)
|
|
980
|
+
}).superRefine((value, context) => {
|
|
981
|
+
if (value.items.length !== value.total) {
|
|
982
|
+
context.addIssue({ code: "custom", path: ["total"], message: "Request total is inconsistent." });
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
export const CodexV6AdminAccountRequestListQuerySchema = z.strictObject({
|
|
986
|
+
expiresBefore: CodexV3InstantSchema.optional(),
|
|
987
|
+
includeTerminal: z.boolean().optional()
|
|
988
|
+
});
|
|
989
|
+
export const CodexV6AdminReplacementCandidateQuerySchema = z.strictObject({
|
|
990
|
+
replaceBefore: CodexV3InstantSchema
|
|
991
|
+
});
|
|
992
|
+
export const CodexV6CancelAccountRequestInputSchema = z.strictObject({
|
|
993
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
994
|
+
expectedRequestVersion: z.number().int().nonnegative()
|
|
995
|
+
});
|
|
996
|
+
export const CodexV6AdminReviewAccountRequestInputSchema = z.strictObject({
|
|
997
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
998
|
+
expectedRequestVersion: z.number().int().nonnegative(),
|
|
999
|
+
decision: z.enum(["APPROVE", "REJECT"]),
|
|
1000
|
+
reason: z.string().trim().min(5).max(1_000),
|
|
1001
|
+
approvedDeviceLimit: z.number().int().min(1).max(32).nullable(),
|
|
1002
|
+
validFrom: CodexV3InstantSchema.nullable(),
|
|
1003
|
+
validUntil: CodexV3InstantSchema.nullable()
|
|
1004
|
+
}).superRefine((value, context) => {
|
|
1005
|
+
const approval = value.approvedDeviceLimit !== null && value.validFrom !== null
|
|
1006
|
+
&& value.validUntil !== null;
|
|
1007
|
+
if ((value.decision === "APPROVE") !== approval) {
|
|
1008
|
+
context.addIssue({ code: "custom", message: "Approval decision fields are inconsistent." });
|
|
1009
|
+
}
|
|
1010
|
+
});
|
|
1011
|
+
export const CodexV6DeviceBindingStatusSchema = z.enum([
|
|
1012
|
+
"PENDING_TOKEN",
|
|
1013
|
+
"READY",
|
|
1014
|
+
"ACTIVE",
|
|
1015
|
+
"REPLACEMENT_PENDING",
|
|
1016
|
+
"NEEDS_REAUTH",
|
|
1017
|
+
"RETIREMENT_PENDING",
|
|
1018
|
+
"RETIRED"
|
|
1019
|
+
]);
|
|
1020
|
+
export const CodexV6DeviceBindingSchema = z.strictObject({
|
|
1021
|
+
id: CodexV3IdSchema,
|
|
1022
|
+
requestId: CodexV3IdSchema,
|
|
1023
|
+
userSubject: CodexV3IdSchema,
|
|
1024
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1025
|
+
deviceLabel: z.string().trim().min(1).max(128),
|
|
1026
|
+
platform: z.enum(["darwin", "linux", "win32", "unknown"]),
|
|
1027
|
+
source: z.enum([
|
|
1028
|
+
"REQUEST_INITIAL",
|
|
1029
|
+
"ADMIN_ADDED",
|
|
1030
|
+
"LEGACY_AUTO_MIGRATED",
|
|
1031
|
+
"ACCOUNT_REPLACEMENT"
|
|
1032
|
+
]),
|
|
1033
|
+
status: CodexV6DeviceBindingStatusSchema,
|
|
1034
|
+
predecessorBindingId: CodexV3IdSchema.nullable(),
|
|
1035
|
+
managedAccountId: CodexV3IdSchema.nullable(),
|
|
1036
|
+
providerAccountId: z.string().min(1).max(512).nullable(),
|
|
1037
|
+
poolEntryId: CodexV3IdSchema.nullable(),
|
|
1038
|
+
credentialLineageId: CodexV3IdSchema.nullable(),
|
|
1039
|
+
generationVersion: z.number().int().positive().nullable(),
|
|
1040
|
+
credentialExpiresAt: CodexV3InstantSchema.nullable(),
|
|
1041
|
+
accountExpiresAt: CodexV3InstantSchema.nullable(),
|
|
1042
|
+
replacementDueAt: CodexV3InstantSchema.nullable(),
|
|
1043
|
+
replacementReason: z.enum([
|
|
1044
|
+
"SUBSCRIPTION_EXPIRING",
|
|
1045
|
+
"CREDENTIAL_UNHEALTHY",
|
|
1046
|
+
"ADMIN_REQUESTED"
|
|
1047
|
+
]).nullable(),
|
|
1048
|
+
accessTokenHealth: CodexV3AccessTokenHealthSchema,
|
|
1049
|
+
refreshTokenHealth: CodexV3RefreshTokenHealthSchema,
|
|
1050
|
+
legacyAssignmentId: CodexV3IdSchema.nullable(),
|
|
1051
|
+
createdAt: CodexV3InstantSchema,
|
|
1052
|
+
activatedAt: CodexV3InstantSchema.nullable(),
|
|
1053
|
+
retiredAt: CodexV3InstantSchema.nullable()
|
|
1054
|
+
}).superRefine((value, context) => {
|
|
1055
|
+
const complete = [value.managedAccountId, value.providerAccountId, value.poolEntryId,
|
|
1056
|
+
value.credentialLineageId, value.generationVersion, value.credentialExpiresAt]
|
|
1057
|
+
.every((item) => item !== null);
|
|
1058
|
+
if ((value.status === "PENDING_TOKEN") === complete) {
|
|
1059
|
+
context.addIssue({ code: "custom", message: "Device binding credential evidence is inconsistent." });
|
|
1060
|
+
}
|
|
1061
|
+
if ((value.source === "LEGACY_AUTO_MIGRATED") !== (value.legacyAssignmentId !== null)) {
|
|
1062
|
+
context.addIssue({ code: "custom", message: "Legacy migration evidence is inconsistent." });
|
|
1063
|
+
}
|
|
1064
|
+
if ((value.source === "ACCOUNT_REPLACEMENT") !== (value.predecessorBindingId !== null)) {
|
|
1065
|
+
context.addIssue({ code: "custom", message: "Replacement predecessor evidence is inconsistent." });
|
|
1066
|
+
}
|
|
1067
|
+
const replacementEvidence = value.replacementDueAt !== null && value.replacementReason !== null;
|
|
1068
|
+
if ((value.replacementDueAt !== null) !== (value.replacementReason !== null)
|
|
1069
|
+
|| (value.status === "REPLACEMENT_PENDING" || value.source === "ACCOUNT_REPLACEMENT")
|
|
1070
|
+
!== replacementEvidence) {
|
|
1071
|
+
context.addIssue({ code: "custom", message: "Replacement timing evidence is inconsistent." });
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
export const CodexV6DeviceBindingListResponseSchema = z.strictObject({
|
|
1075
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1076
|
+
items: z.array(CodexV6DeviceBindingSchema).max(32),
|
|
1077
|
+
total: z.number().int().min(0).max(32)
|
|
1078
|
+
}).superRefine((value, context) => {
|
|
1079
|
+
if (value.items.length !== value.total
|
|
1080
|
+
|| new Set(value.items.map(({ id }) => id)).size !== value.items.length
|
|
1081
|
+
|| new Set(value.items.filter(({ credentialLineageId }) => credentialLineageId !== null)
|
|
1082
|
+
.map(({ credentialLineageId }) => credentialLineageId)).size
|
|
1083
|
+
!== value.items.filter(({ credentialLineageId }) => credentialLineageId !== null).length) {
|
|
1084
|
+
context.addIssue({ code: "custom", message: "Device bindings are duplicated or incomplete." });
|
|
1085
|
+
}
|
|
1086
|
+
const byId = new Map(value.items.map((item) => [item.id, item]));
|
|
1087
|
+
const successors = new Set();
|
|
1088
|
+
for (const item of value.items) {
|
|
1089
|
+
if (item.predecessorBindingId === null)
|
|
1090
|
+
continue;
|
|
1091
|
+
const predecessor = byId.get(item.predecessorBindingId);
|
|
1092
|
+
if (!predecessor || predecessor.installationId !== item.installationId
|
|
1093
|
+
|| predecessor.requestId !== item.requestId || predecessor.userSubject !== item.userSubject
|
|
1094
|
+
|| successors.has(predecessor.id)) {
|
|
1095
|
+
context.addIssue({ code: "custom", message: "Replacement binding chain is inconsistent." });
|
|
1096
|
+
break;
|
|
1097
|
+
}
|
|
1098
|
+
successors.add(predecessor.id);
|
|
1099
|
+
}
|
|
1100
|
+
const activeByInstallation = new Map();
|
|
1101
|
+
for (const item of value.items.filter(({ status }) => status !== "RETIRED")) {
|
|
1102
|
+
activeByInstallation.set(item.installationId, [...(activeByInstallation.get(item.installationId) ?? []), item]);
|
|
1103
|
+
}
|
|
1104
|
+
for (const items of activeByInstallation.values()) {
|
|
1105
|
+
if (items.length > 2 || items.length === 2 && !items.some(({ status }) => status === "REPLACEMENT_PENDING") || items.length === 2 && !items.some(({ source }) => source === "ACCOUNT_REPLACEMENT")) {
|
|
1106
|
+
context.addIssue({ code: "custom", message: "Installation has conflicting active bindings." });
|
|
1107
|
+
break;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
export const CodexV6AdminReplacementCandidateListResponseSchema = z.strictObject({
|
|
1112
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1113
|
+
items: z.array(z.strictObject({
|
|
1114
|
+
request: CodexV6AccountRequestSchema,
|
|
1115
|
+
binding: CodexV6DeviceBindingSchema,
|
|
1116
|
+
recommendedReason: z.enum([
|
|
1117
|
+
"SUBSCRIPTION_EXPIRING",
|
|
1118
|
+
"CREDENTIAL_UNHEALTHY",
|
|
1119
|
+
"ADMIN_REQUESTED"
|
|
1120
|
+
]),
|
|
1121
|
+
replaceBefore: CodexV3InstantSchema
|
|
1122
|
+
})).max(256),
|
|
1123
|
+
total: z.number().int().min(0).max(256)
|
|
1124
|
+
}).superRefine((value, context) => {
|
|
1125
|
+
if (value.items.length !== value.total || value.items.some(({ request, binding }) => binding.requestId !== request.id || binding.userSubject !== request.userSubject
|
|
1126
|
+
|| !["ACTIVE", "NEEDS_REAUTH"].includes(binding.status))) {
|
|
1127
|
+
context.addIssue({ code: "custom", message: "Replacement candidates are inconsistent." });
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
const CodexV6LegacyDeviceEvidenceSchema = z.strictObject({
|
|
1131
|
+
assignmentId: CodexV3IdSchema,
|
|
1132
|
+
managedAccountId: CodexV3IdSchema,
|
|
1133
|
+
providerAccountId: z.string().min(1).max(512),
|
|
1134
|
+
lineageId: CodexV3IdSchema,
|
|
1135
|
+
generationVersion: z.number().int().positive()
|
|
1136
|
+
});
|
|
1137
|
+
export const CodexV6ReconcileDeviceAccessInputSchema = z.strictObject({
|
|
1138
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1139
|
+
clientRequestId: CodexV3ClientRequestIdSchema,
|
|
1140
|
+
device: CodexV6DeviceDescriptorSchema,
|
|
1141
|
+
legacy: CodexV6LegacyDeviceEvidenceSchema.nullable()
|
|
1142
|
+
});
|
|
1143
|
+
export const CodexV6ReconcileDeviceAccessResponseSchema = z.strictObject({
|
|
1144
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1145
|
+
accessStatus: z.enum([
|
|
1146
|
+
"AVAILABLE",
|
|
1147
|
+
"REQUEST_REQUIRED",
|
|
1148
|
+
"REQUEST_PENDING",
|
|
1149
|
+
"DEVICE_BINDING_REQUIRED",
|
|
1150
|
+
"TOKEN_PENDING",
|
|
1151
|
+
"REQUEST_EXPIRED",
|
|
1152
|
+
"UNAVAILABLE"
|
|
1153
|
+
]),
|
|
1154
|
+
request: CodexV6AccountRequestSchema.nullable(),
|
|
1155
|
+
binding: CodexV6DeviceBindingSchema.nullable(),
|
|
1156
|
+
replacementBinding: CodexV6DeviceBindingSchema.nullable(),
|
|
1157
|
+
migration: z.enum([
|
|
1158
|
+
"NONE",
|
|
1159
|
+
"AUTO_MIGRATED",
|
|
1160
|
+
"ALREADY_MIGRATED",
|
|
1161
|
+
"ADDITIONAL_DEVICE_DETECTED"
|
|
1162
|
+
]),
|
|
1163
|
+
guidanceCode: z.enum([
|
|
1164
|
+
"account_request_required",
|
|
1165
|
+
"account_request_pending",
|
|
1166
|
+
"device_binding_admin_required",
|
|
1167
|
+
"device_token_pending",
|
|
1168
|
+
"account_request_expired",
|
|
1169
|
+
"account_unavailable"
|
|
1170
|
+
]).nullable(),
|
|
1171
|
+
replayed: z.boolean()
|
|
1172
|
+
}).superRefine((value, context) => {
|
|
1173
|
+
if (value.accessStatus === "AVAILABLE" && (value.request === null || value.binding === null
|
|
1174
|
+
|| !["READY", "ACTIVE", "REPLACEMENT_PENDING"].includes(value.binding.status))) {
|
|
1175
|
+
context.addIssue({ code: "custom", message: "Available device access lacks an active binding." });
|
|
1176
|
+
}
|
|
1177
|
+
if (value.accessStatus === "DEVICE_BINDING_REQUIRED"
|
|
1178
|
+
&& value.guidanceCode !== "device_binding_admin_required") {
|
|
1179
|
+
context.addIssue({ code: "custom", message: "Unbound devices must receive administrator guidance." });
|
|
1180
|
+
}
|
|
1181
|
+
if (value.replacementBinding !== null && (value.request === null || value.binding === null
|
|
1182
|
+
|| value.binding.status !== "REPLACEMENT_PENDING"
|
|
1183
|
+
|| value.replacementBinding.status !== "READY"
|
|
1184
|
+
|| value.replacementBinding.source !== "ACCOUNT_REPLACEMENT"
|
|
1185
|
+
|| value.replacementBinding.predecessorBindingId !== value.binding.id
|
|
1186
|
+
|| value.replacementBinding.requestId !== value.binding.requestId
|
|
1187
|
+
|| value.replacementBinding.userSubject !== value.binding.userSubject
|
|
1188
|
+
|| value.replacementBinding.installationId !== value.binding.installationId
|
|
1189
|
+
|| value.replacementBinding.credentialLineageId === value.binding.credentialLineageId
|
|
1190
|
+
|| value.replacementBinding.poolEntryId === value.binding.poolEntryId)) {
|
|
1191
|
+
context.addIssue({ code: "custom", message: "Ready replacement binding is inconsistent." });
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
export const CodexV6AdminCreateDeviceBindingInputSchema = z.strictObject({
|
|
1195
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1196
|
+
expectedRequestVersion: z.number().int().nonnegative(),
|
|
1197
|
+
device: CodexV6DeviceDescriptorSchema,
|
|
1198
|
+
poolEntryId: CodexV3IdSchema.nullable()
|
|
1199
|
+
});
|
|
1200
|
+
export const CodexV6AdminCreateDeviceBindingResponseSchema = z.strictObject({
|
|
1201
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1202
|
+
request: CodexV6AccountRequestSchema,
|
|
1203
|
+
binding: CodexV6DeviceBindingSchema,
|
|
1204
|
+
replayed: z.boolean()
|
|
1205
|
+
});
|
|
1206
|
+
export const CodexV6AdminReplaceDeviceTokenInputSchema = z.strictObject({
|
|
1207
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1208
|
+
expectedRequestVersion: z.number().int().nonnegative(),
|
|
1209
|
+
reason: z.enum([
|
|
1210
|
+
"SUBSCRIPTION_EXPIRING",
|
|
1211
|
+
"CREDENTIAL_UNHEALTHY",
|
|
1212
|
+
"ADMIN_REQUESTED"
|
|
1213
|
+
]),
|
|
1214
|
+
replaceBefore: CodexV3InstantSchema,
|
|
1215
|
+
poolEntryId: CodexV3IdSchema.nullable()
|
|
1216
|
+
});
|
|
1217
|
+
export const CodexV6AdminReplaceDeviceTokenResponseSchema = z.strictObject({
|
|
1218
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1219
|
+
request: CodexV6AccountRequestSchema,
|
|
1220
|
+
currentBinding: CodexV6DeviceBindingSchema,
|
|
1221
|
+
replacementBinding: CodexV6DeviceBindingSchema,
|
|
1222
|
+
replayed: z.boolean()
|
|
1223
|
+
}).superRefine((value, context) => {
|
|
1224
|
+
if (value.currentBinding.requestId !== value.request.id
|
|
1225
|
+
|| value.currentBinding.userSubject !== value.request.userSubject
|
|
1226
|
+
|| value.currentBinding.status !== "REPLACEMENT_PENDING"
|
|
1227
|
+
|| value.replacementBinding.requestId !== value.request.id
|
|
1228
|
+
|| value.replacementBinding.userSubject !== value.request.userSubject
|
|
1229
|
+
|| value.replacementBinding.source !== "ACCOUNT_REPLACEMENT"
|
|
1230
|
+
|| value.replacementBinding.predecessorBindingId !== value.currentBinding.id
|
|
1231
|
+
|| value.replacementBinding.installationId !== value.currentBinding.installationId
|
|
1232
|
+
|| value.replacementBinding.poolEntryId !== null
|
|
1233
|
+
&& value.replacementBinding.poolEntryId === value.currentBinding.poolEntryId
|
|
1234
|
+
|| value.replacementBinding.credentialLineageId !== null
|
|
1235
|
+
&& value.replacementBinding.credentialLineageId === value.currentBinding.credentialLineageId) {
|
|
1236
|
+
context.addIssue({ code: "custom", message: "Replacement response identities are inconsistent." });
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1239
|
+
export const CodexV6FullCredentialDeliveryInputSchema = z.strictObject({
|
|
1240
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1241
|
+
clientRequestId: CodexV3ClientRequestIdSchema,
|
|
1242
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1243
|
+
clientKey: CodexShortLivedDeliveryClientKeySchema
|
|
1244
|
+
});
|
|
1245
|
+
const CodexV6FullCredentialDeliveryMetadataSchema = z.strictObject({
|
|
1246
|
+
id: CodexV3IdSchema,
|
|
1247
|
+
clientRequestId: CodexV3ClientRequestIdSchema,
|
|
1248
|
+
requestId: CodexV3IdSchema,
|
|
1249
|
+
bindingId: CodexV3IdSchema,
|
|
1250
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1251
|
+
managedAccountId: CodexV3IdSchema,
|
|
1252
|
+
providerAccountId: z.string().min(1).max(512),
|
|
1253
|
+
credentialLineageId: CodexV3IdSchema,
|
|
1254
|
+
generationVersion: z.number().int().positive(),
|
|
1255
|
+
status: z.enum(["AWAITING_ACK", "ACKED", "EXPIRED"]),
|
|
1256
|
+
issuedAt: CodexV3InstantSchema,
|
|
1257
|
+
credentialExpiresAt: CodexV3InstantSchema,
|
|
1258
|
+
ackExpiresAt: CodexV3InstantSchema,
|
|
1259
|
+
ackedAt: CodexV3InstantSchema.nullable()
|
|
1260
|
+
});
|
|
1261
|
+
export const CodexV6FullCredentialDeliveryResponseSchema = z.strictObject({
|
|
1262
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1263
|
+
delivery: CodexV6FullCredentialDeliveryMetadataSchema.extend({
|
|
1264
|
+
status: z.literal("AWAITING_ACK"),
|
|
1265
|
+
envelope: CodexShortLivedDeliveryEnvelopeSchema
|
|
1266
|
+
}),
|
|
1267
|
+
replayed: z.boolean()
|
|
1268
|
+
});
|
|
1269
|
+
export const CodexV6FullCredentialBundleSchema = z.strictObject({
|
|
1270
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1271
|
+
deliveryId: CodexV3IdSchema,
|
|
1272
|
+
requestId: CodexV3IdSchema,
|
|
1273
|
+
bindingId: CodexV3IdSchema,
|
|
1274
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1275
|
+
managedAccountId: CodexV3IdSchema,
|
|
1276
|
+
providerAccountId: z.string().min(1).max(512),
|
|
1277
|
+
credentialLineageId: CodexV3IdSchema,
|
|
1278
|
+
generationVersion: z.number().int().positive(),
|
|
1279
|
+
refreshToken: z.string().min(1).max(65_536),
|
|
1280
|
+
accessToken: z.string().min(1).max(65_536),
|
|
1281
|
+
idToken: z.string().min(1).max(65_536),
|
|
1282
|
+
expiresAt: CodexV3InstantSchema
|
|
1283
|
+
});
|
|
1284
|
+
export const CodexV6AcknowledgeFullCredentialDeliveryInputSchema = z.strictObject({
|
|
1285
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1286
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1287
|
+
credentialLineageId: CodexV3IdSchema,
|
|
1288
|
+
generationVersion: z.number().int().positive(),
|
|
1289
|
+
installed: z.literal(true)
|
|
1290
|
+
});
|
|
1291
|
+
export const CodexV6AcknowledgeFullCredentialDeliveryResponseSchema = z.strictObject({
|
|
1292
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1293
|
+
delivery: CodexV6FullCredentialDeliveryMetadataSchema.extend({
|
|
1294
|
+
status: z.literal("ACKED"),
|
|
1295
|
+
ackedAt: CodexV3InstantSchema
|
|
1296
|
+
}),
|
|
1297
|
+
replayed: z.boolean()
|
|
1298
|
+
});
|
|
1299
|
+
export const CodexV6GenerationReportInputSchema = z.strictObject({
|
|
1300
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1301
|
+
clientRequestId: CodexV3ClientRequestIdSchema,
|
|
1302
|
+
bindingId: CodexV3IdSchema,
|
|
1303
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1304
|
+
expectedGenerationVersion: z.number().int().positive(),
|
|
1305
|
+
rotationMode: z.enum(["ROTATED", "RETAINED"]),
|
|
1306
|
+
envelope: CodexV3CredentialEnvelopeSchema,
|
|
1307
|
+
accessTokenHealth: CodexV3AccessTokenHealthSchema,
|
|
1308
|
+
refreshTokenHealth: CodexV3RefreshTokenHealthSchema,
|
|
1309
|
+
observedAt: CodexV3InstantSchema
|
|
1310
|
+
});
|
|
1311
|
+
export const CodexV6GenerationReportResponseSchema = z.strictObject({
|
|
1312
|
+
schemaVersion: z.literal(CODEX_REQUEST_BOUND_DEVICE_V6_SCHEMA_VERSION),
|
|
1313
|
+
report: z.strictObject({
|
|
1314
|
+
id: CodexV3IdSchema,
|
|
1315
|
+
clientRequestId: CodexV3ClientRequestIdSchema,
|
|
1316
|
+
requestId: CodexV3IdSchema,
|
|
1317
|
+
bindingId: CodexV3IdSchema,
|
|
1318
|
+
installationId: CodexV5InstallationIdSchema,
|
|
1319
|
+
credentialLineageId: CodexV3IdSchema,
|
|
1320
|
+
previousGenerationVersion: z.number().int().positive(),
|
|
1321
|
+
generationVersion: z.number().int().positive(),
|
|
1322
|
+
rotationMode: z.enum(["ROTATED", "RETAINED"]),
|
|
1323
|
+
accessTokenHealth: CodexV3AccessTokenHealthSchema,
|
|
1324
|
+
refreshTokenHealth: CodexV3RefreshTokenHealthSchema,
|
|
1325
|
+
credentialExpiresAt: CodexV3InstantSchema,
|
|
1326
|
+
observedAt: CodexV3InstantSchema,
|
|
1327
|
+
status: z.literal("APPLIED")
|
|
1328
|
+
}),
|
|
1329
|
+
replayed: z.boolean()
|
|
1330
|
+
}).superRefine((value, context) => {
|
|
1331
|
+
if (value.report.generationVersion !== value.report.previousGenerationVersion + 1) {
|
|
1332
|
+
context.addIssue({ code: "custom", path: ["report", "generationVersion"],
|
|
1333
|
+
message: "Generation did not advance exactly once." });
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
898
1336
|
export const CodexV4AccessObservationStateSchema = z.enum([
|
|
899
1337
|
"VALID", "EXPIRING", "EXPIRED", "INVALID"
|
|
900
1338
|
]);
|
|
@@ -1085,6 +1523,62 @@ export function codexV5DeviceSessionActionPath(sessionId, action) {
|
|
|
1085
1523
|
export function codexV5LineageGenerationReportsPath(lineageId) {
|
|
1086
1524
|
return `${CODEX_MULTI_DEVICE_V5_CREDENTIAL_LINEAGES_PATH}/${encodeURIComponent(lineageId)}/generations/report`;
|
|
1087
1525
|
}
|
|
1526
|
+
export function codexV6AccountRequestPath(requestId) {
|
|
1527
|
+
return `${CODEX_V6_ACCOUNT_REQUESTS_PATH}/${encodeURIComponent(requestId)}`;
|
|
1528
|
+
}
|
|
1529
|
+
export function codexV6AccountRequestActionPath(requestId, action) {
|
|
1530
|
+
return `${codexV6AccountRequestPath(requestId)}/${action}`;
|
|
1531
|
+
}
|
|
1532
|
+
export function codexV6AccountRequestDeviceBindingsPath(requestId) {
|
|
1533
|
+
return `${codexV6AccountRequestPath(requestId)}/device-bindings`;
|
|
1534
|
+
}
|
|
1535
|
+
export function codexV6AdminAccountRequestDeviceBindingsPath(requestId) {
|
|
1536
|
+
return `${CODEX_V6_ADMIN_ACCOUNT_REQUESTS_PATH}/${encodeURIComponent(requestId)}/device-bindings`;
|
|
1537
|
+
}
|
|
1538
|
+
export function codexV6AdminDeviceBindingReplacementPath(requestId, bindingId) {
|
|
1539
|
+
return `${codexV6AdminAccountRequestDeviceBindingsPath(requestId)}/`
|
|
1540
|
+
+ `${encodeURIComponent(bindingId)}/replacement`;
|
|
1541
|
+
}
|
|
1542
|
+
export function codexV6AdminAccountRequestPath(requestId) {
|
|
1543
|
+
return `${CODEX_V6_ADMIN_ACCOUNT_REQUESTS_PATH}/${encodeURIComponent(requestId)}`;
|
|
1544
|
+
}
|
|
1545
|
+
export function codexV6AdminAccountRequestsPath(query = {}) {
|
|
1546
|
+
const parsed = CodexV6AdminAccountRequestListQuerySchema.parse(query);
|
|
1547
|
+
const parameters = new URLSearchParams();
|
|
1548
|
+
if (parsed.expiresBefore)
|
|
1549
|
+
parameters.set("expiresBefore", parsed.expiresBefore);
|
|
1550
|
+
if (parsed.includeTerminal !== undefined) {
|
|
1551
|
+
parameters.set("includeTerminal", String(parsed.includeTerminal));
|
|
1552
|
+
}
|
|
1553
|
+
const suffix = parameters.toString();
|
|
1554
|
+
return `${CODEX_V6_ADMIN_ACCOUNT_REQUESTS_PATH}${suffix ? `?${suffix}` : ""}`;
|
|
1555
|
+
}
|
|
1556
|
+
export function codexV6AdminReplacementCandidatesPath(query) {
|
|
1557
|
+
const parsed = CodexV6AdminReplacementCandidateQuerySchema.parse(query);
|
|
1558
|
+
return `${CODEX_V6_ADMIN_DEVICE_BINDINGS_PATH}/replacement-candidates`
|
|
1559
|
+
+ `?replaceBefore=${encodeURIComponent(parsed.replaceBefore)}`;
|
|
1560
|
+
}
|
|
1561
|
+
export function codexV6AdminAccountRequestReviewPath(requestId) {
|
|
1562
|
+
return `${codexV6AdminAccountRequestPath(requestId)}/review`;
|
|
1563
|
+
}
|
|
1564
|
+
export function codexV6DeviceBindingFullCredentialDeliveriesPath(bindingId) {
|
|
1565
|
+
return `${CODEX_V6_DEVICE_BINDINGS_PATH}/${encodeURIComponent(bindingId)}/full-credential-deliveries`;
|
|
1566
|
+
}
|
|
1567
|
+
export function codexV6DeviceBindingFullCredentialDeliveryResolvePath(bindingId, clientRequestId) {
|
|
1568
|
+
return `${codexV6DeviceBindingFullCredentialDeliveriesPath(bindingId)}`
|
|
1569
|
+
+ `/resolve?clientRequestId=${encodeURIComponent(clientRequestId)}`;
|
|
1570
|
+
}
|
|
1571
|
+
export function codexV6FullCredentialDeliveryAckPath(deliveryId) {
|
|
1572
|
+
return `${CODEX_REQUEST_BOUND_DEVICE_V6_RUNTIME_PATH}/full-credential-deliveries/`
|
|
1573
|
+
+ `${encodeURIComponent(deliveryId)}/ack`;
|
|
1574
|
+
}
|
|
1575
|
+
export function codexV6BindingGenerationReportsPath(bindingId) {
|
|
1576
|
+
return `${CODEX_V6_DEVICE_BINDINGS_PATH}/${encodeURIComponent(bindingId)}/generations/report`;
|
|
1577
|
+
}
|
|
1578
|
+
export function codexV6BindingGenerationReportResolvePath(bindingId, clientRequestId) {
|
|
1579
|
+
return `${CODEX_V6_DEVICE_BINDINGS_PATH}/${encodeURIComponent(bindingId)}`
|
|
1580
|
+
+ `/generations/resolve?clientRequestId=${encodeURIComponent(clientRequestId)}`;
|
|
1581
|
+
}
|
|
1088
1582
|
export function codexTokenPoolV4DirectoryResolvePath(principal) {
|
|
1089
1583
|
return `${CODEX_TOKEN_POOL_V4_DIRECTORY_RESOLVE_PATH}?principal=${encodeURIComponent(principal)}`;
|
|
1090
1584
|
}
|