sunscrapers / djoser

REST implementation of Django authentication system.
MIT License
2.52k stars 460 forks source link

Djoser "Password Changed Confirmation" Email Not Sending #665

Open jmahicks opened 2 years ago

jmahicks commented 2 years ago

Good day,

I have been overwriting the default Djoser email templates with success, but I can't get the "Password Changed Confirmation" email to send.

According to djoser/conf.py, djoser/email.py, and djoser/templates/email it appears I am doing everything correctly. But it's not obvious why this one isn't sending as there are no errors being raised.

The project directory has these relevant files and paths:

project
  - core
    - email.py
    - settings.py
  - templates
    - email
      - activation.html                    # works
      - confirmation.html                  # works
      - password_changed_confirmation.html # does not work
      - password_reset.html                # works

settings.py was set as per the Djoser docs.

DJOSER = {
    'LOGIN_FIELD': 'email',
    'USER_CREATE_PASSWORD_RETYPE': True,
    'SET_PASSWORD_RETYPE': True,
    'SEND_ACTIVATION_EMAIL': True,
    'ACTIVATION_URL': 'activate/{uid}/{token}',
    'SEND_CONFIRMATION_EMAIL': True,
    'PASSWORD_RESET_CONFIRM_URL': 'password/reset/confirm/{uid}/{token}',
    # I set this to True as per the docs:
    'PASSWORD_CHANGED_EMAIL_CONFIRMATION:': True,
    'USERNAME_RESET_SHOW_EMAIL_NOT_FOUND': True,
    'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': True,
    'SERIALIZERS': {
        'user_create': 'users.serializers.UserCreateSerializer',
        'user': 'users.serializers.UserCreateSerializer',
    },
    'EMAIL': {
        # These 3 templates send:
        'activation': 'core.email.ActivationEmail',
        'confirmation': 'core.email.ConfirmationEmail',
        'password_reset': 'core.email.PasswordResetEmail',
        # This one does not:
        'password_changed_confirmation': 'core.email.PasswordChangedConfirmationEmail',
    }
}

In email.py I create my custom class to reference the template. The print statements don't even fire so I don't think this is even getting called.

from djoser import email

# Override the default Djoser confirmation email.
class PasswordChangedConfirmationEmail(email.PasswordChangedConfirmationEmail):
    template_name = 'email/password_changed_confirmation.html'

    def send(self, to, *args, **kwargs):
        print(f"Sending password changed mail to {to}")
        try:
            super().send(to, *args, **kwargs)
        except:
            print(f"Couldn't send mail to {to}")
            raise
        print(f"Password changed mail sent successfully to {to}")

Sending a reset password POST request yields the following (expected) messages in the console:

Sending password reset mail to ['someone@somewhere.com']
Password reset mail sent successfully to ['someone@somewhere.com']
[25/Apr/2022 13:53:56] "POST /api/v1/users/reset_password/ HTTP/1.1" 204 0

I then go to the URL it provides and send a POST request with the provided uid and token to the reset_password_confirm end-point and it resolves successfully.

[25/Apr/2022 14:13:33] "POST /api/v1/users/reset_password_confirm/ HTTP/1.1" 204 0

I can successfully change the password, but there aren't any print statements from my PasswordChangedConfirmationEmail class and no email received.

What am I doing wrong here?

Any help would be appreciated, thank you.

IshuSinghSE commented 1 year ago

Have you tried this... It should work for you.

from djoser import email

# Override the default Djoser confirmation email.
class PasswordChangedConfirmationEmail(email.PasswordChangedConfirmationEmail):
    template_name = 'email/password_changed_confirmation.html'