mirror of
https://github.com/bitwarden/browser
synced 2025-12-26 13:13:22 +00:00
* Use account service to track accounts and active account * Remove state service active account Observables. * Add email verified to account service * Do not store account info on logged out accounts * Add account activity tracking to account service * Use last account activity from account service * migrate or replicate account service data * Add `AccountActivityService` that handles storing account last active data * Move active and next active user to account service * Remove authenticated accounts from state object * Fold account activity into account service * Fix builds * Fix desktop app switch * Fix logging out non active user * Expand helper to handle new authenticated accounts location * Prefer view observable to tons of async pipes * Fix `npm run test:types` * Correct user activity sorting test * Be more precise about log out messaging * Fix dev compare errors All stored values are serializable, the next step wasn't necessary and was erroring on some types that lack `toString`. * If the account in unlocked on load of lock component, navigate away from lock screen * Handle no users case for auth service statuses * Specify account to switch to * Filter active account out of inactive accounts * Prefer constructor init * Improve comparator * Use helper methods internally * Fixup component tests * Clarify name * Ensure accounts object has only valid userIds * Capitalize const values * Prefer descriptive, single-responsibility guards * Update libs/common/src/state-migrations/migrate.ts Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Fix merge * Add user Id validation activity for undefined was being set, which was resulting in requests for the auth status of `"undefined"` (string) userId, due to key enumeration. These changes stop that at both locations, as well as account add for good measure. --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
137 lines
4.9 KiB
HTML
137 lines
4.9 KiB
HTML
<bit-banner
|
|
class="-tw-m-6 tw-flex tw-flex-col tw-pb-6"
|
|
(onClose)="unassignedItemsBannerService.hideBanner()"
|
|
*ngIf="
|
|
(unassignedItemsBannerEnabled$ | async) &&
|
|
(unassignedItemsBannerService.showBanner$ | async) &&
|
|
!(unassignedItemsBannerService.loading$ | async)
|
|
"
|
|
>
|
|
{{ unassignedItemsBannerService.bannerText$ | async | i18n }}
|
|
{{ "unassignedItemsBannerCTAPartOne" | i18n }}
|
|
<a
|
|
[href]="unassignedItemsBannerService.adminConsoleUrl$ | async"
|
|
bitLink
|
|
linkType="contrast"
|
|
rel="noreferrer"
|
|
>{{ "adminConsole" | i18n }}</a
|
|
>
|
|
{{ "unassignedItemsBannerCTAPartTwo" | i18n }}
|
|
<a
|
|
href="https://bitwarden.com/help/unassigned-vault-items-moved-to-admin-console"
|
|
bitLink
|
|
linkType="contrast"
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
>{{ "learnMore" | i18n }}</a
|
|
>
|
|
</bit-banner>
|
|
<header
|
|
*ngIf="routeData$ | async as routeData"
|
|
class="-tw-m-6 tw-mb-3 tw-flex tw-flex-col tw-p-6"
|
|
[ngClass]="{
|
|
'tw-border-0 tw-border-b tw-border-solid tw-border-secondary-300 tw-bg-background-alt tw-pb-0':
|
|
tabsContainer.childElementCount !== 0
|
|
}"
|
|
>
|
|
<div class="tw-flex">
|
|
<div class="tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-gap-2">
|
|
<ng-content select="[slot=breadcrumbs]"></ng-content>
|
|
<h1
|
|
bitTypography="h1"
|
|
noMargin
|
|
class="tw-m-0 tw-mr-2 tw-truncate tw-leading-10"
|
|
[title]="title || (routeData.titleId | i18n)"
|
|
>
|
|
<i *ngIf="icon" class="bwi {{ icon }}" aria-hidden="true"></i>
|
|
{{ title || (routeData.titleId | i18n) }}
|
|
<ng-content select="[slot=title-suffix]"></ng-content>
|
|
</h1>
|
|
</div>
|
|
<div class="tw-ml-auto tw-flex tw-flex-col tw-gap-4">
|
|
<div class="tw-flex tw-min-w-max tw-items-center tw-justify-end tw-gap-2">
|
|
<ng-content></ng-content>
|
|
<product-switcher></product-switcher>
|
|
<ng-container *ngIf="account$ | async as account">
|
|
<button
|
|
type="button"
|
|
[bitMenuTriggerFor]="accountMenu"
|
|
class="tw-border-0 tw-bg-transparent tw-p-0"
|
|
>
|
|
<dynamic-avatar [id]="account.id" [text]="account | userName"></dynamic-avatar>
|
|
</button>
|
|
|
|
<bit-menu #accountMenu>
|
|
<div class="tw-flex tw-min-w-52 tw-max-w-72 tw-flex-col">
|
|
<div
|
|
class="tw-flex tw-items-center tw-px-4 tw-py-1 tw-leading-tight tw-text-info"
|
|
appStopProp
|
|
>
|
|
<dynamic-avatar [id]="account.id" [text]="account | userName"></dynamic-avatar>
|
|
<div class="tw-ml-2 tw-block tw-overflow-hidden tw-whitespace-nowrap">
|
|
<span>{{ "loggedInAs" | i18n }}</span>
|
|
<small class="tw-block tw-overflow-hidden tw-whitespace-nowrap tw-text-muted">
|
|
{{ account | userName }}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
<ng-container *ngIf="selfHosted">
|
|
<bit-menu-divider></bit-menu-divider>
|
|
<span class="tw-break-all tw-px-4 tw-py-1 tw-text-left tw-text-muted">
|
|
{{ hostname }}
|
|
</span>
|
|
</ng-container>
|
|
|
|
<bit-menu-divider></bit-menu-divider>
|
|
|
|
<a bitMenuItem routerLink="/settings/account">
|
|
<i class="bwi bwi-fw bwi-user" aria-hidden="true"></i>
|
|
{{ "accountSettings" | i18n }}
|
|
</a>
|
|
<a bitMenuItem href="https://bitwarden.com/help/" target="_blank" rel="noreferrer">
|
|
<i class="bwi bwi-fw bwi-question-circle" aria-hidden="true"></i>
|
|
{{ "getHelp" | i18n }}
|
|
</a>
|
|
<a
|
|
bitMenuItem
|
|
href="https://bitwarden.com/download/"
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
>
|
|
<i class="bwi bwi-fw bwi-download" aria-hidden="true"></i>
|
|
{{ "getApps" | i18n }}
|
|
</a>
|
|
|
|
<bit-menu-divider></bit-menu-divider>
|
|
|
|
<button *ngIf="canLock$ | async" bitMenuItem type="button" (click)="lock()">
|
|
<i class="bwi bwi-fw bwi-lock" aria-hidden="true"></i>
|
|
{{ "lockNow" | i18n }}
|
|
</button>
|
|
<button bitMenuItem type="button" (click)="logout()">
|
|
<i class="bwi bwi-fw bwi-sign-out" aria-hidden="true"></i>
|
|
{{ "logOut" | i18n }}
|
|
</button>
|
|
</div>
|
|
</bit-menu>
|
|
</ng-container>
|
|
</div>
|
|
<div
|
|
class="tw-ml-auto"
|
|
#contentContainer
|
|
[ngClass]="{ 'tw-hidden': contentContainer.childElementCount === 0 }"
|
|
>
|
|
<ng-content select="[slot=secondary]"></ng-content>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
#tabsContainer
|
|
class="-tw-mx-4 -tw-mb-px"
|
|
[ngClass]="{ 'tw-hidden': tabsContainer.childElementCount === 0 }"
|
|
>
|
|
<ng-content select="[slot=tabs]"></ng-content>
|
|
</div>
|
|
</header>
|