feat: replace email flows with in-app notifications
Add recipient notification detail and filtering, a queued admin composer, and contextual automatic titles. Retire email delivery, obsolete auth routes, newsletter data, and related templates and settings.
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
from django.contrib.auth.models import AbstractUser, UserManager as DjangoUserManager
|
||||
from django.utils import timezone
|
||||
from django.db import models
|
||||
|
||||
import uuid
|
||||
from datetime import timedelta
|
||||
|
||||
from core.media import (
|
||||
delete_image_derivatives_by_name,
|
||||
get_image_previous_name,
|
||||
@@ -80,11 +76,6 @@ class User(AbstractUser, BaseModel):
|
||||
)
|
||||
is_email_verified = models.BooleanField(default=False)
|
||||
is_mobile_verified = models.BooleanField(default=False)
|
||||
email_verification_token = models.UUIDField(default=uuid.uuid4, unique=True)
|
||||
email_verification_sent_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
password_reset_token = models.UUIDField(null=True, blank=True, unique=True)
|
||||
password_reset_token_expires_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
USERNAME_FIELD = 'username'
|
||||
REQUIRED_FIELDS = ['mobile']
|
||||
@@ -95,6 +86,7 @@ class User(AbstractUser, BaseModel):
|
||||
db_table = 'users'
|
||||
verbose_name = 'User'
|
||||
verbose_name_plural = 'Users'
|
||||
permissions = [('send_notification', 'Can send in-app notifications')]
|
||||
|
||||
def __str__(self):
|
||||
identity = self.mobile or self.email or self.username
|
||||
@@ -124,21 +116,15 @@ class User(AbstractUser, BaseModel):
|
||||
is_active=True,
|
||||
).exists()
|
||||
|
||||
def regenerate_verification_token(self):
|
||||
self.email_verification_token = uuid.uuid4()
|
||||
self.save(update_fields=['email_verification_token'])
|
||||
|
||||
def set_password_reset_token(self):
|
||||
"""Generates a new password reset token and sets its expiry."""
|
||||
self.password_reset_token = uuid.uuid4()
|
||||
self.password_reset_token_expires_at = timezone.now() + timedelta(hours=1)
|
||||
self.save(update_fields=['password_reset_token', 'password_reset_token_expires_at'])
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
previous_image_name = get_image_previous_name(self, "profile_picture")
|
||||
current_image_name = self.profile_picture.name if self.profile_picture else None
|
||||
self.email = normalize_email_identity(self.email)
|
||||
self.mobile = normalize_mobile_number(self.mobile)
|
||||
if kwargs.get('update_fields') is None or 'email' in kwargs['update_fields']:
|
||||
self.is_email_verified = bool(self.email)
|
||||
if kwargs.get('update_fields') is not None:
|
||||
kwargs['update_fields'] = set(kwargs['update_fields']) | {'is_email_verified'}
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user