Ps/pm 5965/better config polling (#8325)
* Create tracker that can await until expected observables are received. * Test dates are almost equal * Remove unused class method * Allow for updating active account in accout service fake * Correct observable tracker behavior Clarify documentation * Transition config service to state provider Updates the config fetching behavior to be lazy and ensure that any emitted value has been updated if older than a configurable value (statically compiled). If desired, config fetching can be ensured fresh through an async. * Update calls to config service in DI and bootstrapping * Migrate account server configs * Fix global config fetching * Test migration rollback * Adhere to implementation naming convention * Adhere to abstract class naming convention * Complete config abstraction rename * Remove unnecessary cli config service * Fix builds * Validate observable does not complete * Use token service to determine authed or unauthed config pull * Remove superfluous factory config * Name describe blocks after the thing they test * Remove implementation documentation Unfortunately the experience when linking to external documentation is quite poor. Instead of following the link and retrieving docs, you get a link that can be clicked to take you out of context to the docs. No link _does_ retrieve docs, but lacks indication in the implementation that documentation exists at all. On the balance, removing the link is the better experience. * Fix storybook
This commit is contained in:
parent
64d6f6fef3
commit
62ad39e697
|
@ -12,7 +12,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -44,7 +44,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
protected authService: AuthService,
|
protected authService: AuthService,
|
||||||
@Inject(WINDOW) private win: Window,
|
@Inject(WINDOW) private win: Window,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -59,7 +59,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||||
appIdService: AppIdService,
|
appIdService: AppIdService,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
ssoLoginService: SsoLoginServiceAbstraction,
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
@Inject(WINDOW) protected win: Window,
|
@Inject(WINDOW) protected win: Window,
|
||||||
|
|
|
@ -70,6 +70,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||||
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
|
@ -93,6 +94,7 @@ import { StateFactory } from "@bitwarden/common/platform/factories/state-factory
|
||||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
||||||
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
||||||
|
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
|
||||||
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||||
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
||||||
|
@ -201,7 +203,6 @@ import { BrowserApi } from "../platform/browser/browser-api";
|
||||||
import { flagEnabled } from "../platform/flags";
|
import { flagEnabled } from "../platform/flags";
|
||||||
import { UpdateBadge } from "../platform/listeners/update-badge";
|
import { UpdateBadge } from "../platform/listeners/update-badge";
|
||||||
import { BrowserStateService as StateServiceAbstraction } from "../platform/services/abstractions/browser-state.service";
|
import { BrowserStateService as StateServiceAbstraction } from "../platform/services/abstractions/browser-state.service";
|
||||||
import { BrowserConfigService } from "../platform/services/browser-config.service";
|
|
||||||
import { BrowserCryptoService } from "../platform/services/browser-crypto.service";
|
import { BrowserCryptoService } from "../platform/services/browser-crypto.service";
|
||||||
import { BrowserEnvironmentService } from "../platform/services/browser-environment.service";
|
import { BrowserEnvironmentService } from "../platform/services/browser-environment.service";
|
||||||
import BrowserLocalStorageService from "../platform/services/browser-local-storage.service";
|
import BrowserLocalStorageService from "../platform/services/browser-local-storage.service";
|
||||||
|
@ -293,7 +294,7 @@ export default class MainBackground {
|
||||||
avatarService: AvatarServiceAbstraction;
|
avatarService: AvatarServiceAbstraction;
|
||||||
mainContextMenuHandler: MainContextMenuHandler;
|
mainContextMenuHandler: MainContextMenuHandler;
|
||||||
cipherContextMenuHandler: CipherContextMenuHandler;
|
cipherContextMenuHandler: CipherContextMenuHandler;
|
||||||
configService: BrowserConfigService;
|
configService: ConfigService;
|
||||||
configApiService: ConfigApiServiceAbstraction;
|
configApiService: ConfigApiServiceAbstraction;
|
||||||
devicesApiService: DevicesApiServiceAbstraction;
|
devicesApiService: DevicesApiServiceAbstraction;
|
||||||
devicesService: DevicesServiceAbstraction;
|
devicesService: DevicesServiceAbstraction;
|
||||||
|
@ -609,16 +610,13 @@ export default class MainBackground {
|
||||||
|
|
||||||
this.userVerificationApiService = new UserVerificationApiService(this.apiService);
|
this.userVerificationApiService = new UserVerificationApiService(this.apiService);
|
||||||
|
|
||||||
this.configApiService = new ConfigApiService(this.apiService, this.authService);
|
this.configApiService = new ConfigApiService(this.apiService, this.tokenService);
|
||||||
|
|
||||||
this.configService = new BrowserConfigService(
|
this.configService = new DefaultConfigService(
|
||||||
this.stateService,
|
|
||||||
this.configApiService,
|
this.configApiService,
|
||||||
this.authService,
|
|
||||||
this.environmentService,
|
this.environmentService,
|
||||||
this.logService,
|
this.logService,
|
||||||
this.stateProvider,
|
this.stateProvider,
|
||||||
true,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cipherService = new CipherService(
|
this.cipherService = new CipherService(
|
||||||
|
@ -1005,7 +1003,6 @@ export default class MainBackground {
|
||||||
this.filelessImporterBackground.init();
|
this.filelessImporterBackground.init();
|
||||||
await this.commandsBackground.init();
|
await this.commandsBackground.init();
|
||||||
|
|
||||||
this.configService.init();
|
|
||||||
this.twoFactorService.init();
|
this.twoFactorService.init();
|
||||||
|
|
||||||
await this.overlayBackground.init();
|
await this.overlayBackground.init();
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { firstValueFrom } from "rxjs";
|
||||||
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
|
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
|
||||||
import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants";
|
import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants";
|
||||||
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -46,7 +46,7 @@ export default class RuntimeBackground {
|
||||||
private environmentService: BrowserEnvironmentService,
|
private environmentService: BrowserEnvironmentService,
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private fido2Service: Fido2Service,
|
private fido2Service: Fido2Service,
|
||||||
) {
|
) {
|
||||||
// onInstalled listener must be wired up before anything else, so we do it in the ctor
|
// onInstalled listener must be wired up before anything else, so we do it in the ctor
|
||||||
|
@ -136,7 +136,7 @@ export default class RuntimeBackground {
|
||||||
await this.main.refreshBadge();
|
await this.main.refreshBadge();
|
||||||
await this.main.refreshMenu();
|
await this.main.refreshMenu();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
this.configService.triggerServerConfigFetch();
|
await this.configService.ensureConfigFetched();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "openPopup":
|
case "openPopup":
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstract
|
||||||
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
authServiceFactory,
|
tokenServiceFactory,
|
||||||
AuthServiceInitOptions,
|
TokenServiceInitOptions,
|
||||||
} from "../../../auth/background/service-factories/auth-service.factory";
|
} from "../../../auth/background/service-factories/token-service.factory";
|
||||||
|
|
||||||
import { apiServiceFactory, ApiServiceInitOptions } from "./api-service.factory";
|
import { apiServiceFactory, ApiServiceInitOptions } from "./api-service.factory";
|
||||||
import { FactoryOptions, CachedServices, factory } from "./factory-options";
|
import { FactoryOptions, CachedServices, factory } from "./factory-options";
|
||||||
|
@ -13,7 +13,7 @@ type ConfigApiServiceFactoyOptions = FactoryOptions;
|
||||||
|
|
||||||
export type ConfigApiServiceInitOptions = ConfigApiServiceFactoyOptions &
|
export type ConfigApiServiceInitOptions = ConfigApiServiceFactoyOptions &
|
||||||
ApiServiceInitOptions &
|
ApiServiceInitOptions &
|
||||||
AuthServiceInitOptions;
|
TokenServiceInitOptions;
|
||||||
|
|
||||||
export function configApiServiceFactory(
|
export function configApiServiceFactory(
|
||||||
cache: { configApiService?: ConfigApiServiceAbstraction } & CachedServices,
|
cache: { configApiService?: ConfigApiServiceAbstraction } & CachedServices,
|
||||||
|
@ -26,7 +26,7 @@ export function configApiServiceFactory(
|
||||||
async () =>
|
async () =>
|
||||||
new ConfigApiService(
|
new ConfigApiService(
|
||||||
await apiServiceFactory(cache, opts),
|
await apiServiceFactory(cache, opts),
|
||||||
await authServiceFactory(cache, opts),
|
await tokenServiceFactory(cache, opts),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
|
||||||
|
|
||||||
import {
|
|
||||||
authServiceFactory,
|
|
||||||
AuthServiceInitOptions,
|
|
||||||
} from "../../../auth/background/service-factories/auth-service.factory";
|
|
||||||
|
|
||||||
import { configApiServiceFactory, ConfigApiServiceInitOptions } from "./config-api.service.factory";
|
import { configApiServiceFactory, ConfigApiServiceInitOptions } from "./config-api.service.factory";
|
||||||
import {
|
import {
|
||||||
|
@ -13,39 +8,30 @@ import {
|
||||||
} from "./environment-service.factory";
|
} from "./environment-service.factory";
|
||||||
import { FactoryOptions, CachedServices, factory } from "./factory-options";
|
import { FactoryOptions, CachedServices, factory } from "./factory-options";
|
||||||
import { logServiceFactory, LogServiceInitOptions } from "./log-service.factory";
|
import { logServiceFactory, LogServiceInitOptions } from "./log-service.factory";
|
||||||
import { stateProviderFactory } from "./state-provider.factory";
|
import { stateProviderFactory, StateProviderInitOptions } from "./state-provider.factory";
|
||||||
import { stateServiceFactory, StateServiceInitOptions } from "./state-service.factory";
|
|
||||||
|
|
||||||
type ConfigServiceFactoryOptions = FactoryOptions & {
|
type ConfigServiceFactoryOptions = FactoryOptions;
|
||||||
configServiceOptions?: {
|
|
||||||
subscribe?: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ConfigServiceInitOptions = ConfigServiceFactoryOptions &
|
export type ConfigServiceInitOptions = ConfigServiceFactoryOptions &
|
||||||
StateServiceInitOptions &
|
|
||||||
ConfigApiServiceInitOptions &
|
ConfigApiServiceInitOptions &
|
||||||
AuthServiceInitOptions &
|
|
||||||
EnvironmentServiceInitOptions &
|
EnvironmentServiceInitOptions &
|
||||||
LogServiceInitOptions;
|
LogServiceInitOptions &
|
||||||
|
StateProviderInitOptions;
|
||||||
|
|
||||||
export function configServiceFactory(
|
export function configServiceFactory(
|
||||||
cache: { configService?: ConfigServiceAbstraction } & CachedServices,
|
cache: { configService?: ConfigService } & CachedServices,
|
||||||
opts: ConfigServiceInitOptions,
|
opts: ConfigServiceInitOptions,
|
||||||
): Promise<ConfigServiceAbstraction> {
|
): Promise<ConfigService> {
|
||||||
return factory(
|
return factory(
|
||||||
cache,
|
cache,
|
||||||
"configService",
|
"configService",
|
||||||
opts,
|
opts,
|
||||||
async () =>
|
async () =>
|
||||||
new ConfigService(
|
new DefaultConfigService(
|
||||||
await stateServiceFactory(cache, opts),
|
|
||||||
await configApiServiceFactory(cache, opts),
|
await configApiServiceFactory(cache, opts),
|
||||||
await authServiceFactory(cache, opts),
|
|
||||||
await environmentServiceFactory(cache, opts),
|
await environmentServiceFactory(cache, opts),
|
||||||
await logServiceFactory(cache, opts),
|
await logServiceFactory(cache, opts),
|
||||||
await stateProviderFactory(cache, opts),
|
await stateProviderFactory(cache, opts),
|
||||||
opts.configServiceOptions?.subscribe ?? true,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { ReplaySubject } from "rxjs";
|
|
||||||
|
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
|
||||||
import { ServerConfig } from "@bitwarden/common/platform/abstractions/config/server-config";
|
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
|
||||||
import { StateProvider } from "@bitwarden/common/platform/state";
|
|
||||||
|
|
||||||
import { browserSession, sessionSync } from "../decorators/session-sync-observable";
|
|
||||||
|
|
||||||
@browserSession
|
|
||||||
export class BrowserConfigService extends ConfigService {
|
|
||||||
@sessionSync<ServerConfig>({ initializer: ServerConfig.fromJSON })
|
|
||||||
protected _serverConfig: ReplaySubject<ServerConfig | null>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
stateService: StateService,
|
|
||||||
configApiService: ConfigApiServiceAbstraction,
|
|
||||||
authService: AuthService,
|
|
||||||
environmentService: EnvironmentService,
|
|
||||||
logService: LogService,
|
|
||||||
stateProvider: StateProvider,
|
|
||||||
subscribe = false,
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
stateService,
|
|
||||||
configApiService,
|
|
||||||
authService,
|
|
||||||
environmentService,
|
|
||||||
logService,
|
|
||||||
stateProvider,
|
|
||||||
subscribe,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import { AbstractThemingService } from "@bitwarden/angular/platform/services/the
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
|
||||||
|
|
||||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||||
import BrowserPopupUtils from "../../platform/popup/browser-popup-utils";
|
import BrowserPopupUtils from "../../platform/popup/browser-popup-utils";
|
||||||
|
@ -19,7 +18,6 @@ export class InitService {
|
||||||
private stateService: StateServiceAbstraction,
|
private stateService: StateServiceAbstraction,
|
||||||
private logService: LogServiceAbstraction,
|
private logService: LogServiceAbstraction,
|
||||||
private themingService: AbstractThemingService,
|
private themingService: AbstractThemingService,
|
||||||
private configService: ConfigService,
|
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -55,7 +53,6 @@ export class InitService {
|
||||||
this.logService.info("Force redraw is on");
|
this.logService.info("Force redraw is on");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.configService.init();
|
|
||||||
this.setupVaultPopupHeartbeat();
|
this.setupVaultPopupHeartbeat();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,17 +46,13 @@ import {
|
||||||
UserNotificationSettingsService,
|
UserNotificationSettingsService,
|
||||||
UserNotificationSettingsServiceAbstraction,
|
UserNotificationSettingsServiceAbstraction,
|
||||||
} from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
} from "@bitwarden/common/autofill/services/user-notification-settings.service";
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import {
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
LogService,
|
|
||||||
LogService as LogServiceAbstraction,
|
|
||||||
} from "@bitwarden/common/platform/abstractions/log.service";
|
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { StateService as BaseStateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService as BaseStateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
|
@ -66,7 +62,6 @@ import {
|
||||||
} from "@bitwarden/common/platform/abstractions/storage.service";
|
} from "@bitwarden/common/platform/abstractions/storage.service";
|
||||||
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
||||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
|
||||||
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||||
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
||||||
|
@ -95,7 +90,6 @@ import { Account } from "../../models/account";
|
||||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||||
import BrowserPopupUtils from "../../platform/popup/browser-popup-utils";
|
import BrowserPopupUtils from "../../platform/popup/browser-popup-utils";
|
||||||
import { BrowserStateService as StateServiceAbstraction } from "../../platform/services/abstractions/browser-state.service";
|
import { BrowserStateService as StateServiceAbstraction } from "../../platform/services/abstractions/browser-state.service";
|
||||||
import { BrowserConfigService } from "../../platform/services/browser-config.service";
|
|
||||||
import { BrowserEnvironmentService } from "../../platform/services/browser-environment.service";
|
import { BrowserEnvironmentService } from "../../platform/services/browser-environment.service";
|
||||||
import { BrowserFileDownloadService } from "../../platform/services/browser-file-download.service";
|
import { BrowserFileDownloadService } from "../../platform/services/browser-file-download.service";
|
||||||
import BrowserLocalStorageService from "../../platform/services/browser-local-storage.service";
|
import BrowserLocalStorageService from "../../platform/services/browser-local-storage.service";
|
||||||
|
@ -186,7 +180,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||||
i18nService,
|
i18nService,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
deps: [LogServiceAbstraction, I18nServiceAbstraction],
|
deps: [LogService, I18nServiceAbstraction],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: CipherFileUploadService,
|
provide: CipherFileUploadService,
|
||||||
|
@ -205,7 +199,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||||
deps: [],
|
deps: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: LogServiceAbstraction,
|
provide: LogService,
|
||||||
useFactory: (platformUtilsService: PlatformUtilsService) =>
|
useFactory: (platformUtilsService: PlatformUtilsService) =>
|
||||||
new ConsoleLogService(platformUtilsService.isDev()),
|
new ConsoleLogService(platformUtilsService.isDev()),
|
||||||
deps: [PlatformUtilsService],
|
deps: [PlatformUtilsService],
|
||||||
|
@ -367,7 +361,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||||
storageService: AbstractStorageService,
|
storageService: AbstractStorageService,
|
||||||
secureStorageService: AbstractStorageService,
|
secureStorageService: AbstractStorageService,
|
||||||
memoryStorageService: AbstractMemoryStorageService,
|
memoryStorageService: AbstractMemoryStorageService,
|
||||||
logService: LogServiceAbstraction,
|
logService: LogService,
|
||||||
accountService: AccountServiceAbstraction,
|
accountService: AccountServiceAbstraction,
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
tokenService: TokenService,
|
tokenService: TokenService,
|
||||||
|
@ -389,7 +383,7 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||||
AbstractStorageService,
|
AbstractStorageService,
|
||||||
SECURE_STORAGE,
|
SECURE_STORAGE,
|
||||||
MEMORY_STORAGE,
|
MEMORY_STORAGE,
|
||||||
LogServiceAbstraction,
|
LogService,
|
||||||
AccountServiceAbstraction,
|
AccountServiceAbstraction,
|
||||||
EnvironmentService,
|
EnvironmentService,
|
||||||
TokenService,
|
TokenService,
|
||||||
|
@ -430,18 +424,6 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||||
},
|
},
|
||||||
deps: [PlatformUtilsService],
|
deps: [PlatformUtilsService],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
provide: ConfigService,
|
|
||||||
useClass: BrowserConfigService,
|
|
||||||
deps: [
|
|
||||||
StateServiceAbstraction,
|
|
||||||
ConfigApiServiceAbstraction,
|
|
||||||
AuthServiceAbstraction,
|
|
||||||
EnvironmentService,
|
|
||||||
StateProvider,
|
|
||||||
LogService,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
provide: FilePopoutUtilsService,
|
provide: FilePopoutUtilsService,
|
||||||
useFactory: (platformUtilsService: PlatformUtilsService) => {
|
useFactory: (platformUtilsService: PlatformUtilsService) => {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Component } from "@angular/core";
|
||||||
import { combineLatest, map } from "rxjs";
|
import { combineLatest, map } from "rxjs";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { ButtonModule, DialogModule } from "@bitwarden/components";
|
import { ButtonModule, DialogModule } from "@bitwarden/components";
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ export class AboutComponent {
|
||||||
]).pipe(map(([serverConfig, isCloud]) => ({ serverConfig, isCloud })));
|
]).pipe(map(([serverConfig, isCloud]) => ({ serverConfig, isCloud })));
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private environmentService: EnvironmentService,
|
private environmentService: EnvironmentService,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { firstValueFrom } from "rxjs";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
|
import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/services/auth.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||||
import { Importer, ImportResult, ImportServiceAbstraction } from "@bitwarden/importer/core";
|
import { Importer, ImportResult, ImportServiceAbstraction } from "@bitwarden/importer/core";
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||||
import { ImportServiceAbstraction } from "@bitwarden/importer/core";
|
import { ImportServiceAbstraction } from "@bitwarden/importer/core";
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class FilelessImporterBackground implements FilelessImporterBackgroundInterface
|
||||||
* @param syncService - Used to trigger a full sync after the import is completed.
|
* @param syncService - Used to trigger a full sync after the import is completed.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
private notificationBackground: NotificationBackground,
|
private notificationBackground: NotificationBackground,
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -68,7 +68,7 @@ export class AddEditComponent extends BaseAddEditComponent {
|
||||||
sendApiService: SendApiService,
|
sendApiService: SendApiService,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
datePipe: DatePipe,
|
datePipe: DatePipe,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
cipherService,
|
cipherService,
|
||||||
|
|
|
@ -47,6 +47,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||||
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
||||||
import { ClientType } from "@bitwarden/common/enums";
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
|
||||||
import {
|
import {
|
||||||
|
@ -60,6 +61,7 @@ import { GlobalState } from "@bitwarden/common/platform/models/domain/global-sta
|
||||||
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/services/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/services/broadcaster.service";
|
||||||
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
||||||
|
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
|
||||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
|
||||||
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
||||||
|
@ -131,7 +133,6 @@ import {
|
||||||
VaultExportServiceAbstraction,
|
VaultExportServiceAbstraction,
|
||||||
} from "@bitwarden/vault-export-core";
|
} from "@bitwarden/vault-export-core";
|
||||||
|
|
||||||
import { CliConfigService } from "./platform/services/cli-config.service";
|
|
||||||
import { CliPlatformUtilsService } from "./platform/services/cli-platform-utils.service";
|
import { CliPlatformUtilsService } from "./platform/services/cli-platform-utils.service";
|
||||||
import { ConsoleLogService } from "./platform/services/console-log.service";
|
import { ConsoleLogService } from "./platform/services/console-log.service";
|
||||||
import { I18nService } from "./platform/services/i18n.service";
|
import { I18nService } from "./platform/services/i18n.service";
|
||||||
|
@ -214,7 +215,7 @@ export class Main {
|
||||||
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction;
|
deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction;
|
||||||
authRequestService: AuthRequestService;
|
authRequestService: AuthRequestService;
|
||||||
configApiService: ConfigApiServiceAbstraction;
|
configApiService: ConfigApiServiceAbstraction;
|
||||||
configService: CliConfigService;
|
configService: ConfigService;
|
||||||
accountService: AccountService;
|
accountService: AccountService;
|
||||||
globalStateProvider: GlobalStateProvider;
|
globalStateProvider: GlobalStateProvider;
|
||||||
singleUserStateProvider: SingleUserStateProvider;
|
singleUserStateProvider: SingleUserStateProvider;
|
||||||
|
@ -504,16 +505,13 @@ export class Main {
|
||||||
this.stateService,
|
this.stateService,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.configApiService = new ConfigApiService(this.apiService, this.authService);
|
this.configApiService = new ConfigApiService(this.apiService, this.tokenService);
|
||||||
|
|
||||||
this.configService = new CliConfigService(
|
this.configService = new DefaultConfigService(
|
||||||
this.stateService,
|
|
||||||
this.configApiService,
|
this.configApiService,
|
||||||
this.authService,
|
|
||||||
this.environmentService,
|
this.environmentService,
|
||||||
this.logService,
|
this.logService,
|
||||||
this.stateProvider,
|
this.stateProvider,
|
||||||
true,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cipherService = new CipherService(
|
this.cipherService = new CipherService(
|
||||||
|
@ -714,7 +712,6 @@ export class Main {
|
||||||
this.containerService.attachToGlobal(global);
|
this.containerService.attachToGlobal(global);
|
||||||
await this.i18nService.init();
|
await this.i18nService.init();
|
||||||
this.twoFactorService.init();
|
this.twoFactorService.init();
|
||||||
this.configService.init();
|
|
||||||
|
|
||||||
const installedVersion = await this.stateService.getInstalledVersion();
|
const installedVersion = await this.stateService.getInstalledVersion();
|
||||||
const currentVersion = await this.platformUtilsService.getApplicationVersion();
|
const currentVersion = await this.platformUtilsService.getApplicationVersion();
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { NEVER } from "rxjs";
|
|
||||||
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
|
||||||
|
|
||||||
export class CliConfigService extends ConfigService {
|
|
||||||
// The rxjs timer uses setTimeout/setInterval under the hood, which prevents the node process from exiting
|
|
||||||
// when the command is finished. Cli should never be alive long enough to use the timer, so we disable it.
|
|
||||||
protected refreshTimer$ = NEVER;
|
|
||||||
}
|
|
|
@ -31,7 +31,7 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authenticatio
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -147,7 +147,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
private modalService: ModalService,
|
private modalService: ModalService,
|
||||||
private keyConnectorService: KeyConnectorService,
|
private keyConnectorService: KeyConnectorService,
|
||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private biometricStateService: BiometricStateService,
|
private biometricStateService: BiometricStateService,
|
||||||
private stateEventRunnerService: StateEventRunnerService,
|
private stateEventRunnerService: StateEventRunnerService,
|
||||||
|
@ -265,7 +265,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.updateAppMenu();
|
this.updateAppMenu();
|
||||||
this.configService.triggerServerConfigFetch();
|
await this.configService.ensureConfigFetched();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "openSettings":
|
case "openSettings":
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.
|
||||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
|
||||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||||
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
|
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
|
||||||
import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service";
|
import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service";
|
||||||
|
@ -36,7 +35,6 @@ export class InitService {
|
||||||
private nativeMessagingService: NativeMessagingService,
|
private nativeMessagingService: NativeMessagingService,
|
||||||
private themingService: AbstractThemingService,
|
private themingService: AbstractThemingService,
|
||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
private configService: ConfigService,
|
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -70,8 +68,6 @@ export class InitService {
|
||||||
|
|
||||||
const containerService = new ContainerService(this.cryptoService, this.encryptService);
|
const containerService = new ContainerService(this.cryptoService, this.encryptService);
|
||||||
containerService.attachToGlobal(this.win);
|
containerService.attachToGlobal(this.win);
|
||||||
|
|
||||||
this.configService.init();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from "@bitwarden/auth/common";
|
} from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -38,7 +38,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
passwordGenerationService: PasswordGenerationServiceAbstraction,
|
passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
ssoLoginService,
|
ssoLoginService,
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -59,7 +59,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
ssoLoginService: SsoLoginServiceAbstraction,
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
@Inject(WINDOW) protected win: Window,
|
@Inject(WINDOW) protected win: Window,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -49,7 +49,7 @@ export class AddEditComponent extends BaseAddEditComponent implements OnChanges,
|
||||||
sendApiService: SendApiService,
|
sendApiService: SendApiService,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
datePipe: DatePipe,
|
datePipe: DatePipe,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
cipherService,
|
cipherService,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Injectable } from "@angular/core";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request";
|
import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request";
|
||||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
import { CoreOrganizationModule } from "../../core-organization.module";
|
import { CoreOrganizationModule } from "../../core-organization.module";
|
||||||
import { GroupView } from "../../views/group.view";
|
import { GroupView } from "../../views/group.view";
|
||||||
|
@ -18,7 +18,7 @@ import { GroupDetailsResponse, GroupResponse } from "./responses/group.response"
|
||||||
export class GroupService {
|
export class GroupService {
|
||||||
constructor(
|
constructor(
|
||||||
protected apiService: ApiService,
|
protected apiService: ApiService,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async get(orgId: string, groupId: string): Promise<GroupView> {
|
async get(orgId: string, groupId: string): Promise<GroupView> {
|
||||||
|
@ -52,7 +52,7 @@ export class GroupService {
|
||||||
export class InternalGroupService extends GroupService {
|
export class InternalGroupService extends GroupService {
|
||||||
constructor(
|
constructor(
|
||||||
protected apiService: ApiService,
|
protected apiService: ApiService,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(apiService, configService);
|
super(apiService, configService);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
OrganizationUserUpdateRequest,
|
OrganizationUserUpdateRequest,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization-user/requests";
|
} from "@bitwarden/common/admin-console/abstractions/organization-user/requests";
|
||||||
import { OrganizationUserDetailsResponse } from "@bitwarden/common/admin-console/abstractions/organization-user/responses";
|
import { OrganizationUserDetailsResponse } from "@bitwarden/common/admin-console/abstractions/organization-user/responses";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
import { CoreOrganizationModule } from "../core-organization.module";
|
import { CoreOrganizationModule } from "../core-organization.module";
|
||||||
import { OrganizationUserAdminView } from "../views/organization-user-admin-view";
|
import { OrganizationUserAdminView } from "../views/organization-user-admin-view";
|
||||||
|
@ -14,7 +14,7 @@ import { OrganizationUserAdminView } from "../views/organization-user-admin-view
|
||||||
@Injectable({ providedIn: CoreOrganizationModule })
|
@Injectable({ providedIn: CoreOrganizationModule })
|
||||||
export class UserAdminService {
|
export class UserAdminService {
|
||||||
constructor(
|
constructor(
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private organizationUserService: OrganizationUserService,
|
private organizationUserService: OrganizationUserService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction as ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { BannerModule, IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
import { BannerModule, IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { ProductType } from "@bitwarden/common/enums";
|
import { ProductType } from "@bitwarden/common/enums";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
|
import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
|
||||||
|
@ -148,7 +148,7 @@ export class MemberDialogComponent implements OnDestroy {
|
||||||
private userService: UserAdminService,
|
private userService: UserAdminService,
|
||||||
private organizationUserService: OrganizationUserService,
|
private organizationUserService: OrganizationUserService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
organizationService: OrganizationService,
|
organizationService: OrganizationService,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/
|
||||||
import { OrganizationUpdateRequest } from "@bitwarden/common/admin-console/models/request/organization-update.request";
|
import { OrganizationUpdateRequest } from "@bitwarden/common/admin-console/models/request/organization-update.request";
|
||||||
import { OrganizationResponse } from "@bitwarden/common/admin-console/models/response/organization.response";
|
import { OrganizationResponse } from "@bitwarden/common/admin-console/models/response/organization.response";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
|
@ -95,7 +95,7 @@ export class AccountComponent {
|
||||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
||||||
import { PaymentMethodWarningsServiceAbstraction as PaymentMethodWarningService } from "@bitwarden/common/billing/abstractions/payment-method-warnings-service.abstraction";
|
import { PaymentMethodWarningsServiceAbstraction as PaymentMethodWarningService } from "@bitwarden/common/billing/abstractions/payment-method-warnings-service.abstraction";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
|
@ -83,7 +83,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
||||||
private policyService: InternalPolicyService,
|
private policyService: InternalPolicyService,
|
||||||
protected policyListService: PolicyListService,
|
protected policyListService: PolicyListService,
|
||||||
private keyConnectorService: KeyConnectorService,
|
private keyConnectorService: KeyConnectorService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private biometricStateService: BiometricStateService,
|
private biometricStateService: BiometricStateService,
|
||||||
private stateEventRunnerService: StateEventRunnerService,
|
private stateEventRunnerService: StateEventRunnerService,
|
||||||
|
@ -158,7 +158,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
||||||
break;
|
break;
|
||||||
case "syncCompleted":
|
case "syncCompleted":
|
||||||
if (message.successfully) {
|
if (message.successfully) {
|
||||||
this.configService.triggerServerConfigFetch();
|
await this.configService.ensureConfigFetched();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "upgradeOrganization": {
|
case "upgradeOrganization": {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { EncryptionType } from "@bitwarden/common/platform/enums";
|
import { EncryptionType } from "@bitwarden/common/platform/enums";
|
||||||
|
@ -39,7 +39,7 @@ describe("KeyRotationService", () => {
|
||||||
let mockCryptoService: MockProxy<CryptoService>;
|
let mockCryptoService: MockProxy<CryptoService>;
|
||||||
let mockEncryptService: MockProxy<EncryptService>;
|
let mockEncryptService: MockProxy<EncryptService>;
|
||||||
let mockStateService: MockProxy<StateService>;
|
let mockStateService: MockProxy<StateService>;
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigService>;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
mockApiService = mock<UserKeyRotationApiService>();
|
mockApiService = mock<UserKeyRotationApiService>();
|
||||||
|
@ -52,7 +52,7 @@ describe("KeyRotationService", () => {
|
||||||
mockCryptoService = mock<CryptoService>();
|
mockCryptoService = mock<CryptoService>();
|
||||||
mockEncryptService = mock<EncryptService>();
|
mockEncryptService = mock<EncryptService>();
|
||||||
mockStateService = mock<StateService>();
|
mockStateService = mock<StateService>();
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock<ConfigService>();
|
||||||
|
|
||||||
keyRotationService = new UserKeyRotationService(
|
keyRotationService = new UserKeyRotationService(
|
||||||
mockApiService,
|
mockApiService,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
|
@ -34,7 +34,7 @@ export class UserKeyRotationService {
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -52,7 +52,7 @@ export class EmergencyAddEditCipherComponent extends BaseAddEditComponent {
|
||||||
sendApiService: SendApiService,
|
sendApiService: SendApiService,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
datePipe: DatePipe,
|
datePipe: DatePipe,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
billingAccountProfileStateService: BillingAccountProfileStateService,
|
billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { OrganizationDomainSsoDetailsResponse } from "@bitwarden/common/admin-co
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { HttpStatusCode } from "@bitwarden/common/enums";
|
import { HttpStatusCode } from "@bitwarden/common/enums";
|
||||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -45,7 +45,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
private orgDomainApiService: OrgDomainApiServiceAbstraction,
|
private orgDomainApiService: OrgDomainApiServiceAbstraction,
|
||||||
private validationService: ValidationService,
|
private validationService: ValidationService,
|
||||||
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
ssoLoginService,
|
ssoLoginService,
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -49,7 +49,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
ssoLoginService: SsoLoginServiceAbstraction,
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
@Inject(WINDOW) protected win: Window,
|
@Inject(WINDOW) protected win: Window,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
|
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
|
||||||
import { BitPayInvoiceRequest } from "@bitwarden/common/billing/models/request/bit-pay-invoice.request";
|
import { BitPayInvoiceRequest } from "@bitwarden/common/billing/models/request/bit-pay-invoice.request";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
|
@ -57,7 +57,7 @@ export class AddCreditComponent implements OnInit {
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
const payPalConfig = process.env.PAYPAL_CONFIG as PayPalConfig;
|
const payPalConfig = process.env.PAYPAL_CONFIG as PayPalConfig;
|
||||||
this.ppButtonFormAction = payPalConfig.buttonAction;
|
this.ppButtonFormAction = payPalConfig.buttonAction;
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/pla
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
|
||||||
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
|
||||||
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
|
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
|
||||||
import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service";
|
import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service";
|
||||||
|
@ -28,7 +27,6 @@ export class InitService {
|
||||||
private cryptoService: CryptoServiceAbstraction,
|
private cryptoService: CryptoServiceAbstraction,
|
||||||
private themingService: AbstractThemingService,
|
private themingService: AbstractThemingService,
|
||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
private configService: ConfigService,
|
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ -46,8 +44,6 @@ export class InitService {
|
||||||
this.themingService.applyThemeChangesTo(this.document);
|
this.themingService.applyThemeChangesTo(this.document);
|
||||||
const containerService = new ContainerService(this.cryptoService, this.encryptService);
|
const containerService = new ContainerService(this.cryptoService, this.encryptService);
|
||||||
containerService.attachToGlobal(this.win);
|
containerService.attachToGlobal(this.win);
|
||||||
|
|
||||||
this.configService.init();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction as ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||||
import { IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
import { IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||||
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
@ -107,7 +107,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private organizationUserService: OrganizationUserService,
|
private organizationUserService: OrganizationUserService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private changeDetectorRef: ChangeDetectorRef,
|
private changeDetectorRef: ChangeDetectorRef,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||||
import { AvatarService } from "@bitwarden/common/auth/abstractions/avatar.service";
|
import { AvatarService } from "@bitwarden/common/auth/abstractions/avatar.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||||
|
@ -92,7 +92,7 @@ export default {
|
||||||
} as Partial<TokenService>,
|
} as Partial<TokenService>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: ConfigServiceAbstraction,
|
provide: ConfigService,
|
||||||
useValue: {
|
useValue: {
|
||||||
getFeatureFlag() {
|
getFeatureFlag() {
|
||||||
// does not currently affect any display logic, default all to OFF
|
// does not currently affect any display logic, default all to OFF
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EventType, ProductType } from "@bitwarden/common/enums";
|
import { EventType, ProductType } from "@bitwarden/common/enums";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -65,7 +65,7 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On
|
||||||
sendApiService: SendApiService,
|
sendApiService: SendApiService,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
datePipe: DatePipe,
|
datePipe: DatePipe,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { Subject, of } from "rxjs";
|
||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { StateProvider } from "@bitwarden/common/platform/state";
|
import { StateProvider } from "@bitwarden/common/platform/state";
|
||||||
|
@ -21,7 +21,7 @@ describe("VaultOnboardingComponent", () => {
|
||||||
let mockApiService: Partial<ApiService>;
|
let mockApiService: Partial<ApiService>;
|
||||||
let mockPolicyService: MockProxy<PolicyService>;
|
let mockPolicyService: MockProxy<PolicyService>;
|
||||||
let mockI18nService: MockProxy<I18nService>;
|
let mockI18nService: MockProxy<I18nService>;
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigService>;
|
||||||
let mockVaultOnboardingService: MockProxy<VaultOnboardingServiceAbstraction>;
|
let mockVaultOnboardingService: MockProxy<VaultOnboardingServiceAbstraction>;
|
||||||
let mockStateProvider: Partial<StateProvider>;
|
let mockStateProvider: Partial<StateProvider>;
|
||||||
let setInstallExtLinkSpy: any;
|
let setInstallExtLinkSpy: any;
|
||||||
|
@ -34,7 +34,7 @@ describe("VaultOnboardingComponent", () => {
|
||||||
mockApiService = {
|
mockApiService = {
|
||||||
getProfile: jest.fn(),
|
getProfile: jest.fn(),
|
||||||
};
|
};
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock<ConfigService>();
|
||||||
mockVaultOnboardingService = mock<VaultOnboardingServiceAbstraction>();
|
mockVaultOnboardingService = mock<VaultOnboardingServiceAbstraction>();
|
||||||
mockStateProvider = {
|
mockStateProvider = {
|
||||||
getActive: jest.fn().mockReturnValue(
|
getActive: jest.fn().mockReturnValue(
|
||||||
|
@ -56,7 +56,7 @@ describe("VaultOnboardingComponent", () => {
|
||||||
{ provide: VaultOnboardingServiceAbstraction, useValue: mockVaultOnboardingService },
|
{ provide: VaultOnboardingServiceAbstraction, useValue: mockVaultOnboardingService },
|
||||||
{ provide: I18nService, useValue: mockI18nService },
|
{ provide: I18nService, useValue: mockI18nService },
|
||||||
{ provide: ApiService, useValue: mockApiService },
|
{ provide: ApiService, useValue: mockApiService },
|
||||||
{ provide: ConfigServiceAbstraction, useValue: mockConfigService },
|
{ provide: ConfigService, useValue: mockConfigService },
|
||||||
{ provide: StateProvider, useValue: mockStateProvider },
|
{ provide: StateProvider, useValue: mockStateProvider },
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { VaultOnboardingMessages } from "@bitwarden/common/vault/enums/vault-onboarding.enum";
|
import { VaultOnboardingMessages } from "@bitwarden/common/vault/enums/vault-onboarding.enum";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
@ -55,7 +55,7 @@ export class VaultOnboardingComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
protected platformUtilsService: PlatformUtilsService,
|
protected platformUtilsService: PlatformUtilsService,
|
||||||
protected policyService: PolicyService,
|
protected policyService: PolicyService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private vaultOnboardingService: VaultOnboardingServiceAbstraction,
|
private vaultOnboardingService: VaultOnboardingServiceAbstraction,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
|
||||||
import { EventType } from "@bitwarden/common/enums";
|
import { EventType } from "@bitwarden/common/enums";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -180,7 +180,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||||
private eventCollectionService: EventCollectionService,
|
private eventCollectionService: EventCollectionService,
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
private searchPipe: SearchPipe,
|
private searchPipe: SearchPipe,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -54,7 +54,7 @@ export class AddEditComponent extends BaseAddEditComponent {
|
||||||
sendApiService: SendApiService,
|
sendApiService: SendApiService,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
datePipe: DatePipe,
|
datePipe: DatePipe,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
billingAccountProfileStateService: BillingAccountProfileStateService,
|
billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Subject } from "rxjs";
|
||||||
|
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||||
|
@ -65,7 +65,7 @@ export class BulkCollectionAssignmentDialogComponent implements OnDestroy, OnIni
|
||||||
private cipherService: CipherService,
|
private cipherService: CipherService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||||
import { EventType } from "@bitwarden/common/enums";
|
import { EventType } from "@bitwarden/common/enums";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -184,7 +184,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||||
private totpService: TotpService,
|
private totpService: TotpService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||||
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
|
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction as ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
import { IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
||||||
import { ProviderPortalLogo } from "@bitwarden/web-vault/app/admin-console/icons/provider-portal-logo";
|
import { ProviderPortalLogo } from "@bitwarden/web-vault/app/admin-console/icons/provider-portal-logo";
|
||||||
import { PaymentMethodWarningsModule } from "@bitwarden/web-vault/app/billing/shared";
|
import { PaymentMethodWarningsModule } from "@bitwarden/web-vault/app/billing/shared";
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { first } from "rxjs/operators";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { ProviderSetupRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-setup.request";
|
import { ProviderSetupRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-setup.request";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction as ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { SsoConfigApi } from "@bitwarden/common/auth/models/api/sso-config.api";
|
||||||
import { OrganizationSsoRequest } from "@bitwarden/common/auth/models/request/organization-sso.request";
|
import { OrganizationSsoRequest } from "@bitwarden/common/auth/models/request/organization-sso.request";
|
||||||
import { OrganizationSsoResponse } from "@bitwarden/common/auth/models/response/organization-sso.response";
|
import { OrganizationSsoResponse } from "@bitwarden/common/auth/models/response/organization-sso.response";
|
||||||
import { SsoConfigView } from "@bitwarden/common/auth/models/view/sso-config.view";
|
import { SsoConfigView } from "@bitwarden/common/auth/models/view/sso-config.view";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
@ -186,7 +186,7 @@ export class SsoComponent implements OnInit, OnDestroy {
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -66,7 +66,7 @@ describe("SsoComponent", () => {
|
||||||
let mockPasswordGenerationService: MockProxy<PasswordGenerationServiceAbstraction>;
|
let mockPasswordGenerationService: MockProxy<PasswordGenerationServiceAbstraction>;
|
||||||
let mockLogService: MockProxy<LogService>;
|
let mockLogService: MockProxy<LogService>;
|
||||||
let mockUserDecryptionOptionsService: MockProxy<UserDecryptionOptionsServiceAbstraction>;
|
let mockUserDecryptionOptionsService: MockProxy<UserDecryptionOptionsServiceAbstraction>;
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigService>;
|
||||||
|
|
||||||
// Mock authService.logIn params
|
// Mock authService.logIn params
|
||||||
let code: string;
|
let code: string;
|
||||||
|
@ -107,16 +107,16 @@ describe("SsoComponent", () => {
|
||||||
queryParams: mockQueryParams,
|
queryParams: mockQueryParams,
|
||||||
} as any as ActivatedRoute;
|
} as any as ActivatedRoute;
|
||||||
|
|
||||||
mockSsoLoginService = mock<SsoLoginServiceAbstraction>();
|
mockSsoLoginService = mock();
|
||||||
mockStateService = mock<StateService>();
|
mockStateService = mock();
|
||||||
mockPlatformUtilsService = mock<PlatformUtilsService>();
|
mockPlatformUtilsService = mock();
|
||||||
mockApiService = mock<ApiService>();
|
mockApiService = mock();
|
||||||
mockCryptoFunctionService = mock<CryptoFunctionService>();
|
mockCryptoFunctionService = mock();
|
||||||
mockEnvironmentService = mock<EnvironmentService>();
|
mockEnvironmentService = mock();
|
||||||
mockPasswordGenerationService = mock<PasswordGenerationServiceAbstraction>();
|
mockPasswordGenerationService = mock();
|
||||||
mockLogService = mock<LogService>();
|
mockLogService = mock();
|
||||||
mockUserDecryptionOptionsService = mock<UserDecryptionOptionsServiceAbstraction>();
|
mockUserDecryptionOptionsService = mock();
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock();
|
||||||
|
|
||||||
// Mock loginStrategyService.logIn params
|
// Mock loginStrategyService.logIn params
|
||||||
code = "code";
|
code = "code";
|
||||||
|
@ -198,7 +198,7 @@ describe("SsoComponent", () => {
|
||||||
useValue: mockUserDecryptionOptionsService,
|
useValue: mockUserDecryptionOptionsService,
|
||||||
},
|
},
|
||||||
{ provide: LogService, useValue: mockLogService },
|
{ provide: LogService, useValue: mockLogService },
|
||||||
{ provide: ConfigServiceAbstraction, useValue: mockConfigService },
|
{ provide: ConfigService, useValue: mockConfigService },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { SsoPreValidateResponse } from "@bitwarden/common/auth/models/response/sso-pre-validate.response";
|
import { SsoPreValidateResponse } from "@bitwarden/common/auth/models/response/sso-pre-validate.response";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -65,7 +65,7 @@ export class SsoComponent {
|
||||||
protected passwordGenerationService: PasswordGenerationServiceAbstraction,
|
protected passwordGenerationService: PasswordGenerationServiceAbstraction,
|
||||||
protected logService: LogService,
|
protected logService: LogService,
|
||||||
protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -62,7 +62,7 @@ describe("TwoFactorComponent", () => {
|
||||||
let mockLoginService: MockProxy<LoginService>;
|
let mockLoginService: MockProxy<LoginService>;
|
||||||
let mockUserDecryptionOptionsService: MockProxy<UserDecryptionOptionsServiceAbstraction>;
|
let mockUserDecryptionOptionsService: MockProxy<UserDecryptionOptionsServiceAbstraction>;
|
||||||
let mockSsoLoginService: MockProxy<SsoLoginServiceAbstraction>;
|
let mockSsoLoginService: MockProxy<SsoLoginServiceAbstraction>;
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigService>;
|
||||||
|
|
||||||
let mockUserDecryptionOpts: {
|
let mockUserDecryptionOpts: {
|
||||||
noMasterPassword: UserDecryptionOptions;
|
noMasterPassword: UserDecryptionOptions;
|
||||||
|
@ -92,7 +92,7 @@ describe("TwoFactorComponent", () => {
|
||||||
mockLoginService = mock<LoginService>();
|
mockLoginService = mock<LoginService>();
|
||||||
mockUserDecryptionOptionsService = mock<UserDecryptionOptionsServiceAbstraction>();
|
mockUserDecryptionOptionsService = mock<UserDecryptionOptionsServiceAbstraction>();
|
||||||
mockSsoLoginService = mock<SsoLoginServiceAbstraction>();
|
mockSsoLoginService = mock<SsoLoginServiceAbstraction>();
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock<ConfigService>();
|
||||||
|
|
||||||
mockUserDecryptionOpts = {
|
mockUserDecryptionOpts = {
|
||||||
noMasterPassword: new UserDecryptionOptions({
|
noMasterPassword: new UserDecryptionOptions({
|
||||||
|
@ -169,7 +169,7 @@ describe("TwoFactorComponent", () => {
|
||||||
useValue: mockUserDecryptionOptionsService,
|
useValue: mockUserDecryptionOptionsService,
|
||||||
},
|
},
|
||||||
{ provide: SsoLoginServiceAbstraction, useValue: mockSsoLoginService },
|
{ provide: SsoLoginServiceAbstraction, useValue: mockSsoLoginService },
|
||||||
{ provide: ConfigServiceAbstraction, useValue: mockConfigService },
|
{ provide: ConfigService, useValue: mockConfigService },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two
|
||||||
import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service";
|
import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service";
|
||||||
import { WebAuthnIFrame } from "@bitwarden/common/auth/webauthn-iframe";
|
import { WebAuthnIFrame } from "@bitwarden/common/auth/webauthn-iframe";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
@ -91,7 +91,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
|
||||||
protected loginService: LoginService,
|
protected loginService: LoginService,
|
||||||
protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
protected ssoLoginService: SsoLoginServiceAbstraction,
|
protected ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super(environmentService, i18nService, platformUtilsService);
|
super(environmentService, i18nService, platformUtilsService);
|
||||||
this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win);
|
this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { By } from "@angular/platform-browser";
|
||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
|
|
||||||
import { FeatureFlag, FeatureFlagValue } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag, FeatureFlagValue } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
|
||||||
import { IfFeatureDirective } from "./if-feature.directive";
|
import { IfFeatureDirective } from "./if-feature.directive";
|
||||||
|
@ -39,7 +39,7 @@ class TestComponent {
|
||||||
describe("IfFeatureDirective", () => {
|
describe("IfFeatureDirective", () => {
|
||||||
let fixture: ComponentFixture<TestComponent>;
|
let fixture: ComponentFixture<TestComponent>;
|
||||||
let content: HTMLElement;
|
let content: HTMLElement;
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigService>;
|
||||||
|
|
||||||
const mockConfigFlagValue = (flag: FeatureFlag, flagValue: FeatureFlagValue) => {
|
const mockConfigFlagValue = (flag: FeatureFlag, flagValue: FeatureFlagValue) => {
|
||||||
mockConfigService.getFeatureFlag.mockImplementation((f, defaultValue) =>
|
mockConfigService.getFeatureFlag.mockImplementation((f, defaultValue) =>
|
||||||
|
@ -51,14 +51,14 @@ describe("IfFeatureDirective", () => {
|
||||||
fixture.debugElement.query(By.css(`[data-testid="${testId}"]`))?.nativeElement;
|
fixture.debugElement.query(By.css(`[data-testid="${testId}"]`))?.nativeElement;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock<ConfigService>();
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [IfFeatureDirective, TestComponent],
|
declarations: [IfFeatureDirective, TestComponent],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: LogService, useValue: mock<LogService>() },
|
{ provide: LogService, useValue: mock<LogService>() },
|
||||||
{
|
{
|
||||||
provide: ConfigServiceAbstraction,
|
provide: ConfigService,
|
||||||
useValue: mockConfigService,
|
useValue: mockConfigService,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from "@angular/core";
|
import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from "@angular/core";
|
||||||
|
|
||||||
import { FeatureFlag, FeatureFlagValue } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag, FeatureFlagValue } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ export class IfFeatureDirective implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private templateRef: TemplateRef<any>,
|
private templateRef: TemplateRef<any>,
|
||||||
private viewContainer: ViewContainerRef,
|
private viewContainer: ViewContainerRef,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { RouterTestingModule } from "@angular/router/testing";
|
||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
|
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
|
@ -21,11 +21,11 @@ describe("canAccessFeature", () => {
|
||||||
const featureRoute = "enabled-feature";
|
const featureRoute = "enabled-feature";
|
||||||
const redirectRoute = "redirect";
|
const redirectRoute = "redirect";
|
||||||
|
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigService>;
|
||||||
let mockPlatformUtilsService: MockProxy<PlatformUtilsService>;
|
let mockPlatformUtilsService: MockProxy<PlatformUtilsService>;
|
||||||
|
|
||||||
const setup = (featureGuard: CanActivateFn, flagValue: any) => {
|
const setup = (featureGuard: CanActivateFn, flagValue: any) => {
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock<ConfigService>();
|
||||||
mockPlatformUtilsService = mock<PlatformUtilsService>();
|
mockPlatformUtilsService = mock<PlatformUtilsService>();
|
||||||
|
|
||||||
// Mock the correct getter based on the type of flagValue; also mock default values if one is not provided
|
// Mock the correct getter based on the type of flagValue; also mock default values if one is not provided
|
||||||
|
@ -56,7 +56,7 @@ describe("canAccessFeature", () => {
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: ConfigServiceAbstraction, useValue: mockConfigService },
|
{ provide: ConfigService, useValue: mockConfigService },
|
||||||
{ provide: PlatformUtilsService, useValue: mockPlatformUtilsService },
|
{ provide: PlatformUtilsService, useValue: mockPlatformUtilsService },
|
||||||
{ provide: LogService, useValue: mock<LogService>() },
|
{ provide: LogService, useValue: mock<LogService>() },
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { inject } from "@angular/core";
|
||||||
import { CanActivateFn, Router } from "@angular/router";
|
import { CanActivateFn, Router } from "@angular/router";
|
||||||
|
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
|
@ -23,7 +23,7 @@ export const canAccessFeature = (
|
||||||
redirectUrlOnDisabled?: string,
|
redirectUrlOnDisabled?: string,
|
||||||
): CanActivateFn => {
|
): CanActivateFn => {
|
||||||
return async () => {
|
return async () => {
|
||||||
const configService = inject(ConfigServiceAbstraction);
|
const configService = inject(ConfigService);
|
||||||
const platformUtilsService = inject(PlatformUtilsService);
|
const platformUtilsService = inject(PlatformUtilsService);
|
||||||
const router = inject(Router);
|
const router = inject(Router);
|
||||||
const i18nService = inject(I18nService);
|
const i18nService = inject(I18nService);
|
||||||
|
|
|
@ -111,7 +111,7 @@ import { PaymentMethodWarningsService } from "@bitwarden/common/billing/services
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||||
|
@ -135,7 +135,7 @@ import { Account } from "@bitwarden/common/platform/models/domain/account";
|
||||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/services/app-id.service";
|
||||||
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/services/config/config.service";
|
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
|
||||||
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
|
||||||
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
|
||||||
|
@ -400,7 +400,7 @@ const typesafeProviders: Array<SafeProvider> = [
|
||||||
autofillSettingsService: AutofillSettingsServiceAbstraction,
|
autofillSettingsService: AutofillSettingsServiceAbstraction,
|
||||||
encryptService: EncryptService,
|
encryptService: EncryptService,
|
||||||
fileUploadService: CipherFileUploadServiceAbstraction,
|
fileUploadService: CipherFileUploadServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigService,
|
||||||
) =>
|
) =>
|
||||||
new CipherService(
|
new CipherService(
|
||||||
cryptoService,
|
cryptoService,
|
||||||
|
@ -424,7 +424,7 @@ const typesafeProviders: Array<SafeProvider> = [
|
||||||
AutofillSettingsServiceAbstraction,
|
AutofillSettingsServiceAbstraction,
|
||||||
EncryptService,
|
EncryptService,
|
||||||
CipherFileUploadServiceAbstraction,
|
CipherFileUploadServiceAbstraction,
|
||||||
ConfigServiceAbstraction,
|
ConfigService,
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
|
@ -851,25 +851,18 @@ const typesafeProviders: Array<SafeProvider> = [
|
||||||
deps: [],
|
deps: [],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: ConfigService,
|
provide: DefaultConfigService,
|
||||||
useClass: ConfigService,
|
useClass: DefaultConfigService,
|
||||||
deps: [
|
deps: [ConfigApiServiceAbstraction, EnvironmentService, LogService, StateProvider],
|
||||||
StateServiceAbstraction,
|
|
||||||
ConfigApiServiceAbstraction,
|
|
||||||
AuthServiceAbstraction,
|
|
||||||
EnvironmentService,
|
|
||||||
LogService,
|
|
||||||
StateProvider,
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: ConfigServiceAbstraction,
|
provide: ConfigService,
|
||||||
useExisting: ConfigService,
|
useExisting: DefaultConfigService,
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: ConfigApiServiceAbstraction,
|
provide: ConfigApiServiceAbstraction,
|
||||||
useClass: ConfigApiService,
|
useClass: ConfigApiService,
|
||||||
deps: [ApiServiceAbstraction, AuthServiceAbstraction],
|
deps: [ApiServiceAbstraction, TokenServiceAbstraction],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: AnonymousHubServiceAbstraction,
|
provide: AnonymousHubServiceAbstraction,
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga
|
||||||
import { EventType } from "@bitwarden/common/enums";
|
import { EventType } from "@bitwarden/common/enums";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service";
|
import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -119,7 +119,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
||||||
protected dialogService: DialogService,
|
protected dialogService: DialogService,
|
||||||
protected win: Window,
|
protected win: Window,
|
||||||
protected datePipe: DatePipe,
|
protected datePipe: DatePipe,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
this.typeOptions = [
|
this.typeOptions = [
|
||||||
{ name: i18nService.t("typeLogin"), value: CipherType.Login },
|
{ name: i18nService.t("typeLogin"), value: CipherType.Login },
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
describe("toAlmostEqual custom matcher", () => {
|
||||||
|
it("matches identical Dates", () => {
|
||||||
|
const date = new Date();
|
||||||
|
expect(date).toAlmostEqual(date);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches when older but within default ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() - 5);
|
||||||
|
expect(date).toAlmostEqual(olderDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches when newer but within default ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() + 5);
|
||||||
|
expect(date).toAlmostEqual(olderDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't match if older than default ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() - 11);
|
||||||
|
expect(date).not.toAlmostEqual(olderDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't match if newer than default ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() + 11);
|
||||||
|
expect(date).not.toAlmostEqual(olderDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches when older but within custom ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() - 15);
|
||||||
|
expect(date).toAlmostEqual(olderDate, 20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches when newer but within custom ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() + 15);
|
||||||
|
expect(date).toAlmostEqual(olderDate, 20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't match if older than custom ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() - 21);
|
||||||
|
expect(date).not.toAlmostEqual(olderDate, 20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't match if newer than custom ms", () => {
|
||||||
|
const date = new Date();
|
||||||
|
const olderDate = new Date(date.getTime() + 21);
|
||||||
|
expect(date).not.toAlmostEqual(olderDate, 20);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
* Matches the expected date within an optional ms precision
|
||||||
|
* @param received The received date
|
||||||
|
* @param expected The expected date
|
||||||
|
* @param msPrecision The optional precision in milliseconds
|
||||||
|
*/
|
||||||
|
export const toAlmostEqual: jest.CustomMatcher = function (
|
||||||
|
received: Date,
|
||||||
|
expected: Date,
|
||||||
|
msPrecision: number = 10,
|
||||||
|
) {
|
||||||
|
const receivedTime = received.getTime();
|
||||||
|
const expectedTime = expected.getTime();
|
||||||
|
const difference = Math.abs(receivedTime - expectedTime);
|
||||||
|
return {
|
||||||
|
pass: difference <= msPrecision,
|
||||||
|
message: () =>
|
||||||
|
`expected ${received} to be within ${msPrecision}ms of ${expected} (actual difference: ${difference}ms)`,
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,86 @@
|
||||||
|
import { Observable, Subscription, firstValueFrom, throwError, timeout } from "rxjs";
|
||||||
|
|
||||||
|
/** Test class to enable async awaiting of observable emissions */
|
||||||
|
export class ObservableTracker<T> {
|
||||||
|
private subscription: Subscription;
|
||||||
|
emissions: T[] = [];
|
||||||
|
constructor(private observable: Observable<T>) {
|
||||||
|
this.emissions = this.trackEmissions(observable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unsubscribes from the observable */
|
||||||
|
unsubscribe() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Awaits the next emission from the observable, or throws if the timeout is exceeded
|
||||||
|
* @param msTimeout The maximum time to wait for another emission before throwing
|
||||||
|
*/
|
||||||
|
async expectEmission(msTimeout = 50) {
|
||||||
|
await firstValueFrom(
|
||||||
|
this.observable.pipe(
|
||||||
|
timeout({
|
||||||
|
first: msTimeout,
|
||||||
|
with: () => throwError(() => new Error("Timeout exceeded waiting for another emission.")),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Awaits until the the total number of emissions observed by this tracker equals or exceeds {@link count}
|
||||||
|
* @param count The number of emissions to wait for
|
||||||
|
*/
|
||||||
|
async pauseUntilReceived(count: number, msTimeout = 50): Promise<T[]> {
|
||||||
|
for (let i = 0; i < count - this.emissions.length; i++) {
|
||||||
|
await this.expectEmission(msTimeout);
|
||||||
|
}
|
||||||
|
return this.emissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private trackEmissions<T>(observable: Observable<T>): T[] {
|
||||||
|
const emissions: T[] = [];
|
||||||
|
this.subscription = observable.subscribe((value) => {
|
||||||
|
switch (value) {
|
||||||
|
case undefined:
|
||||||
|
case null:
|
||||||
|
emissions.push(value);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
// process by type
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
case "number":
|
||||||
|
case "boolean":
|
||||||
|
emissions.push(value);
|
||||||
|
break;
|
||||||
|
case "symbol":
|
||||||
|
// Cheating types to make symbols work at all
|
||||||
|
emissions.push(value.toString() as T);
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
emissions.push(clone(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return emissions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function clone(value: any): any {
|
||||||
|
if (global.structuredClone != undefined) {
|
||||||
|
return structuredClone(value);
|
||||||
|
} else {
|
||||||
|
return JSON.parse(JSON.stringify(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A test helper that builds an @see{@link ObservableTracker}, which can be used to assert things about the
|
||||||
|
* emissions of the given observable
|
||||||
|
* @param observable The observable to track
|
||||||
|
*/
|
||||||
|
export function subscribeTo<T>(observable: Observable<T>) {
|
||||||
|
return new ObservableTracker(observable);
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
|
import { UserId } from "../../../types/guid";
|
||||||
import { ServerConfigResponse } from "../../models/response/server-config.response";
|
import { ServerConfigResponse } from "../../models/response/server-config.response";
|
||||||
|
|
||||||
export abstract class ConfigApiServiceAbstraction {
|
export abstract class ConfigApiServiceAbstraction {
|
||||||
get: () => Promise<ServerConfigResponse>;
|
/**
|
||||||
|
* Fetches the server configuration for the given user. If no user is provided, the configuration will not contain user-specific context.
|
||||||
|
*/
|
||||||
|
get: (userId: UserId | undefined) => Promise<ServerConfigResponse>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
import { Observable } from "rxjs";
|
|
||||||
import { SemVer } from "semver";
|
|
||||||
|
|
||||||
import { FeatureFlag } from "../../../enums/feature-flag.enum";
|
|
||||||
import { Region } from "../environment.service";
|
|
||||||
|
|
||||||
import { ServerConfig } from "./server-config";
|
|
||||||
|
|
||||||
export abstract class ConfigServiceAbstraction {
|
|
||||||
serverConfig$: Observable<ServerConfig | null>;
|
|
||||||
cloudRegion$: Observable<Region>;
|
|
||||||
getFeatureFlag$: <T extends boolean | number | string>(
|
|
||||||
key: FeatureFlag,
|
|
||||||
defaultValue?: T,
|
|
||||||
) => Observable<T>;
|
|
||||||
getFeatureFlag: <T extends boolean | number | string>(
|
|
||||||
key: FeatureFlag,
|
|
||||||
defaultValue?: T,
|
|
||||||
) => Promise<T>;
|
|
||||||
checkServerMeetsVersionRequirement$: (
|
|
||||||
minimumRequiredServerVersion: SemVer,
|
|
||||||
) => Observable<boolean>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Force ConfigService to fetch an updated config from the server and emit it from serverConfig$
|
|
||||||
* @deprecated The service implementation should subscribe to an observable and use that to trigger a new fetch from
|
|
||||||
* server instead
|
|
||||||
*/
|
|
||||||
triggerServerConfigFetch: () => void;
|
|
||||||
}
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
import { SemVer } from "semver";
|
||||||
|
|
||||||
|
import { FeatureFlag } from "../../../enums/feature-flag.enum";
|
||||||
|
import { Region } from "../environment.service";
|
||||||
|
|
||||||
|
import { ServerConfig } from "./server-config";
|
||||||
|
|
||||||
|
export abstract class ConfigService {
|
||||||
|
/** The server config of the currently active user */
|
||||||
|
serverConfig$: Observable<ServerConfig | null>;
|
||||||
|
/** The cloud region of the currently active user */
|
||||||
|
cloudRegion$: Observable<Region>;
|
||||||
|
/**
|
||||||
|
* Retrieves the value of a feature flag for the currently active user
|
||||||
|
* @param key The feature flag to retrieve
|
||||||
|
* @param defaultValue The default value to return if the feature flag is not set or the server's config is irretrievable
|
||||||
|
* @returns An observable that emits the value of the feature flag, updates as the server config changes
|
||||||
|
*/
|
||||||
|
getFeatureFlag$: <T extends boolean | number | string>(
|
||||||
|
key: FeatureFlag,
|
||||||
|
defaultValue?: T,
|
||||||
|
) => Observable<T>;
|
||||||
|
/**
|
||||||
|
* Retrieves the value of a feature flag for the currently active user
|
||||||
|
* @param key The feature flag to retrieve
|
||||||
|
* @param defaultValue The default value to return if the feature flag is not set or the server's config is irretrievable
|
||||||
|
* @returns The value of the feature flag
|
||||||
|
*/
|
||||||
|
getFeatureFlag: <T extends boolean | number | string>(
|
||||||
|
key: FeatureFlag,
|
||||||
|
defaultValue?: T,
|
||||||
|
) => Promise<T>;
|
||||||
|
/**
|
||||||
|
* Verifies whether the server version meets the minimum required version
|
||||||
|
* @param minimumRequiredServerVersion The minimum version required
|
||||||
|
* @returns True if the server version is greater than or equal to the minimum required version
|
||||||
|
*/
|
||||||
|
checkServerMeetsVersionRequirement$: (
|
||||||
|
minimumRequiredServerVersion: SemVer,
|
||||||
|
) => Observable<boolean>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers a check that the config for the currently active user is up-to-date. If it is not, it will be fetched from the server and stored.
|
||||||
|
*/
|
||||||
|
abstract ensureConfigFetched(): Promise<void>;
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ import {
|
||||||
} from "../../models/data/server-config.data";
|
} from "../../models/data/server-config.data";
|
||||||
|
|
||||||
const dayInMilliseconds = 24 * 3600 * 1000;
|
const dayInMilliseconds = 24 * 3600 * 1000;
|
||||||
const eighteenHoursInMilliseconds = 18 * 3600 * 1000;
|
|
||||||
|
|
||||||
export class ServerConfig {
|
export class ServerConfig {
|
||||||
version: string;
|
version: string;
|
||||||
|
@ -38,10 +37,6 @@ export class ServerConfig {
|
||||||
return this.getAgeInMilliseconds() <= dayInMilliseconds;
|
return this.getAgeInMilliseconds() <= dayInMilliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
expiresSoon(): boolean {
|
|
||||||
return this.getAgeInMilliseconds() >= eighteenHoursInMilliseconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromJSON(obj: Jsonify<ServerConfig>): ServerConfig {
|
static fromJSON(obj: Jsonify<ServerConfig>): ServerConfig {
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { LocalData } from "../../vault/models/data/local.data";
|
||||||
import { CipherView } from "../../vault/models/view/cipher.view";
|
import { CipherView } from "../../vault/models/view/cipher.view";
|
||||||
import { AddEditCipherInfo } from "../../vault/types/add-edit-cipher-info";
|
import { AddEditCipherInfo } from "../../vault/types/add-edit-cipher-info";
|
||||||
import { KdfType } from "../enums";
|
import { KdfType } from "../enums";
|
||||||
import { ServerConfigData } from "../models/data/server-config.data";
|
|
||||||
import { Account } from "../models/domain/account";
|
import { Account } from "../models/domain/account";
|
||||||
import { EncString } from "../models/domain/enc-string";
|
import { EncString } from "../models/domain/enc-string";
|
||||||
import { StorageOptions } from "../models/domain/storage-options";
|
import { StorageOptions } from "../models/domain/storage-options";
|
||||||
|
@ -278,14 +277,6 @@ export abstract class StateService<T extends Account = Account> {
|
||||||
setVaultTimeoutAction: (value: string, options?: StorageOptions) => Promise<void>;
|
setVaultTimeoutAction: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
getApproveLoginRequests: (options?: StorageOptions) => Promise<boolean>;
|
getApproveLoginRequests: (options?: StorageOptions) => Promise<boolean>;
|
||||||
setApproveLoginRequests: (value: boolean, options?: StorageOptions) => Promise<void>;
|
setApproveLoginRequests: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
/**
|
|
||||||
* @deprecated Do not call this directly, use ConfigService
|
|
||||||
*/
|
|
||||||
getServerConfig: (options?: StorageOptions) => Promise<ServerConfigData>;
|
|
||||||
/**
|
|
||||||
* @deprecated Do not call this directly, use ConfigService
|
|
||||||
*/
|
|
||||||
setServerConfig: (value: ServerConfigData, options?: StorageOptions) => Promise<void>;
|
|
||||||
/**
|
/**
|
||||||
* fetches string value of URL user tried to navigate to while unauthenticated.
|
* fetches string value of URL user tried to navigate to while unauthenticated.
|
||||||
* @param options Defines the storage options for the URL; Defaults to session Storage.
|
* @param options Defines the storage options for the URL; Defaults to session Storage.
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { CipherView } from "../../../vault/models/view/cipher.view";
|
||||||
import { AddEditCipherInfo } from "../../../vault/types/add-edit-cipher-info";
|
import { AddEditCipherInfo } from "../../../vault/types/add-edit-cipher-info";
|
||||||
import { KdfType } from "../../enums";
|
import { KdfType } from "../../enums";
|
||||||
import { Utils } from "../../misc/utils";
|
import { Utils } from "../../misc/utils";
|
||||||
import { ServerConfigData } from "../../models/data/server-config.data";
|
|
||||||
|
|
||||||
import { EncryptedString, EncString } from "./enc-string";
|
import { EncryptedString, EncString } from "./enc-string";
|
||||||
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
|
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
|
||||||
|
@ -196,7 +195,6 @@ export class AccountSettings {
|
||||||
protectedPin?: string;
|
protectedPin?: string;
|
||||||
vaultTimeout?: number;
|
vaultTimeout?: number;
|
||||||
vaultTimeoutAction?: string = "lock";
|
vaultTimeoutAction?: string = "lock";
|
||||||
serverConfig?: ServerConfigData;
|
|
||||||
approveLoginRequests?: boolean;
|
approveLoginRequests?: boolean;
|
||||||
avatarColor?: string;
|
avatarColor?: string;
|
||||||
trustDeviceChoiceForDecryption?: boolean;
|
trustDeviceChoiceForDecryption?: boolean;
|
||||||
|
@ -214,7 +212,6 @@ export class AccountSettings {
|
||||||
obj?.pinProtected,
|
obj?.pinProtected,
|
||||||
EncString.fromJSON,
|
EncString.fromJSON,
|
||||||
),
|
),
|
||||||
serverConfig: ServerConfigData.fromJSON(obj?.serverConfig),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
import { ApiService } from "../../../abstractions/api.service";
|
import { ApiService } from "../../../abstractions/api.service";
|
||||||
import { AuthService } from "../../../auth/abstractions/auth.service";
|
import { TokenService } from "../../../auth/abstractions/token.service";
|
||||||
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
import { UserId } from "../../../types/guid";
|
||||||
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
||||||
import { ServerConfigResponse } from "../../models/response/server-config.response";
|
import { ServerConfigResponse } from "../../models/response/server-config.response";
|
||||||
|
|
||||||
export class ConfigApiService implements ConfigApiServiceAbstraction {
|
export class ConfigApiService implements ConfigApiServiceAbstraction {
|
||||||
constructor(
|
constructor(
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private authService: AuthService,
|
private tokenService: TokenService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async get(): Promise<ServerConfigResponse> {
|
async get(userId: UserId | undefined): Promise<ServerConfigResponse> {
|
||||||
|
// Authentication adds extra context to config responses, if the user has an access token, we want to use it
|
||||||
|
// We don't particularly care about ensuring the token is valid and not expired, just that it exists
|
||||||
const authed: boolean =
|
const authed: boolean =
|
||||||
(await this.authService.getAuthStatus()) !== AuthenticationStatus.LoggedOut;
|
userId == null ? false : (await this.tokenService.getAccessToken(userId)) != null;
|
||||||
|
|
||||||
const r = await this.apiService.send("GET", "/config", null, authed, true);
|
const r = await this.apiService.send("GET", "/config", null, authed, true);
|
||||||
return new ServerConfigResponse(r);
|
return new ServerConfigResponse(r);
|
||||||
|
|
|
@ -1,200 +1,264 @@
|
||||||
import { MockProxy, mock } from "jest-mock-extended";
|
/**
|
||||||
import { ReplaySubject, skip, take } from "rxjs";
|
* need to update test environment so structuredClone works appropriately
|
||||||
|
* @jest-environment ../../libs/shared/test.environment.ts
|
||||||
|
*/
|
||||||
|
|
||||||
import { FakeStateProvider, mockAccountServiceWith } from "../../../../spec";
|
import { mock } from "jest-mock-extended";
|
||||||
import { AuthService } from "../../../auth/abstractions/auth.service";
|
import { Subject, firstValueFrom, of } from "rxjs";
|
||||||
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
|
||||||
|
import {
|
||||||
|
FakeGlobalState,
|
||||||
|
FakeSingleUserState,
|
||||||
|
FakeStateProvider,
|
||||||
|
awaitAsync,
|
||||||
|
mockAccountServiceWith,
|
||||||
|
} from "../../../../spec";
|
||||||
|
import { subscribeTo } from "../../../../spec/observable-tracker";
|
||||||
import { UserId } from "../../../types/guid";
|
import { UserId } from "../../../types/guid";
|
||||||
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
||||||
import { ServerConfig } from "../../abstractions/config/server-config";
|
import { ServerConfig } from "../../abstractions/config/server-config";
|
||||||
import { Environment, EnvironmentService } from "../../abstractions/environment.service";
|
import { Environment, EnvironmentService } from "../../abstractions/environment.service";
|
||||||
import { LogService } from "../../abstractions/log.service";
|
import { LogService } from "../../abstractions/log.service";
|
||||||
import { StateService } from "../../abstractions/state.service";
|
import { Utils } from "../../misc/utils";
|
||||||
import { ServerConfigData } from "../../models/data/server-config.data";
|
import { ServerConfigData } from "../../models/data/server-config.data";
|
||||||
import {
|
import {
|
||||||
EnvironmentServerConfigResponse,
|
EnvironmentServerConfigResponse,
|
||||||
ServerConfigResponse,
|
ServerConfigResponse,
|
||||||
ThirdPartyServerConfigResponse,
|
ThirdPartyServerConfigResponse,
|
||||||
} from "../../models/response/server-config.response";
|
} from "../../models/response/server-config.response";
|
||||||
import { StateProvider } from "../../state";
|
|
||||||
|
|
||||||
import { ConfigService } from "./config.service";
|
import {
|
||||||
|
ApiUrl,
|
||||||
|
DefaultConfigService,
|
||||||
|
RETRIEVAL_INTERVAL,
|
||||||
|
GLOBAL_SERVER_CONFIGURATIONS,
|
||||||
|
USER_SERVER_CONFIG,
|
||||||
|
} from "./default-config.service";
|
||||||
|
|
||||||
describe("ConfigService", () => {
|
describe("ConfigService", () => {
|
||||||
let stateService: MockProxy<StateService>;
|
const configApiService = mock<ConfigApiServiceAbstraction>();
|
||||||
let configApiService: MockProxy<ConfigApiServiceAbstraction>;
|
const environmentService = mock<EnvironmentService>();
|
||||||
let authService: MockProxy<AuthService>;
|
const logService = mock<LogService>();
|
||||||
let environmentService: MockProxy<EnvironmentService>;
|
let stateProvider: FakeStateProvider;
|
||||||
let logService: MockProxy<LogService>;
|
let globalState: FakeGlobalState<Record<ApiUrl, ServerConfig>>;
|
||||||
let replaySubject: ReplaySubject<Environment>;
|
let userState: FakeSingleUserState<ServerConfig>;
|
||||||
let stateProvider: StateProvider;
|
const activeApiUrl = apiUrl(0);
|
||||||
|
const userId = "userId" as UserId;
|
||||||
let serverResponseCount: number; // increments to track distinct responses received from server
|
const accountService = mockAccountServiceWith(userId);
|
||||||
|
const tooOld = new Date(Date.now() - 1.1 * RETRIEVAL_INTERVAL);
|
||||||
// Observables will start emitting as soon as this is created, so only create it
|
|
||||||
// after everything is mocked
|
|
||||||
const configServiceFactory = () => {
|
|
||||||
const configService = new ConfigService(
|
|
||||||
stateService,
|
|
||||||
configApiService,
|
|
||||||
authService,
|
|
||||||
environmentService,
|
|
||||||
logService,
|
|
||||||
stateProvider,
|
|
||||||
);
|
|
||||||
configService.init();
|
|
||||||
return configService;
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
stateService = mock();
|
|
||||||
configApiService = mock();
|
|
||||||
authService = mock();
|
|
||||||
environmentService = mock();
|
|
||||||
logService = mock();
|
|
||||||
replaySubject = new ReplaySubject<Environment>(1);
|
|
||||||
const accountService = mockAccountServiceWith("0" as UserId);
|
|
||||||
stateProvider = new FakeStateProvider(accountService);
|
stateProvider = new FakeStateProvider(accountService);
|
||||||
|
globalState = stateProvider.global.getFake(GLOBAL_SERVER_CONFIGURATIONS);
|
||||||
environmentService.environment$ = replaySubject.asObservable();
|
userState = stateProvider.singleUser.getFake(userId, USER_SERVER_CONFIG);
|
||||||
|
|
||||||
serverResponseCount = 1;
|
|
||||||
configApiService.get.mockImplementation(() =>
|
|
||||||
Promise.resolve(serverConfigResponseFactory("server" + serverResponseCount++)),
|
|
||||||
);
|
|
||||||
|
|
||||||
jest.useFakeTimers();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.useRealTimers();
|
jest.resetAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Uses storage as fallback", (done) => {
|
describe.each([null, userId])("active user: %s", (activeUserId) => {
|
||||||
const storedConfigData = serverConfigDataFactory("storedConfig");
|
let sut: DefaultConfigService;
|
||||||
stateService.getServerConfig.mockResolvedValueOnce(storedConfigData);
|
|
||||||
|
|
||||||
configApiService.get.mockRejectedValueOnce(new Error("Unable to fetch"));
|
beforeAll(async () => {
|
||||||
|
await accountService.switchAccount(activeUserId);
|
||||||
const configService = configServiceFactory();
|
|
||||||
|
|
||||||
configService.serverConfig$.pipe(take(1)).subscribe((config) => {
|
|
||||||
expect(config).toEqual(new ServerConfig(storedConfigData));
|
|
||||||
expect(stateService.getServerConfig).toHaveBeenCalledTimes(1);
|
|
||||||
expect(stateService.setServerConfig).not.toHaveBeenCalled();
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
configService.triggerServerConfigFetch();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Stream does not error out if fetch fails", (done) => {
|
|
||||||
const storedConfigData = serverConfigDataFactory("storedConfig");
|
|
||||||
stateService.getServerConfig.mockResolvedValueOnce(storedConfigData);
|
|
||||||
|
|
||||||
const configService = configServiceFactory();
|
|
||||||
|
|
||||||
configService.serverConfig$.pipe(skip(1), take(1)).subscribe((config) => {
|
|
||||||
try {
|
|
||||||
expect(config.gitHash).toEqual("server1");
|
|
||||||
done();
|
|
||||||
} catch (e) {
|
|
||||||
done(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
configApiService.get.mockRejectedValueOnce(new Error("Unable to fetch"));
|
|
||||||
configService.triggerServerConfigFetch();
|
|
||||||
|
|
||||||
configApiService.get.mockResolvedValueOnce(serverConfigResponseFactory("server1"));
|
|
||||||
configService.triggerServerConfigFetch();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Fetches config from server", () => {
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
stateService.getServerConfig.mockResolvedValueOnce(null);
|
environmentService.environment$ = of(environmentFactory(activeApiUrl));
|
||||||
|
sut = new DefaultConfigService(
|
||||||
|
configApiService,
|
||||||
|
environmentService,
|
||||||
|
logService,
|
||||||
|
stateProvider,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each<number | jest.DoneCallback>([1, 2, 3])(
|
describe("serverConfig$", () => {
|
||||||
"after %p hour/s",
|
it.each([{}, null])("handles null stored state", async (globalTestState) => {
|
||||||
(hours: number, done: jest.DoneCallback) => {
|
globalState.stateSubject.next(globalTestState);
|
||||||
const configService = configServiceFactory();
|
userState.nextState(null);
|
||||||
|
await expect(firstValueFrom(sut.serverConfig$)).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
// skip previous hours (if any)
|
describe.each(["stale", "missing"])("%s config", (configStateDescription) => {
|
||||||
configService.serverConfig$.pipe(skip(hours - 1), take(1)).subscribe((config) => {
|
const userStored =
|
||||||
try {
|
configStateDescription === "missing"
|
||||||
expect(config.gitHash).toEqual("server" + hours);
|
? null
|
||||||
expect(configApiService.get).toHaveBeenCalledTimes(hours);
|
: serverConfigFactory(activeApiUrl + userId, tooOld);
|
||||||
done();
|
const globalStored =
|
||||||
} catch (e) {
|
configStateDescription === "missing"
|
||||||
done(e);
|
? {}
|
||||||
}
|
: {
|
||||||
|
[activeApiUrl]: serverConfigFactory(activeApiUrl, tooOld),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
globalState.stateSubject.next(globalStored);
|
||||||
|
userState.nextState(userStored);
|
||||||
});
|
});
|
||||||
|
|
||||||
const oneHourInMs = 1000 * 3600;
|
// sanity check
|
||||||
jest.advanceTimersByTime(oneHourInMs * hours + 1);
|
test("authed and unauthorized state are different", () => {
|
||||||
},
|
expect(globalStored[activeApiUrl]).not.toEqual(userStored);
|
||||||
);
|
});
|
||||||
|
|
||||||
it("when environment URLs change", (done) => {
|
describe("fail to fetch", () => {
|
||||||
const configService = configServiceFactory();
|
beforeEach(() => {
|
||||||
|
configApiService.get.mockRejectedValue(new Error("Unable to fetch"));
|
||||||
|
});
|
||||||
|
|
||||||
configService.serverConfig$.pipe(take(1)).subscribe((config) => {
|
it("uses storage as fallback", async () => {
|
||||||
try {
|
const actual = await firstValueFrom(sut.serverConfig$);
|
||||||
expect(config.gitHash).toEqual("server1");
|
expect(actual).toEqual(activeUserId ? userStored : globalStored[activeApiUrl]);
|
||||||
done();
|
expect(configApiService.get).toHaveBeenCalledTimes(1);
|
||||||
} catch (e) {
|
});
|
||||||
done(e);
|
|
||||||
}
|
it("does not error out when fetch fails", async () => {
|
||||||
|
await expect(firstValueFrom(sut.serverConfig$)).resolves.not.toThrow();
|
||||||
|
expect(configApiService.get).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("logs an error when unable to fetch", async () => {
|
||||||
|
await firstValueFrom(sut.serverConfig$);
|
||||||
|
|
||||||
|
expect(logService.error).toHaveBeenCalledWith(
|
||||||
|
`Unable to fetch ServerConfig from ${activeApiUrl}: Unable to fetch`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("fetch success", () => {
|
||||||
|
const response = serverConfigResponseFactory();
|
||||||
|
const newConfig = new ServerConfig(new ServerConfigData(response));
|
||||||
|
|
||||||
|
it("should be a new config", async () => {
|
||||||
|
expect(newConfig).not.toEqual(activeUserId ? userStored : globalStored[activeApiUrl]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fetches config from server when it's older than an hour", async () => {
|
||||||
|
await firstValueFrom(sut.serverConfig$);
|
||||||
|
|
||||||
|
expect(configApiService.get).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns the updated config", async () => {
|
||||||
|
configApiService.get.mockResolvedValue(response);
|
||||||
|
|
||||||
|
const actual = await firstValueFrom(sut.serverConfig$);
|
||||||
|
|
||||||
|
// This is the time the response is converted to a config
|
||||||
|
expect(actual.utcDate).toAlmostEqual(newConfig.utcDate, 1000);
|
||||||
|
delete actual.utcDate;
|
||||||
|
delete newConfig.utcDate;
|
||||||
|
|
||||||
|
expect(actual).toEqual(newConfig);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
replaySubject.next(null);
|
describe("fresh configuration", () => {
|
||||||
});
|
const userStored = serverConfigFactory(activeApiUrl + userId);
|
||||||
|
const globalStored = {
|
||||||
|
[activeApiUrl]: serverConfigFactory(activeApiUrl),
|
||||||
|
};
|
||||||
|
beforeEach(() => {
|
||||||
|
globalState.stateSubject.next(globalStored);
|
||||||
|
userState.nextState(userStored);
|
||||||
|
});
|
||||||
|
it("does not fetch from server", async () => {
|
||||||
|
await firstValueFrom(sut.serverConfig$);
|
||||||
|
|
||||||
it("when triggerServerConfigFetch() is called", (done) => {
|
expect(configApiService.get).not.toHaveBeenCalled();
|
||||||
const configService = configServiceFactory();
|
});
|
||||||
|
|
||||||
configService.serverConfig$.pipe(take(1)).subscribe((config) => {
|
it("uses stored value", async () => {
|
||||||
try {
|
const actual = await firstValueFrom(sut.serverConfig$);
|
||||||
expect(config.gitHash).toEqual("server1");
|
expect(actual).toEqual(activeUserId ? userStored : globalStored[activeApiUrl]);
|
||||||
done();
|
});
|
||||||
} catch (e) {
|
|
||||||
done(e);
|
it("does not complete after emit", async () => {
|
||||||
}
|
const emissions = [];
|
||||||
|
const subscription = sut.serverConfig$.subscribe((v) => emissions.push(v));
|
||||||
|
await awaitAsync();
|
||||||
|
expect(emissions.length).toBe(1);
|
||||||
|
expect(subscription.closed).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
configService.triggerServerConfigFetch();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Saves server config to storage when the user is logged in", (done) => {
|
describe("environment change", () => {
|
||||||
stateService.getServerConfig.mockResolvedValueOnce(null);
|
let sut: DefaultConfigService;
|
||||||
authService.getAuthStatus.mockResolvedValue(AuthenticationStatus.Locked);
|
let environmentSubject: Subject<Environment>;
|
||||||
const configService = configServiceFactory();
|
|
||||||
|
|
||||||
configService.serverConfig$.pipe(take(1)).subscribe(() => {
|
beforeAll(async () => {
|
||||||
try {
|
// updating environment with an active account is undefined behavior
|
||||||
expect(stateService.setServerConfig).toHaveBeenCalledWith(
|
await accountService.switchAccount(null);
|
||||||
expect.objectContaining({ gitHash: "server1" }),
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
} catch (e) {
|
|
||||||
done(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
configService.triggerServerConfigFetch();
|
beforeEach(() => {
|
||||||
|
environmentSubject = new Subject<Environment>();
|
||||||
|
environmentService.environment$ = environmentSubject;
|
||||||
|
sut = new DefaultConfigService(
|
||||||
|
configApiService,
|
||||||
|
environmentService,
|
||||||
|
logService,
|
||||||
|
stateProvider,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("serverConfig$", () => {
|
||||||
|
it("emits a new config when the environment changes", async () => {
|
||||||
|
const globalStored = {
|
||||||
|
[apiUrl(0)]: serverConfigFactory(apiUrl(0)),
|
||||||
|
[apiUrl(1)]: serverConfigFactory(apiUrl(1)),
|
||||||
|
};
|
||||||
|
globalState.stateSubject.next(globalStored);
|
||||||
|
|
||||||
|
const spy = subscribeTo(sut.serverConfig$);
|
||||||
|
|
||||||
|
environmentSubject.next(environmentFactory(apiUrl(0)));
|
||||||
|
environmentSubject.next(environmentFactory(apiUrl(1)));
|
||||||
|
|
||||||
|
const expected = [globalStored[apiUrl(0)], globalStored[apiUrl(1)]];
|
||||||
|
|
||||||
|
const actual = await spy.pauseUntilReceived(2);
|
||||||
|
expect(actual.length).toBe(2);
|
||||||
|
|
||||||
|
// validate dates this is done separately because the dates are created when ServerConfig is initialized
|
||||||
|
expect(actual[0].utcDate).toAlmostEqual(expected[0].utcDate, 1000);
|
||||||
|
expect(actual[1].utcDate).toAlmostEqual(expected[1].utcDate, 1000);
|
||||||
|
delete actual[0].utcDate;
|
||||||
|
delete actual[1].utcDate;
|
||||||
|
delete expected[0].utcDate;
|
||||||
|
delete expected[1].utcDate;
|
||||||
|
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
spy.unsubscribe();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function serverConfigDataFactory(gitHash: string) {
|
function apiUrl(count: number) {
|
||||||
return new ServerConfigData(serverConfigResponseFactory(gitHash));
|
return `https://api${count}.test.com`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function serverConfigResponseFactory(gitHash: string) {
|
function serverConfigFactory(hash: string, date: Date = new Date()) {
|
||||||
|
const config = new ServerConfig(serverConfigDataFactory(hash));
|
||||||
|
config.utcDate = date;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
function serverConfigDataFactory(hash?: string) {
|
||||||
|
return new ServerConfigData(serverConfigResponseFactory(hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
function serverConfigResponseFactory(hash?: string) {
|
||||||
return new ServerConfigResponse({
|
return new ServerConfigResponse({
|
||||||
version: "myConfigVersion",
|
version: "myConfigVersion",
|
||||||
gitHash: gitHash,
|
gitHash: hash ?? Utils.newGuid(), // Use optional git hash to store uniqueness value
|
||||||
server: new ThirdPartyServerConfigResponse({
|
server: new ThirdPartyServerConfigResponse({
|
||||||
name: "myThirdPartyServer",
|
name: "myThirdPartyServer",
|
||||||
url: "www.example.com",
|
url: "www.example.com",
|
||||||
|
@ -209,3 +273,9 @@ function serverConfigResponseFactory(gitHash: string) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function environmentFactory(apiUrl: string) {
|
||||||
|
return {
|
||||||
|
getApiUrl: () => apiUrl,
|
||||||
|
} as Environment;
|
||||||
|
}
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
import {
|
|
||||||
ReplaySubject,
|
|
||||||
Subject,
|
|
||||||
catchError,
|
|
||||||
concatMap,
|
|
||||||
defer,
|
|
||||||
delayWhen,
|
|
||||||
firstValueFrom,
|
|
||||||
map,
|
|
||||||
merge,
|
|
||||||
timer,
|
|
||||||
} from "rxjs";
|
|
||||||
import { SemVer } from "semver";
|
|
||||||
|
|
||||||
import { AuthService } from "../../../auth/abstractions/auth.service";
|
|
||||||
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
|
||||||
import { FeatureFlag, FeatureFlagValue } from "../../../enums/feature-flag.enum";
|
|
||||||
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
|
||||||
import { ConfigServiceAbstraction } from "../../abstractions/config/config.service.abstraction";
|
|
||||||
import { ServerConfig } from "../../abstractions/config/server-config";
|
|
||||||
import { EnvironmentService, Region } from "../../abstractions/environment.service";
|
|
||||||
import { LogService } from "../../abstractions/log.service";
|
|
||||||
import { StateService } from "../../abstractions/state.service";
|
|
||||||
import { ServerConfigData } from "../../models/data/server-config.data";
|
|
||||||
import { StateProvider } from "../../state";
|
|
||||||
|
|
||||||
const ONE_HOUR_IN_MILLISECONDS = 1000 * 3600;
|
|
||||||
|
|
||||||
export class ConfigService implements ConfigServiceAbstraction {
|
|
||||||
private inited = false;
|
|
||||||
|
|
||||||
protected _serverConfig = new ReplaySubject<ServerConfig | null>(1);
|
|
||||||
serverConfig$ = this._serverConfig.asObservable();
|
|
||||||
|
|
||||||
private _forceFetchConfig = new Subject<void>();
|
|
||||||
protected refreshTimer$ = timer(ONE_HOUR_IN_MILLISECONDS, ONE_HOUR_IN_MILLISECONDS); // after 1 hour, then every hour
|
|
||||||
|
|
||||||
cloudRegion$ = this.serverConfig$.pipe(
|
|
||||||
map((config) => config?.environment?.cloudRegion ?? Region.US),
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private stateService: StateService,
|
|
||||||
private configApiService: ConfigApiServiceAbstraction,
|
|
||||||
private authService: AuthService,
|
|
||||||
private environmentService: EnvironmentService,
|
|
||||||
private logService: LogService,
|
|
||||||
private stateProvider: StateProvider,
|
|
||||||
|
|
||||||
// Used to avoid duplicate subscriptions, e.g. in browser between the background and popup
|
|
||||||
private subscribe = true,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
if (!this.subscribe || this.inited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const latestServerConfig$ = defer(() => this.configApiService.get()).pipe(
|
|
||||||
map((response) => new ServerConfigData(response)),
|
|
||||||
delayWhen((data) => this.saveConfig(data)),
|
|
||||||
catchError((e: unknown) => {
|
|
||||||
// fall back to stored ServerConfig (if any)
|
|
||||||
this.logService.error("Unable to fetch ServerConfig: " + (e as Error)?.message);
|
|
||||||
return this.stateService.getServerConfig();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
// If you need to fetch a new config when an event occurs, add an observable that emits on that event here
|
|
||||||
merge(
|
|
||||||
this.refreshTimer$, // an overridable interval
|
|
||||||
this.environmentService.environment$, // when environment URLs change (including when app is started)
|
|
||||||
this._forceFetchConfig, // manual
|
|
||||||
)
|
|
||||||
.pipe(
|
|
||||||
concatMap(() => latestServerConfig$),
|
|
||||||
map((data) => (data == null ? null : new ServerConfig(data))),
|
|
||||||
)
|
|
||||||
.subscribe((config) => this._serverConfig.next(config));
|
|
||||||
|
|
||||||
this.inited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFeatureFlag$<T extends FeatureFlagValue>(key: FeatureFlag, defaultValue?: T) {
|
|
||||||
return this.serverConfig$.pipe(
|
|
||||||
map((serverConfig) => {
|
|
||||||
if (serverConfig?.featureStates == null || serverConfig.featureStates[key] == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return serverConfig.featureStates[key] as T;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getFeatureFlag<T extends FeatureFlagValue>(key: FeatureFlag, defaultValue?: T) {
|
|
||||||
return await firstValueFrom(this.getFeatureFlag$(key, defaultValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerServerConfigFetch() {
|
|
||||||
this._forceFetchConfig.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async saveConfig(data: ServerConfigData) {
|
|
||||||
if ((await this.authService.getAuthStatus()) === AuthenticationStatus.LoggedOut) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const userId = await firstValueFrom(this.stateProvider.activeUserId$);
|
|
||||||
await this.stateService.setServerConfig(data);
|
|
||||||
await this.environmentService.setCloudRegion(userId, data.environment?.cloudRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies whether the server version meets the minimum required version
|
|
||||||
* @param minimumRequiredServerVersion The minimum version required
|
|
||||||
* @returns True if the server version is greater than or equal to the minimum required version
|
|
||||||
*/
|
|
||||||
checkServerMeetsVersionRequirement$(minimumRequiredServerVersion: SemVer) {
|
|
||||||
return this.serverConfig$.pipe(
|
|
||||||
map((serverConfig) => {
|
|
||||||
if (serverConfig == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const serverVersion = new SemVer(serverConfig.version);
|
|
||||||
return serverVersion.compare(minimumRequiredServerVersion) >= 0;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
import {
|
||||||
|
NEVER,
|
||||||
|
Observable,
|
||||||
|
Subject,
|
||||||
|
combineLatest,
|
||||||
|
firstValueFrom,
|
||||||
|
map,
|
||||||
|
mergeWith,
|
||||||
|
of,
|
||||||
|
shareReplay,
|
||||||
|
switchMap,
|
||||||
|
tap,
|
||||||
|
} from "rxjs";
|
||||||
|
import { SemVer } from "semver";
|
||||||
|
|
||||||
|
import { FeatureFlag, FeatureFlagValue } from "../../../enums/feature-flag.enum";
|
||||||
|
import { UserId } from "../../../types/guid";
|
||||||
|
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
||||||
|
import { ConfigService } from "../../abstractions/config/config.service";
|
||||||
|
import { ServerConfig } from "../../abstractions/config/server-config";
|
||||||
|
import { EnvironmentService, Region } from "../../abstractions/environment.service";
|
||||||
|
import { LogService } from "../../abstractions/log.service";
|
||||||
|
import { ServerConfigData } from "../../models/data/server-config.data";
|
||||||
|
import { CONFIG_DISK, KeyDefinition, StateProvider, UserKeyDefinition } from "../../state";
|
||||||
|
|
||||||
|
export const RETRIEVAL_INTERVAL = 3_600_000; // 1 hour
|
||||||
|
|
||||||
|
export type ApiUrl = string;
|
||||||
|
|
||||||
|
export const USER_SERVER_CONFIG = new UserKeyDefinition<ServerConfig>(CONFIG_DISK, "serverConfig", {
|
||||||
|
deserializer: (data) => (data == null ? null : ServerConfig.fromJSON(data)),
|
||||||
|
clearOn: ["logout"],
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO MDG: When to clean these up?
|
||||||
|
export const GLOBAL_SERVER_CONFIGURATIONS = KeyDefinition.record<ServerConfig, ApiUrl>(
|
||||||
|
CONFIG_DISK,
|
||||||
|
"byServer",
|
||||||
|
{
|
||||||
|
deserializer: (data) => (data == null ? null : ServerConfig.fromJSON(data)),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// FIXME: currently we are limited to api requests for active users. Update to accept a UserId and APIUrl once ApiService supports it.
|
||||||
|
export class DefaultConfigService implements ConfigService {
|
||||||
|
private failedFetchFallbackSubject = new Subject<ServerConfig>();
|
||||||
|
|
||||||
|
serverConfig$: Observable<ServerConfig>;
|
||||||
|
|
||||||
|
cloudRegion$: Observable<Region>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private configApiService: ConfigApiServiceAbstraction,
|
||||||
|
private environmentService: EnvironmentService,
|
||||||
|
private logService: LogService,
|
||||||
|
private stateProvider: StateProvider,
|
||||||
|
) {
|
||||||
|
const apiUrl$ = this.environmentService.environment$.pipe(
|
||||||
|
map((environment) => environment.getApiUrl()),
|
||||||
|
);
|
||||||
|
|
||||||
|
this.serverConfig$ = combineLatest([this.stateProvider.activeUserId$, apiUrl$]).pipe(
|
||||||
|
switchMap(([userId, apiUrl]) => {
|
||||||
|
const config$ =
|
||||||
|
userId == null ? this.globalConfigFor$(apiUrl) : this.userConfigFor$(userId);
|
||||||
|
return config$.pipe(map((config) => [config, userId, apiUrl] as const));
|
||||||
|
}),
|
||||||
|
tap(async (rec) => {
|
||||||
|
const [existingConfig, userId, apiUrl] = rec;
|
||||||
|
// Grab new config if older retrieval interval
|
||||||
|
if (!existingConfig || this.olderThanRetrievalInterval(existingConfig.utcDate)) {
|
||||||
|
await this.renewConfig(existingConfig, userId, apiUrl);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
switchMap(([existingConfig]) => {
|
||||||
|
// If we needed to fetch, stop this emit, we'll get a new one after update
|
||||||
|
// This is split up with the above tap because we need to return an observable from a failed promise,
|
||||||
|
// which isn't very doable since promises are converted to observables in switchMap
|
||||||
|
if (!existingConfig || this.olderThanRetrievalInterval(existingConfig.utcDate)) {
|
||||||
|
return NEVER;
|
||||||
|
}
|
||||||
|
return of(existingConfig);
|
||||||
|
}),
|
||||||
|
// If fetch fails, we'll emit on this subject to fallback to the existing config
|
||||||
|
mergeWith(this.failedFetchFallbackSubject),
|
||||||
|
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||||
|
);
|
||||||
|
|
||||||
|
this.cloudRegion$ = this.serverConfig$.pipe(
|
||||||
|
map((config) => config?.environment?.cloudRegion ?? Region.US),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
getFeatureFlag$<T extends FeatureFlagValue>(key: FeatureFlag, defaultValue?: T) {
|
||||||
|
return this.serverConfig$.pipe(
|
||||||
|
map((serverConfig) => {
|
||||||
|
if (serverConfig?.featureStates == null || serverConfig.featureStates[key] == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverConfig.featureStates[key] as T;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFeatureFlag<T extends FeatureFlagValue>(key: FeatureFlag, defaultValue?: T) {
|
||||||
|
return await firstValueFrom(this.getFeatureFlag$(key, defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
checkServerMeetsVersionRequirement$(minimumRequiredServerVersion: SemVer) {
|
||||||
|
return this.serverConfig$.pipe(
|
||||||
|
map((serverConfig) => {
|
||||||
|
if (serverConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const serverVersion = new SemVer(serverConfig.version);
|
||||||
|
return serverVersion.compare(minimumRequiredServerVersion) >= 0;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async ensureConfigFetched() {
|
||||||
|
// Triggering a retrieval for the given user ensures that the config is less than RETRIEVAL_INTERVAL old
|
||||||
|
await firstValueFrom(this.serverConfig$);
|
||||||
|
}
|
||||||
|
|
||||||
|
private olderThanRetrievalInterval(date: Date) {
|
||||||
|
return new Date().getTime() - date.getTime() > RETRIEVAL_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the on-disk configuration with a newly retrieved configuration
|
||||||
|
private async renewConfig(
|
||||||
|
existingConfig: ServerConfig,
|
||||||
|
userId: UserId,
|
||||||
|
apiUrl: string,
|
||||||
|
): Promise<void> {
|
||||||
|
try {
|
||||||
|
const response = await this.configApiService.get(userId);
|
||||||
|
const newConfig = new ServerConfig(new ServerConfigData(response));
|
||||||
|
|
||||||
|
// Update the environment region
|
||||||
|
if (
|
||||||
|
newConfig?.environment?.cloudRegion != null &&
|
||||||
|
existingConfig?.environment?.cloudRegion != newConfig.environment.cloudRegion
|
||||||
|
) {
|
||||||
|
// Null userId sets global, otherwise sets to the given user
|
||||||
|
await this.environmentService.setCloudRegion(userId, newConfig?.environment?.cloudRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
// update global state with new pulled config
|
||||||
|
await this.stateProvider.getGlobal(GLOBAL_SERVER_CONFIGURATIONS).update((configs) => {
|
||||||
|
return { ...configs, [apiUrl]: newConfig };
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// update state with new pulled config
|
||||||
|
await this.stateProvider.setUserState(USER_SERVER_CONFIG, newConfig, userId);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// mutate error to be handled by catchError
|
||||||
|
this.logService.error(
|
||||||
|
`Unable to fetch ServerConfig from ${apiUrl}: ${(e as Error)?.message}`,
|
||||||
|
);
|
||||||
|
// Emit the existing config
|
||||||
|
this.failedFetchFallbackSubject.next(existingConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private globalConfigFor$(apiUrl: string): Observable<ServerConfig> {
|
||||||
|
return this.stateProvider
|
||||||
|
.getGlobal(GLOBAL_SERVER_CONFIGURATIONS)
|
||||||
|
.state$.pipe(map((configs) => configs?.[apiUrl]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private userConfigFor$(userId: UserId): Observable<ServerConfig> {
|
||||||
|
return this.stateProvider.getUser(userId, USER_SERVER_CONFIG).state$;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ import {
|
||||||
import { HtmlStorageLocation, KdfType, StorageLocation } from "../enums";
|
import { HtmlStorageLocation, KdfType, StorageLocation } from "../enums";
|
||||||
import { StateFactory } from "../factories/state-factory";
|
import { StateFactory } from "../factories/state-factory";
|
||||||
import { Utils } from "../misc/utils";
|
import { Utils } from "../misc/utils";
|
||||||
import { ServerConfigData } from "../models/data/server-config.data";
|
|
||||||
import { Account, AccountData, AccountSettings } from "../models/domain/account";
|
import { Account, AccountData, AccountSettings } from "../models/domain/account";
|
||||||
import { EncString } from "../models/domain/enc-string";
|
import { EncString } from "../models/domain/enc-string";
|
||||||
import { GlobalState } from "../models/domain/global-state";
|
import { GlobalState } from "../models/domain/global-state";
|
||||||
|
@ -1377,23 +1376,6 @@ export class StateService<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setServerConfig(value: ServerConfigData, options?: StorageOptions): Promise<void> {
|
|
||||||
const account = await this.getAccount(
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()),
|
|
||||||
);
|
|
||||||
account.settings.serverConfig = value;
|
|
||||||
return await this.saveAccount(
|
|
||||||
account,
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getServerConfig(options: StorageOptions): Promise<ServerConfigData> {
|
|
||||||
return (
|
|
||||||
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()))
|
|
||||||
)?.settings?.serverConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDeepLinkRedirectUrl(options?: StorageOptions): Promise<string> {
|
async getDeepLinkRedirectUrl(options?: StorageOptions): Promise<string> {
|
||||||
return (
|
return (
|
||||||
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
||||||
|
|
|
@ -73,6 +73,9 @@ export const APPLICATION_ID_DISK = new StateDefinition("applicationId", "disk",
|
||||||
});
|
});
|
||||||
export const BIOMETRIC_SETTINGS_DISK = new StateDefinition("biometricSettings", "disk");
|
export const BIOMETRIC_SETTINGS_DISK = new StateDefinition("biometricSettings", "disk");
|
||||||
export const CLEAR_EVENT_DISK = new StateDefinition("clearEvent", "disk");
|
export const CLEAR_EVENT_DISK = new StateDefinition("clearEvent", "disk");
|
||||||
|
export const CONFIG_DISK = new StateDefinition("config", "disk", {
|
||||||
|
web: "disk-local",
|
||||||
|
});
|
||||||
export const CRYPTO_DISK = new StateDefinition("crypto", "disk");
|
export const CRYPTO_DISK = new StateDefinition("crypto", "disk");
|
||||||
export const CRYPTO_MEMORY = new StateDefinition("crypto", "memory");
|
export const CRYPTO_MEMORY = new StateDefinition("crypto", "memory");
|
||||||
export const DESKTOP_SETTINGS_DISK = new StateDefinition("desktopSettings", "disk");
|
export const DESKTOP_SETTINGS_DISK = new StateDefinition("desktopSettings", "disk");
|
||||||
|
|
|
@ -44,6 +44,7 @@ import { MergeEnvironmentState } from "./migrations/45-merge-environment-state";
|
||||||
import { DeleteBiometricPromptCancelledData } from "./migrations/46-delete-orphaned-biometric-prompt-data";
|
import { DeleteBiometricPromptCancelledData } from "./migrations/46-delete-orphaned-biometric-prompt-data";
|
||||||
import { MoveDesktopSettingsMigrator } from "./migrations/47-move-desktop-settings";
|
import { MoveDesktopSettingsMigrator } from "./migrations/47-move-desktop-settings";
|
||||||
import { MoveDdgToStateProviderMigrator } from "./migrations/48-move-ddg-to-state-provider";
|
import { MoveDdgToStateProviderMigrator } from "./migrations/48-move-ddg-to-state-provider";
|
||||||
|
import { AccountServerConfigMigrator } from "./migrations/49-move-account-server-configs";
|
||||||
import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-keys";
|
import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-keys";
|
||||||
import { RemoveLegacyEtmKeyMigrator } from "./migrations/6-remove-legacy-etm-key";
|
import { RemoveLegacyEtmKeyMigrator } from "./migrations/6-remove-legacy-etm-key";
|
||||||
import { MoveBiometricAutoPromptToAccount } from "./migrations/7-move-biometric-auto-prompt-to-account";
|
import { MoveBiometricAutoPromptToAccount } from "./migrations/7-move-biometric-auto-prompt-to-account";
|
||||||
|
@ -52,8 +53,7 @@ import { MoveBrowserSettingsToGlobal } from "./migrations/9-move-browser-setting
|
||||||
import { MinVersionMigrator } from "./migrations/min-version";
|
import { MinVersionMigrator } from "./migrations/min-version";
|
||||||
|
|
||||||
export const MIN_VERSION = 3;
|
export const MIN_VERSION = 3;
|
||||||
export const CURRENT_VERSION = 48;
|
export const CURRENT_VERSION = 49;
|
||||||
|
|
||||||
export type MinVersion = typeof MIN_VERSION;
|
export type MinVersion = typeof MIN_VERSION;
|
||||||
|
|
||||||
export function createMigrationBuilder() {
|
export function createMigrationBuilder() {
|
||||||
|
@ -103,7 +103,8 @@ export function createMigrationBuilder() {
|
||||||
.with(MergeEnvironmentState, 44, 45)
|
.with(MergeEnvironmentState, 44, 45)
|
||||||
.with(DeleteBiometricPromptCancelledData, 45, 46)
|
.with(DeleteBiometricPromptCancelledData, 45, 46)
|
||||||
.with(MoveDesktopSettingsMigrator, 46, 47)
|
.with(MoveDesktopSettingsMigrator, 46, 47)
|
||||||
.with(MoveDdgToStateProviderMigrator, 47, CURRENT_VERSION);
|
.with(MoveDdgToStateProviderMigrator, 47, 48)
|
||||||
|
.with(AccountServerConfigMigrator, 48, CURRENT_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function currentVersion(
|
export async function currentVersion(
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
import { runMigrator } from "../migration-helper.spec";
|
||||||
|
|
||||||
|
import { AccountServerConfigMigrator } from "./49-move-account-server-configs";
|
||||||
|
|
||||||
|
describe("AccountServerConfigMigrator", () => {
|
||||||
|
const migrator = new AccountServerConfigMigrator(48, 49);
|
||||||
|
|
||||||
|
describe("all data", () => {
|
||||||
|
function toMigrate() {
|
||||||
|
return {
|
||||||
|
authenticatedAccounts: ["user1", "user2"],
|
||||||
|
user1: {
|
||||||
|
settings: {
|
||||||
|
serverConfig: {
|
||||||
|
config: "user1 server config",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user2: {
|
||||||
|
settings: {
|
||||||
|
serverConfig: {
|
||||||
|
config: "user2 server config",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function migrated() {
|
||||||
|
return {
|
||||||
|
authenticatedAccounts: ["user1", "user2"],
|
||||||
|
|
||||||
|
user1: {
|
||||||
|
settings: {},
|
||||||
|
},
|
||||||
|
user2: {
|
||||||
|
settings: {},
|
||||||
|
},
|
||||||
|
user_user1_config_serverConfig: {
|
||||||
|
config: "user1 server config",
|
||||||
|
},
|
||||||
|
user_user2_config_serverConfig: {
|
||||||
|
config: "user2 server config",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function rolledBack(previous: object) {
|
||||||
|
return {
|
||||||
|
...previous,
|
||||||
|
user_user1_config_serverConfig: null as unknown,
|
||||||
|
user_user2_config_serverConfig: null as unknown,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
it("migrates", async () => {
|
||||||
|
const output = await runMigrator(migrator, toMigrate(), "migrate");
|
||||||
|
expect(output).toEqual(migrated());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rolls back", async () => {
|
||||||
|
const output = await runMigrator(migrator, migrated(), "rollback");
|
||||||
|
expect(output).toEqual(rolledBack(toMigrate()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("missing parts", () => {
|
||||||
|
function toMigrate() {
|
||||||
|
return {
|
||||||
|
authenticatedAccounts: ["user1", "user2"],
|
||||||
|
user1: {
|
||||||
|
settings: {
|
||||||
|
serverConfig: {
|
||||||
|
config: "user1 server config",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user2: null as unknown,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function migrated() {
|
||||||
|
return {
|
||||||
|
authenticatedAccounts: ["user1", "user2"],
|
||||||
|
user1: {
|
||||||
|
settings: {},
|
||||||
|
},
|
||||||
|
user2: null as unknown,
|
||||||
|
user_user1_config_serverConfig: {
|
||||||
|
config: "user1 server config",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function rollback(previous: object) {
|
||||||
|
return {
|
||||||
|
...previous,
|
||||||
|
user_user1_config_serverConfig: null as unknown,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
it("migrates", async () => {
|
||||||
|
const output = await runMigrator(migrator, toMigrate(), "migrate");
|
||||||
|
expect(output).toEqual(migrated());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rolls back", async () => {
|
||||||
|
const output = await runMigrator(migrator, migrated(), "rollback");
|
||||||
|
expect(output).toEqual(rollback(toMigrate()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { KeyDefinitionLike, MigrationHelper, StateDefinitionLike } from "../migration-helper";
|
||||||
|
import { Migrator } from "../migrator";
|
||||||
|
|
||||||
|
const CONFIG_DISK: StateDefinitionLike = { name: "config" };
|
||||||
|
export const USER_SERVER_CONFIG: KeyDefinitionLike = {
|
||||||
|
stateDefinition: CONFIG_DISK,
|
||||||
|
key: "serverConfig",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note: no need to migrate global configs, they don't currently exist
|
||||||
|
|
||||||
|
type ExpectedAccountType = {
|
||||||
|
settings?: {
|
||||||
|
serverConfig?: unknown;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export class AccountServerConfigMigrator extends Migrator<48, 49> {
|
||||||
|
async migrate(helper: MigrationHelper): Promise<void> {
|
||||||
|
const accounts = await helper.getAccounts<ExpectedAccountType>();
|
||||||
|
|
||||||
|
async function migrateAccount(userId: string, account: ExpectedAccountType): Promise<void> {
|
||||||
|
if (account?.settings?.serverConfig != null) {
|
||||||
|
await helper.setToUser(userId, USER_SERVER_CONFIG, account.settings.serverConfig);
|
||||||
|
delete account.settings.serverConfig;
|
||||||
|
await helper.set(userId, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollback(helper: MigrationHelper): Promise<void> {
|
||||||
|
const accounts = await helper.getAccounts<ExpectedAccountType>();
|
||||||
|
|
||||||
|
async function rollbackAccount(userId: string, account: ExpectedAccountType): Promise<void> {
|
||||||
|
const serverConfig = await helper.getFromUser(userId, USER_SERVER_CONFIG);
|
||||||
|
|
||||||
|
if (serverConfig) {
|
||||||
|
account ??= {};
|
||||||
|
account.settings ??= {};
|
||||||
|
|
||||||
|
account.settings.serverConfig = serverConfig;
|
||||||
|
await helper.setToUser(userId, USER_SERVER_CONFIG, null);
|
||||||
|
await helper.set(userId, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import { SearchService } from "../../abstractions/search.service";
|
||||||
import { AutofillSettingsService } from "../../autofill/services/autofill-settings.service";
|
import { AutofillSettingsService } from "../../autofill/services/autofill-settings.service";
|
||||||
import { DomainSettingsService } from "../../autofill/services/domain-settings.service";
|
import { DomainSettingsService } from "../../autofill/services/domain-settings.service";
|
||||||
import { UriMatchStrategy } from "../../models/domain/domain-service";
|
import { UriMatchStrategy } from "../../models/domain/domain-service";
|
||||||
import { ConfigServiceAbstraction } from "../../platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "../../platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "../../platform/abstractions/encrypt.service";
|
import { EncryptService } from "../../platform/abstractions/encrypt.service";
|
||||||
import { I18nService } from "../../platform/abstractions/i18n.service";
|
import { I18nService } from "../../platform/abstractions/i18n.service";
|
||||||
|
@ -108,7 +108,7 @@ describe("Cipher Service", () => {
|
||||||
const i18nService = mock<I18nService>();
|
const i18nService = mock<I18nService>();
|
||||||
const searchService = mock<SearchService>();
|
const searchService = mock<SearchService>();
|
||||||
const encryptService = mock<EncryptService>();
|
const encryptService = mock<EncryptService>();
|
||||||
const configService = mock<ConfigServiceAbstraction>();
|
const configService = mock<ConfigService>();
|
||||||
|
|
||||||
let cipherService: CipherService;
|
let cipherService: CipherService;
|
||||||
let cipherObj: Cipher;
|
let cipherObj: Cipher;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { UriMatchStrategySetting } from "../../models/domain/domain-service";
|
||||||
import { ErrorResponse } from "../../models/response/error.response";
|
import { ErrorResponse } from "../../models/response/error.response";
|
||||||
import { ListResponse } from "../../models/response/list.response";
|
import { ListResponse } from "../../models/response/list.response";
|
||||||
import { View } from "../../models/view/view";
|
import { View } from "../../models/view/view";
|
||||||
import { ConfigServiceAbstraction } from "../../platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "../../platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
||||||
import { EncryptService } from "../../platform/abstractions/encrypt.service";
|
import { EncryptService } from "../../platform/abstractions/encrypt.service";
|
||||||
import { I18nService } from "../../platform/abstractions/i18n.service";
|
import { I18nService } from "../../platform/abstractions/i18n.service";
|
||||||
|
@ -72,7 +72,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||||
private autofillSettingsService: AutofillSettingsServiceAbstraction,
|
private autofillSettingsService: AutofillSettingsServiceAbstraction,
|
||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
private cipherFileUploadService: CipherFileUploadService,
|
private cipherFileUploadService: CipherFileUploadService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getDecryptedCipherCache(): Promise<CipherView[]> {
|
async getDecryptedCipherCache(): Promise<CipherView[]> {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { of } from "rxjs";
|
||||||
import { AuthService } from "../../../auth/abstractions/auth.service";
|
import { AuthService } from "../../../auth/abstractions/auth.service";
|
||||||
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
||||||
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
||||||
import { ConfigServiceAbstraction } from "../../../platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
||||||
import { Utils } from "../../../platform/misc/utils";
|
import { Utils } from "../../../platform/misc/utils";
|
||||||
import {
|
import {
|
||||||
Fido2AuthenticatorError,
|
Fido2AuthenticatorError,
|
||||||
|
@ -30,7 +30,7 @@ const VaultUrl = "https://vault.bitwarden.com";
|
||||||
|
|
||||||
describe("FidoAuthenticatorService", () => {
|
describe("FidoAuthenticatorService", () => {
|
||||||
let authenticator!: MockProxy<Fido2AuthenticatorService>;
|
let authenticator!: MockProxy<Fido2AuthenticatorService>;
|
||||||
let configService!: MockProxy<ConfigServiceAbstraction>;
|
let configService!: MockProxy<ConfigService>;
|
||||||
let authService!: MockProxy<AuthService>;
|
let authService!: MockProxy<AuthService>;
|
||||||
let vaultSettingsService: MockProxy<VaultSettingsService>;
|
let vaultSettingsService: MockProxy<VaultSettingsService>;
|
||||||
let domainSettingsService: MockProxy<DomainSettingsService>;
|
let domainSettingsService: MockProxy<DomainSettingsService>;
|
||||||
|
@ -39,7 +39,7 @@ describe("FidoAuthenticatorService", () => {
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
authenticator = mock<Fido2AuthenticatorService>();
|
authenticator = mock<Fido2AuthenticatorService>();
|
||||||
configService = mock<ConfigServiceAbstraction>();
|
configService = mock<ConfigService>();
|
||||||
authService = mock<AuthService>();
|
authService = mock<AuthService>();
|
||||||
vaultSettingsService = mock<VaultSettingsService>();
|
vaultSettingsService = mock<VaultSettingsService>();
|
||||||
domainSettingsService = mock<DomainSettingsService>();
|
domainSettingsService = mock<DomainSettingsService>();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { parse } from "tldts";
|
||||||
import { AuthService } from "../../../auth/abstractions/auth.service";
|
import { AuthService } from "../../../auth/abstractions/auth.service";
|
||||||
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
|
||||||
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
import { DomainSettingsService } from "../../../autofill/services/domain-settings.service";
|
||||||
import { ConfigServiceAbstraction } from "../../../platform/abstractions/config/config.service.abstraction";
|
import { ConfigService } from "../../../platform/abstractions/config/config.service";
|
||||||
import { LogService } from "../../../platform/abstractions/log.service";
|
import { LogService } from "../../../platform/abstractions/log.service";
|
||||||
import { Utils } from "../../../platform/misc/utils";
|
import { Utils } from "../../../platform/misc/utils";
|
||||||
import {
|
import {
|
||||||
|
@ -40,7 +40,7 @@ import { Fido2Utils } from "./fido2-utils";
|
||||||
export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
export class Fido2ClientService implements Fido2ClientServiceAbstraction {
|
||||||
constructor(
|
constructor(
|
||||||
private authenticator: Fido2AuthenticatorService,
|
private authenticator: Fido2AuthenticatorService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private vaultSettingsService: VaultSettingsService,
|
private vaultSettingsService: VaultSettingsService,
|
||||||
private domainSettingsService: DomainSettingsService,
|
private domainSettingsService: DomainSettingsService,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { webcrypto } from "crypto";
|
import { webcrypto } from "crypto";
|
||||||
|
|
||||||
import { toEqualBuffer } from "./spec";
|
import { toEqualBuffer } from "./spec";
|
||||||
|
import { toAlmostEqual } from "./spec/matchers/to-almost-equal";
|
||||||
|
|
||||||
Object.defineProperty(window, "crypto", {
|
Object.defineProperty(window, "crypto", {
|
||||||
value: webcrypto,
|
value: webcrypto,
|
||||||
|
@ -10,8 +11,15 @@ Object.defineProperty(window, "crypto", {
|
||||||
|
|
||||||
expect.extend({
|
expect.extend({
|
||||||
toEqualBuffer: toEqualBuffer,
|
toEqualBuffer: toEqualBuffer,
|
||||||
|
toAlmostEqual: toAlmostEqual,
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface CustomMatchers<R = unknown> {
|
export interface CustomMatchers<R = unknown> {
|
||||||
toEqualBuffer(expected: Uint8Array | ArrayBuffer): R;
|
toEqualBuffer(expected: Uint8Array | ArrayBuffer): R;
|
||||||
|
/**
|
||||||
|
* Matches the expected date within an optional ms precision
|
||||||
|
* @param expected The expected date
|
||||||
|
* @param msPrecision The optional precision in milliseconds
|
||||||
|
*/
|
||||||
|
toAlmostEqual(expected: Date, msPrecision?: number): R;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue