fix(browser-bridge): auth bypass when secret empty, popup status fix, force ping on open
This commit is contained in:
parent
58751945eb
commit
fa5001341e
|
|
@ -0,0 +1 @@
|
|||
{"uploadUuid":"8634d0ba5e1641b2a504640b5992b540","channel":"unlisted","xpiCrcHash":"124e35e2b615071abcbccd2e75a8f4247f42ddb700077632affa3a7c3c82c2ef"}
|
||||
|
|
@ -60,6 +60,10 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
|||
flushQueue();
|
||||
sendResponse({ ok: true });
|
||||
}
|
||||
if (msg.type === 'FORCE_PING') {
|
||||
pingBridge();
|
||||
sendResponse({ ok: true });
|
||||
}
|
||||
if (msg.type === 'SET_TRACKING') {
|
||||
chrome.storage.local.set({ 'verstak_tracking_enabled': msg.enabled });
|
||||
sendResponse({ ok: true });
|
||||
|
|
@ -184,6 +188,7 @@ function flushQueue() {
|
|||
'X-Verstak-Secret': secret,
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
signal: AbortSignal.timeout(5000),
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
|
|
@ -191,13 +196,27 @@ function flushQueue() {
|
|||
updateRecent(ev);
|
||||
}
|
||||
chrome.storage.local.set({ [STORAGE_KEY]: [] });
|
||||
chrome.storage.local.set({
|
||||
[BRIDGE_KEY]: { ...config, bridgeReachable: true, lastPing: Date.now() }
|
||||
});
|
||||
chrome.runtime.sendMessage({ type: 'UI_UPDATE' }).catch(() => {});
|
||||
} else if (res.status === 401) {
|
||||
console.warn('[verstak] bridge auth failed, check secret');
|
||||
chrome.storage.local.set({
|
||||
[BRIDGE_KEY]: { ...config, bridgeReachable: false, lastPing: Date.now() }
|
||||
});
|
||||
} else {
|
||||
console.warn('[verstak] bridge error', res.status);
|
||||
chrome.storage.local.set({
|
||||
[BRIDGE_KEY]: { ...config, bridgeReachable: false, lastPing: Date.now() }
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Bridge not available — keep events in queue
|
||||
.catch((err) => {
|
||||
console.warn('[verstak] bridge unreachable:', err.message);
|
||||
chrome.storage.local.set({
|
||||
[BRIDGE_KEY]: { ...config, bridgeReachable: false, lastPing: Date.now() }
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -207,17 +226,21 @@ function pingBridge() {
|
|||
const config = data[BRIDGE_KEY] || DEFAULT_CONFIG;
|
||||
const port = config.port || 9786;
|
||||
|
||||
fetch(`http://127.0.0.1:${port}/api/ping`)
|
||||
fetch(`http://127.0.0.1:${port}/api/ping`, {
|
||||
signal: AbortSignal.timeout(3000),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((info) => {
|
||||
chrome.storage.local.set({
|
||||
[BRIDGE_KEY]: { ...config, ...info, bridgeReachable: true, lastPing: Date.now() }
|
||||
});
|
||||
chrome.runtime.sendMessage({ type: 'UI_UPDATE' }).catch(() => {});
|
||||
})
|
||||
.catch(() => {
|
||||
chrome.storage.local.set({
|
||||
[BRIDGE_KEY]: { ...config, bridgeReachable: false, lastPing: Date.now() }
|
||||
});
|
||||
chrome.runtime.sendMessage({ type: 'UI_UPDATE' }).catch(() => {});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Verstak Bridge",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"description": "Отслеживает активные вкладки и отправляет события в Verstak",
|
||||
"author": "Verstak",
|
||||
"homepage_url": "https://git.mirv.top/mirivlad/verstak",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,15 +1,5 @@
|
|||
{
|
||||
"name": "verstak-bridge-firefox",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Verstak Bridge Firefox extension",
|
||||
"scripts": {
|
||||
"lint:firefox": "web-ext lint --source-dir .",
|
||||
"build:firefox": "web-ext build --source-dir . --artifacts-dir ../web-ext-artifacts --overwrite-dest",
|
||||
"sign:firefox": "../scripts/sign-firefox-xpi.sh",
|
||||
"release:firefox": "../scripts/release-firefox-xpi.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"web-ext": "^8.0.0"
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^9.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@ const RECENT_KEY = 'verstak_recent';
|
|||
const DEFAULT_PORT = 9786;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateUI();
|
||||
// Force a fresh ping check on popup open, don't rely on stale cache
|
||||
chrome.runtime.sendMessage({ type: 'FORCE_PING' });
|
||||
// Read cached state for immediate render
|
||||
restoreToggleState();
|
||||
restoreSettingsPanel();
|
||||
updateUI();
|
||||
|
||||
document.getElementById('sync-btn').addEventListener('click', forceSync);
|
||||
document.getElementById('track-toggle').addEventListener('change', onToggle);
|
||||
|
|
@ -32,16 +35,22 @@ function updateUI() {
|
|||
const portEl = document.getElementById('bridge-port');
|
||||
const dotEl = document.getElementById('status-dot');
|
||||
|
||||
if (config.bridgeReachable) {
|
||||
if (config.bridgeReachable === true) {
|
||||
statusEl.textContent = 'Доступен';
|
||||
statusEl.className = 'value online';
|
||||
dotEl.className = 'dot online';
|
||||
portEl.textContent = '127.0.0.1:' + (config.port || DEFAULT_PORT);
|
||||
} else {
|
||||
} else if (config.bridgeReachable === false) {
|
||||
statusEl.textContent = 'Недоступен';
|
||||
statusEl.className = 'value offline';
|
||||
dotEl.className = 'dot offline';
|
||||
portEl.textContent = config.lastPing ? '—' : 'проверка...';
|
||||
portEl.textContent = '127.0.0.1:' + (config.port || DEFAULT_PORT);
|
||||
} else {
|
||||
// Unknown — not yet checked
|
||||
statusEl.textContent = 'Проверка...';
|
||||
statusEl.className = 'value';
|
||||
dotEl.className = 'dot';
|
||||
portEl.textContent = '127.0.0.1:' + (config.port || DEFAULT_PORT);
|
||||
}
|
||||
|
||||
// Update settings panel port field
|
||||
|
|
@ -146,11 +155,12 @@ function savePort() {
|
|||
chrome.storage.local.get(BRIDGE_KEY, (data) => {
|
||||
const config = data[BRIDGE_KEY] || {};
|
||||
config.port = port;
|
||||
config.bridgeReachable = null; // Force re-check on next popup open
|
||||
chrome.storage.local.set({ [BRIDGE_KEY]: config }, () => {
|
||||
statusEl.textContent = 'Сохранено';
|
||||
statusEl.className = 'port-status ok';
|
||||
// Trigger immediate ping with new port
|
||||
chrome.runtime.sendMessage({ type: 'FORCE_FLUSH' });
|
||||
chrome.runtime.sendMessage({ type: 'FORCE_PING' });
|
||||
setTimeout(() => { updateUI(); statusEl.textContent = ''; }, 1500);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -239,6 +239,11 @@ func (s *Server) handleEvents(w http.ResponseWriter, r *http.Request) {
|
|||
// withAuth wraps a handler with shared-secret authentication.
|
||||
func (s *Server) withAuth(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// If no secret is configured, skip authentication
|
||||
if s.secret == "" {
|
||||
next(w, r)
|
||||
return
|
||||
}
|
||||
auth := r.Header.Get("X-Verstak-Secret")
|
||||
if auth != s.secret {
|
||||
http.Error(w, "unauthorized", 401)
|
||||
|
|
|
|||
Loading…
Reference in New Issue