-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[PM-27886] - Archive Revamp: Replace ArchiveDate from Cipher Entity and SQL Files #6589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: PM-27884
Are you sure you want to change the base?
Conversation
|
Claude finished @jaasen-livefront's task —— View job Code Review CompleteSummary of Changes Since Last ReviewThe author has addressed shane-melton's feedback by moving the CipherArchive join into the TVFs ( Critical IssuesFinding 1: Missing data migration from Cipher.ArchivedDate to CipherArchive❌ BLOCKING - The migration script updates stored procedures but does not migrate existing Required FixAdd this at the beginning of -- Migrate existing archived ciphers from Cipher.ArchivedDate to CipherArchive table
-- Note: Cipher.ArchivedDate was not per-user. We migrate to the cipher's owner (UserId).
-- Organizational ciphers (UserId = NULL) with ArchivedDate are skipped since CipherArchive requires UserId.
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[Cipher]') AND name = 'ArchivedDate')
BEGIN
INSERT INTO [dbo].[CipherArchive] (CipherId, UserId, ArchivedDate)
SELECT c.Id, c.UserId, c.ArchivedDate
FROM [dbo].[Cipher] c
WHERE c.ArchivedDate IS NOT NULL
AND c.UserId IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM [dbo].[CipherArchive] ca
WHERE ca.CipherId = c.Id AND ca.UserId = c.UserId
);
END
GOPre-deployment verification needed:
Finding 2: Potential KeyNotFoundException in CipherDetailsQuery
Suggested FixReplace lines 70-74 with: FolderId = GetFolderIdSafe(c.Folders, userId, _ignoreFolders),Then add helper method: private static Guid? GetFolderIdSafe(string foldersJson, Guid userId, bool ignoreFolders)
{
if (ignoreFolders || string.IsNullOrWhiteSpace(foldersJson))
return null;
try
{
if (!foldersJson.ToLowerInvariant().Contains(userId.ToString()))
return null;
var folders = CoreHelpers.LoadClassFromJsonData<Dictionary<Guid, Guid>>(foldersJson);
return folders?.TryGetValue(userId, out var folder) == true ? folder : null;
}
catch
{
return null;
}
}ImprovementsFinding 3: Missing unit tests for archive functionality♻️ Technical Debt - Per CLAUDE.md line 25, unit tests should be added for new feature development. The archive/unarchive logic in Consider adding unit tests covering:
Finding 4: Organizational cipher archiving behavior unclear💭 Question - The Questions:
If organizational ciphers should NOT support archiving, consider adding a comment in the stored procedure explaining this business rule for future maintainers. Good Practices Observed
Action Items for Author
|
util/Migrator/DbScripts/2025-11-14_00_AddArchiveCipherToCipherDetails.sql
Show resolved
Hide resolved
src/Sql/dbo/Vault/Stored Procedures/Cipher/Cipher_Unarchive.sql
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Repositories/Queries/UserCipherDetailsQuery.cs
Outdated
Show resolved
Hide resolved
|
New Issues (2)Checkmarx found the following issues in this Pull Request
|
util/Migrator/DbScripts/2025-11-14_00_AddArchiveCipherToCipherDetails.sql
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Repositories/Queries/UserCipherDetailsQuery.cs
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Vault/Repositories/Queries/CipherDetailsQuery.cs
Show resolved
Hide resolved
util/Migrator/DbScripts/2025-11-14_00_AddArchiveCipherToCipherDetails.sql
Outdated
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Vault/Repositories/Queries/CipherDetailsQuery.cs
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Repositories/Queries/UserCipherDetailsQuery.cs
Outdated
Show resolved
Hide resolved
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## PM-27884 #6589 +/- ##
============================================
- Coverage 57.01% 56.93% -0.08%
============================================
Files 1916 1914 -2
Lines 85265 85155 -110
Branches 7626 7617 -9
============================================
- Hits 48616 48486 -130
- Misses 34815 34833 +18
- Partials 1834 1836 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎨 I think it would be preferable to put the additional join in the CipherDetails.sql function that way we don't have to repeat it in all these CipherDetails_* sprocs (or anywhere else the function is used).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shane-melton Totally agree. I had done that originally but then had a bunch of failing sql and tests that couldn't seem to handle the nested join. I'll see if I can get them to work again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shane-melton this is now resolved in da0131c
src/Infrastructure.EntityFramework/Repositories/Queries/UserCipherDetailsQuery.cs
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Vault/Repositories/Queries/CipherDetailsQuery.cs
Show resolved
Hide resolved
util/Migrator/DbScripts/2025-11-14_00_AddArchiveCipherToCipherDetails.sql
Show resolved
Hide resolved
util/Migrator/DbScripts/2025-11-14_00_AddArchiveCipherToCipherDetails.sql
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Repositories/Queries/UserCipherDetailsQuery.cs
Show resolved
Hide resolved
src/Infrastructure.EntityFramework/Vault/Repositories/Queries/CipherDetailsQuery.cs
Show resolved
Hide resolved
|





🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-27886
📔 Objective
This PR migrates per-user archive state out of the Cipher table into a new CipherArchive table.
Key changes:
CipherDetailsandUserCipherDetailsTVFs to join CipherArchive📸 Screenshots
⏰ Reminders before review
🦮 Reviewer guidelines
:+1:) or similar for great changes:memo:) or ℹ️ (:information_source:) for notes or general info:question:) for questions:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion:art:) for suggestions / improvements:x:) or:warning:) for more significant problems or concerns needing attention:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt:pick:) for minor or nitpick changes