mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
implementing thumbnail settings
This commit is contained in:
parent
0781f54c90
commit
998efcdbf5
@ -20,6 +20,7 @@
|
||||
"testTsconfig": "tsconfig.spec.json",
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"../node_modules/bootstrap/dist/css/bootstrap.css",
|
||||
"styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
|
@ -1,12 +1,13 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {Logger} from "../Logger";
|
||||
import {MySQLConnection} from "../model/mysql/MySQLConnection";
|
||||
import {DataBaseConfig, DatabaseType} from "../../common/config/private/IPrivateConfig";
|
||||
import {DataBaseConfig, DatabaseType, ThumbnailConfig} from "../../common/config/private/IPrivateConfig";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {ConfigDiagnostics} from "../model/ConfigDiagnostics";
|
||||
import {MapConfig} from "../../common/config/public/ConfigClass";
|
||||
import {ClientConfig} from "../../common/config/public/ConfigClass";
|
||||
import set = Reflect.set;
|
||||
|
||||
|
||||
const LOG_TAG = "[AdminMWs]";
|
||||
@ -16,7 +17,7 @@ export class AdminMWs {
|
||||
public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
}
|
||||
|
||||
const databaseSettings = <DataBaseConfig>req.body.settings;
|
||||
@ -43,61 +44,83 @@ export class AdminMWs {
|
||||
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.SETTINGS_ERROR, "Error saving database settings", err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "ErrorDTO saving database settings", err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async testDatabaseSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
}
|
||||
|
||||
const databaseSettings = <DataBaseConfig>req.body.settings;
|
||||
|
||||
try {
|
||||
if (databaseSettings.type == DatabaseType.mysql) {
|
||||
await ConfigDiagnostics.testDatabase(databaseSettings);
|
||||
}
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async updateMapSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testMapConfig(<MapConfig>req.body.settings);
|
||||
await ConfigDiagnostics.testMapConfig(<ClientConfig.MapConfig>req.body.settings);
|
||||
|
||||
Config.Client.Map = <MapConfig>req.body.settings;
|
||||
Config.Client.Map = <ClientConfig.MapConfig>req.body.settings;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Client.Map = <MapConfig>req.body.settings;
|
||||
original.Client.Map = <ClientConfig.MapConfig>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async testMapSettings(req: Request, res: Response, next: NextFunction) {
|
||||
public static async updateAuthenticationSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testMapConfig(<MapConfig>req.body.settings);
|
||||
Config.Client.authenticationRequired = <boolean>req.body.settings;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Client.authenticationRequired = <boolean>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateThumbnailSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
}
|
||||
|
||||
try {
|
||||
const settings: {
|
||||
server: ThumbnailConfig,
|
||||
client: ClientConfig.ThumbnailConfig
|
||||
} = req.body.settings;
|
||||
|
||||
await ConfigDiagnostics.testServerThumbnailConfig(settings.server);
|
||||
await ConfigDiagnostics.testClientThumbnailConfig(settings.client);
|
||||
Config.Server.thumbnail = settings.server;
|
||||
Config.Client.Thumbnail = settings.client;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Server.thumbnail = settings.server;
|
||||
original.Client.Thumbnail = settings.client;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + err.toString(), err));
|
||||
}
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {DirectoryDTO} from "../../common/entities/DirectoryDTO";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {SearchTypes} from "../../common/entities/AutoCompleteItem";
|
||||
@ -37,7 +37,7 @@ export class GalleryMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during listing the directory", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during listing the directory", err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ export class GalleryMWs {
|
||||
|
||||
//check if thumbnail already exist
|
||||
if (fs.existsSync(fullImagePath) === false) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "no such file:" + fullImagePath));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "no such file:" + fullImagePath));
|
||||
}
|
||||
|
||||
req.resultPipe = fullImagePath;
|
||||
@ -108,7 +108,7 @@ export class GalleryMWs {
|
||||
req.resultPipe = new ContentWrapper(null, result);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during searching", err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ export class GalleryMWs {
|
||||
req.resultPipe = new ContentWrapper(null, result);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during searching", err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ export class GalleryMWs {
|
||||
req.resultPipe = await ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during searching", err));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {Utils} from "../../common/Utils";
|
||||
import {Message} from "../../common/entities/Message";
|
||||
import {SharingDTO} from "../../common/entities/SharingDTO";
|
||||
@ -21,7 +21,7 @@ export class RenderingMWs {
|
||||
|
||||
public static renderSessionUser(req: Request, res: Response, next: NextFunction) {
|
||||
if (!(req.session.user)) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "User not exists"));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "User not exists"));
|
||||
}
|
||||
|
||||
const user = Utils.clone(req.session.user);
|
||||
@ -59,7 +59,7 @@ export class RenderingMWs {
|
||||
|
||||
public static renderError(err: any, req: Request, res: Response, next: NextFunction): any {
|
||||
|
||||
if (err instanceof Error) {
|
||||
if (err instanceof ErrorDTO) {
|
||||
if (err.details) {
|
||||
if (!(req.session.user && req.session.user.role >= UserRoles.Developer)) {
|
||||
Logger.warn("Handled error:", err.details.toString() || err.details);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {CreateSharingDTO, SharingDTO} from "../../common/entities/SharingDTO";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
|
||||
const LOG_TAG = "[SharingMWs]";
|
||||
export class SharingMWs {
|
||||
@ -26,14 +26,14 @@ export class SharingMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during retrieving sharing link", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during retrieving sharing link", err));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static async createSharing(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.createSharing === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "createSharing filed is missing"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "createSharing filed is missing"));
|
||||
}
|
||||
const createSharing: CreateSharingDTO = req.body.createSharing;
|
||||
let sharingKey = SharingMWs.generateKey();
|
||||
@ -68,13 +68,13 @@ export class SharingMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during creating sharing link", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during creating sharing link", err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateSharing(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.updateSharing === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "updateSharing filed is missing"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "updateSharing filed is missing"));
|
||||
}
|
||||
const updateSharing: CreateSharingDTO = req.body.updateSharing;
|
||||
const directoryName = req.params.directory || "/";
|
||||
@ -95,7 +95,7 @@ export class SharingMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during creating sharing link", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "ErrorDTO during creating sharing link", err));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import * as crypto from "crypto";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
@ -62,8 +62,8 @@ export class ThumbnailGeneratorMWs {
|
||||
let thumbnailFolder = ProjectPath.ThumbnailFolder;
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
let fullImagePath = path.join(ProjectPath.ImageFolder, photos[i].directory.path, photos[i].directory.name, photos[i].name);
|
||||
for (let j = 0; j < Config.Client.thumbnailSizes.length; j++) {
|
||||
let size = Config.Client.thumbnailSizes[j];
|
||||
for (let j = 0; j < Config.Client.Thumbnail.thumbnailSizes.length; j++) {
|
||||
let size = Config.Client.Thumbnail.thumbnailSizes[j];
|
||||
let thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, size));
|
||||
if (fs.existsSync(thPath) === true) {
|
||||
if (typeof photos[i].readyThumbnails == "undefined") {
|
||||
@ -72,7 +72,7 @@ export class ThumbnailGeneratorMWs {
|
||||
photos[i].readyThumbnails.push(size);
|
||||
}
|
||||
}
|
||||
let iconPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, Config.Client.iconSize));
|
||||
let iconPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, Config.Client.Thumbnail.iconSize));
|
||||
if (fs.existsSync(iconPath) === true) {
|
||||
photos[i].readyIcon = true;
|
||||
}
|
||||
@ -103,11 +103,11 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
//load parameters
|
||||
let imagePath = req.resultPipe;
|
||||
let size: number = parseInt(req.params.size) || Config.Client.thumbnailSizes[0];
|
||||
let size: number = parseInt(req.params.size) || Config.Client.Thumbnail.thumbnailSizes[0];
|
||||
|
||||
//validate size
|
||||
if (Config.Client.thumbnailSizes.indexOf(size) === -1) {
|
||||
size = Config.Client.thumbnailSizes[0];
|
||||
if (Config.Client.Thumbnail.thumbnailSizes.indexOf(size) === -1) {
|
||||
size = Config.Client.Thumbnail.thumbnailSizes[0];
|
||||
}
|
||||
|
||||
ThumbnailGeneratorMWs.generateImage(imagePath, size, false, req, res, next);
|
||||
@ -121,7 +121,7 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
//load parameters
|
||||
let imagePath = req.resultPipe;
|
||||
let size: number = Config.Client.iconSize;
|
||||
let size: number = Config.Client.Thumbnail.iconSize;
|
||||
ThumbnailGeneratorMWs.generateImage(imagePath, size, true, req, res, next);
|
||||
|
||||
|
||||
@ -162,7 +162,7 @@ export class ThumbnailGeneratorMWs {
|
||||
return next();
|
||||
}
|
||||
} catch (error) {
|
||||
return next(new Error(ErrorCodes.THUMBNAIL_GENERATION_ERROR, "Error during generating thumbnail", error));
|
||||
return next(new ErrorDTO(ErrorCodes.THUMBNAIL_GENERATION_ERROR, "ErrorDTO during generating thumbnail", error));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
///<reference path="../customtypings/ExtendedRequest.d.ts"/>
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
@ -63,10 +63,10 @@ export class AuthenticationMWs {
|
||||
return next();
|
||||
}
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND, null, err));
|
||||
}
|
||||
if (typeof req.session.user === 'undefined') {
|
||||
return next(new Error(ErrorCodes.NOT_AUTHENTICATED));
|
||||
return next(new ErrorDTO(ErrorCodes.NOT_AUTHENTICATED));
|
||||
}
|
||||
return next();
|
||||
}
|
||||
@ -74,7 +74,7 @@ export class AuthenticationMWs {
|
||||
public static authorise(role: UserRoles) {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
if (req.session.user.role < role) {
|
||||
return next(new Error(ErrorCodes.NOT_AUTHORISED));
|
||||
return next(new ErrorDTO(ErrorCodes.NOT_AUTHORISED));
|
||||
}
|
||||
return next();
|
||||
};
|
||||
@ -92,12 +92,12 @@ export class AuthenticationMWs {
|
||||
return next();
|
||||
|
||||
}
|
||||
return next(new Error(ErrorCodes.PERMISSION_DENIED));
|
||||
return next(new ErrorDTO(ErrorCodes.PERMISSION_DENIED));
|
||||
}
|
||||
|
||||
public static inverseAuthenticate(req: Request, res: Response, next: NextFunction) {
|
||||
if (typeof req.session.user !== 'undefined') {
|
||||
return next(new Error(ErrorCodes.ALREADY_AUTHENTICATED));
|
||||
return next(new ErrorDTO(ErrorCodes.ALREADY_AUTHENTICATED));
|
||||
}
|
||||
return next();
|
||||
}
|
||||
@ -107,7 +107,7 @@ export class AuthenticationMWs {
|
||||
//not enough parameter
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.loginCredential === 'undefined') || (typeof req.body.loginCredential.username === 'undefined') ||
|
||||
(typeof req.body.loginCredential.password === 'undefined')) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR));
|
||||
}
|
||||
//TODO: implement remember me
|
||||
try {
|
||||
@ -127,10 +127,10 @@ export class AuthenticationMWs {
|
||||
return next();
|
||||
}
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND, null, err));
|
||||
}
|
||||
|
||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||
return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||
}
|
||||
|
||||
|
||||
@ -144,7 +144,7 @@ export class AuthenticationMWs {
|
||||
}
|
||||
//not enough parameter
|
||||
if ((!req.query.sk && !req.params.sharingKey)) {
|
||||
return next(new Error(ErrorCodes.INPUT_ERROR, "no sharing key provided"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "no sharing key provided"));
|
||||
}
|
||||
|
||||
try {
|
||||
@ -156,7 +156,7 @@ export class AuthenticationMWs {
|
||||
if (!sharing || sharing.expires < Date.now() ||
|
||||
(Config.Client.Sharing.passwordProtected === true
|
||||
&& sharing.password && !PasswordHelper.comparePassword(password, sharing.password))) {
|
||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||
return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||
}
|
||||
|
||||
let path = sharing.path;
|
||||
@ -168,7 +168,7 @@ export class AuthenticationMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
@ -8,7 +8,7 @@ export class UserMWs {
|
||||
|
||||
public static async changePassword(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new Error(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.userModReq === 'undefined')
|
||||
|| (typeof req.body.userModReq.id === 'undefined')
|
||||
@ -22,14 +22,14 @@ export class UserMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async createUser(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new Error(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.newUser === 'undefined')) {
|
||||
return next();
|
||||
@ -40,7 +40,7 @@ export class UserMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.USER_CREATION_ERROR, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.USER_CREATION_ERROR, null, err));
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ export class UserMWs {
|
||||
|
||||
public static async deleteUser(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new Error(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
|
||||
return next();
|
||||
@ -60,7 +60,7 @@ export class UserMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
|
||||
|
||||
@ -68,7 +68,7 @@ export class UserMWs {
|
||||
|
||||
public static async changeRole(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new Error(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')
|
||||
|| (typeof req.body === 'undefined') || (typeof req.body.newRole === 'undefined')) {
|
||||
@ -80,14 +80,14 @@ export class UserMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async listUsers(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new Error(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
|
||||
try {
|
||||
@ -99,7 +99,7 @@ export class UserMWs {
|
||||
req.resultPipe = result;
|
||||
next();
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Error, ErrorCodes} from "../../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||
|
||||
@ -10,7 +10,7 @@ export class UserRequestConstrainsMWs {
|
||||
return next();
|
||||
}
|
||||
if (req.session.user.id !== req.params.id) {
|
||||
return next(new Error(ErrorCodes.NOT_AUTHORISED));
|
||||
return next(new ErrorDTO(ErrorCodes.NOT_AUTHORISED));
|
||||
}
|
||||
|
||||
return next();
|
||||
@ -23,7 +23,7 @@ export class UserRequestConstrainsMWs {
|
||||
}
|
||||
|
||||
if (req.session.user.id === req.params.id) {
|
||||
return next(new Error(ErrorCodes.NOT_AUTHORISED));
|
||||
return next(new ErrorDTO(ErrorCodes.NOT_AUTHORISED));
|
||||
}
|
||||
|
||||
return next();
|
||||
@ -42,12 +42,12 @@ export class UserRequestConstrainsMWs {
|
||||
try {
|
||||
const result = await ObjectManagerRepository.getInstance().UserManager.find({minRole: UserRoles.Admin});
|
||||
if (result.length <= 1) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR));
|
||||
}
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import {NotificationManager} from "./NotifocationManager";
|
||||
import {ProjectPath} from "../ProjectPath";
|
||||
import {MySQLConnection} from "./mysql/MySQLConnection";
|
||||
import * as fs from "fs";
|
||||
import {MapConfig, SearchConfig, SharingConfig} from "../../common/config/public/ConfigClass";
|
||||
import {ClientConfig} from "../../common/config/public/ConfigClass";
|
||||
|
||||
const LOG_TAG = "[ConfigDiagnostics]";
|
||||
export class ConfigDiagnostics {
|
||||
@ -32,9 +32,10 @@ export class ConfigDiagnostics {
|
||||
const gm = require("gm");
|
||||
await new Promise((resolve, reject) => {
|
||||
gm(ProjectPath.FrontendFolder + "/assets/icon.png").size((err, value) => {
|
||||
if (!err) {
|
||||
return reject(err);
|
||||
if (err) {
|
||||
return reject(err.toString());
|
||||
}
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
break;
|
||||
@ -45,7 +46,7 @@ export class ConfigDiagnostics {
|
||||
await new Promise((resolve, reject) => {
|
||||
fs.access(folder, fs.constants.W_OK, (err) => {
|
||||
if (err) {
|
||||
reject({message: "Error during getting write access to temp folder", error: err});
|
||||
reject({message: "ErrorDTO during getting write access to temp folder", error: err.toString()});
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
@ -59,7 +60,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
fs.access(folder, fs.constants.R_OK, (err) => {
|
||||
if (err) {
|
||||
reject({message: "Error during getting read access to images folder", error: err});
|
||||
reject({message: "ErrorDTO during getting read access to images folder", error: err.toString()});
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
@ -67,26 +68,41 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
|
||||
static async testThumbnailConfig(thumbnailConfig: ThumbnailConfig) {
|
||||
static async testServerThumbnailConfig(thumbnailConfig: ThumbnailConfig) {
|
||||
await ConfigDiagnostics.testThumbnailLib(thumbnailConfig.processingLibrary);
|
||||
await ConfigDiagnostics.testThumbnailFolder(thumbnailConfig.folder);
|
||||
}
|
||||
|
||||
static async testClientThumbnailConfig(thumbnailConfig: ClientConfig.ThumbnailConfig) {
|
||||
if (isNaN(thumbnailConfig.iconSize) || thumbnailConfig.iconSize <= 0) {
|
||||
throw "IconSize has to be >= 0 integer, got: " + thumbnailConfig.iconSize;
|
||||
}
|
||||
|
||||
static async testSearchConfig(search: SearchConfig) {
|
||||
if (!thumbnailConfig.thumbnailSizes.length) {
|
||||
throw "At least one thumbnail size is needed";
|
||||
}
|
||||
for (let i = 0; i < thumbnailConfig.thumbnailSizes.length; i++) {
|
||||
if (isNaN(thumbnailConfig.thumbnailSizes[i]) || thumbnailConfig.thumbnailSizes[i] <= 0) {
|
||||
throw "Thumbnail size has to be >= 0 integer, got: " + thumbnailConfig.thumbnailSizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async testSearchConfig(search: ClientConfig.SearchConfig) {
|
||||
if (search.enabled == true && Config.Server.database.type == DatabaseType.memory) {
|
||||
throw "Memory Database do not support searching";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async testSharingConfig(sharing: SharingConfig) {
|
||||
static async testSharingConfig(sharing: ClientConfig.SharingConfig) {
|
||||
if (sharing.enabled == true && Config.Server.database.type == DatabaseType.memory) {
|
||||
throw "Memory Database do not support sharing";
|
||||
}
|
||||
}
|
||||
|
||||
static async testMapConfig(map: MapConfig) {
|
||||
static async testMapConfig(map: ClientConfig.MapConfig) {
|
||||
if (map.enabled == true && (!map.googleApiKey || map.googleApiKey.length == 0)) {
|
||||
throw "Maps need a valid google api key";
|
||||
}
|
||||
@ -100,8 +116,8 @@ export class ConfigDiagnostics {
|
||||
await ConfigDiagnostics.testDatabase(Config.Server.database);
|
||||
} catch (err) {
|
||||
Logger.warn(LOG_TAG, "[MYSQL error]", err);
|
||||
Logger.warn(LOG_TAG, "Error during initializing mysql falling back temporally to memory DB");
|
||||
NotificationManager.warning("Error during initializing mysql falling back temporally to memory DB", err);
|
||||
Logger.warn(LOG_TAG, "ErrorDTO during initializing mysql falling back temporally to memory DB");
|
||||
NotificationManager.warning("ErrorDTO during initializing mysql falling back temporally to memory DB", err);
|
||||
Config.setDatabaseType(DatabaseType.memory);
|
||||
}
|
||||
}
|
||||
@ -135,6 +151,12 @@ export class ConfigDiagnostics {
|
||||
NotificationManager.error("Images folder error", err);
|
||||
Logger.error(LOG_TAG, "Images folder error", err);
|
||||
}
|
||||
try {
|
||||
await ConfigDiagnostics.testClientThumbnailConfig(Config.Client.Thumbnail)
|
||||
} catch (err) {
|
||||
NotificationManager.error("Thumbnail settings error", err);
|
||||
Logger.error(LOG_TAG, "Thumbnail settings error", err);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
@ -35,7 +35,7 @@ export class UserManager implements IUserManager {
|
||||
this.createUser(<UserDTO>{name: "developer", password: "developer", role: UserRoles.Developer});
|
||||
this.createUser(<UserDTO>{name: "admin", password: "admin", role: UserRoles.Admin});
|
||||
this.createUser(<UserDTO>{name: "user", password: "user", role: UserRoles.User});
|
||||
this.createUser(<UserDTO>{name: "guest", password: "guest", role: UserRoles.LimitedGuest});
|
||||
this.createUser(<UserDTO>{name: "guest", password: "guest", role: UserRoles.Guest});
|
||||
}
|
||||
|
||||
|
||||
@ -54,8 +54,10 @@ export class UserManager implements IUserManager {
|
||||
public async find(filter: any) {
|
||||
let pass = filter.password;
|
||||
delete filter.password;
|
||||
const users = await this.db.get("users");
|
||||
const users = (await this.db.get("users")).slice();
|
||||
let i = users.length;
|
||||
console.log("filer", filter);
|
||||
console.log(users);
|
||||
while (i--) {
|
||||
if (pass && !(PasswordHelper.comparePassword(pass, users[i].password))) {
|
||||
users.splice(i, 1);
|
||||
@ -65,6 +67,7 @@ export class UserManager implements IUserManager {
|
||||
users.splice(i, 1);
|
||||
}
|
||||
}
|
||||
console.log(users);
|
||||
return users;
|
||||
}
|
||||
|
||||
|
@ -42,13 +42,6 @@ export class AdminRouter {
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
app.post("/api/settings/test/database",
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.testDatabaseSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
app.put("/api/settings/map",
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
@ -56,12 +49,19 @@ export class AdminRouter {
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
app.post("/api/settings/test/map",
|
||||
app.put("/api/settings/authentication",
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.testMapSettings,
|
||||
AdminMWs.updateAuthenticationSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/thumbnail",
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateThumbnailSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {Logger} from "../Logger";
|
||||
import Request = Express.Request;
|
||||
import Response = Express.Response;
|
||||
@ -21,7 +21,7 @@ export class ErrorRouter {
|
||||
app.use((err: any, req: Request, res: Response, next: Function) => {
|
||||
//Flush out the stack to the console
|
||||
Logger.error("Unexpected error:", err);
|
||||
next(new Error(ErrorCodes.SERVER_ERROR, "Unknown server side error", err));
|
||||
next(new ErrorDTO(ErrorCodes.SERVER_ERROR, "Unknown server side error", err));
|
||||
},
|
||||
RenderingMWs.renderError
|
||||
);
|
||||
|
@ -6,6 +6,9 @@ export class Utils {
|
||||
}
|
||||
|
||||
static equalsFilter(object: any, filter: any): boolean {
|
||||
if (typeof filter !== "object" || filter == null) {
|
||||
return object == filter;
|
||||
}
|
||||
const keys = Object.keys(filter);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
|
@ -40,5 +40,5 @@ export interface ServerConfig {
|
||||
}
|
||||
export interface IPrivateConfig {
|
||||
Server: ServerConfig;
|
||||
Client: ClientConfig;
|
||||
Client: ClientConfig.Config;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
export module ClientConfig {
|
||||
export interface SearchConfig {
|
||||
enabled: boolean
|
||||
instantSearchEnabled: boolean
|
||||
@ -13,11 +14,14 @@ export interface MapConfig {
|
||||
enabled: boolean;
|
||||
googleApiKey: string;
|
||||
}
|
||||
|
||||
export interface ClientConfig {
|
||||
applicationTitle: string;
|
||||
export interface ThumbnailConfig {
|
||||
iconSize: number;
|
||||
thumbnailSizes: Array<number>;
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
applicationTitle: string;
|
||||
Thumbnail: ThumbnailConfig;
|
||||
Search: SearchConfig;
|
||||
Sharing: SharingConfig;
|
||||
Map: MapConfig;
|
||||
@ -29,15 +33,18 @@ export interface ClientConfig {
|
||||
publicUrl: string;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* These configuration will be available at frontend and backend too
|
||||
*/
|
||||
export class PublicConfigClass {
|
||||
|
||||
public Client: ClientConfig = {
|
||||
public Client: ClientConfig.Config = {
|
||||
applicationTitle: "PiGallery 2",
|
||||
Thumbnail: {
|
||||
thumbnailSizes: [200, 400, 600],
|
||||
iconSize: 30,
|
||||
iconSize: 30
|
||||
},
|
||||
Search: {
|
||||
enabled: true,
|
||||
instantSearchEnabled: true,
|
||||
|
@ -20,7 +20,7 @@ export enum ErrorCodes{
|
||||
SETTINGS_ERROR = 11
|
||||
}
|
||||
|
||||
export class Error {
|
||||
export class ErrorDTO {
|
||||
constructor(public code: ErrorCodes, public message?: string, public details?: any) {
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {Error} from "./Error";
|
||||
import {ErrorDTO} from "./Error";
|
||||
|
||||
export class Message<T> {
|
||||
public error: Error = null;
|
||||
public error: ErrorDTO = null;
|
||||
public result: T = null;
|
||||
|
||||
constructor(error: Error, result: T) {
|
||||
constructor(error: ErrorDTO, result: T) {
|
||||
this.error = error;
|
||||
this.result = result;
|
||||
}
|
||||
|
@ -21,8 +21,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<settings-usermanager *ngIf="userManagementEnable"></settings-usermanager>
|
||||
<settings-usermanager></settings-usermanager>
|
||||
<settings-database></settings-database>
|
||||
<settings-map></settings-map>
|
||||
<settings-thumbnail></settings-thumbnail>
|
||||
</div>
|
||||
</app-frame>
|
||||
|
@ -1,28 +1,25 @@
|
||||
import {Component, OnInit} from "@angular/core";
|
||||
import {AuthenticationService} from "../model/network/authentication.service";
|
||||
import {Router} from "@angular/router";
|
||||
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {NotificationService} from "../model/notification.service";
|
||||
import {NotificationType} from "../../../common/entities/NotificationDTO";
|
||||
import {NavigationService} from "../model/navigation.service";
|
||||
@Component({
|
||||
selector: 'admin',
|
||||
templateUrl: './admin.component.html',
|
||||
styleUrls: ['./admin.component.css']
|
||||
})
|
||||
export class AdminComponent implements OnInit {
|
||||
userManagementEnable: boolean = false;
|
||||
|
||||
constructor(private _authService: AuthenticationService,
|
||||
private _router: Router,
|
||||
private _navigation: NavigationService,
|
||||
public notificationService: NotificationService) {
|
||||
this.userManagementEnable = Config.Client.authenticationRequired;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (!this._authService.isAuthenticated()
|
||||
|| this._authService.user.value.role < UserRoles.Admin) {
|
||||
this._router.navigate(['login']);
|
||||
this._navigation.toLogin();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ import {ClipboardModule} from "ngx-clipboard";
|
||||
import {NavigationService} from "./model/navigation.service";
|
||||
import {InfoPanelLightboxComponent} from "./gallery/lightbox/infopanel/info-panel.lightbox.gallery.component";
|
||||
import {MapSettingsComponent} from "./settings/map/map.settings.component";
|
||||
|
||||
import {TooltipModule} from "ngx-bootstrap/tooltip";
|
||||
import {ThumbnailSettingsComponent} from "./settings/thumbnail/thumbanil.settings.component";
|
||||
@Injectable()
|
||||
export class GoogleMapsConfig {
|
||||
apiKey: string;
|
||||
@ -65,6 +66,7 @@ export class GoogleMapsConfig {
|
||||
appRoutes,
|
||||
ClipboardModule,
|
||||
JWBootstrapSwitchModule,
|
||||
TooltipModule.forRoot(),
|
||||
ToastModule.forRoot(),
|
||||
ModalModule.forRoot(),
|
||||
AgmCoreModule.forRoot(),
|
||||
@ -94,6 +96,7 @@ export class GoogleMapsConfig {
|
||||
UserMangerSettingsComponent,
|
||||
DatabaseSettingsComponent,
|
||||
MapSettingsComponent,
|
||||
ThumbnailSettingsComponent,
|
||||
StringifyRole],
|
||||
providers: [
|
||||
{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig},
|
||||
|
@ -19,7 +19,7 @@ export class Photo extends IconPhoto {
|
||||
|
||||
getThumbnailSize() {
|
||||
let renderSize = Math.sqrt(this.renderWidth * this.renderHeight);
|
||||
return Utils.findClosest(renderSize, Config.Client.thumbnailSizes);
|
||||
return Utils.findClosest(renderSize, Config.Client.Thumbnail.thumbnailSizes);
|
||||
}
|
||||
|
||||
getReplacementThumbnailSize(): number {
|
||||
|
@ -0,0 +1,37 @@
|
||||
.title {
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.panel-heading bSwitch {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.switch-wrapper {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
text-align: right;
|
||||
padding: 0;
|
||||
|
||||
}
|
@ -2,7 +2,7 @@ import {OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||
import {UserRoles} from "../../../../common/entities/UserDTO";
|
||||
import {Utils} from "../../../../common/Utils";
|
||||
import {Error} from "../../../../common/entities/Error";
|
||||
import {ErrorDTO} from "../../../../common/entities/Error";
|
||||
import {NotificationService} from "../../model/notification.service";
|
||||
import {NavigationService} from "../../model/navigation.service";
|
||||
import {ISettingsService} from "./abstract.settings.service";
|
||||
@ -11,13 +11,12 @@ import {ISettingsService} from "./abstract.settings.service";
|
||||
export abstract class SettingsComponent<T> implements OnInit, OnDestroy {
|
||||
|
||||
@ViewChild('settingsForm') form;
|
||||
public settings: T;
|
||||
public settings: T = <T>{};
|
||||
public inProgress = false;
|
||||
private original: T;
|
||||
public tested = false;
|
||||
private original: T = <T>{};
|
||||
public error: string = null;
|
||||
public changed: boolean = false;
|
||||
private subscription;
|
||||
private subscription = null;
|
||||
|
||||
constructor(private name,
|
||||
private _authService: AuthenticationService,
|
||||
@ -37,8 +36,6 @@ export abstract class SettingsComponent<T> implements OnInit, OnDestroy {
|
||||
|
||||
this.subscription = this.form.valueChanges.subscribe((data) => {
|
||||
this.changed = !Utils.equalsFilter(this.settings, this.original);
|
||||
|
||||
this.tested = false;
|
||||
});
|
||||
}
|
||||
|
||||
@ -52,7 +49,7 @@ export abstract class SettingsComponent<T> implements OnInit, OnDestroy {
|
||||
const s = await this._settingsService.getSettings();
|
||||
this.original = Utils.clone(s);
|
||||
this.settings = s;
|
||||
this.tested = false;
|
||||
console.log(this.settings);
|
||||
this.changed = false;
|
||||
}
|
||||
|
||||
@ -61,30 +58,22 @@ export abstract class SettingsComponent<T> implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
|
||||
public async test() {
|
||||
this.inProgress = true;
|
||||
try {
|
||||
this.error = "";
|
||||
await this._settingsService.testSettings(this.settings);
|
||||
this.tested = true;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if (err.message) {
|
||||
this.error = (<Error>err).message;
|
||||
}
|
||||
}
|
||||
this.inProgress = false;
|
||||
}
|
||||
|
||||
public async save() {
|
||||
if (!this.tested) {
|
||||
return;
|
||||
}
|
||||
this.inProgress = true;
|
||||
this.error = "";
|
||||
try {
|
||||
await this._settingsService.updateSettings(this.settings);
|
||||
await this.getSettings();
|
||||
this.notification.success(this.name + ' settings saved', "Success");
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if (err.message) {
|
||||
this.error = (<ErrorDTO>err).message;
|
||||
}
|
||||
}
|
||||
this.inProgress = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
export interface ISettingsService<T> {
|
||||
getSettings(): Promise<T>;
|
||||
updateSettings(settings: T): Promise<void>;
|
||||
testSettings(settings: T): Promise<void> ;
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
.title {
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
margin: 5px 0;
|
||||
}
|
@ -23,13 +23,7 @@
|
||||
</ng-container>
|
||||
|
||||
</form>
|
||||
<button class="btn btn-primary pull-right"
|
||||
*ngIf="tested==false"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
(click)="test()">Test
|
||||
</button>
|
||||
<button class="btn btn-success pull-right"
|
||||
*ngIf="tested==true"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
(click)="save()">Save
|
||||
</button>
|
||||
|
@ -10,7 +10,8 @@ import {DatabaseSettingsService} from "./database.settings.service";
|
||||
@Component({
|
||||
selector: 'settings-database',
|
||||
templateUrl: './database.settings.component.html',
|
||||
styleUrls: ['./database.settings.component.css'],
|
||||
styleUrls: ['./database.settings.component.css',
|
||||
'./../_abstract/abstract.settings.component.css'],
|
||||
providers: [DatabaseSettingsService],
|
||||
})
|
||||
export class DatabaseSettingsComponent extends SettingsComponent<DataBaseConfig> {
|
||||
|
@ -15,7 +15,4 @@ export class DatabaseSettingsService {
|
||||
return this._networkService.putJson("/settings/database", {settings: settings});
|
||||
}
|
||||
|
||||
public testSettings(settings: DataBaseConfig): Promise<void> {
|
||||
return this._networkService.postJson<void>("/settings/test/database", {settings: settings});
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
.title {
|
||||
margin-left: -5px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
margin: 5px 0;
|
||||
}
|
@ -1,22 +1,26 @@
|
||||
<form #settingsForm="ngForm">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Map settings</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
<form #settingsForm="ngForm">
|
||||
<p>
|
||||
<h3 class="panel-title col-sm-4">Map settings</h3>
|
||||
<div class="switch-wrapper col-sm-8">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
name="enabled"
|
||||
[switch-on-color]="'success'"
|
||||
[switch-inverse]="'inverse'"
|
||||
[switch-off-text]="'Disabled'"
|
||||
[switch-on-text]="'Enabled'"
|
||||
[switch-disabled]="inProgress"
|
||||
[switch-handle-width]="'100'"
|
||||
[switch-label-width]="'20'"
|
||||
[(ngModel)]="settings.enabled">
|
||||
</bSwitch>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
||||
|
||||
<input type="text" class="form-control" placeholder="Google api key" autofocus
|
||||
[(ngModel)]="settings.googleApiKey"
|
||||
[disabled]="!settings.enabled"
|
||||
@ -24,14 +28,7 @@
|
||||
<span class="help-block">To show the images on a map, <a
|
||||
href="https://developers.google.com/maps/documentation/javascript/get-api-key">google api key</a> is need</span>
|
||||
|
||||
</form>
|
||||
<button class="btn btn-primary pull-right"
|
||||
*ngIf="tested==false"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
(click)="test()">Test
|
||||
</button>
|
||||
<button class="btn btn-success pull-right"
|
||||
*ngIf="tested==true"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
(click)="save()">Save
|
||||
</button>
|
||||
@ -40,3 +37,5 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
@ -1,19 +1,20 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {MapConfig} from "../../../../common/config/public/ConfigClass";
|
||||
import {MapSettingsService} from "./map.settings.service";
|
||||
import {SettingsComponent} from "../_abstract/abstract.settings.component";
|
||||
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||
import {NavigationService} from "../../model/navigation.service";
|
||||
import {NotificationService} from "../../model/notification.service";
|
||||
import {ClientConfig} from "../../../../common/config/public/ConfigClass";
|
||||
|
||||
@Component({
|
||||
selector: 'settings-map',
|
||||
templateUrl: './map.settings.component.html',
|
||||
styleUrls: ['./map.settings.component.css'],
|
||||
styleUrls: ['./map.settings.component.css',
|
||||
'./../_abstract/abstract.settings.component.css'],
|
||||
providers: [MapSettingsService],
|
||||
})
|
||||
export class MapSettingsComponent extends SettingsComponent<MapConfig> {
|
||||
public settings: MapConfig = <MapConfig> {
|
||||
export class MapSettingsComponent extends SettingsComponent<ClientConfig.MapConfig> {
|
||||
public settings: ClientConfig.MapConfig = <ClientConfig.MapConfig> {
|
||||
enabled: true,
|
||||
googleApiKey: ""
|
||||
};
|
||||
|
@ -1,22 +1,19 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {NetworkService} from "../../model/network/network.service";
|
||||
import {MapConfig} from "../../../../common/config/public/ConfigClass";
|
||||
import {IPrivateConfig} from "../../../../common/config/private/IPrivateConfig";
|
||||
import {ClientConfig} from "../../../../common/config/public/ConfigClass";
|
||||
|
||||
@Injectable()
|
||||
export class MapSettingsService {
|
||||
constructor(private _networkService: NetworkService) {
|
||||
}
|
||||
|
||||
public async getSettings(): Promise<MapConfig> {
|
||||
public async getSettings(): Promise<ClientConfig.MapConfig> {
|
||||
return (await <Promise<IPrivateConfig>>this._networkService.getJson("/settings")).Client.Map;
|
||||
}
|
||||
|
||||
public updateSettings(settings: MapConfig): Promise<void> {
|
||||
public updateSettings(settings: ClientConfig.MapConfig): Promise<void> {
|
||||
return this._networkService.putJson("/settings/map", {settings: settings});
|
||||
}
|
||||
|
||||
public testSettings(settings: MapConfig): Promise<void> {
|
||||
return this._networkService.postJson<void>("/settings/test/map", {settings: settings});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
<form #settingsForm="ngForm" class="form-horizontal">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Thumbnail settings</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
<div [hidden]="settings.server.processingLibrary!=ThumbnailProcessingLib.Jimp" class="alert alert-warning"
|
||||
role="alert">It is highly recommended to use hardware accelerated (sharp or gm) lib for thumbnail generation
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="lib">Thumbnail generation library</label>
|
||||
<div class="col-sm-10">
|
||||
<select id="lib" class="form-control" [(ngModel)]="settings.server.processingLibrary" name="type" required>
|
||||
<option *ngFor="let type of types" [ngValue]="type.key">{{type.value}}
|
||||
</option>
|
||||
</select>
|
||||
<span *ngIf="settings.server.processingLibrary==ThumbnailProcessingLib.sharp" class="help-block">Make sure that sharp node module is installed (npm install sharp)</span>
|
||||
<span *ngIf="settings.server.processingLibrary==ThumbnailProcessingLib.gm" class="help-block">Make sure that gm node module and <a
|
||||
href="http://www.graphicsmagick.org/">GraphicsMagick</a> are installed (npm install sharp)</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="folder">Thumbnail folder</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" placeholder="path"
|
||||
id="folder"
|
||||
[(ngModel)]="settings.server.folder"
|
||||
name="path" required>
|
||||
<span class="help-block">Thumbnails will be saved in this folder. Write access is required</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="quality">Thumbnail Quality</label>
|
||||
<div class="col-sm-10">
|
||||
<bSwitch
|
||||
id="quality"
|
||||
class="switch"
|
||||
name="enabled"
|
||||
[switch-on-color]="'primary'"
|
||||
[switch-inverse]="'inverse'"
|
||||
[switch-off-text]="'Low'"
|
||||
[switch-on-text]="'High'"
|
||||
[switch-handle-width]="'100'"
|
||||
[switch-label-width]="'20'"
|
||||
[(ngModel)]="settings.server.qualityPriority">
|
||||
</bSwitch>
|
||||
<span class="help-block">High quality may be slow. Especially with Jimp.</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="icon">Icon size</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" class="form-control" placeholder="30"
|
||||
id="icon"
|
||||
[(ngModel)]="settings.client.iconSize"
|
||||
min="1"
|
||||
max="100"
|
||||
step="1"
|
||||
name="icon" required>
|
||||
<span class="help-block">Icon size (used on maps)</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="thumbnailSizes">Thumbnail sizes</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" placeholder="200; 400"
|
||||
id="thumbnailSizes"
|
||||
[(ngModel)]="ThumbnailSizes"
|
||||
name="thumbnailSizes" required>
|
||||
<span class="help-block">
|
||||
Size of the thumbnails.<br/>
|
||||
The best matching size will be generated. (More size gives better quality, but use storage to store and CPU to render.)<br/>
|
||||
';' separated integers. If size is 200, tha thumbnail will have 200^2 pixels.
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<button class="btn btn-success pull-right"
|
||||
[disabled]="!settingsForm.form.valid || !changed || inProgress"
|
||||
(click)="save()">Save
|
||||
</button>
|
||||
<button class="btn btn-default pull-right"
|
||||
(click)="reset()">Reset
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
@ -0,0 +1,65 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {SettingsComponent} from "../_abstract/abstract.settings.component";
|
||||
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||
import {NavigationService} from "../../model/navigation.service";
|
||||
import {NotificationService} from "../../model/notification.service";
|
||||
import {ThumbnailConfig, ThumbnailProcessingLib} from "../../../../common/config/private/IPrivateConfig";
|
||||
import {ClientConfig} from "../../../../common/config/public/ConfigClass";
|
||||
import {ThumbnailSettingsService} from "./thumbanil.settings.service";
|
||||
import {Utils} from "../../../../common/Utils";
|
||||
|
||||
@Component({
|
||||
selector: 'settings-thumbnail',
|
||||
templateUrl: './thumbanil.settings.component.html',
|
||||
styleUrls: ['./thumbanil.settings.component.css',
|
||||
'./../_abstract/abstract.settings.component.css'],
|
||||
providers: [ThumbnailSettingsService],
|
||||
})
|
||||
export class ThumbnailSettingsComponent extends SettingsComponent<{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }> {
|
||||
public settings: { server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig } = <{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }> {
|
||||
server: {
|
||||
folder: "",
|
||||
processingLibrary: ThumbnailProcessingLib.Jimp,
|
||||
qualityPriority: true
|
||||
},
|
||||
client: {
|
||||
iconSize: null,
|
||||
thumbnailSizes: []
|
||||
}
|
||||
};
|
||||
types: Array<any> = [];
|
||||
ThumbnailProcessingLib: any;
|
||||
|
||||
constructor(_authService: AuthenticationService,
|
||||
_navigation: NavigationService,
|
||||
_settingsSettings: ThumbnailSettingsService,
|
||||
notification: NotificationService) {
|
||||
super("Thumbnail", _authService, _navigation, _settingsSettings, notification);
|
||||
}
|
||||
|
||||
get ThumbnailSizes(): string {
|
||||
return this.settings.client.thumbnailSizes.join("; ");
|
||||
}
|
||||
|
||||
set ThumbnailSizes(value: string) {
|
||||
value = value.replace(new RegExp(',', 'g'), ";");
|
||||
value = value.replace(new RegExp(' ', 'g'), ";");
|
||||
this.settings.client.thumbnailSizes = value.split(";").map(s => parseInt(s)).filter(i => !isNaN(i) && i > 0);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.types = Utils
|
||||
.enumToArray(ThumbnailProcessingLib).map((v) => {
|
||||
if (v.value.toLowerCase() == "sharp") {
|
||||
v.value += " (recommended)";
|
||||
}
|
||||
return v;
|
||||
});
|
||||
this.ThumbnailProcessingLib = ThumbnailProcessingLib;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {NetworkService} from "../../model/network/network.service";
|
||||
import {ClientConfig} from "../../../../common/config/public/ConfigClass";
|
||||
import {IPrivateConfig, ThumbnailConfig} from "../../../../common/config/private/IPrivateConfig";
|
||||
import {ISettingsService} from "../_abstract/abstract.settings.service";
|
||||
|
||||
@Injectable()
|
||||
export class ThumbnailSettingsService implements ISettingsService<{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }> {
|
||||
constructor(private _networkService: NetworkService) {
|
||||
}
|
||||
|
||||
public async getSettings(): Promise<{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }> {
|
||||
const settings = (await <Promise<IPrivateConfig>>this._networkService.getJson("/settings"));
|
||||
return {server: settings.Server.thumbnail, client: settings.Client.Thumbnail};
|
||||
}
|
||||
|
||||
public updateSettings(settings: { server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }): Promise<void> {
|
||||
return this._networkService.putJson("/settings/thumbnail", {settings: settings});
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
.form-control {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.panel-info {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -1,9 +1,26 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">User management</h3>
|
||||
<h3 class="panel-title col-sm-4">Password protection </h3>
|
||||
<div class="switch-wrapper col-sm-8">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
name="enabled"
|
||||
[switch-on-color]="'success'"
|
||||
[switch-inverse]="'inverse'"
|
||||
[switch-off-text]="'Disabled'"
|
||||
[switch-on-text]="'Enabled'"
|
||||
[switch-handle-width]="'100'"
|
||||
[switch-label-width]="'20'"
|
||||
[switch-disabled]="inProgress"
|
||||
[(ngModel)]="enabled"
|
||||
(onChangeState)="switched($event)">
|
||||
</bSwitch>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
||||
<ng-container *ngIf="enabled">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -38,6 +55,10 @@
|
||||
(click)="initNewUser()">+ Add
|
||||
user
|
||||
</button>
|
||||
</ng-container>
|
||||
<div class="panel-info" *ngIf="!enabled">
|
||||
To protect the site with password / have login enable this
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -5,11 +5,14 @@ import {Utils} from "../../../../common/Utils";
|
||||
import {UserManagerSettingsService} from "./usermanager.settings.service";
|
||||
import {ModalDirective} from "ngx-bootstrap/modal";
|
||||
import {NavigationService} from "../../model/navigation.service";
|
||||
import {NotificationService} from "../../model/notification.service";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../../common/entities/Error";
|
||||
|
||||
@Component({
|
||||
selector: 'settings-usermanager',
|
||||
templateUrl: './usermanager.settings.component.html',
|
||||
styleUrls: ['./usermanager.settings.component.css'],
|
||||
styleUrls: ['./usermanager.settings.component.css',
|
||||
'./../_abstract/abstract.settings.component.css'],
|
||||
providers: [UserManagerSettingsService],
|
||||
})
|
||||
export class UserMangerSettingsComponent implements OnInit {
|
||||
@ -17,10 +20,17 @@ export class UserMangerSettingsComponent implements OnInit {
|
||||
public newUser = <UserDTO>{};
|
||||
public userRoles: Array<any> = [];
|
||||
public users: Array<UserDTO> = [];
|
||||
public enabled = true;
|
||||
public error: string = null;
|
||||
public inProgress = false;
|
||||
|
||||
constructor(private _authService: AuthenticationService, private _navigation: NavigationService, private _userSettings: UserManagerSettingsService) {
|
||||
constructor(private _authService: AuthenticationService,
|
||||
private _navigation: NavigationService,
|
||||
private _userSettings: UserManagerSettingsService,
|
||||
private notification: NotificationService) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
if (!this._authService.isAuthenticated() ||
|
||||
this._authService.user.value.role < UserRoles.Admin) {
|
||||
@ -33,11 +43,23 @@ export class UserMangerSettingsComponent implements OnInit {
|
||||
.filter(r => r.key <= this._authService.user.value.role)
|
||||
.sort((a, b) => a.key - b.key);
|
||||
|
||||
this.getSettings();
|
||||
this.getUsersList();
|
||||
}
|
||||
|
||||
private async getUsersList() {
|
||||
try {
|
||||
this.users = await this._userSettings.getUsers();
|
||||
} catch (err) {
|
||||
this.users = [];
|
||||
if ((<ErrorDTO>err).code != ErrorCodes.USER_MANAGEMENT_DISABLED) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async getSettings() {
|
||||
this.enabled = await this._userSettings.getSettings();
|
||||
}
|
||||
|
||||
|
||||
@ -72,6 +94,28 @@ export class UserMangerSettingsComponent implements OnInit {
|
||||
await this.getUsersList();
|
||||
this.childModal.hide();
|
||||
}
|
||||
|
||||
async switched(event: { previousValue: false, currentValue: true }) {
|
||||
this.inProgress = true;
|
||||
this.error = "";
|
||||
this.enabled = event.currentValue;
|
||||
try {
|
||||
await this._userSettings.updateSettings(this.enabled);
|
||||
await this.getSettings();
|
||||
if (this.enabled == true) {
|
||||
this.notification.success('Password protection enabled', "Success");
|
||||
this.getUsersList();
|
||||
} else {
|
||||
this.notification.success('Password protection disabled', "Success");
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
if (err.message) {
|
||||
this.error = (<ErrorDTO>err).message;
|
||||
}
|
||||
}
|
||||
this.inProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {UserDTO} from "../../../../common/entities/UserDTO";
|
||||
import {NetworkService} from "../../model/network/network.service";
|
||||
import {IPrivateConfig} from "../../../../common/config/private/IPrivateConfig";
|
||||
|
||||
@Injectable()
|
||||
export class UserManagerSettingsService {
|
||||
@ -13,6 +14,13 @@ export class UserManagerSettingsService {
|
||||
return this._networkService.putJson("/user", {newUser: user});
|
||||
}
|
||||
|
||||
public async getSettings(): Promise<boolean> {
|
||||
return (await <Promise<IPrivateConfig>>this._networkService.getJson("/settings")).Client.authenticationRequired;
|
||||
}
|
||||
|
||||
public updateSettings(settings: boolean): Promise<void> {
|
||||
return this._networkService.putJson("/settings/authentication", {settings: settings});
|
||||
}
|
||||
|
||||
public getUsers(): Promise<Array<UserDTO>> {
|
||||
return this._networkService.getJson("/user/list");
|
||||
|
@ -7,9 +7,11 @@
|
||||
<link rel="shortcut icon" href="assets/icon.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="../node_modules/ng2-toastr/bundles/ng2-toastr.min.css" rel="stylesheet"/>
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap3/bootstrap-switch.css">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.4/css/bootstrap3/bootstrap-switch.css">
|
||||
|
||||
<script type="text/javascript" src="config_inject.js"></script>
|
||||
</head>
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
||||
"@types/node": "^8.0.13",
|
||||
"@types/sharp": "^0.17.2",
|
||||
"@types/winston": "^2.3.3",
|
||||
"bootstrap": "^3.3.7",
|
||||
"chai": "^4.1.0",
|
||||
"codelyzer": "~3.1.2",
|
||||
"core-js": "^2.4.1",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {expect} from "chai";
|
||||
import {AuthenticationMWs} from "../../../../../backend/middlewares/user/AuthenticationMWs";
|
||||
import {Error, ErrorCodes} from "../../../../../common/entities/Error";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../../../common/entities/Error";
|
||||
import {UserDTO, UserRoles} from "../../../../../common/entities/UserDTO";
|
||||
import {ObjectManagerRepository} from "../../../../../backend/model/ObjectManagerRepository";
|
||||
import {UserManager} from "../../../../../backend/model/memory/UserManager";
|
||||
@ -38,7 +38,7 @@ describe('Authentication middleware', () => {
|
||||
};
|
||||
Config.Client.authenticationRequired = true;
|
||||
let res: any = {};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.NOT_AUTHENTICATED);
|
||||
done();
|
||||
@ -71,7 +71,7 @@ describe('Authentication middleware', () => {
|
||||
}
|
||||
};
|
||||
let res: any = {};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.ALREADY_AUTHENTICATED);
|
||||
done();
|
||||
@ -106,7 +106,7 @@ describe('Authentication middleware', () => {
|
||||
}
|
||||
}
|
||||
};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.NOT_AUTHORISED);
|
||||
done();
|
||||
@ -121,13 +121,13 @@ describe('Authentication middleware', () => {
|
||||
ObjectManagerRepository.reset();
|
||||
});
|
||||
|
||||
describe('should call input Error next on missing...', () => {
|
||||
describe('should call input ErrorDTO next on missing...', () => {
|
||||
it('body', (done) => {
|
||||
let req: any = {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.INPUT_ERROR);
|
||||
done();
|
||||
@ -142,7 +142,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.INPUT_ERROR);
|
||||
done();
|
||||
@ -159,7 +159,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.INPUT_ERROR);
|
||||
done();
|
||||
@ -181,7 +181,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.CREDENTIAL_NOT_FOUND);
|
||||
done();
|
||||
@ -208,7 +208,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
let next: any = (err: Error) => {
|
||||
let next: any = (err: ErrorDTO) => {
|
||||
expect(err).to.be.undefined;
|
||||
expect(req.session.user).to.be.eql("test user");
|
||||
done();
|
||||
|
Loading…
x
Reference in New Issue
Block a user