mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43: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:
@@ -22,6 +22,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
|
||||
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
import { SshKeyPasswordPromptComponent } from "@bitwarden/importer/ui";
|
||||
@@ -148,6 +149,16 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cipher when an attachment is altered.
|
||||
* Note: This only updates the `attachments` and `revisionDate`
|
||||
* properties to ensure any in-progress edits are not lost.
|
||||
*/
|
||||
patchCipherAttachments(cipher: CipherView) {
|
||||
this.cipher.attachments = cipher.attachments;
|
||||
this.cipher.revisionDate = cipher.revisionDate;
|
||||
}
|
||||
|
||||
async importSshKeyFromClipboard(password: string = "") {
|
||||
const key = await this.platformUtilsService.readFromClipboard();
|
||||
const parsedKey = await ipc.platform.sshAgent.importKey(key, password);
|
||||
|
||||
@@ -159,11 +159,6 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
await this.vaultFilterComponent.reloadCollectionsAndFolders(this.activeFilter);
|
||||
await this.vaultFilterComponent.reloadOrganizations();
|
||||
break;
|
||||
case "refreshCiphers":
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.vaultItemsComponent.refresh();
|
||||
break;
|
||||
case "modalShown":
|
||||
this.showingModal = true;
|
||||
break;
|
||||
@@ -535,9 +530,19 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
|
||||
let madeAttachmentChanges = false;
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
childComponent.onUploadedAttachment.subscribe(() => (madeAttachmentChanges = true));
|
||||
childComponent.onUploadedAttachment.subscribe((cipher) => {
|
||||
madeAttachmentChanges = true;
|
||||
// Update the edit component cipher with the updated cipher,
|
||||
// which is needed because the revision date is updated when an attachment is altered
|
||||
this.addEditComponent.patchCipherAttachments(cipher);
|
||||
});
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
childComponent.onDeletedAttachment.subscribe(() => (madeAttachmentChanges = true));
|
||||
childComponent.onDeletedAttachment.subscribe((cipher) => {
|
||||
madeAttachmentChanges = true;
|
||||
// Update the edit component cipher with the updated cipher,
|
||||
// which is needed because the revision date is updated when an attachment is altered
|
||||
this.addEditComponent.patchCipherAttachments(cipher);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
|
||||
this.modal.onClosed.subscribe(async () => {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user