Arag / app /schemas /auth.py
baqir3033
Isolate author and superadmin sessions to stop surprise logouts.
8162879
Raw
History Blame Contribute Delete
2.12 kB
"""Author RAG Chatbot SaaS — Pydantic Schemas for Auth."""
from typing import Literal
from pydantic import BaseModel, EmailStr, Field, field_validator
ClientId = Literal["author", "superadmin"]
class RegisterRequest(BaseModel):
"""Request body for author registration."""
email: EmailStr
password: str = Field(..., min_length=8, max_length=128)
full_name: str = Field(..., min_length=1, max_length=255)
referral_code: str | None = Field(None, max_length=50, description="Optional referral code from ?ref=")
@field_validator("password")
@classmethod
def password_strength(cls, v: str) -> str:
"""Enforce password complexity: uppercase, digit, special char."""
if not any(c.isupper() for c in v):
raise ValueError("Password must contain at least one uppercase letter")
if not any(c.isdigit() for c in v):
raise ValueError("Password must contain at least one digit")
if not any(c in "!@#$%^&*()_+-=[]{}|;':\",./<>?" for c in v):
raise ValueError("Password must contain at least one special character")
return v
class LoginRequest(BaseModel):
"""Request body for author/superadmin login."""
email: str = Field(..., min_length=1) # Accepts email or username
password: str = Field(..., min_length=1)
client_id: ClientId = "author"
class RefreshRequest(BaseModel):
"""Request body for token refresh."""
refresh_token: str = ""
client_id: ClientId = "author"
class LogoutRequest(BaseModel):
"""Request body for scoped logout."""
client_id: ClientId = "author"
class TokenResponse(BaseModel):
"""Response containing JWT token pair."""
access_token: str
refresh_token: str
token_type: str = "bearer"
author_slug: str | None = None
is_superadmin: bool = False
role: str | None = None
class UserResponse(BaseModel):
"""Public user profile response."""
id: str
email: str
full_name: str | None
role: str
bot_name: str
timezone: str
chatbot_is_active: bool
model_config = {"from_attributes": True}