Stop leaking the Gemini API key through /gemini_key

The settings endpoint returned the raw key to any caller, and the
frontend used that response to pre-fill the input field, which also
meant saving with an untouched field would silently resubmit the
plaintext key. /gemini_key now reports only whether a key is set and
a masked preview; the UI shows that as a placeholder and only updates
the stored key when the field is actually filled in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ubuntu
2026-08-30 23:16:39 +00:00
co-authored by Claude Sonnet 5
parent b16a0a811c
commit 21d40c932e
2 changed files with 6 additions and 2 deletions
+2 -1
View File
@@ -1248,7 +1248,8 @@ async def set_epg_url(request):
async def get_gemini_key(request): async def get_gemini_key(request):
doc = settings_collection.find_one({'key': 'gemini_key'}) doc = settings_collection.find_one({'key': 'gemini_key'})
key = doc.get('value', '') if doc else '' key = doc.get('value', '') if doc else ''
return web.json_response({'gemini_key': key}) masked_key = (key[:4] + '...' + key[-4:]) if len(key) > 8 else ('****' if key else '')
return web.json_response({'configured': bool(key), 'masked_key': masked_key})
async def set_gemini_key(request): async def set_gemini_key(request):
+4 -1
View File
@@ -3171,8 +3171,11 @@
function openGeminiKeySettings() { function openGeminiKeySettings() {
$('#geminiKeyAlert').html(''); $('#geminiKeyAlert').html('');
$('#gemini_key_input').val('');
$.get('/gemini_key', function(data) { $.get('/gemini_key', function(data) {
$('#gemini_key_input').val(data.gemini_key || ''); $('#gemini_key_input').attr('placeholder', data.configured
? ('Clé enregistrée (' + data.masked_key + ') — laisser vide pour ne pas changer')
: 'AIza...');
}); });
var show = localStorage.getItem('show_ai_button') !== 'false'; var show = localStorage.getItem('show_ai_button') !== 'false';
$('#toggle_ai_button').prop('checked', show); $('#toggle_ai_button').prop('checked', show);