1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 01:03:35 +00:00

[PM-11249] Sync attachment updates across platforms (#11758)

* update extension refresh form when an attachment is added or removed

- This is needed because the revision date was updated on the server and the locally stored cipher needs to match.

* receive updated cipher from delete attachment endpoint

- deleting an attachment will now alter the revision timestamp on a cipher.

* patch the cipher when an attachment is added or deleted

* migrate vault component to use the `cipherViews$` observable

* reference `cipherViews$` on desktop for vault-items

- This avoid race conditions where ciphers are cleared out in the background. `cipherViews` should always emit the latest views

* return CipherData from cipher service so that consumers have the updated cipher right away

* use the updated cipher from attachment endpoints to refresh the details within the add/edit components on desktop
This commit is contained in:
Nick Krantz
2025-01-28 10:01:23 -06:00
committed by GitHub
parent 70ea75d8f7
commit 7c2bf504a3
10 changed files with 95 additions and 26 deletions

View File

@@ -43,6 +43,7 @@ import {
DecryptionFailureDialogComponent,
} from "@bitwarden/vault";
import { CipherFormComponent } from "../../../../../../../libs/vault/src/cipher-form/components/cipher-form.component";
import { SharedModule } from "../../../shared/shared.module";
import {
AttachmentDialogCloseResult,
@@ -144,6 +145,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
@ViewChild("dialogContent")
protected dialogContent: ElementRef<HTMLElement>;
@ViewChild(CipherFormComponent) cipherFormComponent!: CipherFormComponent;
/**
* Tracks if the cipher was ever modified while the dialog was open. Used to ensure the dialog emits the correct result
* in case of closing with the X button or ESC key.
@@ -432,6 +435,22 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
result.action === AttachmentDialogResult.Removed ||
result.action === AttachmentDialogResult.Uploaded
) {
const updatedCipher = await this.cipherService.get(this.formConfig.originalCipher?.id);
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
);
const updatedCipherView = await updatedCipher.decrypt(
await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId),
);
this.cipherFormComponent.patchCipher((currentCipher) => {
currentCipher.attachments = updatedCipherView.attachments;
currentCipher.revisionDate = updatedCipherView.revisionDate;
return currentCipher;
});
this._cipherModified = true;
}
};