security: auth redesign, SSRF protection, CORS lockdown, and 13 other fixes
- Auth (#2/#3): UUID PK, 256-bit keys, SHA-256 lookup + bcrypt hash - SSRF (#1): validate URLs, block private IPs, cloud metadata endpoints - CORS (#4): lock to pingql.com origins, not wildcard - SSE limit (#6): 10 connections per monitor max - ReDoS (#7): cap $regex patterns at 200 chars - Monitor limit (#8): 100 per account default - Cookie env config (#9): secure/domain from env vars - Bearer parsing (#10): case-insensitive RFC 6750 - Pings retention (#11): 90-day pruner, hourly interval - monitors.enabled index (#12): partial index for /internal/due - Runner locking (#14): locked_until for horizontal scale safety - COALESCE nullable bug (#17): dynamic PATCH with explicit undefined checks - MONITOR_TOKEN null guard (#18): startup validation + middleware hardening - reset-key cookie fix (#16): sets new cookie in response
This commit is contained in:
@@ -15,11 +15,11 @@
|
||||
<h2 class="text-sm font-semibold text-gray-300 mb-4">Account</h2>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Primary Key</label>
|
||||
<label class="block text-xs text-gray-500 mb-1">Account ID</label>
|
||||
<div class="flex gap-2">
|
||||
<code id="primary-key" class="flex-1 bg-gray-800 border border-gray-700 rounded-lg px-4 py-2.5 text-blue-400 text-sm tracking-widest"><%= it.account.id %></code>
|
||||
<button onclick="copyKey()" class="px-3 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-lg text-gray-400 hover:text-white transition-colors text-xs">Copy</button>
|
||||
<code id="account-id" class="flex-1 bg-gray-800 border border-gray-700 rounded-lg px-4 py-2.5 text-gray-400 text-sm"><%= it.account.id %></code>
|
||||
</div>
|
||||
<p class="text-xs text-gray-600 mt-1.5">Your secret key was shown once at registration and cannot be displayed again. Use "Rotate Key" below to generate a new one.</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Member since</label>
|
||||
@@ -88,7 +88,7 @@
|
||||
<div class="flex items-center justify-between p-3 bg-gray-800/50 rounded-lg border border-gray-700/50">
|
||||
<div>
|
||||
<p class="text-sm text-gray-200"><%= k.label %></p>
|
||||
<p class="text-xs text-gray-600 mt-0.5 font-mono"><%= k.id %> · created <%= new Date(k.created_at).toLocaleDateString() %> <%~ k.last_used_at ? '· last used ' + it.timeAgoSSR(k.last_used_at) : '· never used' %></p>
|
||||
<p class="text-xs text-gray-600 mt-0.5">created <%= new Date(k.created_at).toLocaleDateString() %> <%~ k.last_used_at ? '· last used ' + it.timeAgoSSR(k.last_used_at) : '· never used' %></p>
|
||||
</div>
|
||||
<button onclick="deleteKey('<%= k.id %>')" class="text-xs text-gray-600 hover:text-red-400 transition-colors px-2 py-1">Revoke</button>
|
||||
</div>
|
||||
@@ -111,14 +111,6 @@
|
||||
}
|
||||
})();
|
||||
|
||||
function copyKey() {
|
||||
const key = document.getElementById('primary-key').textContent;
|
||||
navigator.clipboard.writeText(key);
|
||||
const btn = event.target;
|
||||
btn.textContent = 'Copied!';
|
||||
setTimeout(() => btn.textContent = 'Copy', 1500);
|
||||
}
|
||||
|
||||
async function saveEmail() {
|
||||
const email = document.getElementById('email-input').value.trim();
|
||||
if (!email) return;
|
||||
@@ -139,8 +131,10 @@
|
||||
async function confirmReset() {
|
||||
if (!confirm('Rotate your primary key?\n\nYour current key will stop working immediately. Make sure to copy the new one.')) return;
|
||||
const data = await api('/account/reset-key', { method: 'POST', body: {} });
|
||||
await fetch('/account/login', { method: 'POST', credentials: 'same-origin', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ key: data.key }) });
|
||||
location.reload();
|
||||
// New key is shown once — display it in the new-key-reveal area
|
||||
document.getElementById('new-key-value').textContent = data.key;
|
||||
document.getElementById('new-key-reveal').classList.remove('hidden');
|
||||
// Cookie is set server-side by reset-key endpoint
|
||||
}
|
||||
|
||||
function showCreateKey() {
|
||||
|
||||
Reference in New Issue
Block a user