Files
Davide Scaini 1b4f0318e7 feat: self-service password reset via email (Phase 4)
- email column on users (migration-safe ALTER TABLE)
- email_reset_tokens table (1h TTL, single-use)
- smtp.py: send via STARTTLS, config from CLI/env vars
- POST /api/auth/request-reset — sends reset link, always 200 (no email leak)
- POST /api/auth/reset-password-token — consumes email token
- GET/POST /api/me/email — users can register/update their email
- reset-password page: email form primary, admin code form as toggle,
  token form shown automatically when ?token= is in URL
- CLI: --smtp-host/port/user/password/from (BINCIO_SMTP_* env vars)
2026-06-03 16:03:08 +02:00

59 lines
1.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Pydantic request/response models for bincio-auth."""
from __future__ import annotations
from pydantic import BaseModel, Field
class LoginRequest(BaseModel):
handle: str = Field(..., description="User handle")
password: str = Field(..., description="User password")
class LoginResponse(BaseModel):
ok: bool = True
handle: str
display_name: str
is_admin: bool
wiki_access: bool
activity_access: bool
class RegisterRequest(BaseModel):
code: str = Field(..., description="Invite code")
handle: str = Field(..., description="Desired username (lowercase, 130 chars)")
password: str = Field(..., description="Password (min 8 characters)")
display_name: str = Field(default="", description="Full name (optional)")
class RegisterResponse(BaseModel):
ok: bool = True
handle: str
class ResetPasswordRequest(BaseModel):
handle: str
code: str = Field(..., description="One-time reset code (24 h TTL)")
password: str = Field(..., description="New password (min 8 chars)")
class CreateInviteRequest(BaseModel):
grants_activity: bool = Field(default=False)
class RequestResetRequest(BaseModel):
email: str
class ResetPasswordTokenRequest(BaseModel):
token: str
password: str = Field(..., min_length=8, description="New password (min 8 chars)")
class SetEmailRequest(BaseModel):
email: str
class GenericResponse(BaseModel):
ok: bool = True