35f46926a9
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
26 lines
1007 B
Python
26 lines
1007 B
Python
"""API key sessions: one row per login, stored as a SHA-256 hash."""
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import DateTime, ForeignKey, Integer, String
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from src.backend.database import Base
|
|
|
|
|
|
class ApiKey(Base):
|
|
"""One API key per login session.
|
|
|
|
Only the SHA-256 hex digest is stored, never the key. Dates are naive UTC.
|
|
"""
|
|
__tablename__ = "api_keys"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
user_id: Mapped[int] = mapped_column(
|
|
Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
key_hash: Mapped[str] = mapped_column(String(64), nullable=False, unique=True, index=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
expires_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
last_used_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
|