Skip to content

[PM-30993] Better Error Message for Expired Invitation Tokens#6971

Open
sven-bitwarden wants to merge 8 commits intomainfrom
ac/pm-30993/update-expired-token-exception-message
Open

[PM-30993] Better Error Message for Expired Invitation Tokens#6971
sven-bitwarden wants to merge 8 commits intomainfrom
ac/pm-30993/update-expired-token-exception-message

Conversation

@sven-bitwarden
Copy link
Contributor

@sven-bitwarden sven-bitwarden commented Feb 10, 2026

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-30993

📔 Objective

The server currently sends a nondescript Invalid token. error message when accepting an invalid token. While technically true, we want to be kinder to users accepting expired tokens, giving them a better error message.

Other Considerations

I thought about enhancing the Tokenable API to be return a TokenableValidationResult, which could mirror the existing inheritance hierarchy to return objects that indicate what went wrong. For example, Tokenable returns TokenableValidationResult, ExpiringTokenable returns ExpiringTokenableValidationResult.. each tacking on new metadata.

I opted not to do this, as this is so far the only Tokenable area that is interested in knowing what validation failed, and I didn't want to force the creation of N result classes (one for each Tokenable derivative).

📸 Screenshots

Screenshot 2026-02-10 at 7 51 20 AM

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Logo
Checkmarx One – Scan Summary & Details30e95b61-3abb-4918-bebd-31cbc9e2bfb2


New Issues (2) Checkmarx found the following issues in this Pull Request
# Severity Issue Source File / Package Checkmarx Insight
1 HIGH Path_Traversal /src/Api/Controllers/SelfHosted/SelfHostedOrganizationLicensesController.cs: 56
detailsMethod at line 56 of /src/Api/Controllers/SelfHosted/SelfHostedOrganizationLicensesController.cs gets dynamic data from the model element. This ...
Attack Vector
2 MEDIUM CSRF /src/Api/Auth/Controllers/AccountsController.cs: 291
detailsMethod at line 291 of /src/Api/Auth/Controllers/AccountsController.cs gets a parameter from a user request from model. This parameter value flow...
Attack Vector

Fixed Issues (1) Great job! The following issues were fixed in this Pull Request
Severity Issue Source File / Package
MEDIUM CSRF /src/Api/KeyManagement/Controllers/AccountsKeyManagementController.cs: 146

@codecov
Copy link

codecov bot commented Feb 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.08%. Comparing base (4732d7f) to head (896474a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6971   +/-   ##
=======================================
  Coverage   57.08%   57.08%           
=======================================
  Files        2028     2028           
  Lines       88794    88801    +7     
  Branches     7914     7917    +3     
=======================================
+ Hits        50684    50691    +7     
  Misses      36279    36279           
  Partials     1831     1831           

☔ View full report in Codecov by Sentry.
📢 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.

@sven-bitwarden sven-bitwarden marked this pull request as ready for review February 10, 2026 14:01
@sven-bitwarden sven-bitwarden requested review from a team as code owners February 10, 2026 14:01
@claude
Copy link
Contributor

claude bot commented Feb 10, 2026

Claude finished @sven-bitwarden's task in 2m 25s —— View job


Code Review: PM-30993 Better Error Message for Expired Invitation Tokens

Reviewed commit: 896474a (Merge branch 'main' into ac/pm-30993/update-expired-token-exception-message)

Files reviewed (4):

  • src/Core/Tokens/ExpiringTokenable.cs
  • src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs
  • src/Core/Auth/Models/Business/Tokenables/OrgUserInviteTokenable.cs
  • test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommandTests.cs

Summary

This PR adds a public IsExpired property to ExpiringTokenable and uses it in AcceptOrgUserCommand to distinguish expired tokens from invalid tokens, returning a more helpful "Expired token." error message to clients. The switch expression in AcceptOrgUserCommand correctly prioritizes the expired check before the general invalidity check, and the fallback for failed decryption returns the generic "Invalid token." message.

Findings

No issues found. The implementation is clean and correct:

  • Logic correctness: The switch expression in AcceptOrgUserCommand (lines 77-84) properly differentiates all cases: expired token, invalid-but-decryptable token, undecryptable token, and valid token. The ordering of arms ensures expired tokens are caught before the general validity check, which is correct since Valid would already be false for expired tokens.
  • Security: Distinguishing "Expired token." from "Invalid token." in an invitation flow is an acceptable UX trade-off. These are not authentication tokens, and the information revealed (that a token was once valid) has negligible attacker value given the token was already sent via email.
  • Backward compatibility: The existing ValidateOrgUserInviteStringToken static method remains intact and is still used by other callers (PoliciesController, InitPendingOrganizationValidator, InitPendingOrganizationCommand, RegisterUserCommand).
  • Test coverage: The PR updates the existing expired-token test to expect the new message and adds a dedicated test for the invalid-token path using a null org-user to force token data mismatch. Codecov confirms all modified lines are covered.

This PR looks good to merge.

JaredScar
JaredScar previously approved these changes Feb 10, 2026
Copy link
Contributor

@JaredSnider-Bitwarden JaredSnider-Bitwarden left a comment

Choose a reason for hiding this comment

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

Nice work!

JaredScar
JaredScar previously approved these changes Feb 11, 2026
…essage

# Conflicts:
#	src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs
@sven-bitwarden
Copy link
Contributor Author

@JaredScar @JaredSnider-Bitwarden sorry y'all, my prior PR #6972 had a conflict here 🙏

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 9, 2026

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

Labels

ai-review Request a Claude code review needs-qa

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants