Spaces:
Paused
Paused
| import readline from 'readline'; | |
| import fs from 'fs'; | |
| import path from 'path'; | |
| import { fileURLToPath } from 'url'; | |
| import { initBrowser, shutdownBrowser, getBrowserContext } from '../browser/browser.js'; | |
| import { extractAuthToken } from '../api/chat.js'; | |
| import { loadTokens, saveTokens, markValid, removeToken } from '../api/tokenManager.js'; | |
| import { loadAuthToken } from '../browser/session.js'; | |
| const __filename = fileURLToPath(import.meta.url); | |
| const __dirname = path.dirname(__filename); | |
| function prompt(question) { | |
| const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); | |
| return new Promise(resolve => rl.question(question, ans => { rl.close(); resolve(ans.trim()); })); | |
| } | |
| function ensureAccountDir(id) { | |
| const accountDir = path.join(__dirname, '..', '..', 'session', 'accounts', id); | |
| if (!fs.existsSync(accountDir)) { | |
| fs.mkdirSync(accountDir, { recursive: true }); | |
| } | |
| return accountDir; | |
| } | |
| export async function addAccountInteractive() { | |
| console.log('======================================================'); | |
| console.log('Добавление нового аккаунта Qwen'); | |
| console.log('Браузер откроется, войдите в систему, затем вернитесь к консоли.'); | |
| console.log('======================================================'); | |
| const ok = await initBrowser(true, true); | |
| if (!ok) { | |
| console.error('Не удалось запустить браузер.'); | |
| return null; | |
| } | |
| const ctx = getBrowserContext(); | |
| let token = await extractAuthToken(ctx, true); | |
| if (!token) { | |
| token = loadAuthToken(); | |
| if (token) { | |
| console.log('Токен получен из сохранённого файла.'); | |
| } | |
| } | |
| if (!token) { | |
| console.error('Токен не был получен. Аккаунт не добавлен.'); | |
| await shutdownBrowser(); | |
| return null; | |
| } | |
| await shutdownBrowser(); | |
| // --- | |
| const id = 'acc_' + Date.now(); | |
| ensureAccountDir(id); | |
| fs.writeFileSync(path.join(__dirname, '..', '..', 'session', 'accounts', id, 'token.txt'), token, 'utf8'); | |
| const list = loadTokens(); | |
| list.push({ id, token, resetAt: null }); | |
| saveTokens(list); | |
| console.log(`Аккаунт '${id}' добавлен. Всего аккаунтов: ${list.length}`); | |
| console.log('======================================================'); | |
| return id; | |
| } | |
| export async function interactiveAccountMenu() { | |
| while (true) { | |
| console.log('\n=== Меню управления аккаунтами ==='); | |
| console.log('1 - Добавить новый аккаунт'); | |
| console.log('2 - Завершить'); | |
| const choice = await prompt('Ваш выбор (1/2): '); | |
| if (choice === '1') { | |
| await addAccountInteractive(); | |
| } else if (choice === '2') { | |
| break; | |
| } else { | |
| console.log('Неверный выбор.'); | |
| } | |
| } | |
| } | |
| export async function reloginAccountInteractive() { | |
| const tokens = loadTokens(); | |
| const invalids = tokens.filter(t => t.invalid); | |
| if (!invalids.length) { | |
| console.log('Нет аккаунтов, требующих повторного входа.'); | |
| await prompt('Нажмите ENTER чтобы вернуться в меню...'); | |
| return; | |
| } | |
| console.log('\nАккаунты с истекшим токеном:'); | |
| invalids.forEach((t, idx) => console.log(`${idx + 1} - ${t.id}`)); | |
| const choice = await prompt('Выберите номер аккаунта для повторного входа: '); | |
| const num = parseInt(choice, 10); | |
| if (isNaN(num) || num < 1 || num > invalids.length) { | |
| console.log('Неверный выбор.'); | |
| return; | |
| } | |
| const account = invalids[num - 1]; | |
| console.log(`\nПовторная авторизация для ${account.id}`); | |
| const ok = await initBrowser(true, true); | |
| if (!ok) { | |
| console.error('Не удалось запустить браузер.'); | |
| return; | |
| } | |
| const token = await extractAuthToken(getBrowserContext(), true); | |
| await shutdownBrowser(); | |
| if (!token) { | |
| console.error('Не удалось извлечь токен.'); | |
| return; | |
| } | |
| // сохраняем новый токен и снимаем invalid | |
| markValid(account.id, token); | |
| fs.writeFileSync(path.join(__dirname, '..', '..', 'session', 'accounts', account.id, 'token.txt'), token, 'utf8'); | |
| console.log(`Токен обновлён для ${account.id}`); | |
| } | |
| export async function removeAccountInteractive() { | |
| const tokens = loadTokens(); | |
| if (!tokens.length) { | |
| console.log('Нет сохранённых аккаунтов.'); | |
| await prompt('ENTER чтобы вернуться...'); | |
| return; | |
| } | |
| console.log('\nДоступные аккаунты:'); | |
| tokens.forEach((t, idx) => console.log(`${idx + 1} - ${t.id}`)); | |
| const choice = await prompt('Номер аккаунта, который нужно удалить (или ENTER для отмены): '); | |
| if (!choice) return; | |
| const num = parseInt(choice, 10); | |
| if (isNaN(num) || num < 1 || num > tokens.length) { | |
| console.log('Неверный выбор.'); | |
| await prompt('ENTER чтобы вернуться...'); | |
| return; | |
| } | |
| const acc = tokens[num - 1]; | |
| const confirm = await prompt(`Точно удалить ${acc.id}? (y/N): `); | |
| if (confirm.toLowerCase() !== 'y') return; | |
| removeToken(acc.id); | |
| // удалить директорию аккаунта | |
| const dir = path.join(__dirname, '..', '..', 'session', 'accounts', acc.id); | |
| if (fs.existsSync(dir)) { | |
| fs.rmSync(dir, { recursive: true, force: true }); | |
| } | |
| console.log(`Аккаунт ${acc.id} удалён.`); | |
| await prompt('ENTER чтобы вернуться...'); | |
| } |