mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +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:
@@ -702,7 +702,7 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
}
|
||||
|
||||
deleteCipherAttachment(id: string, attachmentId: string): Promise<any> {
|
||||
return this.send("DELETE", "/ciphers/" + id + "/attachment/" + attachmentId, null, true, false);
|
||||
return this.send("DELETE", "/ciphers/" + id + "/attachment/" + attachmentId, null, true, true);
|
||||
}
|
||||
|
||||
deleteCipherAttachmentAdmin(id: string, attachmentId: string): Promise<any> {
|
||||
|
||||
@@ -154,8 +154,8 @@ export abstract class CipherService implements UserKeyRotationDataProvider<Ciphe
|
||||
delete: (id: string | string[]) => Promise<any>;
|
||||
deleteWithServer: (id: string, asAdmin?: boolean) => Promise<any>;
|
||||
deleteManyWithServer: (ids: string[], asAdmin?: boolean) => Promise<any>;
|
||||
deleteAttachment: (id: string, attachmentId: string) => Promise<void>;
|
||||
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<void>;
|
||||
deleteAttachment: (id: string, revisionDate: string, attachmentId: string) => Promise<CipherData>;
|
||||
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<CipherData>;
|
||||
sortCiphersByLastUsed: (a: CipherView, b: CipherView) => number;
|
||||
sortCiphersByLastUsedThenName: (a: CipherView, b: CipherView) => number;
|
||||
getLocaleSortingFunction: () => (a: CipherView, b: CipherView) => number;
|
||||
|
||||
@@ -1078,7 +1078,11 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
await this.delete(ids);
|
||||
}
|
||||
|
||||
async deleteAttachment(id: string, attachmentId: string): Promise<void> {
|
||||
async deleteAttachment(
|
||||
id: string,
|
||||
revisionDate: string,
|
||||
attachmentId: string,
|
||||
): Promise<CipherData> {
|
||||
let ciphers = await firstValueFrom(this.ciphers$);
|
||||
const cipherId = id as CipherId;
|
||||
// eslint-disable-next-line
|
||||
@@ -1092,6 +1096,10 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
}
|
||||
}
|
||||
|
||||
// Deleting the cipher updates the revision date on the server,
|
||||
// Update the stored `revisionDate` to match
|
||||
ciphers[cipherId].revisionDate = revisionDate;
|
||||
|
||||
await this.clearCache();
|
||||
await this.encryptedCiphersState.update(() => {
|
||||
if (ciphers == null) {
|
||||
@@ -1099,15 +1107,20 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
}
|
||||
return ciphers;
|
||||
});
|
||||
|
||||
return ciphers[cipherId];
|
||||
}
|
||||
|
||||
async deleteAttachmentWithServer(id: string, attachmentId: string): Promise<void> {
|
||||
async deleteAttachmentWithServer(id: string, attachmentId: string): Promise<CipherData> {
|
||||
let cipherResponse = null;
|
||||
try {
|
||||
await this.apiService.deleteCipherAttachment(id, attachmentId);
|
||||
cipherResponse = await this.apiService.deleteCipherAttachment(id, attachmentId);
|
||||
} catch (e) {
|
||||
return Promise.reject((e as ErrorResponse).getSingleMessage());
|
||||
}
|
||||
await this.deleteAttachment(id, attachmentId);
|
||||
const cipherData = CipherData.fromJSON(cipherResponse?.cipher);
|
||||
|
||||
return await this.deleteAttachment(id, cipherData.revisionDate, attachmentId);
|
||||
}
|
||||
|
||||
sortCiphersByLastUsed(a: CipherView, b: CipherView): number {
|
||||
|
||||
Reference in New Issue
Block a user