v0.248.0: i18n slice 1 release A — apps and settings in English, Hungarian byte-identical (R-556)
gates / gates (push) Successful in 20s
gates / gates (push) Successful in 20s
Ten pages converted against fixtures captured from unconverted templates (6be55a0); marker
coverage test; English page mask narrowed; English retrieval-promise stems; common keys;
title keys and infraMeta from the bundle; old wording tests read the Hungarian expansion.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -2,52 +2,51 @@
|
||||
{{template "layout_start" .}}
|
||||
|
||||
<div class="page-header">
|
||||
<h2>Beállítások — Biztonság és hozzáférés</h2>
|
||||
<h2>{{T "settings_security.beallitasok_biztonsag_es_hozzaferes"}}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Section B: Password Change -->
|
||||
<div class="settings-card">
|
||||
<h3>Jelszó módosítás</h3>
|
||||
<h3>{{T "settings_security.jelszo_modositas"}}</h3>
|
||||
{{if .AuthEnabled}}
|
||||
{{if .PasswordError}}<div class="alert alert-error">{{.PasswordError}}</div>{{end}}
|
||||
<form method="POST" action="/settings/password">
|
||||
{{.CSRFField}}
|
||||
<div class="form-group">
|
||||
<label for="current_password">Jelenlegi jelszó</label>
|
||||
<label for="current_password">{{T "settings_security.jelenlegi_jelszo"}}</label>
|
||||
<input type="password" id="current_password" name="current_password" required
|
||||
placeholder="Adja meg a jelenlegi jelszavát" class="form-control">
|
||||
placeholder="{{T "settings_security.adja_meg_a_jelenlegi_jelszavat"}}" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="new_password">Új jelszó</label>
|
||||
<label for="new_password">{{T "settings_security.uj_jelszo"}}</label>
|
||||
<input type="password" id="new_password" name="new_password" required minlength="8"
|
||||
placeholder="Legalább 8 karakter" class="form-control">
|
||||
placeholder="{{T "settings_security.legalabb_8_karakter"}}" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="confirm_password">Új jelszó megerősítése</label>
|
||||
<label for="confirm_password">{{T "settings_security.uj_jelszo_megerositese"}}</label>
|
||||
<input type="password" id="confirm_password" name="confirm_password" required minlength="8"
|
||||
placeholder="Jelszó mégegyszer" class="form-control">
|
||||
placeholder="{{T "settings_security.jelszo_megegyszer"}}" class="form-control">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Jelszó módosítása</button>
|
||||
<button type="submit" class="btn btn-primary">{{T "settings_security.jelszo_modositasa"}}</button>
|
||||
</form>
|
||||
{{else}}
|
||||
<div class="alert alert-info">
|
||||
A jelszavas védelem nincs beállítva. Kérd az üzemeltetőt a beállításhoz.
|
||||
{{T "settings_security.a_jelszavas_vedelem_nincs_beallitva"}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<!-- Section: Geo-Restriction -->
|
||||
<div class="settings-card">
|
||||
<h3>Földrajzi korlátozás</h3>
|
||||
<h3>{{T "settings_security.foldrajzi_korlatozas"}}</h3>
|
||||
<p class="settings-card-desc">
|
||||
Ország alapján korlátozható a webes alkalmazások elérése a Cloudflare WAF segítségével.
|
||||
<br><span class="form-hint">A helyi hálózati hozzáférés mindig engedélyezett (nem halad át a Cloudflare-en).</span>
|
||||
{{T "settings_security.orszag_alapjan_korlatozhato_a_webes"}}
|
||||
<br><span class="form-hint">{{T "settings_security.a_helyi_halozati_hozzaferes_mindig"}}</span>
|
||||
</p>
|
||||
|
||||
{{if not .CFConfigured}}
|
||||
<div class="alert alert-info">
|
||||
A Cloudflare API token nincs konfigurálva. Kérd az üzemeltetőt a beállításhoz.<br>
|
||||
<small>A tokennek <strong>Zone WAF:Edit</strong> jogosultsággal kell rendelkeznie.</small>
|
||||
{{T "settings_security.a_cloudflare_api_token_nincs"}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div id="geo-status-msg"></div>
|
||||
@@ -55,16 +54,16 @@
|
||||
<label class="toggle" style="margin-bottom:1rem">
|
||||
<input type="checkbox" id="geo-enabled" {{if .GeoEnabled}}checked{{end}}
|
||||
onchange="toggleGeo(this.checked)">
|
||||
<span class="toggle-label">Geo-korlátozás aktív</span>
|
||||
<span class="toggle-label">{{T "settings_security.geo_korlatozas_aktiv"}}</span>
|
||||
</label>
|
||||
|
||||
<div id="geo-details" {{if not .GeoEnabled}}style="display:none"{{end}}>
|
||||
<!-- Global allowed countries -->
|
||||
<div class="form-group">
|
||||
<label>Engedélyezett országok (globális)</label>
|
||||
<label>{{T "settings_security.engedelyezett_orszagok_globalis"}}</label>
|
||||
<div class="geo-country-selector" id="geo-countries">
|
||||
<input type="text" id="geo-search" class="form-control"
|
||||
placeholder="Ország keresése..."
|
||||
placeholder="{{T "settings_security.orszag_keresese"}}"
|
||||
autocomplete="off"
|
||||
oninput="filterCountries(this.value)"
|
||||
onfocus="showCountryList()"
|
||||
@@ -72,22 +71,22 @@
|
||||
<div class="geo-country-list" id="geo-country-list"></div>
|
||||
</div>
|
||||
<div class="geo-selected-tags" id="geo-selected-tags"></div>
|
||||
<span class="form-hint">Csak a kiválasztott országokból érhető el a rendszer.</span>
|
||||
<span class="form-hint">{{T "settings_security.csak_a_kivalasztott_orszagokbol_erheto"}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Per-app overrides -->
|
||||
<div class="form-group" style="margin-top:1.5rem">
|
||||
<label>Alkalmazás-specifikus felülírások</label>
|
||||
<label>{{T "settings_security.alkalmazas_specifikus_felulirasok"}}</label>
|
||||
<div id="geo-app-overrides"></div>
|
||||
{{if .DeployedApps}}
|
||||
<div style="margin-top:.5rem;display:flex;align-items:center;gap:.5rem">
|
||||
<select id="geo-add-app-select" class="form-control" style="max-width:250px">
|
||||
<option value="">— Alkalmazás kiválasztása —</option>
|
||||
<option value="">{{T "settings_security.alkalmazas_kivalasztasa"}}</option>
|
||||
{{range .DeployedApps}}
|
||||
<option value="{{.Name}}">{{.Display}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<button class="btn btn-sm btn-outline" onclick="addAppOverride()">+ Hozzáadás</button>
|
||||
<button class="btn btn-sm btn-outline" onclick="addAppOverride()">{{T "settings_security.hozzaadas"}}</button>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -96,11 +95,11 @@
|
||||
<div class="form-group" style="margin-top:1.5rem">
|
||||
<div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap">
|
||||
<button class="btn btn-primary" id="btn-geo-save" onclick="saveGeoSettings()">
|
||||
Mentés és szinkronizálás
|
||||
{{T "settings_security.mentes_es_szinkronizalas"}}
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline" onclick="triggerGeoSync()">Kézi szinkronizálás</button>
|
||||
<button class="btn btn-sm btn-outline" onclick="triggerGeoSync()">{{T "settings_security.kezi_szinkronizalas"}}</button>
|
||||
<span id="geo-sync-status" class="form-hint">
|
||||
{{if .GeoLastSync}}Utolsó szinkronizálás: {{.GeoLastSync}}{{end}}
|
||||
{{if .GeoLastSync}}{{T "settings_security.utolso_szinkronizalas"}}{{end}}
|
||||
{{if .GeoLastError}} <span class="state-text-crit">{{.GeoLastError}}</span>{{end}}
|
||||
</span>
|
||||
</div>
|
||||
@@ -118,10 +117,10 @@ function openDialog(opts){
|
||||
var root=document.getElementById('dialog-root');
|
||||
if(!root) return;
|
||||
root.innerHTML='<div class="confirm-overlay" onclick="if(event.target===this)document.getElementById(\'dialog-cancel\').click()"><div class="confirm-box">'
|
||||
+'<h3>'+escText(opts.title||'Megerősítés')+'</h3>'
|
||||
+'<h3>'+escText(opts.title||'{{T "settings_security.megerosites"}}')+'</h3>'
|
||||
+'<p style="white-space:pre-line">'+escText(opts.message||'')+'</p>'
|
||||
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'Megerősítés')+'</button>'
|
||||
+'<button type="button" class="btn btn-outline" id="dialog-cancel">Mégsem</button></div>'
|
||||
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'{{T "settings_security.megerosites"}}')+'</button>'
|
||||
+'<button type="button" class="btn btn-outline" id="dialog-cancel">{{T "common.megsem"}}</button></div>'
|
||||
+'</div></div>';
|
||||
document.getElementById('dialog-go').onclick=function(){ closeDialog(); if(opts.onConfirm) opts.onConfirm(); };
|
||||
document.getElementById('dialog-cancel').onclick=function(){ closeDialog(); if(opts.onCancel) opts.onCancel(); };
|
||||
@@ -171,7 +170,7 @@ function openDialog(opts){
|
||||
+ escHtml(c.name) + ' <small>(' + c.code + ')</small></div>';
|
||||
count++;
|
||||
}
|
||||
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">Nincs találat</div>';
|
||||
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">{{T "settings_security.nincs_talalat"}}</div>';
|
||||
// Reveal with 'block', NOT '' — the .geo-country-list CSS default is display:none,
|
||||
// and clearing the inline style ('') would fall back to that and keep the (populated)
|
||||
// list hidden. This was the country-autocomplete "no list" bug.
|
||||
@@ -188,8 +187,8 @@ function openDialog(opts){
|
||||
|
||||
window.removeCountry = function(code) {
|
||||
if (code === 'HU') {
|
||||
openDialog({title:'Figyelem', confirmLabel:'Eltávolítás',
|
||||
message:'Figyelem: Magyarország eltávolítása azt jelenti, hogy magyar IP-ről sem lesz elérhető a rendszer távolról. Biztosan folytatja?',
|
||||
openDialog({title:'{{T "settings_security.figyelem"}}', confirmLabel:'{{T "common.eltavolitas"}}',
|
||||
message:'{{T "settings_security.figyelem_magyarorszag_eltavolitasa_azt_j"}}',
|
||||
onConfirm:function(){ doRemoveCountry(code); }});
|
||||
return;
|
||||
}
|
||||
@@ -247,8 +246,8 @@ function openDialog(opts){
|
||||
var idx = ov.allowed_countries.indexOf(code);
|
||||
if (idx >= 0) {
|
||||
if (code === 'HU') {
|
||||
openDialog({title:'Figyelem', confirmLabel:'Eltávolítás',
|
||||
message:'Magyarország eltávolítása nem ajánlott. Folytatja?',
|
||||
openDialog({title:'{{T "settings_security.figyelem"}}', confirmLabel:'{{T "common.eltavolitas"}}',
|
||||
message:'{{T "settings_security.magyarorszag_eltavolitasa_nem_ajanlott_f"}}',
|
||||
onConfirm:function(){ ov.allowed_countries.splice(ov.allowed_countries.indexOf(code), 1); },
|
||||
onCancel:function(){ el.checked = true; }});
|
||||
return;
|
||||
@@ -262,7 +261,7 @@ function openDialog(opts){
|
||||
function renderAppOverrides() {
|
||||
var el = document.getElementById('geo-app-overrides');
|
||||
if (!appOverrides || Object.keys(appOverrides).length === 0) {
|
||||
el.innerHTML = '<p class="form-hint">Nincs alkalmazás-specifikus beállítás. Minden alkalmazás a globális beállítást követi.</p>';
|
||||
el.innerHTML = '<p class="form-hint">{{T "settings_security.nincs_alkalmazas_specifikus_beallitas_mi"}}</p>';
|
||||
return;
|
||||
}
|
||||
var html = '';
|
||||
@@ -284,8 +283,8 @@ function openDialog(opts){
|
||||
html += '<span class="geo-tag geo-tag-sm">' + code + '</span>';
|
||||
}
|
||||
html += '</div>';
|
||||
html += '<button class="btn btn-sm btn-outline" onclick="editAppOverride(\'' + appName + '\')">Szerkesztés</button>';
|
||||
html += '<button class="btn btn-sm btn-danger-outline" onclick="removeAppOverride(\'' + appName + '\')">Törlés</button>';
|
||||
html += '<button class="btn btn-sm btn-outline" onclick="editAppOverride(\'' + appName + '\')">{{T "settings_security.szerkesztes"}}</button>';
|
||||
html += '<button class="btn btn-sm btn-danger-outline" onclick="removeAppOverride(\'' + appName + '\')">{{T "common.torles"}}</button>';
|
||||
html += '</div>';
|
||||
}
|
||||
el.innerHTML = html;
|
||||
@@ -298,7 +297,7 @@ function openDialog(opts){
|
||||
var checked = {};
|
||||
for (var i = 0; i < ov.allowed_countries.length; i++) checked[ov.allowed_countries[i]] = true;
|
||||
var html = '<div class="geo-edit-overlay" id="geo-edit-' + appName + '">';
|
||||
html += '<h4>Engedélyezett országok: ' + escHtml(appName) + '</h4>';
|
||||
html += '<h4>{{T "settings_security.engedelyezett_orszagok"}} ' + escHtml(appName) + '</h4>';
|
||||
html += '<div class="geo-edit-grid">';
|
||||
for (var i = 0; i < allCountries.length; i++) {
|
||||
var c = allCountries[i];
|
||||
@@ -307,7 +306,7 @@ function openDialog(opts){
|
||||
+ ' ' + escHtml(c.name) + ' (' + c.code + ')</label>';
|
||||
}
|
||||
html += '</div>';
|
||||
html += '<button class="btn btn-sm btn-primary" style="margin-top:.5rem" onclick="closeAppEdit(\'' + appName + '\')">Kész</button>';
|
||||
html += '<button class="btn btn-sm btn-primary" style="margin-top:.5rem" onclick="closeAppEdit(\'' + appName + '\')">{{T "settings_security.kesz"}}</button>';
|
||||
html += '</div>';
|
||||
document.getElementById('geo-app-overrides').innerHTML += html;
|
||||
});
|
||||
@@ -324,7 +323,7 @@ function openDialog(opts){
|
||||
var btn = document.getElementById('btn-geo-save');
|
||||
var status = document.getElementById('geo-status-msg');
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Mentés...';
|
||||
btn.textContent = '{{T "settings_security.mentes"}}';
|
||||
|
||||
var payload = {
|
||||
enabled: document.getElementById('geo-enabled').checked,
|
||||
@@ -339,21 +338,21 @@ function openDialog(opts){
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(d){
|
||||
if (d.ok) {
|
||||
status.innerHTML = '<div class="alert alert-info">' + (d.message || 'Mentve') + '</div>';
|
||||
status.innerHTML = '<div class="alert alert-info">' + (d.message || '{{T "settings_security.mentve"}}') + '</div>';
|
||||
// Save per-app overrides
|
||||
if (appOverrides && Object.keys(appOverrides).length > 0) {
|
||||
saveAllAppOverrides();
|
||||
}
|
||||
} else {
|
||||
status.innerHTML = '<div class="alert alert-error">' + (d.error || 'Hiba') + '</div>';
|
||||
status.innerHTML = '<div class="alert alert-error">' + (d.error || '{{T "common.hiba"}}') + '</div>';
|
||||
}
|
||||
})
|
||||
.catch(function(err){
|
||||
status.innerHTML = '<div class="alert alert-error">Hálózati hiba</div>';
|
||||
status.innerHTML = '<div class="alert alert-error">{{T "settings_security.halozati_hiba"}}</div>';
|
||||
})
|
||||
.finally(function(){
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Mentés és szinkronizálás';
|
||||
btn.textContent = '{{T "settings_security.mentes_es_szinkronizalas"}}';
|
||||
setTimeout(function(){ status.innerHTML = ''; }, 8000);
|
||||
});
|
||||
};
|
||||
@@ -375,7 +374,7 @@ function openDialog(opts){
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(d){
|
||||
var status = document.getElementById('geo-sync-status');
|
||||
status.textContent = d.ok ? 'Szinkronizálás elindítva...' : (d.error || 'Hiba');
|
||||
status.textContent = d.ok ? '{{T "settings_security.szinkronizalas_elinditva"}}' : (d.error || '{{T "common.hiba"}}');
|
||||
setTimeout(function(){
|
||||
fetch('/api/geo/status', {headers: csrfHeaders()})
|
||||
.then(function(r){return r.json()})
|
||||
@@ -383,7 +382,7 @@ function openDialog(opts){
|
||||
if (d.ok && d.data) {
|
||||
var sync = d.data.last_sync || '';
|
||||
var err = d.data.last_sync_error || '';
|
||||
status.innerHTML = sync ? ('Utolsó: ' + sync.substring(0,19).replace('T',' ')) : '';
|
||||
status.innerHTML = sync ? ('{{T "settings_security.utolso"}} ' + sync.substring(0,19).replace('T',' ')) : '';
|
||||
if (err) status.innerHTML += ' <span class="state-text-crit">' + escHtml(err) + '</span>';
|
||||
}
|
||||
});
|
||||
@@ -407,13 +406,13 @@ function openDialog(opts){
|
||||
<!-- Section: Recovery Info -->
|
||||
{{if .HasRetrievalPassword}}
|
||||
<div class="settings-card">
|
||||
<h3>Vészhelyzeti információk</h3>
|
||||
<h3>{{T "settings_security.veszhelyzeti_informaciok"}}</h3>
|
||||
<p class="settings-card-desc">
|
||||
Ezeket az adatokat mentse el biztos helyre. Újratelepítés esetén szükség lesz rájuk a rendszer visszaállításához.
|
||||
{{T "settings_security.ezeket_az_adatokat_mentse_el"}}
|
||||
</p>
|
||||
<div class="settings-grid">
|
||||
<div class="settings-row">
|
||||
<span class="settings-label">Ügyfél azonosító</span>
|
||||
<span class="settings-label">{{T "common.ugyfel_azonosito"}}</span>
|
||||
<span class="settings-value mono">{{.CustomerID}}</span>
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
@@ -421,22 +420,20 @@ function openDialog(opts){
|
||||
<span class="settings-value mono">{{.HubURL}}</span>
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
<span class="settings-label">Visszaállítási jelszó</span>
|
||||
<span class="settings-label">{{T "settings_security.visszaallitasi_jelszo"}}</span>
|
||||
<!-- R-249: the value is NOT in this page. The old markup rendered it into a
|
||||
display:none span, which hid it from the eye and from nothing else — a fetch of the
|
||||
page returned the plaintext. „Megjelenít" now asks the server for it. -->
|
||||
<span class="settings-value">
|
||||
<span id="retrieval-pw-slot" class="mono">••••••••••••••••</span>
|
||||
<button type="button" id="retrieval-pw-btn" class="btn btn-xs btn-outline" onclick="revealRetrievalPw()">Megjelenít</button>
|
||||
<button type="button" id="retrieval-pw-btn" class="btn btn-xs btn-outline" onclick="revealRetrievalPw()">{{T "settings_security.megjelenit"}}</button>
|
||||
<span id="retrieval-pw-err" class="form-hint" style="display:none;color:var(--red)"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
<span class="settings-label">Támogatás</span>
|
||||
<span class="settings-label">{{T "settings_security.tamogatas"}}</span>
|
||||
<span class="settings-value">
|
||||
<a href="mailto:{{.SupportEmail}}" style="color: var(--blue);">{{.SupportEmail}}</a>
|
||||
|
|
||||
<a href="{{.SupportURL}}" target="_blank" style="color: var(--blue);">felhom.eu/kapcsolat</a>
|
||||
{{T "settings_security.felhom_eu_kapcsolat"}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -451,7 +448,7 @@ function revealRetrievalPw() {
|
||||
err.style.display = 'none';
|
||||
if (btn.dataset.shown === '1') { // „Elrejt" — drop the value out of the DOM again
|
||||
slot.textContent = '••••••••••••••••';
|
||||
btn.textContent = 'Megjelenít';
|
||||
btn.textContent = '{{T "settings_security.megjelenit"}}';
|
||||
btn.dataset.shown = '';
|
||||
return;
|
||||
}
|
||||
@@ -463,16 +460,16 @@ function revealRetrievalPw() {
|
||||
}).then(function (r) { return r.json(); }).then(function (j) {
|
||||
btn.disabled = false;
|
||||
if (!j.ok) {
|
||||
err.textContent = j.error || 'A visszaállítási jelszó lekérése nem sikerült.';
|
||||
err.textContent = j.error || '{{T "settings_security.a_visszaallitasi_jelszo_lekerese_nem"}}';
|
||||
err.style.display = 'inline';
|
||||
return;
|
||||
}
|
||||
slot.textContent = j.data.password;
|
||||
btn.textContent = 'Elrejt';
|
||||
btn.textContent = '{{T "settings_security.elrejt"}}';
|
||||
btn.dataset.shown = '1';
|
||||
}).catch(function () {
|
||||
btn.disabled = false;
|
||||
err.textContent = 'A visszaállítási jelszó lekérése nem sikerült.';
|
||||
err.textContent = '{{T "settings_security.a_visszaallitasi_jelszo_lekerese_nem"}}';
|
||||
err.style.display = 'inline';
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user