From ad62aab07d83ec3971677a232106f24d2814eccb Mon Sep 17 00:00:00 2001 From: oxpoe Date: Fri, 6 Nov 2026 03:50:06 +0700 Subject: [PATCH] feat(gowa): device id kosong ikut device terhubung + auto webhook secret - hapus auto-pin gowa_device_id pada QR/status - hint device id + secret otomatis - ensureGowaWebhookSecret saat boot & simpan pengaturan - versi 0.5.18 --- CHANGELOG.md | 6 ++++++ README.md | 2 +- app-customer.js | 1 + config/settingsManager.js | 15 ++++++++++++++- package.json | 2 +- routes/adminPortal.js | 16 +++++++++------- version.txt | 2 +- views/admin/whatsapp.ejs | 6 ++++-- 8 files changed, 37 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a366ce2..49c09b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Format mengikuti [Keep a Changelog](https://keepachangelog.com/) dan [Semantic Versioning](https://semver.org/). +## [0.5.18] — 2026-11-06 — "gowa-autodevice" + +### Diperbaiki +- **Device ID kosong** = otomatis mengikuti device yang terhubung lewat QR dashboard (tidak lagi dipin/disimpan otomatis). Isi Device ID hanya untuk menunjuk device GOWA tertentu. +- **Webhook secret GOWA** dibuat otomatis (32 byte hex) bila kosong atau masih default `secret`, lalu ditampilkan di pengaturan untuk disamakan dengan `WHATSAPP_WEBHOOK_SECRET` di GOWA. + ## [0.5.17] — 2026-11-06 — "gowa-connected" ### Diperbaiki diff --git a/README.md b/README.md index 45893fc..a2bd9c0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@

Lisensi: ISC - Versi 0.5.17 (gowa-connected) + Versi 0.5.18 (gowa-autodevice) Node.js >= 20 Docker Demo diff --git a/app-customer.js b/app-customer.js index e1e2861..702c284 100644 --- a/app-customer.js +++ b/app-customer.js @@ -60,6 +60,7 @@ const { SUPPORTED_LANGS, FALLBACK_LANG, normalizeLang, t } = require('./config/i // Pastikan semua default settings ada (untuk migrasi/update dari Gitea) if (typeof ensureDefaultSettings === 'function') { ensureDefaultSettings(); + try { require('./config/settingsManager').ensureGowaWebhookSecret(); } catch (e) {} } // Inisialisasi aplikasi Express diff --git a/config/settingsManager.js b/config/settingsManager.js index 01577ab..6fbab28 100644 --- a/config/settingsManager.js +++ b/config/settingsManager.js @@ -278,6 +278,18 @@ function formatTimeLocal(date) { * Memastikan semua setting wajib ada di settings.json dengan default value. * Dijalankan saat startup aplikasi untuk migrasi/inisialisasi setting baru. */ +/** + * Pastikan gowa_webhook_secret tidak memakai default 'secret'. + * Dibuat otomatis (32 byte hex) bila kosong/default/terlalu pendek. + */ +function ensureGowaWebhookSecret(force) { + const current = String(getSetting('gowa_webhook_secret', '') || '').trim(); + if (!force && current && current !== 'secret' && current.length >= 24) return current; + const secret = crypto.randomBytes(32).toString('hex'); + saveSettings({ gowa_webhook_secret: secret }); + return secret; +} + function ensureDefaultSettings() { try { const currentSettings = getSettings(); @@ -361,5 +373,6 @@ module.exports = { getNowLocalISO, parseDateInTimezone, startSettingsWatcher, - ensureDefaultSettings + ensureDefaultSettings, + ensureGowaWebhookSecret }; diff --git a/package.json b/package.json index 9a72a9e..80b1d9b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-isp", - "version": "0.5.17", + "version": "0.5.18", "description": "OPEN-ISP \u2014 sistem billing & manajemen ISP open-source (PWA pelanggan, multi-OLT, RADIUS, WhatsApp, QRIS)", "main": "app-customer.js", "scripts": { diff --git a/routes/adminPortal.js b/routes/adminPortal.js index 6f74bad..1cd8623 100644 --- a/routes/adminPortal.js +++ b/routes/adminPortal.js @@ -6738,7 +6738,7 @@ router.get('/whatsapp/gowa/qr', requireAdminSession, async (req, res) => { try { const gowa = require('../services/gowaWhatsappService'); const dev = await gowa.ensureDevice(); - if (dev && dev !== getSetting('gowa_device_id', '')) saveSettings({ gowa_device_id: dev }); + // Jangan simpan otomatis: device id kosong = ikuti device yang terhubung via QR. const r = await gowa.getLoginQr(dev); if (!r.ok) { const detail = r.message || r.code || 'pastikan GOWA berjalan & username/password Basic Auth benar'; @@ -6782,13 +6782,15 @@ router.get('/whatsapp', requireAdminSession, requireSidebarMenuAccess('whatsapp' fonnte_country_code: getSetting('fonnte_country_code', '62') }; const gowaBaseUrl = getSetting('gowa_base_url', 'http://127.0.0.1:3000'); + let gowaWebhookSecret = getSetting('gowa_webhook_secret', ''); + try { gowaWebhookSecret = require('../config/settingsManager').ensureGowaWebhookSecret(); } catch (e) {} const gowaSettings = { gowa_mode: getSetting('gowa_mode', /^https:/i.test(String(gowaBaseUrl)) ? 'cloud' : 'local'), gowa_base_url: gowaBaseUrl, gowa_username: getSetting('gowa_username', ''), gowa_password: getSetting('gowa_password', ''), gowa_device_id: getSetting('gowa_device_id', ''), - gowa_webhook_secret: getSetting('gowa_webhook_secret', 'secret') + gowa_webhook_secret: gowaWebhookSecret }; const gowaWebhookUrl = String(getSetting('app_url', '') || ((req.headers['x-forwarded-proto'] || req.protocol) + '://' + req.get('host'))).replace(/\/+$/, '') + '/api/webhook/gowa'; const gowaUiHost = String(req.get('host') || '').split(':')[0]; @@ -6844,7 +6846,10 @@ router.post('/whatsapp/gateway-settings', requireAdminSession, express.urlencode gowa_username: String(gowa_username || '').trim(), gowa_password: String(gowa_password || '').trim(), gowa_device_id: String(gowa_device_id || '').trim(), - gowa_webhook_secret: String(gowa_webhook_secret || 'secret').trim() + gowa_webhook_secret: (function () { + const v = String(gowa_webhook_secret || '').trim(); + return (v && v !== 'secret' && v.length >= 24) ? v : crypto.randomBytes(32).toString('hex'); + })() }); if ((wa_gateway_type || 'baileys') === 'baileys') { @@ -7400,10 +7405,7 @@ router.get('/api/whatsapp/status', requireAdmin, async (req, res) => { const isConn = !!(pick.is_connected || pick.connected || pick.state === 'connected'); const conn = isConn ? 'open' : (loggedIn ? 'connecting' : 'close'); const deviceId = String(pick.device_id || pick.id || '').trim(); - // Simpan otomatis device id agar status berikutnya memakai /devices/:id/status. - if (deviceId && !String(getSetting('gowa_device_id', '') || '').trim()) { - try { saveSettings({ gowa_device_id: deviceId }); } catch (e) {} - } + // device id kosong = selalu ikuti device yang terhubung (tidak dipin otomatis) res.json({ connection: conn, gateway: 'gowa', loggedIn: loggedIn, deviceId: deviceId, user: { id: deviceId || 'gowa_gateway', name: loggedIn ? 'GOWA (WhatsApp)' : 'GOWA Gateway' }, diff --git a/version.txt b/version.txt index 0d240c6..d2d81b7 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.5.17 \ No newline at end of file +0.5.18 \ No newline at end of file diff --git a/views/admin/whatsapp.ejs b/views/admin/whatsapp.ejs index 8ba0efa..8152c6a 100644 --- a/views/admin/whatsapp.ejs +++ b/views/admin/whatsapp.ejs @@ -181,7 +181,8 @@

- + +
Kosongkan untuk otomatis mengikuti device yang login via QR. Isi hanya bila ingin menunjuk device GOWA tertentu.
@@ -219,7 +220,8 @@
- + +
Dibuat otomatis (32 byte). Samakan dengan WHATSAPP_WEBHOOK_SECRET di GOWA.