mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-20 00:23:03 +00:00
192 lines
5.4 KiB
TypeScript
192 lines
5.4 KiB
TypeScript
/*
|
|
* Copyright (C) 2019, 2020 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 {NGXLogger} from 'ngx-logger';
|
|
import packageJson from '../../../../package.json';
|
|
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;
|
|
|
|
/**
|
|
* Version of the @openstapps/core package that app is using
|
|
*/
|
|
scVersion = packageJson.dependencies['@openstapps/core'];
|
|
|
|
/**
|
|
* First session indicator (config not found in storage)
|
|
*/
|
|
firstSession = true;
|
|
|
|
/**
|
|
* Constructor, initialise api client
|
|
*
|
|
* @param storageProvider StorageProvider to load persistent configuration
|
|
* @param swHttpClient Api client
|
|
* @param logger An angular logger
|
|
*/
|
|
constructor(
|
|
private readonly storageProvider: StorageProvider,
|
|
swHttpClient: StAppsWebHttpClient,
|
|
private readonly logger: NGXLogger,
|
|
) {
|
|
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(this.scVersion);
|
|
} catch {
|
|
throw new ConfigFetchError();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the value of an app configuration
|
|
*
|
|
* @param attribute requested attribute from app configuration
|
|
*/
|
|
public getValue(attribute: keyof SCAppConfiguration) {
|
|
if (typeof this.config.app[attribute] !== 'undefined') {
|
|
return this.config.app[attribute];
|
|
}
|
|
throw new ConfigValueNotAvailable(attribute);
|
|
}
|
|
|
|
/**
|
|
* Returns a value of the configuration (not only app configuration)
|
|
*
|
|
* @param attribute requested attribute from the configuration
|
|
*/
|
|
public getAnyValue(attribute: keyof SCIndexResponse) {
|
|
if (typeof this.config[attribute] !== 'undefined') {
|
|
return this.config[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;
|
|
// load saved configuration
|
|
try {
|
|
this.config = await this.loadLocal();
|
|
this.firstSession = false;
|
|
this.logger.log(`initialised configuration from storage`);
|
|
if (this.config.backend.SCVersion !== this.scVersion) {
|
|
loadError = new WrongConfigVersionInStorage(
|
|
this.scVersion,
|
|
this.config.backend.SCVersion,
|
|
);
|
|
}
|
|
} catch (error) {
|
|
loadError = error;
|
|
}
|
|
// fetch remote configuration from backend
|
|
try {
|
|
const fetchedConfig: SCIndexResponse = await this.fetch();
|
|
await this.set(fetchedConfig);
|
|
this.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') {
|
|
this.logger.warn(loadError);
|
|
}
|
|
if (typeof fetchError !== 'undefined') {
|
|
this.logger.warn(fetchError);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns saved configuration from StorageModule
|
|
*
|
|
* @throws SavedConfigNotAvailable if no configuration could be loaded
|
|
*/
|
|
async loadLocal(): Promise<SCIndexResponse> {
|
|
// 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);
|
|
}
|
|
}
|