1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 06:13:38 +00:00

fix(browser): use appCopyField instead of appCopyClick for singleCopiableLogin (#14692)

Fixes #14167

Co-authored-by: Daniel James Smith <2670567+djsmith85@users.noreply.github.com>
This commit is contained in:
sportshead
2025-05-15 20:54:41 +01:00
committed by GitHub
parent ee4c3cfd94
commit 0d19432f14
2 changed files with 20 additions and 16 deletions

View File

@@ -40,12 +40,9 @@
type="button" type="button"
bitIconButton="bwi-clone" bitIconButton="bwi-clone"
size="small" size="small"
[appA11yTitle]=" [appA11yTitle]="singleCopiableLogin.key"
'copyFieldValue' | i18n: singleCopiableLogin.key : singleCopiableLogin.value [appCopyField]="$any(singleCopiableLogin.field)"
" [cipher]="cipher"
[appCopyClick]="singleCopiableLogin.value"
[valueLabel]="singleCopiableLogin.key"
showToast
></button> ></button>
<ng-container *ngIf="!singleCopiableLogin"> <ng-container *ngIf="!singleCopiableLogin">
<button <button

View File

@@ -15,6 +15,7 @@ import { VaultPopupCopyButtonsService } from "../../../services/vault-popup-copy
type CipherItem = { type CipherItem = {
value: string; value: string;
key: string; key: string;
field?: string;
}; };
@Component({ @Component({
@@ -43,15 +44,23 @@ export class ItemCopyActionsComponent {
); );
} }
/*
* singleCopiableLogin uses appCopyField instead of appCopyClick. This allows for the TOTP
* code to be copied correctly. See #14167
*/
get singleCopiableLogin() { get singleCopiableLogin() {
const loginItems: CipherItem[] = [ const loginItems: CipherItem[] = [
{ value: this.cipher.login.username, key: "username" }, { value: this.cipher.login.username, key: "copyUsername", field: "username" },
{ value: this.cipher.login.password, key: "password" }, { value: this.cipher.login.password, key: "copyPassword", field: "password" },
{ value: this.cipher.login.totp, key: "totp" }, { value: this.cipher.login.totp, key: "copyVerificationCode", field: "totp" },
]; ];
// If both the password and username are visible but the password is hidden, return the username // If both the password and username are visible but the password is hidden, return the username
if (!this.cipher.viewPassword && this.cipher.login.username && this.cipher.login.password) { if (!this.cipher.viewPassword && this.cipher.login.username && this.cipher.login.password) {
return { value: this.cipher.login.username, key: this.i18nService.t("username") }; return {
value: this.cipher.login.username,
key: this.i18nService.t("copyUsername"),
field: "username",
};
} }
return this.findSingleCopiableItem(loginItems); return this.findSingleCopiableItem(loginItems);
} }
@@ -78,12 +87,10 @@ export class ItemCopyActionsComponent {
* Given a list of CipherItems, if there is only one item with a value, * Given a list of CipherItems, if there is only one item with a value,
* return it with the translated key. Otherwise return null * return it with the translated key. Otherwise return null
*/ */
findSingleCopiableItem(items: { value: string; key: string }[]): CipherItem | null { findSingleCopiableItem(items: CipherItem[]): CipherItem | null {
const singleItemWithValue = items.find( const itemsWithValue = items.filter(({ value }) => !!value);
(key) => key.value && items.every((f) => f === key || !f.value), return itemsWithValue.length === 1
); ? { ...itemsWithValue[0], key: this.i18nService.t(itemsWithValue[0].key) }
return singleItemWithValue
? { value: singleItemWithValue.value, key: this.i18nService.t(singleItemWithValue.key) }
: null; : null;
} }