Add local auth: AuthProvider, mailer, sessions, /api/v1/auth
Pluggable AuthProvider interface with a local (email+password) implementation, and a Mailer interface (ConsoleMailer for dev, SMTPMailer for operators). The auth service owns registration, login, opaque session issuance, email verification, and password reset (which revokes prior sessions). Endpoints under /api/v1/auth; sessions are returned as a Bearer token and set as an HttpOnly cookie. Replaces the temporary X-User-Id shim: get_current_user now resolves a real session (Bearer or cookie). The open user-bootstrap endpoint is gone (registration replaces it). App logging is configured so the ConsoleMailer's verification/reset links are visible to self-hosters. Verified end-to-end on the deploy target, including the email-verification flow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Justin Paul <justin@jpaul.me>
This commit is contained in:
@@ -1,21 +1,11 @@
|
||||
from fastapi import APIRouter, status
|
||||
from fastapi import APIRouter
|
||||
|
||||
from app.api.deps import CurrentUser, SessionDep
|
||||
from app.schemas.user import UserCreate, UserRead
|
||||
from app.services import user_service
|
||||
from app.api.deps import CurrentUser
|
||||
from app.schemas.user import UserRead
|
||||
|
||||
router = APIRouter(prefix="/users", tags=["users"])
|
||||
|
||||
|
||||
@router.post("", response_model=UserRead, status_code=status.HTTP_201_CREATED)
|
||||
async def create_user(data: UserCreate, session: SessionDep) -> UserRead:
|
||||
# Open dev bootstrap until the auth slice; lets us create tree owners.
|
||||
user = await user_service.create_user(
|
||||
session, email=data.email, display_name=data.display_name
|
||||
)
|
||||
return UserRead.model_validate(user)
|
||||
|
||||
|
||||
@router.get("/me", response_model=UserRead)
|
||||
async def read_me(current: CurrentUser) -> UserRead:
|
||||
return UserRead.model_validate(current)
|
||||
|
||||
Reference in New Issue
Block a user