-
-
+
+
+
@@ -5794,8 +5794,22 @@ async function ensureBleNativeReady(){
_bleNativeInitialized=true;
}
+// Envia log diagnóstico direto pro servidor (evita crash de clipboard/share em WebView)
+async function sendDiagLogToServer(){
+ const el=document.getElementById('bt-diag');
+ if(!el){toast('Log vazio');return}
+ const txt=`Shivao v${APP_VERSION} · log diagnóstico\n\n`+(el.innerText||el.textContent||'').trim();
+ if(!cloudConfigured()){toast('Faça login primeiro pra enviar log');return}
+ toast('📤 Enviando log pro servidor...');
+ try{
+ const r=await cloudFetch('/api/bms/diag-log',{method:'POST',body:JSON.stringify({log:txt})});
+ const j=await r.json();
+ if(j.ok)toast('✓ Log enviado · '+(j.file||'OK'));
+ else throw new Error(j.error||'falhou');
+ }catch(e){toast('Erro: '+e.message)}
+}
+
// Mostra log num modal pro usuário copiar/compartilhar manualmente
-// (navigator.clipboard crasha em alguns WebViews Capacitor / Samsung One UI)
function copyDiagLog(){
const el=document.getElementById('bt-diag');
if(!el){toast('Log vazio');return}
@@ -6329,7 +6343,7 @@ async function removeBluetoothDevice(id){
renderBluetoothCard();
}
-const APP_VERSION='1.10.8';
+const APP_VERSION='1.10.9';
function renderBluetoothCard(){
const el=document.getElementById('bt-list');
const supportEl=document.getElementById('bt-support');
diff --git a/server/src/index.js b/server/src/index.js
index 3d923d5..ce885aa 100644
--- a/server/src/index.js
+++ b/server/src/index.js
@@ -126,6 +126,23 @@ app.get('/api/auth/me', requireAuth, (req, res) => {
res.json(req.user);
});
+// Diagnostic log endpoint — recebe log do BLE pra debugar
+app.post('/api/bms/diag-log', requireAuth, (req, res) => {
+ const { log } = req.body || {};
+ if (!log || typeof log !== 'string') return res.status(400).json({ error: 'log string required' });
+ const dir = path.join(db.dataDir, 'diag-logs');
+ try { fs.mkdirSync(dir, { recursive: true }); } catch {}
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
+ const file = path.join(dir, `${req.user.id}-${ts}.txt`);
+ try {
+ fs.writeFileSync(file, log.slice(0, 50000)); // cap em 50KB
+ db.audit(req.user.id, 'bms_diag_log', 'bluetooth', null, { bytes: log.length, file: path.basename(file) }, req.ip);
+ res.json({ ok: true, file: path.basename(file) });
+ } catch (e) {
+ res.status(500).json({ error: e.message });
+ }
+});
+
// ===== Google Login via OAuth redirect (pra apps Capacitor onde GSI popup não funciona) =====
// In-memory store: session_id → { tokens, createdAt }. Auto-expira em 10min.
const pendingGoogleSessions = new Map();
@@ -347,7 +364,7 @@ app.get('/.well-known/assetlinks.json', (req, res) => {
});
// Atalho: /apk redireciona pra última APK release no Forgejo
-const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.10.8/Shivao-v1.10.8.apk';
+const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.10.9/Shivao-v1.10.9.apk';
app.get('/apk', (req, res) => res.redirect(302, LATEST_APK_URL));
// Página A4 imprimível com QR Code + instruções (cola no barco/marina)