[AC-2447] Allow the UI to save and close dialog when user removes final Can Manage Collection of an item (#9136)
* update saveCollectionsWithServer to accept a new value if user can no longer manage cipher after requested update
This commit is contained in:
parent
b7463d551c
commit
5075d0865e
|
@ -123,6 +123,7 @@ import {
|
||||||
CollectionDetailsResponse,
|
CollectionDetailsResponse,
|
||||||
CollectionResponse,
|
CollectionResponse,
|
||||||
} from "../vault/models/response/collection.response";
|
} from "../vault/models/response/collection.response";
|
||||||
|
import { OptionalCipherResponse } from "../vault/models/response/optional-cipher.response";
|
||||||
import { SyncResponse } from "../vault/models/response/sync.response";
|
import { SyncResponse } from "../vault/models/response/sync.response";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -218,7 +219,10 @@ export abstract class ApiService {
|
||||||
putMoveCiphers: (request: CipherBulkMoveRequest) => Promise<any>;
|
putMoveCiphers: (request: CipherBulkMoveRequest) => Promise<any>;
|
||||||
putShareCipher: (id: string, request: CipherShareRequest) => Promise<CipherResponse>;
|
putShareCipher: (id: string, request: CipherShareRequest) => Promise<CipherResponse>;
|
||||||
putShareCiphers: (request: CipherBulkShareRequest) => Promise<any>;
|
putShareCiphers: (request: CipherBulkShareRequest) => Promise<any>;
|
||||||
putCipherCollections: (id: string, request: CipherCollectionsRequest) => Promise<CipherResponse>;
|
putCipherCollections: (
|
||||||
|
id: string,
|
||||||
|
request: CipherCollectionsRequest,
|
||||||
|
) => Promise<OptionalCipherResponse>;
|
||||||
putCipherCollectionsAdmin: (id: string, request: CipherCollectionsRequest) => Promise<any>;
|
putCipherCollectionsAdmin: (id: string, request: CipherCollectionsRequest) => Promise<any>;
|
||||||
postPurgeCiphers: (request: SecretVerificationRequest, organizationId?: string) => Promise<any>;
|
postPurgeCiphers: (request: SecretVerificationRequest, organizationId?: string) => Promise<any>;
|
||||||
putDeleteCipher: (id: string) => Promise<any>;
|
putDeleteCipher: (id: string) => Promise<any>;
|
||||||
|
|
|
@ -138,6 +138,7 @@ import {
|
||||||
CollectionDetailsResponse,
|
CollectionDetailsResponse,
|
||||||
CollectionResponse,
|
CollectionResponse,
|
||||||
} from "../vault/models/response/collection.response";
|
} from "../vault/models/response/collection.response";
|
||||||
|
import { OptionalCipherResponse } from "../vault/models/response/optional-cipher.response";
|
||||||
import { SyncResponse } from "../vault/models/response/sync.response";
|
import { SyncResponse } from "../vault/models/response/sync.response";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -566,9 +567,15 @@ export class ApiService implements ApiServiceAbstraction {
|
||||||
async putCipherCollections(
|
async putCipherCollections(
|
||||||
id: string,
|
id: string,
|
||||||
request: CipherCollectionsRequest,
|
request: CipherCollectionsRequest,
|
||||||
): Promise<CipherResponse> {
|
): Promise<OptionalCipherResponse> {
|
||||||
const response = await this.send("PUT", "/ciphers/" + id + "/collections", request, true, true);
|
const response = await this.send(
|
||||||
return new CipherResponse(response);
|
"PUT",
|
||||||
|
"/ciphers/" + id + "/collections_v2",
|
||||||
|
request,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
return new OptionalCipherResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
putCipherCollectionsAdmin(id: string, request: CipherCollectionsRequest): Promise<any> {
|
putCipherCollectionsAdmin(id: string, request: CipherCollectionsRequest): Promise<any> {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { BaseResponse } from "../../../models/response/base.response";
|
||||||
|
|
||||||
|
import { CipherResponse } from "./cipher.response";
|
||||||
|
|
||||||
|
export class OptionalCipherResponse extends BaseResponse {
|
||||||
|
unavailable: boolean;
|
||||||
|
cipher?: CipherResponse;
|
||||||
|
|
||||||
|
constructor(response: any) {
|
||||||
|
super(response);
|
||||||
|
this.unavailable = this.getResponseProperty("Unavailable");
|
||||||
|
this.cipher = new CipherResponse(this.getResponseProperty("Cipher"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -776,9 +776,14 @@ export class CipherService implements CipherServiceAbstraction {
|
||||||
async saveCollectionsWithServer(cipher: Cipher): Promise<Cipher> {
|
async saveCollectionsWithServer(cipher: Cipher): Promise<Cipher> {
|
||||||
const request = new CipherCollectionsRequest(cipher.collectionIds);
|
const request = new CipherCollectionsRequest(cipher.collectionIds);
|
||||||
const response = await this.apiService.putCipherCollections(cipher.id, request);
|
const response = await this.apiService.putCipherCollections(cipher.id, request);
|
||||||
const data = new CipherData(response);
|
// The response will now check for an unavailable value. This value determines whether
|
||||||
|
// the user still has Can Manage access to the item after updating.
|
||||||
|
if (response.unavailable) {
|
||||||
|
await this.delete(cipher.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = new CipherData(response.cipher);
|
||||||
const updated = await this.upsert(data);
|
const updated = await this.upsert(data);
|
||||||
// Collection updates don't change local data
|
|
||||||
return new Cipher(updated[cipher.id as CipherId], cipher.localData);
|
return new Cipher(updated[cipher.id as CipherId], cipher.localData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue