Case-insensitive login, auto-matching after scan, per-library sources

- auth: username lookup is now case-insensitive via func.lower()
- scanner: trigger match_audiobook for each newly found item after scan
- matcher: read match_sources from library settings; refactored to loop
  over configured sources in priority order instead of hardcoded sequence
- schemas/routers: expose matchSources in LibraryOut API response
- Admin UI: pill-toggle for MusicBrainz/Open Library/Google Books per library

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Audiolib
2026-05-26 15:01:56 +02:00
parent b8984f0c2c
commit 6bb07ff873
6 changed files with 104 additions and 57 deletions

View File

@@ -1,7 +1,7 @@
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy import select, func
from ..database import AsyncSessionLocal
from ..dependencies import get_db, get_current_user
from ..models.user import User
@@ -42,7 +42,7 @@ def _build_user_out(user: User) -> UserOut:
@router.post("/login", response_model=LoginResponse)
async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)):
result = await db.execute(
select(User).where(User.username == body.username, User.is_active == True)
select(User).where(func.lower(User.username) == body.username.lower(), User.is_active == True)
)
user = result.scalar_one_or_none()
if not user or not verify_password(body.password, user.password_hash):