From adbe3c25075b8825d6d07035c13f502aa7054663 Mon Sep 17 00:00:00 2001 From: Audiolib Date: Tue, 26 May 2026 13:21:23 +0200 Subject: [PATCH] Add password visibility toggle to login; auto-sync admin password from ENV - Login.tsx: Eye/EyeOff toggle button on password field - main.py: _seed_admin() now updates stored bcrypt hash when ENV password changed Co-Authored-By: Claude Sonnet 4.6 --- backend/app/main.py | 9 +++++++-- frontend/src/pages/Login.tsx | 27 +++++++++++++++++++-------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/backend/app/main.py b/backend/app/main.py index cf2af5f..6015bbe 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -10,7 +10,7 @@ from apscheduler.schedulers.asyncio import AsyncIOScheduler from .database import init_db, AsyncSessionLocal from .config import get_settings from .models import User, Library -from .services.auth import hash_password, create_token +from .services.auth import hash_password, verify_password, create_token from .services.file_watcher import start_file_watcher, stop_file_watcher from .services.podcast_feed import update_all_feeds from sqlalchemy import select @@ -25,7 +25,12 @@ async def _seed_admin(): settings = get_settings() async with AsyncSessionLocal() as db: result = await db.execute(select(User).where(User.is_admin == True)) - if result.scalar_one_or_none(): + existing = result.scalar_one_or_none() + if existing: + if not verify_password(settings.admin_password, existing.password_hash): + existing.password_hash = hash_password(settings.admin_password) + await db.commit() + logger.info("Admin-Passwort aus ENV aktualisiert.") return logger.info(f"Lege Admin-User an: {settings.admin_username}") admin = User( diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index f2469b6..40f18b9 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -1,11 +1,12 @@ import React, { useState } from 'react' import { useNavigate } from 'react-router-dom' -import { BookOpen, Loader2 } from 'lucide-react' +import { BookOpen, Loader2, Eye, EyeOff } from 'lucide-react' import { useAuthStore } from '../store/authStore' export default function Login() { const [username, setUsername] = useState('') const [password, setPassword] = useState('') + const [showPwd, setShowPwd] = useState(false) const [error, setError] = useState('') const { login, loading } = useAuthStore() const navigate = useNavigate() @@ -43,13 +44,23 @@ export default function Login() {
- setPassword(e.target.value)} - className="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 text-white placeholder-gray-500 focus:outline-none focus:ring-1 focus:ring-primary" - placeholder="••••••••" - /> +
+ setPassword(e.target.value)} + className="w-full bg-white/5 border border-white/10 rounded-lg px-3 py-2 pr-10 text-white placeholder-gray-500 focus:outline-none focus:ring-1 focus:ring-primary" + placeholder="••••••••" + /> + +
{error &&

{error}

}