File size: 6,050 Bytes
9de864e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
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 чтобы вернуться...');
}