mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 05:43:41 +00:00
[PM-1349] Update client service to retrieve feature flags from API (#5064)
* [PM-1351] Add property to server-config.response. Change config to be able to fetch without being authed. * [PM-1351] fetch every hour. * [PM-1351] fetch on vault sync. * [PM-1351] browser desktop fetch configs on sync complete. * [PM-1351] Add methods to retrieve feature flags * [PM-1351] Add enum to use as key to get values feature flag values * [PM-1351] Remove debug code * [PM-1351] Get flags when unauthed. Add enums as params. Hourly always fetch. * [PM-1351] add check for authed user using auth service * [PM-1351] remove unnecessary timer on account unlock
This commit is contained in:
@@ -2,6 +2,8 @@ import { AvatarUpdateService as AvatarUpdateServiceAbstraction } from "@bitwarde
|
|||||||
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/abstractions/appId.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/abstractions/appId.service";
|
||||||
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
||||||
|
import { ConfigApiServiceAbstraction } from "@bitwarden/common/abstractions/config/config-api.service.abstraction";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/abstractions/cryptoFunction.service";
|
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/abstractions/cryptoFunction.service";
|
||||||
import { EncryptService } from "@bitwarden/common/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/abstractions/encrypt.service";
|
||||||
@@ -49,6 +51,7 @@ import { AvatarUpdateService } from "@bitwarden/common/services/account/avatar-u
|
|||||||
import { ApiService } from "@bitwarden/common/services/api.service";
|
import { ApiService } from "@bitwarden/common/services/api.service";
|
||||||
import { AppIdService } from "@bitwarden/common/services/appId.service";
|
import { AppIdService } from "@bitwarden/common/services/appId.service";
|
||||||
import { AuditService } from "@bitwarden/common/services/audit.service";
|
import { AuditService } from "@bitwarden/common/services/audit.service";
|
||||||
|
import { ConfigService } from "@bitwarden/common/services/config/config.service";
|
||||||
import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service";
|
import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service";
|
||||||
import { ContainerService } from "@bitwarden/common/services/container.service";
|
import { ContainerService } from "@bitwarden/common/services/container.service";
|
||||||
import { EncryptServiceImplementation } from "@bitwarden/common/services/cryptography/encrypt.service.implementation";
|
import { EncryptServiceImplementation } from "@bitwarden/common/services/cryptography/encrypt.service.implementation";
|
||||||
@@ -185,6 +188,8 @@ export default class MainBackground {
|
|||||||
avatarUpdateService: AvatarUpdateServiceAbstraction;
|
avatarUpdateService: AvatarUpdateServiceAbstraction;
|
||||||
mainContextMenuHandler: MainContextMenuHandler;
|
mainContextMenuHandler: MainContextMenuHandler;
|
||||||
cipherContextMenuHandler: CipherContextMenuHandler;
|
cipherContextMenuHandler: CipherContextMenuHandler;
|
||||||
|
configService: ConfigServiceAbstraction;
|
||||||
|
configApiService: ConfigApiServiceAbstraction;
|
||||||
|
|
||||||
// Passed to the popup for Safari to workaround issues with theming, downloading, etc.
|
// Passed to the popup for Safari to workaround issues with theming, downloading, etc.
|
||||||
backgroundWindow = window;
|
backgroundWindow = window;
|
||||||
@@ -493,6 +498,12 @@ export default class MainBackground {
|
|||||||
this.userVerificationApiService
|
this.userVerificationApiService
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.configService = new ConfigService(
|
||||||
|
this.stateService,
|
||||||
|
this.configApiService,
|
||||||
|
this.authService
|
||||||
|
);
|
||||||
|
|
||||||
const systemUtilsServiceReloadCallback = () => {
|
const systemUtilsServiceReloadCallback = () => {
|
||||||
const forceWindowReload =
|
const forceWindowReload =
|
||||||
this.platformUtilsService.isSafari() ||
|
this.platformUtilsService.isSafari() ||
|
||||||
@@ -522,7 +533,8 @@ export default class MainBackground {
|
|||||||
this.systemService,
|
this.systemService,
|
||||||
this.environmentService,
|
this.environmentService,
|
||||||
this.messagingService,
|
this.messagingService,
|
||||||
this.logService
|
this.logService,
|
||||||
|
this.configService
|
||||||
);
|
);
|
||||||
this.nativeMessagingBackground = new NativeMessagingBackground(
|
this.nativeMessagingBackground = new NativeMessagingBackground(
|
||||||
this.cryptoService,
|
this.cryptoService,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction";
|
||||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||||
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||||
@@ -28,7 +29,8 @@ export default class RuntimeBackground {
|
|||||||
private systemService: SystemService,
|
private systemService: SystemService,
|
||||||
private environmentService: BrowserEnvironmentService,
|
private environmentService: BrowserEnvironmentService,
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private logService: LogService
|
private logService: LogService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {
|
) {
|
||||||
// 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
|
||||||
chrome.runtime.onInstalled.addListener((details: any) => {
|
chrome.runtime.onInstalled.addListener((details: any) => {
|
||||||
@@ -94,6 +96,7 @@ export default class RuntimeBackground {
|
|||||||
await this.main.refreshMenu();
|
await this.main.refreshMenu();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
this.main.avatarUpdateService.loadColorFromState();
|
this.main.avatarUpdateService.loadColorFromState();
|
||||||
|
this.configService.fetchServerConfig();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "openPopup":
|
case "openPopup":
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { firstValueFrom, Subject, takeUntil } from "rxjs";
|
|||||||
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
|
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
|
||||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction";
|
||||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
|
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
|
||||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
@@ -133,7 +134,8 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||||||
private eventUploadService: EventUploadService,
|
private eventUploadService: EventUploadService,
|
||||||
private policyService: InternalPolicyService,
|
private policyService: InternalPolicyService,
|
||||||
private modalService: ModalService,
|
private modalService: ModalService,
|
||||||
private keyConnectorService: KeyConnectorService
|
private keyConnectorService: KeyConnectorService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@@ -217,6 +219,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||||||
break;
|
break;
|
||||||
case "syncCompleted":
|
case "syncCompleted":
|
||||||
await this.updateAppMenu();
|
await this.updateAppMenu();
|
||||||
|
await this.configService.fetchServerConfig();
|
||||||
break;
|
break;
|
||||||
case "openSettings":
|
case "openSettings":
|
||||||
await this.openModal<SettingsComponent>(SettingsComponent, this.settingsRef);
|
await this.openModal<SettingsComponent>(SettingsComponent, this.settingsRef);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Subject, takeUntil } from "rxjs";
|
|||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
|
|
||||||
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction";
|
||||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
|
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
|
||||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
@@ -77,7 +78,8 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
private eventUploadService: EventUploadService,
|
private eventUploadService: EventUploadService,
|
||||||
private policyService: InternalPolicyService,
|
private policyService: InternalPolicyService,
|
||||||
protected policyListService: PolicyListService,
|
protected policyListService: PolicyListService,
|
||||||
private keyConnectorService: KeyConnectorService
|
private keyConnectorService: KeyConnectorService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@@ -127,6 +129,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
case "syncStarted":
|
case "syncStarted":
|
||||||
break;
|
break;
|
||||||
case "syncCompleted":
|
case "syncCompleted":
|
||||||
|
await this.configService.fetchServerConfig();
|
||||||
break;
|
break;
|
||||||
case "upgradeOrganization": {
|
case "upgradeOrganization": {
|
||||||
const upgradeConfirmed = await this.platformUtilsService.showDialog(
|
const upgradeConfirmed = await this.platformUtilsService.showDialog(
|
||||||
|
|||||||
@@ -615,7 +615,7 @@ import { AbstractThemingService } from "./theming/theming.service.abstraction";
|
|||||||
{
|
{
|
||||||
provide: ConfigServiceAbstraction,
|
provide: ConfigServiceAbstraction,
|
||||||
useClass: ConfigService,
|
useClass: ConfigService,
|
||||||
deps: [StateServiceAbstraction, ConfigApiServiceAbstraction],
|
deps: [StateServiceAbstraction, ConfigApiServiceAbstraction, AuthServiceAbstraction],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: ConfigApiServiceAbstraction,
|
provide: ConfigApiServiceAbstraction,
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { FeatureFlag } from "../../enums/feature-flag.enum";
|
||||||
|
|
||||||
import { ServerConfig } from "./server-config";
|
import { ServerConfig } from "./server-config";
|
||||||
|
|
||||||
export abstract class ConfigServiceAbstraction {
|
export abstract class ConfigServiceAbstraction {
|
||||||
serverConfig$: Observable<ServerConfig | null>;
|
serverConfig$: Observable<ServerConfig | null>;
|
||||||
|
fetchServerConfig: () => Promise<ServerConfig>;
|
||||||
|
getFeatureFlagBool: (key: FeatureFlag, defaultValue?: boolean) => Promise<boolean>;
|
||||||
|
getFeatureFlagString: (key: FeatureFlag, defaultValue?: string) => Promise<string>;
|
||||||
|
getFeatureFlagNumber: (key: FeatureFlag, defaultValue?: number) => Promise<number>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export class ServerConfig {
|
|||||||
server?: ThirdPartyServerConfigData;
|
server?: ThirdPartyServerConfigData;
|
||||||
environment?: EnvironmentServerConfigData;
|
environment?: EnvironmentServerConfigData;
|
||||||
utcDate: Date;
|
utcDate: Date;
|
||||||
|
featureStates: { [key: string]: string } = {};
|
||||||
|
|
||||||
constructor(serverConfigData: ServerConfigData) {
|
constructor(serverConfigData: ServerConfigData) {
|
||||||
this.version = serverConfigData.version;
|
this.version = serverConfigData.version;
|
||||||
@@ -22,6 +23,7 @@ export class ServerConfig {
|
|||||||
this.server = serverConfigData.server;
|
this.server = serverConfigData.server;
|
||||||
this.utcDate = new Date(serverConfigData.utcDate);
|
this.utcDate = new Date(serverConfigData.utcDate);
|
||||||
this.environment = serverConfigData.environment;
|
this.environment = serverConfigData.environment;
|
||||||
|
this.featureStates = serverConfigData.featureStates;
|
||||||
|
|
||||||
if (this.server?.name == null && this.server?.url == null) {
|
if (this.server?.name == null && this.server?.url == null) {
|
||||||
this.server = null;
|
this.server = null;
|
||||||
|
|||||||
3
libs/common/src/enums/feature-flag.enum.ts
Normal file
3
libs/common/src/enums/feature-flag.enum.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export enum FeatureFlag {
|
||||||
|
DisplayEuEnvironmentFlag = "display-eu-environment",
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ export class ServerConfigData {
|
|||||||
server?: ThirdPartyServerConfigData;
|
server?: ThirdPartyServerConfigData;
|
||||||
environment?: EnvironmentServerConfigData;
|
environment?: EnvironmentServerConfigData;
|
||||||
utcDate: string;
|
utcDate: string;
|
||||||
|
featureStates: { [key: string]: string } = {};
|
||||||
|
|
||||||
constructor(serverConfigResponse: Partial<ServerConfigResponse>) {
|
constructor(serverConfigResponse: Partial<ServerConfigResponse>) {
|
||||||
this.version = serverConfigResponse?.version;
|
this.version = serverConfigResponse?.version;
|
||||||
@@ -23,6 +24,7 @@ export class ServerConfigData {
|
|||||||
this.environment = serverConfigResponse?.environment
|
this.environment = serverConfigResponse?.environment
|
||||||
? new EnvironmentServerConfigData(serverConfigResponse.environment)
|
? new EnvironmentServerConfigData(serverConfigResponse.environment)
|
||||||
: null;
|
: null;
|
||||||
|
this.featureStates = serverConfigResponse?.featureStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJSON(obj: Jsonify<ServerConfigData>): ServerConfigData {
|
static fromJSON(obj: Jsonify<ServerConfigData>): ServerConfigData {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export class ServerConfigResponse extends BaseResponse {
|
|||||||
gitHash: string;
|
gitHash: string;
|
||||||
server: ThirdPartyServerConfigResponse;
|
server: ThirdPartyServerConfigResponse;
|
||||||
environment: EnvironmentServerConfigResponse;
|
environment: EnvironmentServerConfigResponse;
|
||||||
|
featureStates: { [key: string]: string } = {};
|
||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
super(response);
|
super(response);
|
||||||
@@ -17,6 +18,7 @@ export class ServerConfigResponse extends BaseResponse {
|
|||||||
this.gitHash = this.getResponseProperty("GitHash");
|
this.gitHash = this.getResponseProperty("GitHash");
|
||||||
this.server = new ThirdPartyServerConfigResponse(this.getResponseProperty("Server"));
|
this.server = new ThirdPartyServerConfigResponse(this.getResponseProperty("Server"));
|
||||||
this.environment = new EnvironmentServerConfigResponse(this.getResponseProperty("Environment"));
|
this.environment = new EnvironmentServerConfigResponse(this.getResponseProperty("Environment"));
|
||||||
|
this.featureStates = this.getResponseProperty("FeatureStates");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export class ConfigApiService implements ConfigApiServiceAbstraction {
|
|||||||
constructor(private apiService: ApiService) {}
|
constructor(private apiService: ApiService) {}
|
||||||
|
|
||||||
async get(): Promise<ServerConfigResponse> {
|
async get(): Promise<ServerConfigResponse> {
|
||||||
const r = await this.apiService.send("GET", "/config", null, true, true);
|
const r = await this.apiService.send("GET", "/config", null, false, true);
|
||||||
return new ServerConfigResponse(r);
|
return new ServerConfigResponse(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { BehaviorSubject, concatMap, map, switchMap, timer, EMPTY } from "rxjs";
|
import { BehaviorSubject, concatMap, timer } from "rxjs";
|
||||||
|
|
||||||
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "../../abstractions/config/config.service.abstraction";
|
import { ConfigServiceAbstraction } from "../../abstractions/config/config.service.abstraction";
|
||||||
import { ServerConfig } from "../../abstractions/config/server-config";
|
import { ServerConfig } from "../../abstractions/config/server-config";
|
||||||
import { StateService } from "../../abstractions/state.service";
|
import { StateService } from "../../abstractions/state.service";
|
||||||
|
import { AuthService } from "../../auth/abstractions/auth.service";
|
||||||
|
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
|
||||||
|
import { FeatureFlag } from "../../enums/feature-flag.enum";
|
||||||
import { ServerConfigData } from "../../models/data/server-config.data";
|
import { ServerConfigData } from "../../models/data/server-config.data";
|
||||||
|
|
||||||
export class ConfigService implements ConfigServiceAbstraction {
|
export class ConfigService implements ConfigServiceAbstraction {
|
||||||
@@ -12,21 +15,14 @@ export class ConfigService implements ConfigServiceAbstraction {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private configApiService: ConfigApiServiceAbstraction
|
private configApiService: ConfigApiServiceAbstraction,
|
||||||
|
private authService: AuthService
|
||||||
) {
|
) {
|
||||||
this.stateService.activeAccountUnlocked$
|
// Re-fetch the server config every hour
|
||||||
|
timer(0, 1000 * 3600)
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap((unlocked) => {
|
concatMap(async () => {
|
||||||
if (!unlocked) {
|
return await this.fetchServerConfig();
|
||||||
this._serverConfig.next(null);
|
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-fetch the server config every hour
|
|
||||||
return timer(0, 3600 * 1000).pipe(map(() => unlocked));
|
|
||||||
}),
|
|
||||||
concatMap(async (unlocked) => {
|
|
||||||
return unlocked ? await this.buildServerConfig() : null;
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.subscribe((serverConfig) => {
|
.subscribe((serverConfig) => {
|
||||||
@@ -34,9 +30,51 @@ export class ConfigService implements ConfigServiceAbstraction {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchServerConfig(): Promise<ServerConfig> {
|
||||||
|
try {
|
||||||
|
const response = await this.configApiService.get();
|
||||||
|
|
||||||
|
if (response != null) {
|
||||||
|
const data = new ServerConfigData(response);
|
||||||
|
const serverConfig = new ServerConfig(data);
|
||||||
|
this._serverConfig.next(serverConfig);
|
||||||
|
if ((await this.authService.getAuthStatus()) === AuthenticationStatus.LoggedOut) {
|
||||||
|
return serverConfig;
|
||||||
|
}
|
||||||
|
await this.stateService.setServerConfig(data);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFeatureFlagBool(key: FeatureFlag, defaultValue = false): Promise<boolean> {
|
||||||
|
return await this.getFeatureFlag(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFeatureFlagString(key: FeatureFlag, defaultValue = ""): Promise<string> {
|
||||||
|
return await this.getFeatureFlag(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFeatureFlagNumber(key: FeatureFlag, defaultValue = 0): Promise<number> {
|
||||||
|
return await this.getFeatureFlag(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getFeatureFlag<T>(key: FeatureFlag, defaultValue: T): Promise<T> {
|
||||||
|
const serverConfig = await this.buildServerConfig();
|
||||||
|
if (
|
||||||
|
serverConfig == null ||
|
||||||
|
serverConfig.featureStates == null ||
|
||||||
|
serverConfig.featureStates[key] == null
|
||||||
|
) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return serverConfig.featureStates[key] as T;
|
||||||
|
}
|
||||||
|
|
||||||
private async buildServerConfig(): Promise<ServerConfig> {
|
private async buildServerConfig(): Promise<ServerConfig> {
|
||||||
const data = await this.stateService.getServerConfig();
|
const data = await this.stateService.getServerConfig();
|
||||||
const domain = data ? new ServerConfig(data) : null;
|
const domain = data ? new ServerConfig(data) : this._serverConfig.getValue();
|
||||||
|
|
||||||
if (domain == null || !domain.isValid() || domain.expiresSoon()) {
|
if (domain == null || !domain.isValid() || domain.expiresSoon()) {
|
||||||
const value = await this.fetchServerConfig();
|
const value = await this.fetchServerConfig();
|
||||||
@@ -45,18 +83,4 @@ export class ConfigService implements ConfigServiceAbstraction {
|
|||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async fetchServerConfig(): Promise<ServerConfig> {
|
|
||||||
try {
|
|
||||||
const response = await this.configApiService.get();
|
|
||||||
|
|
||||||
if (response != null) {
|
|
||||||
const data = new ServerConfigData(response);
|
|
||||||
await this.stateService.setServerConfig(data);
|
|
||||||
return new ServerConfig(data);
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user