Skip to content

Commit

Permalink
[PM-3797 Part 1] Add Emergency Access Service (#6612)
Browse files Browse the repository at this point in the history
* lazy load and move accept emergency component

* create emergency access services
- move api calls to specific api service and refactor

* remove any from emergency api service

* move emergency access logic to service

* create emergency access view

* move view ciphers logic to service

* move models to web folder

* move takeover logic to service

* remove emergency api service dependency from other files

* write tests for emergency access service

* import shared module into component

* fix imports

* Revert "fix imports"

This reverts commit d21cb02.

* create emergency access module for service

* move emergency access out of core folder
- add more organization to components under settings

* change EA views to domain models

* move EA enums to folder

* resolve PR feedback
  • Loading branch information
jlf0dev authored Nov 8, 2023
1 parent cf6ada5 commit 929a083
Show file tree
Hide file tree
Showing 36 changed files with 889 additions and 435 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { Component } from "@angular/core";
import { ActivatedRoute, Params, Router } from "@angular/router";

import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { EmergencyAccessAcceptRequest } from "@bitwarden/common/auth/models/request/emergency-access-accept.request";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";

import { BaseAcceptComponent } from "../common/base.accept.component";
import { BaseAcceptComponent } from "../../../common/base.accept.component";
import { SharedModule } from "../../../shared";
import { EmergencyAccessModule } from "../emergency-access.module";
import { EmergencyAccessService } from "../services/emergency-access.service";

@Component({
selector: "app-accept-emergency",
standalone: true,
imports: [SharedModule, EmergencyAccessModule],
templateUrl: "accept-emergency.component.html",
})
export class AcceptEmergencyComponent extends BaseAcceptComponent {
Expand All @@ -25,16 +27,14 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent {
platformUtilsService: PlatformUtilsService,
i18nService: I18nService,
route: ActivatedRoute,
private apiService: ApiService,
stateService: StateService
stateService: StateService,
private emergencyAccessService: EmergencyAccessService
) {
super(router, platformUtilsService, i18nService, route, stateService);
}

async authedHandler(qParams: Params): Promise<void> {
const request = new EmergencyAccessAcceptRequest();
request.token = qParams.token;
this.actionPromise = this.apiService.postEmergencyAccessAccept(qParams.id, request);
this.actionPromise = this.emergencyAccessService.accept(qParams.id, qParams.token);
await this.actionPromise;
await this.stateService.setEmergencyAccessInvitation(null);
this.platformUtilService.showToast(
Expand Down
11 changes: 11 additions & 0 deletions apps/web/src/app/auth/emergency-access/emergency-access.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NgModule } from "@angular/core";

import { EmergencyAccessApiService } from "./services/emergency-access-api.service";
import { EmergencyAccessService } from "./services/emergency-access.service";

@NgModule({
declarations: [],
imports: [],
providers: [EmergencyAccessApiService, EmergencyAccessService],
})
export class EmergencyAccessModule {}
2 changes: 2 additions & 0 deletions apps/web/src/app/auth/emergency-access/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./emergency-access.module";
export * from "./services";
42 changes: 42 additions & 0 deletions apps/web/src/app/auth/emergency-access/models/emergency-access.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { KdfType } from "@bitwarden/common/enums";
import { CipherResponse } from "@bitwarden/common/vault/models/response/cipher.response";

import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type";
import { EmergencyAccessType } from "../enums/emergency-access-type";

export class GranteeEmergencyAccess {
id: string;
granteeId: string;
name: string;
email: string;
type: EmergencyAccessType;
status: EmergencyAccessStatusType;
waitTimeDays: number;
creationDate: string;
avatarColor: string;
}

export class GrantorEmergencyAccess {
id: string;
grantorId: string;
name: string;
email: string;
type: EmergencyAccessType;
status: EmergencyAccessStatusType;
waitTimeDays: number;
creationDate: string;
avatarColor: string;
}

export class TakeoverTypeEmergencyAccess {
keyEncrypted: string;
kdf: KdfType;
kdfIterations: number;
kdfMemory?: number;
kdfParallelism?: number;
}

export class ViewTypeEmergencyAccess {
keyEncrypted: string;
ciphers: CipherResponse[] = [];
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmergencyAccessType } from "../../enums/emergency-access-type";
import { EmergencyAccessType } from "../enums/emergency-access-type";

export class EmergencyAccessInviteRequest {
email: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmergencyAccessType } from "../../enums/emergency-access-type";
import { EmergencyAccessType } from "../enums/emergency-access-type";

export class EmergencyAccessUpdateRequest {
type: EmergencyAccessType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { KdfType } from "../../../enums";
import { BaseResponse } from "../../../models/response/base.response";
import { CipherResponse } from "../../../vault/models/response/cipher.response";
import { EmergencyAccessStatusType } from "../../enums/emergency-access-status-type";
import { EmergencyAccessType } from "../../enums/emergency-access-type";
import { KdfType } from "@bitwarden/common/enums";
import { BaseResponse } from "@bitwarden/common/models/response/base.response";
import { CipherResponse } from "@bitwarden/common/vault/models/response/cipher.response";

import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type";
import { EmergencyAccessType } from "../enums/emergency-access-type";

export class EmergencyAccessGranteeDetailsResponse extends BaseResponse {
id: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { Injectable } from "@angular/core";

import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
import { ListResponse } from "@bitwarden/common/models/response/list.response";

import { EmergencyAccessAcceptRequest } from "../request/emergency-access-accept.request";
import { EmergencyAccessConfirmRequest } from "../request/emergency-access-confirm.request";
import { EmergencyAccessInviteRequest } from "../request/emergency-access-invite.request";
import { EmergencyAccessPasswordRequest } from "../request/emergency-access-password.request";
import { EmergencyAccessUpdateRequest } from "../request/emergency-access-update.request";
import {
EmergencyAccessGranteeDetailsResponse,
EmergencyAccessGrantorDetailsResponse,
EmergencyAccessTakeoverResponse,
EmergencyAccessViewResponse,
} from "../response/emergency-access.response";

@Injectable()
export class EmergencyAccessApiService {
constructor(private apiService: ApiService) {}

async getEmergencyAccessTrusted(): Promise<ListResponse<EmergencyAccessGranteeDetailsResponse>> {
const r = await this.apiService.send("GET", "/emergency-access/trusted", null, true, true);
return new ListResponse(r, EmergencyAccessGranteeDetailsResponse);
}

async getEmergencyAccessGranted(): Promise<ListResponse<EmergencyAccessGrantorDetailsResponse>> {
const r = await this.apiService.send("GET", "/emergency-access/granted", null, true, true);
return new ListResponse(r, EmergencyAccessGrantorDetailsResponse);
}

async getEmergencyAccess(id: string): Promise<EmergencyAccessGranteeDetailsResponse> {
const r = await this.apiService.send("GET", "/emergency-access/" + id, null, true, true);
return new EmergencyAccessGranteeDetailsResponse(r);
}

async getEmergencyGrantorPolicies(id: string): Promise<ListResponse<PolicyResponse>> {
const r = await this.apiService.send(
"GET",
"/emergency-access/" + id + "/policies",
null,
true,
true
);
return new ListResponse(r, PolicyResponse);
}

putEmergencyAccess(id: string, request: EmergencyAccessUpdateRequest): Promise<void> {
return this.apiService.send("PUT", "/emergency-access/" + id, request, true, false);
}

deleteEmergencyAccess(id: string): Promise<void> {
return this.apiService.send("DELETE", "/emergency-access/" + id, null, true, false);
}

postEmergencyAccessInvite(request: EmergencyAccessInviteRequest): Promise<void> {
return this.apiService.send("POST", "/emergency-access/invite", request, true, false);
}

postEmergencyAccessReinvite(id: string): Promise<void> {
return this.apiService.send("POST", "/emergency-access/" + id + "/reinvite", null, true, false);
}

postEmergencyAccessAccept(id: string, request: EmergencyAccessAcceptRequest): Promise<void> {
return this.apiService.send(
"POST",
"/emergency-access/" + id + "/accept",
request,
true,
false
);
}

postEmergencyAccessConfirm(id: string, request: EmergencyAccessConfirmRequest): Promise<void> {
return this.apiService.send(
"POST",
"/emergency-access/" + id + "/confirm",
request,
true,
false
);
}

postEmergencyAccessInitiate(id: string): Promise<void> {
return this.apiService.send("POST", "/emergency-access/" + id + "/initiate", null, true, false);
}

postEmergencyAccessApprove(id: string): Promise<void> {
return this.apiService.send("POST", "/emergency-access/" + id + "/approve", null, true, false);
}

postEmergencyAccessReject(id: string): Promise<void> {
return this.apiService.send("POST", "/emergency-access/" + id + "/reject", null, true, false);
}

async postEmergencyAccessTakeover(id: string): Promise<EmergencyAccessTakeoverResponse> {
const r = await this.apiService.send(
"POST",
"/emergency-access/" + id + "/takeover",
null,
true,
true
);
return new EmergencyAccessTakeoverResponse(r);
}

async postEmergencyAccessPassword(
id: string,
request: EmergencyAccessPasswordRequest
): Promise<void> {
await this.apiService.send(
"POST",
"/emergency-access/" + id + "/password",
request,
true,
true
);
}

async postEmergencyAccessView(id: string): Promise<EmergencyAccessViewResponse> {
const r = await this.apiService.send(
"POST",
"/emergency-access/" + id + "/view",
null,
true,
true
);
return new EmergencyAccessViewResponse(r);
}
}
Loading

0 comments on commit 929a083

Please sign in to comment.