Skip to content

fix: Revoke DRF token after password change - #8698

Open
bakirFS wants to merge 2 commits into
mainfrom
fix/logout-on-password-change
Open

bakirFS wants to merge 2 commits into
mainfrom
fix/logout-on-password-change

Conversation

@bakirFS

@bakirFS bakirFS commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Closes #8651

How did you test this code?

Logged in, changed password, verified the token was deleted in Django-admin, after logging in with the new password a new token is issued. When the user wants to change the password they get a modal warning them they will be logged out and when they are redirected to the login page a banner says they need to log back in with the new password.

@bakirFS
bakirFS requested review from a team as code owners October 8, 2026 09:11
@bakirFS
bakirFS requested review from khvn26 and kyle-ssg and removed request for a team October 8, 2026 09:11
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated
docs Ignored Ignored Preview Oct 8, 2026 9:23am UTC
flagsmith-frontend-preview Ignored Ignored Preview Oct 8, 2026 9:23am UTC
flagsmith-frontend-staging Ignored Ignored Preview Oct 8, 2026 9:23am UTC

Request Review

@github-actions github-actions Bot added front-end Issue related to the React Front End Dashboard api Issue related to the REST API labels Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-e2e:pr-8698 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-frontend:pr-8698 Finished ✅ Results ✅
ghcr.io/flagsmith/flagsmith-api-test:pr-8698 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api:pr-8698 Finished ✅ Results ✅
ghcr.io/flagsmith/flagsmith-private-cloud:pr-8698 Finished ✅ Results ✅

@github-actions github-actions Bot added the fix label Oct 8, 2026
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

📝 Walkthrough

Walkthrough

The backend enables token revocation when a password changes. The dashboard now requires confirmation before submitting a password change, logs the user out after success, and displays a notification at login.

Priority: ⬆️ High

Estimated code review effort: 3 (Moderate) | ~20 minutes

Severity of issue fixed: High

Merge Risk: 🟡 Moderate · up to f9155

Changing a password now signs out other sessions. Resetting a password does not, so a device that was already logged in stays logged in after a reset. Issue #8651 asks for revocation in both cases. A minor issue also remains: an old password error can stay on screen while the user retries.

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 3e7486dc-9d8d-4e94-96ba-f5a2b256a864
📥 Commits

Reviewing files that changed from the base of the PR and between 6b0a8d1 and 903e9b9.

📒 Files selected for processing (5)
  • api/app/settings/common.py
  • api/tests/unit/custom_auth/test_unit_custom_auth_views.py
  • frontend/common/constants.ts
  • frontend/web/components/pages/AccountSettingsPage.tsx
  • frontend/web/components/pages/home-page/HomePage.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

"confirmation": "users.emails.ConfirmationEmail",
},
"SET_PASSWORD_RETYPE": True,
"LOGOUT_ON_PASSWORD_CHANGE": True,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Revoke tokens after password resets too.

LOGOUT_ON_PASSWORD_CHANGE affects Djoser's set_password action, but not reset_password_confirm. After a successful password reset, an existing DRF token therefore remains valid. Add token revocation to the reset-confirmation path and test a request made with the old token. (raw.githubusercontent.com)

Comment on lines +150 to +171
onYes: () => {
setIsSaving(true)
_data
.post(`${Project.api}auth/users/set_password/`, {
current_password: currentPassword,
new_password: newPassword1,
re_new_password: newPassword2,
})
.then(() => {
setIsSaving(false)
// Changing the password revokes the auth token on every device,
// including this one, so log out to show the login page.
sessionStorage.setItem(PASSWORD_CHANGED_SESSION_KEY, 'true')
AppActions.logout()
})
.catch(() => {
setIsSaving(false)
setPasswordError(
'There was an error setting your password, please check your details.',
)
})
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clear passwordError when the user confirms a new attempt.

The onYes handler sets passwordError on failure. It never clears the error before a retry. A stale error stays visible while the new request runs. Call setPasswordError(null) at the start of onYes.

A second concern: the logout depends on the .then callback. If AppActions.logout() throws, the .catch handler shows a "password" error although the password changed. This is unlikely. Keep the logout call outside the request error path if you want exact error reporting.

Proposed fix
--- "a/frontend/web/components/pages/AccountSettingsPage.tsx"
+++ "b/frontend/web/components/pages/AccountSettingsPage.tsx"
@@ -147,8 +147,9 @@
           password.
         </div>
       ),
       onYes: () => {
+        setPasswordError(null)
         setIsSaving(true)
         _data
           .post(`${Project.api}auth/users/set_password/`, {
             current_password: currentPassword,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onYes: () => {
setIsSaving(true)
_data
.post(`${Project.api}auth/users/set_password/`, {
current_password: currentPassword,
new_password: newPassword1,
re_new_password: newPassword2,
})
.then(() => {
setIsSaving(false)
// Changing the password revokes the auth token on every device,
// including this one, so log out to show the login page.
sessionStorage.setItem(PASSWORD_CHANGED_SESSION_KEY, 'true')
AppActions.logout()
})
.catch(() => {
setIsSaving(false)
setPasswordError(
'There was an error setting your password, please check your details.',
)
})
},
onYes: () => {
setPasswordError(null)
setIsSaving(true)
_data
.post(`${Project.api}auth/users/set_password/`, {
current_password: currentPassword,
new_password: newPassword1,
re_new_password: newPassword2,
})
.then(() => {
setIsSaving(false)
// Changing the password revokes the auth token on every device,
// including this one, so log out to show the login page.
sessionStorage.setItem(PASSWORD_CHANGED_SESSION_KEY, 'true')
AppActions.logout()
})
.catch(() => {
setIsSaving(false)
setPasswordError(
'There was an error setting your password, please check your details.',
)
})
},

Source: Learnings

@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.85%. Comparing base (76c4802) to head (f91558b).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8698   +/-   ##
=======================================
  Coverage   98.85%   98.85%           
=======================================
  Files        1663     1663           
  Lines       68711    68720    +9     
=======================================
+ Hits        67921    67930    +9     
  Misses        790      790           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor
✅ private-cloud · depot-ubuntu-latest-arm-16 — run #21402 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  45.7 seconds
commit  f91558b
info  🔄 Run: #21402 (attempt 1)

🗂️ Previous results
✅ private-cloud · depot-ubuntu-latest-16 — run #21402 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  4 passed

Details

stats  4 tests across 4 suites
duration  50.1 seconds
commit  f91558b
info  🔄 Run: #21402 (attempt 1)

✅ oss · depot-ubuntu-latest-arm-16 — run #21402 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  37.5 seconds
commit  f91558b
info  🔄 Run: #21402 (attempt 1)

✅ oss · depot-ubuntu-latest-16 — run #21402 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  31.6 seconds
commit  f91558b
info  🔄 Run: #21402 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-arm-16 — run #21401 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  37.2 seconds
commit  903e9b9
info  🔄 Run: #21401 (attempt 1)

✅ private-cloud · depot-ubuntu-latest-16 — run #21401 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  6 passed

Details

stats  6 tests across 5 suites
duration  44.3 seconds
commit  903e9b9
info  🔄 Run: #21401 (attempt 1)

✅ oss · depot-ubuntu-latest-arm-16 — run #21401 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  35.5 seconds
commit  903e9b9
info  🔄 Run: #21401 (attempt 1)

✅ oss · depot-ubuntu-latest-16 — run #21401 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  32.6 seconds
commit  903e9b9
info  🔄 Run: #21401 (attempt 1)

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Visual Regression

20 screenshots compared. See report for details.
View full report

@github-actions github-actions Bot added fix and removed fix labels Oct 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 11e6a933-d532-4f74-b3f2-6e8eb7349872
📥 Commits

Reviewing files that changed from the base of the PR and between 903e9b9 and f91558b.

📒 Files selected for processing (1)
  • api/tests/unit/custom_auth/test_unit_custom_auth_views.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

staff_user: FFAdminUser,
) -> None:
# Given
staff_user.password = make_password("old-password")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Revoke tokens after password resets as well.

This test covers set_password only, but issue #8651 also requires revocation after reset_password_confirm. Djoser 2.3.0 and 2.3.4 revoke tokens in set_password; reset_password_confirm saves the new password without revoking tokens. An existing token can therefore still authenticate after a reset. (raw.githubusercontent.com) Add revocation to the reset flow and assert that a pre-reset token receives 401.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API fix front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Existing auth tokens are not revoked when a user's password is changed or reset

1 participant