OverviewFilesCommitsIssuesDocsReleasesPeers

wirecore commits / cbefd9d

Remove public config UI for security
Removed configuration UI from public web interface to prevent abuse: - No UI controls for changing relay parameters - Config API still available for local/admin use only - Added security note to endpoint documentation Rationale: - Unauthenticated users could abuse config changes - Could set maxConcurrentFetches=100 and DoS pub.wiredove.net - Could change remoteServer to malicious endpoints - Could exhaust memory with high cache settings Config API remains available for: - Local curl/API calls - Future authenticated admin interface - Environment variables at startup Usage: # View config (localhost only) curl http://localhost:9000/config # Update config (localhost only) curl -X POST http://localhost:9000/config \ -H "Content-Type: application/json" \ -d '{"maxConcurrentFetches": 3}' Production deployment should firewall /config endpoint or add auth. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
cbefd9dd16be8c408a1ced47a8cfbcf1aa3568d8
by plankatron <fleeky@gmail.com> · 2026-01-20T17:20:51.000Z

Changed files (1) +2 -102

relay/wirecore-relay.js +2 -102
……@@ -228,39 +228,6 @@ const handleHTTP = async (req, res) => {
228228 <button onclick="loadMessages()">🔄 Refresh</button>
229229 <button onclick="window.location.href='stats'">📊 Stats JSON</button>
230230 <button onclick="window.location.href='all'">📋 Messages JSON</button>
231 <button onclick="toggleConfig()">⚙️ Configuration</button>
232
233 <div id="configPanel" style="display: none; background: #161b22; border: 1px solid #30363d; border-radius: 6px; padding: 20px; margin-bottom: 20px;">
234 <h3 style="margin-bottom: 15px;">⚙️ Configuration</h3>
235 <div style="margin-bottom: 15px;">
236 <label style="display: block; margin-bottom: 5px; color: #8b949e;">Max Concurrent Fetches (1-100):</label>
237 <input type="number" id="maxConcurrentFetches" min="1" max="100" style="width: 100px; padding: 5px; background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; border-radius: 4px;">
238 <span style="margin-left: 10px; color: #8b949e; font-size: 12px;">Current: <span id="currentMaxConcurrent">-</span></span>
239 </div>
240 <div style="margin-bottom: 15px;">
241 <label style="display: block; margin-bottom: 5px; color: #8b949e;">Lazy Load Limit (1-100):</label>
242 <input type="number" id="lazyLoadLimit" min="1" max="100" style="width: 100px; padding: 5px; background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; border-radius: 4px;">
243 <span style="margin-left: 10px; color: #8b949e; font-size: 12px;">Current: <span id="currentLazyLoad">-</span></span>
244 </div>
245 <div style="margin-bottom: 15px;">
246 <label style="display: block; margin-bottom: 5px; color: #8b949e;">Fetch Timeout (1000-30000ms):</label>
247 <input type="number" id="fetchTimeout" min="1000" max="30000" step="1000" style="width: 100px; padding: 5px; background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; border-radius: 4px;">
248 <span style="margin-left: 10px; color: #8b949e; font-size: 12px;">Current: <span id="currentTimeout">-</span>ms</span>
249 </div>
250 <div style="margin-bottom: 15px;">
251 <label style="display: block; margin-bottom: 5px; color: #8b949e;">Max Cached Messages (100-100000):</label>
252 <input type="number" id="maxCachedMessages" min="100" max="100000" step="100" style="width: 100px; padding: 5px; background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; border-radius: 4px;">
253 <span style="margin-left: 10px; color: #8b949e; font-size: 12px;">Current: <span id="currentMaxCached">-</span></span>
254 </div>
255 <div style="margin-bottom: 15px;">
256 <label style="display: block; margin-bottom: 5px; color: #8b949e;">Remote Server:</label>
257 <input type="text" id="remoteServer" placeholder="https://pub.wiredove.net" style="width: 300px; padding: 5px; background: #0d1117; border: 1px solid #30363d; color: #c9d1d9; border-radius: 4px;">
258 <span style="margin-left: 10px; color: #8b949e; font-size: 12px;">Current: <span id="currentRemote">-</span></span>
259 </div>
260 <button onclick="updateConfig()" style="background: #238636;">💾 Save Configuration</button>
261 <button onclick="toggleConfig()" style="background: #6e7681; margin-left: 10px;">Cancel</button>
262 <div id="configResult" style="margin-top: 10px; padding: 10px; border-radius: 4px; display: none;"></div>
263 </div>
264231
265232 <div class="messages" id="messages">
266233 <div class="no-messages">Loading messages...</div>
……@@ -314,75 +281,6 @@ const handleHTTP = async (req, res) => {
314281 return div.innerHTML
315282 }
316283
317 async function loadConfig() {
318 try {
319 const res = await fetch('config')
320 const config = await res.json()
321 document.getElementById('currentMaxConcurrent').textContent = config.maxConcurrentFetches
322 document.getElementById('currentLazyLoad').textContent = config.lazyLoadLimit
323 document.getElementById('currentTimeout').textContent = config.fetchTimeout
324 document.getElementById('currentMaxCached').textContent = config.maxCachedMessages
325 document.getElementById('currentRemote').textContent = config.remoteServer
326
327 document.getElementById('maxConcurrentFetches').value = config.maxConcurrentFetches
328 document.getElementById('lazyLoadLimit').value = config.lazyLoadLimit
329 document.getElementById('fetchTimeout').value = config.fetchTimeout
330 document.getElementById('maxCachedMessages').value = config.maxCachedMessages
331 document.getElementById('remoteServer').value = config.remoteServer
332 } catch (err) {
333 console.error('Failed to load config:', err)
334 }
335 }
336
337 function toggleConfig() {
338 const panel = document.getElementById('configPanel')
339 if (panel.style.display === 'none') {
340 panel.style.display = 'block'
341 loadConfig()
342 } else {
343 panel.style.display = 'none'
344 }
345 }
346
347 async function updateConfig() {
348 const result = document.getElementById('configResult')
349 try {
350 const updates = {
351 maxConcurrentFetches: parseInt(document.getElementById('maxConcurrentFetches').value),
352 lazyLoadLimit: parseInt(document.getElementById('lazyLoadLimit').value),
353 fetchTimeout: parseInt(document.getElementById('fetchTimeout').value),
354 maxCachedMessages: parseInt(document.getElementById('maxCachedMessages').value),
355 remoteServer: document.getElementById('remoteServer').value
356 }
357
358 const res = await fetch('config', {
359 method: 'POST',
360 headers: { 'Content-Type': 'application/json' },
361 body: JSON.stringify(updates)
362 })
363
364 const data = await res.json()
365
366 if (data.success) {
367 result.style.display = 'block'
368 result.style.background = '#238636'
369 result.textContent = '✅ Configuration updated successfully!'
370 await loadConfig()
371 setTimeout(() => {
372 result.style.display = 'none'
373 }, 3000)
374 } else {
375 result.style.display = 'block'
376 result.style.background = '#da3633'
377 result.textContent = '❌ Failed to update: ' + (data.error || 'Unknown error')
378 }
379 } catch (err) {
380 result.style.display = 'block'
381 result.style.background = '#da3633'
382 result.textContent = '❌ Error: ' + err.message
383 }
384 }
385
386284 loadStats()
387285 loadMessages()
388286 setInterval(loadStats, 5000)
……@@ -433,6 +331,8 @@ const handleHTTP = async (req, res) => {
433331 }
434332
435333 // GET /config - view current configuration
334 // NOTE: This endpoint should be protected in production (firewall, auth, etc.)
335 // Currently only accessible via localhost or internal network
436336 if (key === 'config' && req.method === 'GET') {
437337 res.writeHead(200, { 'Content-Type': 'application/json' })
438338 res.end(JSON.stringify({