mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-20 08:33:11 +00:00
174 lines
5.1 KiB
TypeScript
174 lines
5.1 KiB
TypeScript
/*
|
|
* Copyright (C) 2019 StApps
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation, version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
import {Injectable} from '@angular/core';
|
|
import {Client} from '@openstapps/api/lib/client';
|
|
import {SCAppConfiguration, SCIndexResponse} from '@openstapps/core';
|
|
import {Logger} from '@openstapps/logger';
|
|
import {environment} from '../../../environments/environment';
|
|
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
|
import {StorageProvider} from '../storage/storage.provider';
|
|
import {
|
|
ConfigFetchError,
|
|
ConfigInitError,
|
|
ConfigValueNotAvailable,
|
|
SavedConfigNotAvailable,
|
|
WrongConfigVersionInStorage,
|
|
} from './errors';
|
|
|
|
/**
|
|
* Key to store config in storage module
|
|
*
|
|
* @TODO: Issue #41 centralise storage keys
|
|
*/
|
|
export const STORAGE_KEY_CONFIG = 'stapps.config';
|
|
|
|
/**
|
|
* Provides configuration
|
|
*/
|
|
@Injectable()
|
|
export class ConfigProvider {
|
|
/**
|
|
* Api client
|
|
*/
|
|
client: Client;
|
|
/**
|
|
* App configuration as IndexResponse
|
|
*/
|
|
config: SCIndexResponse;
|
|
/**
|
|
* Initialised status flag of config provider
|
|
*/
|
|
initialised = false;
|
|
|
|
/**
|
|
* Constructor, initialise api client
|
|
*
|
|
* @param storageProvider StorageProvider to load persistet configuration
|
|
* @param swHttpClient Api client
|
|
*/
|
|
constructor(private readonly storageProvider: StorageProvider, swHttpClient: StAppsWebHttpClient) {
|
|
this.client = new Client(swHttpClient, environment.backend_url, environment.backend_version);
|
|
}
|
|
|
|
/**
|
|
* Fetches configuration from backend
|
|
*/
|
|
async fetch(): Promise<SCIndexResponse> {
|
|
try {
|
|
return await this.client.handshake(environment.backend_version);
|
|
} catch (error) {
|
|
throw new ConfigFetchError();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the value of an app configuration
|
|
*
|
|
* @param attribute requested attribute from app configuration
|
|
*/
|
|
public async getValue(attribute: keyof SCAppConfiguration) {
|
|
if (!this.initialised) {
|
|
try {
|
|
await this.init();
|
|
} catch (error) {
|
|
// don't throw ConfigFetchError if saved config is available
|
|
if (!(error.name === 'ConfigFetchError' && this.initialised)) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
if (typeof this.config.app[attribute] !== 'undefined') {
|
|
return this.config.app[attribute];
|
|
}
|
|
throw new ConfigValueNotAvailable(attribute);
|
|
}
|
|
|
|
/**
|
|
* Initialises the ConfigProvider
|
|
*
|
|
* @throws ConfigInitError if no configuration could be loaded.
|
|
* @throws WrongConfigVersionInStorage if fetch failed and saved config has wrong SCVersion
|
|
*/
|
|
async init(): Promise<void> {
|
|
let loadError;
|
|
let fetchError;
|
|
this.initialised = false;
|
|
// load saved configuration
|
|
try {
|
|
this.config = await this.loadLocal();
|
|
this.initialised = true;
|
|
Logger.log(`initialised configuration from storage`);
|
|
if (this.config.backend.SCVersion !== environment.backend_version) {
|
|
loadError = new WrongConfigVersionInStorage(environment.backend_version, this.config.backend.SCVersion);
|
|
Logger.warn(loadError);
|
|
}
|
|
} catch (error) {
|
|
loadError = error;
|
|
}
|
|
// fetch remote configuration from backend
|
|
try {
|
|
const fetchedConfig: SCIndexResponse = await this.fetch();
|
|
await this.set(fetchedConfig);
|
|
this.initialised = true;
|
|
Logger.log(`initialised configuration from remote`);
|
|
} catch (error) {
|
|
fetchError = error;
|
|
}
|
|
// check for occurred errors and throw them
|
|
if (typeof loadError !== 'undefined' && typeof fetchError !== 'undefined') {
|
|
throw new ConfigInitError();
|
|
}
|
|
if (typeof loadError !== 'undefined') {
|
|
throw loadError;
|
|
}
|
|
if (typeof fetchError !== 'undefined') {
|
|
throw fetchError;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns saved configuration from StorageModule
|
|
*
|
|
* @throws SavedConfigNotAvailable if no configuration could be loaded
|
|
*/
|
|
async loadLocal(): Promise<SCIndexResponse> {
|
|
await this.storageProvider.init();
|
|
// get local configuration
|
|
if (await this.storageProvider.has(STORAGE_KEY_CONFIG)) {
|
|
return this.storageProvider.get<SCIndexResponse>(STORAGE_KEY_CONFIG);
|
|
}
|
|
throw new SavedConfigNotAvailable();
|
|
}
|
|
|
|
/**
|
|
* Saves the configuration from the provider
|
|
*
|
|
* @param config configuration to save
|
|
*/
|
|
async save(config: SCIndexResponse): Promise<void> {
|
|
await this.storageProvider.put(STORAGE_KEY_CONFIG, config);
|
|
}
|
|
|
|
/**
|
|
* Sets the configuration in the module and writes it into app storage
|
|
*
|
|
* @param config SCIndexResponse to set
|
|
*/
|
|
async set(config: SCIndexResponse): Promise<void> {
|
|
this.config = config;
|
|
await this.save(this.config);
|
|
}
|
|
}
|