1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 02:03:39 +00:00

[PM-6688] Use AccountService as account source (#8893)

* 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>
This commit is contained in:
Matt Gibson
2024-04-30 09:13:02 -04:00
committed by GitHub
parent 61d079cc34
commit c70a5aa024
67 changed files with 1380 additions and 618 deletions

View File

@@ -2,6 +2,7 @@ import {
Observable,
combineLatest,
distinctUntilChanged,
firstValueFrom,
map,
of,
shareReplay,
@@ -12,6 +13,7 @@ import { ApiService } from "../../abstractions/api.service";
import { CryptoService } from "../../platform/abstractions/crypto.service";
import { MessagingService } from "../../platform/abstractions/messaging.service";
import { StateService } from "../../platform/abstractions/state.service";
import { Utils } from "../../platform/misc/utils";
import { UserId } from "../../types/guid";
import { AccountService } from "../abstractions/account.service";
import { AuthService as AuthServiceAbstraction } from "../abstractions/auth.service";
@@ -39,13 +41,16 @@ export class AuthService implements AuthServiceAbstraction {
this.authStatuses$ = this.accountService.accounts$.pipe(
map((accounts) => Object.keys(accounts) as UserId[]),
switchMap((entries) =>
combineLatest(
switchMap((entries) => {
if (entries.length === 0) {
return of([] as { userId: UserId; status: AuthenticationStatus }[]);
}
return combineLatest(
entries.map((userId) =>
this.authStatusFor$(userId).pipe(map((status) => ({ userId, status }))),
),
),
),
);
}),
map((statuses) => {
return statuses.reduce(
(acc, { userId, status }) => {
@@ -59,7 +64,7 @@ export class AuthService implements AuthServiceAbstraction {
}
authStatusFor$(userId: UserId): Observable<AuthenticationStatus> {
if (userId == null) {
if (!Utils.isGuid(userId)) {
return of(AuthenticationStatus.LoggedOut);
}
@@ -84,17 +89,8 @@ export class AuthService implements AuthServiceAbstraction {
}
async getAuthStatus(userId?: string): Promise<AuthenticationStatus> {
// If we don't have an access token or userId, we're logged out
const isAuthenticated = await this.stateService.getIsAuthenticated({ userId: userId });
if (!isAuthenticated) {
return AuthenticationStatus.LoggedOut;
}
// Note: since we aggresively set the auto user key to memory if it exists on app init (see InitService)
// we only need to check if the user key is in memory.
const hasUserKey = await this.cryptoService.hasUserKeyInMemory(userId as UserId);
return hasUserKey ? AuthenticationStatus.Unlocked : AuthenticationStatus.Locked;
userId ??= await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id)));
return await firstValueFrom(this.authStatusFor$(userId as UserId));
}
logOut(callback: () => void) {