Files
2026-09-13 20:12:28 +01:00

133 lines
4.9 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>First-time setup · Martinhal ISDSS</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="auth-wrap">
<div class="auth-hero">
<div>
<div class="logo-lg">M</div>
<h1>Welcome to ISDSS</h1>
<p>Let's create the administrator account for this installation. This only happens once.</p>
<div class="feat">
<div>%SHIELD% This account has full administrative rights</div>
<div>%CHECK% You can add two-factor authentication right after</div>
<div>%LOGS% Everything from here on is recorded in the audit log</div>
</div>
</div>
<div class="foot">© 2026 Martinhal IT - Joao Vaz - Version 1.5 Patch 0.2</div>
</div>
<div class="auth-panel">
<div class="auth-form">
<div id="step-form">
<div class="setup-badge">Step 1 of 1 · First-time setup</div>
<h2>Create administrator</h2>
<p class="sub">These are the credentials you will use to sign in from now on.</p>
<div class="field">
<label>Username</label>
<input type="text" id="username" autocomplete="username" autofocus placeholder="admin">
<span class="hint">332 characters. Letters, numbers, dot, underscore or hyphen.</span>
</div>
<div class="field">
<label>Email address <span class="req-star">*</span></label>
<input type="email" id="email" required autocomplete="email" placeholder="admin@yourdomain.com">
<span class="hint">Required. Approval requests and system notifications are sent here.</span>
</div>
<div class="field">
<label>Password</label>
<input type="password" id="password" autocomplete="new-password">
<div class="pw-meter"><span id="pwBar"></span></div>
<span class="hint" id="pwHint">At least 10 characters, including a letter and a number.</span>
</div>
<div class="field">
<label>Confirm password</label>
<input type="password" id="confirm" autocomplete="new-password">
</div>
<button class="btn btn-primary" id="createBtn">Create account &amp; continue</button>
<div class="err-line" id="err"></div>
</div>
<div id="step-done" style="display:none">
<h2>All set</h2>
<p class="sub">Your administrator account has been created and you are now signed in.</p>
<p class="hint">Taking you to ISDSS…</p>
</div>
</div>
</div>
</div>
<script src="/js/app.js"></script>
<script>
document.querySelector('.auth-hero').innerHTML =
document.querySelector('.auth-hero').innerHTML
.replace('%SHIELD%', ICON.shield).replace('%CHECK%', ICON.check).replace('%LOGS%', ICON.logs);
const $ = (id) => document.getElementById(id);
// If setup was already completed (e.g. someone bookmarked this page), leave.
(async () => {
try {
const s = await api('/api/setup/status');
if (!s.needs_setup) location.href = '/login.html';
} catch (_) { /* ignore — the server will reject the POST anyway */ }
})();
// Lightweight strength indicator (guidance only; the server enforces the rules).
function strength(p) {
let s = 0;
if (p.length >= 10) s++;
if (p.length >= 14) s++;
if (/[A-Z]/.test(p) && /[a-z]/.test(p)) s++;
if (/[0-9]/.test(p)) s++;
if (/[^A-Za-z0-9]/.test(p)) s++;
return Math.min(s, 4);
}
$('password').addEventListener('input', () => {
const s = strength($('password').value);
const bar = $('pwBar');
bar.className = 'lvl-' + s;
bar.style.width = (s * 25) + '%';
});
async function create() {
$('err').textContent = '';
const payload = {
username: $('username').value.trim(),
email: $('email').value.trim(),
password: $('password').value,
confirm: $('confirm').value,
};
if (!payload.email) { $('err').textContent = 'An email address is required.'; return; }
if (!payload.username || !payload.password) {
$('err').textContent = 'Please fill in every field.'; return;
}
if (payload.password !== payload.confirm) {
$('err').textContent = 'The two passwords do not match.'; return;
}
$('createBtn').disabled = true;
$('createBtn').textContent = 'Creating…';
try {
await api('/api/setup', { method: 'POST', body: payload });
$('step-form').style.display = 'none';
$('step-done').style.display = 'block';
setTimeout(() => { location.href = '/view-data.html'; }, 1200);
} catch (e) {
$('err').textContent = e.message;
$('createBtn').disabled = false;
$('createBtn').textContent = 'Create account & continue';
}
}
$('createBtn').onclick = create;
$('confirm').addEventListener('keydown', (e) => { if (e.key === 'Enter') create(); });
</script>
</body>
</html>