feat: add e-mail change with confirmation and undo
Page at /email asks for the new address and the current password (shared failure counter with the password page, five requests per hour) and mails a one-hour confirmation link to the new address. Confirming writes the address and mails the old address a 24-hour undo link; undoing restores it, ends every session of the user and notifies the Admin (ADMIN_NOTIFY_EMAIL). Link pages show on GET and apply on POST; tokens are stored only as hashes, single use, and are blanked from every log line. New table owned by profile, German text, tests; review findings logged in the plan. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FocPJ75XPma7TcuYEMy8zm
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
3fd8f27127
commit
94c1d39c9d
@@ -0,0 +1,25 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class PendingEmailChange(models.Model):
|
||||
"""A one-time link for an e-mail change. Owned by `profile` (AD-19).
|
||||
|
||||
The token itself is never stored, only its SHA-256 hash (AD-9). A `confirm` row holds the
|
||||
address the user asked for (`new_address`) and the one they had then (`old_address`). An
|
||||
`undo` row holds the address to restore (`old_address`) and the one that was confirmed
|
||||
(`new_address`).
|
||||
"""
|
||||
|
||||
class Kind(models.TextChoices):
|
||||
CONFIRM = "confirm"
|
||||
UNDO = "undo"
|
||||
|
||||
user_key = models.CharField(max_length=256, db_index=True) # lower case
|
||||
sam = models.CharField(max_length=256) # exact sAMAccountName, for directory calls
|
||||
kind = models.CharField(max_length=10, choices=Kind.choices)
|
||||
token_hash = models.CharField(max_length=64, unique=True)
|
||||
old_address = models.CharField(max_length=254, blank=True)
|
||||
new_address = models.CharField(max_length=254)
|
||||
created_at = models.DateTimeField()
|
||||
expires_at = models.DateTimeField()
|
||||
used_at = models.DateTimeField(null=True, blank=True)
|
||||
Reference in New Issue
Block a user