evogram-gramjs 1.1.0 → 1.1.1
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/lib/EvogramGramJS.d.ts +51 -0
- package/lib/EvogramGramJS.js +99 -0
- package/lib/commands/Accounts.command.d.ts +6 -0
- package/lib/commands/Accounts.command.js +95 -0
- package/lib/commands/AddAccount.command.d.ts +19 -0
- package/lib/commands/AddAccount.command.js +461 -0
- package/lib/commands/index.d.ts +2 -0
- package/lib/commands/index.js +5 -0
- package/lib/commands/managment/DeleteAccount.command.d.ts +0 -0
- package/{src/commands/managment/DeleteAccount.command.ts → lib/commands/managment/DeleteAccount.command.js} +1 -2
- package/lib/config/database.config.d.ts +26 -0
- package/lib/config/database.config.js +31 -0
- package/lib/entities/Session.entity.d.ts +28 -0
- package/lib/entities/Session.entity.js +71 -0
- package/lib/entities/SessionEventLog.entity.d.ts +22 -0
- package/lib/entities/SessionEventLog.entity.js +50 -0
- package/lib/examples/auth.example.d.ts +10 -0
- package/lib/examples/auth.example.js +126 -0
- package/lib/examples/database.example.d.ts +13 -0
- package/lib/examples/database.example.js +109 -0
- package/lib/examples/usage.example.d.ts +13 -0
- package/lib/examples/usage.example.js +127 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +10 -0
- package/lib/services/DatabaseService.d.ts +30 -0
- package/lib/services/DatabaseService.js +93 -0
- package/lib/services/ImageUploadService.d.ts +15 -0
- package/lib/services/ImageUploadService.js +56 -0
- package/lib/sessions/Session.d.ts +13 -0
- package/lib/sessions/Session.js +25 -0
- package/lib/sessions/SessionAuth.d.ts +72 -0
- package/lib/sessions/SessionAuth.js +327 -0
- package/lib/sessions/SessionLogger.d.ts +84 -0
- package/lib/sessions/SessionLogger.js +196 -0
- package/lib/sessions/SessionManager.d.ts +84 -0
- package/lib/sessions/SessionManager.js +198 -0
- package/lib/test.d.ts +1 -0
- package/lib/test.js +144 -0
- package/lib/types/auth.types.d.ts +90 -0
- package/lib/types/auth.types.js +19 -0
- package/lib/types/session.types.d.ts +87 -0
- package/lib/types/session.types.js +21 -0
- package/lib/utils/Deferrer.d.ts +6 -0
- package/lib/utils/Deferrer.js +14 -0
- package/package.json +1 -2
- package/src/EvogramGramJS.ts +0 -98
- package/src/commands/Accounts.command.ts +0 -89
- package/src/commands/AddAccount.command.ts +0 -449
- package/src/commands/index.ts +0 -2
- package/src/config/database.config.ts +0 -75
- package/src/entities/Session.entity.ts +0 -58
- package/src/entities/SessionEventLog.entity.ts +0 -41
- package/src/index.ts +0 -7
- package/src/services/DatabaseService.ts +0 -82
- package/src/services/ImageUploadService.ts +0 -49
- package/src/sessions/Session.ts +0 -21
- package/src/sessions/SessionAuth.ts +0 -356
- package/src/sessions/SessionLogger.ts +0 -208
- package/src/sessions/SessionManager.ts +0 -211
- package/src/types/auth.types.ts +0 -94
- package/src/types/session.types.ts +0 -96
- package/src/utils/Deferrer.ts +0 -12
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ImageUploadService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
6
|
+
const form_data_1 = tslib_1.__importDefault(require("form-data"));
|
|
7
|
+
/**
|
|
8
|
+
* Сервис для загрузки изображений на внешние хостинги
|
|
9
|
+
*/
|
|
10
|
+
class ImageUploadService {
|
|
11
|
+
/**
|
|
12
|
+
* Загружает изображение на imgbox.vu/uploads
|
|
13
|
+
*
|
|
14
|
+
* @param imageBuffer Буфер изображения
|
|
15
|
+
* @param filename Имя файла (опционально)
|
|
16
|
+
* @returns Promise с URL загруженного изображения
|
|
17
|
+
* @throws Error если загрузка не удалась
|
|
18
|
+
*/
|
|
19
|
+
static uploadToImgbox(imageBuffer, filename) {
|
|
20
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
var _a;
|
|
22
|
+
try {
|
|
23
|
+
const formData = new form_data_1.default();
|
|
24
|
+
formData.append('file', imageBuffer, {
|
|
25
|
+
filename: filename || 'avatar.jpg',
|
|
26
|
+
contentType: 'image/jpeg',
|
|
27
|
+
});
|
|
28
|
+
const response = yield axios_1.default.post(this.UPLOAD_URL, formData, {
|
|
29
|
+
headers: formData.getHeaders(),
|
|
30
|
+
});
|
|
31
|
+
const result = response.data;
|
|
32
|
+
// Проверяем формат ответа imgbox.vu
|
|
33
|
+
// API может возвращать URL в разных форматах, нужно проверить структуру ответа
|
|
34
|
+
if (result.url) {
|
|
35
|
+
return result.url;
|
|
36
|
+
}
|
|
37
|
+
else if ((_a = result.data) === null || _a === void 0 ? void 0 : _a.url) {
|
|
38
|
+
return result.data.url;
|
|
39
|
+
}
|
|
40
|
+
else if (typeof result === 'string' && result.startsWith('http')) {
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Если формат ответа неизвестен, возвращаем весь ответ как строку для отладки
|
|
45
|
+
throw new Error(`Неожиданный формат ответа от imgbox.vu: ${JSON.stringify(result)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
50
|
+
throw new Error(`Ошибка загрузки изображения на imgbox.vu: ${errorMessage}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.ImageUploadService = ImageUploadService;
|
|
56
|
+
ImageUploadService.UPLOAD_URL = 'https://imgbox.vu/uploads';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TelegramClient } from 'telegram';
|
|
2
|
+
import { SessionAuth } from './SessionAuth';
|
|
3
|
+
import { SessionLogger } from './SessionLogger';
|
|
4
|
+
export declare class Session {
|
|
5
|
+
readonly sessionId: string;
|
|
6
|
+
readonly client: TelegramClient;
|
|
7
|
+
readonly logger: SessionLogger | undefined;
|
|
8
|
+
/** Объект авторизации для сессии */
|
|
9
|
+
auth: SessionAuth;
|
|
10
|
+
constructor(sessionId: string, client: TelegramClient, logger: SessionLogger | undefined, auth: SessionAuth);
|
|
11
|
+
db(): Promise<import("..").Session | null>;
|
|
12
|
+
user(): Promise<import("telegram").Api.User>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Session = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const EvogramGramJS_1 = require("../EvogramGramJS");
|
|
6
|
+
class Session {
|
|
7
|
+
constructor(sessionId, client, logger, auth) {
|
|
8
|
+
this.sessionId = sessionId;
|
|
9
|
+
this.client = client;
|
|
10
|
+
this.logger = logger;
|
|
11
|
+
this.auth = auth;
|
|
12
|
+
}
|
|
13
|
+
db() {
|
|
14
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
var _a;
|
|
16
|
+
return (_a = (yield EvogramGramJS_1.EvogramGramJS.databaseService.getSession(this.sessionId))) !== null && _a !== void 0 ? _a : null;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
user() {
|
|
20
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
return yield this.client.getMe();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.Session = Session;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { TelegramClient } from 'telegram';
|
|
3
|
+
import { AuthState } from '../types/auth.types';
|
|
4
|
+
import { Deferred } from '../utils/Deferrer';
|
|
5
|
+
import { SessionLogger } from './SessionLogger';
|
|
6
|
+
/**
|
|
7
|
+
* События авторизации для сессии
|
|
8
|
+
*/
|
|
9
|
+
export declare enum SessionAuthEvent {
|
|
10
|
+
/** Начало авторизации */
|
|
11
|
+
AUTH_STARTED = "auth:started",
|
|
12
|
+
/** Код отправлен */
|
|
13
|
+
CODE_SENT = "auth:code_sent",
|
|
14
|
+
/** Код получен */
|
|
15
|
+
CODE_RECEIVED = "auth:code_received",
|
|
16
|
+
/** Требуется пароль */
|
|
17
|
+
PASSWORD_REQUIRED = "auth:password_required",
|
|
18
|
+
/** Авторизация успешна */
|
|
19
|
+
AUTH_SUCCESS = "auth:success",
|
|
20
|
+
/** Ошибка авторизации */
|
|
21
|
+
AUTH_ERROR = "auth:error",
|
|
22
|
+
/** Авторизация отменена */
|
|
23
|
+
AUTH_CANCELLED = "auth:cancelled"
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Класс авторизации для конкретной сессии
|
|
27
|
+
* Предоставляет методы авторизации, привязанные к сессии
|
|
28
|
+
*/
|
|
29
|
+
export declare class SessionAuth extends EventEmitter {
|
|
30
|
+
private readonly sessionId;
|
|
31
|
+
private readonly client;
|
|
32
|
+
private readonly logger?;
|
|
33
|
+
state: {
|
|
34
|
+
code: Deferred<string>;
|
|
35
|
+
password: Deferred<string>;
|
|
36
|
+
isRequiredPassword: boolean;
|
|
37
|
+
stage: AuthState;
|
|
38
|
+
connect: Deferred<boolean>;
|
|
39
|
+
};
|
|
40
|
+
constructor(sessionId: string, client: TelegramClient, logger?: SessionLogger | undefined);
|
|
41
|
+
start(phoneNumber: string): Promise<{
|
|
42
|
+
success: boolean;
|
|
43
|
+
error?: undefined;
|
|
44
|
+
} | {
|
|
45
|
+
success: boolean;
|
|
46
|
+
error: unknown;
|
|
47
|
+
}>;
|
|
48
|
+
setCode(code: string): Promise<{
|
|
49
|
+
success: boolean;
|
|
50
|
+
error: Error;
|
|
51
|
+
}>;
|
|
52
|
+
setPassword(password: string): Promise<{
|
|
53
|
+
success: boolean;
|
|
54
|
+
error: Error;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Начинает авторизацию через QR-код
|
|
58
|
+
*
|
|
59
|
+
* @param onQRCode Callback для обработки QR-кода (получает URL и токен)
|
|
60
|
+
* @returns Promise с результатом авторизации
|
|
61
|
+
*/
|
|
62
|
+
startWithQRCode(onQRCode: (qrUrl: string, qrToken: string, expires: number) => Promise<void>): Promise<{
|
|
63
|
+
success: boolean;
|
|
64
|
+
error?: any;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Проверяет, требуется ли пароль для авторизации
|
|
68
|
+
*
|
|
69
|
+
* @returns true, если требуется пароль
|
|
70
|
+
*/
|
|
71
|
+
isRequiredPassword(): Promise<boolean>;
|
|
72
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionAuth = exports.SessionAuthEvent = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
const telegram_1 = require("telegram");
|
|
7
|
+
const EvogramGramJS_1 = require("../EvogramGramJS");
|
|
8
|
+
const ImageUploadService_1 = require("../services/ImageUploadService");
|
|
9
|
+
const auth_types_1 = require("../types/auth.types");
|
|
10
|
+
const Deferrer_1 = require("../utils/Deferrer");
|
|
11
|
+
/**
|
|
12
|
+
* События авторизации для сессии
|
|
13
|
+
*/
|
|
14
|
+
var SessionAuthEvent;
|
|
15
|
+
(function (SessionAuthEvent) {
|
|
16
|
+
/** Начало авторизации */
|
|
17
|
+
SessionAuthEvent["AUTH_STARTED"] = "auth:started";
|
|
18
|
+
/** Код отправлен */
|
|
19
|
+
SessionAuthEvent["CODE_SENT"] = "auth:code_sent";
|
|
20
|
+
/** Код получен */
|
|
21
|
+
SessionAuthEvent["CODE_RECEIVED"] = "auth:code_received";
|
|
22
|
+
/** Требуется пароль */
|
|
23
|
+
SessionAuthEvent["PASSWORD_REQUIRED"] = "auth:password_required";
|
|
24
|
+
/** Авторизация успешна */
|
|
25
|
+
SessionAuthEvent["AUTH_SUCCESS"] = "auth:success";
|
|
26
|
+
/** Ошибка авторизации */
|
|
27
|
+
SessionAuthEvent["AUTH_ERROR"] = "auth:error";
|
|
28
|
+
/** Авторизация отменена */
|
|
29
|
+
SessionAuthEvent["AUTH_CANCELLED"] = "auth:cancelled";
|
|
30
|
+
})(SessionAuthEvent || (exports.SessionAuthEvent = SessionAuthEvent = {}));
|
|
31
|
+
/**
|
|
32
|
+
* Класс авторизации для конкретной сессии
|
|
33
|
+
* Предоставляет методы авторизации, привязанные к сессии
|
|
34
|
+
*/
|
|
35
|
+
class SessionAuth extends events_1.EventEmitter {
|
|
36
|
+
constructor(sessionId, client, logger) {
|
|
37
|
+
super();
|
|
38
|
+
this.sessionId = sessionId;
|
|
39
|
+
this.client = client;
|
|
40
|
+
this.logger = logger;
|
|
41
|
+
this.state = null;
|
|
42
|
+
}
|
|
43
|
+
start(phoneNumber) {
|
|
44
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
if (this.state)
|
|
46
|
+
throw new Error(`Авторизация для сессии "${this.sessionId}" уже начата`);
|
|
47
|
+
this.state = {
|
|
48
|
+
code: new Deferrer_1.Deferred(),
|
|
49
|
+
password: new Deferrer_1.Deferred(),
|
|
50
|
+
isRequiredPassword: false,
|
|
51
|
+
stage: auth_types_1.AuthState.INITIAL,
|
|
52
|
+
connect: new Deferrer_1.Deferred(),
|
|
53
|
+
};
|
|
54
|
+
try {
|
|
55
|
+
yield new Promise((res, rej) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
yield this.client
|
|
57
|
+
.start({
|
|
58
|
+
phoneNumber,
|
|
59
|
+
phoneCode: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
res(true);
|
|
61
|
+
this.state.stage = auth_types_1.AuthState.WAITING_CODE;
|
|
62
|
+
const code = yield this.state.code.promise;
|
|
63
|
+
this.state.code = new Deferrer_1.Deferred();
|
|
64
|
+
return code;
|
|
65
|
+
}),
|
|
66
|
+
password: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
this.state.isRequiredPassword = true;
|
|
68
|
+
this.state.stage = auth_types_1.AuthState.WAITING_PASSWORD;
|
|
69
|
+
const password = yield this.state.password.promise;
|
|
70
|
+
this.state.password = new Deferrer_1.Deferred();
|
|
71
|
+
return password;
|
|
72
|
+
}),
|
|
73
|
+
onError: (error) => {
|
|
74
|
+
this.state.stage = auth_types_1.AuthState.ERROR;
|
|
75
|
+
this.emit(SessionAuthEvent.AUTH_ERROR, {
|
|
76
|
+
sessionId: this.sessionId,
|
|
77
|
+
error: error instanceof Error ? error.message : String(error),
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
.catch(rej);
|
|
82
|
+
try {
|
|
83
|
+
const me = yield this.client.getMe();
|
|
84
|
+
this.state.connect.resolve(true);
|
|
85
|
+
let avatarBuffer = yield this.client.downloadProfilePhoto('me'), avatarUrl;
|
|
86
|
+
if (avatarBuffer)
|
|
87
|
+
avatarUrl = yield ImageUploadService_1.ImageUploadService.uploadToImgbox(Buffer.isBuffer(avatarBuffer) ? avatarBuffer : Buffer.from(avatarBuffer));
|
|
88
|
+
yield EvogramGramJS_1.EvogramGramJS.databaseService.saveSession({
|
|
89
|
+
sessionId: this.sessionId,
|
|
90
|
+
apiId: this.client.apiId,
|
|
91
|
+
apiHash: this.client.apiHash,
|
|
92
|
+
userId: Number(me.id),
|
|
93
|
+
username: me.username,
|
|
94
|
+
firstName: me.firstName,
|
|
95
|
+
lastName: me.lastName,
|
|
96
|
+
phoneNumber: me.phone,
|
|
97
|
+
sessionString: this.client.session.save(),
|
|
98
|
+
avatarUrl,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (_a) { }
|
|
102
|
+
}));
|
|
103
|
+
return {
|
|
104
|
+
success: true,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
this.emit(SessionAuthEvent.AUTH_ERROR, {
|
|
109
|
+
sessionId: this.sessionId,
|
|
110
|
+
error: error instanceof Error ? error.message : String(error),
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
setCode(code) {
|
|
120
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
if (!this.state)
|
|
122
|
+
throw new Error(`Авторизация для сессии "${this.sessionId}" не начата`);
|
|
123
|
+
const errorPromise = new Promise((resolve, reject) => {
|
|
124
|
+
this.once(SessionAuthEvent.AUTH_ERROR, (data) => data.sessionId === this.sessionId && resolve(data.error));
|
|
125
|
+
setTimeout(resolve, 1000);
|
|
126
|
+
});
|
|
127
|
+
this.state.code.resolve(code);
|
|
128
|
+
const error = yield errorPromise;
|
|
129
|
+
return {
|
|
130
|
+
success: error ? false : true,
|
|
131
|
+
error: error || undefined,
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
setPassword(password) {
|
|
136
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
if (!this.state)
|
|
138
|
+
throw new Error(`Авторизация для сессии "${this.sessionId}" не начата`);
|
|
139
|
+
const errorPromise = new Promise((resolve, reject) => {
|
|
140
|
+
this.once(SessionAuthEvent.AUTH_ERROR, (data) => data.sessionId === this.sessionId && resolve(data.error));
|
|
141
|
+
setTimeout(resolve, 1000);
|
|
142
|
+
});
|
|
143
|
+
this.state.password.resolve(password);
|
|
144
|
+
const error = yield errorPromise;
|
|
145
|
+
return {
|
|
146
|
+
success: error ? false : true,
|
|
147
|
+
error: error || undefined,
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Начинает авторизацию через QR-код
|
|
153
|
+
*
|
|
154
|
+
* @param onQRCode Callback для обработки QR-кода (получает URL и токен)
|
|
155
|
+
* @returns Promise с результатом авторизации
|
|
156
|
+
*/
|
|
157
|
+
startWithQRCode(onQRCode) {
|
|
158
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
159
|
+
var _a, _b, _c, _d;
|
|
160
|
+
console.log(`[QR-AUTH] Начало метода startWithQRCode для сессии "${this.sessionId}"`);
|
|
161
|
+
console.log(`[QR-AUTH] Текущее состояние state:`, this.state ? 'уже инициализировано' : 'null');
|
|
162
|
+
if (this.state)
|
|
163
|
+
throw new Error(`Авторизация для сессии "${this.sessionId}" уже начата`);
|
|
164
|
+
console.log(`[QR-AUTH] Инициализация state для сессии "${this.sessionId}"`);
|
|
165
|
+
this.state = {
|
|
166
|
+
code: new Deferrer_1.Deferred(),
|
|
167
|
+
password: new Deferrer_1.Deferred(),
|
|
168
|
+
isRequiredPassword: false,
|
|
169
|
+
stage: auth_types_1.AuthState.INITIAL,
|
|
170
|
+
connect: new Deferrer_1.Deferred(),
|
|
171
|
+
};
|
|
172
|
+
console.log(`[QR-AUTH] State успешно инициализирован:`, {
|
|
173
|
+
stage: this.state.stage,
|
|
174
|
+
isRequiredPassword: this.state.isRequiredPassword,
|
|
175
|
+
});
|
|
176
|
+
try {
|
|
177
|
+
console.log(`[QR-AUTH] Получение API credentials для клиента`);
|
|
178
|
+
const apiCredentials = {
|
|
179
|
+
apiId: this.client.apiId,
|
|
180
|
+
apiHash: this.client.apiHash,
|
|
181
|
+
};
|
|
182
|
+
console.log(`[QR-AUTH] API credentials:`, {
|
|
183
|
+
apiId: apiCredentials.apiId,
|
|
184
|
+
apiHashLength: ((_a = apiCredentials.apiHash) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
185
|
+
});
|
|
186
|
+
console.log(`[QR-AUTH] Смена стадии на WAITING_CODE`);
|
|
187
|
+
this.state.stage = auth_types_1.AuthState.WAITING_CODE;
|
|
188
|
+
console.log(`[QR-AUTH] Текущая стадия:`, this.state.stage);
|
|
189
|
+
console.log(`[QR-AUTH] Вызов client.signInUserWithQrCode для сессии "${this.sessionId}"`);
|
|
190
|
+
const user = yield this.client.signInUserWithQrCode(apiCredentials, {
|
|
191
|
+
qrCode: (qrCode) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
192
|
+
var _a;
|
|
193
|
+
console.log(`[QR-AUTH] Получен QR-код callback для сессии "${this.sessionId}"`);
|
|
194
|
+
console.log(`[QR-AUTH] QR-код объект:`, {
|
|
195
|
+
tokenLength: ((_a = qrCode.token) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
196
|
+
expires: qrCode.expires,
|
|
197
|
+
expiresDate: new Date(qrCode.expires * 1000).toISOString(),
|
|
198
|
+
});
|
|
199
|
+
const qrToken = qrCode.token.toString('base64url');
|
|
200
|
+
console.log(`[QR-AUTH] QR token (base64url):`, qrToken);
|
|
201
|
+
const qrUrl = `tg://login?token=${qrToken}`;
|
|
202
|
+
console.log(`[QR-AUTH] QR URL:`, qrUrl);
|
|
203
|
+
console.log(`[QR-AUTH] Вызов onQRCode callback`);
|
|
204
|
+
yield onQRCode(qrUrl, qrToken, qrCode.expires);
|
|
205
|
+
console.log(`[QR-AUTH] onQRCode callback выполнен успешно`);
|
|
206
|
+
}),
|
|
207
|
+
password: (hint) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
console.log(`[QR-AUTH] Запрошен пароль для сессии "${this.sessionId}"`);
|
|
209
|
+
console.log(`[QR-AUTH] Password hint:`, hint);
|
|
210
|
+
this.state.isRequiredPassword = true;
|
|
211
|
+
this.state.stage = auth_types_1.AuthState.WAITING_PASSWORD;
|
|
212
|
+
console.log(`[QR-AUTH] Состояние обновлено:`, {
|
|
213
|
+
stage: this.state.stage,
|
|
214
|
+
isRequiredPassword: this.state.isRequiredPassword,
|
|
215
|
+
});
|
|
216
|
+
console.log(`[QR-AUTH] Ожидание password promise`);
|
|
217
|
+
const password = yield this.state.password.promise;
|
|
218
|
+
console.log(`[QR-AUTH] Password получен, длина:`, (password === null || password === void 0 ? void 0 : password.length) || 0);
|
|
219
|
+
this.state.password = new Deferrer_1.Deferred();
|
|
220
|
+
console.log(`[QR-AUTH] Password promise сброшен`);
|
|
221
|
+
return password;
|
|
222
|
+
}),
|
|
223
|
+
onError: (error) => {
|
|
224
|
+
var _a;
|
|
225
|
+
console.log(`[QR-AUTH] ❌ Ошибка в callback onError для сессии "${this.sessionId}"`);
|
|
226
|
+
console.log(`[QR-AUTH] Тип ошибки:`, (_a = error === null || error === void 0 ? void 0 : error.constructor) === null || _a === void 0 ? void 0 : _a.name);
|
|
227
|
+
console.log(`[QR-AUTH] Сообщение ошибки:`, error instanceof Error ? error.message : String(error));
|
|
228
|
+
console.log(`[QR-AUTH] Stack trace:`, error instanceof Error ? error.stack : 'N/A');
|
|
229
|
+
this.state.stage = auth_types_1.AuthState.ERROR;
|
|
230
|
+
console.log(`[QR-AUTH] Стадия изменена на ERROR`);
|
|
231
|
+
this.emit(SessionAuthEvent.AUTH_ERROR, {
|
|
232
|
+
sessionId: this.sessionId,
|
|
233
|
+
error: error instanceof Error ? error.message : String(error),
|
|
234
|
+
});
|
|
235
|
+
console.log(`[QR-AUTH] Событие AUTH_ERROR отправлено`);
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
console.log(`[QR-AUTH] ✅ signInUserWithQrCode завершен для сессии "${this.sessionId}"`);
|
|
239
|
+
console.log(`[QR-AUTH] Полученный user объект:`, {
|
|
240
|
+
type: (_b = user === null || user === void 0 ? void 0 : user.constructor) === null || _b === void 0 ? void 0 : _b.name,
|
|
241
|
+
isApiUser: user instanceof telegram_1.Api.User,
|
|
242
|
+
});
|
|
243
|
+
// Проверяем, что это реальный пользователь
|
|
244
|
+
if (!(user instanceof telegram_1.Api.User)) {
|
|
245
|
+
console.log(`[QR-AUTH] ❌ Неверный тип пользователя:`, (_c = user === null || user === void 0 ? void 0 : user.constructor) === null || _c === void 0 ? void 0 : _c.name);
|
|
246
|
+
throw new Error('Получен неверный тип пользователя');
|
|
247
|
+
}
|
|
248
|
+
this.state.stage = auth_types_1.AuthState.AUTHORIZED;
|
|
249
|
+
this.state.connect.resolve(true);
|
|
250
|
+
// Сохраняем сессию в базу данных
|
|
251
|
+
console.log(`[QR-AUTH] Начало сохранения сессии в БД`);
|
|
252
|
+
try {
|
|
253
|
+
let avatarBuffer = yield this.client.downloadProfilePhoto('me'), avatarUrl;
|
|
254
|
+
if (avatarBuffer) {
|
|
255
|
+
console.log(`[QR-AUTH] Загрузка аватара на Imgbox`);
|
|
256
|
+
avatarUrl = yield ImageUploadService_1.ImageUploadService.uploadToImgbox(Buffer.isBuffer(avatarBuffer) ? avatarBuffer : Buffer.from(avatarBuffer)).catch(() => null);
|
|
257
|
+
console.log(`[QR-AUTH] Аватар загружен на Imgbox:`, avatarUrl);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
console.log(`[QR-AUTH] Аватар отсутствует, пропускаем загрузку`);
|
|
261
|
+
}
|
|
262
|
+
const sessionString = this.client.session.save();
|
|
263
|
+
const sessionData = {
|
|
264
|
+
sessionId: this.sessionId,
|
|
265
|
+
apiId: this.client.apiId,
|
|
266
|
+
apiHash: this.client.apiHash,
|
|
267
|
+
userId: Number(user.id),
|
|
268
|
+
username: user.username,
|
|
269
|
+
firstName: user.firstName,
|
|
270
|
+
lastName: user.lastName,
|
|
271
|
+
phoneNumber: user.phone,
|
|
272
|
+
sessionString: sessionString,
|
|
273
|
+
avatarUrl,
|
|
274
|
+
};
|
|
275
|
+
yield EvogramGramJS_1.EvogramGramJS.databaseService.saveSession(sessionData);
|
|
276
|
+
}
|
|
277
|
+
catch (saveError) {
|
|
278
|
+
console.log(`[QR-AUTH] ⚠️ Ошибка при сохранении сессии в БД:`, {
|
|
279
|
+
error: saveError instanceof Error ? saveError.message : String(saveError),
|
|
280
|
+
stack: saveError instanceof Error ? saveError.stack : 'N/A',
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
console.log(`[QR-AUTH] Отправка события AUTH_SUCCESS`);
|
|
284
|
+
this.emit(SessionAuthEvent.AUTH_SUCCESS, {
|
|
285
|
+
sessionId: this.sessionId,
|
|
286
|
+
});
|
|
287
|
+
console.log(`[QR-AUTH] ✅ Авторизация через QR-код успешно завершена для сессии "${this.sessionId}"`);
|
|
288
|
+
return {
|
|
289
|
+
success: true,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
console.log(`[QR-AUTH] ❌ Критическая ошибка в startWithQRCode для сессии "${this.sessionId}"`);
|
|
294
|
+
console.log(`[QR-AUTH] Тип ошибки:`, (_d = error === null || error === void 0 ? void 0 : error.constructor) === null || _d === void 0 ? void 0 : _d.name);
|
|
295
|
+
console.log(`[QR-AUTH] Сообщение ошибки:`, error instanceof Error ? error.message : String(error));
|
|
296
|
+
console.log(`[QR-AUTH] Stack trace:`, error instanceof Error ? error.stack : 'N/A');
|
|
297
|
+
console.log(`[QR-AUTH] Полный объект ошибки:`, error);
|
|
298
|
+
this.state.stage = auth_types_1.AuthState.ERROR;
|
|
299
|
+
console.log(`[QR-AUTH] Стадия изменена на ERROR`);
|
|
300
|
+
this.emit(SessionAuthEvent.AUTH_ERROR, {
|
|
301
|
+
sessionId: this.sessionId,
|
|
302
|
+
error: error instanceof Error ? error.message : String(error),
|
|
303
|
+
});
|
|
304
|
+
console.log(`[QR-AUTH] Событие AUTH_ERROR отправлено`);
|
|
305
|
+
return {
|
|
306
|
+
success: false,
|
|
307
|
+
error: error instanceof Error ? error.message : String(error),
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Проверяет, требуется ли пароль для авторизации
|
|
314
|
+
*
|
|
315
|
+
* @returns true, если требуется пароль
|
|
316
|
+
*/
|
|
317
|
+
isRequiredPassword() {
|
|
318
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
319
|
+
var _a, _b, _c;
|
|
320
|
+
if ((_a = this.state) === null || _a === void 0 ? void 0 : _a.isRequiredPassword)
|
|
321
|
+
return true;
|
|
322
|
+
yield new Promise((resolve) => setTimeout(resolve, 1000));
|
|
323
|
+
return (_c = (_b = this.state) === null || _b === void 0 ? void 0 : _b.isRequiredPassword) !== null && _c !== void 0 ? _c : false;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
exports.SessionAuth = SessionAuth;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Логгер для отдельной сессии
|
|
3
|
+
* Записывает все действия и активность сессии в отдельный файл
|
|
4
|
+
*/
|
|
5
|
+
export declare class SessionLogger {
|
|
6
|
+
private readonly sessionId;
|
|
7
|
+
private readonly logsDirectory;
|
|
8
|
+
private logStream;
|
|
9
|
+
private logFilePath;
|
|
10
|
+
private isInitialized;
|
|
11
|
+
/**
|
|
12
|
+
* @param sessionId Идентификатор сессии
|
|
13
|
+
* @param logsDirectory Директория для хранения логов (по умолчанию './logs')
|
|
14
|
+
*/
|
|
15
|
+
constructor(sessionId: string, logsDirectory?: string);
|
|
16
|
+
/**
|
|
17
|
+
* Инициализирует логгер (создает директорию и файл)
|
|
18
|
+
*/
|
|
19
|
+
initialize(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Записывает лог-запись в файл
|
|
22
|
+
*
|
|
23
|
+
* @param level Уровень логирования (INFO, WARN, ERROR, DEBUG)
|
|
24
|
+
* @param message Сообщение для логирования
|
|
25
|
+
* @param data Дополнительные данные (опционально)
|
|
26
|
+
*/
|
|
27
|
+
log(level: 'INFO' | 'WARN' | 'ERROR' | 'DEBUG', message: string, data?: any): void;
|
|
28
|
+
/**
|
|
29
|
+
* Логирует информацию
|
|
30
|
+
*/
|
|
31
|
+
info(message: string, data?: any): void;
|
|
32
|
+
/**
|
|
33
|
+
* Логирует предупреждение
|
|
34
|
+
*/
|
|
35
|
+
warn(message: string, data?: any): void;
|
|
36
|
+
/**
|
|
37
|
+
* Логирует ошибку
|
|
38
|
+
*/
|
|
39
|
+
error(message: string, error?: Error | any): void;
|
|
40
|
+
/**
|
|
41
|
+
* Логирует отладочную информацию
|
|
42
|
+
*/
|
|
43
|
+
debug(message: string, data?: any): void;
|
|
44
|
+
/**
|
|
45
|
+
* Логирует действие сессии
|
|
46
|
+
*
|
|
47
|
+
* @param action Название действия
|
|
48
|
+
* @param details Детали действия
|
|
49
|
+
*/
|
|
50
|
+
logAction(action: string, details?: any): void;
|
|
51
|
+
/**
|
|
52
|
+
* Логирует событие от Telegram клиента
|
|
53
|
+
*
|
|
54
|
+
* @param eventName Название события
|
|
55
|
+
* @param eventData Данные события
|
|
56
|
+
*/
|
|
57
|
+
logTelegramEvent(eventName: string, eventData?: any): void;
|
|
58
|
+
/**
|
|
59
|
+
* Закрывает поток записи
|
|
60
|
+
*/
|
|
61
|
+
close(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Получает путь к файлу лога
|
|
64
|
+
*/
|
|
65
|
+
getLogFilePath(): string;
|
|
66
|
+
/**
|
|
67
|
+
* Внутренний метод для записи в файл
|
|
68
|
+
*
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
private writeLog;
|
|
72
|
+
/**
|
|
73
|
+
* Форматирует запись лога для записи в файл
|
|
74
|
+
*
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
private formatLogEntry;
|
|
78
|
+
/**
|
|
79
|
+
* Очищает имя файла от недопустимых символов
|
|
80
|
+
*
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
private sanitizeFileName;
|
|
84
|
+
}
|