@modelprofile.com/authswitch 7.0.0 → 8.1.0
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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/authority-contract.d.ts +1 -3
- package/dist_ts/authority-contract.js +1 -1
- package/dist_ts/authority-import-contract.d.ts +207 -0
- package/dist_ts/authority-import-contract.js +18 -0
- package/dist_ts/classes.authoritybroker.js +1 -5
- package/dist_ts/classes.authoritycli.d.ts +4 -0
- package/dist_ts/classes.authoritycli.js +149 -12
- package/dist_ts/classes.authorityclient.d.ts +7 -0
- package/dist_ts/classes.authorityclient.js +13 -1
- package/dist_ts/classes.authoritydaemon.d.ts +4 -0
- package/dist_ts/classes.authoritydaemon.js +75 -9
- package/dist_ts/classes.authoritydatabase.d.ts +10 -26
- package/dist_ts/classes.authoritydatabase.js +68 -133
- package/dist_ts/classes.authorityimport.d.ts +161 -0
- package/dist_ts/classes.authorityimport.js +638 -0
- package/dist_ts/classes.authoritymodels.d.ts +39 -43
- package/dist_ts/classes.authoritymodels.js +209 -243
- package/dist_ts/classes.authoritypreuse.js +1 -2
- package/dist_ts/classes.authorityregistry.d.ts +2 -17
- package/dist_ts/classes.authorityregistry.js +18 -74
- package/dist_ts/classes.authoritysecrets.d.ts +1 -1
- package/dist_ts/classes.authoritysecrets.js +2 -2
- package/dist_ts/classes.authorityusage.d.ts +3 -3
- package/dist_ts/classes.claudeauthority.js +3 -7
- package/dist_ts/classes.claudenative.d.ts +1 -8
- package/dist_ts/classes.claudenative.js +2 -25
- package/dist_ts/classes.codexmanaged.d.ts +1 -1
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +6 -3
- package/dist_ts/plugins.d.ts +7 -7
- package/dist_ts/plugins.js +8 -8
- package/dist_ts/ts_migration/0001_authority_meta.d.ts +13 -3
- package/dist_ts/ts_migration/0001_authority_meta.js +29 -17
- package/dist_ts/ts_migration/0002_remove_backup_records.d.ts +17 -0
- package/dist_ts/ts_migration/0002_remove_backup_records.js +48 -0
- package/dist_ts/ts_migration/index.d.ts +6 -3
- package/dist_ts/ts_migration/index.js +10 -4
- package/dist_ts/ts_migration/legacysources/authswitchstores.d.ts +2 -0
- package/dist_ts/ts_migration/legacysources/authswitchstores.js +244 -0
- package/dist_ts/ts_migration/legacysources/index.d.ts +18 -0
- package/dist_ts/ts_migration/legacysources/index.js +24 -0
- package/dist_ts/ts_migration/legacysources/material.d.ts +37 -0
- package/dist_ts/ts_migration/legacysources/material.js +120 -0
- package/dist_ts/ts_migration/legacysources/nativestores.d.ts +2 -0
- package/dist_ts/ts_migration/legacysources/nativestores.js +207 -0
- package/dist_ts/ts_migration/legacysources/shared.d.ts +124 -0
- package/dist_ts/ts_migration/legacysources/shared.js +142 -0
- package/package.json +6 -5
- package/readme.md +68 -26
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/authority-contract.ts +1 -3
- package/ts/authority-import-contract.ts +216 -0
- package/ts/classes.authoritybroker.ts +0 -4
- package/ts/classes.authoritycli.ts +165 -11
- package/ts/classes.authorityclient.ts +22 -0
- package/ts/classes.authoritydaemon.ts +75 -8
- package/ts/classes.authoritydatabase.ts +70 -145
- package/ts/classes.authorityimport.ts +718 -0
- package/ts/classes.authoritymodels.ts +253 -269
- package/ts/classes.authoritypreuse.ts +0 -1
- package/ts/classes.authorityregistry.ts +20 -91
- package/ts/classes.authoritysecrets.ts +1 -1
- package/ts/classes.authorityusage.ts +3 -3
- package/ts/classes.claudeauthority.ts +2 -6
- package/ts/classes.claudenative.ts +1 -32
- package/ts/classes.codexmanaged.ts +1 -1
- package/ts/index.ts +5 -2
- package/ts/plugins.ts +7 -7
- package/ts/ts_migration/0001_authority_meta.ts +29 -17
- package/ts/ts_migration/0002_remove_backup_records.ts +49 -0
- package/ts/ts_migration/index.ts +10 -5
- package/ts/ts_migration/legacysources/authswitchstores.ts +211 -0
- package/ts/ts_migration/legacysources/index.ts +35 -0
- package/ts/ts_migration/legacysources/material.ts +134 -0
- package/ts/ts_migration/legacysources/nativestores.ts +204 -0
- package/ts/ts_migration/legacysources/shared.ts +220 -0
- package/dist_ts/authorityrehearsal.child.d.ts +0 -1
- package/dist_ts/authorityrehearsal.child.js +0 -395
- package/dist_ts/classes.authoritybackup.d.ts +0 -134
- package/dist_ts/classes.authoritybackup.js +0 -769
- package/dist_ts/classes.authorityrehearsal.d.ts +0 -127
- package/dist_ts/classes.authorityrehearsal.js +0 -632
- package/ts/authorityrehearsal.child.ts +0 -330
- package/ts/classes.authoritybackup.ts +0 -780
- package/ts/classes.authorityrehearsal.ts +0 -625
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { accessTokenExpiry, claudeSourceIdentity, legacyHash, legacySourceDigest, legacySourceId, openAiSourceIdentity, openCodeOpenAiIdentity, parseLegacyJson, readLegacyFile } from './shared.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reads authswitch's own legacy stores: the Codex stash directories of `StashStore` and the saved records of
|
|
5
|
+
* `CredentialStore`.
|
|
6
|
+
*
|
|
7
|
+
* Both are copies authswitch made for itself. No other tool refreshes them, so the authority can become
|
|
8
|
+
* their owner outright -- unlike a native store, where the vendor tool keeps refreshing.
|
|
9
|
+
*
|
|
10
|
+
* `StashStore.list()` skips an incomplete directory and `CredentialStore.list()` throws on a malformed
|
|
11
|
+
* record; neither behaviour is acceptable here, because a source the owner cannot see is a source the
|
|
12
|
+
* cutover would delete unexamined. Every directory and every record is reported, with its defect.
|
|
13
|
+
*/
|
|
14
|
+
const STASH_AUTH_FILE = 'auth.json';
|
|
15
|
+
const STASH_META_FILE = 'stash.json';
|
|
16
|
+
/** The harness namespaces authswitch itself wrote, and the store layout each one uses. */
|
|
17
|
+
const STASH_HARNESSES = ['codex'];
|
|
18
|
+
const RECORD_HARNESSES = ['claude', 'opencode'];
|
|
19
|
+
const RECORD_FILE = /^[a-f0-9]{64}\.json$/;
|
|
20
|
+
const baseRecord = (path, files) => {
|
|
21
|
+
const sourcePathHash = legacyHash(path);
|
|
22
|
+
return {
|
|
23
|
+
id: legacySourceId('authswitch_stash', sourcePathHash),
|
|
24
|
+
sourceKind: 'authswitch_stash',
|
|
25
|
+
path,
|
|
26
|
+
sourcePathHash,
|
|
27
|
+
sourceDigest: legacySourceDigest(files),
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/** One `~/.authswitch/codex/<slug>` directory: a Codex credential plus the enrollments saved with it. */
|
|
31
|
+
const readStashDirectory = (path) => {
|
|
32
|
+
const problems = [];
|
|
33
|
+
const files = [];
|
|
34
|
+
for (const name of [STASH_AUTH_FILE, STASH_META_FILE]) {
|
|
35
|
+
const read = readLegacyFile(plugins.path.join(path, name), name);
|
|
36
|
+
if (read.problem)
|
|
37
|
+
problems.push(read.problem);
|
|
38
|
+
else if (read.file === null)
|
|
39
|
+
problems.push(`${name} is missing`);
|
|
40
|
+
else
|
|
41
|
+
files.push(read.file);
|
|
42
|
+
}
|
|
43
|
+
const record = {
|
|
44
|
+
...baseRecord(path, files),
|
|
45
|
+
treatment: 'refuse',
|
|
46
|
+
proof: 'none',
|
|
47
|
+
accountId: null,
|
|
48
|
+
subject: null,
|
|
49
|
+
workspaceId: null,
|
|
50
|
+
providerId: null,
|
|
51
|
+
email: null,
|
|
52
|
+
plan: null,
|
|
53
|
+
label: null,
|
|
54
|
+
accessExpiresAt: null,
|
|
55
|
+
enrollmentCount: null,
|
|
56
|
+
problems,
|
|
57
|
+
};
|
|
58
|
+
const auth = files.find(file => file.name === STASH_AUTH_FILE);
|
|
59
|
+
const meta = files.find(file => file.name === STASH_META_FILE);
|
|
60
|
+
if (meta) {
|
|
61
|
+
const parsed = parseLegacyJson(meta.raw);
|
|
62
|
+
if (!parsed)
|
|
63
|
+
problems.push(`${STASH_META_FILE} is not a JSON object`);
|
|
64
|
+
else {
|
|
65
|
+
record.label = typeof parsed.email === 'string' ? parsed.email : null;
|
|
66
|
+
record.enrollmentCount = Array.isArray(parsed.enrollments) ? parsed.enrollments.length : null;
|
|
67
|
+
if (record.enrollmentCount === null)
|
|
68
|
+
problems.push(`${STASH_META_FILE} carries no enrollment list`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!auth)
|
|
72
|
+
return record;
|
|
73
|
+
const parsed = parseLegacyJson(auth.raw);
|
|
74
|
+
const tokens = parsed?.tokens;
|
|
75
|
+
const tokenRecord = tokens && typeof tokens === 'object' && !Array.isArray(tokens)
|
|
76
|
+
? tokens : null;
|
|
77
|
+
const idToken = typeof tokenRecord?.id_token === 'string' ? tokenRecord.id_token : null;
|
|
78
|
+
const refreshToken = typeof tokenRecord?.refresh_token === 'string' ? tokenRecord.refresh_token : null;
|
|
79
|
+
const identity = idToken === null ? null : openAiSourceIdentity(idToken);
|
|
80
|
+
if (identity === null) {
|
|
81
|
+
// An API-key credential is a stash authswitch can restore but not an OAuth grant the authority can hold.
|
|
82
|
+
problems.push('the saved credential carries no ChatGPT identity the authority can hold');
|
|
83
|
+
return record;
|
|
84
|
+
}
|
|
85
|
+
record.providerId = 'openai';
|
|
86
|
+
record.accountId = identity.accountId;
|
|
87
|
+
record.subject = identity.subject;
|
|
88
|
+
record.workspaceId = identity.workspaceId;
|
|
89
|
+
record.email = identity.email;
|
|
90
|
+
record.plan = identity.plan;
|
|
91
|
+
record.label = record.label ?? identity.email;
|
|
92
|
+
record.accessExpiresAt = accessTokenExpiry(typeof tokenRecord?.access_token === 'string' ? tokenRecord.access_token : null);
|
|
93
|
+
if (refreshToken === null)
|
|
94
|
+
problems.push('the saved credential carries no refresh token');
|
|
95
|
+
else if (problems.length === 0) {
|
|
96
|
+
record.treatment = 'import';
|
|
97
|
+
record.proof = 'rotating_refresh';
|
|
98
|
+
}
|
|
99
|
+
return record;
|
|
100
|
+
};
|
|
101
|
+
/** One `~/.authswitch/<harness>/<id>.json` record, validated as `CredentialStore.read` validates it. */
|
|
102
|
+
const readCredentialRecord = (harness, path, id) => {
|
|
103
|
+
const problems = [];
|
|
104
|
+
const files = [];
|
|
105
|
+
const read = readLegacyFile(path, `${id}.json`);
|
|
106
|
+
if (read.problem)
|
|
107
|
+
problems.push(read.problem);
|
|
108
|
+
else if (read.file === null)
|
|
109
|
+
problems.push('the record disappeared while it was being read');
|
|
110
|
+
else
|
|
111
|
+
files.push(read.file);
|
|
112
|
+
const record = {
|
|
113
|
+
...baseRecord(path, files),
|
|
114
|
+
treatment: 'refuse',
|
|
115
|
+
proof: 'none',
|
|
116
|
+
accountId: null,
|
|
117
|
+
subject: null,
|
|
118
|
+
workspaceId: null,
|
|
119
|
+
providerId: null,
|
|
120
|
+
email: null,
|
|
121
|
+
plan: null,
|
|
122
|
+
label: null,
|
|
123
|
+
accessExpiresAt: null,
|
|
124
|
+
enrollmentCount: null,
|
|
125
|
+
problems,
|
|
126
|
+
};
|
|
127
|
+
const file = files[0];
|
|
128
|
+
if (!file)
|
|
129
|
+
return record;
|
|
130
|
+
const parsed = parseLegacyJson(file.raw);
|
|
131
|
+
if (!parsed || parsed.schemaVersion !== 1 || parsed.id !== id || typeof parsed.slotId !== 'string'
|
|
132
|
+
|| typeof parsed.label !== 'string' || !parsed.credential || typeof parsed.credential !== 'object'
|
|
133
|
+
|| Array.isArray(parsed.credential)) {
|
|
134
|
+
problems.push('the saved record does not match the credential-store schema');
|
|
135
|
+
return record;
|
|
136
|
+
}
|
|
137
|
+
const credential = parsed.credential;
|
|
138
|
+
record.label = parsed.label;
|
|
139
|
+
if (harness === 'claude') {
|
|
140
|
+
const identity = claudeSourceIdentity(credential);
|
|
141
|
+
if (identity === null)
|
|
142
|
+
problems.push('the saved Claude login or its account metadata is incomplete');
|
|
143
|
+
else {
|
|
144
|
+
record.providerId = 'anthropic';
|
|
145
|
+
record.accountId = identity.accountId;
|
|
146
|
+
record.subject = identity.subject;
|
|
147
|
+
record.workspaceId = identity.workspaceId;
|
|
148
|
+
record.email = identity.email;
|
|
149
|
+
record.accessExpiresAt = identity.accessExpiresAt;
|
|
150
|
+
if (typeof credential.claudeAiOauth === 'object' && credential.claudeAiOauth !== null
|
|
151
|
+
&& typeof credential.claudeAiOauth.refreshToken !== 'string') {
|
|
152
|
+
problems.push('the saved Claude login carries no refresh token');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (parsed.slotId === 'openai') {
|
|
157
|
+
const { identity, accessExpiresAt } = openCodeOpenAiIdentity(credential);
|
|
158
|
+
record.accessExpiresAt = accessExpiresAt;
|
|
159
|
+
if (identity === null)
|
|
160
|
+
problems.push('the saved OpenAI login carries no identity the authority can hold');
|
|
161
|
+
else {
|
|
162
|
+
record.providerId = 'openai';
|
|
163
|
+
record.accountId = identity.accountId;
|
|
164
|
+
record.subject = identity.subject;
|
|
165
|
+
record.workspaceId = identity.workspaceId;
|
|
166
|
+
record.email = identity.email;
|
|
167
|
+
record.plan = identity.plan;
|
|
168
|
+
}
|
|
169
|
+
if (typeof credential.refresh !== 'string')
|
|
170
|
+
problems.push('the saved login carries no refresh token');
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// API keys and other provider entries are credentials, but not grants the authority model can express.
|
|
174
|
+
problems.push(`provider ${parsed.slotId} is not a login the authority can hold`);
|
|
175
|
+
}
|
|
176
|
+
if (problems.length === 0) {
|
|
177
|
+
record.treatment = 'import';
|
|
178
|
+
record.proof = 'rotating_refresh';
|
|
179
|
+
}
|
|
180
|
+
return record;
|
|
181
|
+
};
|
|
182
|
+
export const readAuthSwitchStores = (locations) => {
|
|
183
|
+
const sources = [];
|
|
184
|
+
const problems = [];
|
|
185
|
+
let entries;
|
|
186
|
+
try {
|
|
187
|
+
entries = plugins.fs.readdirSync(locations.authSwitchHome, { withFileTypes: true });
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
if (error.code === 'ENOENT')
|
|
191
|
+
return { sources, problems };
|
|
192
|
+
return { sources, problems: [`${locations.authSwitchHome} could not be listed`] };
|
|
193
|
+
}
|
|
194
|
+
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
195
|
+
const path = plugins.path.join(locations.authSwitchHome, entry.name);
|
|
196
|
+
if (!entry.isDirectory()) {
|
|
197
|
+
problems.push(`${entry.name} is not a harness directory`);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (STASH_HARNESSES.includes(entry.name)) {
|
|
201
|
+
let stashes;
|
|
202
|
+
try {
|
|
203
|
+
stashes = plugins.fs.readdirSync(path, { withFileTypes: true });
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
problems.push(`${entry.name} could not be listed`);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
for (const stash of stashes.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
210
|
+
if (!stash.isDirectory()) {
|
|
211
|
+
problems.push(`${entry.name}/${stash.name} is not a stash`);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
sources.push(readStashDirectory(plugins.path.join(path, stash.name)));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (RECORD_HARNESSES.includes(entry.name)) {
|
|
218
|
+
let records;
|
|
219
|
+
try {
|
|
220
|
+
records = plugins.fs.readdirSync(path, { withFileTypes: true });
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
problems.push(`${entry.name} could not be listed`);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
for (const item of records.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
227
|
+
// switches.json is authswitch's advisory record of the last switch, not a credential source.
|
|
228
|
+
if (item.name === 'switches.json' || item.name === '.lock')
|
|
229
|
+
continue;
|
|
230
|
+
if (!item.isFile() || !RECORD_FILE.test(item.name)) {
|
|
231
|
+
problems.push(`${entry.name}/${item.name} is not a saved account record`);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
sources.push(readCredentialRecord(entry.name, plugins.path.join(path, item.name), item.name.slice(0, -5)));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// Guessing a store layout would be the one way this migration could lose an account silently.
|
|
239
|
+
problems.push(`${entry.name} uses no legacy store layout this import knows`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return { sources, problems };
|
|
243
|
+
};
|
|
244
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aHN3aXRjaHN0b3Jlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3RzX21pZ3JhdGlvbi9sZWdhY3lzb3VyY2VzL2F1dGhzd2l0Y2hzdG9yZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFDOUYsb0JBQW9CLEVBQUUsc0JBQXNCLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFFbkQsTUFBTSxhQUFhLENBQUM7QUFFaEQ7Ozs7Ozs7Ozs7R0FVRztBQUVILE1BQU0sZUFBZSxHQUFHLFdBQVcsQ0FBQztBQUNwQyxNQUFNLGVBQWUsR0FBRyxZQUFZLENBQUM7QUFDckMsMEZBQTBGO0FBQzFGLE1BQU0sZUFBZSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDbEMsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUNoRCxNQUFNLFdBQVcsR0FBRyxzQkFBc0IsQ0FBQztBQUUzQyxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxLQUFtQyxFQUNILEVBQUU7SUFDbEUsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLE9BQU87UUFDTCxFQUFFLEVBQUUsY0FBYyxDQUFDLGtCQUFrQixFQUFFLGNBQWMsQ0FBQztRQUN0RCxVQUFVLEVBQUUsa0JBQWtCO1FBQzlCLElBQUk7UUFDSixjQUFjO1FBQ2QsWUFBWSxFQUFFLGtCQUFrQixDQUFDLEtBQUssQ0FBQztLQUN4QyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUYseUdBQXlHO0FBQ3pHLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxJQUFZLEVBQXVCLEVBQUU7SUFDL0QsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBQzlC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
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ILegacySourceReport } from './shared.js';
|
|
2
|
+
export { resolveLegacySourceLocations } from './shared.js';
|
|
3
|
+
export type { ILegacySourceLocations, ILegacySourceRecord, ILegacySourceReport } from './shared.js';
|
|
4
|
+
export { LegacySourceChangedError, readLegacySourceEnrollments, readLegacySourceMaterial } from './material.js';
|
|
5
|
+
export type { TLegacySourceMaterial } from './material.js';
|
|
6
|
+
export interface ILegacySourceOptions {
|
|
7
|
+
env: NodeJS.ProcessEnv;
|
|
8
|
+
homeDirectory: string;
|
|
9
|
+
now: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Every legacy credential source this host holds, read and never changed.
|
|
13
|
+
*
|
|
14
|
+
* One function so that the import and the inventory always see the same list: a submit re-runs this read to
|
|
15
|
+
* resolve a source's location from its hash and to re-check its digest, and a discrepancy between what the
|
|
16
|
+
* owner approved and what is imported would defeat the point of approving anything.
|
|
17
|
+
*/
|
|
18
|
+
export declare const readLegacySources: (options: ILegacySourceOptions) => ILegacySourceReport;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readAuthSwitchStores } from './authswitchstores.js';
|
|
2
|
+
import { readNativeStores } from './nativestores.js';
|
|
3
|
+
import { resolveLegacySourceLocations } from './shared.js';
|
|
4
|
+
export { resolveLegacySourceLocations } from './shared.js';
|
|
5
|
+
export { LegacySourceChangedError, readLegacySourceEnrollments, readLegacySourceMaterial } from './material.js';
|
|
6
|
+
/**
|
|
7
|
+
* Every legacy credential source this host holds, read and never changed.
|
|
8
|
+
*
|
|
9
|
+
* One function so that the import and the inventory always see the same list: a submit re-runs this read to
|
|
10
|
+
* resolve a source's location from its hash and to re-check its digest, and a discrepancy between what the
|
|
11
|
+
* owner approved and what is imported would defeat the point of approving anything.
|
|
12
|
+
*/
|
|
13
|
+
export const readLegacySources = (options) => {
|
|
14
|
+
const locations = resolveLegacySourceLocations(options.env, options.homeDirectory);
|
|
15
|
+
const reports = [readAuthSwitchStores(locations), readNativeStores(locations, options.now)];
|
|
16
|
+
const sources = [];
|
|
17
|
+
const problems = [];
|
|
18
|
+
for (const report of reports) {
|
|
19
|
+
sources.push(...report.sources);
|
|
20
|
+
problems.push(...report.problems);
|
|
21
|
+
}
|
|
22
|
+
return { sources, problems };
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy90c19taWdyYXRpb24vbGVnYWN5c291cmNlcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsNEJBQTRCLEVBQ1QsTUFBTSxhQUFhLENBQUM7QUFFaEQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTNELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSwyQkFBMkIsRUFDNUQsd0JBQXdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFTbEQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxPQUE2QixFQUF1QixFQUFFO0lBQ3RGLE1BQU0sU0FBUyxHQUFHLDRCQUE0QixDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ25GLE1BQU0sT0FBTyxHQUFHLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzVGLE1BQU0sT0FBTyxHQUEwQixFQUFFLENBQUM7SUFDMUMsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBQzlCLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQy9CLENBQUMsQ0FBQyJ9
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ILegacySourceRecord } from './shared.js';
|
|
2
|
+
/**
|
|
3
|
+
* Re-opens the credential of one source, inside the daemon, from the location its hash stands for.
|
|
4
|
+
*
|
|
5
|
+
* Nothing carries this material over a socket: a caller names a source by id and digest, and the daemon reads
|
|
6
|
+
* the bytes itself. The digest is re-checked here, so a source that changed between the owner's approval and
|
|
7
|
+
* the import is refused rather than imported unseen.
|
|
8
|
+
*/
|
|
9
|
+
/** Exactly the envelope the authority already seals for each provider, so no new stored shape appears. */
|
|
10
|
+
export type TLegacySourceMaterial = {
|
|
11
|
+
providerId: 'openai';
|
|
12
|
+
credential: {
|
|
13
|
+
kind: 'chatgptOAuth';
|
|
14
|
+
providerId: 'openai';
|
|
15
|
+
accessToken: string;
|
|
16
|
+
refreshToken: string;
|
|
17
|
+
idToken: string;
|
|
18
|
+
};
|
|
19
|
+
} | {
|
|
20
|
+
providerId: 'anthropic';
|
|
21
|
+
login: {
|
|
22
|
+
claudeAiOauth: Record<string, unknown>;
|
|
23
|
+
oauthAccount: Record<string, unknown>;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export declare class LegacySourceChangedError extends Error {
|
|
27
|
+
constructor();
|
|
28
|
+
}
|
|
29
|
+
/** Reads the source named by `record`, proves it is still the inventoried source, and returns its envelope. */
|
|
30
|
+
export declare const readLegacySourceMaterial: (record: ILegacySourceRecord) => TLegacySourceMaterial;
|
|
31
|
+
/**
|
|
32
|
+
* The remote-control enrollments a Codex stash saved beside its credential.
|
|
33
|
+
*
|
|
34
|
+
* They are separate from the refresh grant and are the pairing between this machine's Codex app-server and a
|
|
35
|
+
* ChatGPT client: a migration that dropped them would silently unpair the account.
|
|
36
|
+
*/
|
|
37
|
+
export declare const readLegacySourceEnrollments: (record: ILegacySourceRecord) => Record<string, unknown>[];
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { legacySourceDigest, parseLegacyJson, readLegacyFile } from './shared.js';
|
|
3
|
+
export class LegacySourceChangedError extends Error {
|
|
4
|
+
constructor() { super('The source changed after it was inventoried; no credential was read.'); }
|
|
5
|
+
}
|
|
6
|
+
const files = (record, names, base) => {
|
|
7
|
+
const read = [];
|
|
8
|
+
for (const name of names) {
|
|
9
|
+
const item = readLegacyFile(plugins.path.join(base, name), name);
|
|
10
|
+
if (item.file === null)
|
|
11
|
+
throw new LegacySourceChangedError();
|
|
12
|
+
read.push(item.file);
|
|
13
|
+
}
|
|
14
|
+
return read;
|
|
15
|
+
};
|
|
16
|
+
const openAiFromTokens = (tokens) => {
|
|
17
|
+
if (!tokens || typeof tokens !== 'object' || Array.isArray(tokens))
|
|
18
|
+
return null;
|
|
19
|
+
const record = tokens;
|
|
20
|
+
const accessToken = record.access_token;
|
|
21
|
+
const refreshToken = record.refresh_token;
|
|
22
|
+
const idToken = record.id_token;
|
|
23
|
+
if (typeof accessToken !== 'string' || typeof refreshToken !== 'string'
|
|
24
|
+
|| typeof idToken !== 'string')
|
|
25
|
+
return null;
|
|
26
|
+
return { providerId: 'openai',
|
|
27
|
+
credential: { kind: 'chatgptOAuth', providerId: 'openai', accessToken, refreshToken, idToken } };
|
|
28
|
+
};
|
|
29
|
+
const claudeFromComposite = (credential) => {
|
|
30
|
+
const oauth = credential.claudeAiOauth;
|
|
31
|
+
const account = credential.oauthAccount;
|
|
32
|
+
if (!oauth || typeof oauth !== 'object' || Array.isArray(oauth)
|
|
33
|
+
|| !account || typeof account !== 'object' || Array.isArray(account))
|
|
34
|
+
return null;
|
|
35
|
+
return { providerId: 'anthropic',
|
|
36
|
+
login: { claudeAiOauth: oauth,
|
|
37
|
+
oauthAccount: account } };
|
|
38
|
+
};
|
|
39
|
+
/** Reads the source named by `record`, proves it is still the inventoried source, and returns its envelope. */
|
|
40
|
+
export const readLegacySourceMaterial = (record) => {
|
|
41
|
+
const assertUnchanged = (read) => {
|
|
42
|
+
if (legacySourceDigest(read) !== record.sourceDigest)
|
|
43
|
+
throw new LegacySourceChangedError();
|
|
44
|
+
};
|
|
45
|
+
const fail = () => { throw new Error('The source holds no credential the authority can seal.'); };
|
|
46
|
+
if (record.sourceKind === 'authswitch_stash' && record.path.endsWith('.json')) {
|
|
47
|
+
const read = files(record, [plugins.path.basename(record.path)], plugins.path.dirname(record.path));
|
|
48
|
+
assertUnchanged(read);
|
|
49
|
+
const parsed = parseLegacyJson(read[0].raw);
|
|
50
|
+
const credential = parsed?.credential;
|
|
51
|
+
if (!credential || typeof credential !== 'object' || Array.isArray(credential))
|
|
52
|
+
return fail();
|
|
53
|
+
const material = record.providerId === 'anthropic'
|
|
54
|
+
? claudeFromComposite(credential)
|
|
55
|
+
: openCodeOpenAi(credential);
|
|
56
|
+
return material ?? fail();
|
|
57
|
+
}
|
|
58
|
+
if (record.sourceKind === 'authswitch_stash' || record.sourceKind === 'codex_native') {
|
|
59
|
+
const base = record.sourceKind === 'codex_native' ? plugins.path.dirname(record.path) : record.path;
|
|
60
|
+
const names = record.sourceKind === 'codex_native' ? ['auth.json'] : ['auth.json', 'stash.json'];
|
|
61
|
+
const read = files(record, names, base);
|
|
62
|
+
assertUnchanged(read);
|
|
63
|
+
return openAiFromTokens(parseLegacyJson(read[0].raw)?.tokens) ?? fail();
|
|
64
|
+
}
|
|
65
|
+
if (record.sourceKind === 'claude_native') {
|
|
66
|
+
const credentials = readLegacyFile(record.path, '.credentials.json');
|
|
67
|
+
const configFile = plugins.path.join(plugins.path.dirname(record.path), '.claude.json');
|
|
68
|
+
const config = readLegacyFile(configFile, '.claude.json');
|
|
69
|
+
const read = [credentials.file, config.file].filter((file) => file !== null);
|
|
70
|
+
assertUnchanged(read);
|
|
71
|
+
const credentialData = credentials.file === null ? null : parseLegacyJson(credentials.file.raw);
|
|
72
|
+
const configData = config.file === null ? null : parseLegacyJson(config.file.raw);
|
|
73
|
+
return claudeFromComposite({ claudeAiOauth: credentialData?.claudeAiOauth,
|
|
74
|
+
oauthAccount: configData?.oauthAccount }) ?? fail();
|
|
75
|
+
}
|
|
76
|
+
if (record.sourceKind === 'opencode_native') {
|
|
77
|
+
// The provider entries share a file; the location names the entry, and the digest covers that entry only.
|
|
78
|
+
const separator = record.path.lastIndexOf('#');
|
|
79
|
+
const file = record.path.slice(0, separator);
|
|
80
|
+
const provider = record.path.slice(separator + 1);
|
|
81
|
+
const read = readLegacyFile(file, 'auth.json');
|
|
82
|
+
if (read.file === null)
|
|
83
|
+
throw new LegacySourceChangedError();
|
|
84
|
+
const entry = parseLegacyJson(read.file.raw)?.[provider];
|
|
85
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry))
|
|
86
|
+
throw new LegacySourceChangedError();
|
|
87
|
+
assertUnchanged([{ name: provider, raw: JSON.stringify(entry) }]);
|
|
88
|
+
return openCodeOpenAi(entry) ?? fail();
|
|
89
|
+
}
|
|
90
|
+
return fail();
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* The remote-control enrollments a Codex stash saved beside its credential.
|
|
94
|
+
*
|
|
95
|
+
* They are separate from the refresh grant and are the pairing between this machine's Codex app-server and a
|
|
96
|
+
* ChatGPT client: a migration that dropped them would silently unpair the account.
|
|
97
|
+
*/
|
|
98
|
+
export const readLegacySourceEnrollments = (record) => {
|
|
99
|
+
if (record.sourceKind !== 'authswitch_stash' || record.path.endsWith('.json'))
|
|
100
|
+
return [];
|
|
101
|
+
const read = readLegacyFile(plugins.path.join(record.path, 'stash.json'), 'stash.json');
|
|
102
|
+
if (read.file === null)
|
|
103
|
+
return [];
|
|
104
|
+
const enrollments = parseLegacyJson(read.file.raw)?.enrollments;
|
|
105
|
+
return Array.isArray(enrollments)
|
|
106
|
+
? enrollments.filter((row) => Boolean(row) && typeof row === 'object' && !Array.isArray(row))
|
|
107
|
+
: [];
|
|
108
|
+
};
|
|
109
|
+
/** An OpenCode OAuth entry: access and refresh, with the identity claims carried by the access token. */
|
|
110
|
+
const openCodeOpenAi = (entry) => {
|
|
111
|
+
const accessToken = entry.access;
|
|
112
|
+
const refreshToken = entry.refresh;
|
|
113
|
+
if (typeof accessToken !== 'string' || typeof refreshToken !== 'string')
|
|
114
|
+
return null;
|
|
115
|
+
// OpenCode stores no id_token; the access token carries the same claims the authority reads.
|
|
116
|
+
return { providerId: 'openai',
|
|
117
|
+
credential: { kind: 'chatgptOAuth', providerId: 'openai', accessToken, refreshToken,
|
|
118
|
+
idToken: accessToken } };
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy90c19taWdyYXRpb24vbGVnYWN5c291cmNlcy9tYXRlcmlhbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUNoQyxNQUFNLGFBQWEsQ0FBQztBQWlCaEQsTUFBTSxPQUFPLHdCQUF5QixTQUFRLEtBQUs7SUFDakQsZ0JBQWdCLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDLENBQUMsQ0FBQztDQUNqRztBQUVELE1BQU0sS0FBSyxHQUFHLENBQUMsTUFBMkIsRUFBRSxLQUF3QixFQUNsRSxJQUFZLEVBQXVCLEVBQUU7SUFDckMsTUFBTSxJQUFJLEdBQXdCLEVBQUUsQ0FBQztJQUNyQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUk7WUFBRSxNQUFNLElBQUksd0JBQXdCLEVBQUUsQ0FBQztRQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDLENBQUM7QUFFRixNQUFNLGdCQUFnQixHQUFHLENBQUMsTUFBZSxFQUFnQyxFQUFFO0lBQ3pFLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDaEYsTUFBTSxNQUFNLEdBQUcsTUFB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
|