mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
[PM-3797 Part 1] Add Emergency Access Service (#6612)
* 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 d21cb02bd8.
* 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
This commit is contained in:
@@ -19,7 +19,6 @@ import {
|
||||
} from "../admin-console/models/response/organization-connection.response";
|
||||
import { OrganizationExportResponse } from "../admin-console/models/response/organization-export.response";
|
||||
import { OrganizationSponsorshipSyncStatusResponse } from "../admin-console/models/response/organization-sponsorship-sync-status.response";
|
||||
import { PolicyResponse } from "../admin-console/models/response/policy.response";
|
||||
import {
|
||||
ProviderOrganizationOrganizationDetailsResponse,
|
||||
ProviderOrganizationResponse,
|
||||
@@ -36,11 +35,6 @@ import { CreateAuthRequest } from "../auth/models/request/create-auth.request";
|
||||
import { DeviceVerificationRequest } from "../auth/models/request/device-verification.request";
|
||||
import { EmailTokenRequest } from "../auth/models/request/email-token.request";
|
||||
import { EmailRequest } from "../auth/models/request/email.request";
|
||||
import { EmergencyAccessAcceptRequest } from "../auth/models/request/emergency-access-accept.request";
|
||||
import { EmergencyAccessConfirmRequest } from "../auth/models/request/emergency-access-confirm.request";
|
||||
import { EmergencyAccessInviteRequest } from "../auth/models/request/emergency-access-invite.request";
|
||||
import { EmergencyAccessPasswordRequest } from "../auth/models/request/emergency-access-password.request";
|
||||
import { EmergencyAccessUpdateRequest } from "../auth/models/request/emergency-access-update.request";
|
||||
import { PasswordTokenRequest } from "../auth/models/request/identity-token/password-token.request";
|
||||
import { SsoTokenRequest } from "../auth/models/request/identity-token/sso-token.request";
|
||||
import { UserApiTokenRequest } from "../auth/models/request/identity-token/user-api-token.request";
|
||||
@@ -65,12 +59,6 @@ import { UpdateTwoFactorYubioOtpRequest } from "../auth/models/request/update-tw
|
||||
import { ApiKeyResponse } from "../auth/models/response/api-key.response";
|
||||
import { AuthRequestResponse } from "../auth/models/response/auth-request.response";
|
||||
import { DeviceVerificationResponse } from "../auth/models/response/device-verification.response";
|
||||
import {
|
||||
EmergencyAccessGranteeDetailsResponse,
|
||||
EmergencyAccessGrantorDetailsResponse,
|
||||
EmergencyAccessTakeoverResponse,
|
||||
EmergencyAccessViewResponse,
|
||||
} from "../auth/models/response/emergency-access.response";
|
||||
import { IdentityCaptchaResponse } from "../auth/models/response/identity-captcha.response";
|
||||
import { IdentityTokenResponse } from "../auth/models/response/identity-token.response";
|
||||
import { IdentityTwoFactorResponse } from "../auth/models/response/identity-two-factor.response";
|
||||
@@ -365,25 +353,6 @@ export abstract class ApiService {
|
||||
request: DeviceVerificationRequest
|
||||
) => Promise<DeviceVerificationResponse>;
|
||||
|
||||
getEmergencyAccessTrusted: () => Promise<ListResponse<EmergencyAccessGranteeDetailsResponse>>;
|
||||
getEmergencyAccessGranted: () => Promise<ListResponse<EmergencyAccessGrantorDetailsResponse>>;
|
||||
getEmergencyAccess: (id: string) => Promise<EmergencyAccessGranteeDetailsResponse>;
|
||||
getEmergencyGrantorPolicies: (id: string) => Promise<ListResponse<PolicyResponse>>;
|
||||
putEmergencyAccess: (id: string, request: EmergencyAccessUpdateRequest) => Promise<any>;
|
||||
deleteEmergencyAccess: (id: string) => Promise<any>;
|
||||
postEmergencyAccessInvite: (request: EmergencyAccessInviteRequest) => Promise<any>;
|
||||
postEmergencyAccessReinvite: (id: string) => Promise<any>;
|
||||
postEmergencyAccessAccept: (id: string, request: EmergencyAccessAcceptRequest) => Promise<any>;
|
||||
postEmergencyAccessConfirm: (id: string, request: EmergencyAccessConfirmRequest) => Promise<any>;
|
||||
postEmergencyAccessInitiate: (id: string) => Promise<any>;
|
||||
postEmergencyAccessApprove: (id: string) => Promise<any>;
|
||||
postEmergencyAccessReject: (id: string) => Promise<any>;
|
||||
postEmergencyAccessTakeover: (id: string) => Promise<EmergencyAccessTakeoverResponse>;
|
||||
postEmergencyAccessPassword: (
|
||||
id: string,
|
||||
request: EmergencyAccessPasswordRequest
|
||||
) => Promise<any>;
|
||||
postEmergencyAccessView: (id: string) => Promise<EmergencyAccessViewResponse>;
|
||||
getCloudCommunicationsEnabled: () => Promise<boolean>;
|
||||
abstract getOrganizationConnection<TConfig extends OrganizationConnectionConfigApis>(
|
||||
id: string,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
export enum EmergencyAccessStatusType {
|
||||
Invited = 0,
|
||||
Accepted = 1,
|
||||
Confirmed = 2,
|
||||
RecoveryInitiated = 3,
|
||||
RecoveryApproved = 4,
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export enum EmergencyAccessType {
|
||||
View = 0,
|
||||
Takeover = 1,
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export class EmergencyAccessAcceptRequest {
|
||||
token: string;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export class EmergencyAccessConfirmRequest {
|
||||
key: string;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { EmergencyAccessType } from "../../enums/emergency-access-type";
|
||||
|
||||
export class EmergencyAccessInviteRequest {
|
||||
email: string;
|
||||
type: EmergencyAccessType;
|
||||
waitTimeDays: number;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export class EmergencyAccessPasswordRequest {
|
||||
newMasterPasswordHash: string;
|
||||
key: string;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { EmergencyAccessType } from "../../enums/emergency-access-type";
|
||||
|
||||
export class EmergencyAccessUpdateRequest {
|
||||
type: EmergencyAccessType;
|
||||
waitTimeDays: number;
|
||||
keyEncrypted?: string;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
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";
|
||||
|
||||
export class EmergencyAccessGranteeDetailsResponse extends BaseResponse {
|
||||
id: string;
|
||||
granteeId: string;
|
||||
name: string;
|
||||
email: string;
|
||||
type: EmergencyAccessType;
|
||||
status: EmergencyAccessStatusType;
|
||||
waitTimeDays: number;
|
||||
creationDate: string;
|
||||
avatarColor: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.granteeId = this.getResponseProperty("GranteeId");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.email = this.getResponseProperty("Email");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.waitTimeDays = this.getResponseProperty("WaitTimeDays");
|
||||
this.creationDate = this.getResponseProperty("CreationDate");
|
||||
this.avatarColor = this.getResponseProperty("AvatarColor");
|
||||
}
|
||||
}
|
||||
|
||||
export class EmergencyAccessGrantorDetailsResponse extends BaseResponse {
|
||||
id: string;
|
||||
grantorId: string;
|
||||
name: string;
|
||||
email: string;
|
||||
type: EmergencyAccessType;
|
||||
status: EmergencyAccessStatusType;
|
||||
waitTimeDays: number;
|
||||
creationDate: string;
|
||||
avatarColor: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.grantorId = this.getResponseProperty("GrantorId");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.email = this.getResponseProperty("Email");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.waitTimeDays = this.getResponseProperty("WaitTimeDays");
|
||||
this.creationDate = this.getResponseProperty("CreationDate");
|
||||
this.avatarColor = this.getResponseProperty("AvatarColor");
|
||||
}
|
||||
}
|
||||
|
||||
export class EmergencyAccessTakeoverResponse extends BaseResponse {
|
||||
keyEncrypted: string;
|
||||
kdf: KdfType;
|
||||
kdfIterations: number;
|
||||
kdfMemory?: number;
|
||||
kdfParallelism?: number;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
|
||||
this.keyEncrypted = this.getResponseProperty("KeyEncrypted");
|
||||
this.kdf = this.getResponseProperty("Kdf");
|
||||
this.kdfIterations = this.getResponseProperty("KdfIterations");
|
||||
this.kdfMemory = this.getResponseProperty("KdfMemory");
|
||||
this.kdfParallelism = this.getResponseProperty("KdfParallelism");
|
||||
}
|
||||
}
|
||||
|
||||
export class EmergencyAccessViewResponse extends BaseResponse {
|
||||
keyEncrypted: string;
|
||||
ciphers: CipherResponse[] = [];
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
|
||||
this.keyEncrypted = this.getResponseProperty("KeyEncrypted");
|
||||
|
||||
const ciphers = this.getResponseProperty("Ciphers");
|
||||
if (ciphers != null) {
|
||||
this.ciphers = ciphers.map((c: any) => new CipherResponse(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
} from "../admin-console/models/response/organization-connection.response";
|
||||
import { OrganizationExportResponse } from "../admin-console/models/response/organization-export.response";
|
||||
import { OrganizationSponsorshipSyncStatusResponse } from "../admin-console/models/response/organization-sponsorship-sync-status.response";
|
||||
import { PolicyResponse } from "../admin-console/models/response/policy.response";
|
||||
import {
|
||||
ProviderOrganizationOrganizationDetailsResponse,
|
||||
ProviderOrganizationResponse,
|
||||
@@ -38,11 +37,6 @@ import { CreateAuthRequest } from "../auth/models/request/create-auth.request";
|
||||
import { DeviceVerificationRequest } from "../auth/models/request/device-verification.request";
|
||||
import { EmailTokenRequest } from "../auth/models/request/email-token.request";
|
||||
import { EmailRequest } from "../auth/models/request/email.request";
|
||||
import { EmergencyAccessAcceptRequest } from "../auth/models/request/emergency-access-accept.request";
|
||||
import { EmergencyAccessConfirmRequest } from "../auth/models/request/emergency-access-confirm.request";
|
||||
import { EmergencyAccessInviteRequest } from "../auth/models/request/emergency-access-invite.request";
|
||||
import { EmergencyAccessPasswordRequest } from "../auth/models/request/emergency-access-password.request";
|
||||
import { EmergencyAccessUpdateRequest } from "../auth/models/request/emergency-access-update.request";
|
||||
import { DeviceRequest } from "../auth/models/request/identity-token/device.request";
|
||||
import { PasswordTokenRequest } from "../auth/models/request/identity-token/password-token.request";
|
||||
import { SsoTokenRequest } from "../auth/models/request/identity-token/sso-token.request";
|
||||
@@ -69,12 +63,6 @@ import { UpdateTwoFactorYubioOtpRequest } from "../auth/models/request/update-tw
|
||||
import { ApiKeyResponse } from "../auth/models/response/api-key.response";
|
||||
import { AuthRequestResponse } from "../auth/models/response/auth-request.response";
|
||||
import { DeviceVerificationResponse } from "../auth/models/response/device-verification.response";
|
||||
import {
|
||||
EmergencyAccessGranteeDetailsResponse,
|
||||
EmergencyAccessGrantorDetailsResponse,
|
||||
EmergencyAccessTakeoverResponse,
|
||||
EmergencyAccessViewResponse,
|
||||
} from "../auth/models/response/emergency-access.response";
|
||||
import { IdentityCaptchaResponse } from "../auth/models/response/identity-captcha.response";
|
||||
import { IdentityTokenResponse } from "../auth/models/response/identity-token.response";
|
||||
import { IdentityTwoFactorResponse } from "../auth/models/response/identity-two-factor.response";
|
||||
@@ -1123,81 +1111,6 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
return new DeviceVerificationResponse(r);
|
||||
}
|
||||
|
||||
// Emergency Access APIs
|
||||
|
||||
async getEmergencyAccessTrusted(): Promise<ListResponse<EmergencyAccessGranteeDetailsResponse>> {
|
||||
const r = await this.send("GET", "/emergency-access/trusted", null, true, true);
|
||||
return new ListResponse(r, EmergencyAccessGranteeDetailsResponse);
|
||||
}
|
||||
|
||||
async getEmergencyAccessGranted(): Promise<ListResponse<EmergencyAccessGrantorDetailsResponse>> {
|
||||
const r = await this.send("GET", "/emergency-access/granted", null, true, true);
|
||||
return new ListResponse(r, EmergencyAccessGrantorDetailsResponse);
|
||||
}
|
||||
|
||||
async getEmergencyAccess(id: string): Promise<EmergencyAccessGranteeDetailsResponse> {
|
||||
const r = await this.send("GET", "/emergency-access/" + id, null, true, true);
|
||||
return new EmergencyAccessGranteeDetailsResponse(r);
|
||||
}
|
||||
|
||||
async getEmergencyGrantorPolicies(id: string): Promise<ListResponse<PolicyResponse>> {
|
||||
const r = await this.send("GET", "/emergency-access/" + id + "/policies", null, true, true);
|
||||
return new ListResponse(r, PolicyResponse);
|
||||
}
|
||||
|
||||
putEmergencyAccess(id: string, request: EmergencyAccessUpdateRequest): Promise<any> {
|
||||
return this.send("PUT", "/emergency-access/" + id, request, true, false);
|
||||
}
|
||||
|
||||
deleteEmergencyAccess(id: string): Promise<any> {
|
||||
return this.send("DELETE", "/emergency-access/" + id, null, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessInvite(request: EmergencyAccessInviteRequest): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/invite", request, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessReinvite(id: string): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/" + id + "/reinvite", null, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessAccept(id: string, request: EmergencyAccessAcceptRequest): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/" + id + "/accept", request, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessConfirm(id: string, request: EmergencyAccessConfirmRequest): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/" + id + "/confirm", request, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessInitiate(id: string): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/" + id + "/initiate", null, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessApprove(id: string): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/" + id + "/approve", null, true, false);
|
||||
}
|
||||
|
||||
postEmergencyAccessReject(id: string): Promise<any> {
|
||||
return this.send("POST", "/emergency-access/" + id + "/reject", null, true, false);
|
||||
}
|
||||
|
||||
async postEmergencyAccessTakeover(id: string): Promise<EmergencyAccessTakeoverResponse> {
|
||||
const r = await this.send("POST", "/emergency-access/" + id + "/takeover", null, true, true);
|
||||
return new EmergencyAccessTakeoverResponse(r);
|
||||
}
|
||||
|
||||
async postEmergencyAccessPassword(
|
||||
id: string,
|
||||
request: EmergencyAccessPasswordRequest
|
||||
): Promise<any> {
|
||||
await this.send("POST", "/emergency-access/" + id + "/password", request, true, true);
|
||||
}
|
||||
|
||||
async postEmergencyAccessView(id: string): Promise<EmergencyAccessViewResponse> {
|
||||
const r = await this.send("POST", "/emergency-access/" + id + "/view", null, true, true);
|
||||
return new EmergencyAccessViewResponse(r);
|
||||
}
|
||||
|
||||
// Organization APIs
|
||||
|
||||
async getCloudCommunicationsEnabled(): Promise<boolean> {
|
||||
|
||||
Reference in New Issue
Block a user