prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Failure to invalidate session when user resets their own password
  ## Description
  
  When a user resets their own password, their session is not invalidated. 
  
  ## Steps to Reproduce
  
  1. User logs in
  2. User resets password
  
  ## Expected Behavior
  
  User is logged out and is requested to use their new password to login
  
  ## Actual Behavior
  
  User can continue to browse without having to enter their new password again
  
  ## Comments
  
  Related tickets: #2300, #880
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `securedrop/journalist_app/account.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 
  3 from flask import (Blueprint, render_template, request, g, redirect, url_for,
  4                    flash)
  5 from flask_babel import gettext
  6 
  7 from db import db_session
  8 from journalist_app.utils import (make_password, set_diceware_password,
  9                                   validate_user)
  10 
  11 
  12 def make_blueprint(config):
  13     view = Blueprint('account', __name__)
  14 
  15     @view.route('/account', methods=('GET',))
  16     def edit():
  17         password = make_password(config)
  18         return render_template('edit_account.html',
  19                                password=password)
  20 
  21     @view.route('/new-password', methods=('POST',))
  22     def new_password():
  23         user = g.user
  24         current_password = request.form.get('current_password')
  25         token = request.form.get('token')
  26         error_message = gettext('Incorrect password or two-factor code.')
  27         # If the user is validated, change their password
  28         if validate_user(user.username, current_password, token,
  29                          error_message):
  30             password = request.form.get('password')
  31             set_diceware_password(user, password)
  32         return redirect(url_for('account.edit'))
  33 
  34     @view.route('/2fa', methods=('GET', 'POST'))
  35     def new_two_factor():
  36         if request.method == 'POST':
  37             token = request.form['token']
  38             if g.user.verify_token(token):
  39                 flash(gettext("Token in two-factor authentication verified."),
  40                       "notification")
  41                 return redirect(url_for('account.edit'))
  42             else:
  43                 flash(gettext(
  44                     "Could not verify token in two-factor authentication."),
  45                       "error")
  46 
  47         return render_template('account_new_two_factor.html', user=g.user)
  48 
  49     @view.route('/reset-2fa-totp', methods=['POST'])
  50     def reset_two_factor_totp():
  51         g.user.is_totp = True
  52         g.user.regenerate_totp_shared_secret()
  53         db_session.commit()
  54         return redirect(url_for('account.new_two_factor'))
  55 
  56     @view.route('/reset-2fa-hotp', methods=['POST'])
  57     def reset_two_factor_hotp():
  58         otp_secret = request.form.get('otp_secret', None)
  59         if otp_secret:
  60             g.user.set_hotp_secret(otp_secret)
  61             db_session.commit()
  62             return redirect(url_for('account.new_two_factor'))
  63         else:
  64             return render_template('account_edit_hotp_secret.html')
  65 
  66     return view
  67
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/securedrop/journalist_app/account.py b/securedrop/journalist_app/account.py
  --- a/securedrop/journalist_app/account.py
  +++ b/securedrop/journalist_app/account.py
  @@ -1,7 +1,7 @@
   # -*- coding: utf-8 -*-
   
   from flask import (Blueprint, render_template, request, g, redirect, url_for,
  -                   flash)
  +                   flash, session)
   from flask_babel import gettext
   
   from db import db_session
  @@ -29,6 +29,9 @@
                            error_message):
               password = request.form.get('password')
               set_diceware_password(user, password)
  +            session.pop('uid', None)
  +            session.pop('expires', None)
  +            return redirect(url_for('main.login'))
           return redirect(url_for('account.edit'))
   
       @view.route('/2fa', methods=('GET', 'POST'))
  
verification_info: {"golden_diff": "diff --git a/securedrop/journalist_app/account.py b/securedrop/journalist_app/account.py\n--- a/securedrop/journalist_app/account.py\n+++ b/securedrop/journalist_app/account.py\n@@ -1,7 +1,7 @@\n # -*- coding: utf-8 -*-\n \n from flask import (Blueprint, render_template, request, g, redirect, url_for,\n-                   flash)\n+                   flash, session)\n from flask_babel import gettext\n \n from db import db_session\n@@ -29,6 +29,9 @@\n                          error_message):\n             password = request.form.get('password')\n             set_diceware_password(user, password)\n+            session.pop('uid', None)\n+            session.pop('expires', None)\n+            return redirect(url_for('main.login'))\n         return redirect(url_for('account.edit'))\n \n     @view.route('/2fa', methods=('GET', 'POST'))\n", "issue": "Failure to invalidate session when user resets their own password\n## Description\r\n\r\nWhen a user resets their own password, their session is not invalidated. \r\n\r\n## Steps to Reproduce\r\n\r\n1. User logs in\r\n2. User resets password\r\n\r\n## Expected Behavior\r\n\r\nUser is logged out and is requested to use their new password to login\r\n\r\n## Actual Behavior\r\n\r\nUser can continue to browse without having to enter their new password again\r\n\r\n## Comments\r\n\r\nRelated tickets: #2300, #880\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\nfrom flask import (Blueprint, render_template, request, g, redirect, url_for,\n                   flash)\nfrom flask_babel import gettext\n\nfrom db import db_session\nfrom journalist_app.utils import (make_password, set_diceware_password,\n                                  validate_user)\n\n\ndef make_blueprint(config):\n    view = Blueprint('account', __name__)\n\n    @view.route('/account', methods=('GET',))\n    def edit():\n        password = make_password(config)\n        return render_template('edit_account.html',\n                               password=password)\n\n    @view.route('/new-password', methods=('POST',))\n    def new_password():\n        user = g.user\n        current_password = request.form.get('current_password')\n        token = request.form.get('token')\n        error_message = gettext('Incorrect password or two-factor code.')\n        # If the user is validated, change their password\n        if validate_user(user.username, current_password, token,\n                         error_message):\n            password = request.form.get('password')\n            set_diceware_password(user, password)\n        return redirect(url_for('account.edit'))\n\n    @view.route('/2fa', methods=('GET', 'POST'))\n    def new_two_factor():\n        if request.method == 'POST':\n            token = request.form['token']\n            if g.user.verify_token(token):\n                flash(gettext(\"Token in two-factor authentication verified.\"),\n                      \"notification\")\n                return redirect(url_for('account.edit'))\n            else:\n                flash(gettext(\n                    \"Could not verify token in two-factor authentication.\"),\n                      \"error\")\n\n        return render_template('account_new_two_factor.html', user=g.user)\n\n    @view.route('/reset-2fa-totp', methods=['POST'])\n    def reset_two_factor_totp():\n        g.user.is_totp = True\n        g.user.regenerate_totp_shared_secret()\n        db_session.commit()\n        return redirect(url_for('account.new_two_factor'))\n\n    @view.route('/reset-2fa-hotp', methods=['POST'])\n    def reset_two_factor_hotp():\n        otp_secret = request.form.get('otp_secret', None)\n        if otp_secret:\n            g.user.set_hotp_secret(otp_secret)\n            db_session.commit()\n            return redirect(url_for('account.new_two_factor'))\n        else:\n            return render_template('account_edit_hotp_secret.html')\n\n    return view\n", "path": "securedrop/journalist_app/account.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\nfrom flask import (Blueprint, render_template, request, g, redirect, url_for,\n                   flash, session)\nfrom flask_babel import gettext\n\nfrom db import db_session\nfrom journalist_app.utils import (make_password, set_diceware_password,\n                                  validate_user)\n\n\ndef make_blueprint(config):\n    view = Blueprint('account', __name__)\n\n    @view.route('/account', methods=('GET',))\n    def edit():\n        password = make_password(config)\n        return render_template('edit_account.html',\n                               password=password)\n\n    @view.route('/new-password', methods=('POST',))\n    def new_password():\n        user = g.user\n        current_password = request.form.get('current_password')\n        token = request.form.get('token')\n        error_message = gettext('Incorrect password or two-factor code.')\n        # If the user is validated, change their password\n        if validate_user(user.username, current_password, token,\n                         error_message):\n            password = request.form.get('password')\n            set_diceware_password(user, password)\n            session.pop('uid', None)\n            session.pop('expires', None)\n            return redirect(url_for('main.login'))\n        return redirect(url_for('account.edit'))\n\n    @view.route('/2fa', methods=('GET', 'POST'))\n    def new_two_factor():\n        if request.method == 'POST':\n            token = request.form['token']\n            if g.user.verify_token(token):\n                flash(gettext(\"Token in two-factor authentication verified.\"),\n                      \"notification\")\n                return redirect(url_for('account.edit'))\n            else:\n                flash(gettext(\n                    \"Could not verify token in two-factor authentication.\"),\n                      \"error\")\n\n        return render_template('account_new_two_factor.html', user=g.user)\n\n    @view.route('/reset-2fa-totp', methods=['POST'])\n    def reset_two_factor_totp():\n        g.user.is_totp = True\n        g.user.regenerate_totp_shared_secret()\n        db_session.commit()\n        return redirect(url_for('account.new_two_factor'))\n\n    @view.route('/reset-2fa-hotp', methods=['POST'])\n    def reset_two_factor_hotp():\n        otp_secret = request.form.get('otp_secret', None)\n        if otp_secret:\n            g.user.set_hotp_secret(otp_secret)\n            db_session.commit()\n            return redirect(url_for('account.new_two_factor'))\n        else:\n            return render_template('account_edit_hotp_secret.html')\n\n    return view\n", "path": "securedrop/journalist_app/account.py"}]}