fix: re-upload login.html with correct encoding
This commit is contained in:
1 parent
249162fabb
commit
1d209b5daa
1 file changed
+65
-1
+65
-1
@@ -1 +1,65 @@
|
||||
PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPgogIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wIj4KICA8dGl0bGU+RnJhbWJlIEFkbWluIOKAlCBMb2dpbjwvdGl0bGU+CiAgPHN0eWxlPgogICAgKiwgKjo6YmVmb3JlLCAqOjphZnRlciB7IG1hcmdpbjogMDsgcGFkZGluZzogMDsgYm94LXNpemluZzogYm9yZGVyLWJveDsgfQogICAgYm9keSB7IGJhY2tncm91bmQ6ICMwZjBmMWE7IGNvbG9yOiAjZTBlMGUwOyBmb250LWZhbWlseTogLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCAnU2Vnb2UgVUknLCBSb2JvdG8sIHNhbnMtc2VyaWY7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyOyBtaW4taGVpZ2h0OiAxMDB2aDsgfQogICAgLmxvZ2luLWNhcmQgeyBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwyNTUsMjU1LDAuMDQpOyBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMDgpOyBib3JkZXItcmFkaXVzOiAxNnB4OyBwYWRkaW5nOiAyLjVyZW07IHdpZHRoOiAxMDAlOyBtYXgtd2lkdGg6IDM4MHB4OyB9CiAgICAubG9naW4taGVhZGVyIHsgdGV4dC1hbGlnbjogY2VudGVyOyBtYXJnaW4tYm90dG9tOiAycmVtOyB9CiAgICAubG9naW4taGVhZGVyIGltZyB7IHdpZHRoOiA1NnB4OyBoZWlnaHQ6IDU2cHg7IGJvcmRlci1yYWRpdXM6IDEycHg7IG1hcmdpbi1ib3R0b206IDFyZW07IH0KICAgIC5sb2dpbi1oZWFkZXIgaDEgeyBmb250LXNpemU6IDEuNHJlbTsgZm9udC13ZWlnaHQ6IDMwMDsgfQogICAgLmxvZ2luLWhlYWRlciBwIHsgZm9udC1zaXplOiAwLjhyZW07IGNvbG9yOiAjNjY2OyBtYXJnaW4tdG9wOiAwLjI1cmVtOyB9CiAgICAuZm9ybS1ncm91cCB7IG1hcmdpbi1ib3R0b206IDEuMjVyZW07IH0KICAgIC5mb3JtLWdyb3VwIGxhYmVsIHsgZGlzcGxheTogYmxvY2s7IGZvbnQtc2l6ZTogMC44cmVtOyBjb2xvcjogIzg4ODsgbWFyZ2luLWJvdHRvbTogMC40cmVtOyB9CiAgICAuZm9ybS1ncm91cCBpbnB1dCB7IHdpZHRoOiAxMDAlOyBwYWRkaW5nOiAxMHB4IDE0cHg7IGJhY2tncm91bmQ6IHJnYmEoMjU1LDI1NSwyNTUsMC4wNik7IGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC4xMik7IGJvcmRlci1yYWRpdXM6IDhweDsgY29sb3I6ICNlMGUwZTA7IGZvbnQtc2l6ZTogMC45NXJlbTsgb3V0bGluZTogbm9uZTsgdHJhbnNpdGlvbjogYm9yZGVyLWNvbG9yIDAuMTVzOyB9CiAgICAuZm9ybS1ncm91cCBpbnB1dDpmb2N1cyB7IGJvcmRlci1jb2xvcjogIzYzNjZmMTsgfQogICAgLmxvZ2luLWJ0biB7IHdpZHRoOiAxMDAlOyBwYWRkaW5nOiAxMXB4OyBiYWNrZ3JvdW5kOiByZ2JhKDk5LDEwMiwyNDEsMC4yKTsgYm9yZGVyOiAxcHggc29saWQgIzYzNjZmMTsgYm9yZGVyLXJhZGl1czogOHB4OyBjb2xvcjogI2E1YjRmYzsgZm9udC1zaXplOiAwLjk1cmVtOyBjdXJzb3I6IHBvaW50ZXI7IHRyYW5zaXRpb246IGFsbCAwLjE1czsgfQogICAgLmxvZ2luLWJ0bjpob3ZlciB7IGJhY2tncm91bmQ6IHJnYmEoOTksMTAyLDI0MSwwLjM1KTsgfQogICAgLmxvZ2luLWJ0bjpkaXNhYmxlZCB7IG9wYWNpdHk6IDAuNTsgY3Vyc29yOiBub3QtYWxsb3dlZDsgfQogICAgLmVycm9yLW1zZyB7IGJhY2tncm91bmQ6IHJnYmEoMjM5LDY4LDY4LDAuMTIpOyBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDIzOSw2OCw2OCwwLjMpOyBib3JkZXItcmFkaXVzOiA4cHg7IGNvbG9yOiAjZmNhNWE1OyBmb250LXNpemU6IDAuODVyZW07IHBhZGRpbmc6IDhweCAxMnB4OyBtYXJnaW4tYm90dG9tOiAxcmVtOyBkaXNwbGF5OiBub25lOyB9CiAgPC9zdHlsZT4KPC9oZWFkPgo8Ym9keT4KICA8ZGl2IGNsYXNzPSJsb2dpbi1jYXJkIj4KICAgIDxkaXYgY2xhc3M9ImxvZ2luLWhlYWRlciI+CiAgICAgIDxpbWcgc3JjPSIvaW1nL2ljb24ucG5nIiBhbHQ9IkZyYW1iZSIgb25lcnJvcj0idGhpcy5zdHlsZS5kaXNwbGF5PSdub25lJyI+CiAgICAgIDxoMT5GcmFtYmUgQWRtaW48L2gxPgogICAgICA8cD5TaWduIGluIHRvIG1hbmFnZSB5b3VyIGZyYW1lczwvcD4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0iZXJyb3ItbXNnIiBpZD0iZXJyb3ItbXNnIj48L2Rpdj4KICAgIDxkaXYgY2xhc3M9ImZvcm0tZ3JvdXAiPgogICAgICA8bGFiZWwgZm9yPSJ1c2VybmFtZSI+VXNlcm5hbWU8L2xhYmVsPgogICAgICA8aW5wdXQgdHlwZT0idGV4dCIgaWQ9InVzZXJuYW1lIiBhdXRvY29tcGxldGU9InVzZXJuYW1lIiBhdXRvZm9jdXM+CiAgICA8L2Rpdj4KICAgIDxkaXYgY2xhc3M9ImZvcm0tZ3JvdXAiPgogICAgICA8bGFiZWwgZm9yPSJwYXNzd29yZCI+UGFzc3dvcmQ8L2xhYmVsPgogICAgICA8aW5wdXQgdHlwZT0icGFzc3dvcmQiIGlkPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJjdXJyZW50LXBhc3N3b3JkIj4KICAgIDwvZGl2PgogICAgPGJ1dHRvbiBjbGFzcz0ibG9naW4tYnRuIiBpZD0ibG9naW4tYnRuIiBvbmNsaWNrPSJkb0xvZ2luKCkiPlNpZ24gSW48L2J1dHRvbj4KICA8L2Rpdj4KICA8c2NyaXB0PgogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3N3b3JkJykuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGZ1bmN0aW9uKGUpIHsgaWYgKGUua2V5ID09PSAnRW50ZXInKSBkb0xvZ2luKCk7IH0pOwogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VzZXJuYW1lJykuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGZ1bmN0aW9uKGUpIHsgaWYgKGUua2V5ID09PSAnRW50ZXInKSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFzc3dvcmQnKS5mb2N1cygpOyB9KTsKCiAgICBhc3luYyBmdW5jdGlvbiBkb0xvZ2luKCkgewogICAgICB2YXIgYnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvZ2luLWJ0bicpOwogICAgICB2YXIgZXJyRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXJyb3ItbXNnJyk7CiAgICAgIGJ0bi5kaXNhYmxlZCA9IHRydWU7CiAgICAgIGVyckVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgIHZhciB1c2VybmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1c2VybmFtZScpLnZhbHVlLnRyaW0oKTsKICAgICAgdmFyIHBhc3N3b3JkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3N3b3JkJykudmFsdWU7CiAgICAgIGlmICghdXNlcm5hbWUgfHwgIXBhc3N3b3JkKSB7IGVyckVsLnRleHRDb250ZW50ID0gJ1BsZWFzZSBlbnRlciBib3RoIHVzZXJuYW1lIGFuZCBwYXNzd29yZCc7IGVyckVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOyBidG4uZGlzYWJsZWQgPSBmYWxzZTsgcmV0dXJuOyB9CiAgICAgIHRyeSB7CiAgICAgICAgdmFyIHIgPSBhd2FpdCBmZXRjaCgnL2FwaS9hdXRoL2xvZ2luJywgeyBtZXRob2Q6ICdQT1NUJywgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgdXNlcm5hbWU6IHVzZXJuYW1lLCBwYXNzd29yZDogcGFzc3dvcmQgfSkgfSk7CiAgICAgICAgdmFyIGQgPSBhd2FpdCByLmpzb24oKTsKICAgICAgICBpZiAoZC5vaykgeyB3aW5kb3cubG9jYXRpb24uaHJlZiA9ICcvYWRtaW4nOyB9CiAgICAgICAgZWxzZSB7IGVyckVsLnRleHRDb250ZW50ID0gZC5lcnJvciB8fCAnTG9naW4gZmFpbGVkJzsgZXJyRWwLine truncated
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Frambe Admin — Login</title>
|
||||
<style>
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { background: #0f0f1a; color: #e0e0e0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; }
|
||||
.login-card { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 16px; padding: 2.5rem; width: 100%; max-width: 380px; }
|
||||
.login-header { text-align: center; margin-bottom: 2rem; }
|
||||
.login-header img { width: 56px; height: 56px; border-radius: 12px; margin-bottom: 1rem; }
|
||||
.login-header h1 { font-size: 1.4rem; font-weight: 300; }
|
||||
.login-header p { font-size: 0.8rem; color: #666; margin-top: 0.25rem; }
|
||||
.form-group { margin-bottom: 1.25rem; }
|
||||
.form-group label { display: block; font-size: 0.8rem; color: #888; margin-bottom: 0.4rem; }
|
||||
.form-group input { width: 100%; padding: 10px 14px; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12); border-radius: 8px; color: #e0e0e0; font-size: 0.95rem; outline: none; transition: border-color 0.15s; }
|
||||
.form-group input:focus { border-color: #6366f1; }
|
||||
.login-btn { width: 100%; padding: 11px; background: rgba(99,102,241,0.2); border: 1px solid #6366f1; border-radius: 8px; color: #a5b4fc; font-size: 0.95rem; cursor: pointer; transition: all 0.15s; }
|
||||
.login-btn:hover { background: rgba(99,102,241,0.35); }
|
||||
.login-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.error-msg { background: rgba(239,68,68,0.12); border: 1px solid rgba(239,68,68,0.3); border-radius: 8px; color: #fca5a5; font-size: 0.85rem; padding: 8px 12px; margin-bottom: 1rem; display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-card">
|
||||
<div class="login-header">
|
||||
<img src="/img/icon.png" alt="Frambe" onerror="this.style.display='none'">
|
||||
<h1>Frambe Admin</h1>
|
||||
<p>Sign in to manage your frames</p>
|
||||
</div>
|
||||
<div class="error-msg" id="error-msg"></div>
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" autocomplete="username" autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" autocomplete="current-password">
|
||||
</div>
|
||||
<button class="login-btn" id="login-btn" onclick="doLogin()">Sign In</button>
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById('password').addEventListener('keydown', function(e) { if (e.key === 'Enter') doLogin(); });
|
||||
document.getElementById('username').addEventListener('keydown', function(e) { if (e.key === 'Enter') document.getElementById('password').focus(); });
|
||||
|
||||
async function doLogin() {
|
||||
var btn = document.getElementById('login-btn');
|
||||
var errEl = document.getElementById('error-msg');
|
||||
btn.disabled = true;
|
||||
errEl.style.display = 'none';
|
||||
var username = document.getElementById('username').value.trim();
|
||||
var password = document.getElementById('password').value;
|
||||
if (!username || !password) { errEl.textContent = 'Please enter both username and password'; errEl.style.display = 'block'; btn.disabled = false; return; }
|
||||
try {
|
||||
var r = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: username, password: password }) });
|
||||
var d = await r.json();
|
||||
if (d.ok) { window.location.href = '/admin'; }
|
||||
else { errEl.textContent = d.error || 'Login failed'; errEl.style.display = 'block'; }
|
||||
} catch (e) { errEl.textContent = 'Connection error'; errEl.style.display = 'block'; }
|
||||
btn.disabled = false;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user