Auth/PM-37621 - Fix Device.LastActivityDate surfacing legacy NULL rows as DateTime.UtcNow#7649
Conversation
…DateTime.UtcNow
Dapper's deserializer skips the property setter when a nullable column is
DBNull, leaving the property at its CLR default. The field initializer
`public DateTime? LastActivityDate { get; internal set; } = DateTime.UtcNow`
poisoned that default, so rows whose LastActivityDate column was NULL (e.g.
devices created before the column existed) read back as the current time.
Drop the initializer, relax `internal set` to `set`, and stamp
LastActivityDate explicitly at the two creation call sites
(DeviceValidator.GetDeviceFromRequest and DeviceRequestModel.ToDevice). Adds
an integration regression test that creates a device with an explicit null
LastActivityDate and asserts the read path surfaces null. Augments
DeviceValidatorTests.GetDeviceFromRequest_RawDeviceInfoValid_ReturnsDevice
to lock in the creation-time stamp.
There was a problem hiding this comment.
ℹ️ this is used in the device creation post seen here: https://github.com/bitwarden/server/blob/main/src/Api/Controllers/DevicesController.cs#L91-L99
There was a problem hiding this comment.
This is when we create a device on first success login.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7649 +/- ##
==========================================
+ Coverage 59.84% 64.26% +4.41%
==========================================
Files 2121 2121
Lines 93460 93464 +4
Branches 8291 8291
==========================================
+ Hits 55932 60063 +4131
+ Misses 35547 31333 -4214
- Partials 1981 2068 +87 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE This PR fixes a bug where legacy NULL Code Review DetailsNo findings. The change is well-scoped: both production |
Patrick-Pimentel-Bitwarden
left a comment
There was a problem hiding this comment.
Changes look good!
|



🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-37621
📔 Objective
To fix an issue with where null
Device.LastActivityDatevalues were coming out of the server as newDateTime.UtcNow📸 Screenshots
PM-37621.mov