mirror of
https://github.com/bitwarden/browser
synced 2026-03-01 19:11:22 +00:00
[PM-30891] - Create My Items On Restore (#18454)
* Added encrypted default collection name to new feature flagged restore user methods/endpoint. * corrected filter to use null check with imperative code
This commit is contained in:
@@ -13,6 +13,8 @@ import {
|
||||
OrganizationUserUpdateRequest,
|
||||
OrganizationUserBulkRequest,
|
||||
} from "../models/requests";
|
||||
import { OrganizationUserBulkRestoreRequest } from "../models/requests/organization-user-bulk-restore.request";
|
||||
import { OrganizationUserRestoreRequest } from "../models/requests/organization-user-restore.request";
|
||||
import {
|
||||
OrganizationUserBulkPublicKeyResponse,
|
||||
OrganizationUserBulkResponse,
|
||||
@@ -359,6 +361,20 @@ export class DefaultOrganizationUserApiService implements OrganizationUserApiSer
|
||||
);
|
||||
}
|
||||
|
||||
restoreOrganizationUser_vNext(
|
||||
organizationId: string,
|
||||
id: string,
|
||||
request: OrganizationUserRestoreRequest,
|
||||
): Promise<void> {
|
||||
return this.apiService.send(
|
||||
"PUT",
|
||||
"/organizations/" + organizationId + "/users/" + id + "/restore/vnext",
|
||||
request,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
async restoreManyOrganizationUsers(
|
||||
organizationId: string,
|
||||
ids: string[],
|
||||
@@ -373,6 +389,20 @@ export class DefaultOrganizationUserApiService implements OrganizationUserApiSer
|
||||
return new ListResponse(r, OrganizationUserBulkResponse);
|
||||
}
|
||||
|
||||
async restoreManyOrganizationUsers_vNext(
|
||||
organizationId: string,
|
||||
request: OrganizationUserBulkRestoreRequest,
|
||||
): Promise<ListResponse<OrganizationUserBulkResponse>> {
|
||||
const r = await this.apiService.send(
|
||||
"PUT",
|
||||
"/organizations/" + organizationId + "/users/restore",
|
||||
request,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
return new ListResponse(r, OrganizationUserBulkResponse);
|
||||
}
|
||||
|
||||
deleteOrganizationUser(organizationId: string, id: string): Promise<void> {
|
||||
return this.apiService.send(
|
||||
"DELETE",
|
||||
|
||||
@@ -61,6 +61,8 @@ describe("DefaultOrganizationUserService", () => {
|
||||
organizationUserApiService = {
|
||||
postOrganizationUserConfirm: jest.fn(),
|
||||
postOrganizationUserBulkConfirm: jest.fn(),
|
||||
restoreOrganizationUser_vNext: jest.fn(),
|
||||
restoreManyOrganizationUsers_vNext: jest.fn(),
|
||||
} as any;
|
||||
|
||||
accountService = {
|
||||
@@ -174,4 +176,97 @@ describe("DefaultOrganizationUserService", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildRestoreUserRequest", () => {
|
||||
beforeEach(() => {
|
||||
setupCommonMocks();
|
||||
});
|
||||
|
||||
it("should build a restore request with encrypted collection name", (done) => {
|
||||
service.buildRestoreUserRequest(mockOrganization).subscribe({
|
||||
next: (request) => {
|
||||
expect(i18nService.t).toHaveBeenCalledWith("myItems");
|
||||
expect(encryptService.encryptString).toHaveBeenCalledWith(
|
||||
mockDefaultCollectionName,
|
||||
mockOrgKey,
|
||||
);
|
||||
expect(request).toEqual({
|
||||
defaultUserCollectionName: mockEncryptedCollectionName.encryptedString,
|
||||
});
|
||||
done();
|
||||
},
|
||||
error: done,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("restoreUser", () => {
|
||||
beforeEach(() => {
|
||||
setupCommonMocks();
|
||||
organizationUserApiService.restoreOrganizationUser_vNext.mockReturnValue(Promise.resolve());
|
||||
});
|
||||
|
||||
it("should restore a user successfully", (done) => {
|
||||
service.restoreUser(mockOrganization, mockUserId).subscribe({
|
||||
next: () => {
|
||||
expect(i18nService.t).toHaveBeenCalledWith("myItems");
|
||||
expect(encryptService.encryptString).toHaveBeenCalledWith(
|
||||
mockDefaultCollectionName,
|
||||
mockOrgKey,
|
||||
);
|
||||
expect(organizationUserApiService.restoreOrganizationUser_vNext).toHaveBeenCalledWith(
|
||||
mockOrganization.id,
|
||||
mockUserId,
|
||||
{
|
||||
defaultUserCollectionName: mockEncryptedCollectionName.encryptedString,
|
||||
},
|
||||
);
|
||||
done();
|
||||
},
|
||||
error: done,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("bulkRestoreUsers", () => {
|
||||
const mockUserIds = ["user-1", "user-2"];
|
||||
|
||||
const mockBulkResponse = {
|
||||
data: [
|
||||
{ id: "user-1", error: null } as OrganizationUserBulkResponse,
|
||||
{ id: "user-2", error: null } as OrganizationUserBulkResponse,
|
||||
],
|
||||
} as ListResponse<OrganizationUserBulkResponse>;
|
||||
|
||||
beforeEach(() => {
|
||||
setupCommonMocks();
|
||||
organizationUserApiService.restoreManyOrganizationUsers_vNext.mockReturnValue(
|
||||
Promise.resolve(mockBulkResponse),
|
||||
);
|
||||
});
|
||||
|
||||
it("should bulk restore users successfully", (done) => {
|
||||
service.bulkRestoreUsers(mockOrganization, mockUserIds).subscribe({
|
||||
next: (response) => {
|
||||
expect(i18nService.t).toHaveBeenCalledWith("myItems");
|
||||
expect(encryptService.encryptString).toHaveBeenCalledWith(
|
||||
mockDefaultCollectionName,
|
||||
mockOrgKey,
|
||||
);
|
||||
expect(
|
||||
organizationUserApiService.restoreManyOrganizationUsers_vNext,
|
||||
).toHaveBeenCalledWith(
|
||||
mockOrganization.id,
|
||||
expect.objectContaining({
|
||||
userIds: mockUserIds,
|
||||
defaultUserCollectionName: mockEncryptedCollectionName.encryptedString,
|
||||
}),
|
||||
);
|
||||
expect(response).toEqual(mockBulkResponse);
|
||||
done();
|
||||
},
|
||||
error: done,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { combineLatest, filter, map, Observable, switchMap } from "rxjs";
|
||||
|
||||
import {
|
||||
OrganizationUserConfirmRequest,
|
||||
OrganizationUserBulkConfirmRequest,
|
||||
OrganizationUserApiService,
|
||||
OrganizationUserBulkConfirmRequest,
|
||||
OrganizationUserBulkResponse,
|
||||
OrganizationUserConfirmRequest,
|
||||
OrganizationUserService,
|
||||
} from "@bitwarden/admin-console/common";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
@@ -16,6 +16,9 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
|
||||
import { OrganizationUserBulkRestoreRequest } from "../models/requests/organization-user-bulk-restore.request";
|
||||
import { OrganizationUserRestoreRequest } from "../models/requests/organization-user-restore.request";
|
||||
|
||||
export class DefaultOrganizationUserService implements OrganizationUserService {
|
||||
constructor(
|
||||
protected keyService: KeyService,
|
||||
@@ -83,6 +86,43 @@ export class DefaultOrganizationUserService implements OrganizationUserService {
|
||||
);
|
||||
}
|
||||
|
||||
buildRestoreUserRequest(organization: Organization): Observable<OrganizationUserRestoreRequest> {
|
||||
return this.getEncryptedDefaultCollectionName$(organization).pipe(
|
||||
map((collectionName) => new OrganizationUserRestoreRequest(collectionName.encryptedString)),
|
||||
);
|
||||
}
|
||||
|
||||
restoreUser(organization: Organization, userId: string): Observable<void> {
|
||||
return this.buildRestoreUserRequest(organization).pipe(
|
||||
switchMap((request) =>
|
||||
this.organizationUserApiService.restoreOrganizationUser_vNext(
|
||||
organization.id,
|
||||
userId,
|
||||
request,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bulkRestoreUsers(
|
||||
organization: Organization,
|
||||
userIds: string[],
|
||||
): Observable<ListResponse<OrganizationUserBulkResponse>> {
|
||||
return this.getEncryptedDefaultCollectionName$(organization).pipe(
|
||||
switchMap((collectionName) => {
|
||||
const request = new OrganizationUserBulkRestoreRequest(
|
||||
userIds,
|
||||
collectionName.encryptedString,
|
||||
);
|
||||
|
||||
return this.organizationUserApiService.restoreManyOrganizationUsers_vNext(
|
||||
organization.id,
|
||||
request,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private getEncryptedDefaultCollectionName$(organization: Organization) {
|
||||
return this.orgKey$(organization).pipe(
|
||||
switchMap((orgKey) =>
|
||||
|
||||
Reference in New Issue
Block a user