opencode-qwen-cli-auth 2.3.8 → 2.3.9
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.js +108 -0
- package/dist/lib/auth/auth.d.ts +1 -0
- package/dist/lib/auth/auth.js +12 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1397,6 +1397,114 @@ export const QwenAuthPlugin = async (_input) => {
|
|
|
1397
1397
|
};
|
|
1398
1398
|
},
|
|
1399
1399
|
},
|
|
1400
|
+
{
|
|
1401
|
+
label: "Add another Qwen account (multi-account switch)",
|
|
1402
|
+
type: "oauth",
|
|
1403
|
+
/**
|
|
1404
|
+
* Them account Qwen phu de auto-switch khi account chinh het quota.
|
|
1405
|
+
* Luon tao account moi (forceNew), khong ghi de account cu.
|
|
1406
|
+
* Account moi khong duoc dat active ngay (setActive: false).
|
|
1407
|
+
*/
|
|
1408
|
+
authorize: async () => {
|
|
1409
|
+
const pkce = await createPKCE();
|
|
1410
|
+
const deviceAuth = await requestDeviceCode(pkce);
|
|
1411
|
+
if (!deviceAuth) {
|
|
1412
|
+
throw new Error("Failed to request device code");
|
|
1413
|
+
}
|
|
1414
|
+
console.log(`\n[Add Account] Please visit: ${deviceAuth.verification_uri}`);
|
|
1415
|
+
console.log(`[Add Account] Enter code: ${deviceAuth.user_code}\n`);
|
|
1416
|
+
const verificationUrl = deviceAuth.verification_uri_complete || deviceAuth.verification_uri;
|
|
1417
|
+
return {
|
|
1418
|
+
url: verificationUrl,
|
|
1419
|
+
method: "auto",
|
|
1420
|
+
instructions: "Login with a DIFFERENT Qwen account to add it as backup for auto-switch.",
|
|
1421
|
+
callback: async () => {
|
|
1422
|
+
let pollInterval = (deviceAuth.interval || 5) * 1000;
|
|
1423
|
+
const POLLING_MARGIN_MS = 3000;
|
|
1424
|
+
const maxInterval = DEVICE_FLOW.MAX_POLL_INTERVAL;
|
|
1425
|
+
const startTime = Date.now();
|
|
1426
|
+
const expiresIn = deviceAuth.expires_in * 1000;
|
|
1427
|
+
let consecutivePollFailures = 0;
|
|
1428
|
+
while (Date.now() - startTime < expiresIn) {
|
|
1429
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval + POLLING_MARGIN_MS));
|
|
1430
|
+
const result = await pollForToken(deviceAuth.device_code, pkce.verifier);
|
|
1431
|
+
if (result.type === "success") {
|
|
1432
|
+
// Luu vao legacy token file de loader co the doc
|
|
1433
|
+
saveToken(result);
|
|
1434
|
+
// forceNew: luon tao account moi, khong match account cu
|
|
1435
|
+
// setActive: false - giu account hien tai, chi them du phong
|
|
1436
|
+
const savedAccount = await upsertOAuthAccount(result, {
|
|
1437
|
+
setActive: false,
|
|
1438
|
+
forceNew: true,
|
|
1439
|
+
});
|
|
1440
|
+
if (LOGGING_ENABLED) {
|
|
1441
|
+
logInfo("Added new backup Qwen account", {
|
|
1442
|
+
accountId: savedAccount?.accountId,
|
|
1443
|
+
totalAccounts: savedAccount?.totalAccountCount,
|
|
1444
|
+
healthyAccounts: savedAccount?.healthyAccountCount,
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
console.log(`[Add Account] Success! Account added. Total accounts: ${savedAccount?.totalAccountCount || "?"}`);
|
|
1448
|
+
// Khoi phuc legacy token file (oauth_creds.json) ve active account
|
|
1449
|
+
// de loader doc dung token cua account chinh, khong dung token account moi
|
|
1450
|
+
try {
|
|
1451
|
+
const activeAcct = await getActiveOAuthAccount({ allowExhausted: true });
|
|
1452
|
+
if (activeAcct?.accessToken) {
|
|
1453
|
+
// getActiveOAuthAccount da tu dong sync vao oauth_creds.json
|
|
1454
|
+
// nen khong can goi saveToken thu cong
|
|
1455
|
+
}
|
|
1456
|
+
} catch (_restoreError) {
|
|
1457
|
+
// Khong anh huong chuc nang chinh
|
|
1458
|
+
}
|
|
1459
|
+
return {
|
|
1460
|
+
type: "success",
|
|
1461
|
+
access: result.access,
|
|
1462
|
+
refresh: result.refresh,
|
|
1463
|
+
expires: result.expires,
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
if (result.type === "slow_down") {
|
|
1467
|
+
consecutivePollFailures = 0;
|
|
1468
|
+
pollInterval = Math.min(pollInterval + 5000, maxInterval);
|
|
1469
|
+
continue;
|
|
1470
|
+
}
|
|
1471
|
+
if (result.type === "pending") {
|
|
1472
|
+
consecutivePollFailures = 0;
|
|
1473
|
+
continue;
|
|
1474
|
+
}
|
|
1475
|
+
if (result.type === "failed") {
|
|
1476
|
+
if (result.fatal) {
|
|
1477
|
+
logError("OAuth token polling failed with fatal error (add-account)", {
|
|
1478
|
+
status: result.status,
|
|
1479
|
+
error: result.error,
|
|
1480
|
+
description: result.description,
|
|
1481
|
+
});
|
|
1482
|
+
return { type: "failed" };
|
|
1483
|
+
}
|
|
1484
|
+
consecutivePollFailures += 1;
|
|
1485
|
+
logWarn(`OAuth token polling failed (add-account) (${consecutivePollFailures}/${MAX_CONSECUTIVE_POLL_FAILURES})`);
|
|
1486
|
+
if (consecutivePollFailures >= MAX_CONSECUTIVE_POLL_FAILURES) {
|
|
1487
|
+
console.error("[qwen-oauth-plugin] OAuth token polling failed repeatedly (add-account)");
|
|
1488
|
+
return { type: "failed" };
|
|
1489
|
+
}
|
|
1490
|
+
continue;
|
|
1491
|
+
}
|
|
1492
|
+
if (result.type === "denied") {
|
|
1493
|
+
console.error("[qwen-oauth-plugin] Device authorization was denied (add-account)");
|
|
1494
|
+
return { type: "failed" };
|
|
1495
|
+
}
|
|
1496
|
+
if (result.type === "expired") {
|
|
1497
|
+
console.error("[qwen-oauth-plugin] Device authorization code expired (add-account)");
|
|
1498
|
+
return { type: "failed" };
|
|
1499
|
+
}
|
|
1500
|
+
return { type: "failed" };
|
|
1501
|
+
}
|
|
1502
|
+
console.error("[qwen-oauth-plugin] Device authorization timed out (add-account)");
|
|
1503
|
+
return { type: "failed" };
|
|
1504
|
+
},
|
|
1505
|
+
};
|
|
1506
|
+
},
|
|
1507
|
+
},
|
|
1400
1508
|
],
|
|
1401
1509
|
},
|
|
1402
1510
|
/**
|
package/dist/lib/auth/auth.d.ts
CHANGED
package/dist/lib/auth/auth.js
CHANGED
|
@@ -1056,14 +1056,17 @@ export async function upsertOAuthAccount(tokenResult, options = {}) {
|
|
|
1056
1056
|
await withAccountsStoreLock((store) => {
|
|
1057
1057
|
const now = Date.now();
|
|
1058
1058
|
let index = -1;
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1059
|
+
// forceNew: bo qua match, luon tao account moi (dung cho "Add another account")
|
|
1060
|
+
if (!options.forceNew) {
|
|
1061
|
+
if (typeof options.accountId === "string" && options.accountId.length > 0) {
|
|
1062
|
+
index = store.accounts.findIndex(account => account.id === options.accountId);
|
|
1063
|
+
}
|
|
1064
|
+
if (index < 0 && accountKey) {
|
|
1065
|
+
index = store.accounts.findIndex(account => account.accountKey === accountKey);
|
|
1066
|
+
}
|
|
1067
|
+
if (index < 0) {
|
|
1068
|
+
index = store.accounts.findIndex(account => account.token?.refresh_token === tokenData.refresh_token);
|
|
1069
|
+
}
|
|
1067
1070
|
}
|
|
1068
1071
|
if (index < 0) {
|
|
1069
1072
|
const newId = typeof options.accountId === "string" && options.accountId.length > 0
|
|
@@ -1105,7 +1108,7 @@ export async function getActiveOAuthAccount(options = {}) {
|
|
|
1105
1108
|
? options.preferredAccountId
|
|
1106
1109
|
: null;
|
|
1107
1110
|
const attemptedAuthRejected = new Set();
|
|
1108
|
-
for (
|
|
1111
|
+
for (; ;) {
|
|
1109
1112
|
const lockPath = await acquireAccountsLock();
|
|
1110
1113
|
let selected = null;
|
|
1111
1114
|
let dirty = false;
|
package/package.json
CHANGED