Add server settings model and service.

This commit is contained in:
Alec Rippberger 2024-10-03 21:40:12 -05:00
parent 903c215867
commit 3d0b7a0ea2
No known key found for this signature in database
GPG Key ID: 9DD8DA583B28154A
7 changed files with 48 additions and 2 deletions

View File

@ -3,6 +3,7 @@ import { SemVer } from "semver";
import { FeatureFlag, FeatureFlagValueType } from "../../../enums/feature-flag.enum"; import { FeatureFlag, FeatureFlagValueType } from "../../../enums/feature-flag.enum";
import { UserId } from "../../../types/guid"; import { UserId } from "../../../types/guid";
import { ServerSettings } from "../../models/domain/server-settings";
import { Region } from "../environment.service"; import { Region } from "../environment.service";
import { ServerConfig } from "./server-config"; import { ServerConfig } from "./server-config";
@ -10,6 +11,8 @@ import { ServerConfig } from "./server-config";
export abstract class ConfigService { export abstract class ConfigService {
/** The server config of the currently active user */ /** The server config of the currently active user */
serverConfig$: Observable<ServerConfig | null>; serverConfig$: Observable<ServerConfig | null>;
/** The server settings of the currently active user */
serverSettings$: Observable<ServerSettings | null>;
/** The cloud region of the currently active user */ /** The cloud region of the currently active user */
cloudRegion$: Observable<Region>; cloudRegion$: Observable<Region>;
/** /**

View File

@ -6,6 +6,7 @@ import {
ThirdPartyServerConfigData, ThirdPartyServerConfigData,
EnvironmentServerConfigData, EnvironmentServerConfigData,
} from "../../models/data/server-config.data"; } from "../../models/data/server-config.data";
import { ServerSettings } from "../../models/domain/server-settings";
const dayInMilliseconds = 24 * 3600 * 1000; const dayInMilliseconds = 24 * 3600 * 1000;
@ -16,6 +17,7 @@ export class ServerConfig {
environment?: EnvironmentServerConfigData; environment?: EnvironmentServerConfigData;
utcDate: Date; utcDate: Date;
featureStates: { [key: string]: AllowedFeatureFlagTypes } = {}; featureStates: { [key: string]: AllowedFeatureFlagTypes } = {};
settings: ServerSettings;
constructor(serverConfigData: ServerConfigData) { constructor(serverConfigData: ServerConfigData) {
this.version = serverConfigData.version; this.version = serverConfigData.version;
@ -24,6 +26,7 @@ export class ServerConfig {
this.utcDate = new Date(serverConfigData.utcDate); this.utcDate = new Date(serverConfigData.utcDate);
this.environment = serverConfigData.environment; this.environment = serverConfigData.environment;
this.featureStates = serverConfigData.featureStates; this.featureStates = serverConfigData.featureStates;
this.settings = serverConfigData.settings;
if (this.server?.name == null && this.server?.url == null) { if (this.server?.name == null && this.server?.url == null) {
this.server = null; this.server = null;

View File

@ -2,6 +2,7 @@ import { Jsonify } from "type-fest";
import { AllowedFeatureFlagTypes } from "../../../enums/feature-flag.enum"; import { AllowedFeatureFlagTypes } from "../../../enums/feature-flag.enum";
import { Region } from "../../abstractions/environment.service"; import { Region } from "../../abstractions/environment.service";
import { ServerSettings } from "../domain/server-settings";
import { import {
ServerConfigResponse, ServerConfigResponse,
ThirdPartyServerConfigResponse, ThirdPartyServerConfigResponse,
@ -15,6 +16,7 @@ export class ServerConfigData {
environment?: EnvironmentServerConfigData; environment?: EnvironmentServerConfigData;
utcDate: string; utcDate: string;
featureStates: { [key: string]: AllowedFeatureFlagTypes } = {}; featureStates: { [key: string]: AllowedFeatureFlagTypes } = {};
settings: ServerSettings;
constructor(serverConfigResponse: Partial<ServerConfigResponse>) { constructor(serverConfigResponse: Partial<ServerConfigResponse>) {
this.version = serverConfigResponse?.version; this.version = serverConfigResponse?.version;
@ -27,6 +29,7 @@ export class ServerConfigData {
? new EnvironmentServerConfigData(serverConfigResponse.environment) ? new EnvironmentServerConfigData(serverConfigResponse.environment)
: null; : null;
this.featureStates = serverConfigResponse?.featureStates; this.featureStates = serverConfigResponse?.featureStates;
this.settings = new ServerSettings(serverConfigResponse.settings);
} }
static fromJSON(obj: Jsonify<ServerConfigData>): ServerConfigData { static fromJSON(obj: Jsonify<ServerConfigData>): ServerConfigData {

View File

@ -0,0 +1,11 @@
export interface Settings {
disableUserRegistration: boolean;
}
export class ServerSettings implements Settings {
disableUserRegistration: boolean;
constructor(data?: Settings) {
this.disableUserRegistration = data?.disableUserRegistration ?? false;
}
}

View File

@ -1,6 +1,7 @@
import { AllowedFeatureFlagTypes } from "../../../enums/feature-flag.enum"; import { AllowedFeatureFlagTypes } from "../../../enums/feature-flag.enum";
import { BaseResponse } from "../../../models/response/base.response"; import { BaseResponse } from "../../../models/response/base.response";
import { Region } from "../../abstractions/environment.service"; import { Region } from "../../abstractions/environment.service";
import { ServerSettings } from "../domain/server-settings";
export class ServerConfigResponse extends BaseResponse { export class ServerConfigResponse extends BaseResponse {
version: string; version: string;
@ -8,6 +9,7 @@ export class ServerConfigResponse extends BaseResponse {
server: ThirdPartyServerConfigResponse; server: ThirdPartyServerConfigResponse;
environment: EnvironmentServerConfigResponse; environment: EnvironmentServerConfigResponse;
featureStates: { [key: string]: AllowedFeatureFlagTypes } = {}; featureStates: { [key: string]: AllowedFeatureFlagTypes } = {};
settings: ServerSettings;
constructor(response: any) { constructor(response: any) {
super(response); super(response);
@ -21,6 +23,7 @@ export class ServerConfigResponse extends BaseResponse {
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"); this.featureStates = this.getResponseProperty("FeatureStates");
this.settings = new ServerSettings(this.getResponseProperty("Settings"));
} }
} }

View File

@ -28,11 +28,12 @@ import { Environment, EnvironmentService, Region } from "../../abstractions/envi
import { LogService } from "../../abstractions/log.service"; import { LogService } from "../../abstractions/log.service";
import { devFlagEnabled, devFlagValue } from "../../misc/flags"; import { devFlagEnabled, devFlagValue } from "../../misc/flags";
import { ServerConfigData } from "../../models/data/server-config.data"; import { ServerConfigData } from "../../models/data/server-config.data";
import { ServerSettings } from "../../models/domain/server-settings";
import { CONFIG_DISK, KeyDefinition, StateProvider, UserKeyDefinition } from "../../state"; import { CONFIG_DISK, KeyDefinition, StateProvider, UserKeyDefinition } from "../../state";
export const RETRIEVAL_INTERVAL = devFlagEnabled("configRetrievalIntervalMs") export const RETRIEVAL_INTERVAL = devFlagEnabled("configRetrievalIntervalMs")
? (devFlagValue("configRetrievalIntervalMs") as number) ? (devFlagValue("configRetrievalIntervalMs") as number)
: 3_600_000; // 1 hour : 60_000; // 1 minute
export const SLOW_EMISSION_GUARD = 800; export const SLOW_EMISSION_GUARD = 800;
@ -57,6 +58,8 @@ export class DefaultConfigService implements ConfigService {
serverConfig$: Observable<ServerConfig>; serverConfig$: Observable<ServerConfig>;
serverSettings$: Observable<ServerSettings>;
cloudRegion$: Observable<Region>; cloudRegion$: Observable<Region>;
constructor( constructor(
@ -79,7 +82,7 @@ export class DefaultConfigService implements ConfigService {
switchMap(([userId, environment, authStatus]) => { switchMap(([userId, environment, authStatus]) => {
if (userId == null || authStatus !== AuthenticationStatus.Unlocked) { if (userId == null || authStatus !== AuthenticationStatus.Unlocked) {
return this.globalConfigFor$(environment.getApiUrl()).pipe( return this.globalConfigFor$(environment.getApiUrl()).pipe(
map((config) => [config, null, environment] as const), map((config): readonly [ServerConfig, any, Environment] => [config, null, environment]),
); );
} }
@ -111,6 +114,10 @@ export class DefaultConfigService implements ConfigService {
this.cloudRegion$ = this.serverConfig$.pipe( this.cloudRegion$ = this.serverConfig$.pipe(
map((config) => config?.environment?.cloudRegion ?? Region.US), map((config) => config?.environment?.cloudRegion ?? Region.US),
); );
this.serverSettings$ = this.serverConfig$.pipe(
map((config) => config?.settings ?? new ServerSettings()),
);
} }
getFeatureFlag$<Flag extends FeatureFlag>(key: Flag) { getFeatureFlag$<Flag extends FeatureFlag>(key: Flag) {

View File

@ -0,0 +1,16 @@
import { map, Observable } from "rxjs";
import { ConfigService } from "../abstractions/config/config.service";
import { ServerSettings, Settings } from "../models/domain/server-settings";
export class ServerSettingsService {
constructor(private configService: ConfigService) {}
getSettings$(): Observable<Settings> {
return this.configService.serverSettings$.pipe(map((settings: ServerSettings) => settings));
}
get isUserRegistrationDisabled$(): Observable<boolean> {
return this.getSettings$().pipe(map((settings: Settings) => settings.disableUserRegistration));
}
}