| """ |
| BackupCode model — recovery codes for MFA. |
| |
| Maps to AGENT.md DBML: `backup_codes` table (Lines 237-243). |
| """ |
| from django.conf import settings |
| from django.db import models |
|
|
| from core.models import BaseModel |
|
|
|
|
| class BackupCode(BaseModel): |
| """ |
| One-time backup codes for MFA recovery. |
| |
| Codes are stored as hashes. Once used, `used_at` is set and the code |
| cannot be reused. |
| """ |
|
|
| user = models.ForeignKey( |
| settings.AUTH_USER_MODEL, |
| on_delete=models.CASCADE, |
| related_name="backup_codes", |
| ) |
| code_hash = models.CharField(max_length=255) |
| used_at = models.DateTimeField(null=True, blank=True) |
|
|
| class Meta: |
| db_table = "backup_codes" |
| ordering = ["created_at"] |
|
|
| def __str__(self) -> str: |
| status = "used" if self.used_at else "available" |
| return f"BackupCode for {self.user_id} [{status}]" |
|
|
| @property |
| def is_used(self) -> bool: |
| return self.used_at is not None |
|
|