-
Notifications
You must be signed in to change notification settings - Fork 1.5k
PM-13944 - Refactor canClone method to use CipherAuthorizationService #16849
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: main
Are you sure you want to change the base?
Conversation
Claude finished @theMickster's task —— View job Code Review Complete ✅Summary of ChangesThis PR successfully refactors the
Overall Assessment: This is a solid tech debt refactor that improves code maintainability and consistency. The changes are functionally equivalent to the original implementation and follow Angular/RxJS best practices. Critical IssuesNone identified. ✅ Suggested Improvements🎨 Consider consistency with reference implementationapps/web/src/app/vault/components/vault-items/vault-items.component.ts:287-303 Your implementation correctly follows the pattern from // Your implementation (vault-items.component.ts:287-303)
protected canClone$(vaultItem: VaultItem<C>): Observable<boolean> {
return this.restrictedItemTypesService.restricted$.pipe(
switchMap((restrictedTypes) => {
const isItemRestricted = restrictedTypes.some(
(rt) => rt.cipherType === CipherViewLikeUtils.getType(vaultItem.cipher),
);
if (isItemRestricted) {
return of(false);
}
return this.cipherAuthorizationService.canCloneCipher$(
vaultItem.cipher,
this.showAdminActions,
);
}),
);
}
// Reference implementation (item-more-options.component.ts:76-91)
protected canClone$ = combineLatest([
this._cipher$,
this.restrictedItemTypesService.restricted$,
]).pipe(
filter(([c]) => c != null),
switchMap(([c, restrictedTypes]) => {
const isItemRestricted = restrictedTypes.some(
(restrictType) => restrictType.cipherType === CipherViewLikeUtils.getType(c),
);
if (!isItemRestricted) { // Note: inverted condition
return this.cipherAuthorizationService.canCloneCipher$(c);
}
return new BehaviorSubject(false);
}),
); Differences:
Recommendation: Consider inverting the condition to match the reference pattern for consistency: if (!isItemRestricted) {
return this.cipherAuthorizationService.canCloneCipher$(
vaultItem.cipher,
this.showAdminActions,
);
}
return of(false); This is purely stylistic - your current implementation is correct. 🤔 Question: Missing unit tests for component glue codeapps/web/src/app/vault/components/vault-items/vault-items.component.ts:287-303 The PR description states:
While this is a reasonable position, the reference implementation in Consideration: The
Question for consideration: Would a component-level test that verifies the integration of the two services (restricted items + authorization) provide value? For example:
This would ensure the orchestration logic remains correct even if service implementations change. 📝 Minor: Removed import cleanupapps/web/src/app/vault/components/vault-items/vault-items.component.ts:5 Good catch removing the now-unused Good Practices Observed
Action Items for Author
Additional ContextThe refactor successfully centralizes authorization logic, making it:
The pattern matches No blocking issues identified. This is ready for merge pending CI validation. 👍 |
|
Great job! No new security vulnerabilities introduced in this pull request |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #16849 +/- ##
=======================================
Coverage 38.92% 38.93%
=======================================
Files 3435 3435
Lines 97482 97473 -9
Branches 14660 14657 -3
=======================================
+ Hits 37947 37952 +5
+ Misses 57877 57863 -14
Partials 1658 1658 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-13944
📔 Objective
Follow-up tech debt work to #11660 to use the
CipherAuthorizationService
and theRestrictedItemTypesService
to determine whether a user can clone a cipher. Leverages similar patterns found initem-more-options.component.ts
and thecanClone$
.In terms of unit testing the canClone$(), it contains no business logic—it simply orchestrates two well-tested services via RxJS pipes—so unit testing it would only verify trivial Observable piping while creating maintenance overhead without meaningful coverage gains. My general observation is that we don't unit test component glue code.
I found additional related services that needed covering unit tests.
📸 Screenshots
Please see the following screen recording that shows the testing following the refactor.
All appears to function as it did before the refactor.
Screen.Recording.2025-10-13.at.1.04.12.PM.mov
⏰ 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