from pydantic import BaseModel, EmailStr, Field, model_validator class RegisterRequest(BaseModel): company_name: str = Field(min_length=2, max_length=255) first_name: str = Field(min_length=1, max_length=100) last_name: str = Field(min_length=1, max_length=100) email: EmailStr password: str = Field(min_length=8, max_length=128) @model_validator(mode="after") def password_strength(self): pw = self.password if not any(c.isupper() for c in pw): raise ValueError("Password must contain at least one uppercase letter") if not any(c.isdigit() for c in pw): raise ValueError("Password must contain at least one digit") return self class LoginRequest(BaseModel): email: EmailStr password: str class RefreshRequest(BaseModel): refresh_token: str | None = None class PasswordResetRequest(BaseModel): email: EmailStr class PasswordResetConfirm(BaseModel): token: str new_password: str = Field(min_length=8, max_length=128) @model_validator(mode="after") def password_strength(self): pw = self.new_password if not any(c.isupper() for c in pw): raise ValueError("Password must contain at least one uppercase letter") if not any(c.isdigit() for c in pw): raise ValueError("Password must contain at least one digit") return self class TokenResponse(BaseModel): access_token: str refresh_token: str | None = None # Nur für API-Clients; Browser nutzt HttpOnly-Cookie token_type: str = "bearer" totp_required: bool = False partial_token: str | None = None class TotpSetupResponse(BaseModel): secret: str # base32 secret for manual entry otpauth_uri: str # otpauth://totp/... für QR-Code class TotpConfirmRequest(BaseModel): code: str = Field(min_length=6, max_length=6) class TotpLoginRequest(BaseModel): partial_token: str code: str = Field(min_length=6, max_length=6) class TotpDisableRequest(BaseModel): password: str code: str = Field(min_length=6, max_length=6) class AccessTokenResponse(BaseModel): access_token: str token_type: str = "bearer" class MessageResponse(BaseModel): message: str