v0.319.0: the app page in panels, the login in one place, a password the box never had is said in words
gates / gates (push) Successful in 52s

- style A (operator 2026-10-16): hero, tab bar and every section are panels on --bg-1, one width, 16px apart;
  the install page's form groups use the same rule; the settings tab's 700px inner wrapper is gone
- „Belépés az alkalmazásba": name + password side by side, fetched on demand (R-254, R-709); pairing in app_login.go
- the empty-value rule: no stored value -> a sentence, never an eye; page and reveal endpoint share storedValuePresent
- „Cím és kulcsok" is rows (no Domain input, no disabled storage select, no install form); hint under the title
- tests red-proved: app_page_tuning_test.go (4); 36 app-page parity fixtures re-captured, 4 new; install fixtures unchanged

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-16 12:12:06 +02:00
parent 8d44416610
commit d170a2aecf
58 changed files with 6046 additions and 1776 deletions
@@ -223,7 +223,7 @@
<div class="app-section" style="margin-top:1rem">
<div class="app-section">
<h3>Hova tegyem a fájlokat?</h3>
<p class="form-hint">Ezeket a mappákat a Fájlkezelőben éred el. Előfordulhat, hogy először be kell jelentkezned a Fájlkezelőbe.</p>
<div class="datapath-list">
@@ -241,7 +241,7 @@
<div class="app-section" style="margin-top:1rem">
<div class="app-section">
<h3>Áthelyezés másik tárhelyre</h3>
<p class="form-hint">Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.</p>
<div style="display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;margin-top:.5rem">
@@ -291,7 +291,7 @@ function appMigrate(btn,app,label){
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -429,13 +429,13 @@ function appMigrate(btn,app,label){
</button>
</div>
<div id="progressCard" class="card" style="max-width:700px;display:none">
<div id="progressCard" class="app-section" style="display:none">
<h3>Folyamat</h3>
<div id="progressSteps"></div>
<div id="progressError" style="display:none;color:var(--crit);margin-top:1rem;font-weight:600"></div>
</div>
<div id="doneCard" class="card" style="max-width:700px;display:none">
<div id="doneCard" class="app-section" style="display:none">
<h3 style="color:var(--blue)">Kész!</h3>
<div style="margin-bottom:1rem">
<span id="doneFile" style="font-weight:600"></span>
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -309,13 +309,13 @@
</button>
</div>
<div id="progressCard" class="card" style="max-width:700px;display:none">
<div id="progressCard" class="app-section" style="display:none">
<h3>Folyamat</h3>
<div id="progressSteps"></div>
<div id="progressError" style="display:none;color:var(--crit);margin-top:1rem;font-weight:600"></div>
</div>
<div id="doneCard" class="card" style="max-width:700px;display:none">
<div id="doneCard" class="app-section" style="display:none">
<h3 style="color:var(--blue)">Kész!</h3>
<div style="margin-bottom:1rem">
<span id="doneFile" style="font-weight:600"></span>
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -227,7 +227,7 @@
<div class="app-section deploy-cross-drive">
<div class="app-section">
<h3>Biztonsági mentés</h3>
<div class="cross-drive-nightly">
@@ -207,19 +207,30 @@
<script>
function appShotGone(img) {
img.style.display = 'none';
var box = img.parentNode, left = false;
box.querySelectorAll('img').forEach(function (i) { if (i.style.display !== 'none') { left = true; } });
if (!left) { box.closest('.app-section').style.display = 'none'; }
}
</script>
<div class="app-section" data-screenshots-section="1">
<div class="app-screenshots" id="screenshots">
<img src="/static/assets/privatebin-screenshot-1.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/privatebin-screenshot-2.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/privatebin-screenshot-3.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
</div>
</div>
<div class="app-section" style="margin-top:1rem">
<div class="app-section">
<p class="form-hint" data-not-installable="1">Ez az alkalmazás most nem telepíthető.</p>
@@ -236,7 +247,7 @@
<p class="form-hint" style="margin-top:1rem" data-guide-missing="1">Ehhez az alkalmazáshoz még nem készült útmutató.</p>
<div class="app-section" data-guide-missing="1"><p>Ehhez az alkalmazáshoz még nem készült útmutató.</p></div>
<div class="app-sections">
@@ -218,14 +218,25 @@
<script>
function appShotGone(img) {
img.style.display = 'none';
var box = img.parentNode, left = false;
box.querySelectorAll('img').forEach(function (i) { if (i.style.display !== 'none') { left = true; } });
if (!left) { box.closest('.app-section').style.display = 'none'; }
}
</script>
<div class="app-section" data-screenshots-section="1">
<div class="app-screenshots" id="screenshots">
<img src="/static/assets/privatebin-screenshot-1.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/privatebin-screenshot-2.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/privatebin-screenshot-3.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
</div>
</div>
@@ -262,7 +273,7 @@
<div class="app-guide" data-guide="1" data-guide-checked="2.0.6">
<div class="app-section" style="margin-top:1rem" data-guide-section="1">
<div class="app-section" data-guide-section="1">
<h3>Első bekapcsolás</h3>
<p>Nyisd meg a böngészőben.</p>
@@ -270,7 +281,7 @@
</ol>
</div>
<div class="app-section" style="margin-top:1rem" data-guide-section="1">
<div class="app-section" data-guide-section="1">
<h3>Megosztás másokkal</h3>
@@ -278,7 +289,7 @@
</ol>
</div>
<div class="app-section" style="margin-top:1rem" data-guide-faq="1">
<div class="app-section" data-guide-faq="1">
<h3>Gyakori kérdések</h3>
<dl class="app-faq">
<dt>Hol vannak a fájlok?</dt>
@@ -205,19 +205,30 @@
<script>
function appShotGone(img) {
img.style.display = 'none';
var box = img.parentNode, left = false;
box.querySelectorAll('img').forEach(function (i) { if (i.style.display !== 'none') { left = true; } });
if (!left) { box.closest('.app-section').style.display = 'none'; }
}
</script>
<div class="app-section" data-screenshots-section="1">
<div class="app-screenshots" id="screenshots">
<img src="/static/assets/privatebin-screenshot-1.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/privatebin-screenshot-2.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/privatebin-screenshot-3.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
</div>
</div>
<div class="app-section" style="margin-top:1rem">
<div class="app-section">
<a href="/apps/privatebin/install" class="btn btn-primary" data-install-cta="1"
onclick="return checkBeforeDeploy(event, 'privatebin')">Telepítés</a>
@@ -235,7 +246,7 @@
<p class="form-hint" style="margin-top:1rem" data-guide-missing="1">Ehhez az alkalmazáshoz még nem készült útmutató.</p>
<div class="app-section" data-guide-missing="1"><p>Ehhez az alkalmazáshoz még nem készült útmutató.</p></div>
<div class="app-sections">
@@ -205,19 +205,30 @@
<script>
function appShotGone(img) {
img.style.display = 'none';
var box = img.parentNode, left = false;
box.querySelectorAll('img').forEach(function (i) { if (i.style.display !== 'none') { left = true; } });
if (!left) { box.closest('.app-section').style.display = 'none'; }
}
</script>
<div class="app-section" data-screenshots-section="1">
<div class="app-screenshots" id="screenshots">
<img src="/static/assets/grocy-screenshot-1.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/grocy-screenshot-2.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
<img src="/static/assets/grocy-screenshot-3.webp" alt="" class="app-screenshot"
onerror="this.style.display='none'">
onerror="appShotGone(this)">
</div>
</div>
<div class="app-section" style="margin-top:1rem">
<div class="app-section">
<a href="/apps/grocy/install" class="btn btn-primary" data-install-cta="1"
onclick="return checkBeforeDeploy(event, 'grocy')">Telepítés</a>
@@ -235,7 +246,7 @@
<p class="form-hint" style="margin-top:1rem" data-guide-missing="1">Ehhez az alkalmazáshoz még nem készült útmutató.</p>
<div class="app-section" data-guide-missing="1"><p>Ehhez az alkalmazáshoz még nem készült útmutató.</p></div>
<div class="app-sections">
+1 -1
View File
@@ -218,7 +218,7 @@
<div data-tab-panel="logs">
<div class="app-section" data-tab-panel="logs">
<div class="logs-container" id="logs-container">
<pre class="logs-output" id="logs-output">2026-09-14 line one
line two</pre>
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -249,7 +249,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="setup-gate-card">
<div class="app-section" id="setup-gate-card">
<h3>Első beállítás</h3>
<p>Most csak te éred el ezt az alkalmazást, amíg be vagy jelentkezve a vezérlőpultba. Így más nem hozhatja létre az első admin fiókot. Nyisd meg, és végezd el az első beállítást.</p>
<p class="form-hint">Ha kész, a doboz magától észreveszi, és mindenkinek megnyitja az alkalmazást.</p>
@@ -260,6 +260,9 @@
<div class="app-sections">
</div>
@@ -273,17 +276,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -321,46 +319,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="close-signup-card">
<div class="app-section" id="close-signup-card">
<h3>Regisztráció</h3>
<p>Ennél az alkalmazásnál bárki regisztrálhat, aki megtalálja a címét. Zárd le a regisztrációt most — a családtagjaidat utána is fel tudod venni.</p>
<button type="button" class="btn btn-sm btn-primary" onclick="appPress(this, '/apps/opengist/close-signup')">Regisztráció lezárása most</button>
@@ -247,6 +247,9 @@
<div class="app-sections">
</div>
@@ -260,17 +263,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -308,46 +306,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="close-signup-card">
<div class="app-section" id="close-signup-card">
<h3>Regisztráció</h3>
<p>Ennél az alkalmazásnál bárki regisztrálhat, aki megtalálja a címét. Zárd le a regisztrációt most — a családtagjaidat utána is fel tudod venni.</p>
<p class="form-hint" data-restarts-once="true">Ehhez az alkalmazás egyszer újraindul, és közben rövid ideig nem érhető el.</p>
@@ -248,6 +248,9 @@
<div class="app-sections">
</div>
@@ -261,17 +264,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -309,46 +307,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -229,7 +229,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -252,6 +252,9 @@
<div class="app-sections">
<div class="app-section">
<h3>Kezdeti belépési adatok</h3>
<table class="initcred-table">
@@ -297,22 +300,17 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row">
<div class="app-field-label">Cím</div>
<div class="app-field-value" data-app-address-row="1">paste.example.hu</div>
</div>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -401,46 +399,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -220,7 +220,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -242,6 +242,9 @@
<div class="app-sections">
</div>
@@ -255,17 +258,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -303,46 +301,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="install-hold-card">
<div class="app-section" id="install-hold-card">
<h3>Még csak te éred el</h3>
<p>A doboz most cseréli le az alkalmazás ismert első jelszavát egy saját, generált jelszóra. Addig csak te éred el, amíg be vagy jelentkezve a vezérlőpultba – más nem léphet be az ismert jelszóval. Ha a csere nem sikerül, változtasd meg a jelszót kézzel, és jelezd itt, hogy megtetted.</p>
</div>
@@ -245,6 +245,9 @@
<div class="app-sections">
</div>
@@ -258,17 +261,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -306,46 +304,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -241,6 +241,9 @@
<div class="app-sections">
<div class="app-section">
@@ -262,17 +265,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -310,46 +308,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -241,6 +241,9 @@
<div class="app-sections">
</div>
@@ -254,17 +257,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -302,46 +300,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -228,7 +228,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -251,6 +251,9 @@
<div class="app-sections">
</div>
@@ -264,17 +267,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -312,46 +310,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -219,7 +219,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -242,6 +242,9 @@
<div class="app-sections">
</div>
@@ -255,17 +258,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -303,46 +301,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -224,7 +224,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -246,6 +246,9 @@
<div class="app-sections">
<div class="app-section">
<h3>Kezdeti belépési adatok</h3>
<table class="initcred-table">
@@ -279,17 +282,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -378,46 +376,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -222,7 +222,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
<div class="flash flash-success">A mentés sikeresen elkészült.</div>
<div class="flash flash-error">A művelet most nem sikerült.</div>
@@ -245,6 +245,20 @@
<div class="app-sections">
<div class="app-section" id="app-login-panel" data-login-panel="1">
<h3>Belépés az alkalmazásba</h3>
<p>Az első bejelentkezéshez. Ha az alkalmazásban megváltoztatod a jelszót, itt a régi marad.</p>
<div class="app-login-pair">
<div class="app-login-field" data-login-field="ADMIN_PASSWORD">
<label class="app-login-label" for="field-ADMIN_PASSWORD">Admin jelszó mező</label>
<p class="form-hint" data-login-restored="ADMIN_PASSWORD">Mentésből töltötted vissza: a belépéshez a mentés idején érvényes jelszavad kell. Az itt tárolt érték nem az, ezért nem mutatjuk.</p>
</div>
</div>
</div>
<div class="app-section">
@@ -256,8 +270,8 @@
<div class="deploy-storage-info">
<h4>Adattárolás</h4>
<div class="app-section">
<h3>Adattárolás</h3>
<div class="settings-grid">
<div class="settings-row">
<span class="settings-label">Tárhely</span>
@@ -284,8 +298,8 @@
</div>
<div class="deploy-stale-data">
<h4>Korábbi adatok</h4>
<div class="app-section deploy-stale-data">
<h3>Korábbi adatok</h3>
<p class="form-hint" style="margin-bottom:1rem">
Az alkalmazás adatainak másolata megtalálható egy másik tárolón is.
Ez általában áthelyezés után marad hátra.
@@ -314,7 +328,7 @@
</div>
<div class="app-optional-config">
<div class="app-section">
<h3>Integrációk</h3>
<p class="config-group-desc">
Más telepített alkalmazásokkal való összekapcsolás. Az integráció automatikusan felfüggesztődik, ha bármelyik alkalmazás leáll, és újraaktiválódik indításkor.
@@ -438,7 +452,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Földrajzi korlátozás</h3>
<p class="config-group-desc">
Az alkalmazás egyéni országkorlátozás nélkül a globális beállítást követi.
@@ -573,7 +587,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Opcionális beállítások</h3>
<div class="config-group">
@@ -672,7 +686,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Email-küldés</h3>
<p class="config-group-desc">
Ez az alkalmazás tud emailt küldeni (pl. jelszó-visszaállítás, meghívók) a Felhom-on keresztül,
@@ -697,209 +711,33 @@
</form>
</div>
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row">
<div class="app-field-label">Cím</div>
<div class="app-field-value" data-app-address-row="1">paste.example.hu</div>
</div>
<form id="deploy-form" class="deploy-form">
<div class="form-section">
<h4>Automatikusan generált értékek</h4>
<p class="form-section-desc">Ezek az értékek automatikusan jöttek létre a telepítéskor.</p>
<div class="form-group form-group-auto">
<label>Titkos kulcs érték <span class="auto-generated-badge"><svg class="ico ico-sm"><use href="#i-check"/></svg> Automatikusan generálva</span></label>
<div class="input-with-button">
<input type="password" id="auto-field-SECRET_KEY" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','SECRET_KEY', this)">Megjelenítés</button>
</div>
</div>
<div class="form-group form-group-auto">
<label>Adatbázis neve itt </label>
<input type="text" id="auto-field-DB_NAME" class="form-control" value="privatebin_db" readonly>
</div>
<div class="form-group form-group-auto">
<label>Üres mező értéke </label>
</div>
<div class="app-field-row">
<div class="app-field-label">Tárhely</div>
<div class="app-field-value" data-app-storage-row="1">HDD egy</div>
</div>
<div class="form-section">
<h4>Beállítások</h4>
<div class="form-group">
<label for="field-LANG_SEL">
Felület nyelve
</label>
<select id="field-LANG_SEL" name="LANG_SEL" class="form-control"
disabled>
<option value="hu">Magyar nyelv</option>
</select>
<div class="app-field-row" data-setting-row="SECRET_KEY">
<div class="app-field-label">Titkos kulcs érték</div>
<div class="app-field-value input-with-button">
<input type="password" id="auto-field-SECRET_KEY" class="form-control" value="" placeholder="••••••••••••" readonly aria-label="Titkos kulcs érték">
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','SECRET_KEY', this)">Megjelenítés</button>
</div>
<div class="form-group">
<label for="field-ADMIN_PASSWORD">
Admin jelszó mező
<span class="required">*</span>
<span class="locked-hint">telepítés után nem módosítható</span>
</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_PASSWORD" class="form-control" value="" placeholder="••••••••••••" disabled>
</div>
<span class="form-hint">Mentésből töltötted vissza: a belépéshez a mentés idején érvényes jelszavad kell. Az itt tárolt érték nem az, ezért nem mutatjuk.</span>
</div>
<div class="form-group">
<label for="field-FLAG">
Kapcsoló mező itt
</label>
<label class="toggle">
<input type="checkbox" id="field-FLAG" name="FLAG" value="true"
disabled>
<span class="toggle-label">Igen</span>
</label>
<span class="form-hint">Egy kapcsoló leírása</span>
</div>
<div class="form-group">
<label for="field-HDD_PATH">
Adatok helye itt
<span class="required">*</span>
</label>
<select id="field-HDD_PATH" name="HDD_PATH" class="form-control"
disabled
onchange="checkStorageSpace(this)">
<option value="/mnt/hdd1" data-free-percent="50"
selected>
HDD egy — 500 GB szabad (alapértelmezett)
</option>
<option value="/mnt/nas" data-free-percent="90"
disabled
>
NAS egy — 900 GB szabad (hálózati tárhely nem használható)
</option>
<option value="/mnt/hdd2" data-free-percent="10"
>
HDD kettő — 100 GB szabad
</option>
</select>
<div id="storage-space-warn" class="form-hint" style="color:var(--warn);display:none">
<svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> A kiválasztott tárhely majdnem megtelt.
</div>
<div class="form-hint" style="margin-top:.4rem;opacity:.8">
<svg class="ico ico-sm"><use href="#i-info"/></svg> A kiválasztott meghajtón az alkalmazás <strong>fájljai</strong> (média, dokumentumok) tárolódnak.
Az <strong>adatbázis a gyors belső SSD-n</strong> fut — és az alkalmazással együtt készül róla biztonsági mentés.
</div>
</div>
<div class="form-group">
<label for="field-NOTE">
Megjegyzés mező
</label>
<input type="text" id="field-NOTE" name="NOTE"
class="form-control" value=""
placeholder="Írj ide valamit"
disabled>
</div>
</div>
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row" data-setting-row="LANG_SEL">
<div class="app-field-label">Felület nyelve</div>
<div class="app-field-value">Magyar nyelv</div>
</div>
</div>
</div>
@@ -937,46 +775,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -222,7 +222,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
<div class="flash flash-success">A mentés sikeresen elkészült.</div>
<div class="flash flash-error">A művelet most nem sikerült.</div>
@@ -245,6 +245,30 @@
<div class="app-sections">
<div class="app-section" id="app-login-panel" data-login-panel="1">
<h3>Belépés az alkalmazásba</h3>
<p>Az első bejelentkezéshez. Ha az alkalmazásban megváltoztatod a jelszót, itt a régi marad.</p>
<div class="app-login-pair">
<div class="app-login-field" data-login-field="ADMIN_USER">
<label class="app-login-label" for="field-ADMIN_USER">Admin név mező</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_USER" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" data-login-reveal="ADMIN_USER" onclick="revealAutoField('privatebin','ADMIN_USER', this, 'field-ADMIN_USER')">Megjelenítés</button>
</div>
</div>
<div class="app-login-field" data-login-field="ADMIN_PASSWORD">
<label class="app-login-label" for="field-ADMIN_PASSWORD">Admin jelszó mező</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_PASSWORD" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" data-login-reveal="ADMIN_PASSWORD" onclick="revealAutoField('privatebin','ADMIN_PASSWORD', this, 'field-ADMIN_PASSWORD')">Megjelenítés</button>
</div>
</div>
</div>
</div>
<div class="app-section">
@@ -256,8 +280,8 @@
<div class="deploy-storage-info">
<h4>Adattárolás</h4>
<div class="app-section">
<h3>Adattárolás</h3>
<div class="settings-grid">
<div class="settings-row">
<span class="settings-label">Tárhely</span>
@@ -284,8 +308,8 @@
</div>
<div class="deploy-stale-data">
<h4>Korábbi adatok</h4>
<div class="app-section deploy-stale-data">
<h3>Korábbi adatok</h3>
<p class="form-hint" style="margin-bottom:1rem">
Az alkalmazás adatainak másolata megtalálható egy másik tárolón is.
Ez általában áthelyezés után marad hátra.
@@ -314,7 +338,7 @@
</div>
<div class="app-optional-config">
<div class="app-section">
<h3>Integrációk</h3>
<p class="config-group-desc">
Más telepített alkalmazásokkal való összekapcsolás. Az integráció automatikusan felfüggesztődik, ha bármelyik alkalmazás leáll, és újraaktiválódik indításkor.
@@ -438,7 +462,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Földrajzi korlátozás</h3>
<p class="config-group-desc">
Az alkalmazás egyéni országkorlátozás nélkül a globális beállítást követi.
@@ -573,7 +597,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Opcionális beállítások</h3>
<div class="config-group">
@@ -672,7 +696,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Email-küldés</h3>
<p class="config-group-desc">
Ez az alkalmazás tud emailt küldeni (pl. jelszó-visszaállítás, meghívók) a Felhom-on keresztül,
@@ -697,212 +721,33 @@
</form>
</div>
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row">
<div class="app-field-label">Cím</div>
<div class="app-field-value" data-app-address-row="1">paste.example.hu</div>
</div>
<form id="deploy-form" class="deploy-form">
<div class="form-section">
<h4>Automatikusan generált értékek</h4>
<p class="form-section-desc">Ezek az értékek automatikusan jöttek létre a telepítéskor.</p>
<div class="form-group form-group-auto">
<label>Titkos kulcs érték <span class="auto-generated-badge"><svg class="ico ico-sm"><use href="#i-check"/></svg> Automatikusan generálva</span></label>
<div class="input-with-button">
<input type="password" id="auto-field-SECRET_KEY" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','SECRET_KEY', this)">Megjelenítés</button>
</div>
</div>
<div class="form-group form-group-auto">
<label>Adatbázis neve itt </label>
<input type="text" id="auto-field-DB_NAME" class="form-control" value="privatebin_db" readonly>
</div>
<div class="form-group form-group-auto">
<label>Üres mező értéke </label>
</div>
<div class="app-field-row">
<div class="app-field-label">Tárhely</div>
<div class="app-field-value" data-app-storage-row="1">HDD egy</div>
</div>
<div class="form-section">
<h4>Beállítások</h4>
<div class="form-group">
<label for="field-LANG_SEL">
Felület nyelve
</label>
<select id="field-LANG_SEL" name="LANG_SEL" class="form-control"
disabled>
<option value="hu">Magyar nyelv</option>
</select>
<div class="app-field-row" data-setting-row="SECRET_KEY">
<div class="app-field-label">Titkos kulcs érték</div>
<div class="app-field-value input-with-button">
<input type="password" id="auto-field-SECRET_KEY" class="form-control" value="" placeholder="••••••••••••" readonly aria-label="Titkos kulcs érték">
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','SECRET_KEY', this)">Megjelenítés</button>
</div>
<div class="form-group">
<label for="field-ADMIN_PASSWORD">
Admin jelszó mező
<span class="required">*</span>
<span class="locked-hint">telepítés után nem módosítható</span>
</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_PASSWORD" class="form-control" value="" placeholder="••••••••••••" disabled>
<button type="button" class="btn btn-sm btn-outline pw-toggle-btn"
onclick="revealPasswordField('privatebin', 'ADMIN_PASSWORD', this)"
title="Megjelenítés">&#128065;</button>
</div>
<span class="form-hint">Telepítéskor beállított kezdeti jelszó — ha az alkalmazásban megváltoztattad, az itt nem frissül.</span>
</div>
<div class="form-group">
<label for="field-FLAG">
Kapcsoló mező itt
</label>
<label class="toggle">
<input type="checkbox" id="field-FLAG" name="FLAG" value="true"
disabled>
<span class="toggle-label">Igen</span>
</label>
<span class="form-hint">Egy kapcsoló leírása</span>
</div>
<div class="form-group">
<label for="field-HDD_PATH">
Adatok helye itt
<span class="required">*</span>
</label>
<select id="field-HDD_PATH" name="HDD_PATH" class="form-control"
disabled
onchange="checkStorageSpace(this)">
<option value="/mnt/hdd1" data-free-percent="50"
selected>
HDD egy — 500 GB szabad (alapértelmezett)
</option>
<option value="/mnt/nas" data-free-percent="90"
disabled
>
NAS egy — 900 GB szabad (hálózati tárhely nem használható)
</option>
<option value="/mnt/hdd2" data-free-percent="10"
>
HDD kettő — 100 GB szabad
</option>
</select>
<div id="storage-space-warn" class="form-hint" style="color:var(--warn);display:none">
<svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> A kiválasztott tárhely majdnem megtelt.
</div>
<div class="form-hint" style="margin-top:.4rem;opacity:.8">
<svg class="ico ico-sm"><use href="#i-info"/></svg> A kiválasztott meghajtón az alkalmazás <strong>fájljai</strong> (média, dokumentumok) tárolódnak.
Az <strong>adatbázis a gyors belső SSD-n</strong> fut — és az alkalmazással együtt készül róla biztonsági mentés.
</div>
</div>
<div class="form-group">
<label for="field-NOTE">
Megjegyzés mező
</label>
<input type="text" id="field-NOTE" name="NOTE"
class="form-control" value=""
placeholder="Írj ide valamit"
disabled>
</div>
</div>
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row" data-setting-row="LANG_SEL">
<div class="app-field-label">Felület nyelve</div>
<div class="app-field-value">Magyar nyelv</div>
</div>
</div>
</div>
@@ -940,46 +785,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="setup-gate-card">
<div class="app-section" id="setup-gate-card">
<h3>Első beállítás</h3>
<p>Most csak te éred el ezt az alkalmazást, amíg be vagy jelentkezve a vezérlőpultba. Így más nem hozhatja létre az első admin fiókot. Nyisd meg, és végezd el az első beállítást.</p>
<p class="form-hint">Ha kész, nyomd meg ezt a gombot. Addig a telefonos alkalmazások és a család többi tagja nem éri el.</p>
@@ -248,6 +248,9 @@
<div class="app-sections">
</div>
@@ -261,17 +264,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -309,46 +307,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="setup-gate-card">
<div class="app-section" id="setup-gate-card">
<h3>Első beállítás</h3>
<p>Most csak te éred el ezt az alkalmazást, amíg be vagy jelentkezve a vezérlőpultba. Így más nem hozhatja létre az első admin fiókot. Nyisd meg, és végezd el az első beállítást.</p>
<p class="form-hint" data-restarts-once="true">Ehhez az alkalmazás egyszer újraindul, és közben rövid ideig nem érhető el.</p>
@@ -249,6 +249,9 @@
<div class="app-sections">
</div>
@@ -262,17 +265,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -310,46 +308,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="setup-gate-card">
<div class="app-section" id="setup-gate-card">
<h3>Első beállítás</h3>
<p>Most csak te éred el ezt az alkalmazást, amíg be vagy jelentkezve a vezérlőpultba. Így más nem hozhatja létre az első admin fiókot. Nyisd meg, és végezd el az első beállítást.</p>
<p class="form-hint">Ha kész, a doboz magától észreveszi, és mindenkinek megnyitja az alkalmazást.</p>
@@ -248,6 +248,9 @@
<div class="app-sections">
</div>
@@ -261,17 +264,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -309,46 +307,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="signup-card">
<div class="app-section" id="signup-card">
<h3>Regisztráció</h3>
<p>Az első admin fiók után a regisztráció zárva: idegen nem hozhat létre fiókot.</p>
<p class="form-hint" id="add-people">Családtagot így adhatsz hozzá: Admin panel → Users.</p>
@@ -248,6 +248,9 @@
<div class="app-sections">
</div>
@@ -261,17 +264,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -309,46 +307,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="signup-card">
<div class="app-section" id="signup-card">
<h3>Regisztráció</h3>
<p>Az első admin fiók után a regisztráció zárva: idegen nem hozhat létre fiókot.</p>
<p class="form-hint" id="add-people">Családtagot így adhatsz hozzá: Admin panel → Users.</p>
@@ -250,6 +250,9 @@
<div class="app-sections">
</div>
@@ -263,17 +266,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -311,46 +309,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="signup-card">
<div class="app-section" id="signup-card">
<h3>Regisztráció</h3>
<p>Az első admin fiók után a regisztráció zárva: idegen nem hozhat létre fiókot.</p>
<p class="form-hint" id="add-people">Családtagot így adhatsz hozzá: Admin panel → Users.</p>
@@ -249,6 +249,9 @@
<div class="app-sections">
</div>
@@ -262,17 +265,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -310,46 +308,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -237,7 +237,7 @@
</div>
<div class="app-section" style="margin-top:1rem" id="signup-card">
<div class="app-section" id="signup-card">
<h3>Regisztráció</h3>
<p>A regisztráció most nyitva, eddig: 14:05</p>
<p class="form-hint" id="add-people">Családtagot így adhatsz hozzá: Admin panel → Users.</p>
@@ -246,6 +246,9 @@
<div class="app-sections">
</div>
@@ -259,17 +262,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -307,46 +305,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -218,7 +218,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
<div class="flash flash-success">A mentés sikeresen elkészült.</div>
<div class="flash flash-error">A művelet most nem sikerült.</div>
@@ -240,6 +240,30 @@
<div class="app-sections">
<div class="app-section" id="app-login-panel" data-login-panel="1">
<h3>Belépés az alkalmazásba</h3>
<p>Az első bejelentkezéshez. Ha az alkalmazásban megváltoztatod a jelszót, itt a régi marad.</p>
<div class="app-login-pair">
<div class="app-login-field" data-login-field="ADMIN_USER">
<label class="app-login-label" for="field-ADMIN_USER">Admin név mező</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_USER" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" data-login-reveal="ADMIN_USER" onclick="revealAutoField('privatebin','ADMIN_USER', this, 'field-ADMIN_USER')">Megjelenítés</button>
</div>
</div>
<div class="app-login-field" data-login-field="ADMIN_PASSWORD">
<label class="app-login-label" for="field-ADMIN_PASSWORD">Admin jelszó mező</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_PASSWORD" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" data-login-reveal="ADMIN_PASSWORD" onclick="revealAutoField('privatebin','ADMIN_PASSWORD', this, 'field-ADMIN_PASSWORD')">Megjelenítés</button>
</div>
</div>
</div>
</div>
<div class="app-section">
@@ -251,8 +275,8 @@
<div class="deploy-storage-info">
<h4>Adattárolás</h4>
<div class="app-section">
<h3>Adattárolás</h3>
<div class="settings-grid">
<div class="settings-row">
<span class="settings-label">Tárhely</span>
@@ -266,7 +290,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Integrációk</h3>
<p class="config-group-desc">
Más telepített alkalmazásokkal való összekapcsolás. Az integráció automatikusan felfüggesztődik, ha bármelyik alkalmazás leáll, és újraaktiválódik indításkor.
@@ -390,7 +414,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Földrajzi korlátozás</h3>
<p class="config-group-desc">
Az alkalmazás egyéni országkorlátozás nélkül a globális beállítást követi.
@@ -525,7 +549,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Opcionális beállítások</h3>
<div class="config-group">
@@ -624,7 +648,7 @@
<div class="app-optional-config">
<div class="app-section">
<h3>Email-küldés</h3>
<p class="config-group-desc">
Ez az alkalmazás tud emailt küldeni (pl. jelszó-visszaállítás, meghívók) a Felhom-on keresztül,
@@ -644,184 +668,33 @@
</form>
</div>
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row">
<div class="app-field-label">Cím</div>
<div class="app-field-value" data-app-address-row="1">paste.example.hu</div>
</div>
<form id="deploy-form" class="deploy-form">
<div class="form-section">
<h4>Automatikusan generált értékek</h4>
<p class="form-section-desc">Ezek az értékek automatikusan jöttek létre a telepítéskor.</p>
<div class="form-group form-group-auto">
<label>Titkos kulcs érték <span class="auto-generated-badge"><svg class="ico ico-sm"><use href="#i-check"/></svg> Automatikusan generálva</span></label>
<div class="input-with-button">
<input type="password" id="auto-field-SECRET_KEY" class="form-control" value="" placeholder="••••••••••••" readonly>
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','SECRET_KEY', this)">Megjelenítés</button>
</div>
</div>
<div class="form-group form-group-auto">
<label>Adatbázis neve itt </label>
<input type="text" id="auto-field-DB_NAME" class="form-control" value="privatebin_db" readonly>
</div>
<div class="form-group form-group-auto">
<label>Üres mező értéke </label>
</div>
<div class="app-field-row">
<div class="app-field-label">Tárhely</div>
<div class="app-field-value" data-app-storage-row="1">/mnt/gone (nem elérhető)</div>
</div>
<div class="form-section">
<h4>Beállítások</h4>
<div class="form-group">
<label for="field-LANG_SEL">
Felület nyelve
</label>
<select id="field-LANG_SEL" name="LANG_SEL" class="form-control"
disabled>
<option value="hu">Magyar nyelv</option>
</select>
<div class="app-field-row" data-setting-row="SECRET_KEY">
<div class="app-field-label">Titkos kulcs érték</div>
<div class="app-field-value input-with-button">
<input type="password" id="auto-field-SECRET_KEY" class="form-control" value="" placeholder="••••••••••••" readonly aria-label="Titkos kulcs érték">
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','SECRET_KEY', this)">Megjelenítés</button>
</div>
<div class="form-group">
<label for="field-ADMIN_PASSWORD">
Admin jelszó mező
<span class="required">*</span>
<span class="locked-hint">telepítés után nem módosítható</span>
</label>
<div class="input-with-button">
<input type="password" id="field-ADMIN_PASSWORD" class="form-control" value="" placeholder="••••••••••••" disabled>
<button type="button" class="btn btn-sm btn-outline pw-toggle-btn"
onclick="revealPasswordField('privatebin', 'ADMIN_PASSWORD', this)"
title="Megjelenítés">&#128065;</button>
</div>
<span class="form-hint">Telepítéskor beállított kezdeti jelszó — ha az alkalmazásban megváltoztattad, az itt nem frissül.</span>
</div>
<div class="form-group">
<label for="field-FLAG">
Kapcsoló mező itt
</label>
<label class="toggle">
<input type="checkbox" id="field-FLAG" name="FLAG" value="true"
disabled>
<span class="toggle-label">Igen</span>
</label>
<span class="form-hint">Egy kapcsoló leírása</span>
</div>
<div class="form-group">
<label for="field-HDD_PATH">
Adatok helye itt
<span class="required">*</span>
</label>
<input type="text" id="field-HDD_PATH" name="HDD_PATH"
class="form-control" value=""
placeholder="/mnt/valahol"
required
disabled>
<span class="form-hint" style="color:var(--warn)">Nincs regisztrált adattároló — add meg kézzel az útvonalat</span>
</div>
<div class="form-group">
<label for="field-NOTE">
Megjegyzés mező
</label>
<input type="text" id="field-NOTE" name="NOTE"
class="form-control" value=""
placeholder="Írj ide valamit"
disabled>
</div>
</div>
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
<div class="app-field-row" data-setting-row="LANG_SEL">
<div class="app-field-label">Felület nyelve</div>
<div class="app-field-value">Magyar nyelv</div>
</div>
</div>
</div>
@@ -859,46 +732,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
@@ -220,7 +220,7 @@
<div class="deploy-container">
<div class="app-settings-tab">
@@ -242,6 +242,9 @@
<div class="app-sections">
</div>
@@ -255,17 +258,12 @@
<div class="app-section">
<div class="app-section" data-address-keys="1">
<h3>Cím és kulcsok</h3>
<form id="deploy-form" class="deploy-form">
</form>
<p class="app-field-hint" data-readonly-hint="1">Ezek telepítéskor jöttek létre, és nem módosíthatók.</p>
</div>
</div>
@@ -303,46 +301,9 @@ function appAfterStart(btn, slug, envVar) {
</script>
<script>
function checkStorageSpace(sel) {
var opt = sel.options[sel.selectedIndex];
var warn = document.getElementById('storage-space-warn');
if (!warn) return;
var freePct = parseFloat(opt.getAttribute('data-free-percent') || '100');
warn.style.display = freePct < 20 ? 'block' : 'none';
}
document.addEventListener('DOMContentLoaded', function() {
var sel = document.querySelector('select[onchange="checkStorageSpace(this)"]');
if (sel) checkStorageSpace(sel);
});
function revealPasswordField(stackName, envVar, btn) {
var el = document.getElementById('field-' + envVar);
if (!el) return;
if (btn.dataset.shown === '1') {
el.value = '';
el.type = 'password';
btn.dataset.shown = '';
return;
}
btn.disabled = true;
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
credentials: 'same-origin',
body: 'env_var=' + encodeURIComponent(envVar)
}).then(function (r) { return r.json(); }).then(function (j) {
btn.disabled = false;
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
el.value = j.data.value;
el.type = 'text';
el.dataset.revealed = '1';
btn.dataset.shown = '1';
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
}
function revealAutoField(stackName, envVar, btn, elId) {
var el = document.getElementById(elId || ('auto-field-' + envVar));
if (!el) return;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff