diff --git a/bitwarden_license/bit-cli/src/admin-console/device-approval/device-approval.program.ts b/bitwarden_license/bit-cli/src/admin-console/device-approval/device-approval.program.ts index bf337be93d..290bbb6fa8 100644 --- a/bitwarden_license/bit-cli/src/admin-console/device-approval/device-approval.program.ts +++ b/bitwarden_license/bit-cli/src/admin-console/device-approval/device-approval.program.ts @@ -38,7 +38,10 @@ export class DeviceApprovalProgram extends BaseProgram { await this.exitIfFeatureFlagDisabled(FeatureFlag.BulkDeviceApproval); await this.exitIfLocked(); - const cmd = new ListCommand(); + const cmd = new ListCommand( + this.serviceContainer.organizationAuthRequestService, + this.serviceContainer.organizationService, + ); const response = await cmd.run(organizationId); this.processResponse(response); }); diff --git a/bitwarden_license/bit-cli/src/admin-console/device-approval/list.command.ts b/bitwarden_license/bit-cli/src/admin-console/device-approval/list.command.ts index 11fb6ec3ee..10da11b35c 100644 --- a/bitwarden_license/bit-cli/src/admin-console/device-approval/list.command.ts +++ b/bitwarden_license/bit-cli/src/admin-console/device-approval/list.command.ts @@ -1,9 +1,42 @@ +import { firstValueFrom } from "rxjs"; + +import { OrganizationAuthRequestService } from "@bitwarden/bit-common/admin-console/auth-requests"; import { Response } from "@bitwarden/cli/models/response"; +import { ListResponse } from "@bitwarden/cli/models/response/list.response"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; + +import { PendingAuthRequestResponse } from "./pending-auth-request.response"; export class ListCommand { - constructor() {} + constructor( + private organizationAuthRequestService: OrganizationAuthRequestService, + private organizationService: OrganizationService, + ) {} async run(organizationId: string): Promise { - throw new Error("Not implemented"); + if (organizationId != null) { + organizationId = organizationId.toLowerCase(); + } + + if (!Utils.isGuid(organizationId)) { + return Response.badRequest("`" + organizationId + "` is not a GUID."); + } + + const organization = await firstValueFrom(this.organizationService.get$(organizationId)); + if (!organization?.canManageUsersPassword) { + return Response.error( + "You do not have permission to approve pending device authorization requests.", + ); + } + + try { + const requests = + await this.organizationAuthRequestService.listPendingRequests(organizationId); + const res = new ListResponse(requests.map((r) => new PendingAuthRequestResponse(r))); + return Response.success(res); + } catch (e) { + return Response.error(e); + } } } diff --git a/bitwarden_license/bit-cli/src/admin-console/device-approval/pending-auth-request.response.ts b/bitwarden_license/bit-cli/src/admin-console/device-approval/pending-auth-request.response.ts new file mode 100644 index 0000000000..991b3fb8e5 --- /dev/null +++ b/bitwarden_license/bit-cli/src/admin-console/device-approval/pending-auth-request.response.ts @@ -0,0 +1,26 @@ +import { PendingAuthRequestView } from "@bitwarden/bit-common/admin-console/auth-requests/"; +import { BaseResponse } from "@bitwarden/cli/models/response/base.response"; + +export class PendingAuthRequestResponse implements BaseResponse { + object = "auth-request"; + + id: string; + userId: string; + organizationUserId: string; + email: string; + requestDeviceIdentifier: string; + requestDeviceType: string; + requestIpAddress: string; + creationDate: Date; + + constructor(authRequest: PendingAuthRequestView) { + this.id = authRequest.id; + this.userId = authRequest.userId; + this.organizationUserId = authRequest.organizationUserId; + this.email = authRequest.email; + this.requestDeviceIdentifier = authRequest.requestDeviceIdentifier; + this.requestDeviceType = authRequest.requestDeviceType; + this.requestIpAddress = authRequest.requestIpAddress; + this.creationDate = authRequest.creationDate; + } +}