mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-28 15:45:22 -04:00
fix(auth): centralize password and username validation constants (#4120)
Added PASSWORD_MIN_LENGTH and RESERVED_USERNAMES to src/constants.py as the single source of truth. Previously PASSWORD_MIN_LENGTH was hardcoded as 8 in four route handlers and all three JS validation paths; RESERVED_USERNAMES was an inline frozenset duplicated in core/auth.py, routes/assistant_routes.py, routes/research_routes.py, and src/task_scheduler.py. Added GET /api/auth/policy (unauthenticated) so the frontend reads the real values from the server instead of hardcoding them in JS. Added missing empty-username guard to /setup and admin POST /users. Both returned a misleading 500/409 on whitespace-only input. /signup already had the check; this makes all three consistent.
This commit is contained in:
+18
-5
@@ -328,6 +328,7 @@
|
||||
|
||||
let mode = 'login'; // 'login' | 'signup' | 'setup'
|
||||
let signupAllowed = false;
|
||||
let policy = { password_min_length: 8, reserved_usernames: [] };
|
||||
|
||||
const rememberToggle = document.getElementById('rememberToggle');
|
||||
|
||||
@@ -360,10 +361,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Check auth status
|
||||
// Check auth status and fetch policy in parallel, but don't block the
|
||||
// authenticated redirect on the policy response.
|
||||
const policyPromise = fetch('/api/auth/policy', { credentials: 'same-origin' }).catch(() => null);
|
||||
try {
|
||||
const res = await fetch('/api/auth/status', { credentials: 'same-origin' });
|
||||
const data = await res.json();
|
||||
const statusRes = await fetch('/api/auth/status', { credentials: 'same-origin' });
|
||||
const data = await statusRes.json();
|
||||
if (data.authenticated) {
|
||||
window.location.replace('/');
|
||||
return;
|
||||
@@ -374,6 +377,10 @@
|
||||
} else {
|
||||
setMode('login');
|
||||
}
|
||||
const policyRes = await policyPromise;
|
||||
if (policyRes && policyRes.ok) {
|
||||
policy = await policyRes.json();
|
||||
}
|
||||
} catch (e) {
|
||||
setMode('login');
|
||||
}
|
||||
@@ -426,8 +433,14 @@
|
||||
submitBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
if (password.length < 8) {
|
||||
errEl.textContent = 'Password must be at least 8 characters';
|
||||
if (password.length < policy.password_min_length) {
|
||||
errEl.textContent = `Password must be at least ${policy.password_min_length} characters`;
|
||||
errEl.style.display = 'block';
|
||||
submitBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
if (policy.reserved_usernames.includes(username.toLowerCase())) {
|
||||
errEl.textContent = 'This username is reserved';
|
||||
errEl.style.display = 'block';
|
||||
submitBtn.disabled = false;
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user