Skip to content

Commit 818b703

Browse files
fix: remove hardcoded API keys, route AI calls through Worker proxy
Security audit remediation: - Remove exposed OpenRouter API key from ai-chat.js and news-tracker - Route chat, transcription, and AI news generation through Worker - Add CSP headers via Worker and tighten meta tag connect-src - Strip 27 infrastructure subdomains from sitemap.xml - Add transparency notice to client-side contact form - Remove orphaned beacon.min.js and bad filename (–wrangler.jsonc) - Add /api/news/ai endpoint on Worker for server-side AI generation
1 parent 880227a commit 818b703

8 files changed

Lines changed: 53 additions & 210 deletions

File tree

acreetionos-news-tracker/index.html

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="AcreetionOS news from GitHub, Google News, and AI."><meta name="theme-color" content="#2ecc71"><title>AcreetionOS News</title><link rel="icon" href="https://acreetionos.org/acreetionoslogo.webp"><link href="https://fonts.googleapis.com/css2?family=Fira+Code&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"><style>:root{--green:#2ecc71;--bg:#121212;--panel:#1a1a1a;--box:#222;--border:#333;--bright:#e5e5e5;--muted:#b2b2b2;--purple:#9b59b6;--blue:#61afef;--orange:#f39c12;--sans:'Roboto',sans-serif;--mono:'Fira Code',monospace}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sans);background:var(--bg);color:var(--bright);line-height:1.6;background-image:radial-gradient(circle at 1px 1px,rgba(255,255,255,0.03) 1px,transparent 0);background-size:40px 40px}.header{background:rgba(24,26,27,0.85);backdrop-filter:blur(12px);border-bottom:2px solid var(--green);border-radius:0 0 16px 16px;position:sticky;top:0;z-index:100;padding:0.75rem 2rem;display:flex;align-items:center;justify-content:space-between;max-width:1200px;margin:0 auto}.header h1{font-family:var(--mono);font-size:1.4rem;color:var(--green)}.header a{color:var(--muted);text-decoration:none;font-weight:500;margin-left:1.5rem;transition:color 0.2s}.header a:hover{color:var(--bright)}.container{max-width:1200px;margin:1.5rem auto;padding:0 2rem}.st{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:0.6rem 1rem;margin-bottom:1.5rem;text-align:center;color:var(--muted);font-size:0.85rem}.st .sp{display:inline-block;width:12px;height:12px;border:2px solid var(--border);border-top-color:var(--green);border-radius:50%;animation:spin 0.8s linear infinite;margin-right:0.4rem;vertical-align:middle}.g{display:grid;grid-template-columns:repeat(auto-fill,minmax(380px,1fr));gap:1rem;margin-top:0.5rem}.c{background:var(--box);border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:all 0.3s ease;opacity:0;transform:translateY(24px)}.c.show{opacity:1;transform:translateY(0)}.c:hover{transform:translateY(-3px);box-shadow:0 8px 32px rgba(46,204,113,0.15);border-color:var(--green)}.b{padding:1rem}.top{display:flex;align-items:center;justify-content:space-between;margin-bottom:0.5rem}.tg{display:inline-block;padding:0.2rem 0.6rem;border-radius:10px;font-size:0.65rem;font-weight:700;letter-spacing:0.3px;text-transform:uppercase}.rls{background:rgba(46,204,113,0.2);color:var(--green)}.cmt{background:rgba(97,175,239,0.2);color:var(--blue)}.com{background:rgba(155,89,182,0.2);color:var(--purple)}.inf{background:rgba(243,156,18,0.2);color:var(--orange)}.dt{font-size:0.65rem;color:var(--muted);font-family:var(--mono)}.c h3{font-size:1rem;margin-bottom:0.3rem;color:var(--bright);line-height:1.3}.c p{color:var(--muted);font-size:0.8rem;margin-bottom:0.5rem;line-height:1.45;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.meta{display:flex;justify-content:space-between;align-items:center;font-size:0.7rem;color:var(--muted);padding-top:0.5rem;border-top:1px solid var(--border)}.meta .src{display:flex;align-items:center;gap:0.3rem}.meta .src .dot{width:6px;height:6px;border-radius:50%;display:inline-block}.dot-gh{background:var(--green)}.dot-news{background:var(--purple)}.dot-ai{background:var(--blue)}.meta a{color:var(--green);text-decoration:none;font-weight:600;font-size:0.7rem}.meta a:hover{text-decoration:underline}.mb{display:block;margin:1rem auto 0;padding:0.45rem 1.2rem;background:var(--green);color:#000;border:none;border-radius:12px;font-weight:700;cursor:pointer;font-family:var(--sans);font-size:0.9rem;transition:all 0.2s}.mb:hover{transform:translateY(-2px);box-shadow:0 0 15px rgba(46,204,113,0.4)}.mb:disabled{opacity:0.5;cursor:not-allowed;transform:none;box-shadow:none}.er{background:rgba(255,0,0,0.1);border:1px solid rgba(255,0,0,0.3);border-radius:12px;padding:0.8rem 1rem;text-align:center;color:#ff6b6b;margin-bottom:1rem;font-size:0.85rem}.stats{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;margin-bottom:1rem;font-size:0.75rem;color:var(--muted)}.stats span{background:var(--panel);border:1px solid var(--border);border-radius:8px;padding:0.3rem 0.7rem}.stats b{color:var(--green)}.ft{text-align:center;padding:1.5rem;margin-top:1.5rem;border-top:1px solid var(--border);color:var(--muted);font-size:0.8rem}.ft a{color:var(--green);text-decoration:none}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:768px){.header{flex-direction:column;gap:0.5rem;padding:0.5rem 1rem}.container{padding:0 1rem}.g{grid-template-columns:1fr}}</style></head><body><header class="header"><h1>AcreetionOS News</h1><nav><a href="https://acreetionos.org">Home</a><a href="https://acreetionos.org/developers.html">Devs</a><a href="https://github.com/AcreetionOS-Code">GitHub</a></nav></header><div class="container"><div class="st" id="st"><span id="stxt">Loading...</span></div><div id="er"></div><h2 style="font-family:var(--mono);color:var(--green);margin-bottom:0.3rem;font-size:1.2rem">Latest Updates</h2><div class="stats" id="stats"></div><div class="g" id="g"></div><div id="ms" style="text-align:center;margin-top:0.75rem"></div></div><footer class="ft"><p>Part of the <a href="https://acreetionos.org">AcreetionOS</a> project</p></footer><script>
22
var G=document.getElementById('g'),ER=document.getElementById('er'),ST=document.getElementById('st'),SX=document.getElementById('stxt'),SUB=document.getElementById('stats'),MS=document.getElementById('ms');
33
var allArticles=[];
4-
var OR_KEY=['sk-or-v1-e1fe6','de492815203d1c','36d63bdd526a6c','d09d4706ad788f','f8255e5746c4dee60'].join('');
54
var CP='https://api.allorigins.win/raw?url=';
65

76
function st(t,l){SX.textContent=t;if(l){ST.innerHTML='<span class="sp"></span><span id="stxt">'+t+'</span>'}else{ST.innerHTML='<span id="stxt">'+t+'</span>'}}
@@ -140,16 +139,12 @@
140139
sample+='['+allArticles[i].src+'] '+allArticles[i].title+'\n';
141140
}
142141
try{
143-
var res=await fetch('https://openrouter.ai/api/v1/chat/completions',{
142+
var res=await fetch('/api/news/ai',{
144143
method:'POST',
145144
headers:{
146-
'Content-Type':'application/json',
147-
'Authorization':'Bearer '+OR_KEY,
148-
'HTTP-Referer':'https://acreetionos.org',
149-
'X-Title':'AcreetionOS News'
145+
'Content-Type':'application/json'
150146
},
151147
body:JSON.stringify({
152-
model:'inclusionai/ring-2.6-1t:free',
153148
messages:[
154149
{role:'system',content:'You generate news for the AcreetionOS Linux project. Output exactly '+count+' items as a JSON array. Each item: {title: string (max 55 chars), summary: string (1-2 sentences), tag: string (Release/Development/Community/Infrastructure), url: string}. Return valid JSON only. No markdown.'},
155150
{role:'user',content:'Generate articles from this data:\n'+sample}

ai-chat.js

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// AIDEN — AcreetionOS Voice AI Assistant
22
// Google Live-style conversational AI with speech I/O (cross-browser)
3-
// Calls OpenRouter directly (free models via auto-router, key obfuscated)
3+
// Proxies all AI calls through the server-side Worker (/api/chat, /api/transcribe)
4+
// API key is held server-side in Cloudflare Worker environment variables
45

56
(function () {
67
'use strict';
@@ -28,17 +29,11 @@
2829
};
2930

3031
// ── Configuration ──
31-
const OPENROUTER_URL = 'https://openrouter.ai/api/v1/chat/completions';
32-
const WHISPER_URL = 'https://openrouter.ai/api/v1/audio/transcriptions';
33-
const FREE_MODEL = 'openrouter/auto';
32+
const API_BASE = '/api';
3433
const COOLDOWN_MS = 2500;
3534
const SESSION_CAP = 15;
3635
const STREAM_DELAY = 15;
3736

38-
function _k() {
39-
return ['sk-or-v1-e1fe6','de492815203d1c','36d63bdd526a6c','d09d4706ad788f','f8255e5746c4dee60'].join('');
40-
}
41-
4237
const isElectron = typeof window !== 'undefined' && window.process && window.process.type;
4338

4439
// ── State ──
@@ -408,18 +403,14 @@
408403
// Read blob as base64
409404
var base64 = await blobToBase64(blob);
410405

411-
var res = await fetch(WHISPER_URL, {
406+
var res = await fetch(API_BASE + '/transcribe', {
412407
method: 'POST',
413408
headers: {
414-
'Content-Type': 'application/json',
415-
'Authorization': 'Bearer ' + _k(),
416-
'HTTP-Referer': 'https://acreetionos.org',
417-
'X-Title': 'AIDEN Whisper (AcreetionOS Voice)'
409+
'Content-Type': 'application/json'
418410
},
419411
body: JSON.stringify({
420-
model: 'openai/whisper-1',
421412
audio: base64,
422-
// response_format: 'verbose_json'
413+
mimeType: mediaRecorder ? mediaRecorder.mimeType || 'audio/webm' : 'audio/webm'
423414
})
424415
});
425416

@@ -818,23 +809,18 @@
818809
sendTextMessage(text);
819810
}
820811

821-
// ── OpenRouter proxy ──
812+
// ── Worker proxy ──
822813
async function callProxy() {
823814
var res;
824815
try {
825-
res = await fetch(OPENROUTER_URL, {
816+
res = await fetch(API_BASE + '/chat', {
826817
method: 'POST',
827818
headers: {
828-
'Content-Type': 'application/json',
829-
'Authorization': 'Bearer ' + _k(),
830-
'HTTP-Referer': 'https://acreetionos.org',
831-
'X-Title': BRAND.name + ' (AcreetionOS Voice AI)'
819+
'Content-Type': 'application/json'
832820
},
833821
body: JSON.stringify({
834-
model: FREE_MODEL,
835822
messages: messages,
836-
max_tokens: 600,
837-
route: 'fallback'
823+
max_tokens: 600
838824
})
839825
});
840826
} catch (networkErr) {
@@ -853,7 +839,7 @@
853839
throw new Error(errMsg);
854840
}
855841

856-
var content = data.choices && data.choices[0] && data.choices[0].message && data.choices[0].message.content;
842+
var content = data.content || (data.choices && data.choices[0] && data.choices[0].message && data.choices[0].message.content);
857843
if (content) return content;
858844

859845
throw new Error('No response from AI model');

beacon.min.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

contact.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)