mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
Expand account service (#6622)
* Define account service observable responsibilities * Establish account service observables and update methods * Update Account Service observables from state service This is a temporary stop-gap to avoid needing to reroute all account activity and status changes through the account service. That can be done as part of the breakup of state service. * Add matchers for Observable emissions * Fix null active account * Test account service * Transition account status to account info * Remove unused matchers * Remove duplicate class * Replay active account for late subscriptions * Add factories for background services * Fix state service for web * Allow for optional messaging This is a temporary hack until the flow of account status can be reversed from state -> account to account -> state. The foreground account service will still logout, it's just the background one cannot send messages * Fix add account logic * Do not throw on recoverable errors It's possible that duplicate entries exist in `activeAccounts` exist in the wild. If we throw on adding a duplicate account this will cause applications to be unusable until duplicates are removed it is not necessary to throw since this is recoverable. with some potential loss in current account status * Add documentation to abstraction * Update libs/common/spec/utils.ts Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Fix justin's comment :fist-shake: --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
||||
|
||||
import {
|
||||
FactoryOptions,
|
||||
CachedServices,
|
||||
factory,
|
||||
} from "../../../platform/background/service-factories/factory-options";
|
||||
import {
|
||||
LogServiceInitOptions,
|
||||
logServiceFactory,
|
||||
} from "../../../platform/background/service-factories/log-service.factory";
|
||||
import {
|
||||
MessagingServiceInitOptions,
|
||||
messagingServiceFactory,
|
||||
} from "../../../platform/background/service-factories/messaging-service.factory";
|
||||
|
||||
type AccountServiceFactoryOptions = FactoryOptions;
|
||||
|
||||
export type AccountServiceInitOptions = AccountServiceFactoryOptions &
|
||||
MessagingServiceInitOptions &
|
||||
LogServiceInitOptions;
|
||||
|
||||
export function accountServiceFactory(
|
||||
cache: { accountService?: AccountService } & CachedServices,
|
||||
opts: AccountServiceInitOptions
|
||||
): Promise<AccountService> {
|
||||
return factory(
|
||||
cache,
|
||||
"accountService",
|
||||
opts,
|
||||
async () =>
|
||||
new AccountServiceImplementation(
|
||||
await messagingServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import { InternalPolicyService as InternalPolicyServiceAbstraction } from "@bitw
|
||||
import { ProviderService as ProviderServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||
import { PolicyApiService } from "@bitwarden/common/admin-console/services/policy/policy-api.service";
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service";
|
||||
import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthRequestCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth-request-crypto.service.abstraction";
|
||||
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
||||
@@ -24,6 +25,7 @@ import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/
|
||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction";
|
||||
import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
||||
import { AuthRequestCryptoServiceImplementation } from "@bitwarden/common/auth/services/auth-request-crypto.service.implementation";
|
||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||
import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation";
|
||||
@@ -225,6 +227,7 @@ export default class MainBackground {
|
||||
authRequestCryptoService: AuthRequestCryptoServiceAbstraction;
|
||||
popupUtilsService: PopupUtilsService;
|
||||
browserPopoutWindowService: BrowserPopoutWindowService;
|
||||
accountService: AccountServiceAbstraction;
|
||||
|
||||
// Passed to the popup for Safari to workaround issues with theming, downloading, etc.
|
||||
backgroundWindow = window;
|
||||
@@ -279,12 +282,14 @@ export default class MainBackground {
|
||||
new KeyGenerationService(this.cryptoFunctionService)
|
||||
)
|
||||
: new MemoryStorageService();
|
||||
this.accountService = new AccountServiceImplementation(this.messagingService, this.logService);
|
||||
this.stateService = new BrowserStateService(
|
||||
this.storageService,
|
||||
this.secureStorageService,
|
||||
this.memoryStorageService,
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account)
|
||||
new StateFactory(GlobalState, Account),
|
||||
this.accountService
|
||||
);
|
||||
this.platformUtilsService = new BrowserPlatformUtilsService(
|
||||
this.messagingService,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||
|
||||
import {
|
||||
accountServiceFactory,
|
||||
AccountServiceInitOptions,
|
||||
} from "../../../auth/background/service-factories/account-service.factory";
|
||||
import { Account } from "../../../models/account";
|
||||
import { BrowserStateService } from "../../services/browser-state.service";
|
||||
|
||||
@@ -26,7 +30,8 @@ export type StateServiceInitOptions = StateServiceFactoryOptions &
|
||||
DiskStorageServiceInitOptions &
|
||||
SecureStorageServiceInitOptions &
|
||||
MemoryStorageServiceInitOptions &
|
||||
LogServiceInitOptions;
|
||||
LogServiceInitOptions &
|
||||
AccountServiceInitOptions;
|
||||
|
||||
export async function stateServiceFactory(
|
||||
cache: { stateService?: BrowserStateService } & CachedServices,
|
||||
@@ -43,6 +48,7 @@ export async function stateServiceFactory(
|
||||
await memoryStorageServiceFactory(cache, opts),
|
||||
await logServiceFactory(cache, opts),
|
||||
opts.stateServiceOptions.stateFactory,
|
||||
await accountServiceFactory(cache, opts),
|
||||
opts.stateServiceOptions.useAccountCache
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
AbstractMemoryStorageService,
|
||||
@@ -27,6 +28,7 @@ describe("Browser State Service", () => {
|
||||
let logService: MockProxy<LogService>;
|
||||
let stateFactory: MockProxy<StateFactory<GlobalState, Account>>;
|
||||
let useAccountCache: boolean;
|
||||
let accountService: MockProxy<AccountService>;
|
||||
|
||||
let state: State<GlobalState, Account>;
|
||||
const userId = "userId";
|
||||
@@ -38,6 +40,7 @@ describe("Browser State Service", () => {
|
||||
diskStorageService = mock();
|
||||
logService = mock();
|
||||
stateFactory = mock();
|
||||
accountService = mock();
|
||||
// turn off account cache for tests
|
||||
useAccountCache = false;
|
||||
|
||||
@@ -62,6 +65,7 @@ describe("Browser State Service", () => {
|
||||
memoryStorageService,
|
||||
logService,
|
||||
stateFactory,
|
||||
accountService,
|
||||
useAccountCache
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
AbstractStorageService,
|
||||
@@ -42,6 +43,7 @@ export class BrowserStateService
|
||||
memoryStorageService: AbstractMemoryStorageService,
|
||||
logService: LogService,
|
||||
stateFactory: StateFactory<GlobalState, Account>,
|
||||
accountService: AccountService,
|
||||
useAccountCache = true
|
||||
) {
|
||||
super(
|
||||
@@ -50,6 +52,7 @@ export class BrowserStateService
|
||||
memoryStorageService,
|
||||
logService,
|
||||
stateFactory,
|
||||
accountService,
|
||||
useAccountCache
|
||||
);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
} from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||
import { PolicyApiService } from "@bitwarden/common/admin-console/services/policy/policy-api.service";
|
||||
import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthRequestCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth-request-crypto.service.abstraction";
|
||||
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
||||
@@ -453,17 +454,25 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
storageService: AbstractStorageService,
|
||||
secureStorageService: AbstractStorageService,
|
||||
memoryStorageService: AbstractMemoryStorageService,
|
||||
logService: LogServiceAbstraction
|
||||
logService: LogServiceAbstraction,
|
||||
accountService: AccountServiceAbstraction
|
||||
) => {
|
||||
return new BrowserStateService(
|
||||
storageService,
|
||||
secureStorageService,
|
||||
memoryStorageService,
|
||||
logService,
|
||||
new StateFactory(GlobalState, Account)
|
||||
new StateFactory(GlobalState, Account),
|
||||
accountService
|
||||
);
|
||||
},
|
||||
deps: [AbstractStorageService, SECURE_STORAGE, MEMORY_STORAGE, LogServiceAbstraction],
|
||||
deps: [
|
||||
AbstractStorageService,
|
||||
SECURE_STORAGE,
|
||||
MEMORY_STORAGE,
|
||||
LogServiceAbstraction,
|
||||
AccountServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: UsernameGenerationServiceAbstraction,
|
||||
|
||||
@@ -12,9 +12,11 @@ import { OrganizationService } from "@bitwarden/common/admin-console/services/or
|
||||
import { PolicyApiService } from "@bitwarden/common/admin-console/services/policy/policy-api.service";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthRequestCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth-request-crypto.service.abstraction";
|
||||
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
||||
import { AuthRequestCryptoServiceImplementation } from "@bitwarden/common/auth/services/auth-request-crypto.service.implementation";
|
||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||
import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation";
|
||||
@@ -152,6 +154,7 @@ export class Main {
|
||||
authRequestCryptoService: AuthRequestCryptoServiceAbstraction;
|
||||
configApiService: ConfigApiServiceAbstraction;
|
||||
configService: CliConfigService;
|
||||
accountService: AccountService;
|
||||
|
||||
constructor() {
|
||||
let p = null;
|
||||
@@ -191,12 +194,15 @@ export class Main {
|
||||
|
||||
this.memoryStorageService = new MemoryStorageService();
|
||||
|
||||
this.accountService = new AccountServiceImplementation(null, this.logService);
|
||||
|
||||
this.stateService = new StateService(
|
||||
this.storageService,
|
||||
this.secureStorageService,
|
||||
this.memoryStorageService,
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account)
|
||||
new StateFactory(GlobalState, Account),
|
||||
this.accountService
|
||||
);
|
||||
|
||||
this.cryptoService = new CryptoService(
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
|
||||
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||
import { PolicyService as PolicyServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/login.service";
|
||||
import { LoginService } from "@bitwarden/common/auth/services/login.service";
|
||||
@@ -120,6 +121,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
||||
MEMORY_STORAGE,
|
||||
LogService,
|
||||
STATE_FACTORY,
|
||||
AccountServiceAbstraction,
|
||||
STATE_SERVICE_USE_CACHE,
|
||||
],
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as path from "path";
|
||||
|
||||
import { app } from "electron";
|
||||
|
||||
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
|
||||
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||
import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service";
|
||||
@@ -93,6 +94,7 @@ export class Main {
|
||||
this.memoryStorageService,
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
new AccountServiceImplementation(null, this.logService), // will not broadcast logouts. This is a hack until we can remove messaging dependency
|
||||
false // Do not use disk caching because this will get out of sync with the renderer service
|
||||
);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
STATE_FACTORY,
|
||||
STATE_SERVICE_USE_CACHE,
|
||||
} from "@bitwarden/angular/services/injection-tokens";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import {
|
||||
AbstractMemoryStorageService,
|
||||
@@ -30,6 +31,7 @@ export class StateService extends BaseStateService<GlobalState, Account> {
|
||||
@Inject(MEMORY_STORAGE) memoryStorageService: AbstractMemoryStorageService,
|
||||
logService: LogService,
|
||||
@Inject(STATE_FACTORY) stateFactory: StateFactory<GlobalState, Account>,
|
||||
accountService: AccountService,
|
||||
@Inject(STATE_SERVICE_USE_CACHE) useAccountCache = true
|
||||
) {
|
||||
super(
|
||||
@@ -38,6 +40,7 @@ export class StateService extends BaseStateService<GlobalState, Account> {
|
||||
memoryStorageService,
|
||||
logService,
|
||||
stateFactory,
|
||||
accountService,
|
||||
useAccountCache
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user