[PM-39778] Fix new item subtitles when using sdk (#21591)

* add bank account list view sdk support to allow for bankAccountSubtitle to work properly

* Update sdk-internal to 0.2.0-main.900

* fix npm ci

---------

Co-authored-by: bw-ghapp[bot] <178206702+bw-ghapp[bot]@users.noreply.github.com>
This commit is contained in:
Jackson Engstrom 2026-07-14 16:31:52 -07:00 committed by GitHub
parent 3262524f72
commit d7bd236b82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 23 deletions

View File

@ -262,7 +262,7 @@ describe("CipherViewLikeUtils", () => {
cipherListView.type = "secureNote";
expect(CipherViewLikeUtils.getType(cipherListView)).toBe(CipherType.SecureNote);
cipherListView.type = "bankAccount";
cipherListView.type = { bankAccount: { accountNumber: "1234", accountType: "checking" } };
expect(CipherViewLikeUtils.getType(cipherListView)).toBe(CipherType.BankAccount);
cipherListView.type = "driversLicense";
@ -362,12 +362,9 @@ describe("CipherViewLikeUtils", () => {
expect(i18nService.t).not.toHaveBeenCalled();
});
it("falls back to the SDK-provided subtitle for a CipherListView bank account", () => {
// CipherListViewType encodes bank account as a plain string discriminator and does
// not carry accountType/accountNumber inline. The SDK's pre-computed `subtitle` is
// the only signal we have.
it("falls back to the SDK-provided subtitle for a CipherListView bank account without inline data", () => {
const cipherListView = {
type: "bankAccount",
type: { bankAccount: { accountNumber: undefined, accountType: undefined } },
subtitle: "SDK-provided fallback",
} as CipherListView;
@ -376,6 +373,20 @@ describe("CipherViewLikeUtils", () => {
);
});
it("computes a translated subtitle from the inline data of a CipherListView bank account", () => {
const cipherListView = {
type: {
bankAccount: { accountNumber: "987651234", accountType: BankAccountType.Checking },
},
subtitle: "SDK-provided fallback",
} as CipherListView;
expect(CipherViewLikeUtils.subtitle(cipherListView, i18nService)).toBe(
"translated:bankAccountTypeChecking, *1234",
);
expect(i18nService.t).toHaveBeenCalledWith("bankAccountTypeChecking");
});
it("returns the base subtitle for non-bank-account ciphers even when i18nService is provided", () => {
const cipherView = createCipherView();
cipherView.login = new LoginView();
@ -767,7 +778,6 @@ describe("CipherViewLikeUtils", () => {
it("returns true for copyable fields in a bank account cipher", () => {
const cipherListView = {
type: "bankAccount",
copyableFields: [
"BankAccountNameOnAccount",
"BankAccountAccountNumber",
@ -777,6 +787,7 @@ describe("CipherViewLikeUtils", () => {
"BankAccountIban",
"BankAccountSwift",
],
type: { bankAccount: { accountNumber: undefined, accountType: undefined } },
} as CipherListView;
expect(CipherViewLikeUtils.hasCopyableValue(cipherListView, "nameOnAccount")).toBe(true);

View File

@ -1,4 +1,5 @@
import {
BankAccountListView,
BankAccountView as SdkBankAccountView,
CardListView,
CipherListView,
@ -130,7 +131,7 @@ export class CipherViewLikeUtils {
return CipherType.SecureNote;
case cipher.type === "sshKey":
return CipherType.SshKey;
case cipher.type === "bankAccount":
case typeof cipher.type === "object" && "bankAccount" in cipher.type:
return CipherType.BankAccount;
case cipher.type === "passport":
return CipherType.Passport;
@ -173,13 +174,16 @@ export class CipherViewLikeUtils {
}
};
private static getBankAccount = (
/** @returns The bank account object from the input cipher. If the cipher is not of type BankAccount, returns null. */
static getBankAccount = (
cipher: CipherViewLike,
): BankAccountView | SdkBankAccountView | null => {
// CipherListViewType only inlines `card` and `login` data — bank account is a plain
// string discriminator without nested view data, so there is nothing to read here.
): BankAccountView | SdkBankAccountView | BankAccountListView | null => {
if (this.isCipherListView(cipher)) {
return null;
if (typeof cipher.type !== "object") {
return null;
}
return "bankAccount" in cipher.type ? cipher.type.bankAccount : null;
}
return cipher.type === CipherType.BankAccount ? (cipher.bankAccount ?? null) : null;

16
package-lock.json generated
View File

@ -23,9 +23,9 @@
"@angular/platform-browser": "21.2.17",
"@angular/platform-browser-dynamic": "21.2.17",
"@angular/router": "21.2.17",
"@bitwarden/commercial-sdk-internal": "0.2.0-main.897",
"@bitwarden/commercial-sdk-internal": "0.2.0-main.900",
"@bitwarden/desktop-napi": "file:apps/desktop/desktop_native/napi",
"@bitwarden/sdk-internal": "0.2.0-main.897",
"@bitwarden/sdk-internal": "0.2.0-main.900",
"@bufbuild/protobuf": "2.11.0",
"@electron/fuses": "2.1.1",
"@emotion/css": "11.13.5",
@ -4835,9 +4835,9 @@
"link": true
},
"node_modules/@bitwarden/commercial-sdk-internal": {
"version": "0.2.0-main.897",
"resolved": "https://registry.npmjs.org/@bitwarden/commercial-sdk-internal/-/commercial-sdk-internal-0.2.0-main.897.tgz",
"integrity": "sha512-U4CJXOzqkuPlQqra4pppXfWKafmJ984IrmGi5aVrO6oNZlJ+3NnGVtP7PRNGrIAAo0Y49KXsndEczDiuEZDP3Q==",
"version": "0.2.0-main.900",
"resolved": "https://registry.npmjs.org/@bitwarden/commercial-sdk-internal/-/commercial-sdk-internal-0.2.0-main.900.tgz",
"integrity": "sha512-ZLFiFazveJ5bMUEx1XM7tdEMTBViNb86iIjLbVCTrnR1gQZ4jm6xxB6XaISTnTOWGo3q4BaDGIWHaXft+v/+Zg==",
"license": "BITWARDEN SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT",
"dependencies": {
"type-fest": "^5.0.0"
@ -4959,9 +4959,9 @@
"link": true
},
"node_modules/@bitwarden/sdk-internal": {
"version": "0.2.0-main.897",
"resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.897.tgz",
"integrity": "sha512-PCaJxhfBxv62gWdpHhq0HwfXkr0fQtA+F68EzpVn+kHXxF1KLkSBmU6vMPdGhfOmLln12jgiSHGPJ8+EnVH18w==",
"version": "0.2.0-main.900",
"resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.900.tgz",
"integrity": "sha512-abrTTSa4Em9HmpMieZ6R0srNoYJI8VvZvXkldrZuMyj75UcI7hqkAXfd3b0nNWJVX24MMryWSZgy+/5dGpbs0A==",
"license": "GPL-3.0",
"dependencies": {
"type-fest": "^5.0.0"

View File

@ -174,9 +174,9 @@
"@angular/platform-browser": "21.2.17",
"@angular/platform-browser-dynamic": "21.2.17",
"@angular/router": "21.2.17",
"@bitwarden/commercial-sdk-internal": "0.2.0-main.897",
"@bitwarden/commercial-sdk-internal": "0.2.0-main.900",
"@bitwarden/desktop-napi": "file:apps/desktop/desktop_native/napi",
"@bitwarden/sdk-internal": "0.2.0-main.897",
"@bitwarden/sdk-internal": "0.2.0-main.900",
"@bufbuild/protobuf": "2.11.0",
"@electron/fuses": "2.1.1",
"@emotion/css": "11.13.5",