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:
+12
-1
@@ -13,6 +13,7 @@ let modalEl = null;
|
||||
// the endpoints list can flash a glow on that row. Cleared once the
|
||||
// animation fires.
|
||||
let _recentlyAddedEpId = null;
|
||||
let _authPolicy = { password_min_length: 8, reserved_usernames: [] };
|
||||
|
||||
function el(id) { return document.getElementById(id); }
|
||||
function esc(s) { return uiModule.esc(s); }
|
||||
@@ -343,6 +344,15 @@ function initSignupToggle() {
|
||||
}
|
||||
|
||||
function initAddUser() {
|
||||
fetch('/api/auth/policy', { credentials: 'same-origin' })
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(policy => {
|
||||
if (!policy) return;
|
||||
_authPolicy = policy;
|
||||
const admPw = el('adm-newPassword');
|
||||
if (admPw) admPw.placeholder = `Password (min ${policy.password_min_length})`;
|
||||
})
|
||||
.catch(() => {});
|
||||
el('adm-addBtn').addEventListener('click', async () => {
|
||||
const msg = el('adm-addMsg');
|
||||
msg.textContent = ''; msg.className = '';
|
||||
@@ -350,7 +360,8 @@ function initAddUser() {
|
||||
const password = el('adm-newPassword').value;
|
||||
const is_admin = el('adm-newIsAdmin').checked;
|
||||
if (!username) { msg.textContent = 'Username required'; msg.className = 'admin-error'; return; }
|
||||
if (password.length < 8) { msg.textContent = 'Password must be at least 8 characters'; msg.className = 'admin-error'; return; }
|
||||
if (password.length < _authPolicy.password_min_length) { msg.textContent = `Password must be at least ${_authPolicy.password_min_length} characters`; msg.className = 'admin-error'; return; }
|
||||
if (_authPolicy.reserved_usernames.includes(username.toLowerCase())) { msg.textContent = 'This username is reserved'; msg.className = 'admin-error'; return; }
|
||||
el('adm-addBtn').disabled = true;
|
||||
try {
|
||||
const res = await fetch('/api/auth/users', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password, is_admin }) });
|
||||
|
||||
+12
-1
@@ -11,6 +11,7 @@ import { isAltGrEvent } from './platform.js';
|
||||
|
||||
let initialized = false;
|
||||
let modalEl = null;
|
||||
let _authPolicy = { password_min_length: 8 };
|
||||
|
||||
function el(id) { return document.getElementById(id); }
|
||||
function esc(s) { return uiModule.esc(s); }
|
||||
@@ -2160,6 +2161,16 @@ function initAccount() {
|
||||
}
|
||||
}).catch(() => {});
|
||||
|
||||
// Update password placeholder and policy from server
|
||||
fetch('/api/auth/policy', { credentials: 'same-origin' })
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(policy => {
|
||||
if (!policy) return;
|
||||
_authPolicy = policy;
|
||||
const pwNew = el('settings-pw-new');
|
||||
if (pwNew) pwNew.placeholder = `New password (min ${policy.password_min_length})`;
|
||||
}).catch(() => {});
|
||||
|
||||
// Change password
|
||||
const saveBtn = el('settings-pw-save');
|
||||
const msgEl = el('settings-pw-msg');
|
||||
@@ -2170,7 +2181,7 @@ function initAccount() {
|
||||
const conf = el('settings-pw-confirm').value;
|
||||
msgEl.style.color = '';
|
||||
if (!cur || !nw) { msgEl.textContent = 'Fill in all fields'; msgEl.style.color = 'var(--red)'; return; }
|
||||
if (nw.length < 8) { msgEl.textContent = 'Min 8 characters'; msgEl.style.color = 'var(--red)'; return; }
|
||||
if (nw.length < _authPolicy.password_min_length) { msgEl.textContent = `Min ${_authPolicy.password_min_length} characters`; msgEl.style.color = 'var(--red)'; return; }
|
||||
if (nw !== conf) { msgEl.textContent = 'Passwords don\'t match'; msgEl.style.color = 'var(--red)'; return; }
|
||||
saveBtn.disabled = true;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user