fix: store key_plain on sub-keys, display always in settings with copy button

This commit is contained in:
M1
2026-03-17 06:40:33 +04:00
parent c684d96d90
commit 54c89a5a11
4 changed files with 18 additions and 35 deletions
+14 -32
View File
@@ -66,27 +66,22 @@
</div>
</div>
<!-- New sub-key reveal (shown after creation) -->
<div id="new-key-reveal" class="hidden mb-4 p-4 bg-green-950/30 rounded-lg border border-green-900/50">
<p class="text-xs text-green-400 mb-2">Sub-key created — copy it now, it won't be shown again.</p>
<div class="flex gap-2">
<code id="new-key-value" class="flex-1 bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-blue-400 text-sm font-mono select-all"></code>
<button onclick="copyNewKey()" class="px-3 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-lg text-gray-400 hover:text-white text-xs transition-colors">Copy</button>
</div>
</div>
<!-- Sub-keys list -->
<div id="keys-list" class="space-y-2">
<% if (it.apiKeys.length === 0) { %>
<p class="text-xs text-gray-600 italic">No sub-keys yet.</p>
<% } else { %>
<% it.apiKeys.forEach(function(k) { %>
<div class="flex items-center justify-between p-3 bg-gray-800/50 rounded-lg border border-gray-700/50">
<div>
<div class="p-3 bg-gray-800/50 rounded-lg border border-gray-700/50">
<div class="flex items-center justify-between mb-2">
<p class="text-sm text-gray-200"><%= k.label %></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>
<button onclick="deleteKey('<%= k.id %>', this)" class="text-xs text-gray-600 hover:text-red-400 transition-colors px-2 py-1">Revoke</button>
</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 class="flex gap-2">
<code class="flex-1 bg-gray-900 border border-gray-800 rounded-lg px-3 py-2 text-blue-400 text-xs font-mono select-all"><%= k.key_plain %></code>
<button onclick="copyKey(this, '<%= k.key_plain %>')" class="px-3 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-lg text-gray-400 hover:text-white text-xs transition-colors">Copy</button>
</div>
<p class="text-xs text-gray-600 mt-1.5">created <%= new Date(k.created_at).toLocaleDateString() %> <%~ k.last_used_at ? '· last used ' + it.timeAgoSSR(k.last_used_at) : '· never used' %></p>
</div>
<% }) %>
<% } %>
@@ -143,33 +138,20 @@
async function createKey() {
const label = document.getElementById('key-label').value.trim();
if (!label) return;
const data = await api('/account/keys', { method: 'POST', body: { label } });
hideCreateKey();
document.getElementById('new-key-value').textContent = data.key;
document.getElementById('new-key-reveal').classList.remove('hidden');
// Add to list without reload
const list = document.getElementById('keys-list');
const empty = list.querySelector('p.italic');
if (empty) empty.remove();
const item = document.createElement('div');
item.className = 'flex items-center justify-between p-3 bg-gray-800/50 rounded-lg border border-gray-700/50';
item.innerHTML = `<div><p class="text-sm text-gray-200">${label}</p><p class="text-xs text-gray-600 mt-0.5">just now · never used</p></div><button onclick="deleteKey('${data.id}')" class="text-xs text-gray-600 hover:text-red-400 transition-colors px-2 py-1">Revoke</button>`;
list.appendChild(item);
await api('/account/keys', { method: 'POST', body: { label } });
location.reload();
}
function copyNewKey() {
const val = document.getElementById('new-key-value').textContent;
function copyKey(btn, val) {
navigator.clipboard.writeText(val);
const btn = event.target;
btn.textContent = 'Copied!';
btn.classList.add('text-green-400');
btn.textContent = 'Copied!'; btn.classList.add('text-green-400');
setTimeout(() => { btn.textContent = 'Copy'; btn.classList.remove('text-green-400'); }, 1500);
}
async function deleteKey(id) {
async function deleteKey(id, btn) {
if (!confirm('Revoke this key? Any apps using it will stop working.')) return;
await api(`/account/keys/${id}`, { method: 'DELETE' });
location.reload();
btn.closest('.p-3').remove();
}
function showStatus(id, msg, color) {