1
0
mirror of https://github.com/bitwarden/browser synced 2026-03-01 02:51:24 +00:00
Files
browser/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.html
2026-02-27 10:56:25 -05:00

271 lines
9.8 KiB
HTML

<app-header></app-header>
<bit-container>
<bit-section>
<p bitTypography="body1">
<span class="tw-text-main">{{ "emergencyAccessDesc" | i18n }}</span>
<a
bitLink
href="https://bitwarden.com/help/emergency-access/"
target="_blank"
rel="noreferrer"
>
{{ "learnMoreAboutEmergencyAccess" | i18n }}
</a>
</p>
<bit-callout *ngIf="isOrganizationOwner" type="warning" title="{{ 'warning' | i18n }}">{{
"emergencyAccessOwnerWarning" | i18n
}}</bit-callout>
</bit-section>
<bit-section>
<div class="tw-flex tw-items-center tw-gap-2 tw-mb-2">
<h2 bitTypography="h2" noMargin class="tw-mb-0">
{{ "trustedEmergencyContacts" | i18n }}
</h2>
<app-premium-badge></app-premium-badge>
<div class="tw-ml-auto tw-flex">
<button
type="button"
bitButton
buttonType="primary"
[bitAction]="invite"
[disabled]="!(canAccessPremium$ | async)"
>
<bit-icon name="bwi-plus" class="bwi-fw"></bit-icon>
{{ "addEmergencyContact" | i18n }}
</button>
</div>
</div>
<bit-table *ngIf="trustedContacts && trustedContacts.length">
<ng-container header>
<tr>
<th bitCell>{{ "name" | i18n }}</th>
<th bitCell>{{ "accessLevel" | i18n }}</th>
<th bitCell class="tw-text-right">{{ "options" | i18n }}</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow *ngFor="let c of trustedContacts; let i = index">
<td bitCell class="tw-flex tw-items-center tw-gap-4">
<bit-avatar
[text]="c | userName"
[id]="c.granteeId"
[color]="c.avatarColor"
></bit-avatar>
<span class="tw-inline-flex tw-gap-2">
<a bitLink href="#" appStopClick (click)="edit(c)">{{ c.email }}</a>
<span
bitBadge
variant="secondary"
*ngIf="c.status === emergencyAccessStatusType.Invited"
>{{ "invited" | i18n }}</span
>
<span
bitBadge
variant="warning"
*ngIf="c.status === emergencyAccessStatusType.Accepted"
>{{ "needsConfirmation" | i18n }}</span
>
<span
bitBadge
variant="warning"
*ngIf="c.status === emergencyAccessStatusType.RecoveryInitiated"
>{{ "emergencyAccessRecoveryInitiated" | i18n }}</span
>
<span bitBadge *ngIf="c.status === emergencyAccessStatusType.RecoveryApproved">{{
"emergencyAccessRecoveryApproved" | i18n
}}</span>
<small class="tw-text-muted tw-block" *ngIf="c.name">{{ c.name }}</small>
</span>
</td>
<td bitCell>
<span bitBadge *ngIf="c.type === emergencyAccessType.View">{{ "view" | i18n }}</span>
<span bitBadge *ngIf="c.type === emergencyAccessType.Takeover">{{
"takeover" | i18n
}}</span>
</td>
<td bitCell class="tw-text-right">
<button
[bitMenuTriggerFor]="trustedContactOptions"
type="button"
label="{{ 'options' | i18n }}"
bitIconButton="bwi-ellipsis-v"
buttonType="main"
></button>
<bit-menu #trustedContactOptions>
<button
type="button"
bitMenuItem
*ngIf="c.status === emergencyAccessStatusType.Invited"
(click)="reinvite(c)"
>
<bit-icon name="bwi-envelope" class="bwi-fw"></bit-icon>
{{ "resendInvitation" | i18n }}
</button>
<button
type="button"
bitMenuItem
*ngIf="c.status === emergencyAccessStatusType.Accepted"
(click)="confirm(c)"
>
<bit-icon name="bwi-check" class="bwi-fw"></bit-icon>
{{ "confirm" | i18n }}
</button>
<button
type="button"
bitMenuItem
*ngIf="c.status === emergencyAccessStatusType.RecoveryInitiated"
(click)="approve(c)"
>
<bit-icon name="bwi-check" class="bwi-fw"></bit-icon>
{{ "approve" | i18n }}
</button>
<button
type="button"
bitMenuItem
*ngIf="
c.status === emergencyAccessStatusType.RecoveryInitiated ||
c.status === emergencyAccessStatusType.RecoveryApproved
"
(click)="reject(c)"
>
<bit-icon name="bwi-close" class="bwi-fw"></bit-icon>
{{ "reject" | i18n }}
</button>
<button type="button" bitMenuItem (click)="remove(c)">
<bit-icon name="bwi-close" class="bwi-fw"></bit-icon>
{{ "remove" | i18n }}
</button>
</bit-menu>
</td>
</tr>
</ng-template>
</bit-table>
<ng-container *ngIf="!trustedContacts || !trustedContacts.length">
<p bitTypography="body1" class="tw-mt-2" *ngIf="loaded">{{ "noTrustedContacts" | i18n }}</p>
<ng-container *ngIf="!loaded">
<bit-icon
name="bwi-spinner"
class="bwi-spin tw-text-muted"
[ariaLabel]="'loading' | i18n"
></bit-icon>
</ng-container>
</ng-container>
</bit-section>
<bit-section>
<h2 bitTypography="h2">{{ "designatedEmergencyContacts" | i18n }}</h2>
<bit-table *ngIf="grantedContacts && grantedContacts.length">
<ng-container header>
<tr>
<th bitCell>{{ "name" | i18n }}</th>
<th bitCell>{{ "accessLevel" | i18n }}</th>
<th bitCell class="tw-text-right">{{ "options" | i18n }}</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow *ngFor="let c of grantedContacts; let i = index">
<td bitCell class="tw-flex tw-items-center tw-gap-4">
<bit-avatar
[text]="c | userName"
[id]="c.grantorId"
[color]="c.avatarColor"
></bit-avatar>
<span class="tw-inline-flex tw-gap-2">
<span>{{ c.email }}</span>
<span bitBadge *ngIf="c.status === emergencyAccessStatusType.Invited">{{
"invited" | i18n
}}</span>
<span
bitBadge
variant="warning"
*ngIf="c.status === emergencyAccessStatusType.Accepted"
>{{ "needsConfirmation" | i18n }}</span
>
<span
bitBadge
variant="warning"
*ngIf="c.status === emergencyAccessStatusType.RecoveryInitiated"
>{{ "emergencyAccessRecoveryInitiated" | i18n }}</span
>
<span
bitBadge
variant="success"
*ngIf="c.status === emergencyAccessStatusType.RecoveryApproved"
>{{ "emergencyAccessRecoveryApproved" | i18n }}</span
>
<small class="tw-text-muted tw-block" *ngIf="c.name">{{ c.name }}</small>
</span>
</td>
<td bitCell>
<span bitBadge *ngIf="c.type === emergencyAccessType.View">{{ "view" | i18n }}</span>
<span bitBadge *ngIf="c.type === emergencyAccessType.Takeover">{{
"takeover" | i18n
}}</span>
</td>
<td bitCell class="tw-text-right">
<button
[bitMenuTriggerFor]="grantedContactOptions"
type="button"
label="{{ 'options' | i18n }}"
bitIconButton="bwi-ellipsis-v"
buttonType="main"
></button>
<bit-menu #grantedContactOptions>
<button
type="button"
bitMenuItem
*ngIf="c.status === emergencyAccessStatusType.Confirmed"
(click)="requestAccess(c)"
>
<bit-icon name="bwi-envelope" class="bwi-fw"></bit-icon>
{{ "requestAccess" | i18n }}
</button>
<button
type="button"
bitMenuItem
*ngIf="
c.status === emergencyAccessStatusType.RecoveryApproved &&
c.type === emergencyAccessType.Takeover
"
(click)="takeover(c)"
>
<bit-icon name="bwi-key" class="bwi-fw"></bit-icon>
{{ "takeover" | i18n }}
</button>
<button
type="button"
bitMenuItem
*ngIf="
c.status === emergencyAccessStatusType.RecoveryApproved &&
c.type === emergencyAccessType.View
"
[routerLink]="c.id"
>
<bit-icon name="bwi-eye" class="bwi-fw"></bit-icon>
{{ "view" | i18n }}
</button>
<button type="button" bitMenuItem (click)="remove(c)">
<bit-icon name="bwi-close" class="bwi-fw"></bit-icon>
{{ "remove" | i18n }}
</button>
</bit-menu>
</td>
</tr>
</ng-template>
</bit-table>
<ng-container *ngIf="!grantedContacts || !grantedContacts.length">
<p bitTypography="body1" *ngIf="loaded">{{ "noGrantedAccess" | i18n }}</p>
<ng-container *ngIf="!loaded">
<bit-icon
name="bwi-spinner"
class="bwi-spin tw-text-muted"
[ariaLabel]="'loading' | i18n"
></bit-icon>
</ng-container>
</ng-container>
</bit-section>
</bit-container>