security + reponsive

This commit is contained in:
2026-07-17 14:16:37 +07:00
parent 00e271fada
commit 57fc826ebf
16 changed files with 2124 additions and 2596 deletions

View File

@@ -194,6 +194,8 @@
id="resetPassword"
name="resetPassword"
placeholder="Enter a new password"
minlength="12"
maxlength="256"
required
class="w-full pl-10 pr-4 py-2.5 bg-surface-container-low border border-outline-variant/30 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent transition-all text-sm font-medium"
/>
@@ -211,6 +213,8 @@
id="resetConfirmPassword"
name="resetConfirmPassword"
placeholder="Re-enter new password"
minlength="12"
maxlength="256"
required
class="w-full pl-10 pr-4 py-2.5 bg-surface-container-low border border-outline-variant/30 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent transition-all text-sm font-medium"
/>
@@ -294,6 +298,8 @@
id="regPassword"
name="password"
placeholder="Create a password"
minlength="12"
maxlength="256"
required
class="w-full pl-10 pr-4 py-2.5 bg-surface-container-low border border-outline-variant/30 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent transition-all text-sm font-medium"
/>
@@ -314,7 +320,7 @@
<!-- Footer -->
<!-- <div class="mt-8 pt-6 border-t border-outline-variant/10 text-center">
<p class="text-[10px] text-on-surface-variant/60">Default credentials for demo: admin / admin</p>
<p class="text-[10px] text-on-surface-variant/60">Use the account provided by your administrator.</p>
</div> -->
</div>
@@ -419,13 +425,37 @@
return 'login';
};
document.addEventListener('DOMContentLoaded', () => {
const initialMode = getInitialMode();
const currentUser = localStorage.getItem('currentUser');
if (currentUser && initialMode !== 'reset') {
window.location.href = './index.html';
return;
document.addEventListener('DOMContentLoaded', async () => {
let initialMode = getInitialMode();
try {
const configResponse = await fetch('/api/auth/config', { cache: 'no-store' });
const config = await configResponse.json();
if (configResponse.ok && config.allowSelfRegistration === false) {
registerTab.classList.add('hidden');
if (initialMode === 'register') {
initialMode = 'login';
}
}
} catch (error) {
registerTab.classList.add('hidden');
if (initialMode === 'register') {
initialMode = 'login';
}
}
if (initialMode !== 'reset') {
try {
const sessionResponse = await fetch('/api/auth/session', { cache: 'no-store' });
const sessionData = await sessionResponse.json();
if (sessionResponse.ok && sessionData.success && sessionData.user) {
localStorage.setItem('currentUser', JSON.stringify(sessionData.user));
window.location.replace('./index.html');
return;
}
} catch (error) {
console.debug('No active session');
}
}
localStorage.removeItem('currentUser');
setMode(initialMode);
@@ -490,7 +520,7 @@
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, password })
body: JSON.stringify({ username, password, remember: rememberCheckbox.checked })
});
const data = await response.json();
@@ -579,8 +609,8 @@
return;
}
if (!newPassword || newPassword.length < 6) {
resetPasswordErrorMessage.textContent = 'New password must be at least 6 characters.';
if (!newPassword || newPassword.length < 12 || newPassword.length > 256) {
resetPasswordErrorMessage.textContent = 'New password must be between 12 and 256 characters.';
resetPasswordErrorMessage.classList.remove('hidden');
return;
}