6989a98d75
- Arkitektur: docs/auth/passwordless-architecture.md - Backend: iom/quixzoom-auth-service/ (FastAPI + Redis) - Webb: quixzoom-market-pages/se/login/ (QR-kod + polling) - App: iom/quixzoom-app/src/features/auth/ (push + deep links) Flöde: QR-kod → app-godkännande → webb-inloggad
101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""
|
|
Device model for passwordless authentication
|
|
Represents a registered mobile device (app)
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
from enum import Enum
|
|
from pydantic import BaseModel, Field
|
|
import uuid
|
|
|
|
|
|
class DevicePlatform(str, Enum):
|
|
"""Supported device platforms"""
|
|
IOS = "ios"
|
|
ANDROID = "android"
|
|
WEB = "web"
|
|
OTHER = "other"
|
|
|
|
|
|
class DeviceStatus(str, Enum):
|
|
"""Device status"""
|
|
ACTIVE = "active"
|
|
REVOKED = "revoked"
|
|
SUSPENDED = "suspended"
|
|
|
|
|
|
class Device(BaseModel):
|
|
"""Device database model"""
|
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
user_id: str = Field(..., description="Associated user ID")
|
|
device_name: str = Field(..., description="Human-readable device name")
|
|
platform: DevicePlatform = Field(..., description="Device platform")
|
|
|
|
# Device fingerprinting
|
|
public_key: str = Field(..., description="Device public key for challenge signing")
|
|
device_fingerprint: str = Field(..., description="Unique device fingerprint hash")
|
|
|
|
# Metadata
|
|
push_token: Optional[str] = Field(None, description="Push notification token")
|
|
last_ip: Optional[str] = Field(None, description="Last known IP address")
|
|
last_user_agent: Optional[str] = Field(None, description="Last user agent")
|
|
|
|
# Status
|
|
status: DeviceStatus = Field(default=DeviceStatus.ACTIVE)
|
|
|
|
# Timestamps
|
|
created_at: datetime = Field(default_factory=datetime.utcnow)
|
|
updated_at: datetime = Field(default_factory=datetime.utcnow)
|
|
last_used_at: Optional[datetime] = Field(None)
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"id": "dev_123456789",
|
|
"user_id": "user_abc123",
|
|
"device_name": "iPhone 15 Pro",
|
|
"platform": "ios",
|
|
"public_key": "-----BEGIN PUBLIC KEY-----\n...",
|
|
"device_fingerprint": "sha256:abc123...",
|
|
"status": "active",
|
|
"created_at": "2024-01-15T10:30:00Z"
|
|
}
|
|
}
|
|
|
|
|
|
class DeviceCreate(BaseModel):
|
|
"""Request model for device registration"""
|
|
user_id: str = Field(..., description="User ID to associate with device")
|
|
device_name: str = Field(..., min_length=1, max_length=100)
|
|
platform: DevicePlatform
|
|
public_key: str = Field(..., min_length=100, description="Device public key")
|
|
device_fingerprint: str = Field(..., min_length=32, description="Device fingerprint")
|
|
push_token: Optional[str] = Field(None, max_length=500)
|
|
|
|
|
|
class DeviceUpdate(BaseModel):
|
|
"""Request model for device update"""
|
|
device_name: Optional[str] = Field(None, min_length=1, max_length=100)
|
|
push_token: Optional[str] = Field(None, max_length=500)
|
|
status: Optional[DeviceStatus] = None
|
|
|
|
|
|
class DeviceResponse(BaseModel):
|
|
"""Response model for device operations"""
|
|
id: str
|
|
user_id: str
|
|
device_name: str
|
|
platform: DevicePlatform
|
|
status: DeviceStatus
|
|
created_at: datetime
|
|
last_used_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class DeviceListResponse(BaseModel):
|
|
"""Response model for listing devices"""
|
|
devices: list[DeviceResponse]
|
|
total: int |