Skip to content

Commit

Permalink
Add support for changing email. (#974)
Browse files Browse the repository at this point in the history
This adds an endpoint - /change-email that allows users to change their email. This sends out a confirmation link to the existing email.
As with all other features - this defaults 'False'.

This is a new endpoint, form, view, link, etc.

close #956
  • Loading branch information
jwag956 authored May 14, 2024
1 parent 51d2355 commit 442faf3
Show file tree
Hide file tree
Showing 24 changed files with 820 additions and 21 deletions.
18 changes: 16 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@ Flask-Security Changelog

Here you can see the full list of changes between each Flask-Security release.

Version 5.5.0
-------------

Released TBD

Features
++++++++
- (:issue:`956`) Add support for changing registered user's email (:py:data:`SECURITY_CHANGE_EMAIL`).

Fixes
+++++
- (:pr:`972`) Set :py:data:`SECURITY_CSRF_COOKIE` at beginning (GET /login) of authentication
ritual - just as we return the CSRF token. (thanks @e-goto)

Version 5.4.3
-------------

Expand All @@ -11,10 +25,10 @@ Released March 23, 2024
Fixes
+++++
- (:issue:`950`) Regression - some templates no longer getting correct config (thanks pete7863).
- (:issue:`954`) CSRF not properly ignored for application forms using SECURITY_CSRF_PROTECT_MECHANISMS.
- (:issue:`954`) CSRF not properly ignored for application forms using :py:data:`SECURITY_CSRF_PROTECT_MECHANISMS`.
- (:pr:`957`) Improve jp translations (e-goto)
- (:issue:`959`) Regression - datetime_factory should still be an attribute (thanks TimotheeJeannin)
- (:issue:`942`) GENERIC_RESPONSES hide email validation/syntax errors.
- (:issue:`942`) :py:data:`SECURITY_RETURN_GENERIC_RESPONSES` hide email validation/syntax errors.

Version 5.4.2
-------------
Expand Down
1 change: 1 addition & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ Security() instantiation.
Forms
-----

.. autoclass:: flask_security.ChangeEmailForm
.. autoclass:: flask_security.ChangePasswordForm
.. autoclass:: flask_security.ConfirmRegisterForm
.. autoclass:: flask_security.ForgotPasswordForm
Expand Down
78 changes: 76 additions & 2 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ These configuration keys are used globally across all features.

.. py:data:: SECURITY_REDIRECT_BEHAVIOR
Passwordless login, confirmation, reset password, unified signin, and oauth signin
Passwordless login, confirmation, reset password, unified signin, change_email, and oauth signin
have GET endpoints that validate the passed token and redirect to an action form.
For Single-Page-Applications style UIs which need to control their own internal URL routing these redirects
need to not contain forms, but contain relevant information as query parameters.
Expand All @@ -279,6 +279,8 @@ These configuration keys are used globally across all features.
- :py:data:`SECURITY_POST_OAUTH_LOGIN_VIEW` (if :py:data:`SECURITY_OAUTH_ENABLE` is True)
- :py:data:`SECURITY_LOGIN_ERROR_VIEW`
- :py:data:`SECURITY_CONFIRM_ERROR_VIEW`
- :py:data:`SECURITY_POST_CHANGE_EMAIL_VIEW`
- :py:data:`SECURITY_CHANGE_EMAIL_ERROR_VIEW`
- :py:data:`SECURITY_POST_CONFIRM_VIEW`
- :py:data:`SECURITY_RESET_ERROR_VIEW`
- :py:data:`SECURITY_RESET_VIEW`
Expand Down Expand Up @@ -902,7 +904,7 @@ Confirmable
Specifies the view to redirect to if a confirmation error occurs.
This value can be set to a URL or an endpoint name.
If this value is ``None``, the user is presented the default view
to resend a confirmation link. In the case of ``SECURITY_REDIRECT_BEHAVIOR`` == ``"spa"``
to resend a confirmation link. In the case of :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``
query params in the redirect will contain the error.

Default: ``None``.
Expand Down Expand Up @@ -1076,6 +1078,71 @@ Recoverable

Default: ``_("Your password has been reset")``.

Change_Email
------------
.. versionadded:: 5.5.0

.. py:data:: SECURITY_CHANGE_EMAIL
It ``True`` an endpoint is created that allows a user to change their email address.

Default: ``False``
.. py:data:: SECURITY_CHANGE_EMAIL_SUBJECT
Sets the subject for the change email confirmation email.

Default: ``_("Confirm your new email address")``.
.. py:data:: SECURITY_CHANGE_EMAIL_TEMPLATE
Specifies the path to the template for the change email page.

Default: ``"security/change_email.html"``.
.. py:data:: SECURITY_CHANGE_EMAIL_WITHIN
Specifies the amount of time a user has before their change email
token expires. Always pluralize the time unit for this value.

Default: ``"2 hours"``
.. py:data:: SECURITY_POST_CHANGE_EMAIL_VIEW
Specifies the view to redirect to after a user successfully confirms their new email address.
This value can be set to a URL or an endpoint name. If this value is
``None``, the user is redirected to the value of :py:data:`SECURITY_POST_LOGIN_VIEW`.
Note that if the request URL or form has a ``next`` parameter, that will take precedence.
In the case of :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"`` this value must be set.

Default: ``None``.
.. py:data:: SECURITY_CHANGE_EMAIL_ERROR_VIEW
Specifies the view to redirect to if a change email confirmation error occurs.
This value can be set to a URL or an endpoint name.
If this value is ``None``, the user is redirected back to the change_email page.
In the case of :py:data:`SECURITY_REDIRECT_BEHAVIOR` == ``"spa"``
this value must be set, and the query params in the redirect will contain the error.

Default: ``None``.
.. py:data:: SECURITY_CHANGE_EMAIL_URL
Specifies the change-email endpoint URL.

Default: ``"/change-email"``.
.. py:data:: SECURITY_CHANGE_EMAIL_CONFIRM_URL
Specifies the change-email confirmation endpoint URL. This is a GET
only endpoint (accessed via a link in an email).

Default: ``"/change-email-confirm"``.
.. py:data:: SECURITY_EMAIL_CHANGE_SALT
Specifies the salt value when generating change email confirmation links/tokens.

Default: ``"change-email-salt"``.

Additional relevant configuration variables:

- :py:data:`SECURITY_FRESHNESS` - Used to protect /change-email.
- :py:data:`SECURITY_FRESHNESS_GRACE_PERIOD` - Used to protect /change-email.

Two-Factor
-----------
Configuration related to the two-factor authentication feature.
Expand Down Expand Up @@ -1709,6 +1776,7 @@ Feature Flags
-------------
All feature flags. By default all are 'False'/not enabled.

* :py:data:`SECURITY_CHANGE_EMAIL`
* :py:data:`SECURITY_CONFIRMABLE`
* :py:data:`SECURITY_REGISTERABLE`
* :py:data:`SECURITY_RECOVERABLE`
Expand All @@ -1729,6 +1797,8 @@ A list of all URLs and Views:
* :py:data:`SECURITY_LOGOUT_URL`
* :py:data:`SECURITY_VERIFY_URL`
* :py:data:`SECURITY_REGISTER_URL`
* :py:data:`SECURITY_CHANGE_EMAIL_URL`
* :py:data:`SECURITY_CHANGE_EMAIL_CONFIRM_URL`
* :py:data:`SECURITY_RESET_URL`
* :py:data:`SECURITY_CHANGE_URL`
* :py:data:`SECURITY_CONFIRM_URL`
Expand Down Expand Up @@ -1777,6 +1847,7 @@ A list of all templates:
* :py:data:`SECURITY_REGISTER_USER_TEMPLATE`
* :py:data:`SECURITY_RESET_PASSWORD_TEMPLATE`
* :py:data:`SECURITY_CHANGE_PASSWORD_TEMPLATE`
* :py:data:`SECURITY_CHANGE_EMAIL_TEMPLATE`
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_TEMPLATE`
* :py:data:`SECURITY_MULTI_FACTOR_RECOVERY_CODES_TEMPLATE`
* :py:data:`SECURITY_SEND_CONFIRMATION_TEMPLATE`
Expand All @@ -1802,6 +1873,9 @@ The default messages and error levels can be found in ``core.py``.
* ``SECURITY_MSG_ALREADY_CONFIRMED``
* ``SECURITY_MSG_API_ERROR``
* ``SECURITY_MSG_ANONYMOUS_USER_REQUIRED``
* ``SECURITY_MSG_CHANGE_EMAIL_EXPIRED``
* ``SECURITY_MSG_CHANGE_EMAIL_CONFIRMED``
* ``SECURITY_MSG_CHANGE_EMAIL_SENT``
* ``SECURITY_MSG_CODE_HAS_BEEN_SENT``
* ``SECURITY_MSG_CONFIRMATION_EXPIRED``
* ``SECURITY_MSG_CONFIRMATION_REQUEST``
Expand Down
9 changes: 9 additions & 0 deletions docs/customizing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ following is a list of view templates:
* `security/register_user.html`
* `security/reset_password.html`
* `security/change_password.html`
* `security/change_email.html`
* `security/send_confirmation.html`
* `security/send_login.html`
* `security/verify.html`
Expand All @@ -47,6 +48,7 @@ Flask application context processor:

* ``<template_name>_form``: A form object for the view.
* ``security``: The Flask-Security extension object.
* ``config``: Injected by Flask - this holds all extensions' configuration.
* ``url_for_security``: A function that returns the configured URL for the passed Security endpoint.
* ``_fsdomain``: A function used to `tag` strings for extraction and localization.
* ``_fs_is_user_authenticated``: Returns True if argument (user) is authenticated.
Expand Down Expand Up @@ -77,6 +79,7 @@ The following is a list of all the available context processor decorators:
* ``register_context_processor``: Register view
* ``reset_password_context_processor``: Reset password view
* ``change_password_context_processor``: Change password view
* ``change_email_context_processor``: Change email view
* ``send_confirmation_context_processor``: Send confirmation view
* ``send_login_context_processor``: Send login view
* ``mail_context_processor``: Whenever an email will be sent
Expand Down Expand Up @@ -162,6 +165,7 @@ The following is a list of all the available form overrides:
* ``forgot_password_form``: Forgot password form
* ``reset_password_form``: Reset password form
* ``change_password_form``: Change password form
* ``change_email_form``: Change email form
* ``send_confirmation_form``: Send confirmation form
* ``mf_recovery_codes_form``: Setup recovery codes form
* ``mf_recovery_form``: Use recovery code form
Expand Down Expand Up @@ -368,6 +372,8 @@ The following is a list of email templates:
* `security/email/reset_notice.txt`
* `security/email/change_notice.txt`
* `security/email/change_notice.html`
* `security/email/change_email_instructions.txt`
* `security/email/change_email_instructions.html`
* `security/email/welcome.html`
* `security/email/welcome.txt`
* `security/email/welcome_existing.html`
Expand Down Expand Up @@ -418,6 +424,9 @@ welcome SECURITY_SEND_REGISTER_EMAIL SECURITY_EM
confirmation_instructions N/A SECURITY_EMAIL_SUBJECT_CONFIRM - user confirm_instructions_sent
- confirmation_link
- confirmation_token
change_email_instructions N/A SECURITY_CHANGE_EMAIL_SUBJECT - user change_email_instructions_sent
- link
- token
login_instructions N/A SECURITY_EMAIL_SUBJECT_PASSWORDLESS - user login_instructions_sent
- login_link
- login_token
Expand Down
5 changes: 5 additions & 0 deletions docs/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ Thus changing the password also invalidates all authentication tokens. This may
behavior, so if the UserModel contains an attribute ``fs_token_uniquifier``, then that will be used
when generating authentication tokens and so won't be affected by password changes.

Email Change
------------
If configured, users can change the email they registered with. This will send a new confirmation email to the new email address.


Login Tracking
--------------
Expand All @@ -262,6 +266,7 @@ JSON is supported for the following operations:
* Unified sign in requests
* Registration requests
* Change password requests
* Change email requests
* Confirmation requests
* Forgot password requests
* Passwordless login requests
Expand Down
26 changes: 12 additions & 14 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@ Welcome to Flask-Security
Flask-Security allows you to quickly add common security mechanisms to your
Flask application. They include:

1. Session based authentication
2. Role and Permission management
3. Password hashing
4. Basic HTTP authentication
5. Token based authentication
6. Token based account activation (optional)
7. Token based password recovery / resetting (optional)
8. Two-factor authentication (optional)
9. Unified sign in (optional)
10. User registration (optional)
11. Login tracking (optional)
12. JSON/Ajax Support
13. WebAuthn Support (optional)
14. Use 'social'/Oauth for authentication (e.g. google, github, ..) (optional)
1. Authentication (via session, Basic HTTP, or token)
2. User registration (optional)
3. Role and Permission management
4. Account activation (via email confirmation) (optional)
5. Password management (recovery and resetting) (optional)
6. Two-factor authentication (optional)
7. WebAuthn Support (optional)
8. Use 'social'/Oauth for authentication (e.g. google, github, ..) (optional)
9. Change email (optional)
10. Login tracking (optional)
11. JSON/Ajax Support


Many of these features are made possible by integrating various Flask extensions
and libraries. They include:
Expand Down
4 changes: 2 additions & 2 deletions docs/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ Confirmable
^^^^^^^^^^^

If you enable account confirmation by setting your application's
:py:data:`SECURITY_CONFIRMABLE` configuration value to `True`, your `User` model will
require the following additional field:
:py:data:`SECURITY_CONFIRMABLE` or :py:data:`SECURITY_CHANGE_EMAIL` configuration value to `True`,
your `User` model will require the following additional field:

* ``confirmed_at`` (datetime)

Expand Down
Loading

0 comments on commit 442faf3

Please sign in to comment.