oc-chatgpt-multi-auth 5.3.2 → 5.3.3
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/index.d.ts.map +1 -1
- package/dist/index.js +238 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +143 -26
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +23 -5
- package/dist/lib/ui/auth-menu.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AA0I/D;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AA0I/D;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAu7G/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAoB,CAAC;AAElD,eAAe,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -226,7 +226,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
226
226
|
await withAccountStorageTransaction(async (loadedStorage, persist) => {
|
|
227
227
|
const now = Date.now();
|
|
228
228
|
const stored = replaceAll ? null : loadedStorage;
|
|
229
|
-
|
|
229
|
+
let accounts = stored?.accounts ? [...stored.accounts] : [];
|
|
230
230
|
const pushIndex = (map, key, index) => {
|
|
231
231
|
const existing = map.get(key);
|
|
232
232
|
if (existing) {
|
|
@@ -241,6 +241,93 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
241
241
|
const [onlyIndex] = indices;
|
|
242
242
|
return typeof onlyIndex === "number" ? onlyIndex : undefined;
|
|
243
243
|
};
|
|
244
|
+
const pickNewestAccountIndex = (existingIndex, candidateIndex) => {
|
|
245
|
+
const existing = accounts[existingIndex];
|
|
246
|
+
const candidate = accounts[candidateIndex];
|
|
247
|
+
if (!existing)
|
|
248
|
+
return candidateIndex;
|
|
249
|
+
if (!candidate)
|
|
250
|
+
return existingIndex;
|
|
251
|
+
const existingLastUsed = existing.lastUsed ?? 0;
|
|
252
|
+
const candidateLastUsed = candidate.lastUsed ?? 0;
|
|
253
|
+
if (candidateLastUsed > existingLastUsed)
|
|
254
|
+
return candidateIndex;
|
|
255
|
+
if (candidateLastUsed < existingLastUsed)
|
|
256
|
+
return existingIndex;
|
|
257
|
+
const existingAddedAt = existing.addedAt ?? 0;
|
|
258
|
+
const candidateAddedAt = candidate.addedAt ?? 0;
|
|
259
|
+
return candidateAddedAt >= existingAddedAt ? candidateIndex : existingIndex;
|
|
260
|
+
};
|
|
261
|
+
const mergeAccountRecords = (targetIndex, sourceIndex) => {
|
|
262
|
+
const target = accounts[targetIndex];
|
|
263
|
+
const source = accounts[sourceIndex];
|
|
264
|
+
if (!target || !source)
|
|
265
|
+
return;
|
|
266
|
+
const targetLastUsed = target.lastUsed ?? 0;
|
|
267
|
+
const sourceLastUsed = source.lastUsed ?? 0;
|
|
268
|
+
const targetAddedAt = target.addedAt ?? 0;
|
|
269
|
+
const sourceAddedAt = source.addedAt ?? 0;
|
|
270
|
+
const sourceIsNewer = sourceLastUsed > targetLastUsed ||
|
|
271
|
+
(sourceLastUsed === targetLastUsed && sourceAddedAt > targetAddedAt);
|
|
272
|
+
const newer = sourceIsNewer ? source : target;
|
|
273
|
+
const older = sourceIsNewer ? target : source;
|
|
274
|
+
const mergedRateLimitResetTimes = {};
|
|
275
|
+
const rateLimitResetKeys = new Set([
|
|
276
|
+
...Object.keys(older.rateLimitResetTimes ?? {}),
|
|
277
|
+
...Object.keys(newer.rateLimitResetTimes ?? {}),
|
|
278
|
+
]);
|
|
279
|
+
for (const key of rateLimitResetKeys) {
|
|
280
|
+
const olderRaw = older.rateLimitResetTimes?.[key];
|
|
281
|
+
const newerRaw = newer.rateLimitResetTimes?.[key];
|
|
282
|
+
const olderValue = typeof olderRaw === "number" && Number.isFinite(olderRaw) ? olderRaw : 0;
|
|
283
|
+
const newerValue = typeof newerRaw === "number" && Number.isFinite(newerRaw) ? newerRaw : 0;
|
|
284
|
+
const resolved = Math.max(olderValue, newerValue);
|
|
285
|
+
if (resolved > 0) {
|
|
286
|
+
mergedRateLimitResetTimes[key] = resolved;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const mergedEnabled = target.enabled === false || source.enabled === false
|
|
290
|
+
? false
|
|
291
|
+
: target.enabled ?? source.enabled;
|
|
292
|
+
const targetCoolingDownUntil = typeof target.coolingDownUntil === "number" && Number.isFinite(target.coolingDownUntil)
|
|
293
|
+
? target.coolingDownUntil
|
|
294
|
+
: 0;
|
|
295
|
+
const sourceCoolingDownUntil = typeof source.coolingDownUntil === "number" && Number.isFinite(source.coolingDownUntil)
|
|
296
|
+
? source.coolingDownUntil
|
|
297
|
+
: 0;
|
|
298
|
+
const mergedCoolingDownUntilValue = Math.max(targetCoolingDownUntil, sourceCoolingDownUntil);
|
|
299
|
+
const mergedCoolingDownUntil = mergedCoolingDownUntilValue > 0 ? mergedCoolingDownUntilValue : undefined;
|
|
300
|
+
const mergedCooldownReason = (() => {
|
|
301
|
+
if (mergedCoolingDownUntilValue <= 0) {
|
|
302
|
+
return target.cooldownReason ?? source.cooldownReason;
|
|
303
|
+
}
|
|
304
|
+
if (sourceCoolingDownUntil > targetCoolingDownUntil) {
|
|
305
|
+
return source.cooldownReason ?? target.cooldownReason;
|
|
306
|
+
}
|
|
307
|
+
if (targetCoolingDownUntil > sourceCoolingDownUntil) {
|
|
308
|
+
return target.cooldownReason ?? source.cooldownReason;
|
|
309
|
+
}
|
|
310
|
+
return source.cooldownReason ?? target.cooldownReason;
|
|
311
|
+
})();
|
|
312
|
+
accounts[targetIndex] = {
|
|
313
|
+
...target,
|
|
314
|
+
accountId: target.accountId ?? source.accountId,
|
|
315
|
+
organizationId: target.organizationId ?? source.organizationId,
|
|
316
|
+
accountIdSource: target.accountIdSource ?? source.accountIdSource,
|
|
317
|
+
accountLabel: target.accountLabel ?? source.accountLabel,
|
|
318
|
+
email: target.email ?? source.email,
|
|
319
|
+
refreshToken: newer.refreshToken || older.refreshToken,
|
|
320
|
+
accessToken: newer.accessToken || older.accessToken,
|
|
321
|
+
expiresAt: newer.expiresAt ?? older.expiresAt,
|
|
322
|
+
enabled: mergedEnabled,
|
|
323
|
+
addedAt: Math.max(target.addedAt ?? 0, source.addedAt ?? 0),
|
|
324
|
+
lastUsed: Math.max(target.lastUsed ?? 0, source.lastUsed ?? 0),
|
|
325
|
+
lastSwitchReason: target.lastSwitchReason ?? source.lastSwitchReason,
|
|
326
|
+
rateLimitResetTimes: mergedRateLimitResetTimes,
|
|
327
|
+
coolingDownUntil: mergedCoolingDownUntil,
|
|
328
|
+
cooldownReason: mergedCooldownReason,
|
|
329
|
+
};
|
|
330
|
+
};
|
|
244
331
|
const resolveUniqueOrgScopedMatch = (indexes, accountId, refreshToken) => {
|
|
245
332
|
const byAccountId = accountId
|
|
246
333
|
? asUniqueIndex(indexes.byAccountIdOrgScoped.get(accountId))
|
|
@@ -260,6 +347,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
260
347
|
const byEmailNoOrg = new Map();
|
|
261
348
|
const byAccountIdOrgScoped = new Map();
|
|
262
349
|
const byRefreshTokenOrgScoped = new Map();
|
|
350
|
+
const byRefreshTokenGlobal = new Map();
|
|
263
351
|
for (let i = 0; i < accounts.length; i += 1) {
|
|
264
352
|
const account = accounts[i];
|
|
265
353
|
if (!account)
|
|
@@ -268,6 +356,10 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
268
356
|
const accountId = account.accountId?.trim();
|
|
269
357
|
const refreshToken = account.refreshToken?.trim();
|
|
270
358
|
const email = account.email?.trim();
|
|
359
|
+
// Global refresh token index: first entry wins (keeps earliest/primary).
|
|
360
|
+
if (refreshToken && !byRefreshTokenGlobal.has(refreshToken)) {
|
|
361
|
+
byRefreshTokenGlobal.set(refreshToken, i);
|
|
362
|
+
}
|
|
271
363
|
if (organizationId) {
|
|
272
364
|
byOrganizationId.set(organizationId, i);
|
|
273
365
|
if (accountId) {
|
|
@@ -295,6 +387,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
295
387
|
byEmailNoOrg,
|
|
296
388
|
byAccountIdOrgScoped,
|
|
297
389
|
byRefreshTokenOrgScoped,
|
|
390
|
+
byRefreshTokenGlobal,
|
|
298
391
|
};
|
|
299
392
|
};
|
|
300
393
|
let identityIndexes = buildIdentityIndexes();
|
|
@@ -328,7 +421,12 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
328
421
|
return byEmail;
|
|
329
422
|
}
|
|
330
423
|
}
|
|
331
|
-
|
|
424
|
+
const orgScoped = resolveUniqueOrgScopedMatch(identityIndexes, normalizedAccountId, result.refresh);
|
|
425
|
+
if (orgScoped !== undefined)
|
|
426
|
+
return orgScoped;
|
|
427
|
+
// Absolute last resort: same refresh token = same human account.
|
|
428
|
+
// Catches org-scoped entries invisible to no-org lookups.
|
|
429
|
+
return identityIndexes.byRefreshTokenGlobal.get(result.refresh);
|
|
332
430
|
})();
|
|
333
431
|
if (existingIndex === undefined) {
|
|
334
432
|
accounts.push({
|
|
@@ -351,11 +449,20 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
351
449
|
continue;
|
|
352
450
|
const nextEmail = accountEmail ?? existing.email;
|
|
353
451
|
const nextOrganizationId = organizationId ?? existing.organizationId;
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
452
|
+
const preserveOrgIdentity = typeof existing.organizationId === "string" &&
|
|
453
|
+
existing.organizationId.trim().length > 0 &&
|
|
454
|
+
!organizationId;
|
|
455
|
+
const nextAccountId = preserveOrgIdentity
|
|
456
|
+
? existing.accountId ?? normalizedAccountId
|
|
457
|
+
: normalizedAccountId ?? existing.accountId;
|
|
458
|
+
const nextAccountIdSource = preserveOrgIdentity
|
|
459
|
+
? existing.accountIdSource ?? accountIdSource
|
|
460
|
+
: normalizedAccountId
|
|
461
|
+
? accountIdSource ?? existing.accountIdSource
|
|
462
|
+
: existing.accountIdSource;
|
|
463
|
+
const nextAccountLabel = preserveOrgIdentity
|
|
464
|
+
? existing.accountLabel ?? accountLabel
|
|
465
|
+
: accountLabel ?? existing.accountLabel;
|
|
359
466
|
accounts[existingIndex] = {
|
|
360
467
|
...existing,
|
|
361
468
|
accountId: nextAccountId,
|
|
@@ -370,22 +477,140 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
370
477
|
};
|
|
371
478
|
identityIndexes = buildIdentityIndexes();
|
|
372
479
|
}
|
|
480
|
+
const pruneRefreshTokenCollisions = () => {
|
|
481
|
+
const indicesToRemove = new Set();
|
|
482
|
+
const refreshMap = new Map();
|
|
483
|
+
for (let i = 0; i < accounts.length; i += 1) {
|
|
484
|
+
const account = accounts[i];
|
|
485
|
+
if (!account)
|
|
486
|
+
continue;
|
|
487
|
+
const refreshToken = account.refreshToken?.trim();
|
|
488
|
+
if (!refreshToken)
|
|
489
|
+
continue;
|
|
490
|
+
const orgKey = account.organizationId?.trim() ?? "";
|
|
491
|
+
let entry = refreshMap.get(refreshToken);
|
|
492
|
+
if (!entry) {
|
|
493
|
+
entry = { byOrg: new Map(), fallbackIndex: undefined };
|
|
494
|
+
refreshMap.set(refreshToken, entry);
|
|
495
|
+
}
|
|
496
|
+
if (orgKey) {
|
|
497
|
+
const existingIndex = entry.byOrg.get(orgKey);
|
|
498
|
+
if (existingIndex !== undefined) {
|
|
499
|
+
const newestIndex = pickNewestAccountIndex(existingIndex, i);
|
|
500
|
+
const obsoleteIndex = newestIndex === existingIndex ? i : existingIndex;
|
|
501
|
+
mergeAccountRecords(newestIndex, obsoleteIndex);
|
|
502
|
+
indicesToRemove.add(obsoleteIndex);
|
|
503
|
+
entry.byOrg.set(orgKey, newestIndex);
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
entry.byOrg.set(orgKey, i);
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
const existingFallback = entry.fallbackIndex;
|
|
510
|
+
if (typeof existingFallback === "number") {
|
|
511
|
+
const newestIndex = pickNewestAccountIndex(existingFallback, i);
|
|
512
|
+
const obsoleteIndex = newestIndex === existingFallback ? i : existingFallback;
|
|
513
|
+
mergeAccountRecords(newestIndex, obsoleteIndex);
|
|
514
|
+
indicesToRemove.add(obsoleteIndex);
|
|
515
|
+
entry.fallbackIndex = newestIndex;
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
entry.fallbackIndex = i;
|
|
519
|
+
}
|
|
520
|
+
for (const entry of refreshMap.values()) {
|
|
521
|
+
const fallbackIndex = entry.fallbackIndex;
|
|
522
|
+
if (typeof fallbackIndex !== "number")
|
|
523
|
+
continue;
|
|
524
|
+
const orgIndices = Array.from(entry.byOrg.values());
|
|
525
|
+
if (orgIndices.length === 0)
|
|
526
|
+
continue;
|
|
527
|
+
const [firstOrgIndex, ...otherOrgIndices] = orgIndices;
|
|
528
|
+
if (typeof firstOrgIndex !== "number")
|
|
529
|
+
continue;
|
|
530
|
+
let preferredOrgIndex = firstOrgIndex;
|
|
531
|
+
for (const orgIndex of otherOrgIndices) {
|
|
532
|
+
preferredOrgIndex = pickNewestAccountIndex(preferredOrgIndex, orgIndex);
|
|
533
|
+
}
|
|
534
|
+
mergeAccountRecords(preferredOrgIndex, fallbackIndex);
|
|
535
|
+
indicesToRemove.add(fallbackIndex);
|
|
536
|
+
}
|
|
537
|
+
if (indicesToRemove.size > 0) {
|
|
538
|
+
accounts = accounts.filter((_, index) => !indicesToRemove.has(index));
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
const collectIdentityKeys = (account) => {
|
|
542
|
+
const keys = [];
|
|
543
|
+
const organizationId = account?.organizationId?.trim();
|
|
544
|
+
if (organizationId)
|
|
545
|
+
keys.push(`org:${organizationId}`);
|
|
546
|
+
const accountId = account?.accountId?.trim();
|
|
547
|
+
if (accountId)
|
|
548
|
+
keys.push(`account:${accountId}`);
|
|
549
|
+
const refreshToken = account?.refreshToken?.trim();
|
|
550
|
+
if (refreshToken)
|
|
551
|
+
keys.push(`refresh:${refreshToken}`);
|
|
552
|
+
return keys;
|
|
553
|
+
};
|
|
554
|
+
const getStoredAccountAtIndex = (rawIndex) => {
|
|
555
|
+
const storedAccounts = stored?.accounts;
|
|
556
|
+
if (!storedAccounts)
|
|
557
|
+
return undefined;
|
|
558
|
+
if (typeof rawIndex !== "number" || !Number.isFinite(rawIndex))
|
|
559
|
+
return undefined;
|
|
560
|
+
const candidate = Math.floor(rawIndex);
|
|
561
|
+
if (candidate < 0 || candidate >= storedAccounts.length)
|
|
562
|
+
return undefined;
|
|
563
|
+
return storedAccounts[candidate];
|
|
564
|
+
};
|
|
565
|
+
const storedActiveKeys = replaceAll
|
|
566
|
+
? []
|
|
567
|
+
: collectIdentityKeys(getStoredAccountAtIndex(stored?.activeIndex));
|
|
568
|
+
const storedActiveKeysByFamily = {};
|
|
569
|
+
if (!replaceAll) {
|
|
570
|
+
for (const family of MODEL_FAMILIES) {
|
|
571
|
+
const familyKeys = collectIdentityKeys(getStoredAccountAtIndex(stored?.activeIndexByFamily?.[family]));
|
|
572
|
+
if (familyKeys.length > 0) {
|
|
573
|
+
storedActiveKeysByFamily[family] = familyKeys;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
pruneRefreshTokenCollisions();
|
|
373
578
|
if (accounts.length === 0)
|
|
374
579
|
return;
|
|
375
|
-
const
|
|
580
|
+
const resolveIndexByIdentityKeys = (identityKeys) => {
|
|
581
|
+
if (!identityKeys || identityKeys.length === 0)
|
|
582
|
+
return undefined;
|
|
583
|
+
for (const identityKey of identityKeys) {
|
|
584
|
+
const index = accounts.findIndex((account) => collectIdentityKeys(account).includes(identityKey));
|
|
585
|
+
if (index >= 0) {
|
|
586
|
+
return index;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return undefined;
|
|
590
|
+
};
|
|
591
|
+
const fallbackActiveIndex = replaceAll
|
|
376
592
|
? 0
|
|
377
593
|
: typeof stored?.activeIndex === "number" && Number.isFinite(stored.activeIndex)
|
|
378
594
|
? stored.activeIndex
|
|
379
595
|
: 0;
|
|
380
|
-
const
|
|
596
|
+
const remappedActiveIndex = replaceAll
|
|
597
|
+
? undefined
|
|
598
|
+
: resolveIndexByIdentityKeys(storedActiveKeys);
|
|
599
|
+
const activeIndex = remappedActiveIndex ?? fallbackActiveIndex;
|
|
600
|
+
const clampedActiveIndex = Math.max(0, Math.min(Math.floor(activeIndex), accounts.length - 1));
|
|
381
601
|
const activeIndexByFamily = {};
|
|
382
602
|
for (const family of MODEL_FAMILIES) {
|
|
383
603
|
const storedFamilyIndex = stored?.activeIndexByFamily?.[family];
|
|
604
|
+
const remappedFamilyIndex = replaceAll
|
|
605
|
+
? undefined
|
|
606
|
+
: resolveIndexByIdentityKeys(storedActiveKeysByFamily[family]);
|
|
384
607
|
const rawFamilyIndex = replaceAll
|
|
385
608
|
? 0
|
|
386
|
-
: typeof
|
|
387
|
-
?
|
|
388
|
-
:
|
|
609
|
+
: typeof remappedFamilyIndex === "number"
|
|
610
|
+
? remappedFamilyIndex
|
|
611
|
+
: typeof storedFamilyIndex === "number" && Number.isFinite(storedFamilyIndex)
|
|
612
|
+
? storedFamilyIndex
|
|
613
|
+
: clampedActiveIndex;
|
|
389
614
|
activeIndexByFamily[family] = Math.max(0, Math.min(Math.floor(rawFamilyIndex), accounts.length - 1));
|
|
390
615
|
}
|
|
391
616
|
await persist({
|
|
@@ -1414,7 +1639,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1414
1639
|
const headers = createCodexHeaders(undefined, params.accountId, params.accessToken, {
|
|
1415
1640
|
model,
|
|
1416
1641
|
});
|
|
1417
|
-
headers.set("content-type", "application/json
|
|
1642
|
+
headers.set("content-type", "application/json");
|
|
1418
1643
|
const controller = new AbortController();
|
|
1419
1644
|
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
1420
1645
|
let response;
|