mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-14417] Create admin TaskService (#12891)
* [PM-14416] Add initial SecurityTask models and enums * [PM-14416] Add support for PATCH request method and 204 No Content response * [PM-14416] Add initial task service abstraction * [PM-14416] Add SecurityTask state/key definitions * [PM-14416] Add DefaultTaskService implementation * [PM-14416] Add DefaultTaskService tests * [PM-14416] Add better null checking to new models * [PM-14416] Improve null value filtering for task service * initial commit, added absract file and implementation file * Added abstract method and implemented bulk create method * Implemented get all api * created spec file * Fixed references * Added exports * Added tests * fixed suggestions * fixed test --------- Co-authored-by: Shane Melton <smelton@bitwarden.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { SecurityTask, SecurityTaskStatus, SecurityTaskType } from "@bitwarden/vault";
|
||||
|
||||
/**
|
||||
* Request type for creating tasks.
|
||||
* @property cipherId - Optional. The ID of the cipher to create the task for.
|
||||
* @property type - The type of task to create. Currently defined as "updateAtRiskCredential".
|
||||
*/
|
||||
export type CreateTasksRequest = Readonly<{
|
||||
cipherId?: CipherId;
|
||||
type: SecurityTaskType.UpdateAtRiskCredential;
|
||||
}>;
|
||||
|
||||
export abstract class AdminTaskService {
|
||||
/**
|
||||
* Retrieves all tasks for a given organization.
|
||||
* @param organizationId - The ID of the organization to retrieve tasks for.
|
||||
* @param status - Optional. The status of the tasks to retrieve.
|
||||
*/
|
||||
abstract getAllTasks(
|
||||
organizationId: OrganizationId,
|
||||
status?: SecurityTaskStatus | undefined,
|
||||
): Promise<SecurityTask[]>;
|
||||
|
||||
/**
|
||||
* Creates multiple tasks for a given organization and sends out notifications to applicable users.
|
||||
* @param organizationId - The ID of the organization to create tasks for.
|
||||
* @param tasks - The tasks to create.
|
||||
*/
|
||||
abstract bulkCreateTasks(
|
||||
organizationId: OrganizationId,
|
||||
tasks: CreateTasksRequest[],
|
||||
): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { MockProxy, mock } from "jest-mock-extended";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { SecurityTaskStatus, SecurityTaskType } from "@bitwarden/vault";
|
||||
|
||||
import { CreateTasksRequest } from "./abstractions/admin-task.abstraction";
|
||||
import { DefaultAdminTaskService } from "./default-admin-task.service";
|
||||
|
||||
describe("DefaultAdminTaskService", () => {
|
||||
let defaultAdminTaskService: DefaultAdminTaskService;
|
||||
let apiService: MockProxy<ApiService>;
|
||||
|
||||
beforeEach(() => {
|
||||
apiService = mock<ApiService>();
|
||||
defaultAdminTaskService = new DefaultAdminTaskService(apiService);
|
||||
});
|
||||
|
||||
describe("getAllTasks", () => {
|
||||
it("should call the api service with the correct parameters with status", async () => {
|
||||
const organizationId = "orgId" as OrganizationId;
|
||||
const status = SecurityTaskStatus.Pending;
|
||||
const expectedUrl = `/tasks/organization?organizationId=${organizationId}&status=0`;
|
||||
|
||||
await defaultAdminTaskService.getAllTasks(organizationId, status);
|
||||
|
||||
expect(apiService.send).toHaveBeenCalledWith("GET", expectedUrl, null, true, true);
|
||||
});
|
||||
|
||||
it("should call the api service with the correct parameters without status", async () => {
|
||||
const organizationId = "orgId" as OrganizationId;
|
||||
const expectedUrl = `/tasks/organization?organizationId=${organizationId}`;
|
||||
|
||||
await defaultAdminTaskService.getAllTasks(organizationId);
|
||||
|
||||
expect(apiService.send).toHaveBeenCalledWith("GET", expectedUrl, null, true, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("bulkCreateTasks", () => {
|
||||
it("should call the api service with the correct parameters", async () => {
|
||||
const organizationId = "orgId" as OrganizationId;
|
||||
const tasks: CreateTasksRequest[] = [
|
||||
{
|
||||
cipherId: "cipherId-1" as CipherId,
|
||||
type: SecurityTaskType.UpdateAtRiskCredential,
|
||||
},
|
||||
{
|
||||
cipherId: "cipherId-2" as CipherId,
|
||||
type: SecurityTaskType.UpdateAtRiskCredential,
|
||||
},
|
||||
];
|
||||
|
||||
await defaultAdminTaskService.bulkCreateTasks(organizationId, tasks);
|
||||
|
||||
expect(apiService.send).toHaveBeenCalledWith(
|
||||
"POST",
|
||||
`/tasks/${organizationId}/bulk-create`,
|
||||
tasks,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import {
|
||||
SecurityTask,
|
||||
SecurityTaskData,
|
||||
SecurityTaskResponse,
|
||||
SecurityTaskStatus,
|
||||
} from "@bitwarden/vault";
|
||||
|
||||
import { AdminTaskService, CreateTasksRequest } from "./abstractions/admin-task.abstraction";
|
||||
|
||||
@Injectable()
|
||||
export class DefaultAdminTaskService implements AdminTaskService {
|
||||
constructor(private apiService: ApiService) {}
|
||||
|
||||
async getAllTasks(
|
||||
organizationId: OrganizationId,
|
||||
status?: SecurityTaskStatus | undefined,
|
||||
): Promise<SecurityTask[]> {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
queryParams.append("organizationId", organizationId);
|
||||
if (status !== undefined) {
|
||||
queryParams.append("status", status.toString());
|
||||
}
|
||||
|
||||
const r = await this.apiService.send(
|
||||
"GET",
|
||||
`/tasks/organization?${queryParams.toString()}`,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
const response = new ListResponse(r, SecurityTaskResponse);
|
||||
|
||||
return response.data.map((d) => new SecurityTask(new SecurityTaskData(d)));
|
||||
}
|
||||
|
||||
async bulkCreateTasks(
|
||||
organizationId: OrganizationId,
|
||||
tasks: CreateTasksRequest[],
|
||||
): Promise<void> {
|
||||
await this.apiService.send("POST", `/tasks/${organizationId}/bulk-create`, tasks, true, true);
|
||||
}
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
export * from "./security-task";
|
||||
export * from "./security-task.data";
|
||||
export * from "./security-task.response";
|
||||
|
||||
Reference in New Issue
Block a user