waengine 1.7.3 → 1.7.4

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.
@@ -0,0 +1,314 @@
1
+ // Session Manager für WAEngine v1.0.6
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+
5
+ export class SessionManager {
6
+ constructor(authDir) {
7
+ this.authDir = authDir;
8
+ }
9
+
10
+ // Prüft ob Session existiert und gültig ist
11
+ async validateSession() {
12
+ try {
13
+ if (!fs.existsSync(this.authDir)) {
14
+ return { valid: false, reason: 'no_auth_dir' };
15
+ }
16
+
17
+ const credsPath = path.join(this.authDir, 'creds.json');
18
+ if (!fs.existsSync(credsPath)) {
19
+ return { valid: false, reason: 'no_creds' };
20
+ }
21
+
22
+ // Robuste JSON-Validierung mit mehreren Fallbacks
23
+ let creds;
24
+ let fileContent;
25
+
26
+ try {
27
+ fileContent = fs.readFileSync(credsPath, 'utf8');
28
+
29
+ // Prüfe ob Datei leer oder zu kurz ist
30
+ if (!fileContent || fileContent.trim().length < 10) {
31
+ console.error('❌ creds.json ist leer oder zu kurz');
32
+ return { valid: false, reason: 'empty_creds' };
33
+ }
34
+
35
+ // Prüfe auf unvollständige JSON (häufiger Fehler)
36
+ if (!fileContent.trim().endsWith('}') && !fileContent.trim().endsWith(']')) {
37
+ console.error('❌ creds.json ist unvollständig (fehlendes Ende)');
38
+ return { valid: false, reason: 'incomplete_creds' };
39
+ }
40
+
41
+ // Versuche JSON zu parsen
42
+ creds = JSON.parse(fileContent);
43
+
44
+ } catch (jsonError) {
45
+ console.error('❌ Fehler beim Lesen der creds.json:', jsonError.message);
46
+
47
+ // Versuche Backup-Recovery
48
+ const backupRecovered = await this.tryRecoverFromBackup();
49
+ if (backupRecovered) {
50
+ console.log('✅ Session aus Backup wiederhergestellt');
51
+ return await this.validateSession(); // Rekursiv nach Recovery
52
+ }
53
+
54
+ // Erstelle Backup der korrupten Datei für Debugging
55
+ await this.backupCorruptedFile(credsPath, fileContent);
56
+
57
+ return { valid: false, reason: 'corrupted_creds', error: jsonError.message };
58
+ }
59
+
60
+ // Prüfe ob User-ID vorhanden (eingeloggt)
61
+ if (!creds || typeof creds !== 'object') {
62
+ return { valid: false, reason: 'invalid_creds_format' };
63
+ }
64
+
65
+ if (!creds.me?.id) {
66
+ return { valid: false, reason: 'not_logged_in' };
67
+ }
68
+
69
+ // Prüfe ob Session nicht zu alt ist (optional)
70
+ const stats = fs.statSync(credsPath);
71
+ const ageInDays = (Date.now() - stats.mtime.getTime()) / (1000 * 60 * 60 * 24);
72
+
73
+ if (ageInDays > 30) { // Session älter als 30 Tage
74
+ return { valid: false, reason: 'session_too_old' };
75
+ }
76
+
77
+ return {
78
+ valid: true,
79
+ userId: creds.me.id,
80
+ lastModified: stats.mtime,
81
+ ageInDays: Math.round(ageInDays)
82
+ };
83
+
84
+ } catch (error) {
85
+ console.error('❌ Session-Validierung Fehler:', error);
86
+ return { valid: false, reason: 'validation_error', error: error.message };
87
+ }
88
+ }
89
+
90
+ // Bereinigt Session komplett
91
+ async cleanupSession() {
92
+ try {
93
+ if (fs.existsSync(this.authDir)) {
94
+ console.log("🧹 Bereinige Session...");
95
+
96
+ // Alle Auth-Dateien löschen
97
+ const files = fs.readdirSync(this.authDir);
98
+ for (const file of files) {
99
+ const filePath = path.join(this.authDir, file);
100
+ fs.unlinkSync(filePath);
101
+ }
102
+
103
+ // Auth-Ordner löschen
104
+ fs.rmdirSync(this.authDir);
105
+ console.log("✅ Session bereinigt");
106
+ return true;
107
+ }
108
+ return true;
109
+ } catch (error) {
110
+ console.error("❌ Fehler beim Session-Cleanup:", error);
111
+ return false;
112
+ }
113
+ }
114
+
115
+ // Erstellt Auth-Ordner falls nicht vorhanden
116
+ async ensureAuthDir() {
117
+ if (!fs.existsSync(this.authDir)) {
118
+ fs.mkdirSync(this.authDir, { recursive: true });
119
+ console.log(`📁 Auth-Ordner erstellt: ${this.authDir}`);
120
+ }
121
+ }
122
+
123
+ // Backup der Session erstellen
124
+ async backupSession() {
125
+ try {
126
+ if (!fs.existsSync(this.authDir)) return false;
127
+
128
+ const backupDir = `${this.authDir}_backup_${Date.now()}`;
129
+ fs.mkdirSync(backupDir, { recursive: true });
130
+
131
+ const files = fs.readdirSync(this.authDir);
132
+ for (const file of files) {
133
+ const srcPath = path.join(this.authDir, file);
134
+ const destPath = path.join(backupDir, file);
135
+ fs.copyFileSync(srcPath, destPath);
136
+ }
137
+
138
+ console.log(`💾 Session-Backup erstellt: ${backupDir}`);
139
+ return backupDir;
140
+ } catch (error) {
141
+ console.error("❌ Backup-Fehler:", error);
142
+ return false;
143
+ }
144
+ }
145
+
146
+ // Session-Status für Debugging
147
+ getSessionStatus() {
148
+ try {
149
+ if (!fs.existsSync(this.authDir)) {
150
+ return { status: 'no_session', files: [] };
151
+ }
152
+
153
+ const files = fs.readdirSync(this.authDir);
154
+ const fileDetails = files.map(file => {
155
+ const filePath = path.join(this.authDir, file);
156
+ const stats = fs.statSync(filePath);
157
+ return {
158
+ name: file,
159
+ size: stats.size,
160
+ modified: stats.mtime
161
+ };
162
+ });
163
+
164
+ return {
165
+ status: 'session_exists',
166
+ files: fileDetails,
167
+ totalFiles: files.length,
168
+ authDir: this.authDir
169
+ };
170
+ } catch (error) {
171
+ return { status: 'error', error: error.message };
172
+ }
173
+ }
174
+
175
+ // Repariert korrupte Session
176
+ async repairSession() {
177
+ console.log("🔧 Versuche Session-Reparatur...");
178
+
179
+ const validation = await this.validateSession();
180
+
181
+ if (validation.reason === 'corrupted') {
182
+ console.log("🗑️ Korrupte Session erkannt - bereinige...");
183
+ await this.cleanupSession();
184
+ return { repaired: true, action: 'cleanup' };
185
+ }
186
+
187
+ if (validation.reason === 'session_too_old') {
188
+ console.log("⏰ Session zu alt - bereinige...");
189
+ await this.cleanupSession();
190
+ return { repaired: true, action: 'cleanup_old' };
191
+ }
192
+
193
+ return { repaired: false, reason: validation.reason };
194
+ }
195
+
196
+ // Versucht Session aus Backup wiederherzustellen
197
+ async tryRecoverFromBackup() {
198
+ try {
199
+ const backupPattern = `${this.authDir}_backup_`;
200
+ const parentDir = path.dirname(this.authDir);
201
+
202
+ if (!fs.existsSync(parentDir)) return false;
203
+
204
+ const entries = fs.readdirSync(parentDir);
205
+ const backupDirs = entries
206
+ .filter(entry => entry.startsWith(path.basename(backupPattern)))
207
+ .map(entry => ({
208
+ path: path.join(parentDir, entry),
209
+ timestamp: parseInt(entry.split('_').pop()) || 0
210
+ }))
211
+ .sort((a, b) => b.timestamp - a.timestamp); // Neueste zuerst
212
+
213
+ for (const backup of backupDirs) {
214
+ const backupCredsPath = path.join(backup.path, 'creds.json');
215
+
216
+ if (fs.existsSync(backupCredsPath)) {
217
+ try {
218
+ // Teste ob Backup-JSON gültig ist
219
+ const backupContent = fs.readFileSync(backupCredsPath, 'utf8');
220
+ const testCreds = JSON.parse(backupContent);
221
+
222
+ if (testCreds.me?.id) {
223
+ // Backup ist gültig - stelle wieder her
224
+ console.log(`🔄 Stelle Session aus Backup wieder her: ${backup.path}`);
225
+
226
+ // Kopiere alle Backup-Dateien zurück
227
+ const backupFiles = fs.readdirSync(backup.path);
228
+ for (const file of backupFiles) {
229
+ const srcPath = path.join(backup.path, file);
230
+ const destPath = path.join(this.authDir, file);
231
+ fs.copyFileSync(srcPath, destPath);
232
+ }
233
+
234
+ return true;
235
+ }
236
+ } catch (backupError) {
237
+ console.log(`⚠️ Backup ${backup.path} ist auch korrupt`);
238
+ continue;
239
+ }
240
+ }
241
+ }
242
+
243
+ return false;
244
+ } catch (error) {
245
+ console.error('❌ Backup-Recovery Fehler:', error);
246
+ return false;
247
+ }
248
+ }
249
+
250
+ // Erstellt Backup der korrupten Datei für Debugging
251
+ async backupCorruptedFile(credsPath, content) {
252
+ try {
253
+ const timestamp = Date.now();
254
+ const corruptedDir = `${this.authDir}_corrupted_${timestamp}`;
255
+
256
+ fs.mkdirSync(corruptedDir, { recursive: true });
257
+
258
+ // Korrupte Datei sichern
259
+ fs.writeFileSync(path.join(corruptedDir, 'creds.json'), content);
260
+
261
+ // Debug-Info hinzufügen
262
+ const debugInfo = {
263
+ timestamp: new Date().toISOString(),
264
+ fileSize: content.length,
265
+ firstChars: content.substring(0, 100),
266
+ lastChars: content.substring(Math.max(0, content.length - 100)),
267
+ error: 'JSON parse failed'
268
+ };
269
+
270
+ fs.writeFileSync(
271
+ path.join(corruptedDir, 'debug-info.json'),
272
+ JSON.stringify(debugInfo, null, 2)
273
+ );
274
+
275
+ console.log(`🗂️ Korrupte Datei gesichert: ${corruptedDir}`);
276
+ } catch (error) {
277
+ console.error('❌ Fehler beim Sichern der korrupten Datei:', error);
278
+ }
279
+ }
280
+
281
+ // Automatische Session-Reparatur mit erweiterten Optionen
282
+ async autoRepairSession() {
283
+ console.log("🔧 Starte automatische Session-Reparatur...");
284
+
285
+ const validation = await this.validateSession();
286
+
287
+ switch (validation.reason) {
288
+ case 'corrupted_creds':
289
+ case 'empty_creds':
290
+ case 'incomplete_creds':
291
+ console.log("🗑️ Korrupte Session erkannt - bereinige...");
292
+ await this.cleanupSession();
293
+ return { repaired: true, action: 'cleanup_corrupted' };
294
+
295
+ case 'session_too_old':
296
+ console.log("⏰ Session zu alt - bereinige...");
297
+ await this.cleanupSession();
298
+ return { repaired: true, action: 'cleanup_old' };
299
+
300
+ case 'not_logged_in':
301
+ console.log("👤 Nicht eingeloggt - Session bereinigen...");
302
+ await this.cleanupSession();
303
+ return { repaired: true, action: 'cleanup_not_logged_in' };
304
+
305
+ case 'no_creds':
306
+ console.log("📄 Keine Credentials - Auth-Ordner vorbereiten...");
307
+ await this.ensureAuthDir();
308
+ return { repaired: true, action: 'prepare_auth_dir' };
309
+
310
+ default:
311
+ return { repaired: false, reason: validation.reason };
312
+ }
313
+ }
314
+ }