mirror of
https://github.com/bitwarden/browser
synced 2025-12-26 05:03:33 +00:00
* Added billing account profile state service
* Update usages after removing state service functions
* Added migrator
* Updated bw.ts and main.background.ts
* Removed comment
* Updated state service dependencies to include billing service
* Added missing mv3 factory and updated MainContextMenuHandler
* updated autofill service and tests
* Updated the remaining extensions usages
* Updated desktop
* Removed subjects where they weren't needed
* Refactored billing service to have a single setter to avoid unecessary emissions
* Refactored has premium guard to return an observable
* Renamed services to match ADR
f633f2cdd8/docs/architecture/clients/presentation/angular.md (abstract--default-implementations)
* Updated property names to be a smidgen more descriptive and added jsdocs
* Updated setting of canAccessPremium to automatically update when the underlying observable emits
* Fixed build error after merge conflicts
* Another build error from conflict
* Removed autofill unit test changes from conflict
* Updated login strategy to not set premium field using state service
* Updated CLI to use billing state provider
* Shortened names a bit
* Fixed build
279 lines
10 KiB
HTML
279 lines
10 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"
|
|
>
|
|
{{ "learnMore" | 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)"
|
|
>
|
|
<i aria-hidden="true" class="bwi bwi-plus bwi-fw"></i>
|
|
{{ "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"
|
|
size="small"
|
|
></bit-avatar>
|
|
<span>
|
|
<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"
|
|
>{{ "accepted" | 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"
|
|
appA11yTitle="{{ 'options' | i18n }}"
|
|
bitIconButton="bwi-ellipsis-v"
|
|
buttonType="main"
|
|
></button>
|
|
<bit-menu #trustedContactOptions>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="c.status === emergencyAccessStatusType.Invited"
|
|
(click)="reinvite(c)"
|
|
>
|
|
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
|
{{ "resendInvitation" | i18n }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="c.status === emergencyAccessStatusType.Accepted"
|
|
(click)="confirm(c)"
|
|
>
|
|
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
|
{{ "confirm" | i18n }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="c.status === emergencyAccessStatusType.RecoveryInitiated"
|
|
(click)="approve(c)"
|
|
>
|
|
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
|
{{ "approve" | i18n }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="
|
|
c.status === emergencyAccessStatusType.RecoveryInitiated ||
|
|
c.status === emergencyAccessStatusType.RecoveryApproved
|
|
"
|
|
(click)="reject(c)"
|
|
>
|
|
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
|
{{ "reject" | i18n }}
|
|
</button>
|
|
<button type="button" bitMenuItem (click)="remove(c)">
|
|
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
|
{{ "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">
|
|
<i
|
|
class="bwi bwi-spinner bwi-spin text-muted"
|
|
title="{{ 'loading' | i18n }}"
|
|
aria-hidden="true"
|
|
></i>
|
|
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
|
</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"
|
|
size="small"
|
|
></bit-avatar>
|
|
<span>
|
|
<span>{{ c.email }}</span>
|
|
<span bitBadge *ngIf="c.status === emergencyAccessStatusType.Invited">{{
|
|
"invited" | i18n
|
|
}}</span>
|
|
<span
|
|
bitBadge
|
|
variant="warning"
|
|
*ngIf="c.status === emergencyAccessStatusType.Accepted"
|
|
>{{ "accepted" | 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"
|
|
appA11yTitle="{{ 'options' | i18n }}"
|
|
bitIconButton="bwi-ellipsis-v"
|
|
buttonType="main"
|
|
></button>
|
|
<bit-menu #grantedContactOptions>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="c.status === emergencyAccessStatusType.Confirmed"
|
|
(click)="requestAccess(c)"
|
|
>
|
|
<i class="bwi bwi-fw bwi-envelope" aria-hidden="true"></i>
|
|
{{ "requestAccess" | i18n }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="
|
|
c.status === emergencyAccessStatusType.RecoveryApproved &&
|
|
c.type === emergencyAccessType.Takeover
|
|
"
|
|
(click)="takeover(c)"
|
|
>
|
|
<i class="bwi bwi-fw bwi-key" aria-hidden="true"></i>
|
|
{{ "takeover" | i18n }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
bitMenuItem
|
|
*ngIf="
|
|
c.status === emergencyAccessStatusType.RecoveryApproved &&
|
|
c.type === emergencyAccessType.View
|
|
"
|
|
[routerLink]="c.id"
|
|
>
|
|
<i class="bwi bwi-fw bwi-eye" aria-hidden="true"></i>
|
|
{{ "view" | i18n }}
|
|
</button>
|
|
<button type="button" bitMenuItem (click)="remove(c)">
|
|
<i class="bwi bwi-fw bwi-close" aria-hidden="true"></i>
|
|
{{ "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">
|
|
<i
|
|
class="bwi bwi-spinner bwi-spin text-muted"
|
|
title="{{ 'loading' | i18n }}"
|
|
aria-hidden="true"
|
|
></i>
|
|
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
|
|
</ng-container>
|
|
</ng-container>
|
|
</bit-section>
|
|
</bit-container>
|
|
|
|
<ng-template #addEdit></ng-template>
|
|
<ng-template #takeoverTemplate></ng-template>
|
|
<ng-template #confirmTemplate></ng-template>
|