mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-25682] Migrate CipherView and subviews to be TS strict compliant (#16463)
* [PM-25682] Remove ts-strict-ignore from Vault view models and update types to be strict * [PM-25682] Ignore ViewEncryptableKeys error for old decrypt methods * [PM-25682] Add null/undefined as possible types for isNull* and other helpers that include null checks internally * [PM-25682] Use patchValue instead of setValue which does not support undefined values * [PM-25682] Add type assertions and other misc. null checks where necessary * [PM-25682] Fix importers specs * [PM-25682] Cleanup card view/details * [PM-25682] Fix cipher view hasAttachment helper * [PM-25682] Cleanup unecessary null assignments in notification.background.spec.ts * [PM-25682] Ensure linkedId is undefined instead of null * [PM-25682] Cleanup misc typing errors * [PM-25682] Make the CipherId required * [PM-25682] Undo CipherId assertions * [PM-25682] Undo brand initial value change * [PM-25682] Update SshKeyView * [PM-25682] Add constructor to Fido2CredentialView * [PM-25682] Prettier * [PM-25682] Fix strict type warnings after merge with main * [PM-25682] Cleanup cipher view spec * [PM-25682] Cleanup new type warnings after merge * [PM-25682] Undo removed eslint-disable-next-line comment * [PM-25682] Fix flaky test * [PM-25682] Use satisfies instead of as for Fido2CredentialAutofillView
This commit is contained in:
@@ -86,7 +86,10 @@ describe("AdditionalOptionsSectionComponent", () => {
|
||||
expect(cipherFormProvider.patchCipher).toHaveBeenCalled();
|
||||
const patchFn = cipherFormProvider.patchCipher.mock.lastCall[0];
|
||||
|
||||
const updated = patchFn(new CipherView());
|
||||
const newCipher = new CipherView();
|
||||
newCipher.creationDate = newCipher.revisionDate = expectedCipher.creationDate;
|
||||
|
||||
const updated = patchFn(newCipher);
|
||||
|
||||
expect(updated).toEqual(expectedCipher);
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ export class DeleteAttachmentComponent {
|
||||
|
||||
await this.cipherService.deleteAttachmentWithServer(
|
||||
this.cipherId,
|
||||
this.attachment.id,
|
||||
this.attachment.id!,
|
||||
activeUserId,
|
||||
this.admin,
|
||||
);
|
||||
|
||||
@@ -67,6 +67,7 @@ describe("CardDetailsSectionComponent", () => {
|
||||
cardView.brand = "Visa";
|
||||
cardView.expMonth = "";
|
||||
cardView.code = "";
|
||||
cardView.expYear = "";
|
||||
|
||||
expect(patchCipherSpy).toHaveBeenCalled();
|
||||
const patchFn = patchCipherSpy.mock.lastCall[0];
|
||||
@@ -85,6 +86,7 @@ describe("CardDetailsSectionComponent", () => {
|
||||
cardView.number = "";
|
||||
cardView.expMonth = "";
|
||||
cardView.code = "";
|
||||
cardView.brand = "";
|
||||
cardView.expYear = "2022";
|
||||
|
||||
expect(patchCipherSpy).toHaveBeenCalled();
|
||||
@@ -122,8 +124,6 @@ describe("CardDetailsSectionComponent", () => {
|
||||
number,
|
||||
code,
|
||||
brand: cardView.brand,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -52,12 +52,12 @@ export class CardDetailsSectionComponent implements OnInit {
|
||||
* leaving as just null gets inferred as `unknown`
|
||||
*/
|
||||
cardDetailsForm = this.formBuilder.group({
|
||||
cardholderName: null as string | null,
|
||||
number: null as string | null,
|
||||
brand: null as string | null,
|
||||
expMonth: null as string | null,
|
||||
expYear: null as string | number | null,
|
||||
code: null as string | null,
|
||||
cardholderName: "",
|
||||
number: "",
|
||||
brand: "",
|
||||
expMonth: "",
|
||||
expYear: "" as string | number,
|
||||
code: "",
|
||||
});
|
||||
|
||||
/** Available Card Brands */
|
||||
@@ -110,16 +110,14 @@ export class CardDetailsSectionComponent implements OnInit {
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe(({ cardholderName, number, brand, expMonth, expYear, code }) => {
|
||||
this.cipherFormContainer.patchCipher((cipher) => {
|
||||
const expirationYear = normalizeExpiryYearFormat(expYear);
|
||||
const expirationYear = normalizeExpiryYearFormat(expYear) ?? "";
|
||||
|
||||
Object.assign(cipher.card, {
|
||||
cardholderName,
|
||||
number,
|
||||
brand,
|
||||
expMonth,
|
||||
expYear: expirationYear,
|
||||
code,
|
||||
});
|
||||
cipher.card.cardholderName = cardholderName;
|
||||
cipher.card.number = number;
|
||||
cipher.card.brand = brand;
|
||||
cipher.card.expMonth = expMonth;
|
||||
cipher.card.expYear = expirationYear;
|
||||
cipher.card.code = code;
|
||||
|
||||
return cipher;
|
||||
});
|
||||
@@ -167,6 +165,7 @@ export class CardDetailsSectionComponent implements OnInit {
|
||||
expMonth: this.initialValues?.expMonth || "",
|
||||
expYear: this.initialValues?.expYear || "",
|
||||
code: this.initialValues?.code || "",
|
||||
brand: CardView.getCardBrandByPatterns(this.initialValues?.number) || "",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -195,18 +194,4 @@ export class CardDetailsSectionComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set form initial form values from the current cipher */
|
||||
private setInitialValues(cipherView: CipherView) {
|
||||
const { cardholderName, number, brand, expMonth, expYear, code } = cipherView.card;
|
||||
|
||||
this.cardDetailsForm.setValue({
|
||||
cardholderName: cardholderName,
|
||||
number: number,
|
||||
brand: brand,
|
||||
expMonth: expMonth,
|
||||
expYear: expYear,
|
||||
code: code,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
||||
fieldView.type = field.type;
|
||||
fieldView.name = field.name;
|
||||
fieldView.value = value;
|
||||
fieldView.linkedId = field.linkedId;
|
||||
fieldView.linkedId = field.linkedId ?? undefined;
|
||||
return fieldView;
|
||||
});
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ export class IdentitySectionComponent implements OnInit {
|
||||
populateFormData(cipherView: CipherView) {
|
||||
const { identity } = cipherView;
|
||||
|
||||
this.identityForm.setValue({
|
||||
this.identityForm.patchValue({
|
||||
title: identity.title,
|
||||
firstName: identity.firstName,
|
||||
middleName: identity.middleName,
|
||||
|
||||
@@ -312,7 +312,7 @@ export class ItemDetailsSectionComponent implements OnInit {
|
||||
private async initFromExistingCipher(prefillCipher: CipherView) {
|
||||
const { name, folderId, collectionIds } = prefillCipher;
|
||||
|
||||
this.itemDetailsForm.setValue({
|
||||
this.itemDetailsForm.patchValue({
|
||||
name: name ? name : (this.initialValues?.name ?? ""),
|
||||
organizationId: prefillCipher.organizationId, // We do not allow changing ownership of an existing cipher.
|
||||
folderId: folderId ? folderId : (this.initialValues?.folderId ?? null),
|
||||
|
||||
@@ -36,7 +36,7 @@ export class DefaultCipherFormService implements CipherFormService {
|
||||
let savedCipher: Cipher;
|
||||
|
||||
// Creating a new cipher
|
||||
if (cipher.id == null) {
|
||||
if (cipher.id == null || cipher.id === "") {
|
||||
const encrypted = await this.cipherService.encrypt(cipher, activeUserId);
|
||||
savedCipher = await this.cipherService.createWithServer(encrypted, config.admin);
|
||||
return await this.cipherService.decrypt(savedCipher, activeUserId);
|
||||
|
||||
@@ -44,7 +44,7 @@ import { VaultAutosizeReadOnlyTextArea } from "../../directives/readonly-textare
|
||||
export class CustomFieldV2Component implements OnInit, OnChanges {
|
||||
@Input({ required: true }) cipher!: CipherView;
|
||||
fieldType = FieldType;
|
||||
fieldOptions: Map<number, LinkedMetadata> | null = null;
|
||||
fieldOptions: Map<number, LinkedMetadata> | undefined;
|
||||
|
||||
/** Indexes of hidden fields that are revealed */
|
||||
revealedHiddenFields: number[] = [];
|
||||
@@ -124,7 +124,7 @@ export class CustomFieldV2Component implements OnInit, OnChanges {
|
||||
case CipherType.Identity:
|
||||
return IdentityView.prototype.linkedFieldOptions;
|
||||
default:
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user