waengine 1.1.2 → 1.7.3

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/src/qr.js CHANGED
@@ -1,115 +1,435 @@
1
- import { chromium } from "playwright";
2
1
  import qrcode from "qrcode-terminal";
2
+ import { exec } from "child_process";
3
+ import { promisify } from "util";
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import os from "os";
7
+
8
+ const execAsync = promisify(exec);
3
9
 
4
10
  let browser = null;
5
11
  let page = null;
12
+ let httpServer = null;
13
+ let lastQRTime = 0;
14
+ let qrDisplayCount = 0;
15
+ let isQRDisplayed = false;
16
+
17
+ // Cross-Platform Browser Detection
18
+ const BROWSERS = {
19
+ windows: [
20
+ 'msedge.exe',
21
+ 'chrome.exe',
22
+ 'firefox.exe',
23
+ 'brave.exe',
24
+ 'opera.exe'
25
+ ],
26
+ darwin: [
27
+ '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
28
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
29
+ '/Applications/Firefox.app/Contents/MacOS/firefox',
30
+ '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser',
31
+ '/Applications/Safari.app/Contents/MacOS/Safari'
32
+ ],
33
+ linux: [
34
+ 'microsoft-edge',
35
+ 'google-chrome',
36
+ 'chromium-browser',
37
+ 'firefox',
38
+ 'brave-browser',
39
+ 'opera'
40
+ ]
41
+ };
6
42
 
7
43
  export async function generateQRCode(qrData = null) {
8
44
  try {
9
- // QR-Code im Terminal anzeigen falls vorhanden
10
- if (qrData) {
11
- console.log("\n📱 QR-CODE GENERIERT!");
12
- console.log("👆 Scanne den QR-Code hier im Terminal:");
13
- console.log("─".repeat(50));
45
+ // QR-Spam Prevention - nur alle 30 Sekunden im Terminal anzeigen
46
+ const now = Date.now();
47
+ const timeSinceLastQR = now - lastQRTime;
48
+ const shouldShowTerminalQR = timeSinceLastQR > 30000 || qrDisplayCount === 0;
49
+
50
+ if (qrData && shouldShowTerminalQR) {
51
+ console.clear(); // Terminal leeren für saubere Anzeige
52
+ console.log("\n" + "=".repeat(60));
53
+ console.log("📱 WAEngine QR-CODE - SCAN EINMAL UND FERTIG!");
54
+ console.log("=".repeat(60));
14
55
 
15
56
  // QR-Code im Terminal anzeigen
16
57
  qrcode.generate(qrData, { small: true });
17
58
 
18
- console.log("".repeat(50));
19
- console.log("📲 Öffne WhatsApp auf deinem Handy:");
20
- console.log(" 1. Gehe zu Einstellungen");
21
- console.log(" 2. Tippe auf 'Verknüpfte Geräte'");
22
- console.log(" 3. Tippe auf 'Gerät verknüpfen'");
23
- console.log(" 4. Scanne den QR-Code OBEN im Terminal");
24
- console.log(" Warte auf QR-Scan...");
25
- }
26
-
27
- // Browser öffnen und den richtigen QR-Code anzeigen
28
- if (!browser && qrData) {
29
- console.log("🌐 Öffne Browser mit korrektem QR-Code...");
30
- browser = await chromium.launch({
31
- channel: "msedge",
32
- headless: false
33
- });
59
+ console.log("=".repeat(60));
60
+ console.log("📲 WhatsApp Anleitung:");
61
+ console.log(" 1. Öffne WhatsApp auf deinem Handy");
62
+ console.log(" 2. Gehe zu Einstellungen (⚙️)");
63
+ console.log(" 3. Tippe auf 'Verknüpfte Geräte'");
64
+ console.log(" 4. Tippe auf 'Gerät verknüpfen'");
65
+ console.log(" 5. Scanne den QR-Code OBEN");
66
+ console.log("=".repeat(60));
67
+ console.log(`⏳ Warte auf QR-Scan... (${qrDisplayCount + 1}. Versuch)`);
68
+ console.log("💡 QR-Code wird auch im Browser angezeigt!");
69
+ console.log("");
70
+
71
+ lastQRTime = now;
72
+ qrDisplayCount++;
73
+ isQRDisplayed = true;
74
+ } else if (qrData && !shouldShowTerminalQR) {
75
+ // Nur kurze Info ohne QR-Spam
76
+ console.log(`🔄 QR-Code aktualisiert (${qrDisplayCount + 1}. Mal) - Browser verwenden oder 30s warten`);
77
+ qrDisplayCount++;
78
+ }
79
+
80
+ // Browser QR immer versuchen (weniger störend)
81
+ if (qrData) {
82
+ await openUniversalBrowser(qrData);
83
+ }
84
+
85
+ return { browser, page };
86
+
87
+ } catch (error) {
88
+ console.error("❌ QR-System Fehler:", error.message);
89
+
90
+ // Fallback nur bei erstem Mal
91
+ if (qrData && qrDisplayCount === 0) {
92
+ console.log("📱 Terminal QR-Code verfügbar (siehe oben)");
93
+ qrDisplayCount++;
94
+ }
95
+
96
+ return null;
97
+ }
98
+ }
99
+
100
+ // QR-Code Status zurücksetzen (für neue Sessions)
101
+ export function resetQRStatus() {
102
+ lastQRTime = 0;
103
+ qrDisplayCount = 0;
104
+ isQRDisplayed = false;
105
+ console.log("🔄 QR-Status zurückgesetzt");
106
+ }
107
+
108
+ // QR-Code manuell anzeigen (für Debugging)
109
+ export function forceShowQR(qrData) {
110
+ lastQRTime = 0; // Reset Timer
111
+ return generateQRCode(qrData);
112
+ }
113
+
114
+ async function openUniversalBrowser(qrData) {
115
+ try {
116
+ const platform = os.platform();
117
+ console.log(`🖥️ Erkannte Plattform: ${platform}`);
118
+
119
+ // 1. Versuche Playwright (wenn verfügbar)
120
+ try {
121
+ await openWithPlaywright(qrData);
122
+ return;
123
+ } catch (playwrightError) {
124
+ console.log("⚠️ Playwright nicht verfügbar, versuche System-Browser...");
125
+ }
126
+
127
+ // 2. Versuche HTTP Server + System Browser
128
+ await openWithSystemBrowser(qrData, platform);
129
+
130
+ } catch (error) {
131
+ console.log("⚠️ Browser-Öffnung fehlgeschlagen:", error.message);
132
+ console.log("📱 Verwende Terminal QR-Code (siehe oben)");
133
+ }
134
+ }
135
+
136
+ async function openWithPlaywright(qrData) {
137
+ try {
138
+ const { chromium } = await import("playwright");
139
+
140
+ // Versuche verschiedene Browser-Channels
141
+ const channels = ['msedge', 'chrome', 'chromium'];
142
+
143
+ for (const channel of channels) {
144
+ try {
145
+ console.log(`🌐 Versuche ${channel}...`);
146
+ browser = await chromium.launch({
147
+ channel,
148
+ headless: false,
149
+ args: ['--no-sandbox', '--disable-setuid-sandbox']
150
+ });
151
+
152
+ page = await browser.newPage();
153
+ const html = await generateQRHTML(qrData);
154
+ await page.setContent(html);
155
+
156
+ console.log(`✅ ${channel} erfolgreich geöffnet!`);
157
+ return;
158
+
159
+ } catch (channelError) {
160
+ console.log(`⚠️ ${channel} nicht verfügbar`);
161
+ if (browser) {
162
+ await browser.close();
163
+ browser = null;
164
+ }
165
+ }
166
+ }
167
+
168
+ throw new Error("Kein Playwright-Browser verfügbar");
169
+
170
+ } catch (error) {
171
+ throw new Error(`Playwright Fehler: ${error.message}`);
172
+ }
173
+ }
174
+
175
+ async function openWithSystemBrowser(qrData, platform) {
176
+ try {
177
+ // HTTP Server starten
178
+ const port = await startHTTPServer(qrData);
179
+ const url = `http://localhost:${port}`;
180
+
181
+ console.log(`🌐 HTTP Server gestartet: ${url}`);
182
+
183
+ // System-Browser öffnen
184
+ await openSystemBrowser(url, platform);
185
+
186
+ } catch (error) {
187
+ throw new Error(`System-Browser Fehler: ${error.message}`);
188
+ }
189
+ }
190
+
191
+ async function startHTTPServer(qrData) {
192
+ return new Promise(async (resolve, reject) => {
193
+ const http = await import('http');
194
+ const port = 3000 + Math.floor(Math.random() * 1000); // Random Port
195
+
196
+ const html = await generateQRHTML(qrData);
197
+
198
+ httpServer = http.default.createServer((req, res) => {
199
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
200
+ res.end(html);
201
+ });
202
+
203
+ httpServer.listen(port, 'localhost', () => {
204
+ console.log(`📡 HTTP Server läuft auf Port ${port}`);
205
+ resolve(port);
206
+ });
207
+
208
+ httpServer.on('error', (error) => {
209
+ reject(error);
210
+ });
211
+ });
212
+ }
213
+
214
+ async function openSystemBrowser(url, platform) {
215
+ try {
216
+ let command;
217
+
218
+ switch (platform) {
219
+ case 'win32':
220
+ // Windows - versuche verschiedene Browser
221
+ command = `start "" "${url}"`;
222
+ break;
223
+
224
+ case 'darwin':
225
+ // macOS - versuche verschiedene Browser
226
+ command = `open "${url}"`;
227
+ break;
228
+
229
+ case 'linux':
230
+ // Linux - versuche verschiedene Browser
231
+ command = `xdg-open "${url}" || sensible-browser "${url}" || x-www-browser "${url}"`;
232
+ break;
233
+
234
+ default:
235
+ throw new Error(`Unbekannte Plattform: ${platform}`);
236
+ }
237
+
238
+ console.log(`🚀 Öffne Browser: ${command}`);
239
+ await execAsync(command);
240
+ console.log("✅ System-Browser geöffnet!");
241
+
242
+ } catch (error) {
243
+ // Versuche spezifische Browser
244
+ await trySpecificBrowsers(url, platform);
245
+ }
246
+ }
247
+
248
+ async function trySpecificBrowsers(url, platform) {
249
+ const browsers = BROWSERS[platform === 'win32' ? 'windows' : platform] || [];
250
+
251
+ for (const browserPath of browsers) {
252
+ try {
253
+ let command;
254
+
255
+ if (platform === 'win32') {
256
+ command = `"${browserPath}" "${url}"`;
257
+ } else {
258
+ command = `"${browserPath}" "${url}"`;
259
+ }
34
260
 
35
- page = await browser.newPage();
261
+ console.log(`🔍 Versuche: ${browserPath}`);
262
+ await execAsync(command);
263
+ console.log(`✅ ${browserPath} erfolgreich geöffnet!`);
264
+ return;
36
265
 
37
- // Custom HTML-Seite mit dem richtigen QR-Code erstellen
38
- const qrCodeDataURL = await generateQRCodeDataURL(qrData);
39
- const html = `
266
+ } catch (error) {
267
+ console.log(`⚠️ ${browserPath} nicht verfügbar`);
268
+ }
269
+ }
270
+
271
+ throw new Error("Kein Browser gefunden");
272
+ }
273
+
274
+ async function generateQRHTML(qrData) {
275
+ // QR-Code als Data URL generieren (async für ES Modules)
276
+ let qrCodeDataURL;
277
+ try {
278
+ const QRCode = await import('qrcode');
279
+ qrCodeDataURL = await QRCode.toDataURL(qrData, {
280
+ width: 400,
281
+ margin: 2,
282
+ color: {
283
+ dark: '#000000',
284
+ light: '#FFFFFF'
285
+ }
286
+ });
287
+ } catch (error) {
288
+ console.error("❌ QR-Code DataURL Fehler:", error);
289
+ qrCodeDataURL = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgZmlsbD0iI2Y4ZjlmYSIvPjx0ZXh0IHg9IjIwMCIgeT0iMjAwIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMjAiIGZpbGw9IiM2NjY2NjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiPkVycm9yPC90ZXh0Pjwvc3ZnPg==';
290
+ }
291
+
292
+ return `
40
293
  <!DOCTYPE html>
41
- <html>
294
+ <html lang="de">
42
295
  <head>
296
+ <meta charset="UTF-8">
297
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
43
298
  <title>WAEngine - QR Code Scanner</title>
44
299
  <style>
300
+ * {
301
+ margin: 0;
302
+ padding: 0;
303
+ box-sizing: border-box;
304
+ }
305
+
45
306
  body {
46
- font-family: Arial, sans-serif;
307
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
47
308
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
48
- margin: 0;
49
- padding: 20px;
309
+ min-height: 100vh;
50
310
  display: flex;
51
- flex-direction: column;
52
311
  align-items: center;
53
312
  justify-content: center;
54
- min-height: 100vh;
313
+ padding: 20px;
55
314
  color: white;
56
315
  }
316
+
57
317
  .container {
58
318
  background: rgba(255, 255, 255, 0.1);
59
- backdrop-filter: blur(10px);
60
- border-radius: 20px;
319
+ backdrop-filter: blur(15px);
320
+ border-radius: 25px;
61
321
  padding: 40px;
62
322
  text-align: center;
63
323
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
64
324
  border: 1px solid rgba(255, 255, 255, 0.2);
325
+ max-width: 500px;
326
+ width: 100%;
65
327
  }
328
+
329
+ .logo {
330
+ font-size: 3em;
331
+ margin-bottom: 10px;
332
+ }
333
+
66
334
  h1 {
67
- margin-bottom: 20px;
68
- font-size: 2.5em;
335
+ margin-bottom: 30px;
336
+ font-size: 2.2em;
337
+ font-weight: 600;
69
338
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
70
339
  }
340
+
71
341
  .qr-container {
72
342
  background: white;
73
- padding: 20px;
74
- border-radius: 15px;
75
- margin: 20px 0;
76
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
343
+ padding: 25px;
344
+ border-radius: 20px;
345
+ margin: 30px 0;
346
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
347
+ display: inline-block;
77
348
  }
349
+
78
350
  .qr-code {
79
- max-width: 300px;
351
+ width: 300px;
352
+ height: 300px;
353
+ max-width: 100%;
80
354
  height: auto;
355
+ border-radius: 10px;
81
356
  }
357
+
358
+ .warning {
359
+ background: rgba(255, 193, 7, 0.2);
360
+ border: 2px solid #ffc107;
361
+ border-radius: 15px;
362
+ padding: 20px;
363
+ margin: 25px 0;
364
+ font-weight: 600;
365
+ font-size: 1.1em;
366
+ }
367
+
82
368
  .instructions {
83
- font-size: 1.2em;
84
- line-height: 1.6;
85
- margin-top: 20px;
369
+ font-size: 1.1em;
370
+ line-height: 1.8;
371
+ margin-top: 25px;
86
372
  }
373
+
87
374
  .step {
88
- margin: 10px 0;
89
- padding: 10px;
375
+ margin: 12px 0;
376
+ padding: 15px;
90
377
  background: rgba(255, 255, 255, 0.1);
91
- border-radius: 10px;
378
+ border-radius: 12px;
379
+ border-left: 4px solid #ffc107;
380
+ text-align: left;
92
381
  }
93
- .warning {
94
- background: rgba(255, 193, 7, 0.2);
95
- border: 2px solid #ffc107;
96
- border-radius: 10px;
382
+
383
+ .platform-info {
384
+ margin-top: 20px;
97
385
  padding: 15px;
98
- margin: 20px 0;
99
- font-weight: bold;
386
+ background: rgba(0, 0, 0, 0.2);
387
+ border-radius: 10px;
388
+ font-size: 0.9em;
389
+ opacity: 0.8;
390
+ }
391
+
392
+ .refresh-info {
393
+ margin-top: 20px;
394
+ font-size: 0.9em;
395
+ opacity: 0.7;
396
+ }
397
+
398
+ @media (max-width: 600px) {
399
+ .container {
400
+ padding: 25px;
401
+ margin: 10px;
402
+ }
403
+
404
+ h1 {
405
+ font-size: 1.8em;
406
+ }
407
+
408
+ .qr-code {
409
+ width: 250px;
410
+ }
411
+
412
+ .step {
413
+ padding: 12px;
414
+ font-size: 1em;
415
+ }
100
416
  }
101
417
  </style>
102
418
  </head>
103
419
  <body>
104
420
  <div class="container">
105
- <h1>🚀 WAEngine QR Scanner</h1>
421
+ <div class="logo">🚀</div>
422
+ <h1>WAEngine QR Scanner</h1>
423
+
106
424
  <div class="qr-container">
107
425
  <img src="${qrCodeDataURL}" alt="QR Code" class="qr-code" />
108
426
  </div>
427
+
109
428
  <div class="warning">
110
429
  ⚠️ Scanne NUR diesen QR-Code!<br>
111
430
  Nicht den Standard WhatsApp Web QR-Code!
112
431
  </div>
432
+
113
433
  <div class="instructions">
114
434
  <div class="step">📱 1. Öffne WhatsApp auf deinem Handy</div>
115
435
  <div class="step">⚙️ 2. Gehe zu Einstellungen</div>
@@ -117,41 +437,82 @@ export async function generateQRCode(qrData = null) {
117
437
  <div class="step">📷 4. Tippe auf "Gerät verknüpfen"</div>
118
438
  <div class="step">🎯 5. Scanne den QR-Code oben</div>
119
439
  </div>
440
+
441
+ <div class="platform-info">
442
+ 🖥️ Plattform: <span id="platform">Wird erkannt...</span><br>
443
+ 🌐 Browser: <span id="browser">Wird erkannt...</span>
444
+ </div>
445
+
446
+ <div class="refresh-info">
447
+ 🔄 Seite wird alle 45 Sekunden aktualisiert
448
+ </div>
120
449
  </div>
450
+
121
451
  <script>
122
- // Auto-refresh QR code every 30 seconds
452
+ // Platform Detection
453
+ const platform = navigator.platform;
454
+ const userAgent = navigator.userAgent;
455
+
456
+ document.getElementById('platform').textContent = platform;
457
+
458
+ let browserName = 'Unbekannt';
459
+ if (userAgent.includes('Edg/')) browserName = 'Microsoft Edge';
460
+ else if (userAgent.includes('Chrome/')) browserName = 'Google Chrome';
461
+ else if (userAgent.includes('Firefox/')) browserName = 'Mozilla Firefox';
462
+ else if (userAgent.includes('Safari/')) browserName = 'Safari';
463
+ else if (userAgent.includes('Opera/')) browserName = 'Opera';
464
+
465
+ document.getElementById('browser').textContent = browserName;
466
+
467
+ // Auto-refresh QR code every 45 seconds
123
468
  setTimeout(() => {
469
+ console.log('🔄 QR-Code wird aktualisiert...');
124
470
  location.reload();
125
- }, 30000);
471
+ }, 45000);
472
+
473
+ // Visual feedback
474
+ let dots = 0;
475
+ setInterval(() => {
476
+ dots = (dots + 1) % 4;
477
+ const loading = '.'.repeat(dots);
478
+ document.title = \`WAEngine QR Scanner\${loading}\`;
479
+ }, 500);
480
+
481
+ console.log('🚀 WAEngine QR Scanner geladen');
482
+ console.log('📱 Scanne den QR-Code mit WhatsApp');
126
483
  </script>
127
484
  </body>
128
485
  </html>`;
129
-
130
- await page.setContent(html);
131
- console.log("✅ Browser mit korrektem QR-Code geöffnet!");
132
- }
486
+ }
133
487
 
134
- return { browser, page };
135
-
136
- } catch (error) {
137
- console.error("❌ Fehler beim QR-Code Browser:", error);
488
+ export async function closeBrowser() {
489
+ try {
490
+ // Playwright Browser schließen
491
+ if (browser) {
492
+ await browser.close();
493
+ browser = null;
494
+ page = null;
495
+ console.log("🔴 Playwright Browser geschlossen");
496
+ }
138
497
 
139
- // Fallback: QR nur im Terminal
140
- if (qrData) {
141
- console.log("📱 Fallback - QR-Code nur im Terminal:");
142
- qrcode.generate(qrData, { small: true });
498
+ // HTTP Server schließen
499
+ if (httpServer) {
500
+ httpServer.close();
501
+ httpServer = null;
502
+ console.log("🔴 HTTP Server geschlossen");
143
503
  }
144
504
 
145
- return null;
505
+ } catch (error) {
506
+ console.error("❌ Fehler beim Schließen:", error.message);
146
507
  }
147
508
  }
148
509
 
149
- // Hilfsfunktion um QR-Code als Data URL zu generieren
510
+ // Hilfsfunktion um QR-Code als Data URL zu generieren (async für Playwright)
150
511
  async function generateQRCodeDataURL(qrData) {
151
512
  try {
152
513
  const QRCode = await import('qrcode');
153
514
  return await QRCode.toDataURL(qrData, {
154
- width: 300,
515
+ width: 400,
155
516
  margin: 2,
156
517
  color: {
157
518
  dark: '#000000',
@@ -160,15 +521,6 @@ async function generateQRCodeDataURL(qrData) {
160
521
  });
161
522
  } catch (error) {
162
523
  console.error("❌ Fehler beim QR-Code DataURL:", error);
163
- return 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMzAwIiBoZWlnaHQ9IjMwMCIgZmlsbD0iI2Y4ZjlmYSIvPjx0ZXh0IHg9IjE1MCIgeT0iMTUwIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IiM2NjY2NjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiPkVycm9yPC90ZXh0Pjwvc3ZnPg==';
164
- }
165
- }
166
-
167
- export async function closeBrowser() {
168
- if (browser) {
169
- await browser.close();
170
- browser = null;
171
- page = null;
172
- console.log("🔴 Browser geschlossen");
524
+ return 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgZmlsbD0iI2Y4ZjlmYSIvPjx0ZXh0IHg9IjIwMCIgeT0iMjAwIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMjAiIGZpbGw9IiM2NjY2NjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiPkVycm9yPC90ZXh0Pjwvc3ZnPg==';
173
525
  }
174
526
  }