Repository navigation
[PM-40673] Two Factor Remember Token Updates (Part 1) - #8427
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #8427 +/- ##
==========================================
+ Coverage 67.12% 73.55% +6.42%
==========================================
Files 2674 2685 +11
Lines 114478 114826 +348
Branches 10390 10420 +30
==========================================
+ Hits 76847 84458 +7611
+ Misses 35122 27742 -7380
- Partials 2509 2626 +117 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Re-reviewed at |
mkincaid-bw
left a comment
There was a problem hiding this comment.
Overall a good PR from the DB side, with a couple minor changes requested.
| @@ -0,0 +1,57 @@ | |||
| CREATE PROCEDURE [dbo].[TwoFactorRememberToken_Save] | |||
There was a problem hiding this comment.
This type of Upsert is not Bitwarden's preferred methodology of performing an Insert/Update. This should be broken into a TwoFactorRememberToken_Create proc and a TwoFactorRememberToken_Update proc. See docs.
| @@ -0,0 +1,22 @@ | |||
| CREATE PROCEDURE [dbo].[TwoFactorRememberToken_DeleteExpired] | |||
There was a problem hiding this comment.
⛏️ This should probably be named TwoFactorRememberToken_DeleteManyExpired
| -- Deleted in batches so each statement holds few enough locks to avoid escalating to a table | ||
| -- lock, which would block logins while the sweep runs. The loop ends when a batch deletes | ||
| -- nothing. | ||
| DECLARE @BatchSize INT = 100 |
There was a problem hiding this comment.
A batch size of 100 is the norm throughout the codebase. However, if you expect this proc to thousands of rows (or more) during each run, then @BatchSize should be raised to 1000.
enmande
left a comment
There was a problem hiding this comment.
Awesome! Thank you ✨
Two questions below: the migration date ordering, and the job trigger timing.
Just LMK on those, everything else looks great.
627bdac to
fb9f2c2
Compare
6a7c424 to
6d27724
Compare
…pers.GenerateComb()
… is enabled for user
…Job to run at a new time to avoid multiple jobs running at same time
… parameter from ValidateTwoFactorRememberTokenQuery
6d27724 to
523502c
Compare
| SET NOCOUNT ON | ||
|
|
||
| SELECT | ||
| * |
There was a problem hiding this comment.
The TwoFactorRememberToken_ReadByUserIdDeviceId procedure selects *, making its returned columns fragile to view schema changes.
Show fix
| * | |
| [Id], | |
| [UserId], | |
| [DeviceId], | |
| [Stamp], | |
| [CreationDate], | |
| [RevisionDate], | |
| [ExpirationDate] |
Details
✨ AI Reasoning
The query uses an explicit wildcard, so its returned columns can change when the view schema changes and its data dependencies are obscured.
Reply on this comment to give feedback or ignore the issue.
More info
| CREATE VIEW [dbo].[TwoFactorRememberTokenView] | ||
| AS | ||
| SELECT | ||
| * |
There was a problem hiding this comment.
The TwoFactorRememberTokenView selects *, so its exposed columns change implicitly when the underlying table schema changes.
Show fix
| * | |
| [Id], | |
| [UserId], | |
| [DeviceId], | |
| [Stamp], | |
| [CreationDate], | |
| [RevisionDate], | |
| [ExpirationDate] |
Details
✨ AI Reasoning
The view exposes every table column through an explicit wildcard, coupling its output to future table schema changes.
Reply on this comment to give feedback or ignore the issue.
More info
| CREATE OR ALTER VIEW [dbo].[TwoFactorRememberTokenView] | ||
| AS | ||
| SELECT | ||
| * |
There was a problem hiding this comment.
The migration's TwoFactorRememberTokenView selects *, so its exposed columns change implicitly when the underlying table schema changes.
Show fix
| * | |
| [Id], | |
| [UserId], | |
| [DeviceId], | |
| [Stamp], | |
| [CreationDate], | |
| [RevisionDate], | |
| [ExpirationDate] |
Details
✨ AI Reasoning
The migration defines a view with an explicit wildcard, making the view's exposed columns depend implicitly on the table schema.
Reply on this comment to give feedback or ignore the issue.
More info
| Microsoft.Data.Sqlite.SqliteException lite => lite.SqliteErrorCode == 19 | ||
| && lite.SqliteExtendedErrorCode is 1555 or 2067, |
There was a problem hiding this comment.
The lite exception filter mixes && with an or pattern on one line, making the duplicate-key condition harder to parse.
Show fix
| Microsoft.Data.Sqlite.SqliteException lite => lite.SqliteErrorCode == 19 | |
| && lite.SqliteExtendedErrorCode is 1555 or 2067, | |
| Microsoft.Data.Sqlite.SqliteException lite => | |
| lite.SqliteErrorCode == 19 && | |
| lite.SqliteExtendedErrorCode is 1555 or 2067, |
Details
✨ AI Reasoning
This condition combines a SQLite error-code check with an alternative pattern match. The mixed operators make it harder to scan the exact conditions under which the exception is treated as a duplicate-key violation.
Reply on this comment to give feedback or ignore the issue.
More info
🎟️ Tracking
PM-40673
PR Stack
📔 Objective
Commit 1 - 239ad75
TwoFactorRememberToken) with a rotatableStamp.ITwoFactorRememberTokenRepository), defining methods that act onTwoFactorRememberTokenrow(s):UserId,DeviceId)StamprotationCommit 2 - 6d5f8ee
src/Sql/Table schema and ViewReadByUserIdDeviceId,Save,DeleteExpired,UpdateManyStampsByUserId)Commit 3 - d463a2f
TwoFactorRememberTokenEntityTypeConfiguration.csCommit 4 - 939a391
TwoFactorRememberTokenable.csCommit 5 - 48aec51
Commit 6 - 9130de8
📸 Screenshots