Skip to content

Conversation

@david-livefront
Copy link
Collaborator

🎟️ Tracking

TBD

📔 Objective

This PR updates the way we handle the pin protected user key and it migration to the pin protected user key envelope.

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 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

storeUserAutoUnlockKey(userId = userId, userAutoUnlockKey = null)
storePinProtectedUserKey(userId = userId, pinProtectedUserKey = null)
storePinProtectedUserKeyEnvelope(userId = userId, pinProtectedUserKeyEnvelope = null)
storeEncryptedPin(userId = userId, encryptedPin = null)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This data is never intended to be removed when loging out of the app (hard or soft logout).

Given this requirement, I am simplifying the UserLogoutManager and handling it here.

// * PinProtectedUserKeyEnvelop
// * DeviceKey
// * PendingAuthRequest
// * OnboardingStatus
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updating the list of properties that are never cleared.

}
authDiskSource.storePinProtectedUserKeyEnvelope(
userId = userId,
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We simply never clear this data, so there is no need to have this logic present to preserve the data.

authDiskSource.storeAccountTokens(
userId = userId,
accountTokens = null,
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The tokens will be cleared as part of clearData(userId = userId) call below.

@david-livefront david-livefront marked this pull request as ready for review November 14, 2025 19:16
@claude
Copy link
Contributor

claude bot commented Nov 14, 2025

Claude finished @david-livefront's task —— View job


Code Review Complete

Overall Assessment: APPROVE

This is a clean refactoring that extracts PIN-protected user key handling into a dedicated manager class. The change follows established architectural patterns, reduces code duplication, and improves separation of concerns.

Summary

Change Type: Refactoring (standard review depth)

Key Improvements:

  • New PinProtectedUserKeyManager consolidates PIN key logic previously scattered across VaultLockManagerImpl and VaultRepositoryImpl
  • Reduces code duplication (-97 lines from two classes, +95 in new manager)
  • Follows Interface + Impl pattern with proper Hilt DI setup
  • Comprehensive test coverage (279 lines of tests)
  • Clarifies data persistence rules (PIN data never cleared on logout)

Findings

⚠️ Finding 1: Typo in comment at AuthDiskSourceImpl.kt:166

  • "PinProtectedUserKeyEnvelop" should be "PinProtectedUserKeyEnvelope" (already noted in previous review)

💭 Finding 2: Test naming was questioned in previous review but names are actually correct

  • Tests at lines 41 and 165 accurately state they test "with...existing pinProtectedUserKeyEnvelope"
  • Previous inline review comment suggesting name change was incorrect

Architecture Validation

MVVM + Manager Pattern: New manager follows established patterns in docs/ARCHITECTURE.md
Dependency Injection: Proper Interface + Impl with Hilt module setup (VaultManagerModule.kt:169-178)
Error Handling: Uses Result types, no exceptions thrown in business logic
Single Responsibility: Manager has focused purpose (PIN key operations only)
Code Reuse: Eliminates duplication between VaultLockManager and VaultRepository

Test Coverage

Comprehensive: All code paths tested (early returns, success, failure, in-memory vs disk)
Proper Mocking: Uses FakeAuthDiskSource and MockK appropriately
Test Migration: Dependent tests updated/removed correctly

Coverage includes:

  • Both public methods (deriveTemporary... and migratePinProtectedUserKeyIfNeeded)
  • Success scenarios (enrollment succeeds, data stored correctly)
  • Failure scenarios (enrollment fails, PIN data cleared)
  • In-memory vs persistent storage modes
  • Legacy migration behavior

Security Assessment

Zero-knowledge architecture preserved
Proper encryption key handling (Android Keystore patterns)
Migration safety: Clears legacy pinProtectedUserKey during migration (PinProtectedUserKeyManagerImpl.kt:89-93)
In-memory-only mode: Supports temporary PIN keys for session-based unlocking

No security concerns identified.

Code Quality

✅ Follows STYLE_AND_BEST_PRACTICES.md
✅ KDoc on all public interface methods
✅ Proper formatting and indentation
✅ Clear inline comments for non-obvious logic


Recommendation: APPROVE pending typo fix in AuthDiskSourceImpl.kt:166

This refactoring improves code organization and maintainability while preserving existing behavior and security properties.

)
}

private fun storePinData(
Copy link
Contributor

Choose a reason for hiding this comment

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

💭 Consider adding KDoc to explain the storePinData behavior, particularly:

  • The relationship between inMemoryOnly parameter and storage calls
  • Why pinProtectedUserKey is always cleared at disk level (lines 91-95)
Suggested KDoc
/**
 * Stores PIN-related data to disk after an enrollment operation.
 * 
 * @param userId The user ID for which to store PIN data.
 * @param encryptedPin The new encrypted PIN value, or null to clear it.
 * @param pinProtectedUserKeyEnvelope The new PIN-protected user key envelope, or null to clear it.
 * @param inMemoryOnly If true, the PIN-protected user key envelope is stored only in memory.
 *                     If false, it is persisted to disk.
 * 
 * Note: This always clears the legacy [pinProtectedUserKey] at the disk level to ensure proper
 * migration to the envelope-based approach.
 */
private fun storePinData(

While private functions don't require KDoc per project guidelines, this function has non-obvious behavior that would benefit from documentation.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

Logo
Checkmarx One – Scan Summary & Detailse0920991-08bf-415e-b3ca-58c8a3d54b91

Great job! No new security vulnerabilities introduced in this pull request

@codecov
Copy link

codecov bot commented Nov 14, 2025

Codecov Report

❌ Patch coverage is 96.22642% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.00%. Comparing base (21afa81) to head (71a987c).

Files with missing lines Patch % Lines
...ta/vault/manager/PinProtectedUserKeyManagerImpl.kt 95.74% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6169      +/-   ##
==========================================
+ Coverage   84.97%   85.00%   +0.03%     
==========================================
  Files         735      724      -11     
  Lines       53087    52848     -239     
  Branches     7678     7678              
==========================================
- Hits        45113    44926     -187     
+ Misses       5291     5246      -45     
+ Partials     2683     2676       -7     

☔ 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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants