diff --git a/index.html b/index.html index 55bd4ba..f48e4fa 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,36 @@ - - TSS Bot + + + + + + + + + + + + + + + + + + + + + Toothless' TSS Bot
diff --git a/public/embed-icon.svg b/public/embed-icon.svg new file mode 100644 index 0000000..887f86a --- /dev/null +++ b/public/embed-icon.svg @@ -0,0 +1,22 @@ + + Toothless' TSS Bot tree icon + + + + + + + + + + + + + + + + + + + + diff --git a/public/embed.svg b/public/embed.svg new file mode 100644 index 0000000..044785e --- /dev/null +++ b/public/embed.svg @@ -0,0 +1,80 @@ + + Toothless' TSS Bot + A share card for Toothless' TSS Bot using the pixel tree from the home page. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LIVE TSS INTEL + Toothless' + TSS Bot + Leaderboards, battle logs, uptime, and viewer analytics. + + + + Teams + + Battle Logs + + Uptime + + diff --git a/server.cjs b/server.cjs index 5dc7370..82be095 100644 --- a/server.cjs +++ b/server.cjs @@ -793,6 +793,23 @@ function proxyRequest(req, res) { req.pipe(proxy) } +function pagePublicOrigin(req) { + const configured = PUBLIC_ORIGIN.split(',').map((origin) => origin.trim()).filter(Boolean)[0] + if (configured) return configured.replace(/\/$/, '') + + const host = req.headers['x-forwarded-host'] || req.headers.host || `localhost:${PORT}` + const proto = req.headers['x-forwarded-proto'] || (req.socket.encrypted ? 'https' : 'http') + return `${String(proto).split(',')[0].trim()}://${String(host).split(',')[0].trim()}`.replace(/\/$/, '') +} + +function sendHtml(req, res, data, status = 200) { + const html = data.toString('utf8').replaceAll('__PUBLIC_ORIGIN__', pagePublicOrigin(req)) + send(res, status, html, { + 'content-type': mimeTypes['.html'], + 'cache-control': 'no-cache', + }) +} + function serveStatic(req, res) { const requestPath = decodeURIComponent(new URL(req.url, `http://localhost:${PORT}`).pathname) const relativePath = requestPath === '/' ? '/index.html' : requestPath @@ -811,15 +828,20 @@ function serveStatic(req, res) { }) } - send(res, 200, indexData, { 'content-type': mimeTypes['.html'] }) + sendHtml(req, res, indexData) }) return } const ext = path.extname(filePath) + if (ext === '.html') { + sendHtml(req, res, data) + return + } + send(res, 200, data, { 'content-type': mimeTypes[ext] || 'application/octet-stream', - 'cache-control': ext === '.html' ? 'no-cache' : 'public, max-age=31536000, immutable', + 'cache-control': 'public, max-age=31536000, immutable', }) }) } diff --git a/src/App.jsx b/src/App.jsx index e732d2c..ace1206 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -390,7 +390,7 @@ function App() { : route.page === 'uptime' ? "Uptime | Toothless' TSS Bot" : route.page === 'viewers' - ? "viewers | Toothless' TSS Bot" + ? "Viewers | Toothless' TSS Bot" : route.page === 'privacy' ? "Privacy notice | Toothless' TSS Bot" : "Toothless' TSS Bot" @@ -959,7 +959,7 @@ function Footer({ navigate }) { onClick={() => navigate('/viewers')} type="button" > - viewers + Viewers