diff --git a/.travis.yml b/.travis.yml index e22e4b8..564b3b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: trusty language: node_js node_js: - '9' @@ -14,3 +15,9 @@ deploy: cache: directories: - node_modules + +addons: + chrome: stable +before_install: + - # start your web application and listen on `localhost` + - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & diff --git a/backend/Logger.ts b/backend/Logger.ts index c29546d..7945cac 100644 --- a/backend/Logger.ts +++ b/backend/Logger.ts @@ -1,4 +1,4 @@ -import * as winston from "winston"; +import * as winston from 'winston'; declare module 'winston' { interface LoggerInstance { @@ -10,19 +10,19 @@ declare module 'winston' { export const winstonSettings = { transports: [ new winston.transports.Console({ - level: process.env.NODE_ENV == "production" ? "info" : 'silly', + level: process.env.NODE_ENV == 'production' ? 'info' : 'silly', handleExceptions: true, json: false, colorize: true, timestamp: function () { return (new Date()).toLocaleString(); }, - label: "innerLabel", + label: 'innerLabel', formatter: (options) => { // Return string will be passed to logger. return options.timestamp() + '[' + winston['config']['colorize'](options.level, options.level.toUpperCase()) + '] ' + (undefined !== options.message ? options.message : '') + - (options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : '' ); + (options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : ''); }, debugStdout: true }) diff --git a/backend/ProjectPath.ts b/backend/ProjectPath.ts index d211e65..bfb9d36 100644 --- a/backend/ProjectPath.ts +++ b/backend/ProjectPath.ts @@ -1,5 +1,5 @@ -import * as path from "path"; -import {Config} from "../common/config/private/Config"; +import * as path from 'path'; +import {Config} from '../common/config/private/Config'; class ProjectPathClass { public Root: string; @@ -24,10 +24,10 @@ class ProjectPathClass { } reset() { - this.Root = path.join(__dirname, "/../"); + this.Root = path.join(__dirname, '/../'); this.ImageFolder = this.getAbsolutePath(Config.Server.imagesFolder); this.ThumbnailFolder = this.getAbsolutePath(Config.Server.thumbnail.folder); - this.FrontendFolder = path.join(this.Root, 'dist') + this.FrontendFolder = path.join(this.Root, 'dist'); } } diff --git a/backend/index.ts b/backend/index.ts index 1a8a122..cb352c3 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -1,9 +1,9 @@ -import * as cluster from "cluster"; +import * as cluster from 'cluster'; if (cluster.isMaster) { - const Server = require("./server").Server; - new Server(); + const Server = require('./server').Server; + const srv = new Server(); } else { - const Worker = require("./model/threading/Worker").Worker; + const Worker = require('./model/threading/Worker').Worker; Worker.process(); } diff --git a/backend/middlewares/AdminMWs.ts b/backend/middlewares/AdminMWs.ts index e53f3fc..99e80a4 100644 --- a/backend/middlewares/AdminMWs.ts +++ b/backend/middlewares/AdminMWs.ts @@ -1,23 +1,18 @@ -import {NextFunction, Request, Response} from "express"; -import {ErrorCodes, ErrorDTO} from "../../common/entities/Error"; -import {ObjectManagerRepository} from "../model/ObjectManagerRepository"; -import {Logger} from "../Logger"; -import {SQLConnection} from "../model/sql/SQLConnection"; -import { - DataBaseConfig, - DatabaseType, - IndexingConfig, - ThumbnailConfig -} from "../../common/config/private/IPrivateConfig"; -import {Config} from "../../common/config/private/Config"; -import {ConfigDiagnostics} from "../model/ConfigDiagnostics"; -import {ClientConfig} from "../../common/config/public/ConfigClass"; -import {BasicConfigDTO} from "../../common/entities/settings/BasicConfigDTO"; -import {OtherConfigDTO} from "../../common/entities/settings/OtherConfigDTO"; -import {ProjectPath} from "../ProjectPath"; +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; +import {ObjectManagerRepository} from '../model/ObjectManagerRepository'; +import {Logger} from '../Logger'; +import {SQLConnection} from '../model/sql/SQLConnection'; +import {DataBaseConfig, DatabaseType, IndexingConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig'; +import {Config} from '../../common/config/private/Config'; +import {ConfigDiagnostics} from '../model/ConfigDiagnostics'; +import {ClientConfig} from '../../common/config/public/ConfigClass'; +import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO'; +import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO'; +import {ProjectPath} from '../ProjectPath'; -const LOG_TAG = "[AdminMWs]"; +const LOG_TAG = '[AdminMWs]'; export class AdminMWs { @@ -25,30 +20,30 @@ 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 ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } const databaseSettings = req.body.settings; try { - if (databaseSettings.type != DatabaseType.memory) { + if (databaseSettings.type !== DatabaseType.memory) { await SQLConnection.tryConnection(databaseSettings); } Config.Server.database = databaseSettings; - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); original.Server.database = databaseSettings; - if (databaseSettings.type == DatabaseType.memory) { + if (databaseSettings.type === DatabaseType.memory) { original.Client.Sharing.enabled = false; original.Client.Search.enabled = false; } original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); ObjectManagerRepository.reset(); - if (Config.Server.database.type != DatabaseType.memory) { + if (Config.Server.database.type !== DatabaseType.memory) { await ObjectManagerRepository.InitSQLManagers(); } else { await ObjectManagerRepository.InitMemoryManagers(); @@ -57,41 +52,41 @@ export class AdminMWs { return next(); } catch (err) { if (err instanceof Error) { - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Error while saving database settings: " + err.toString(), err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Error while saving database settings: ' + err.toString(), err)); } - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Error while saving database settings", err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Error while saving database settings', err)); } } public static async updateMapSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { await ConfigDiagnostics.testMapConfig(req.body.settings); Config.Client.Map = req.body.settings; - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); original.Client.Map = req.body.settings; original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(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 updateShareSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); await ConfigDiagnostics.testSharingConfig(req.body.settings, original); @@ -99,22 +94,22 @@ export class AdminMWs { original.Client.Sharing = req.body.settings; original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(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 updateSearchSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); await ConfigDiagnostics.testSearchConfig(req.body.settings, original); @@ -122,38 +117,38 @@ export class AdminMWs { original.Client.Search = req.body.settings; original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(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 updateAuthenticationSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { Config.Client.authenticationRequired = req.body.settings; - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); original.Client.authenticationRequired = req.body.settings; original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { @@ -166,28 +161,28 @@ export class AdminMWs { 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) + // 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(); ProjectPath.reset(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + 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: ' + err.toString(), err)); } - return next(new ErrorDTO(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 updateBasicSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { @@ -197,7 +192,7 @@ export class AdminMWs { Config.Server.imagesFolder = settings.imagesFolder; Config.Client.publicUrl = settings.publicUrl; Config.Client.applicationTitle = settings.applicationTitle; - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); original.Server.port = settings.port; original.Server.imagesFolder = settings.imagesFolder; @@ -206,18 +201,18 @@ export class AdminMWs { original.save(); ProjectPath.reset(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(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 updateOtherSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { @@ -226,7 +221,7 @@ export class AdminMWs { Config.Client.enableOnScrollRendering = settings.enableOnScrollRendering; Config.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising; - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); original.Client.enableCache = settings.enableCache; original.Client.enableOnScrollRendering = settings.enableOnScrollRendering; @@ -234,33 +229,33 @@ export class AdminMWs { original.Server.enableThreading = settings.enableThreading; original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(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 updateIndexingSettings(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")); + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed')); } try { const settings: IndexingConfig = req.body.settings; Config.Server.indexing = settings; - //only updating explicitly set config (not saving config set by the diagnostics) + // only updating explicitly set config (not saving config set by the diagnostics) const original = Config.original(); original.Server.indexing = settings; original.save(); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "new config:"); + Logger.info(LOG_TAG, 'new config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err)); } } @@ -268,10 +263,10 @@ export class AdminMWs { public static startIndexing(req: Request, res: Response, next: NextFunction) { try { ObjectManagerRepository.getInstance().IndexingManager.startIndexing(); - req.resultPipe = "ok"; + req.resultPipe = 'ok'; return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err)); } } @@ -280,27 +275,27 @@ export class AdminMWs { req.resultPipe = ObjectManagerRepository.getInstance().IndexingManager.getProgress(); return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err)); } } public static cancelIndexing(req: Request, res: Response, next: NextFunction) { try { ObjectManagerRepository.getInstance().IndexingManager.cancelIndexing(); - req.resultPipe = "ok"; + req.resultPipe = 'ok'; return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err)); } } public static async resetIndexes(req: Request, res: Response, next: NextFunction) { try { await ObjectManagerRepository.getInstance().IndexingManager.reset(); - req.resultPipe = "ok"; + req.resultPipe = 'ok'; return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err)); + return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err)); } } } diff --git a/backend/middlewares/GalleryMWs.ts b/backend/middlewares/GalleryMWs.ts index 4c8523c..a1c05be 100644 --- a/backend/middlewares/GalleryMWs.ts +++ b/backend/middlewares/GalleryMWs.ts @@ -1,29 +1,29 @@ -import * as path from "path"; -import * as fs from "fs"; -import {NextFunction, Request, Response} from "express"; -import {ErrorCodes, ErrorDTO} from "../../common/entities/Error"; -import {DirectoryDTO} from "../../common/entities/DirectoryDTO"; -import {ObjectManagerRepository} from "../model/ObjectManagerRepository"; -import {SearchTypes} from "../../common/entities/AutoCompleteItem"; -import {ContentWrapper} from "../../common/entities/ConentWrapper"; -import {PhotoDTO} from "../../common/entities/PhotoDTO"; -import {ProjectPath} from "../ProjectPath"; -import {Config} from "../../common/config/private/Config"; -import {UserDTO} from "../../common/entities/UserDTO"; +import * as path from 'path'; +import * as fs from 'fs'; +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; +import {DirectoryDTO} from '../../common/entities/DirectoryDTO'; +import {ObjectManagerRepository} from '../model/ObjectManagerRepository'; +import {SearchTypes} from '../../common/entities/AutoCompleteItem'; +import {ContentWrapper} from '../../common/entities/ConentWrapper'; +import {PhotoDTO} from '../../common/entities/PhotoDTO'; +import {ProjectPath} from '../ProjectPath'; +import {Config} from '../../common/config/private/Config'; +import {UserDTO} from '../../common/entities/UserDTO'; -const LOG_TAG = "[GalleryMWs]"; +const LOG_TAG = '[GalleryMWs]'; export class GalleryMWs { public static async listDirectory(req: Request, res: Response, next: NextFunction) { - console.log("listDirectory"); - let directoryName = req.params.directory || "/"; + console.log('listDirectory'); + let directoryName = req.params.directory || '/'; let absoluteDirectoryName = path.join(ProjectPath.ImageFolder, directoryName); if (!fs.statSync(absoluteDirectoryName).isDirectory()) { - console.log("not dir"); + console.log('not dir'); return next(); } @@ -31,7 +31,7 @@ export class GalleryMWs { const directory = await ObjectManagerRepository.getInstance().GalleryManager.listDirectory(directoryName, req.query.knownLastModified, req.query.knownLastScanned); if (directory == null) { - console.log("null dir"); + console.log('null dir'); req.resultPipe = new ContentWrapper(null, null, true); return next(); } @@ -39,7 +39,7 @@ export class GalleryMWs { console.log(directory); if (req.session.user.permissions && req.session.user.permissions.length > 0 && - req.session.user.permissions[0] != "/*") { + req.session.user.permissions[0] != '/*') { (directory).directories = (directory).directories.filter(d => UserDTO.isDirectoryAvailable(d, req.session.user.permissions)); } @@ -47,7 +47,7 @@ export class GalleryMWs { return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during listing the directory", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during listing the directory', err)); } } @@ -90,7 +90,7 @@ export class GalleryMWs { //check if thumbnail already exist if (fs.existsSync(fullImagePath) === false) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "no such file:" + fullImagePath)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'no such file:' + fullImagePath)); } if (fs.statSync(fullImagePath).isDirectory()) { return next(); @@ -122,7 +122,7 @@ export class GalleryMWs { req.resultPipe = new ContentWrapper(null, result); return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during searching", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during searching', err)); } } @@ -142,7 +142,7 @@ export class GalleryMWs { req.resultPipe = new ContentWrapper(null, result); return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during searching", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during searching', err)); } } @@ -158,7 +158,7 @@ export class GalleryMWs { req.resultPipe = await ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text); return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during searching", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during searching', err)); } } diff --git a/backend/middlewares/NotificationMWs.ts b/backend/middlewares/NotificationMWs.ts index 997e2a9..5e20cc0 100644 --- a/backend/middlewares/NotificationMWs.ts +++ b/backend/middlewares/NotificationMWs.ts @@ -1,8 +1,9 @@ -import {NextFunction, Request, Response} from "express"; -import {UserRoles} from "../../common/entities/UserDTO"; -import {NotificationManager} from "../model/NotifocationManager"; +import {NextFunction, Request, Response} from 'express'; +import {UserRoles} from '../../common/entities/UserDTO'; +import {NotificationManager} from '../model/NotifocationManager'; + +const LOG_TAG = '[NotificationMWs]'; -const LOG_TAG = "[NotificationMWs]"; export class NotificationMWs { diff --git a/backend/middlewares/RenderingMWs.ts b/backend/middlewares/RenderingMWs.ts index ce8cf5b..f2de48a 100644 --- a/backend/middlewares/RenderingMWs.ts +++ b/backend/middlewares/RenderingMWs.ts @@ -1,18 +1,18 @@ -import {NextFunction, Request, Response} from "express"; -import {ErrorCodes, ErrorDTO} from "../../common/entities/Error"; -import {Utils} from "../../common/Utils"; -import {Message} from "../../common/entities/Message"; -import {SharingDTO} from "../../common/entities/SharingDTO"; -import {Config} from "../../common/config/private/Config"; -import {PrivateConfigClass} from "../../common/config/private/PrivateConfigClass"; -import {UserRoles} from "../../common/entities/UserDTO"; -import {NotificationManager} from "../model/NotifocationManager"; -import {Logger} from "../Logger"; +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; +import {Utils} from '../../common/Utils'; +import {Message} from '../../common/entities/Message'; +import {SharingDTO} from '../../common/entities/SharingDTO'; +import {Config} from '../../common/config/private/Config'; +import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass'; +import {UserRoles} from '../../common/entities/UserDTO'; +import {NotificationManager} from '../model/NotifocationManager'; +import {Logger} from '../Logger'; export class RenderingMWs { public static renderResult(req: Request, res: Response, next: NextFunction) { - if (typeof req.resultPipe == "undefined") + if (typeof req.resultPipe == 'undefined') return next(); return RenderingMWs.renderMessage(res, req.resultPipe); @@ -21,7 +21,7 @@ export class RenderingMWs { public static renderSessionUser(req: Request, res: Response, next: NextFunction) { if (!(req.session.user)) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "User not exists")); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'User not exists')); } const user = Utils.clone(req.session.user); @@ -46,7 +46,7 @@ export class RenderingMWs { } public static renderOK(req: Request, res: Response, next: NextFunction) { - let message = new Message(null, "ok"); + let message = new Message(null, 'ok'); res.json(message); } @@ -62,7 +62,7 @@ export class RenderingMWs { if (err instanceof ErrorDTO) { if (err.details) { if (!(req.session.user && req.session.user.role >= UserRoles.Developer)) { - Logger.warn("Handled error:", err); + Logger.warn('Handled error:', err); delete (err.details); } else { try { @@ -75,7 +75,7 @@ export class RenderingMWs { let message = new Message(err, null); return res.json(message); } - NotificationManager.error("unknown server error", err); + NotificationManager.error('unknown server error', err); return next(err); } diff --git a/backend/middlewares/SharingMWs.ts b/backend/middlewares/SharingMWs.ts index aea1723..f4ce97b 100644 --- a/backend/middlewares/SharingMWs.ts +++ b/backend/middlewares/SharingMWs.ts @@ -1,9 +1,10 @@ -import {NextFunction, Request, Response} from "express"; -import {CreateSharingDTO, SharingDTO} from "../../common/entities/SharingDTO"; -import {ObjectManagerRepository} from "../model/ObjectManagerRepository"; -import {ErrorCodes, ErrorDTO} from "../../common/entities/Error"; +import {NextFunction, Request, Response} from 'express'; +import {CreateSharingDTO, SharingDTO} from '../../common/entities/SharingDTO'; +import {ObjectManagerRepository} from '../model/ObjectManagerRepository'; +import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; + +const LOG_TAG = '[SharingMWs]'; -const LOG_TAG = "[SharingMWs]"; export class SharingMWs { @@ -26,14 +27,14 @@ export class SharingMWs { return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during retrieving sharing link", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error 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 ErrorDTO(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(); @@ -50,7 +51,7 @@ export class SharingMWs { } - const directoryName = req.params.directory || "/"; + const directoryName = req.params.directory || '/'; let sharing: SharingDTO = { id: null, sharingKey: sharingKey, @@ -68,20 +69,20 @@ export class SharingMWs { return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during creating sharing link", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error 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 ErrorDTO(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 || "/"; + const directoryName = req.params.directory || '/'; let sharing: SharingDTO = { id: updateSharing.id, path: directoryName, - sharingKey: "", + sharingKey: '', password: updateSharing.password, creator: req.session.user, expires: Date.now() + updateSharing.valid, @@ -93,7 +94,7 @@ export class SharingMWs { req.resultPipe = await ObjectManagerRepository.getInstance().SharingManager.updateSharing(sharing); return next(); } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during updating sharing link", err)); + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during updating sharing link', err)); } } diff --git a/backend/middlewares/customtypings/jimp.d.ts b/backend/middlewares/customtypings/jimp.d.ts index 2d14da9..2b2445b 100644 --- a/backend/middlewares/customtypings/jimp.d.ts +++ b/backend/middlewares/customtypings/jimp.d.ts @@ -1,10 +1,10 @@ -declare module "jimp" { - function read(filaname); +declare module 'jimp' { + function read(fileName); - var RESIZE_NEAREST_NEIGHBOR; - var RESIZE_BILINEAR; - var RESIZE_BICUBIC; - var RESIZE_HERMITE; - var RESIZE_BEZIER; - var AUTO: any; + const RESIZE_NEAREST_NEIGHBOR; + const RESIZE_BILINEAR; + const RESIZE_BICUBIC; + const RESIZE_HERMITE; + const RESIZE_BEZIER; + const AUTO: any; } diff --git a/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts b/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts index ce51b74..bb00337 100644 --- a/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts +++ b/backend/middlewares/thumbnail/ThumbnailGeneratorMWs.ts @@ -1,19 +1,19 @@ /// -import * as path from "path"; -import * as crypto from "crypto"; -import * as fs from "fs"; -import * as os from "os"; -import {NextFunction, Request, Response} from "express"; -import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error"; -import {ContentWrapper} from "../../../common/entities/ConentWrapper"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {ProjectPath} from "../../ProjectPath"; -import {PhotoDTO} from "../../../common/entities/PhotoDTO"; -import {Config} from "../../../common/config/private/Config"; -import {ThumbnailProcessingLib} from "../../../common/config/private/IPrivateConfig"; -import {ThumbnailTH} from "../../model/threading/ThreadPool"; -import {RendererInput} from "../../model/threading/ThumbnailWoker"; -import {ITaskQue, TaskQue} from "../../model/threading/TaskQue"; +import * as path from 'path'; +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import * as os from 'os'; +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error'; +import {ContentWrapper} from '../../../common/entities/ConentWrapper'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {ProjectPath} from '../../ProjectPath'; +import {PhotoDTO} from '../../../common/entities/PhotoDTO'; +import {Config} from '../../../common/config/private/Config'; +import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig'; +import {ThumbnailTH} from '../../model/threading/ThreadPool'; +import {RendererInput} from '../../model/threading/ThumbnailWoker'; +import {ITaskQue, TaskQue} from '../../model/threading/TaskQue'; export class ThumbnailGeneratorMWs { @@ -21,20 +21,20 @@ export class ThumbnailGeneratorMWs { private static taskQue: ITaskQue = null; public static init() { - if (this.initDone == true) { - return + if (this.initDone === true) { + return; } - if (Config.Server.enableThreading == true || - Config.Server.thumbnail.processingLibrary != ThumbnailProcessingLib.Jimp) { + if (Config.Server.enableThreading === true || + Config.Server.thumbnail.processingLibrary !== ThumbnailProcessingLib.Jimp) { Config.Client.concurrentThumbnailGenerations = Math.max(1, os.cpus().length - 1); } else { Config.Client.concurrentThumbnailGenerations = 1; } - if (Config.Server.enableThreading == true && - Config.Server.thumbnail.processingLibrary == ThumbnailProcessingLib.Jimp) { + if (Config.Server.enableThreading === true && + Config.Server.thumbnail.processingLibrary === ThumbnailProcessingLib.Jimp) { this.taskQue = new ThumbnailTH(Config.Client.concurrentThumbnailGenerations); } else { this.taskQue = new TaskQue(Config.Client.concurrentThumbnailGenerations); @@ -43,49 +43,13 @@ export class ThumbnailGeneratorMWs { this.initDone = true; } - private static addThInfoTODir(directory: DirectoryDTO) { - if (typeof directory.photos == "undefined") { - directory.photos = []; - } - if (typeof directory.directories == "undefined") { - directory.directories = []; - } - ThumbnailGeneratorMWs.addThInfoToPhotos(directory.photos); - - for (let i = 0; i < directory.directories.length; i++) { - ThumbnailGeneratorMWs.addThInfoTODir(directory.directories[i]); - } - - } - - private static addThInfoToPhotos(photos: Array) { - 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.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") { - photos[i].readyThumbnails = []; - } - photos[i].readyThumbnails.push(size); - } - } - let iconPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, Config.Client.Thumbnail.iconSize)); - if (fs.existsSync(iconPath) === true) { - photos[i].readyIcon = true; - } - - } - } - public static addThumbnailInformation(req: Request, res: Response, next: NextFunction) { - if (!req.resultPipe) + if (!req.resultPipe) { return next(); + } - let cw: ContentWrapper = req.resultPipe; - if (cw.notModified == true) { + const cw: ContentWrapper = req.resultPipe; + if (cw.notModified === true) { return next(); } if (cw.directory) { @@ -101,14 +65,15 @@ export class ThumbnailGeneratorMWs { } public static generateThumbnail(req: Request, res: Response, next: NextFunction) { - if (!req.resultPipe) + if (!req.resultPipe) { return next(); + } - //load parameters - let imagePath = req.resultPipe; - let size: number = parseInt(req.params.size) || Config.Client.Thumbnail.thumbnailSizes[0]; + // load parameters + const imagePath = req.resultPipe; + let size: number = parseInt(req.params.size, 10) || Config.Client.Thumbnail.thumbnailSizes[0]; - //validate size + // validate size if (Config.Client.Thumbnail.thumbnailSizes.indexOf(size) === -1) { size = Config.Client.Thumbnail.thumbnailSizes[0]; } @@ -119,37 +84,74 @@ export class ThumbnailGeneratorMWs { } public static generateIcon(req: Request, res: Response, next: NextFunction) { - if (!req.resultPipe) + if (!req.resultPipe) { return next(); + } - //load parameters - let imagePath = req.resultPipe; - let size: number = Config.Client.Thumbnail.iconSize; + // load parameters + const imagePath = req.resultPipe; + const size: number = Config.Client.Thumbnail.iconSize; ThumbnailGeneratorMWs.generateImage(imagePath, size, true, req, res, next); } + private static addThInfoTODir(directory: DirectoryDTO) { + if (typeof directory.photos === 'undefined') { + directory.photos = []; + } + if (typeof directory.directories === 'undefined') { + directory.directories = []; + } + ThumbnailGeneratorMWs.addThInfoToPhotos(directory.photos); + + for (let i = 0; i < directory.directories.length; i++) { + ThumbnailGeneratorMWs.addThInfoTODir(directory.directories[i]); + } + + } + + private static addThInfoToPhotos(photos: Array) { + const thumbnailFolder = ProjectPath.ThumbnailFolder; + for (let i = 0; i < photos.length; i++) { + const fullImagePath = path.join(ProjectPath.ImageFolder, photos[i].directory.path, photos[i].directory.name, photos[i].name); + for (let j = 0; j < Config.Client.Thumbnail.thumbnailSizes.length; j++) { + const size = Config.Client.Thumbnail.thumbnailSizes[j]; + const thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, size)); + if (fs.existsSync(thPath) === true) { + if (typeof photos[i].readyThumbnails === 'undefined') { + photos[i].readyThumbnails = []; + } + photos[i].readyThumbnails.push(size); + } + } + const iconPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, Config.Client.Thumbnail.iconSize)); + if (fs.existsSync(iconPath) === true) { + photos[i].readyIcon = true; + } + + } + } private static async generateImage(imagePath: string, size: number, makeSquare: boolean, req: Request, res: Response, next: NextFunction) { - //generate thumbnail path - let thPath = path.join(ProjectPath.ThumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size)); + // generate thumbnail path + const thPath = path.join(ProjectPath.ThumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size)); req.resultPipe = thPath; - //check if thumbnail already exist + // check if thumbnail already exist if (fs.existsSync(thPath) === true) { return next(); } - //create thumbnail folder if not exist + // create thumbnail folder if not exist if (!fs.existsSync(ProjectPath.ThumbnailFolder)) { fs.mkdirSync(ProjectPath.ThumbnailFolder); } - //run on other thread - let input = { + // run on other thread + const input = { imagePath: imagePath, size: size, thPath: thPath, @@ -160,12 +162,12 @@ export class ThumbnailGeneratorMWs { await this.taskQue.execute(input); return next(); } catch (error) { - return next(new ErrorDTO(ErrorCodes.THUMBNAIL_GENERATION_ERROR, "Error during generating thumbnail", error)); + return next(new ErrorDTO(ErrorCodes.THUMBNAIL_GENERATION_ERROR, 'Error during generating thumbnail', error)); } } private static generateThumbnailName(imagePath: string, size: number): string { - return crypto.createHash('md5').update(imagePath).digest('hex') + "_" + size + ".jpg"; + return crypto.createHash('md5').update(imagePath).digest('hex') + '_' + size + '.jpg'; } } diff --git a/backend/middlewares/user/AuthenticationMWs.ts b/backend/middlewares/user/AuthenticationMWs.ts index 177a36a..4af705d 100644 --- a/backend/middlewares/user/AuthenticationMWs.ts +++ b/backend/middlewares/user/AuthenticationMWs.ts @@ -1,42 +1,17 @@ /// -import {NextFunction, Request, Response} from "express"; -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"; -import {PasswordHelper} from "../../model/PasswordHelper"; -import {Utils} from "../../../common/Utils"; +import {NextFunction, Request, Response} from 'express'; +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'; +import {PasswordHelper} from '../../model/PasswordHelper'; +import {Utils} from '../../../common/Utils'; export class AuthenticationMWs { - private static async getSharingUser(req: Request) { - if (Config.Client.Sharing.enabled === true && - (!!req.query.sk || !!req.params.sharingKey)) { - const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({ - sharingKey: req.query.sk || req.params.sharingKey, - }); - if (!sharing || sharing.expires < Date.now()) { - return null; - } - - if (Config.Client.Sharing.passwordProtected === true && sharing.password) { - return null; - } - - let path = sharing.path; - if (sharing.includeSubfolders == true) { - path += "*"; - } - return {name: "Guest", role: UserRoles.LimitedGuest, permissions: [path]}; - - } - return null; - } - - public static async tryAuthenticate(req: Request, res: Response, next: NextFunction) { if (Config.Client.authenticationRequired === false) { - req.session.user = {name: "Admin", role: UserRoles.Admin}; + req.session.user = {name: 'Admin', role: UserRoles.Admin}; return next(); } try { @@ -55,7 +30,7 @@ export class AuthenticationMWs { public static async authenticate(req: Request, res: Response, next: NextFunction) { if (Config.Client.authenticationRequired === false) { - req.session.user = {name: "Admin", role: UserRoles.Admin}; + req.session.user = {name: 'Admin', role: UserRoles.Admin}; return next(); } try { @@ -78,6 +53,21 @@ export class AuthenticationMWs { return next(); } + public static authoriseDirectory(req: Request, res: Response, next: NextFunction) { + if (req.session.user.permissions == null || + req.session.user.permissions.length == 0 || + req.session.user.permissions[0] == '/*') { + return next(); + } + + const directoryName = req.params.directory || '/'; + if (UserDTO.isPathAvailable(directoryName, req.session.user.permissions) == true) { + return next(); + } + + return next(new ErrorDTO(ErrorCodes.PERMISSION_DENIED)); + } + public static authorise(role: UserRoles) { return (req: Request, res: Response, next: NextFunction) => { if (req.session.user.role < role) { @@ -87,19 +77,40 @@ export class AuthenticationMWs { }; } - public static authoriseDirectory(req: Request, res: Response, next: NextFunction) { - if (req.session.user.permissions == null || - req.session.user.permissions.length == 0 || - req.session.user.permissions[0] == "/*") { + public static async shareLogin(req: Request, res: Response, next: NextFunction) { + + if (Config.Client.Sharing.enabled === false) { return next(); } - - const directoryName = req.params.directory || "/"; - if (UserDTO.isPathAvailable(directoryName, req.session.user.permissions) == true) { - return next(); + //not enough parameter + if ((!req.query.sk && !req.params.sharingKey)) { + return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'no sharing key provided')); + } + + try { + const password = (req.body ? req.body.password : null) || null; + + const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({ + sharingKey: req.query.sk || req.params.sharingKey, + }); + if (!sharing || sharing.expires < Date.now() || + (Config.Client.Sharing.passwordProtected === true + && sharing.password && !PasswordHelper.comparePassword(password, sharing.password))) { + return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND)); + } + + let path = sharing.path; + if (sharing.includeSubfolders == true) { + path += '*'; + } + + req.session.user = {name: 'Guest', role: UserRoles.LimitedGuest, permissions: [path]}; + return next(); + + } catch (err) { + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err)); } - return next(new ErrorDTO(ErrorCodes.PERMISSION_DENIED)); } public static inverseAuthenticate(req: Request, res: Response, next: NextFunction) { @@ -136,41 +147,28 @@ export class AuthenticationMWs { } - - public static async shareLogin(req: Request, res: Response, next: NextFunction) { - - if (Config.Client.Sharing.enabled === false) { - return next(); - } - //not enough parameter - if ((!req.query.sk && !req.params.sharingKey)) { - return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "no sharing key provided")); - } - - try { - const password = (req.body ? req.body.password : null) || null; - + private static async getSharingUser(req: Request) { + if (Config.Client.Sharing.enabled === true && + (!!req.query.sk || !!req.params.sharingKey)) { const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({ sharingKey: req.query.sk || req.params.sharingKey, }); - if (!sharing || sharing.expires < Date.now() || - (Config.Client.Sharing.passwordProtected === true - && sharing.password && !PasswordHelper.comparePassword(password, sharing.password))) { - return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND)); + if (!sharing || sharing.expires < Date.now()) { + return null; + } + + if (Config.Client.Sharing.passwordProtected === true && sharing.password) { + return null; } let path = sharing.path; if (sharing.includeSubfolders == true) { - path += "*"; + path += '*'; } + return {name: 'Guest', role: UserRoles.LimitedGuest, permissions: [path]}; - req.session.user = {name: "Guest", role: UserRoles.LimitedGuest, permissions: [path]}; - return next(); - - } catch (err) { - return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err)); } - + return null; } public static logout(req: Request, res: Response, next: NextFunction) { diff --git a/backend/middlewares/user/UserMWs.ts b/backend/middlewares/user/UserMWs.ts index 0c5b9dc..cd6ee55 100644 --- a/backend/middlewares/user/UserMWs.ts +++ b/backend/middlewares/user/UserMWs.ts @@ -1,8 +1,8 @@ -import {NextFunction, Request, Response} from "express"; -import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error"; -import {ObjectManagerRepository} from "../../model/ObjectManagerRepository"; -import {Utils} from "../../../common/Utils"; -import {Config} from "../../../common/config/private/Config"; +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error'; +import {ObjectManagerRepository} from '../../model/ObjectManagerRepository'; +import {Utils} from '../../../common/Utils'; +import {Config} from '../../../common/config/private/Config'; export class UserMWs { @@ -94,7 +94,7 @@ export class UserMWs { let result = await ObjectManagerRepository.getInstance().UserManager.find({}); result = Utils.clone(result); for (let i = 0; i < result.length; i++) { - result[i].password = ""; + result[i].password = ''; } req.resultPipe = result; next(); diff --git a/backend/middlewares/user/UserRequestConstrainsMWs.ts b/backend/middlewares/user/UserRequestConstrainsMWs.ts index 29aa132..6fed401 100644 --- a/backend/middlewares/user/UserRequestConstrainsMWs.ts +++ b/backend/middlewares/user/UserRequestConstrainsMWs.ts @@ -1,7 +1,7 @@ -import {NextFunction, Request, Response} from "express"; -import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error"; -import {UserRoles} from "../../../common/entities/UserDTO"; -import {ObjectManagerRepository} from "../../model/ObjectManagerRepository"; +import {NextFunction, Request, Response} from 'express'; +import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error'; +import {UserRoles} from '../../../common/entities/UserDTO'; +import {ObjectManagerRepository} from '../../model/ObjectManagerRepository'; export class UserRequestConstrainsMWs { @@ -38,7 +38,7 @@ export class UserRequestConstrainsMWs { return next(); } - //TODO: fix it! + // TODO: fix it! try { const result = await ObjectManagerRepository.getInstance().UserManager.find({minRole: UserRoles.Admin}); if (result.length <= 1) { diff --git a/backend/model/ConfigDiagnostics.ts b/backend/model/ConfigDiagnostics.ts index e2e5ed9..b6c9b5c 100644 --- a/backend/model/ConfigDiagnostics.ts +++ b/backend/model/ConfigDiagnostics.ts @@ -1,19 +1,20 @@ -import {Config} from "../../common/config/private/Config"; +import {Config} from '../../common/config/private/Config'; import { DataBaseConfig, DatabaseType, IPrivateConfig, ThumbnailConfig, ThumbnailProcessingLib -} from "../../common/config/private/IPrivateConfig"; -import {Logger} from "../Logger"; -import {NotificationManager} from "./NotifocationManager"; -import {ProjectPath} from "../ProjectPath"; -import {SQLConnection} from "./sql/SQLConnection"; -import * as fs from "fs"; -import {ClientConfig} from "../../common/config/public/ConfigClass"; +} from '../../common/config/private/IPrivateConfig'; +import {Logger} from '../Logger'; +import {NotificationManager} from './NotifocationManager'; +import {ProjectPath} from '../ProjectPath'; +import {SQLConnection} from './sql/SQLConnection'; +import * as fs from 'fs'; +import {ClientConfig} from '../../common/config/public/ConfigClass'; + +const LOG_TAG = '[ConfigDiagnostics]'; -const LOG_TAG = "[ConfigDiagnostics]"; export class ConfigDiagnostics { static async testDatabase(databaseConfig: DataBaseConfig) { @@ -26,13 +27,13 @@ export class ConfigDiagnostics { static async testThumbnailLib(processingLibrary: ThumbnailProcessingLib) { switch (processingLibrary) { case ThumbnailProcessingLib.sharp: - const sharp = require("sharp"); + const sharp = require('sharp'); sharp(); break; case ThumbnailProcessingLib.gm: - const gm = require("gm"); + const gm = require('gm'); await new Promise((resolve, reject) => { - gm(ProjectPath.FrontendFolder + "/assets/icon.png").size((err, value) => { + gm(ProjectPath.FrontendFolder + '/assets/icon.png').size((err, value) => { if (err) { return reject(err.toString()); } @@ -47,7 +48,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.toString()}); + reject({message: 'Error during getting write access to temp folder', error: err.toString()}); } }); resolve(); @@ -57,11 +58,11 @@ export class ConfigDiagnostics { static async testImageFolder(folder: string) { await new Promise((resolve, reject) => { if (!fs.existsSync(folder)) { - reject("Images folder not exists: '" + folder + "'"); + reject('Images folder not exists: \'' + folder + '\''); } fs.access(folder, fs.constants.R_OK, (err) => { if (err) { - reject({message: "Error during getting read access to images folder", error: err.toString()}); + reject({message: 'Error during getting read access to images folder', error: err.toString()}); } }); resolve(); @@ -76,15 +77,15 @@ export class ConfigDiagnostics { static async testClientThumbnailConfig(thumbnailConfig: ClientConfig.ThumbnailConfig) { if (isNaN(thumbnailConfig.iconSize) || thumbnailConfig.iconSize <= 0) { - throw "IconSize has to be >= 0 integer, got: " + thumbnailConfig.iconSize; + throw 'IconSize has to be >= 0 integer, got: ' + thumbnailConfig.iconSize; } if (!thumbnailConfig.thumbnailSizes.length) { - throw "At least one thumbnail size is needed"; + 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]; + throw 'Thumbnail size has to be >= 0 integer, got: ' + thumbnailConfig.thumbnailSizes[i]; } } } @@ -92,20 +93,20 @@ export class ConfigDiagnostics { static async testSearchConfig(search: ClientConfig.SearchConfig, config: IPrivateConfig) { if (search.enabled == true && config.Server.database.type == DatabaseType.memory) { - throw "Memory Database do not support searching"; + throw 'Memory Database do not support searching'; } } static async testSharingConfig(sharing: ClientConfig.SharingConfig, config: IPrivateConfig) { if (sharing.enabled == true && config.Server.database.type == DatabaseType.memory) { - throw "Memory Database do not support sharing"; + throw 'Memory Database do not support sharing'; } } static async testMapConfig(map: ClientConfig.MapConfig) { if (map.enabled == true && (!map.googleApiKey || map.googleApiKey.length == 0)) { - throw "Maps need a valid google api key"; + throw 'Maps need a valid google api key'; } } @@ -116,9 +117,9 @@ export class ConfigDiagnostics { try { await ConfigDiagnostics.testDatabase(Config.Server.database); } catch (err) { - Logger.warn(LOG_TAG, "[SQL error]", err); - Logger.warn(LOG_TAG, "Error during initializing SQL falling back temporally to memory DB"); - NotificationManager.warning("Error during initializing SQL falling back temporally to memory DB", err); + Logger.warn(LOG_TAG, '[SQL error]', err); + Logger.warn(LOG_TAG, 'Error during initializing SQL falling back temporally to memory DB'); + NotificationManager.warning('Error during initializing SQL falling back temporally to memory DB', err); Config.setDatabaseType(DatabaseType.memory); } } @@ -127,60 +128,60 @@ export class ConfigDiagnostics { try { await ConfigDiagnostics.testThumbnailLib(Config.Server.thumbnail.processingLibrary); } catch (err) { - NotificationManager.warning("Thumbnail hardware acceleration is not possible." + - " '" + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + "' node module is not found." + - " Falling back temporally to JS based thumbnail generation", err); - Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] module error: ", err); - Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." + - " '" + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + "' node module is not found." + - " Falling back temporally to JS based thumbnail generation"); + NotificationManager.warning('Thumbnail hardware acceleration is not possible.' + + ' \'' + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + '\' node module is not found.' + + ' Falling back temporally to JS based thumbnail generation', err); + Logger.warn(LOG_TAG, '[Thumbnail hardware acceleration] module error: ', err); + Logger.warn(LOG_TAG, 'Thumbnail hardware acceleration is not possible.' + + ' \'' + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + '\' node module is not found.' + + ' Falling back temporally to JS based thumbnail generation'); Config.Server.thumbnail.processingLibrary = ThumbnailProcessingLib.Jimp; } } try { - await ConfigDiagnostics.testThumbnailFolder(Config.Server.thumbnail.folder) + await ConfigDiagnostics.testThumbnailFolder(Config.Server.thumbnail.folder); } catch (err) { - NotificationManager.error("Thumbnail folder error", err); - Logger.error(LOG_TAG, "Thumbnail folder error", err); + NotificationManager.error('Thumbnail folder error', err); + Logger.error(LOG_TAG, 'Thumbnail folder error', err); } try { - await ConfigDiagnostics.testImageFolder(Config.Server.imagesFolder) + await ConfigDiagnostics.testImageFolder(Config.Server.imagesFolder); } catch (err) { - NotificationManager.error("Images folder error", err); - Logger.error(LOG_TAG, "Images folder error", err); + NotificationManager.error('Images folder error', err); + Logger.error(LOG_TAG, 'Images folder error', err); } try { - await ConfigDiagnostics.testClientThumbnailConfig(Config.Client.Thumbnail) + await ConfigDiagnostics.testClientThumbnailConfig(Config.Client.Thumbnail); } catch (err) { - NotificationManager.error("Thumbnail settings error", err); - Logger.error(LOG_TAG, "Thumbnail settings error", err); + NotificationManager.error('Thumbnail settings error', err); + Logger.error(LOG_TAG, 'Thumbnail settings error', err); } try { await ConfigDiagnostics.testSearchConfig(Config.Client.Search, Config); } catch (err) { - NotificationManager.warning("Search is not supported with these settings. Disabling temporally. Please adjust the config properly.", err); - Logger.warn(LOG_TAG, "Search is not supported with these settings, switching off..", err); + NotificationManager.warning('Search is not supported with these settings. Disabling temporally. Please adjust the config properly.', err); + Logger.warn(LOG_TAG, 'Search is not supported with these settings, switching off..', err); Config.Client.Search.enabled = false; } try { await ConfigDiagnostics.testSharingConfig(Config.Client.Sharing, Config); } catch (err) { - NotificationManager.warning("Sharing is not supported with these settings. Disabling temporally. Please adjust the config properly.", err); - Logger.warn(LOG_TAG, "Sharing is not supported with these settings, switching off..", err); + NotificationManager.warning('Sharing is not supported with these settings. Disabling temporally. Please adjust the config properly.', err); + Logger.warn(LOG_TAG, 'Sharing is not supported with these settings, switching off..', err); Config.Client.Sharing.enabled = false; } try { await ConfigDiagnostics.testMapConfig(Config.Client.Map); } catch (err) { - NotificationManager.warning("Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.", err); - Logger.warn(LOG_TAG, "Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.", err); + NotificationManager.warning('Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.', err); + Logger.warn(LOG_TAG, 'Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.', err); Config.Client.Map.enabled = false; } diff --git a/backend/model/DiskManger.ts b/backend/model/DiskManger.ts index 64cc04e..3b3073d 100644 --- a/backend/model/DiskManger.ts +++ b/backend/model/DiskManger.ts @@ -1,12 +1,13 @@ /// -import {DirectoryDTO} from "../../common/entities/DirectoryDTO"; -import {Logger} from "../Logger"; -import {Config} from "../../common/config/private/Config"; -import {DiskManagerTH} from "./threading/ThreadPool"; -import {DiskMangerWorker} from "./threading/DiskMangerWorker"; +import {DirectoryDTO} from '../../common/entities/DirectoryDTO'; +import {Logger} from '../Logger'; +import {Config} from '../../common/config/private/Config'; +import {DiskManagerTH} from './threading/ThreadPool'; +import {DiskMangerWorker} from './threading/DiskMangerWorker'; -const LOG_TAG = "[DiskManager]"; +const LOG_TAG = '[DiskManager]'; + export class DiskManager { static threadPool: DiskManagerTH = null; @@ -17,7 +18,7 @@ export class DiskManager { } public static async scanDirectory(relativeDirectoryName: string): Promise { - Logger.silly(LOG_TAG, "scanning directory:", relativeDirectoryName); + Logger.silly(LOG_TAG, 'scanning directory:', relativeDirectoryName); let directory: DirectoryDTO = null; diff --git a/backend/model/Localizations.ts b/backend/model/Localizations.ts index 7b5af32..60b3ed8 100644 --- a/backend/model/Localizations.ts +++ b/backend/model/Localizations.ts @@ -1,7 +1,7 @@ -import {ProjectPath} from "../ProjectPath"; -import * as fs from "fs"; -import * as path from "path"; -import {Config} from "../../common/config/private/Config"; +import {ProjectPath} from '../ProjectPath'; +import * as fs from 'fs'; +import * as path from 'path'; +import {Config} from '../../common/config/private/Config'; export class Localizations { @@ -12,7 +12,7 @@ export class Localizations { const notLanguage = ['assets']; const dirCont = fs.readdirSync(ProjectPath.FrontendFolder).filter(f => fs.statSync(path.resolve(ProjectPath.FrontendFolder, f)).isDirectory()); Config.Client.languages = dirCont.filter(d => notLanguage.indexOf(d) == -1); - Config.Client.languages.push("en"); + Config.Client.languages.push('en'); } } diff --git a/backend/model/NotifocationManager.ts b/backend/model/NotifocationManager.ts index ae5afb5..4826d3a 100644 --- a/backend/model/NotifocationManager.ts +++ b/backend/model/NotifocationManager.ts @@ -1,11 +1,12 @@ -import {NotificationDTO, NotificationType} from "../../common/entities/NotificationDTO"; +import {NotificationDTO, NotificationType} from '../../common/entities/NotificationDTO'; + export class NotificationManager { public static notifications: NotificationDTO[] = []; public static HasNotification: NotificationDTO[] = [ { type: NotificationType.info, - message: "There are unhandled server notification. Login as Administrator to handle them." + message: 'There are unhandled server notification. Login as Administrator to handle them.' } ]; diff --git a/backend/model/ObjectManagerRepository.ts b/backend/model/ObjectManagerRepository.ts index 077fc71..989f3ec 100644 --- a/backend/model/ObjectManagerRepository.ts +++ b/backend/model/ObjectManagerRepository.ts @@ -1,10 +1,10 @@ -import {IUserManager} from "./interfaces/IUserManager"; -import {IGalleryManager} from "./interfaces/IGalleryManager"; -import {ISearchManager} from "./interfaces/ISearchManager"; -import {SQLConnection} from "./sql/SQLConnection"; -import {ISharingManager} from "./interfaces/ISharingManager"; -import {Logger} from "../Logger"; -import {IIndexingManager} from "./interfaces/IIndexingManager"; +import {IUserManager} from './interfaces/IUserManager'; +import {IGalleryManager} from './interfaces/IGalleryManager'; +import {ISearchManager} from './interfaces/ISearchManager'; +import {SQLConnection} from './sql/SQLConnection'; +import {ISharingManager} from './interfaces/ISharingManager'; +import {Logger} from '../Logger'; +import {IIndexingManager} from './interfaces/IIndexingManager'; export class ObjectManagerRepository { @@ -70,11 +70,11 @@ export class ObjectManagerRepository { public static async InitMemoryManagers() { await ObjectManagerRepository.reset(); - const GalleryManager = require("./memory/GalleryManager").GalleryManager; - const UserManager = require("./memory/UserManager").UserManager; - const SearchManager = require("./memory/SearchManager").SearchManager; - const SharingManager = require("./memory/SharingManager").SharingManager; - const IndexingManager = require("./memory/IndexingManager").IndexingManager; + const GalleryManager = require('./memory/GalleryManager').GalleryManager; + const UserManager = require('./memory/UserManager').UserManager; + const SearchManager = require('./memory/SearchManager').SearchManager; + const SharingManager = require('./memory/SharingManager').SharingManager; + const IndexingManager = require('./memory/IndexingManager').IndexingManager; ObjectManagerRepository.getInstance().GalleryManager = new GalleryManager(); ObjectManagerRepository.getInstance().UserManager = new UserManager(); ObjectManagerRepository.getInstance().SearchManager = new SearchManager(); @@ -85,17 +85,17 @@ export class ObjectManagerRepository { public static async InitSQLManagers() { await ObjectManagerRepository.reset(); await SQLConnection.init(); - const GalleryManager = require("./sql/GalleryManager").GalleryManager; - const UserManager = require("./sql/UserManager").UserManager; - const SearchManager = require("./sql/SearchManager").SearchManager; - const SharingManager = require("./sql/SharingManager").SharingManager; - const IndexingManager = require("./sql/IndexingManager").IndexingManager; + const GalleryManager = require('./sql/GalleryManager').GalleryManager; + const UserManager = require('./sql/UserManager').UserManager; + const SearchManager = require('./sql/SearchManager').SearchManager; + const SharingManager = require('./sql/SharingManager').SharingManager; + const IndexingManager = require('./sql/IndexingManager').IndexingManager; ObjectManagerRepository.getInstance().GalleryManager = new GalleryManager(); ObjectManagerRepository.getInstance().UserManager = new UserManager(); ObjectManagerRepository.getInstance().SearchManager = new SearchManager(); ObjectManagerRepository.getInstance().SharingManager = new SharingManager(); ObjectManagerRepository.getInstance().IndexingManager = new IndexingManager(); - Logger.debug("SQL DB inited"); + Logger.debug('SQL DB inited'); } } diff --git a/backend/model/PasswordHelper.ts b/backend/model/PasswordHelper.ts index 475fe29..94c0390 100644 --- a/backend/model/PasswordHelper.ts +++ b/backend/model/PasswordHelper.ts @@ -1,8 +1,8 @@ let bcrypt; try { - bcrypt = require("bcrypt"); + bcrypt = require('bcrypt'); } catch (err) { - bcrypt = require("bcryptjs"); + bcrypt = require('bcryptjs'); } export class PasswordHelper { diff --git a/backend/model/exif.d.ts b/backend/model/exif.d.ts index 7a1651d..dada00e 100644 --- a/backend/model/exif.d.ts +++ b/backend/model/exif.d.ts @@ -1,26 +1,31 @@ -declare module "node-iptc" { +declare module 'node-iptc' { function e(data): any; module e { } - export = e; + export = e; } -declare module "exif-parser" { +declare module 'exif-parser' { export interface ExifData { tags: any; imageSize: any; } + export interface ExifObject { enableTagNames(value: boolean); + enableImageSize(value: boolean); + enableReturnTags(value: boolean); + parse(): ExifData; } + export function create(data: any): ExifObject; } diff --git a/backend/model/interfaces/IGalleryManager.ts b/backend/model/interfaces/IGalleryManager.ts index 20a088f..100ff4d 100644 --- a/backend/model/interfaces/IGalleryManager.ts +++ b/backend/model/interfaces/IGalleryManager.ts @@ -1,4 +1,4 @@ -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; export interface IGalleryManager { listDirectory(relativeDirectoryName: string, diff --git a/backend/model/interfaces/IIndexingManager.ts b/backend/model/interfaces/IIndexingManager.ts index 4607c4a..d9ee5c9 100644 --- a/backend/model/interfaces/IIndexingManager.ts +++ b/backend/model/interfaces/IIndexingManager.ts @@ -1,4 +1,4 @@ -import {IndexingProgressDTO} from "../../../common/entities/settings/IndexingProgressDTO"; +import {IndexingProgressDTO} from '../../../common/entities/settings/IndexingProgressDTO'; export interface IIndexingManager { startIndexing(): void; @@ -7,5 +7,5 @@ export interface IIndexingManager { cancelIndexing(): void; - reset(): Promise ; + reset(): Promise; } diff --git a/backend/model/interfaces/ISearchManager.ts b/backend/model/interfaces/ISearchManager.ts index d0859af..41c4920 100644 --- a/backend/model/interfaces/ISearchManager.ts +++ b/backend/model/interfaces/ISearchManager.ts @@ -1,8 +1,10 @@ -import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem"; -import {SearchResultDTO} from "../../../common/entities/SearchResultDTO"; +import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem'; +import {SearchResultDTO} from '../../../common/entities/SearchResultDTO'; export interface ISearchManager { autocomplete(text: string): Promise; + search(text: string, searchType: SearchTypes): Promise; + instantSearch(text: string): Promise; } diff --git a/backend/model/interfaces/ISharingManager.ts b/backend/model/interfaces/ISharingManager.ts index 2ee39f2..b88439d 100644 --- a/backend/model/interfaces/ISharingManager.ts +++ b/backend/model/interfaces/ISharingManager.ts @@ -1,6 +1,9 @@ -import {SharingDTO} from "../../../common/entities/SharingDTO"; +import {SharingDTO} from '../../../common/entities/SharingDTO'; + export interface ISharingManager { findOne(filter: any): Promise; + createSharing(sharing: SharingDTO): Promise; + updateSharing(sharing: SharingDTO): Promise; } diff --git a/backend/model/interfaces/IUserManager.ts b/backend/model/interfaces/IUserManager.ts index 337fcdd..235e057 100644 --- a/backend/model/interfaces/IUserManager.ts +++ b/backend/model/interfaces/IUserManager.ts @@ -1,9 +1,15 @@ -import {UserDTO, UserRoles} from "../../../common/entities/UserDTO"; +import {UserDTO, UserRoles} from '../../../common/entities/UserDTO'; + export interface IUserManager { findOne(filter: any): Promise; + find(filter: any): Promise; + createUser(user: UserDTO): Promise; + deleteUser(id: number): Promise; + changeRole(id: number, newRole: UserRoles): Promise; + changePassword(request: any): Promise; } diff --git a/backend/model/memory/GalleryManager.ts b/backend/model/memory/GalleryManager.ts index 0f51a59..2c08303 100644 --- a/backend/model/memory/GalleryManager.ts +++ b/backend/model/memory/GalleryManager.ts @@ -1,11 +1,11 @@ -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {IGalleryManager} from "../interfaces/IGalleryManager"; -import * as path from "path"; -import * as fs from "fs"; -import {DiskManager} from "../DiskManger"; -import {ProjectPath} from "../../ProjectPath"; -import {Config} from "../../../common/config/private/Config"; -import {ReIndexingSensitivity} from "../../../common/config/private/IPrivateConfig"; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {IGalleryManager} from '../interfaces/IGalleryManager'; +import * as path from 'path'; +import * as fs from 'fs'; +import {DiskManager} from '../DiskManger'; +import {ProjectPath} from '../../ProjectPath'; +import {Config} from '../../../common/config/private/Config'; +import {ReIndexingSensitivity} from '../../../common/config/private/IPrivateConfig'; export class GalleryManager implements IGalleryManager { diff --git a/backend/model/memory/IndexingManager.ts b/backend/model/memory/IndexingManager.ts index 0270716..6bd861e 100644 --- a/backend/model/memory/IndexingManager.ts +++ b/backend/model/memory/IndexingManager.ts @@ -1,21 +1,21 @@ -import {IIndexingManager} from "../interfaces/IIndexingManager"; -import {IndexingProgressDTO} from "../../../common/entities/settings/IndexingProgressDTO"; +import {IIndexingManager} from '../interfaces/IIndexingManager'; +import {IndexingProgressDTO} from '../../../common/entities/settings/IndexingProgressDTO'; export class IndexingManager implements IIndexingManager { startIndexing(): void { - throw new Error("not supported by memory DB"); + throw new Error('not supported by memory DB'); } getProgress(): IndexingProgressDTO { - throw new Error("not supported by memory DB"); + throw new Error('not supported by memory DB'); } cancelIndexing(): void { - throw new Error("not supported by memory DB"); + throw new Error('not supported by memory DB'); } reset(): Promise { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } } diff --git a/backend/model/memory/SearchManager.ts b/backend/model/memory/SearchManager.ts index 8aadcaa..529b619 100644 --- a/backend/model/memory/SearchManager.ts +++ b/backend/model/memory/SearchManager.ts @@ -1,18 +1,18 @@ -import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem"; -import {ISearchManager} from "../interfaces/ISearchManager"; -import {SearchResultDTO} from "../../../common/entities/SearchResultDTO"; +import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem'; +import {ISearchManager} from '../interfaces/ISearchManager'; +import {SearchResultDTO} from '../../../common/entities/SearchResultDTO'; export class SearchManager implements ISearchManager { autocomplete(text: string): Promise { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } search(text: string, searchType: SearchTypes): Promise { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } instantSearch(text: string): Promise { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } } diff --git a/backend/model/memory/SharingManager.ts b/backend/model/memory/SharingManager.ts index 9695c04..4a07fe4 100644 --- a/backend/model/memory/SharingManager.ts +++ b/backend/model/memory/SharingManager.ts @@ -1,19 +1,19 @@ -import {ISharingManager} from "../interfaces/ISharingManager"; -import {SharingDTO} from "../../../common/entities/SharingDTO"; +import {ISharingManager} from '../interfaces/ISharingManager'; +import {SharingDTO} from '../../../common/entities/SharingDTO'; export class SharingManager implements ISharingManager { findOne(filter: any): Promise { - throw new Error("not implemented"); + throw new Error('not implemented'); } createSharing(sharing: SharingDTO): Promise { - throw new Error("not implemented"); + throw new Error('not implemented'); } updateSharing(sharing: SharingDTO): Promise { - throw new Error("not implemented"); + throw new Error('not implemented'); } diff --git a/backend/model/memory/UserManager.ts b/backend/model/memory/UserManager.ts index 01dc0b8..d5c3ebd 100644 --- a/backend/model/memory/UserManager.ts +++ b/backend/model/memory/UserManager.ts @@ -1,10 +1,10 @@ -import {UserDTO, UserRoles} from "../../../common/entities/UserDTO"; -import {IUserManager} from "../interfaces/IUserManager"; -import {ProjectPath} from "../../ProjectPath"; -import {Utils} from "../../../common/Utils"; -import * as path from "path"; -import * as fs from "fs"; -import {PasswordHelper} from "../PasswordHelper"; +import {UserDTO, UserRoles} from '../../../common/entities/UserDTO'; +import {IUserManager} from '../interfaces/IUserManager'; +import {ProjectPath} from '../../ProjectPath'; +import {Utils} from '../../../common/Utils'; +import * as path from 'path'; +import * as fs from 'fs'; +import {PasswordHelper} from '../PasswordHelper'; export class UserManager implements IUserManager { @@ -28,14 +28,14 @@ export class UserManager implements IUserManager { } if (!this.db.idCounter) { - console.log("creating counter"); + console.log('creating counter'); this.db.idCounter = 1; } if (!this.db.users) { this.db.users = []; //TODO: remove defaults - this.createUser({name: "admin", password: "admin", role: UserRoles.Admin}); + this.createUser({name: 'admin', password: 'admin', role: UserRoles.Admin}); } this.saveDB(); @@ -46,7 +46,7 @@ export class UserManager implements IUserManager { const result = await this.find(filter); if (result.length == 0) { - throw "UserDTO not found"; + throw 'UserDTO not found'; } return result[0]; } @@ -97,7 +97,7 @@ export class UserManager implements IUserManager { } public async changePassword(request: any) { - throw new Error("not implemented"); //TODO: implement + throw new Error('not implemented'); //TODO: implement } private loadDB() { diff --git a/backend/model/sql/GalleryManager.ts b/backend/model/sql/GalleryManager.ts index 0cf83b4..1d9f087 100644 --- a/backend/model/sql/GalleryManager.ts +++ b/backend/model/sql/GalleryManager.ts @@ -1,16 +1,16 @@ -import {IGalleryManager} from "../interfaces/IGalleryManager"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import * as path from "path"; -import * as fs from "fs"; -import {DirectoryEntity} from "./enitites/DirectoryEntity"; -import {SQLConnection} from "./SQLConnection"; -import {DiskManager} from "../DiskManger"; -import {PhotoEntity} from "./enitites/PhotoEntity"; -import {Utils} from "../../../common/Utils"; -import {ProjectPath} from "../../ProjectPath"; -import {Config} from "../../../common/config/private/Config"; -import {ISQLGalleryManager} from "./IGalleryManager"; -import {ReIndexingSensitivity} from "../../../common/config/private/IPrivateConfig"; +import {IGalleryManager} from '../interfaces/IGalleryManager'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import * as path from 'path'; +import * as fs from 'fs'; +import {DirectoryEntity} from './enitites/DirectoryEntity'; +import {SQLConnection} from './SQLConnection'; +import {DiskManager} from '../DiskManger'; +import {PhotoEntity} from './enitites/PhotoEntity'; +import {Utils} from '../../../common/Utils'; +import {ProjectPath} from '../../ProjectPath'; +import {Config} from '../../../common/config/private/Config'; +import {ISQLGalleryManager} from './IGalleryManager'; +import {ReIndexingSensitivity} from '../../../common/config/private/IPrivateConfig'; export class GalleryManager implements IGalleryManager, ISQLGalleryManager { @@ -18,7 +18,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { public async listDirectory(relativeDirectoryName: string, knownLastModified?: number, knownLastScanned?: number): Promise { - relativeDirectoryName = path.normalize(path.join("." + path.sep, relativeDirectoryName)); + relativeDirectoryName = path.normalize(path.join('.' + path.sep, relativeDirectoryName)); const directoryName = path.basename(relativeDirectoryName); const directoryParent = path.join(path.dirname(relativeDirectoryName), path.sep); const connection = await SQLConnection.getConnection(); @@ -26,13 +26,13 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { const lastModified = Math.max(stat.ctime.getTime(), stat.mtime.getTime()); let dir = await connection .getRepository(DirectoryEntity) - .createQueryBuilder("directory") - .where("directory.name = :name AND directory.path = :path", { + .createQueryBuilder('directory') + .where('directory.name = :name AND directory.path = :path', { name: directoryName, path: directoryParent }) - .leftJoinAndSelect("directory.directories", "directories") - .leftJoinAndSelect("directory.photos", "photos") + .leftJoinAndSelect('directory.directories', 'directories') + .leftJoinAndSelect('directory.photos', 'photos') .getOne(); @@ -61,11 +61,11 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { for (let i = 0; i < dir.directories.length; i++) { dir.directories[i].photos = await connection .getRepository(PhotoEntity) - .createQueryBuilder("photo") - .where("photo.directory = :dir", { + .createQueryBuilder('photo') + .where('photo.directory = :dir', { dir: dir.directories[i].id }) - .orderBy("photo.metadata.creationDate", "ASC") + .orderBy('photo.metadata.creationDate', 'ASC') .limit(Config.Server.indexing.folderPreviewSize) .getMany(); dir.directories[i].isPartial = true; @@ -85,7 +85,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { //not indexed since a while, index it in a lazy manner if ((Date.now() - dir.lastScanned > Config.Server.indexing.cachedFolderTimeout && - Config.Server.indexing.reIndexingSensitivity >= ReIndexingSensitivity.medium) || + Config.Server.indexing.reIndexingSensitivity >= ReIndexingSensitivity.medium) || Config.Server.indexing.reIndexingSensitivity >= ReIndexingSensitivity.high) { //on the fly reindexing this.indexDirectory(relativeDirectoryName).catch((err) => { @@ -132,8 +132,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { const photosRepository = connection.getRepository(PhotoEntity); - let currentDir = await directoryRepository.createQueryBuilder("directory") - .where("directory.name = :name AND directory.path = :path", { + let currentDir = await directoryRepository.createQueryBuilder('directory') + .where('directory.name = :name AND directory.path = :path', { name: scannedDirectory.name, path: scannedDirectory.path }).getOne(); @@ -147,8 +147,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { currentDir = await directoryRepository.save(scannedDirectory); } - let childDirectories = await directoryRepository.createQueryBuilder("directory") - .where("directory.parent = :dir", { + let childDirectories = await directoryRepository.createQueryBuilder('directory') + .where('directory.parent = :dir', { dir: currentDir.id }).getMany(); @@ -185,8 +185,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { await directoryRepository.remove(childDirectories); - let indexedPhotos = await photosRepository.createQueryBuilder("photo") - .where("photo.directory = :dir", { + let indexedPhotos = await photosRepository.createQueryBuilder('photo') + .where('photo.directory = :dir', { dir: currentDir.id }).getMany(); diff --git a/backend/model/sql/SQLConnection.ts b/backend/model/sql/SQLConnection.ts index e2bafab..e912f44 100644 --- a/backend/model/sql/SQLConnection.ts +++ b/backend/model/sql/SQLConnection.ts @@ -1,16 +1,16 @@ -import "reflect-metadata"; -import {Connection, ConnectionOptions, createConnection, getConnection} from "typeorm"; -import {UserEntity} from "./enitites/UserEntity"; -import {UserRoles} from "../../../common/entities/UserDTO"; -import {PhotoEntity} from "./enitites/PhotoEntity"; -import {DirectoryEntity} from "./enitites/DirectoryEntity"; -import {Config} from "../../../common/config/private/Config"; -import {SharingEntity} from "./enitites/SharingEntity"; -import {DataBaseConfig, DatabaseType} from "../../../common/config/private/IPrivateConfig"; -import {PasswordHelper} from "../PasswordHelper"; -import {ProjectPath} from "../../ProjectPath"; -import {VersionEntity} from "./enitites/VersionEntity"; -import {Logger} from "../../Logger"; +import 'reflect-metadata'; +import {Connection, ConnectionOptions, createConnection, getConnection} from 'typeorm'; +import {UserEntity} from './enitites/UserEntity'; +import {UserRoles} from '../../../common/entities/UserDTO'; +import {PhotoEntity} from './enitites/PhotoEntity'; +import {DirectoryEntity} from './enitites/DirectoryEntity'; +import {Config} from '../../../common/config/private/Config'; +import {SharingEntity} from './enitites/SharingEntity'; +import {DataBaseConfig, DatabaseType} from '../../../common/config/private/IPrivateConfig'; +import {PasswordHelper} from '../PasswordHelper'; +import {ProjectPath} from '../../ProjectPath'; +import {VersionEntity} from './enitites/VersionEntity'; +import {Logger} from '../../Logger'; export class SQLConnection { @@ -27,7 +27,7 @@ export class SQLConnection { if (this.connection == null) { let options: any = this.getDriver(Config.Server.database); - options.name = "main"; + options.name = 'main'; options.entities = [ UserEntity, PhotoEntity, @@ -46,11 +46,11 @@ export class SQLConnection { public static async tryConnection(config: DataBaseConfig) { try { - await getConnection("test").close(); + await getConnection('test').close(); } catch (err) { } const options: any = this.getDriver(config); - options.name = "test"; + options.name = 'test'; options.entities = [ UserEntity, PhotoEntity, @@ -66,6 +66,20 @@ export class SQLConnection { return true; } + public static async init(): Promise { + const connection = await this.getConnection(); + let userRepository = connection.getRepository(UserEntity); + let admins = await userRepository.find({role: UserRoles.Admin}); + if (admins.length == 0) { + let a = new UserEntity(); + a.name = 'admin'; + a.password = PasswordHelper.cryptPassword('admin'); + a.role = UserRoles.Admin; + await userRepository.save(a); + } + + } + private static async schemeSync(connection: Connection) { let version = null; try { @@ -75,7 +89,7 @@ export class SQLConnection { if (version && version.version == SQLConnection.VERSION) { return; } - Logger.info("Updating database scheme"); + Logger.info('Updating database scheme'); if (!version) { version = new VersionEntity(); } @@ -87,25 +101,11 @@ export class SQLConnection { await connection.getRepository(VersionEntity).save(version); } - public static async init(): Promise { - const connection = await this.getConnection(); - let userRepository = connection.getRepository(UserEntity); - let admins = await userRepository.find({role: UserRoles.Admin}); - if (admins.length == 0) { - let a = new UserEntity(); - a.name = "admin"; - a.password = PasswordHelper.cryptPassword("admin"); - a.role = UserRoles.Admin; - await userRepository.save(a); - } - - } - private static getDriver(config: DataBaseConfig): ConnectionOptions { let driver: ConnectionOptions = null; if (config.type == DatabaseType.mysql) { driver = { - type: "mysql", + type: 'mysql', host: config.mysql.host, port: 3306, username: config.mysql.username, @@ -114,7 +114,7 @@ export class SQLConnection { }; } else if (config.type == DatabaseType.sqlite) { driver = { - type: "sqlite", + type: 'sqlite', database: ProjectPath.getAbsolutePath(config.sqlite.storage) }; } diff --git a/backend/model/sql/SearchManager.ts b/backend/model/sql/SearchManager.ts index fb3d7ac..3fd18a8 100644 --- a/backend/model/sql/SearchManager.ts +++ b/backend/model/sql/SearchManager.ts @@ -1,9 +1,9 @@ -import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem"; -import {ISearchManager} from "../interfaces/ISearchManager"; -import {SearchResultDTO} from "../../../common/entities/SearchResultDTO"; -import {SQLConnection} from "./SQLConnection"; -import {PhotoEntity} from "./enitites/PhotoEntity"; -import {DirectoryEntity} from "./enitites/DirectoryEntity"; +import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem'; +import {ISearchManager} from '../interfaces/ISearchManager'; +import {SearchResultDTO} from '../../../common/entities/SearchResultDTO'; +import {SQLConnection} from './SQLConnection'; +import {PhotoEntity} from './enitites/PhotoEntity'; +import {DirectoryEntity} from './enitites/DirectoryEntity'; export class SearchManager implements ISearchManager { @@ -31,10 +31,10 @@ export class SearchManager implements ISearchManager { (await photoRepository .createQueryBuilder('photo') .select('DISTINCT(photo.metadata.keywords)') - .where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) + .where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .limit(5) .getRawMany()) - .map(r => >r.metadataKeywords.split(",")) + .map(r => >r.metadataKeywords.split(',')) .forEach(keywords => { result = result.concat(this.encapsulateAutoComplete(keywords.filter(k => k.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.keyword)); }); @@ -43,14 +43,14 @@ export class SearchManager implements ISearchManager { (await photoRepository .createQueryBuilder('photo') .select('photo.metadata.positionData.country as country, photo.metadata.positionData.state as state, photo.metadata.positionData.city as city') - .where('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) + .where('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .groupBy('photo.metadata.positionData.country, photo.metadata.positionData.state, photo.metadata.positionData.city') .limit(5) .getRawMany()) .filter(pm => !!pm) - .map(pm => >[pm.city || "", pm.country || "", pm.state || ""]) + .map(pm => >[pm.city || '', pm.country || '', pm.state || '']) .forEach(positions => { result = result.concat(this.encapsulateAutoComplete(positions.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.position)); }); @@ -58,7 +58,7 @@ export class SearchManager implements ISearchManager { result = result.concat(this.encapsulateAutoComplete((await photoRepository .createQueryBuilder('photo') .select('DISTINCT(photo.name)') - .where('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) + .where('photo.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .limit(5) .getRawMany()) .map(r => r.name), SearchTypes.image)); @@ -66,7 +66,7 @@ export class SearchManager implements ISearchManager { result = result.concat(this.encapsulateAutoComplete((await directoryRepository .createQueryBuilder('dir') .select('DISTINCT(dir.name)') - .where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) + .where('dir.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .limit(5) .getRawMany()) .map(r => r.name), SearchTypes.directory)); @@ -88,27 +88,27 @@ export class SearchManager implements ISearchManager { let query = connection .getRepository(PhotoEntity) - .createQueryBuilder("photo") - .innerJoinAndSelect("photo.directory", "directory") - .orderBy("photo.metadata.creationDate", "ASC"); + .createQueryBuilder('photo') + .innerJoinAndSelect('photo.directory', 'directory') + .orderBy('photo.metadata.creationDate', 'ASC'); if (!searchType || searchType === SearchTypes.directory) { - query.orWhere('directory.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}); + query.orWhere('directory.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); } if (!searchType || searchType === SearchTypes.image) { - query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}); + query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); } if (!searchType || searchType === SearchTypes.position) { - query.orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}); + query.orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); } if (!searchType || searchType === SearchTypes.keyword) { - query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}); + query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}); } result.photos = await query @@ -121,8 +121,8 @@ export class SearchManager implements ISearchManager { result.directories = await connection .getRepository(DirectoryEntity) - .createQueryBuilder("dir") - .where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) + .createQueryBuilder('dir') + .where('dir.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .limit(201) .getMany(); @@ -146,22 +146,22 @@ export class SearchManager implements ISearchManager { result.photos = await connection .getRepository(PhotoEntity) - .createQueryBuilder("photo") - .orderBy("photo.metadata.creationDate", "ASC") - .where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) - .innerJoinAndSelect("photo.directory", "directory") + .createQueryBuilder('photo') + .orderBy('photo.metadata.creationDate', 'ASC') + .where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .innerJoinAndSelect('photo.directory', 'directory') .limit(10) .getMany(); result.directories = await connection .getRepository(DirectoryEntity) - .createQueryBuilder("dir") - .where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"}) + .createQueryBuilder('dir') + .where('dir.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .limit(10) .getMany(); diff --git a/backend/model/sql/SharingManager.ts b/backend/model/sql/SharingManager.ts index c2bbb96..0d427b1 100644 --- a/backend/model/sql/SharingManager.ts +++ b/backend/model/sql/SharingManager.ts @@ -1,9 +1,9 @@ -import {ISharingManager} from "../interfaces/ISharingManager"; -import {SharingDTO} from "../../../common/entities/SharingDTO"; -import {SQLConnection} from "./SQLConnection"; -import {SharingEntity} from "./enitites/SharingEntity"; -import {Config} from "../../../common/config/private/Config"; -import {PasswordHelper} from "../PasswordHelper"; +import {ISharingManager} from '../interfaces/ISharingManager'; +import {SharingDTO} from '../../../common/entities/SharingDTO'; +import {SQLConnection} from './SQLConnection'; +import {SharingEntity} from './enitites/SharingEntity'; +import {Config} from '../../../common/config/private/Config'; +import {PasswordHelper} from '../PasswordHelper'; export class SharingManager implements ISharingManager { @@ -11,8 +11,8 @@ export class SharingManager implements ISharingManager { const connection = await SQLConnection.getConnection(); return connection .getRepository(SharingEntity) - .createQueryBuilder("share") - .where("expires < :now", {now: Date.now()}) + .createQueryBuilder('share') + .where('expires < :now', {now: Date.now()}) .delete() .execute(); } @@ -42,7 +42,7 @@ export class SharingManager implements ISharingManager { }); if (sharing.timeStamp < Date.now() - Config.Server.sharing.updateTimeout) { - throw "Sharing is locked, can't update anymore" + throw 'Sharing is locked, can\'t update anymore'; } if (inSharing.password == null) { sharing.password = null; diff --git a/backend/model/sql/UserManager.ts b/backend/model/sql/UserManager.ts index adf5d01..f85f47c 100644 --- a/backend/model/sql/UserManager.ts +++ b/backend/model/sql/UserManager.ts @@ -1,8 +1,8 @@ -import {UserDTO, UserRoles} from "../../../common/entities/UserDTO"; -import {IUserManager} from "../interfaces/IUserManager"; -import {UserEntity} from "./enitites/UserEntity"; -import {SQLConnection} from "./SQLConnection"; -import {PasswordHelper} from "../PasswordHelper"; +import {UserDTO, UserRoles} from '../../../common/entities/UserDTO'; +import {IUserManager} from '../interfaces/IUserManager'; +import {UserEntity} from './enitites/UserEntity'; +import {SQLConnection} from './SQLConnection'; +import {PasswordHelper} from '../PasswordHelper'; export class UserManager implements IUserManager { @@ -22,7 +22,7 @@ export class UserManager implements IUserManager { } if (pass && !PasswordHelper.comparePassword(pass, user.password)) { - throw "No entry found"; + throw 'No entry found'; } return user; @@ -64,7 +64,7 @@ export class UserManager implements IUserManager { } public async changePassword(request: any) { - throw new Error("not implemented"); //TODO: implement + throw new Error('not implemented'); //TODO: implement } } diff --git a/backend/model/sql/enitites/DirectoryEntity.ts b/backend/model/sql/enitites/DirectoryEntity.ts index 60739da..1987ec9 100644 --- a/backend/model/sql/enitites/DirectoryEntity.ts +++ b/backend/model/sql/enitites/DirectoryEntity.ts @@ -1,6 +1,6 @@ -import {Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn} from "typeorm"; -import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO"; -import {PhotoEntity} from "./PhotoEntity"; +import {Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn} from 'typeorm'; +import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO'; +import {PhotoEntity} from './PhotoEntity'; @Entity() export class DirectoryEntity implements DirectoryDTO { @@ -23,12 +23,12 @@ export class DirectoryEntity implements DirectoryDTO { /** * Last time the directory was fully scanned, not only for a few photos to create a preview */ - @Column({type: "bigint", nullable: true}) + @Column({type: 'bigint', nullable: true}) public lastScanned: number; isPartial?: boolean; - @ManyToOne(type => DirectoryEntity, directory => directory.directories, {onDelete: "CASCADE"}) + @ManyToOne(type => DirectoryEntity, directory => directory.directories, {onDelete: 'CASCADE'}) public parent: DirectoryEntity; @OneToMany(type => DirectoryEntity, dir => dir.parent) diff --git a/backend/model/sql/enitites/PhotoEntity.ts b/backend/model/sql/enitites/PhotoEntity.ts index c1fb779..9350e49 100644 --- a/backend/model/sql/enitites/PhotoEntity.ts +++ b/backend/model/sql/enitites/PhotoEntity.ts @@ -1,37 +1,30 @@ -import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from "typeorm"; -import { - CameraMetadata, - GPSMetadata, - ImageSize, - PhotoDTO, - PhotoMetadata, - PositionMetaData -} from "../../../../common/entities/PhotoDTO"; -import {DirectoryEntity} from "./DirectoryEntity"; +import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from 'typeorm'; +import {CameraMetadata, GPSMetadata, ImageSize, PhotoDTO, PhotoMetadata, PositionMetaData} from '../../../../common/entities/PhotoDTO'; +import {DirectoryEntity} from './DirectoryEntity'; @Entity() export class CameraMetadataEntity implements CameraMetadata { - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) ISO: number; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) model: string; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) maker: string; - @Column("int", {nullable: true}) + @Column('int', {nullable: true}) fStop: number; - @Column("int", {nullable: true}) + @Column('int', {nullable: true}) exposure: number; - @Column("int", {nullable: true}) + @Column('int', {nullable: true}) focalLength: number; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) lens: string; } @@ -39,21 +32,21 @@ export class CameraMetadataEntity implements CameraMetadata { @Entity() export class GPSMetadataEntity implements GPSMetadata { - @Column("int", {nullable: true}) + @Column('int', {nullable: true}) latitude: number; - @Column("int", {nullable: true}) + @Column('int', {nullable: true}) longitude: number; - @Column("int", {nullable: true}) + @Column('int', {nullable: true}) altitude: number; } @Entity() export class ImageSizeEntity implements ImageSize { - @Column("int") + @Column('int') width: number; - @Column("int") + @Column('int') height: number; } @@ -64,13 +57,13 @@ export class PositionMetaDataEntity implements PositionMetaData { @Column(type => GPSMetadataEntity) GPSData: GPSMetadataEntity; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) country: string; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) state: string; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) city: string; } @@ -78,7 +71,7 @@ export class PositionMetaDataEntity implements PositionMetaData { @Entity() export class PhotoMetadataEntity implements PhotoMetadata { - @Column("simple-array") + @Column('simple-array') keywords: Array; @Column(type => CameraMetadataEntity) @@ -90,10 +83,10 @@ export class PhotoMetadataEntity implements PhotoMetadata { @Column(type => ImageSizeEntity) size: ImageSizeEntity; - @Column("bigint") + @Column('bigint') creationDate: number; - @Column("int") + @Column('int') fileSize: number; } @@ -104,10 +97,10 @@ export class PhotoEntity implements PhotoDTO { @PrimaryGeneratedColumn() id: number; - @Column("text") + @Column('text') name: string; - @ManyToOne(type => DirectoryEntity, directory => directory.photos, {onDelete: "CASCADE"}) + @ManyToOne(type => DirectoryEntity, directory => directory.photos, {onDelete: 'CASCADE'}) directory: DirectoryEntity; @Column(type => PhotoMetadataEntity) diff --git a/backend/model/sql/enitites/SharingEntity.ts b/backend/model/sql/enitites/SharingEntity.ts index a318f9a..2031235 100644 --- a/backend/model/sql/enitites/SharingEntity.ts +++ b/backend/model/sql/enitites/SharingEntity.ts @@ -1,7 +1,7 @@ -import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from "typeorm"; -import {SharingDTO} from "../../../../common/entities/SharingDTO"; -import {UserEntity} from "./UserEntity"; -import {UserDTO} from "../../../../common/entities/UserDTO"; +import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from 'typeorm'; +import {SharingDTO} from '../../../../common/entities/SharingDTO'; +import {UserEntity} from './UserEntity'; +import {UserDTO} from '../../../../common/entities/UserDTO'; @Entity() export class SharingEntity implements SharingDTO { @@ -14,7 +14,7 @@ export class SharingEntity implements SharingDTO { @Column() path: string; - @Column({type: "text", nullable: true}) + @Column({type: 'text', nullable: true}) password: string; @Column() diff --git a/backend/model/sql/enitites/UserEntity.ts b/backend/model/sql/enitites/UserEntity.ts index 2211a47..99c603c 100644 --- a/backend/model/sql/enitites/UserEntity.ts +++ b/backend/model/sql/enitites/UserEntity.ts @@ -1,5 +1,5 @@ -import {UserDTO, UserRoles} from "../../../../common/entities/UserDTO"; -import {Column, Entity, PrimaryGeneratedColumn} from "typeorm"; +import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO'; +import {Column, Entity, PrimaryGeneratedColumn} from 'typeorm'; @Entity() export class UserEntity implements UserDTO { @@ -13,10 +13,10 @@ export class UserEntity implements UserDTO { @Column() password: string; - @Column("smallint") + @Column('smallint') role: UserRoles; - @Column("text", {nullable: true}) + @Column('text', {nullable: true}) permissions: string[]; } diff --git a/backend/model/sql/enitites/VersionEntity.ts b/backend/model/sql/enitites/VersionEntity.ts index b4c7108..6ff466d 100644 --- a/backend/model/sql/enitites/VersionEntity.ts +++ b/backend/model/sql/enitites/VersionEntity.ts @@ -1,4 +1,4 @@ -import {Column, Entity, PrimaryGeneratedColumn} from "typeorm"; +import {Column, Entity, PrimaryGeneratedColumn} from 'typeorm'; @Entity() export class VersionEntity { diff --git a/backend/model/threading/DiskMangerWorker.ts b/backend/model/threading/DiskMangerWorker.ts index 6fe68ec..6f57761 100644 --- a/backend/model/threading/DiskMangerWorker.ts +++ b/backend/model/threading/DiskMangerWorker.ts @@ -1,14 +1,14 @@ -import * as fs from "fs"; -import * as path from "path"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {CameraMetadata, GPSMetadata, ImageSize, PhotoDTO, PhotoMetadata} from "../../../common/entities/PhotoDTO"; -import {Logger} from "../../Logger"; -import {IptcParser} from "ts-node-iptc"; -import {ExifParserFactory} from "ts-exif-parser"; -import {ProjectPath} from "../../ProjectPath"; -import {Config} from "../../../common/config/private/Config"; +import * as fs from 'fs'; +import * as path from 'path'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {CameraMetadata, GPSMetadata, ImageSize, PhotoDTO, PhotoMetadata} from '../../../common/entities/PhotoDTO'; +import {Logger} from '../../Logger'; +import {IptcParser} from 'ts-node-iptc'; +import {ExifParserFactory} from 'ts-exif-parser'; +import {ProjectPath} from '../../ProjectPath'; +import {Config} from '../../../common/config/private/Config'; -const LOG_TAG = "[DiskManagerTask]"; +const LOG_TAG = '[DiskManagerTask]'; export class DiskMangerWorker { private static isImage(fullPath: string) { @@ -139,7 +139,7 @@ export class DiskMangerWorker { metadata.size = {width: 1, height: 1}; } } catch (err) { - Logger.debug(LOG_TAG, "Error parsing exif", fullPath, err); + Logger.debug(LOG_TAG, 'Error parsing exif', fullPath, err); metadata.size = {width: 1, height: 1}; } diff --git a/backend/model/threading/TaskQue.ts b/backend/model/threading/TaskQue.ts index 6bd1007..b39c061 100644 --- a/backend/model/threading/TaskQue.ts +++ b/backend/model/threading/TaskQue.ts @@ -1,5 +1,5 @@ -import {RendererInput, ThumbnailWoker} from "./ThumbnailWoker"; -import {Config} from "../../../common/config/private/Config"; +import {RendererInput, ThumbnailWoker} from './ThumbnailWoker'; +import {Config} from '../../../common/config/private/Config'; interface QueTask { diff --git a/backend/model/threading/ThreadPool.ts b/backend/model/threading/ThreadPool.ts index 08a81ea..6ca79d1 100644 --- a/backend/model/threading/ThreadPool.ts +++ b/backend/model/threading/ThreadPool.ts @@ -1,10 +1,10 @@ -import * as cluster from "cluster"; -import {Logger} from "../../Logger"; -import {DiskManagerTask, ThumbnailTask, WorkerMessage, WorkerTask, WorkerTaskTypes} from "./Worker"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {RendererInput} from "./ThumbnailWoker"; -import {Config} from "../../../common/config/private/Config"; -import {ITaskQue} from "./TaskQue"; +import * as cluster from 'cluster'; +import {Logger} from '../../Logger'; +import {DiskManagerTask, ThumbnailTask, WorkerMessage, WorkerTask, WorkerTaskTypes} from './Worker'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {RendererInput} from './ThumbnailWoker'; +import {Config} from '../../../common/config/private/Config'; +import {ITaskQue} from './TaskQue'; interface PoolTask { @@ -24,7 +24,7 @@ export class ThreadPool { private tasks: PoolTask[] = []; constructor(private size: number) { - Logger.silly("Creating thread pool with", size, "workers"); + Logger.silly('Creating thread pool with', size, 'workers'); for (let i = 0; i < size; i++) { this.startWorker(); } @@ -39,14 +39,14 @@ export class ThreadPool { }); worker.worker.on('exit', (code, signal) => { ThreadPool.WorkerCount--; - Logger.warn('Worker ' + worker.worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal + ", worker count:", ThreadPool.WorkerCount); + Logger.warn('Worker ' + worker.worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal + ', worker count:', ThreadPool.WorkerCount); Logger.debug('Starting a new worker'); this.startWorker(); }); - worker.worker.on("message", (msg: WorkerMessage) => { + worker.worker.on('message', (msg: WorkerMessage) => { if (worker.poolTask == null) { - throw "No worker task after worker task is completed" + throw 'No worker task after worker task is completed'; } if (msg.error) { worker.poolTask.promise.reject(msg.error); diff --git a/backend/model/threading/ThumbnailWoker.ts b/backend/model/threading/ThumbnailWoker.ts index 4449302..ed47665 100644 --- a/backend/model/threading/ThumbnailWoker.ts +++ b/backend/model/threading/ThumbnailWoker.ts @@ -1,7 +1,7 @@ -import {Metadata, SharpInstance} from "sharp"; -import {Dimensions, State} from "gm"; -import {Logger} from "../../Logger"; -import {ThumbnailProcessingLib} from "../../../common/config/private/IPrivateConfig"; +import {Metadata, SharpInstance} from 'sharp'; +import {Dimensions, State} from 'gm'; +import {Logger} from '../../Logger'; +import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig'; export class ThumbnailWoker { @@ -39,14 +39,14 @@ export class RendererFactory { case ThumbnailProcessingLib.sharp: return RendererFactory.Sharp(); } - throw "unknown renderer" + throw 'unknown renderer'; } public static Jimp() { - const Jimp = require("jimp"); + const Jimp = require('jimp'); return async (input: RendererInput): Promise => { //generate thumbnail - Logger.silly("[JimpThRenderer] rendering thumbnail:", input.imagePath); + Logger.silly('[JimpThRenderer] rendering thumbnail:', input.imagePath); const image = await Jimp.read(input.imagePath); /** * newWidth * newHeight = size*size @@ -83,10 +83,10 @@ export class RendererFactory { public static Sharp() { - const sharp = require("sharp"); + const sharp = require('sharp'); return async (input: RendererInput): Promise => { - Logger.silly("[SharpThRenderer] rendering thumbnail:", input.imagePath); + Logger.silly('[SharpThRenderer] rendering thumbnail:', input.imagePath); const image: SharpInstance = sharp(input.imagePath); const metadata: Metadata = await image.metadata(); @@ -120,10 +120,10 @@ export class RendererFactory { public static Gm() { - const gm = require("gm"); + const gm = require('gm'); return (input: RendererInput): Promise => { return new Promise((resolve, reject) => { - Logger.silly("[GMThRenderer] rendering thumbnail:", input.imagePath); + Logger.silly('[GMThRenderer] rendering thumbnail:', input.imagePath); let image: State = gm(input.imagePath); image.size((err, value: Dimensions) => { if (err) { diff --git a/backend/model/threading/Worker.ts b/backend/model/threading/Worker.ts index bcad1e6..5eed74d 100644 --- a/backend/model/threading/Worker.ts +++ b/backend/model/threading/Worker.ts @@ -1,13 +1,13 @@ -import {DiskMangerWorker} from "./DiskMangerWorker"; -import {Logger} from "../../Logger"; -import {RendererInput, ThumbnailWoker} from "./ThumbnailWoker"; -import {ThumbnailProcessingLib} from "../../../common/config/private/IPrivateConfig"; +import {DiskMangerWorker} from './DiskMangerWorker'; +import {Logger} from '../../Logger'; +import {RendererInput, ThumbnailWoker} from './ThumbnailWoker'; +import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig'; export class Worker { public static process() { - Logger.debug("Worker is waiting for tasks"); + Logger.debug('Worker is waiting for tasks'); process.on('message', async (task: WorkerTask) => { try { let result = null; @@ -22,8 +22,8 @@ export class Worker { result = await ThumbnailWoker.render((task).input, (task).renderer); break; default: - Logger.error("Unknown worker task type"); - throw "Unknown worker task type"; + Logger.error('Unknown worker task type'); + throw 'Unknown worker task type'; } process.send({ error: null, diff --git a/backend/routes/AdminRouter.ts b/backend/routes/AdminRouter.ts index 33c88bc..8c0b072 100644 --- a/backend/routes/AdminRouter.ts +++ b/backend/routes/AdminRouter.ts @@ -1,7 +1,7 @@ -import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs"; -import {UserRoles} from "../../common/entities/UserDTO"; -import {RenderingMWs} from "../middlewares/RenderingMWs"; -import {AdminMWs} from "../middlewares/AdminMWs"; +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {UserRoles} from '../../common/entities/UserDTO'; +import {RenderingMWs} from '../middlewares/RenderingMWs'; +import {AdminMWs} from '../middlewares/AdminMWs'; export class AdminRouter { public static route(app: any) { @@ -12,98 +12,97 @@ export class AdminRouter { private static addIndexGallery(app) { - app.get("/api/admin/indexes/job/progress", + app.get('/api/admin/indexes/job/progress', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.getIndexingProgress, RenderingMWs.renderResult ); - app.put("/api/admin/indexes/job", + app.put('/api/admin/indexes/job', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.startIndexing, RenderingMWs.renderResult ); - app.delete("/api/admin/indexes/job", + app.delete('/api/admin/indexes/job', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.cancelIndexing, RenderingMWs.renderResult ); - app.delete("/api/admin/indexes", + app.delete('/api/admin/indexes', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.resetIndexes, RenderingMWs.renderResult ); - }; + } private static addSettings(app) { - app.get("/api/settings", + app.get('/api/settings', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), RenderingMWs.renderConfig ); - app.put("/api/settings/database", + app.put('/api/settings/database', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateDatabaseSettings, RenderingMWs.renderOK ); - app.put("/api/settings/map", + app.put('/api/settings/map', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateMapSettings, RenderingMWs.renderOK ); - app.put("/api/settings/authentication", + app.put('/api/settings/authentication', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateAuthenticationSettings, RenderingMWs.renderOK ); - app.put("/api/settings/thumbnail", + app.put('/api/settings/thumbnail', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateThumbnailSettings, RenderingMWs.renderOK ); - app.put("/api/settings/search", + app.put('/api/settings/search', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateSearchSettings, RenderingMWs.renderOK ); - app.put("/api/settings/share", + app.put('/api/settings/share', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateShareSettings, RenderingMWs.renderOK ); - app.put("/api/settings/basic", + app.put('/api/settings/basic', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateBasicSettings, RenderingMWs.renderOK ); - app.put("/api/settings/other", + app.put('/api/settings/other', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateOtherSettings, RenderingMWs.renderOK ); - app.put("/api/settings/indexing", + app.put('/api/settings/indexing', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), AdminMWs.updateIndexingSettings, RenderingMWs.renderOK ); - - }; + } } diff --git a/backend/routes/ErrorRouter.ts b/backend/routes/ErrorRouter.ts index 406f116..f38351f 100644 --- a/backend/routes/ErrorRouter.ts +++ b/backend/routes/ErrorRouter.ts @@ -1,6 +1,6 @@ -import {RenderingMWs} from "../middlewares/RenderingMWs"; -import {ErrorCodes, ErrorDTO} from "../../common/entities/Error"; -import {Logger} from "../Logger"; +import {RenderingMWs} from '../middlewares/RenderingMWs'; +import {ErrorCodes, ErrorDTO} from '../../common/entities/Error'; +import {Logger} from '../Logger'; import Request = Express.Request; import Response = Express.Response; @@ -12,17 +12,17 @@ export class ErrorRouter { } private static addApiErrorHandler(app) { - app.use("/api/*", + app.use('/api/*', RenderingMWs.renderError ); - }; + } private static addGenericHandler(app) { app.use((err: any, req: Request, res: Response, next: Function) => { - //Flush out the stack to the console - Logger.error("Unexpected error:"); + // Flush out the stack to the console + Logger.error('Unexpected error:'); console.error(err); - next(new ErrorDTO(ErrorCodes.SERVER_ERROR, "Unknown server side error", err)); + next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'Unknown server side error', err)); }, RenderingMWs.renderError ); diff --git a/backend/routes/GalleryRouter.ts b/backend/routes/GalleryRouter.ts index 14f2ea4..242204c 100644 --- a/backend/routes/GalleryRouter.ts +++ b/backend/routes/GalleryRouter.ts @@ -1,8 +1,8 @@ -import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs"; -import {GalleryMWs} from "../middlewares/GalleryMWs"; -import {RenderingMWs} from "../middlewares/RenderingMWs"; -import {ThumbnailGeneratorMWs} from "../middlewares/thumbnail/ThumbnailGeneratorMWs"; -import {UserRoles} from "../../common/entities/UserDTO"; +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {GalleryMWs} from '../middlewares/GalleryMWs'; +import {RenderingMWs} from '../middlewares/RenderingMWs'; +import {ThumbnailGeneratorMWs} from '../middlewares/thumbnail/ThumbnailGeneratorMWs'; +import {UserRoles} from '../../common/entities/UserDTO'; export class GalleryRouter { public static route(app: any) { @@ -18,7 +18,7 @@ export class GalleryRouter { } private static addDirectoryList(app) { - app.get(["/api/gallery/content/:directory(*)", "/api/gallery/", "/api/gallery//"], + app.get(['/api/gallery/content/:directory(*)', '/api/gallery/', '/api/gallery//'], AuthenticationMWs.authenticate, AuthenticationMWs.authoriseDirectory, GalleryMWs.listDirectory, @@ -26,40 +26,40 @@ export class GalleryRouter { GalleryMWs.removeCyclicDirectoryReferences, RenderingMWs.renderResult ); - }; + } private static addGetImage(app) { - app.get(["/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))"], + app.get(['/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))'], AuthenticationMWs.authenticate, - //TODO: authorize path + // TODO: authorize path GalleryMWs.loadImage, RenderingMWs.renderFile ); - }; + } private static addGetImageThumbnail(app) { - app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?", + app.get('/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?', AuthenticationMWs.authenticate, - //TODO: authorize path + // TODO: authorize path GalleryMWs.loadImage, ThumbnailGeneratorMWs.generateThumbnail, RenderingMWs.renderFile ); - }; + } private static addGetImageIcon(app) { - app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon", + app.get('/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon', AuthenticationMWs.authenticate, - //TODO: authorize path + // TODO: authorize path GalleryMWs.loadImage, ThumbnailGeneratorMWs.generateIcon, RenderingMWs.renderFile ); - }; + } private static addSearch(app) { - app.get("/api/search/:text", + app.get('/api/search/:text', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), GalleryMWs.search, @@ -67,10 +67,10 @@ export class GalleryRouter { GalleryMWs.removeCyclicDirectoryReferences, RenderingMWs.renderResult ); - }; + } private static addInstantSearch(app) { - app.get("/api/instant-search/:text", + app.get('/api/instant-search/:text', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), GalleryMWs.instantSearch, @@ -78,16 +78,15 @@ export class GalleryRouter { GalleryMWs.removeCyclicDirectoryReferences, RenderingMWs.renderResult ); - }; + } private static addAutoComplete(app) { - app.get("/api/autocomplete/:text", + app.get('/api/autocomplete/:text', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), GalleryMWs.autocomplete, RenderingMWs.renderResult ); - }; - + } } diff --git a/backend/routes/LoggerRouter.ts b/backend/routes/LoggerRouter.ts index 0a77c91..69d95c0 100644 --- a/backend/routes/LoggerRouter.ts +++ b/backend/routes/LoggerRouter.ts @@ -1,5 +1,5 @@ -import {NextFunction, Request, Response} from "express"; -import {Logger} from "../Logger"; +import {NextFunction, Request, Response} from 'express'; +import {Logger} from '../Logger'; /** * Adds logging to express @@ -7,32 +7,32 @@ import {Logger} from "../Logger"; export class LoggerRouter { public static route(app: any) { - app.get("/api*", (req: Request, res: Response, next: NextFunction) => { + app.get('/api*', (req: Request, res: Response, next: NextFunction) => { req['_startTime'] = Date.now(); req['logged'] = true; const end = res.end; res.end = (a?: any, b?: any, c?: any) => { res.end = end; res.end(a, b, c); - Logger.verbose(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + "ms"); + Logger.verbose(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + 'ms'); }; return next(); }); - app.get("/node_modules*", (req: Request, res: Response, next: NextFunction) => { + app.get('/node_modules*', (req: Request, res: Response, next: NextFunction) => { req['_startTime'] = Date.now(); req['logged'] = true; const end = res.end; res.end = (a?: any, b?: any, c?: any) => { res.end = end; res.end(a, b, c); - Logger.silly(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + "ms"); + Logger.silly(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + 'ms'); }; return next(); }); app.use((req: Request, res: Response, next: NextFunction) => { - if (req['logged'] == true) { + if (req['logged'] === true) { return next(); } req['_startTime'] = Date.now(); @@ -40,7 +40,7 @@ export class LoggerRouter { res.end = (a?: any, b?: any, c?: any) => { res.end = end; res.end(a, b, c); - Logger.debug(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + "ms"); + Logger.debug(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + 'ms'); }; return next(); }); diff --git a/backend/routes/NotificationRouter.ts b/backend/routes/NotificationRouter.ts index 7481ce7..93a0bcd 100644 --- a/backend/routes/NotificationRouter.ts +++ b/backend/routes/NotificationRouter.ts @@ -1,9 +1,7 @@ -import {UserRoles} from "../../common/entities/UserDTO"; -import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs"; -import {RenderingMWs} from "../middlewares/RenderingMWs"; -import {NotificationMWs} from "../middlewares/NotificationMWs"; -import Request = Express.Request; -import Response = Express.Response; +import {UserRoles} from '../../common/entities/UserDTO'; +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {RenderingMWs} from '../middlewares/RenderingMWs'; +import {NotificationMWs} from '../middlewares/NotificationMWs'; export class NotificationRouter { public static route(app: any) { @@ -12,13 +10,12 @@ export class NotificationRouter { } private static addGetNotifications(app) { - app.get("/api/notifications", + app.get('/api/notifications', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), NotificationMWs.list, RenderingMWs.renderResult ); - }; - + } } diff --git a/backend/routes/PublicRouter.ts b/backend/routes/PublicRouter.ts index 351214f..c601ec8 100644 --- a/backend/routes/PublicRouter.ts +++ b/backend/routes/PublicRouter.ts @@ -1,18 +1,18 @@ -import {NextFunction, Request, Response} from "express"; -import * as path from "path"; -import * as fs from "fs"; -import {Utils} from "../../common/Utils"; -import {Config} from "../../common/config/private/Config"; -import {ProjectPath} from "../ProjectPath"; -import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs"; -import {CookieNames} from "../../common/CookieNames"; +import {NextFunction, Request, Response} from 'express'; +import * as path from 'path'; +import * as fs from 'fs'; +import {Utils} from '../../common/Utils'; +import {Config} from '../../common/config/private/Config'; +import {ProjectPath} from '../ProjectPath'; +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {CookieNames} from '../../common/CookieNames'; export class PublicRouter { public static route(app) { const setLocale = (req: Request, res: Response, next: Function) => { - let localePath = ""; + let localePath = ''; let selectedLocale = req['locale']; if (req.cookies && req.cookies[CookieNames.lang]) { if (Config.Client.languages.indexOf(req.cookies[CookieNames.lang]) !== -1) { @@ -37,7 +37,7 @@ export class PublicRouter { if (Config.Client.languages.indexOf(locale) !== -1) { res.cookie(CookieNames.lang, locale); } - res.redirect("/?ln=" + locale); + res.redirect('/?ln=' + locale); }; }; @@ -47,7 +47,7 @@ export class PublicRouter { res.tpl.user = null; if (req.session.user) { - let user = Utils.clone(req.session.user); + const user = Utils.clone(req.session.user); delete user.password; res.tpl.user = user; } @@ -60,13 +60,13 @@ export class PublicRouter { res.render(path.resolve(ProjectPath.FrontendFolder, 'config_inject.ejs'), res.tpl); }); - app.get(['/', '/login', "/gallery*", "/share*", "/admin", "/search*"], + app.get(['/', '/login', '/gallery*', '/share*', '/admin', '/search*'], AuthenticationMWs.tryAuthenticate, setLocale, renderIndex ); Config.Client.languages.forEach(l => { - app.get(['/' + l + '/', '/' + l + '/login', '/' + l + "/gallery*", '/' + l + "/share*", '/' + l + "/admin", '/' + l + "/search*"], + app.get(['/' + l + '/', '/' + l + '/login', '/' + l + '/gallery*', '/' + l + '/share*', '/' + l + '/admin', '/' + l + '/search*'], redirectToBase(l) ); }); diff --git a/backend/routes/SharingRouter.ts b/backend/routes/SharingRouter.ts index 2a81447..58dd1b1 100644 --- a/backend/routes/SharingRouter.ts +++ b/backend/routes/SharingRouter.ts @@ -1,7 +1,7 @@ -import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs"; -import {UserRoles} from "../../common/entities/UserDTO"; -import {RenderingMWs} from "../middlewares/RenderingMWs"; -import {SharingMWs} from "../middlewares/SharingMWs"; +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {UserRoles} from '../../common/entities/UserDTO'; +import {RenderingMWs} from '../middlewares/RenderingMWs'; +import {SharingMWs} from '../middlewares/SharingMWs'; export class SharingRouter { public static route(app: any) { @@ -13,7 +13,7 @@ export class SharingRouter { } private static addShareLogin(app) { - app.post("/api/share/login", + app.post('/api/share/login', AuthenticationMWs.inverseAuthenticate, AuthenticationMWs.shareLogin, RenderingMWs.renderSessionUser @@ -21,7 +21,7 @@ export class SharingRouter { }; private static addGetSharing(app) { - app.get("/api/share/:sharingKey", + app.get('/api/share/:sharingKey', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.LimitedGuest), SharingMWs.getSharing, @@ -30,7 +30,7 @@ export class SharingRouter { }; private static addCreateSharing(app) { - app.post(["/api/share/:directory(*)", "/api/share/", "/api/share//"], + app.post(['/api/share/:directory(*)', '/api/share/', '/api/share//'], AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.User), SharingMWs.createSharing, @@ -39,7 +39,7 @@ export class SharingRouter { }; private static addUpdateSharing(app) { - app.put(["/api/share/:directory(*)", "/api/share/", "/api/share//"], + app.put(['/api/share/:directory(*)', '/api/share/', '/api/share//'], AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.User), SharingMWs.updateSharing, diff --git a/backend/routes/UserRouter.ts b/backend/routes/UserRouter.ts index db49140..eb5b6fb 100644 --- a/backend/routes/UserRouter.ts +++ b/backend/routes/UserRouter.ts @@ -1,8 +1,8 @@ -import {UserMWs} from "../middlewares/user/UserMWs"; -import {UserRoles} from "../../common/entities/UserDTO"; -import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs"; -import {UserRequestConstrainsMWs} from "../middlewares/user/UserRequestConstrainsMWs"; -import {RenderingMWs} from "../middlewares/RenderingMWs"; +import {UserMWs} from '../middlewares/user/UserMWs'; +import {UserRoles} from '../../common/entities/UserDTO'; +import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs'; +import {UserRequestConstrainsMWs} from '../middlewares/user/UserRequestConstrainsMWs'; +import {RenderingMWs} from '../middlewares/RenderingMWs'; export class UserRouter { public static route(app) { @@ -19,77 +19,77 @@ export class UserRouter { } private static addLogin(app) { - app.post("/api/user/login", + app.post('/api/user/login', AuthenticationMWs.inverseAuthenticate, AuthenticationMWs.login, RenderingMWs.renderSessionUser ); - }; + } private static addLogout(app) { - app.post("/api/user/logout", + app.post('/api/user/logout', AuthenticationMWs.logout, RenderingMWs.renderOK ); - }; + } private static addGetSessionUser(app) { - app.get("/api/user/login", + app.get('/api/user/login', AuthenticationMWs.authenticate, RenderingMWs.renderSessionUser ); - }; + } private static addChangePassword(app) { - app.post("/api/user/:id/password", + app.post('/api/user/:id/password', AuthenticationMWs.authenticate, UserRequestConstrainsMWs.forceSelfRequest, UserMWs.changePassword, RenderingMWs.renderOK ); - }; + } private static addCreateUser(app) { - app.put("/api/user", + app.put('/api/user', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), UserMWs.createUser, RenderingMWs.renderOK ); - }; + } private static addDeleteUser(app) { - app.delete("/api/user/:id", + app.delete('/api/user/:id', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), UserRequestConstrainsMWs.notSelfRequest, UserMWs.deleteUser, RenderingMWs.renderOK ); - }; + } private static addListUsers(app) { - app.get("/api/user/list", + app.get('/api/user/list', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), UserMWs.listUsers, RenderingMWs.renderResult ); - }; + } private static addChangeRole(app) { - app.post("/api/user/:id/role", + app.post('/api/user/:id/role', AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Admin), UserRequestConstrainsMWs.notSelfRequestOr2Admins, UserMWs.changeRole, RenderingMWs.renderOK ); - }; + } } diff --git a/backend/server.ts b/backend/server.ts index 7512c12..b0fe81d 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -1,29 +1,29 @@ -import * as _express from "express"; -import * as _bodyParser from "body-parser"; -import * as cookieParser from "cookie-parser"; -import * as _http from "http"; -import * as locale from "locale"; -import {PublicRouter} from "./routes/PublicRouter"; -import {UserRouter} from "./routes/UserRouter"; -import {GalleryRouter} from "./routes/GalleryRouter"; -import {AdminRouter} from "./routes/AdminRouter"; -import {ErrorRouter} from "./routes/ErrorRouter"; -import {SharingRouter} from "./routes/SharingRouter"; -import {ObjectManagerRepository} from "./model/ObjectManagerRepository"; -import {Logger} from "./Logger"; -import {Config} from "../common/config/private/Config"; -import {DatabaseType} from "../common/config/private/IPrivateConfig"; -import {LoggerRouter} from "./routes/LoggerRouter"; -import {ThumbnailGeneratorMWs} from "./middlewares/thumbnail/ThumbnailGeneratorMWs"; -import {DiskManager} from "./model/DiskManger"; -import {NotificationRouter} from "./routes/NotificationRouter"; -import {ConfigDiagnostics} from "./model/ConfigDiagnostics"; -import {Localizations} from "./model/Localizations"; -import {CookieNames} from "../common/CookieNames"; +import * as _express from 'express'; +import * as _bodyParser from 'body-parser'; +import * as cookieParser from 'cookie-parser'; +import * as _http from 'http'; +import * as locale from 'locale'; +import {PublicRouter} from './routes/PublicRouter'; +import {UserRouter} from './routes/UserRouter'; +import {GalleryRouter} from './routes/GalleryRouter'; +import {AdminRouter} from './routes/AdminRouter'; +import {ErrorRouter} from './routes/ErrorRouter'; +import {SharingRouter} from './routes/SharingRouter'; +import {ObjectManagerRepository} from './model/ObjectManagerRepository'; +import {Logger} from './Logger'; +import {Config} from '../common/config/private/Config'; +import {DatabaseType} from '../common/config/private/IPrivateConfig'; +import {LoggerRouter} from './routes/LoggerRouter'; +import {ThumbnailGeneratorMWs} from './middlewares/thumbnail/ThumbnailGeneratorMWs'; +import {DiskManager} from './model/DiskManger'; +import {NotificationRouter} from './routes/NotificationRouter'; +import {ConfigDiagnostics} from './model/ConfigDiagnostics'; +import {Localizations} from './model/Localizations'; +import {CookieNames} from '../common/CookieNames'; const _session = require('cookie-session'); -const LOG_TAG = "[server]"; +const LOG_TAG = '[server]'; export class Server { @@ -31,16 +31,16 @@ export class Server { private server: any; constructor() { - if (!(process.env.NODE_ENV == "production")) { - Logger.debug(LOG_TAG, "Running in DEBUG mode"); + if (!(process.env.NODE_ENV == 'production')) { + Logger.debug(LOG_TAG, 'Running in DEBUG mode'); } this.init(); } async init() { - Logger.info(LOG_TAG, "running diagnostics..."); + Logger.info(LOG_TAG, 'running diagnostics...'); await ConfigDiagnostics.runDiagnostics(); - Logger.info(LOG_TAG, "using config:"); + Logger.info(LOG_TAG, 'using config:'); Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t')); this.app = _express(); @@ -61,7 +61,7 @@ export class Server { this.app.use(_session({ name: CookieNames.session, - keys: ["key1" + s4() + s4() + s4() + s4(), "key2" + s4() + s4() + s4() + s4(), "key3" + s4() + s4() + s4() + s4()] + keys: ['key1' + s4() + s4() + s4() + s4(), 'key2' + s4() + s4() + s4() + s4(), 'key3' + s4() + s4() + s4() + s4()] })); /* this.app.use((req: Request, res: Response, next: NextFunction) => { @@ -81,7 +81,7 @@ export class Server { ThumbnailGeneratorMWs.init(); Localizations.init(); - this.app.use(locale(Config.Client.languages, "en")); + this.app.use(locale(Config.Client.languages, 'en')); if (Config.Server.database.type != DatabaseType.memory) { await ObjectManagerRepository.InitSQLManagers(); } else { diff --git a/frontend/app/admin/admin.component.ts b/frontend/app/admin/admin.component.ts index a8c5744..2e45ffb 100644 --- a/frontend/app/admin/admin.component.ts +++ b/frontend/app/admin/admin.component.ts @@ -1,10 +1,10 @@ -import {Component, OnInit} from "@angular/core"; -import {AuthenticationService} from "../model/network/authentication.service"; -import {UserRoles} from "../../../common/entities/UserDTO"; -import {NotificationService} from "../model/notification.service"; -import {NotificationType} from "../../../common/entities/NotificationDTO"; -import {NavigationService} from "../model/navigation.service"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component, OnInit} from '@angular/core'; +import {AuthenticationService} from '../model/network/authentication.service'; +import {UserRoles} from '../../../common/entities/UserDTO'; +import {NotificationService} from '../model/notification.service'; +import {NotificationType} from '../../../common/entities/NotificationDTO'; +import {NavigationService} from '../model/navigation.service'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'admin', @@ -15,16 +15,16 @@ export class AdminComponent implements OnInit { simplifiedMode = true; text = { - Advanced: "Advanced", - Simplified: "Simplified" + Advanced: 'Advanced', + Simplified: 'Simplified' }; constructor(private _authService: AuthenticationService, private _navigation: NavigationService, public notificationService: NotificationService, public i18n: I18n) { - this.text.Advanced = i18n("Advanced"); - this.text.Simplified = i18n("Simplified"); + this.text.Advanced = i18n('Advanced'); + this.text.Simplified = i18n('Simplified'); } ngOnInit() { @@ -38,13 +38,13 @@ export class AdminComponent implements OnInit { public getCss(type: NotificationType) { switch (type) { case NotificationType.error: - return "danger"; + return 'danger'; case NotificationType.warning: - return "warning"; + return 'warning'; case NotificationType.info: - return "info"; + return 'info'; } - return "info"; + return 'info'; } } diff --git a/frontend/app/app.component.ts b/frontend/app/app.component.ts index 950b53d..396bee5 100644 --- a/frontend/app/app.component.ts +++ b/frontend/app/app.component.ts @@ -1,15 +1,15 @@ -import {Component, OnDestroy, OnInit, ViewContainerRef} from "@angular/core"; -import {AuthenticationService} from "./model/network/authentication.service"; -import {UserDTO} from "../../common/entities/UserDTO"; -import {Router} from "@angular/router"; -import {Config} from "../../common/config/public/Config"; -import {Title} from "@angular/platform-browser"; -import {NotificationService} from "./model/notification.service"; -import {ShareService} from "./gallery/share.service"; -import "hammerjs"; +import {Component, OnDestroy, OnInit, ViewContainerRef} from '@angular/core'; +import {AuthenticationService} from './model/network/authentication.service'; +import {UserDTO} from '../../common/entities/UserDTO'; +import {Router} from '@angular/router'; +import {Config} from '../../common/config/public/Config'; +import {Title} from '@angular/platform-browser'; +import {NotificationService} from './model/notification.service'; +import {ShareService} from './gallery/share.service'; +import 'hammerjs'; @Component({ - selector: 'pi-gallery2-app', + selector: 'app-pi-gallery2', template: ``, }) @@ -55,17 +55,17 @@ export class AppComponent implements OnInit, OnDestroy { private toLogin() { if (this._shareService.isSharing()) { - return this._router.navigate(["shareLogin"], {queryParams: {sk: this._shareService.getSharingKey()}}); + return this._router.navigate(['shareLogin'], {queryParams: {sk: this._shareService.getSharingKey()}}); } else { - return this._router.navigate(["login"]); + return this._router.navigate(['login']); } } private toGallery() { if (this._shareService.isSharing()) { - return this._router.navigate(["share", this._shareService.getSharingKey()]); + return this._router.navigate(['share', this._shareService.getSharingKey()]); } else { - return this._router.navigate(["gallery", ""]); + return this._router.navigate(['gallery', '']); } } } diff --git a/frontend/app/app.module.ts b/frontend/app/app.module.ts index 92babec..a3317f6 100644 --- a/frontend/app/app.module.ts +++ b/frontend/app/app.module.ts @@ -1,62 +1,62 @@ -import {Injectable, LOCALE_ID, NgModule, TRANSLATIONS} from "@angular/core"; -import {BrowserModule, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from "@angular/platform-browser"; -import {FormsModule} from "@angular/forms"; -import {HttpModule} from "@angular/http"; -import {AgmCoreModule} from "@agm/core"; -import {AppComponent} from "./app.component"; -import {appRoutes} from "./app.routing"; -import {UserService} from "./model/network/user.service"; -import {GalleryService} from "./gallery/gallery.service"; -import {NetworkService} from "./model/network/network.service"; -import {ThumbnailLoaderService} from "./gallery/thumnailLoader.service"; -import {GalleryCacheService} from "./gallery/cache.gallery.service"; -import {FullScreenService} from "./gallery/fullscreen.service"; -import {AuthenticationService} from "./model/network/authentication.service"; -import {UserMangerSettingsComponent} from "./settings/usermanager/usermanager.settings.component"; -import {FrameComponent} from "./frame/frame.component"; -import {GalleryLightboxPhotoComponent} from "./gallery/lightbox/photo/photo.lightbox.gallery.component"; -import {GalleryPhotoLoadingComponent} from "./gallery/grid/photo/loading/loading.photo.grid.gallery.component"; -import {GalleryNavigatorComponent} from "./gallery/navigator/navigator.gallery.component"; -import {GallerySearchComponent} from "./gallery/search/search.gallery.component"; -import {GalleryLightboxComponent} from "./gallery/lightbox/lightbox.gallery.component"; -import {GalleryDirectoryComponent} from "./gallery/directory/directory.gallery.component"; -import {GalleryGridComponent} from "./gallery/grid/grid.gallery.component"; -import {GalleryPhotoComponent} from "./gallery/grid/photo/photo.grid.gallery.component"; -import {LoginComponent} from "./login/login.component"; -import {AdminComponent} from "./admin/admin.component"; -import {GalleryComponent} from "./gallery/gallery.component"; -import {StringifyRole} from "./pipes/StringifyRolePipe"; -import {GalleryMapComponent} from "./gallery/map/map.gallery.component"; -import {GalleryMapLightboxComponent} from "./gallery/map/lightbox/lightbox.map.gallery.component"; -import {ThumbnailManagerService} from "./gallery/thumnailManager.service"; -import {OverlayService} from "./gallery/overlay.service"; -import {Config} from "../../common/config/public/Config"; -import {LAZY_MAPS_API_CONFIG} from "@agm/core/services"; -import {SlimLoadingBarModule} from "ng2-slim-loading-bar"; -import {GalleryShareComponent} from "./gallery/share/share.gallery.component"; -import {ShareLoginComponent} from "./sharelogin/share-login.component"; -import {ShareService} from "./gallery/share.service"; -import {ModalModule} from "ngx-bootstrap/modal"; -import {DatabaseSettingsComponent} from "./settings/database/database.settings.component"; -import {ToastModule} from "ng2-toastr/ng2-toastr"; -import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; -import {NotificationService} from "./model/notification.service"; -import {JWBootstrapSwitchModule} from "jw-bootstrap-switch-ng2"; -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 {BsDropdownModule} from "ngx-bootstrap/dropdown"; -import {ThumbnailSettingsComponent} from "./settings/thumbnail/thumbanil.settings.component"; -import {SearchSettingsComponent} from "./settings/search/search.settings.component"; -import {SettingsService} from "./settings/settings.service"; -import {ShareSettingsComponent} from "./settings/share/share.settings.component"; -import {BasicSettingsComponent} from "./settings/basic/basic.settings.component"; -import {OtherSettingsComponent} from "./settings/other/other.settings.component"; +import {Injectable, LOCALE_ID, NgModule, TRANSLATIONS} from '@angular/core'; +import {BrowserModule, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '@angular/platform-browser'; +import {FormsModule} from '@angular/forms'; +import {AgmCoreModule} from '@agm/core'; +import {AppComponent} from './app.component'; +import {appRoutes} from './app.routing'; +import {UserService} from './model/network/user.service'; +import {GalleryService} from './gallery/gallery.service'; +import {NetworkService} from './model/network/network.service'; +import {ThumbnailLoaderService} from './gallery/thumnailLoader.service'; +import {GalleryCacheService} from './gallery/cache.gallery.service'; +import {FullScreenService} from './gallery/fullscreen.service'; +import {AuthenticationService} from './model/network/authentication.service'; +import {UserMangerSettingsComponent} from './settings/usermanager/usermanager.settings.component'; +import {FrameComponent} from './frame/frame.component'; +import {GalleryLightboxPhotoComponent} from './gallery/lightbox/photo/photo.lightbox.gallery.component'; +import {GalleryPhotoLoadingComponent} from './gallery/grid/photo/loading/loading.photo.grid.gallery.component'; +import {GalleryNavigatorComponent} from './gallery/navigator/navigator.gallery.component'; +import {GallerySearchComponent} from './gallery/search/search.gallery.component'; +import {GalleryLightboxComponent} from './gallery/lightbox/lightbox.gallery.component'; +import {GalleryDirectoryComponent} from './gallery/directory/directory.gallery.component'; +import {GalleryGridComponent} from './gallery/grid/grid.gallery.component'; +import {GalleryPhotoComponent} from './gallery/grid/photo/photo.grid.gallery.component'; +import {LoginComponent} from './login/login.component'; +import {AdminComponent} from './admin/admin.component'; +import {GalleryComponent} from './gallery/gallery.component'; +import {StringifyRole} from './pipes/StringifyRolePipe'; +import {GalleryMapComponent} from './gallery/map/map.gallery.component'; +import {GalleryMapLightboxComponent} from './gallery/map/lightbox/lightbox.map.gallery.component'; +import {ThumbnailManagerService} from './gallery/thumnailManager.service'; +import {OverlayService} from './gallery/overlay.service'; +import {Config} from '../../common/config/public/Config'; +import {LAZY_MAPS_API_CONFIG} from '@agm/core/services'; +import {SlimLoadingBarModule} from 'ng2-slim-loading-bar'; +import {GalleryShareComponent} from './gallery/share/share.gallery.component'; +import {ShareLoginComponent} from './sharelogin/share-login.component'; +import {ShareService} from './gallery/share.service'; +import {ModalModule} from 'ngx-bootstrap/modal'; +import {DatabaseSettingsComponent} from './settings/database/database.settings.component'; +import {ToastModule} from 'ng2-toastr/ng2-toastr'; +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {NotificationService} from './model/notification.service'; +import {JWBootstrapSwitchModule} from 'jw-bootstrap-switch-ng2'; +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 {BsDropdownModule} from 'ngx-bootstrap/dropdown'; +import {ThumbnailSettingsComponent} from './settings/thumbnail/thumbanil.settings.component'; +import {SearchSettingsComponent} from './settings/search/search.settings.component'; +import {SettingsService} from './settings/settings.service'; +import {ShareSettingsComponent} from './settings/share/share.settings.component'; +import {BasicSettingsComponent} from './settings/basic/basic.settings.component'; +import {OtherSettingsComponent} from './settings/other/other.settings.component'; +import {HttpClientModule} from '@angular/common/http'; import {DefaultUrlSerializer, UrlSerializer, UrlTree} from '@angular/router'; -import {IndexingSettingsComponent} from "./settings/indexing/indexing.settings.component"; -import {LanguageComponent} from "./language/language.component"; +import {IndexingSettingsComponent} from './settings/indexing/indexing.settings.component'; +import {LanguageComponent} from './language/language.component'; import {I18n} from '@ngx-translate/i18n-polyfill'; @Injectable() @@ -71,7 +71,7 @@ export class GoogleMapsConfig { export class MyHammerConfig extends HammerGestureConfig { overrides = { 'swipe': {direction: 31} // enable swipe up - } + }; } export class CustomUrlSerializer implements UrlSerializer { @@ -81,7 +81,7 @@ export class CustomUrlSerializer implements UrlSerializer { // Encode parentheses url = url.replace(/\(/g, '%28').replace(/\)/g, '%29'); // Use the default serializer. - return this._defaultUrlSerializer.parse(url) + return this._defaultUrlSerializer.parse(url); } serialize(tree: UrlTree): string { @@ -93,7 +93,7 @@ declare const require; export function translationsFactory(locale: string) { locale = locale || 'en'; // default to english if no locale - console.log("locale", locale); + console.log('locale', locale); return require(`raw-loader!../translate/messages.${locale}.xlf`); } @@ -101,7 +101,7 @@ export function translationsFactory(locale: string) { imports: [ BrowserModule, FormsModule, - HttpModule, + HttpClientModule, BrowserAnimationsModule, appRoutes, ClipboardModule, @@ -117,10 +117,10 @@ export function translationsFactory(locale: string) { LoginComponent, ShareLoginComponent, GalleryComponent, - //misc + // misc FrameComponent, LanguageComponent, - //Gallery + // Gallery GalleryLightboxPhotoComponent, GalleryPhotoLoadingComponent, GalleryGridComponent, @@ -135,7 +135,7 @@ export function translationsFactory(locale: string) { GalleryPhotoComponent, AdminComponent, InfoPanelLightboxComponent, - //Settings + // Settings UserMangerSettingsComponent, DatabaseSettingsComponent, MapSettingsComponent, diff --git a/frontend/app/app.routing.ts b/frontend/app/app.routing.ts index 0470db8..cb2b4e2 100644 --- a/frontend/app/app.routing.ts +++ b/frontend/app/app.routing.ts @@ -1,9 +1,9 @@ -import {ModuleWithProviders} from "@angular/core"; -import {RouterModule, Routes} from "@angular/router"; -import {LoginComponent} from "./login/login.component"; -import {GalleryComponent} from "./gallery/gallery.component"; -import {AdminComponent} from "./admin/admin.component"; -import {ShareLoginComponent} from "./sharelogin/share-login.component"; +import {ModuleWithProviders} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; +import {LoginComponent} from './login/login.component'; +import {GalleryComponent} from './gallery/gallery.component'; +import {AdminComponent} from './admin/admin.component'; +import {ShareLoginComponent} from './sharelogin/share-login.component'; const ROUTES: Routes = [ { diff --git a/frontend/app/frame/frame.component.css b/frontend/app/frame/frame.component.css index ca36e56..a19f403 100644 --- a/frontend/app/frame/frame.component.css +++ b/frontend/app/frame/frame.component.css @@ -53,7 +53,6 @@ ng2-slim-loading-bar { } } - .badge { margin-left: -5px; padding: 0; diff --git a/frontend/app/frame/frame.component.ts b/frontend/app/frame/frame.component.ts index 2475fc8..d18f797 100644 --- a/frontend/app/frame/frame.component.ts +++ b/frontend/app/frame/frame.component.ts @@ -1,10 +1,10 @@ -import {Component, ViewEncapsulation} from "@angular/core"; -import {RouterLink} from "@angular/router"; -import {AuthenticationService} from "../model/network/authentication.service"; -import {UserDTO, UserRoles} from "../../../common/entities/UserDTO"; -import {Config} from "../../../common/config/public/Config"; -import {BehaviorSubject} from "rxjs/BehaviorSubject"; -import {NotificationService} from "../model/notification.service"; +import {Component, ViewEncapsulation} from '@angular/core'; +import {RouterLink} from '@angular/router'; +import {AuthenticationService} from '../model/network/authentication.service'; +import {UserDTO, UserRoles} from '../../../common/entities/UserDTO'; +import {Config} from '../../../common/config/public/Config'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {NotificationService} from '../model/notification.service'; @Component({ selector: 'app-frame', diff --git a/frontend/app/gallery/IconPhoto.ts b/frontend/app/gallery/IconPhoto.ts index b9c3b84..6cbdb99 100644 --- a/frontend/app/gallery/IconPhoto.ts +++ b/frontend/app/gallery/IconPhoto.ts @@ -1,5 +1,6 @@ -import {PhotoDTO} from "../../../common/entities/PhotoDTO"; -import {Utils} from "../../../common/Utils"; +import {PhotoDTO} from '../../../common/entities/PhotoDTO'; +import {Utils} from '../../../common/Utils'; + export class IconPhoto { @@ -18,23 +19,23 @@ export class IconPhoto { } getIconPath() { - return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "icon"); + return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name, 'icon'); } getPhotoPath() { - return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name); + return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name); } equals(other: PhotoDTO | IconPhoto): boolean { //is gridphoto if (other instanceof IconPhoto) { - return this.photo.directory.path === other.photo.directory.path && this.photo.directory.name === other.photo.directory.name && this.photo.name === other.photo.name + return this.photo.directory.path === other.photo.directory.path && this.photo.directory.name === other.photo.directory.name && this.photo.name === other.photo.name; } //is photo if (other.directory) { - return this.photo.directory.path === other.directory.path && this.photo.directory.name === other.directory.name && this.photo.name === other.name + return this.photo.directory.path === other.directory.path && this.photo.directory.name === other.directory.name && this.photo.name === other.name; } return false; diff --git a/frontend/app/gallery/Photo.ts b/frontend/app/gallery/Photo.ts index 28dd0a9..0c1d6a5 100644 --- a/frontend/app/gallery/Photo.ts +++ b/frontend/app/gallery/Photo.ts @@ -1,7 +1,8 @@ -import {PhotoDTO} from "../../../common/entities/PhotoDTO"; -import {Utils} from "../../../common/Utils"; -import {IconPhoto} from "./IconPhoto"; -import {Config} from "../../../common/config/public/Config"; +import {PhotoDTO} from '../../../common/entities/PhotoDTO'; +import {Utils} from '../../../common/Utils'; +import {IconPhoto} from './IconPhoto'; +import {Config} from '../../../common/config/public/Config'; + export class Photo extends IconPhoto { @@ -50,13 +51,13 @@ export class Photo extends IconPhoto { getReplacementThumbnailPath() { let size = this.getReplacementThumbnailSize(); - return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "thumbnail", size.toString()); + return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name, 'thumbnail', size.toString()); } getThumbnailPath() { let size = this.getThumbnailSize(); - return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "thumbnail", size.toString()); + return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name, 'thumbnail', size.toString()); } diff --git a/frontend/app/gallery/cache.gallery.service.ts b/frontend/app/gallery/cache.gallery.service.ts index 1ad2a7e..f65014e 100644 --- a/frontend/app/gallery/cache.gallery.service.ts +++ b/frontend/app/gallery/cache.gallery.service.ts @@ -1,10 +1,10 @@ -import {Injectable} from "@angular/core"; -import {PhotoDTO} from "../../../common/entities/PhotoDTO"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {Utils} from "../../../common/Utils"; -import {Config} from "../../../common/config/public/Config"; -import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem"; -import {SearchResultDTO} from "../../../common/entities/SearchResultDTO"; +import {Injectable} from '@angular/core'; +import {PhotoDTO} from '../../../common/entities/PhotoDTO'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {Utils} from '../../../common/Utils'; +import {Config} from '../../../common/config/public/Config'; +import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem'; +import {SearchResultDTO} from '../../../common/entities/SearchResultDTO'; interface CacheItem { timestamp: number; @@ -14,11 +14,11 @@ interface CacheItem { @Injectable() export class GalleryCacheService { - private static CONTENT_PREFIX = "content:"; - private static AUTO_COMPLETE_PREFIX = "autocomplete:"; - private static INSTANT_SEARCH_PREFIX = "instant_search:"; - private static SEARCH_PREFIX = "search:"; - private static SEARCH_TYPE_PREFIX = ":type:"; + private static CONTENT_PREFIX = 'content:'; + private static AUTO_COMPLETE_PREFIX = 'autocomplete:'; + private static INSTANT_SEARCH_PREFIX = 'instant_search:'; + private static SEARCH_PREFIX = 'search:'; + private static SEARCH_TYPE_PREFIX = ':type:'; public getAutoComplete(text: string): Array { @@ -68,7 +68,7 @@ export class GalleryCacheService { public getSearch(text: string, type?: SearchTypes): SearchResultDTO { let key = GalleryCacheService.SEARCH_PREFIX + text; - if (typeof type != "undefined") { + if (typeof type != 'undefined') { key += GalleryCacheService.SEARCH_TYPE_PREFIX + type; } const tmp = localStorage.getItem(key); @@ -89,7 +89,7 @@ export class GalleryCacheService { item: searchResult }; let key = GalleryCacheService.SEARCH_PREFIX + text; - if (typeof type != "undefined") { + if (typeof type != 'undefined') { key += GalleryCacheService.SEARCH_TYPE_PREFIX + type; } localStorage.setItem(key, JSON.stringify(tmp)); diff --git a/frontend/app/gallery/directory/directory.gallery.component.ts b/frontend/app/gallery/directory/directory.gallery.component.ts index febb151..5537bab 100644 --- a/frontend/app/gallery/directory/directory.gallery.component.ts +++ b/frontend/app/gallery/directory/directory.gallery.component.ts @@ -1,11 +1,11 @@ -import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from "@angular/core"; -import {DomSanitizer} from "@angular/platform-browser"; -import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO"; -import {RouterLink} from "@angular/router"; -import {Utils} from "../../../../common/Utils"; -import {Photo} from "../Photo"; -import {Thumbnail, ThumbnailManagerService} from "../thumnailManager.service"; -import {ShareService} from "../share.service"; +import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {DomSanitizer} from '@angular/platform-browser'; +import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO'; +import {RouterLink} from '@angular/router'; +import {Utils} from '../../../../common/Utils'; +import {Photo} from '../Photo'; +import {Thumbnail, ThumbnailManagerService} from '../thumnailManager.service'; +import {ShareService} from '../share.service'; @Component({ selector: 'gallery-directory', @@ -15,7 +15,7 @@ import {ShareService} from "../share.service"; }) export class GalleryDirectoryComponent implements OnInit, OnDestroy { @Input() directory: DirectoryDTO; - @ViewChild("dirContainer") container: ElementRef; + @ViewChild('dirContainer') container: ElementRef; thumbnail: Thumbnail = null; constructor(private thumbnailService: ThumbnailManagerService, @@ -27,7 +27,7 @@ export class GalleryDirectoryComponent implements OnInit, OnDestroy { size: number = null; getSanitizedThUrl() { - return this._sanitizer.bypassSecurityTrustStyle('url(' + encodeURI(this.thumbnail.Src).replace(/\(/g, "%28").replace(/\)/g, "%29") + ')'); + return this._sanitizer.bypassSecurityTrustStyle('url(' + encodeURI(this.thumbnail.Src).replace(/\(/g, '%28').replace(/\)/g, '%29') + ')'); } //TODO: implement scroll diff --git a/frontend/app/gallery/fullscreen.service.ts b/frontend/app/gallery/fullscreen.service.ts index 3f351cd..1057938 100644 --- a/frontend/app/gallery/fullscreen.service.ts +++ b/frontend/app/gallery/fullscreen.service.ts @@ -1,5 +1,5 @@ -import {Injectable} from "@angular/core"; -import {Event} from "../../../common/event/Event"; +import {Injectable} from '@angular/core'; +import {Event} from '../../../common/event/Event'; @Injectable() export class FullScreenService { diff --git a/frontend/app/gallery/gallery.component.css b/frontend/app/gallery/gallery.component.css index c0ff8bb..cbd15da 100644 --- a/frontend/app/gallery/gallery.component.css +++ b/frontend/app/gallery/gallery.component.css @@ -1,9 +1,9 @@ gallery-map { - margin-right: 0; - margin-left: auto; - display: block; - height: 80px; - width: 100px; + margin-right: 0; + margin-left: auto; + display: block; + height: 80px; + width: 100px; } .directories { diff --git a/frontend/app/gallery/gallery.component.ts b/frontend/app/gallery/gallery.component.ts index f751ac4..9dc8a45 100644 --- a/frontend/app/gallery/gallery.component.ts +++ b/frontend/app/gallery/gallery.component.ts @@ -1,18 +1,18 @@ -import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core"; -import {AuthenticationService} from "../model/network/authentication.service"; -import {ActivatedRoute, Params, Router} from "@angular/router"; -import {GalleryService} from "./gallery.service"; -import {GalleryGridComponent} from "./grid/grid.gallery.component"; -import {GallerySearchComponent} from "./search/search.gallery.component"; -import {SearchTypes} from "../../../common/entities/AutoCompleteItem"; -import {Config} from "../../../common/config/public/Config"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {SearchResultDTO} from "../../../common/entities/SearchResultDTO"; -import {ShareService} from "./share.service"; -import {NavigationService} from "../model/navigation.service"; -import {UserRoles} from "../../../common/entities/UserDTO"; -import {Observable} from "rxjs/Rx"; -import {ContentWrapper} from "../../../common/entities/ConentWrapper"; +import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {AuthenticationService} from '../model/network/authentication.service'; +import {ActivatedRoute, Params, Router} from '@angular/router'; +import {GalleryService} from './gallery.service'; +import {GalleryGridComponent} from './grid/grid.gallery.component'; +import {GallerySearchComponent} from './search/search.gallery.component'; +import {SearchTypes} from '../../../common/entities/AutoCompleteItem'; +import {Config} from '../../../common/config/public/Config'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {SearchResultDTO} from '../../../common/entities/SearchResultDTO'; +import {ShareService} from './share.service'; +import {NavigationService} from '../model/navigation.service'; +import {UserRoles} from '../../../common/entities/UserDTO'; +import {Observable} from 'rxjs/Rx'; +import {ContentWrapper} from '../../../common/entities/ConentWrapper'; @Component({ selector: 'gallery', @@ -62,26 +62,33 @@ export class GalleryComponent implements OnInit, OnDestroy { this.countDown.second = t % 60; } - async ngOnInit() { - await this.shareService.wait(); - if (!this._authService.isAuthenticated() && - (!this.shareService.isSharing() || - (this.shareService.isSharing() && Config.Client.Sharing.passwordProtected == true))) { + private onRoute = async (params: Params) => { + const searchText = params['searchText']; + if (searchText && searchText != '') { + let typeString = params['type']; - return this._navigation.toLogin(); - } - this.showSearchBar = Config.Client.Search.enabled && this._authService.isAuthorized(UserRoles.Guest); - this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User); + if (typeString && typeString != '') { + let type: SearchTypes = SearchTypes[typeString]; + this._galleryService.search(searchText, type); + return; + } - this.subscription.content = this._galleryService.content.subscribe(this.onContentChange); - this.subscription.route = this._route.params.subscribe(this.onRoute); - - if (this.shareService.isSharing()) { - this.$counter = Observable.interval(1000); - this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x)); + this._galleryService.search(searchText); + return; } - } + if (params['sharingKey'] && params['sharingKey'] != '') { + const sharing = await this.shareService.getSharing(); + this._router.navigate(['/gallery', sharing.path], {queryParams: {sk: this.shareService.getSharingKey()}}); + return; + } + + let directoryName = params['directory']; + directoryName = directoryName || ''; + + this._galleryService.getDirectory(directoryName); + + }; ngOnDestroy() { if (this.subscription.content !== null) { @@ -118,33 +125,26 @@ export class GalleryComponent implements OnInit, OnDestroy { } }; - private onRoute = async (params: Params) => { - const searchText = params['searchText']; - if (searchText && searchText != "") { - let typeString = params['type']; + async ngOnInit() { + await this.shareService.wait(); + if (!this._authService.isAuthenticated() && + (!this.shareService.isSharing() || + (this.shareService.isSharing() && Config.Client.Sharing.passwordProtected == true))) { - if (typeString && typeString != "") { - let type: SearchTypes = SearchTypes[typeString]; - this._galleryService.search(searchText, type); - return; - } + return this._navigation.toLogin(); + } + this.showSearchBar = Config.Client.Search.enabled && this._authService.isAuthorized(UserRoles.Guest); + this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User); - this._galleryService.search(searchText); - return; + this.subscription.content = this._galleryService.content.subscribe(this.onContentChange); + this.subscription.route = this._route.params.subscribe(this.onRoute); + + if (this.shareService.isSharing()) { + this.$counter = Observable.interval(1000); + this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x)); } - if (params['sharingKey'] && params['sharingKey'] != "") { - const sharing = await this.shareService.getSharing(); - this._router.navigate(['/gallery', sharing.path], {queryParams: {sk: this.shareService.getSharingKey()}}); - return; - } - - let directoryName = params['directory']; - directoryName = directoryName || ""; - - this._galleryService.getDirectory(directoryName); - - }; + } onLightboxLastElement() { diff --git a/frontend/app/gallery/gallery.service.ts b/frontend/app/gallery/gallery.service.ts index 0bc63a1..2524b04 100644 --- a/frontend/app/gallery/gallery.service.ts +++ b/frontend/app/gallery/gallery.service.ts @@ -1,13 +1,13 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../model/network/network.service"; -import {ContentWrapper} from "../../../common/entities/ConentWrapper"; -import {DirectoryDTO} from "../../../common/entities/DirectoryDTO"; -import {SearchTypes} from "../../../common/entities/AutoCompleteItem"; -import {GalleryCacheService} from "./cache.gallery.service"; -import {BehaviorSubject} from "rxjs/BehaviorSubject"; -import {SharingDTO} from "../../../common/entities/SharingDTO"; -import {Config} from "../../../common/config/public/Config"; -import {ShareService} from "./share.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../model/network/network.service'; +import {ContentWrapper} from '../../../common/entities/ConentWrapper'; +import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; +import {SearchTypes} from '../../../common/entities/AutoCompleteItem'; +import {GalleryCacheService} from './cache.gallery.service'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {SharingDTO} from '../../../common/entities/SharingDTO'; +import {Config} from '../../../common/config/public/Config'; +import {ShareService} from './share.service'; @Injectable() export class GalleryService { @@ -49,7 +49,7 @@ export class GalleryService { } - const cw = await this.networkService.getJson("/gallery/content/" + directoryName, params); + const cw = await this.networkService.getJson('/gallery/content/' + directoryName, params); if (!cw || cw.notModified == true) { @@ -78,8 +78,8 @@ export class GalleryService { if (this.searchId != null) { clearTimeout(this.searchId); } - if (text === null || text === '' || text.trim() == ".") { - return null + if (text === null || text === '' || text.trim() == '.') { + return null; } this.content.next(new ContentWrapper()); @@ -87,10 +87,10 @@ export class GalleryService { cw.searchResult = this.galleryCacheService.getSearch(text, type); if (cw.searchResult == null) { const params = {}; - if (typeof type != "undefined") { + if (typeof type != 'undefined') { params['type'] = type; } - cw.searchResult = (await this.networkService.getJson("/search/" + text, params)).searchResult; + cw.searchResult = (await this.networkService.getJson('/search/' + text, params)).searchResult; this.galleryCacheService.setSearch(text, type, cw.searchResult); } this.content.next(cw); @@ -98,16 +98,16 @@ export class GalleryService { } public async instantSearch(text: string): Promise { - if (text === null || text === '' || text.trim() == ".") { + if (text === null || text === '' || text.trim() == '.') { const content = new ContentWrapper(this.lastDirectory); this.content.next(content); if (this.searchId != null) { clearTimeout(this.searchId); } if (!this.lastDirectory) { - this.getDirectory("/"); + this.getDirectory('/'); } - return null + return null; } if (this.searchId != null) { @@ -128,7 +128,7 @@ export class GalleryService { cw.searchResult = this.galleryCacheService.getInstantSearch(text); if (cw.searchResult == null) { - cw.searchResult = (await this.networkService.getJson("/instant-search/" + text)).searchResult; + cw.searchResult = (await this.networkService.getJson('/instant-search/' + text)).searchResult; this.galleryCacheService.setInstantSearch(text, cw.searchResult); } } @@ -145,7 +145,7 @@ export class GalleryService { } public async getSharing(sharingKey: string): Promise { - return this.networkService.getJson("/share/" + sharingKey); + return this.networkService.getJson('/share/' + sharingKey); } } diff --git a/frontend/app/gallery/grid/GridPhoto.ts b/frontend/app/gallery/grid/GridPhoto.ts index 292fda1..bd09e12 100644 --- a/frontend/app/gallery/grid/GridPhoto.ts +++ b/frontend/app/gallery/grid/GridPhoto.ts @@ -1,5 +1,6 @@ -import {PhotoDTO} from "../../../../common/entities/PhotoDTO"; -import {Photo} from "../Photo"; +import {PhotoDTO} from '../../../../common/entities/PhotoDTO'; +import {Photo} from '../Photo'; + export class GridPhoto extends Photo { diff --git a/frontend/app/gallery/grid/GridRowBuilder.ts b/frontend/app/gallery/grid/GridRowBuilder.ts index 36e2826..586c7a7 100644 --- a/frontend/app/gallery/grid/GridRowBuilder.ts +++ b/frontend/app/gallery/grid/GridRowBuilder.ts @@ -1,4 +1,4 @@ -import {PhotoDTO} from "../../../../common/entities/PhotoDTO"; +import {PhotoDTO} from '../../../../common/entities/PhotoDTO'; export class GridRowBuilder { diff --git a/frontend/app/gallery/grid/grid.gallery.component.css b/frontend/app/gallery/grid/grid.gallery.component.css index a11f2d8..a32806c 100644 --- a/frontend/app/gallery/grid/grid.gallery.component.css +++ b/frontend/app/gallery/grid/grid.gallery.component.css @@ -1,12 +1,12 @@ div { - /*display: block;*/ - line-height: normal; - font-size: 0; + /*display: block;*/ + line-height: normal; + font-size: 0; } gallery-grid-photo { - display: inline-block; + display: inline-block; - cursor: pointer; - margin: 2px; + cursor: pointer; + margin: 2px; } diff --git a/frontend/app/gallery/grid/grid.gallery.component.html b/frontend/app/gallery/grid/grid.gallery.component.html index c09edd3..24874de 100644 --- a/frontend/app/gallery/grid/grid.gallery.component.html +++ b/frontend/app/gallery/grid/grid.gallery.component.html @@ -1,12 +1,12 @@
- + - -
\ No newline at end of file + + diff --git a/frontend/app/gallery/grid/grid.gallery.component.ts b/frontend/app/gallery/grid/grid.gallery.component.ts index 80274c0..67529ce 100644 --- a/frontend/app/gallery/grid/grid.gallery.component.ts +++ b/frontend/app/gallery/grid/grid.gallery.component.ts @@ -10,14 +10,14 @@ import { QueryList, ViewChild, ViewChildren -} from "@angular/core"; -import {PhotoDTO} from "../../../../common/entities/PhotoDTO"; -import {GridRowBuilder} from "./GridRowBuilder"; -import {GalleryLightboxComponent} from "../lightbox/lightbox.gallery.component"; -import {GridPhoto} from "./GridPhoto"; -import {GalleryPhotoComponent} from "./photo/photo.grid.gallery.component"; -import {OverlayService} from "../overlay.service"; -import {Config} from "../../../../common/config/public/Config"; +} from '@angular/core'; +import {PhotoDTO} from '../../../../common/entities/PhotoDTO'; +import {GridRowBuilder} from './GridRowBuilder'; +import {GalleryLightboxComponent} from '../lightbox/lightbox.gallery.component'; +import {GridPhoto} from './GridPhoto'; +import {GalleryPhotoComponent} from './photo/photo.grid.gallery.component'; +import {OverlayService} from '../overlay.service'; +import {Config} from '../../../../common/config/public/Config'; @Component({ selector: 'gallery-grid', @@ -154,7 +154,7 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy this.renderedPhotoIndex < numberOfPhotos)) { let ret = this.renderARow(); if (ret === null) { - throw new Error("Grid photos rendering failed"); + throw new Error('Grid photos rendering failed'); } renderedContentHeight += ret; } diff --git a/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.css b/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.css index 57d1ea9..7892058 100644 --- a/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.css +++ b/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.css @@ -1,97 +1,97 @@ .static { - width: 100%; - height: 100%; - background-color: #bbbbbb; - color: #7f7f7f; - font-size: 50px; + width: 100%; + height: 100%; + background-color: #bbbbbb; + color: #7f7f7f; + font-size: 50px; } .static span { - top: calc(50% - 25px); - left: calc(50% - 25px); + top: calc(50% - 25px); + left: calc(50% - 25px); } .sk-cube-grid { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } .sk-cube-grid .sk-cube { - width: calc(100% / 3); - height: calc(100% / 3); - background-color: #bbbbbb; - float: left; + width: calc(100% / 3); + height: calc(100% / 3); + background-color: #bbbbbb; + float: left; } .sk-cube-grid.animate .sk-cube { - -webkit-animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out; - animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out; + -webkit-animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out; + animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out; } .sk-cube-grid.animate .sk-cube1 { - -webkit-animation-delay: 0.4s; - animation-delay: 0.4s; + -webkit-animation-delay: 0.4s; + animation-delay: 0.4s; } .sk-cube-grid.animate .sk-cube2 { - -webkit-animation-delay: 0.6s; - animation-delay: 0.6s; + -webkit-animation-delay: 0.6s; + animation-delay: 0.6s; } .sk-cube-grid.animate .sk-cube3 { - -webkit-animation-delay: 0.8s; - animation-delay: 0.8s; + -webkit-animation-delay: 0.8s; + animation-delay: 0.8s; } .sk-cube-grid.animate .sk-cube4 { - -webkit-animation-delay: 0.2s; - animation-delay: 0.2s; + -webkit-animation-delay: 0.2s; + animation-delay: 0.2s; } .sk-cube-grid.animate .sk-cube5 { - -webkit-animation-delay: 0.4s; - animation-delay: 0.4s; + -webkit-animation-delay: 0.4s; + animation-delay: 0.4s; } .sk-cube-grid.animate .sk-cube6 { - -webkit-animation-delay: 0.6s; - animation-delay: 0.6s; + -webkit-animation-delay: 0.6s; + animation-delay: 0.6s; } .sk-cube-grid.animate .sk-cube7 { - -webkit-animation-delay: 0s; - animation-delay: 0s; + -webkit-animation-delay: 0s; + animation-delay: 0s; } .sk-cube-grid.animate .sk-cube8 { - -webkit-animation-delay: 0.2s; - animation-delay: 0.2s; + -webkit-animation-delay: 0.2s; + animation-delay: 0.2s; } .sk-cube-grid.animate .sk-cube9 { - -webkit-animation-delay: 0.4s; - animation-delay: 0.4s; + -webkit-animation-delay: 0.4s; + animation-delay: 0.4s; } @-webkit-keyframes sk-cubeGridScaleDelay { - 0%, 70%, 100% { - -webkit-transform: scale3D(1, 1, 1); - transform: scale3D(1, 1, 1); - } - 35% { - -webkit-transform: scale3D(0, 0, 1); - transform: scale3D(0, 0, 1); - } + 0%, 70%, 100% { + -webkit-transform: scale3D(1, 1, 1); + transform: scale3D(1, 1, 1); + } + 35% { + -webkit-transform: scale3D(0, 0, 1); + transform: scale3D(0, 0, 1); + } } @keyframes sk-cubeGridScaleDelay { - 0%, 70%, 100% { - -webkit-transform: scale3D(1, 1, 1); - transform: scale3D(1, 1, 1); - } - 35% { - -webkit-transform: scale3D(0, 0, 1); - transform: scale3D(0, 0, 1); - } + 0%, 70%, 100% { + -webkit-transform: scale3D(1, 1, 1); + transform: scale3D(1, 1, 1); + } + 35% { + -webkit-transform: scale3D(0, 0, 1); + transform: scale3D(0, 0, 1); + } } diff --git a/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.html b/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.html index d727f5b..fdc9e20 100644 --- a/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.html +++ b/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.html @@ -4,13 +4,13 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.ts b/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.ts index 79f598d..dab7594 100644 --- a/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.ts +++ b/frontend/app/gallery/grid/photo/loading/loading.photo.grid.gallery.component.ts @@ -1,4 +1,4 @@ -import {Component, Input} from "@angular/core"; +import {Component, Input} from '@angular/core'; @Component({ selector: 'gallery-grid-photo-loading', diff --git a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css index 063cb48..3fcb97a 100644 --- a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css +++ b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css @@ -49,11 +49,11 @@ img { } .info { - background-color: transparent; - color: white; - font-size: medium; - position: relative; - padding: 5px; + background-color: transparent; + color: white; + font-size: medium; + position: relative; + padding: 5px; margin-top: 0; transition: margin .3s ease-out, background-color .3s ease-out; diff --git a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.ts b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.ts index fd7e67e..01be3f9 100644 --- a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.ts +++ b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.ts @@ -1,11 +1,11 @@ -import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from "@angular/core"; -import {Dimension, IRenderable} from "../../../model/IRenderable"; -import {GridPhoto} from "../GridPhoto"; -import {SearchTypes} from "../../../../../common/entities/AutoCompleteItem"; -import {RouterLink} from "@angular/router"; -import {Thumbnail, ThumbnailManagerService} from "../../thumnailManager.service"; -import {Config} from "../../../../../common/config/public/Config"; -import {AnimationBuilder} from "@angular/animations"; +import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {Dimension, IRenderable} from '../../../model/IRenderable'; +import {GridPhoto} from '../GridPhoto'; +import {SearchTypes} from '../../../../../common/entities/AutoCompleteItem'; +import {RouterLink} from '@angular/router'; +import {Thumbnail, ThumbnailManagerService} from '../../thumnailManager.service'; +import {Config} from '../../../../../common/config/public/Config'; +import {AnimationBuilder} from '@angular/animations'; @Component({ selector: 'gallery-grid-photo', @@ -15,9 +15,9 @@ import {AnimationBuilder} from "@angular/animations"; }) export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy { @Input() gridPhoto: GridPhoto; - @ViewChild("img") imageRef: ElementRef; - @ViewChild("info") infoDiv: ElementRef; - @ViewChild("photoContainer") container: ElementRef; + @ViewChild('img') imageRef: ElementRef; + @ViewChild('info') infoDiv: ElementRef; + @ViewChild('photoContainer') container: ElementRef; thumbnail: Thumbnail; /* @@ -35,7 +35,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy { infoBar = { marginTop: 0, visible: false, - background: "rgba(0,0,0,0.0)" + background: 'rgba(0,0,0,0.0)' }; animationTimer = null; @@ -83,7 +83,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy { getPositionText(): string { if (!this.gridPhoto) { - return "" + return ''; } return this.gridPhoto.photo.metadata.positionData.city || this.gridPhoto.photo.metadata.positionData.state || @@ -97,7 +97,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy { clearTimeout(this.animationTimer); } this.animationTimer = setTimeout(() => { - this.infoBar.background = "rgba(0,0,0,0.8)"; + this.infoBar.background = 'rgba(0,0,0,0.8)'; if (!this.infoDiv) { this.animationTimer = setTimeout(() => { if (!this.infoDiv) { @@ -115,7 +115,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy { mouseOut() { this.infoBar.marginTop = 0; - this.infoBar.background = "rgba(0,0,0,0.0)"; + this.infoBar.background = 'rgba(0,0,0,0.0)'; if (this.animationTimer != null) { clearTimeout(this.animationTimer); } diff --git a/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts b/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts index 2fdc905..5815e23 100644 --- a/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts +++ b/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts @@ -1,6 +1,6 @@ -import {Component, ElementRef, EventEmitter, Input, Output} from "@angular/core"; -import {PhotoDTO} from "../../../../../common/entities/PhotoDTO"; -import {Config} from "../../../../../common/config/public/Config"; +import {Component, ElementRef, EventEmitter, Input, Output} from '@angular/core'; +import {PhotoDTO} from '../../../../../common/entities/PhotoDTO'; +import {Config} from '../../../../../common/config/public/Config'; @Component({ selector: 'info-panel', @@ -21,7 +21,7 @@ export class InfoPanelLightboxComponent { } calcFileSize() { - let postFixes = ["B", "KB", "MB", "GB", "TB"]; + let postFixes = ['B', 'KB', 'MB', 'GB', 'TB']; let index = 0; let size = this.photo.metadata.fileSize; while (size > 1000 && index < postFixes.length - 1) { @@ -42,8 +42,8 @@ export class InfoPanelLightboxComponent { getDate() { const date = new Date(this.photo.metadata.creationDate); - let locale = "en-us"; - return date.toLocaleString(locale, {month: "long"}) + " " + date.getDate(); + let locale = 'en-us'; + return date.toLocaleString(locale, {month: 'long'}) + ' ' + date.getDate(); } getTime() { @@ -53,31 +53,31 @@ export class InfoPanelLightboxComponent { getDay() { const date = new Date(this.photo.metadata.creationDate); - let locale = "en-us"; - return date.toLocaleString(locale, {weekday: "long"}); + let locale = 'en-us'; + return date.toLocaleString(locale, {weekday: 'long'}); } toFraction(f) { if (f > 1) { return f; } - return "1/" + (1 / f); + return '1/' + (1 / f); } hasGPS() { return this.photo.metadata.positionData && this.photo.metadata.positionData.GPSData && - this.photo.metadata.positionData.GPSData.latitude && this.photo.metadata.positionData.GPSData.longitude + this.photo.metadata.positionData.GPSData.latitude && this.photo.metadata.positionData.GPSData.longitude; } getPositionText(): string { if (!this.photo.metadata.positionData) { - return ""; + return ''; } let str = this.photo.metadata.positionData.city || this.photo.metadata.positionData.state; if (str.length != 0) { - str += ", "; + str += ', '; } str += this.photo.metadata.positionData.country; diff --git a/frontend/app/gallery/lightbox/lightbox.gallery.component.ts b/frontend/app/gallery/lightbox/lightbox.gallery.component.ts index 1283ea5..10cd079 100644 --- a/frontend/app/gallery/lightbox/lightbox.gallery.component.ts +++ b/frontend/app/gallery/lightbox/lightbox.gallery.component.ts @@ -1,23 +1,13 @@ -import { - ChangeDetectorRef, - Component, - ElementRef, - EventEmitter, - HostListener, - OnDestroy, - Output, - QueryList, - ViewChild -} from "@angular/core"; -import {PhotoDTO} from "../../../../common/entities/PhotoDTO"; -import {GalleryPhotoComponent} from "../grid/photo/photo.grid.gallery.component"; -import {Dimension} from "../../model/IRenderable"; -import {FullScreenService} from "../fullscreen.service"; -import {OverlayService} from "../overlay.service"; -import {Subscription} from "rxjs"; -import {animate, AnimationBuilder, AnimationPlayer, style} from "@angular/animations"; -import {GalleryLightboxPhotoComponent} from "./photo/photo.lightbox.gallery.component"; -import {Observable} from "rxjs/Observable"; +import {ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, OnDestroy, Output, QueryList, ViewChild} from '@angular/core'; +import {PhotoDTO} from '../../../../common/entities/PhotoDTO'; +import {GalleryPhotoComponent} from '../grid/photo/photo.grid.gallery.component'; +import {Dimension} from '../../model/IRenderable'; +import {FullScreenService} from '../fullscreen.service'; +import {OverlayService} from '../overlay.service'; +import {Subscription} from 'rxjs'; +import {animate, AnimationBuilder, AnimationPlayer, style} from '@angular/animations'; +import {GalleryLightboxPhotoComponent} from './photo/photo.lightbox.gallery.component'; +import {Observable} from 'rxjs/Observable'; @Component({ selector: 'gallery-lightbox', @@ -28,8 +18,8 @@ export class GalleryLightboxComponent implements OnDestroy { @Output('onLastElement') onLastElement = new EventEmitter(); - @ViewChild("photo") photoElement: GalleryLightboxPhotoComponent; - @ViewChild("lightbox") lightboxElement: ElementRef; + @ViewChild('photo') photoElement: GalleryLightboxPhotoComponent; + @ViewChild('lightbox') lightboxElement: ElementRef; public navigation = {hasPrev: true, hasNext: true}; public blackCanvasOpacity: any = 0; @@ -108,40 +98,13 @@ export class GalleryLightboxComponent implements OnDestroy { this.updateActivePhoto(photoIndex, resize); } - private updateActivePhoto(photoIndex: number, resize: boolean = true) { - let pcList = this.gridPhotoQL.toArray(); - - - if (photoIndex < 0 || photoIndex > this.gridPhotoQL.length) { - throw new Error("Can't find the photo"); - } - this.activePhotoId = photoIndex; - this.activePhoto = pcList[photoIndex]; - - if (resize) { - this.animatePhoto(this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo)); - } - this.navigation.hasPrev = photoIndex > 0; - this.navigation.hasNext = photoIndex + 1 < pcList.length; - - let to = this.activePhoto.getDimension(); - - //if target image out of screen -> scroll to there - if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getPhotoFrameHeight() < to.top) { - this.setBodyScrollTop(to.top); - } - - } - - startPhotoDimension: Dimension = {top: 0, left: 0, width: 0, height: 0}; - public show(photo: PhotoDTO) { this.controllersVisible = true; this.showControls(); this.visible = true; let selectedPhoto = this.findPhotoComponent(photo); if (selectedPhoto === null) { - throw new Error("Can't find Photo"); + throw new Error('Can\'t find Photo'); } const lightboxDimension = selectedPhoto.getDimension(); @@ -168,6 +131,33 @@ export class GalleryLightboxComponent implements OnDestroy { this.showPhoto(this.gridPhotoQL.toArray().indexOf(selectedPhoto), false); } + startPhotoDimension: Dimension = {top: 0, left: 0, width: 0, height: 0}; + + private updateActivePhoto(photoIndex: number, resize: boolean = true) { + let pcList = this.gridPhotoQL.toArray(); + + + if (photoIndex < 0 || photoIndex > this.gridPhotoQL.length) { + throw new Error('Can\'t find the photo'); + } + this.activePhotoId = photoIndex; + this.activePhoto = pcList[photoIndex]; + + if (resize) { + this.animatePhoto(this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo)); + } + this.navigation.hasPrev = photoIndex > 0; + this.navigation.hasNext = photoIndex + 1 < pcList.length; + + let to = this.activePhoto.getDimension(); + + //if target image out of screen -> scroll to there + if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getPhotoFrameHeight() < to.top) { + this.setBodyScrollTop(to.top); + } + + } + public hide() { this.controllersVisible = false; this.fullScreenService.exitFullScreen(); diff --git a/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.css b/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.css index 4f38ff0..3ac2717 100644 --- a/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.css +++ b/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.css @@ -1,9 +1,9 @@ .imgContainer img { - position: absolute; + position: absolute; } .imgContainer { - justify-content: center; /* add to align horizontal */ - align-items: center; /* add to align vertical */ + justify-content: center; /* add to align horizontal */ + align-items: center; /* add to align vertical */ } diff --git a/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.html b/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.html index 7db9e06..91afe10 100644 --- a/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.html +++ b/frontend/app/gallery/lightbox/photo/photo.lightbox.gallery.component.html @@ -1,8 +1,8 @@
- + = []; mapCenter = {latitude: 0, longitude: 0}; - @ViewChild("map") map: ElementRef; + @ViewChild('map') map: ElementRef; //TODO: fix zooming ngOnChanges() { diff --git a/frontend/app/gallery/navigator/navigator.gallery.component.ts b/frontend/app/gallery/navigator/navigator.gallery.component.ts index 6850320..0d17b0e 100644 --- a/frontend/app/gallery/navigator/navigator.gallery.component.ts +++ b/frontend/app/gallery/navigator/navigator.gallery.component.ts @@ -1,10 +1,10 @@ -import {Component, Input, OnChanges} from "@angular/core"; -import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO"; -import {RouterLink} from "@angular/router"; -import {UserDTO} from "../../../../common/entities/UserDTO"; -import {AuthenticationService} from "../../model/network/authentication.service"; -import {ShareService} from "../share.service"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component, Input, OnChanges} from '@angular/core'; +import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO'; +import {RouterLink} from '@angular/router'; +import {UserDTO} from '../../../../common/entities/UserDTO'; +import {AuthenticationService} from '../../model/network/authentication.service'; +import {ShareService} from '../share.service'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'gallery-navbar', @@ -31,14 +31,14 @@ export class GalleryNavigatorComponent implements OnChanges { return []; } - let path = this.directory.path.replace(new RegExp("\\\\", 'g'), "/"); + let path = this.directory.path.replace(new RegExp('\\\\', 'g'), '/'); - let dirs = path.split("/"); + let dirs = path.split('/'); dirs.push(this.directory.name); //removing empty strings for (let i = 0; i < dirs.length; i++) { - if (!dirs[i] || 0 === dirs[i].length || "." === dirs[i]) { + if (!dirs[i] || 0 === dirs[i].length || '.' === dirs[i]) { dirs.splice(i, 1); i--; } @@ -49,14 +49,14 @@ export class GalleryNavigatorComponent implements OnChanges { //create root link if (dirs.length == 0) { - arr.push({name: this.i18n("Images"), route: null}); + arr.push({name: this.i18n('Images'), route: null}); } else { - arr.push({name: this.i18n("Images"), route: UserDTO.isPathAvailable("/", user.permissions) ? "/" : null}); + arr.push({name: this.i18n('Images'), route: UserDTO.isPathAvailable('/', user.permissions) ? '/' : null}); } //create rest navigation dirs.forEach((name, index) => { - const route = dirs.slice(0, dirs.indexOf(name) + 1).join("/"); + const route = dirs.slice(0, dirs.indexOf(name) + 1).join('/'); if (dirs.length - 1 == index) { arr.push({name: name, route: null}); } else { diff --git a/frontend/app/gallery/overlay.service.ts b/frontend/app/gallery/overlay.service.ts index b86966a..5e4fc01 100644 --- a/frontend/app/gallery/overlay.service.ts +++ b/frontend/app/gallery/overlay.service.ts @@ -1,5 +1,5 @@ -import {Injectable} from "@angular/core"; -import {Event} from "../../../common/event/Event"; +import {Injectable} from '@angular/core'; +import {Event} from '../../../common/event/Event'; @Injectable() export class OverlayService { @@ -24,20 +24,20 @@ export class OverlayService { if (this.scrollWidth == null) { - let outer = document.createElement("div"); - outer.style.visibility = "hidden"; - outer.style.width = "100px"; - outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps + let outer = document.createElement('div'); + outer.style.visibility = 'hidden'; + outer.style.width = '100px'; + outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps document.body.appendChild(outer); let widthNoScroll = outer.offsetWidth; // force scrollbars - outer.style.overflowY = "scroll"; + outer.style.overflowY = 'scroll'; // add innerdiv - let inner = document.createElement("div"); - inner.style.width = "100%"; + let inner = document.createElement('div'); + inner.style.width = '100%'; outer.appendChild(inner); let widthWithScroll = inner.offsetWidth; diff --git a/frontend/app/gallery/search/autocomplete.service.ts b/frontend/app/gallery/search/autocomplete.service.ts index be9837c..271cc51 100644 --- a/frontend/app/gallery/search/autocomplete.service.ts +++ b/frontend/app/gallery/search/autocomplete.service.ts @@ -1,7 +1,7 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {AutoCompleteItem} from "../../../../common/entities/AutoCompleteItem"; -import {GalleryCacheService} from "../cache.gallery.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {AutoCompleteItem} from '../../../../common/entities/AutoCompleteItem'; +import {GalleryCacheService} from '../cache.gallery.service'; @Injectable() export class AutoCompleteService { @@ -14,7 +14,7 @@ export class AutoCompleteService { public async autoComplete(text: string): Promise> { let items: Array = this.galleryCacheService.getAutoComplete(text); if (items == null) { - items = await this._networkService.getJson>("/autocomplete/" + text); + items = await this._networkService.getJson>('/autocomplete/' + text); this.galleryCacheService.setAutoComplete(text, items); } return items; diff --git a/frontend/app/gallery/search/search.gallery.component.ts b/frontend/app/gallery/search/search.gallery.component.ts index dfd926e..2ea8f9d 100644 --- a/frontend/app/gallery/search/search.gallery.component.ts +++ b/frontend/app/gallery/search/search.gallery.component.ts @@ -1,9 +1,9 @@ -import {Component} from "@angular/core"; -import {AutoCompleteService} from "./autocomplete.service"; -import {AutoCompleteItem, SearchTypes} from "../../../../common/entities/AutoCompleteItem"; -import {ActivatedRoute, Params, RouterLink} from "@angular/router"; -import {GalleryService} from "../gallery.service"; -import {Config} from "../../../../common/config/public/Config"; +import {Component} from '@angular/core'; +import {AutoCompleteService} from './autocomplete.service'; +import {AutoCompleteItem, SearchTypes} from '../../../../common/entities/AutoCompleteItem'; +import {ActivatedRoute, Params, RouterLink} from '@angular/router'; +import {GalleryService} from '../gallery.service'; +import {Config} from '../../../../common/config/public/Config'; @Component({ selector: 'gallery-search', @@ -14,10 +14,10 @@ import {Config} from "../../../../common/config/public/Config"; export class GallerySearchComponent { autoCompleteItems: Array = []; - public searchText: string = ""; + public searchText: string = ''; private cache = { - lastAutocomplete: "", - lastInstantSearch: "" + lastAutocomplete: '', + lastInstantSearch: '' }; SearchTypes: any = []; @@ -32,7 +32,7 @@ export class GallerySearchComponent { this.subscription = this._route.params.subscribe((params: Params) => { let searchText = params['searchText']; - if (searchText && searchText != "") { + if (searchText && searchText != '') { this.searchText = searchText; } }); @@ -41,7 +41,7 @@ export class GallerySearchComponent { ngOnDestroy() { if (this.subscription !== null) { - this.subscription.unsubscribe() + this.subscription.unsubscribe(); } } @@ -94,9 +94,9 @@ export class GallerySearchComponent { private async autocomplete(searchText: string) { if (!Config.Client.Search.autocompleteEnabled) { - return + return; } - if (searchText.trim() == ".") { + if (searchText.trim() == '.') { return; } @@ -129,9 +129,9 @@ export class GallerySearchComponent { } class AutoCompleteRenderItem { - public preText: string = ""; - public highLightText: string = ""; - public postText: string = ""; + public preText: string = ''; + public highLightText: string = ''; + public postText: string = ''; public type: SearchTypes; constructor(public text: string, searchText: string, type: SearchTypes) { diff --git a/frontend/app/gallery/share.service.ts b/frontend/app/gallery/share.service.ts index daf1f92..8e30f56 100644 --- a/frontend/app/gallery/share.service.ts +++ b/frontend/app/gallery/share.service.ts @@ -1,8 +1,8 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../model/network/network.service"; -import {CreateSharingDTO, SharingDTO} from "../../../common/entities/SharingDTO"; -import {Router, RoutesRecognized} from "@angular/router"; -import {BehaviorSubject} from "rxjs/BehaviorSubject"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../model/network/network.service'; +import {CreateSharingDTO, SharingDTO} from '../../../common/entities/SharingDTO'; +import {Router, RoutesRecognized} from '@angular/router'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; @Injectable() export class ShareService { @@ -27,8 +27,8 @@ export class ShareService { this.router.events.subscribe(val => { if (val instanceof RoutesRecognized) { - this.param = val.state.root.firstChild.params["sharingKey"] || null; - this.queryParam = val.state.root.firstChild.queryParams["sk"] || null; + this.param = val.state.root.firstChild.params['sharingKey'] || null; + this.queryParam = val.state.root.firstChild.queryParams['sk'] || null; const changed = this.sharingKey != this.param || this.queryParam; if (changed) { this.sharingKey = this.param || this.queryParam; @@ -50,7 +50,7 @@ export class ShareService { } public createSharing(dir: string, includeSubfolders: boolean, valid: number): Promise { - return this._networkService.postJson("/share/" + dir, { + return this._networkService.postJson('/share/' + dir, { createSharing: { includeSubfolders: includeSubfolders, valid: valid @@ -59,7 +59,7 @@ export class ShareService { } public updateSharing(dir: string, sharingId: number, includeSubfolders: boolean, password: string, valid: number): Promise { - return this._networkService.putJson("/share/" + dir, { + return this._networkService.putJson('/share/' + dir, { updateSharing: { id: sharingId, includeSubfolders: includeSubfolders, @@ -79,7 +79,7 @@ export class ShareService { } public async getSharing(): Promise { - const sharing = await this._networkService.getJson("/share/" + this.getSharingKey()); + const sharing = await this._networkService.getJson('/share/' + this.getSharingKey()); this.sharing.next(sharing); return sharing; } diff --git a/frontend/app/gallery/share/share.gallery.component.ts b/frontend/app/gallery/share/share.gallery.component.ts index cbf01e4..1ae0286 100644 --- a/frontend/app/gallery/share/share.gallery.component.ts +++ b/frontend/app/gallery/share/share.gallery.component.ts @@ -1,14 +1,14 @@ -import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core"; -import {Utils} from "../../../../common/Utils"; -import {ShareService} from "../share.service"; -import {GalleryService} from "../gallery.service"; -import {ContentWrapper} from "../../../../common/entities/ConentWrapper"; -import {SharingDTO} from "../../../../common/entities/SharingDTO"; -import {ModalDirective} from "ngx-bootstrap/modal"; -import {Config} from "../../../../common/config/public/Config"; -import {NotificationService} from "../../model/notification.service"; -import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {Utils} from '../../../../common/Utils'; +import {ShareService} from '../share.service'; +import {GalleryService} from '../gallery.service'; +import {ContentWrapper} from '../../../../common/entities/ConentWrapper'; +import {SharingDTO} from '../../../../common/entities/SharingDTO'; +import {ModalDirective} from 'ngx-bootstrap/modal'; +import {Config} from '../../../../common/config/public/Config'; +import {NotificationService} from '../../model/notification.service'; +import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ @@ -20,7 +20,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy { @ViewChild('shareModal') public childModal: ModalDirective; enabled: boolean = true; - url: string = ""; + url: string = ''; input = { includeSubfolders: true, @@ -28,9 +28,9 @@ export class GalleryShareComponent implements OnInit, OnDestroy { amount: 30, type: ValidityTypes.Days }, - password: "" + password: '' }; - currentDir: string = ""; + currentDir: string = ''; sharing: SharingDTO = null; contentSubscription = null; passwordProtection = false; @@ -72,33 +72,33 @@ export class GalleryShareComponent implements OnInit, OnDestroy { case ValidityTypes.Months: return this.input.valid.amount * 1000 * 60 * 60 * 24 * 30; } - throw new Error("unknown type: " + this.input.valid.type); + throw new Error('unknown type: ' + this.input.valid.type); } async update() { if (this.sharing == null) { return; } - this.url = "loading.."; + this.url = 'loading..'; this.sharing = await this._sharingService.updateSharing(this.currentDir, this.sharing.id, this.input.includeSubfolders, this.input.password, this.calcValidity()); - this.url = Config.Client.publicUrl + "/share/" + this.sharing.sharingKey + this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey; } async get() { - this.url = "loading.."; + this.url = 'loading..'; this.sharing = await this._sharingService.createSharing(this.currentDir, this.input.includeSubfolders, this.calcValidity()); - this.url = Config.Client.publicUrl + "/share/" + this.sharing.sharingKey + this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey; } async showModal() { await this.get(); - this.input.password = ""; + this.input.password = ''; this.childModal.show(); - document.body.style.paddingRight = "0px"; + document.body.style.paddingRight = '0px'; } onCopy() { - this._notification.success(this.i18n("Url has been copied to clipboard")); + this._notification.success(this.i18n('Url has been copied to clipboard')); } public hideModal() { diff --git a/frontend/app/gallery/thumnailLoader.service.ts b/frontend/app/gallery/thumnailLoader.service.ts index 3cb4098..fe7f033 100644 --- a/frontend/app/gallery/thumnailLoader.service.ts +++ b/frontend/app/gallery/thumnailLoader.service.ts @@ -1,9 +1,9 @@ -import {Injectable} from "@angular/core"; -import {GalleryCacheService} from "./cache.gallery.service"; -import {Photo} from "./Photo"; -import {IconPhoto} from "./IconPhoto"; -import {PhotoDTO} from "../../../common/entities/PhotoDTO"; -import {Config} from "../../../common/config/public/Config"; +import {Injectable} from '@angular/core'; +import {GalleryCacheService} from './cache.gallery.service'; +import {Photo} from './Photo'; +import {IconPhoto} from './IconPhoto'; +import {PhotoDTO} from '../../../common/entities/PhotoDTO'; +import {Config} from '../../../common/config/public/Config'; export enum ThumbnailLoadingPriority { extraHigh = 4, high = 3, medium = 2, low = 1 @@ -23,7 +23,7 @@ export class ThumbnailLoaderService { let index = taskEntry.parentTask.taskEntities.indexOf(taskEntry); if (index == -1) { - throw new Error("ThumbnailTaskEntity not exist on Task"); + throw new Error('ThumbnailTaskEntity not exist on Task'); } taskEntry.parentTask.taskEntities.splice(index, 1); @@ -31,7 +31,7 @@ export class ThumbnailLoaderService { && taskEntry.parentTask.inProgress == false) { let i = this.que.indexOf(taskEntry.parentTask); if (i == -1) { - throw new Error("ThumbnailTask not exist"); + throw new Error('ThumbnailTask not exist'); } this.que.splice(i, 1); } @@ -136,7 +136,7 @@ export class ThumbnailLoaderService { let i = this.que.indexOf(task); if (i == -1) { if (task.taskEntities.length !== 0) { - console.error("ThumbnailLoader: can't find poolTask to remove"); + console.error('ThumbnailLoader: can\'t find poolTask to remove'); } return; } diff --git a/frontend/app/gallery/thumnailManager.service.ts b/frontend/app/gallery/thumnailManager.service.ts index b7f6cbc..4228b0f 100644 --- a/frontend/app/gallery/thumnailManager.service.ts +++ b/frontend/app/gallery/thumnailManager.service.ts @@ -1,12 +1,7 @@ -import {Injectable} from "@angular/core"; -import { - ThumbnailLoaderService, - ThumbnailLoadingListener, - ThumbnailLoadingPriority, - ThumbnailTaskEntity -} from "./thumnailLoader.service"; -import {Photo} from "./Photo"; -import {IconPhoto} from "./IconPhoto"; +import {Injectable} from '@angular/core'; +import {ThumbnailLoaderService, ThumbnailLoadingListener, ThumbnailLoadingPriority, ThumbnailTaskEntity} from './thumnailLoader.service'; +import {Photo} from './Photo'; +import {IconPhoto} from './IconPhoto'; @Injectable() @@ -80,7 +75,7 @@ export class IconThumbnail extends ThumbnailBase { constructor(private photo: IconPhoto, thumbnailService: ThumbnailLoaderService) { super(thumbnailService); - this.src = ""; + this.src = ''; this.error = false; if (this.photo.isIconAvailable()) { this.src = this.photo.getIconPath(); @@ -166,28 +161,28 @@ export class Thumbnail extends ThumbnailBase { public load() { if (!this.photo.isThumbnailAvailable() && this.thumbnailTask == null) { // setTimeout(() => { - let listener: ThumbnailLoadingListener = { - onStartedLoading: () => { //onLoadStarted - this.loading = true; - }, - onLoad: () => {//onLoaded - this.src = this.photo.getThumbnailPath(); - if (this.onLoad) this.onLoad(); - this.available = true; - this.loading = false; - this.thumbnailTask = null; - }, - onError: (error) => {//onError - this.thumbnailTask = null; - this.loading = false; - this.error = true; - } - }; - if (this.photo.isReplacementThumbnailAvailable()) { - this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.medium, listener); - } else { - this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.high, listener); + let listener: ThumbnailLoadingListener = { + onStartedLoading: () => { //onLoadStarted + this.loading = true; + }, + onLoad: () => {//onLoaded + this.src = this.photo.getThumbnailPath(); + if (this.onLoad) this.onLoad(); + this.available = true; + this.loading = false; + this.thumbnailTask = null; + }, + onError: (error) => {//onError + this.thumbnailTask = null; + this.loading = false; + this.error = true; } + }; + if (this.photo.isReplacementThumbnailAvailable()) { + this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.medium, listener); + } else { + this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.high, listener); + } // }, 0); } } diff --git a/frontend/app/language/language.component.ts b/frontend/app/language/language.component.ts index e0c977a..1eed392 100644 --- a/frontend/app/language/language.component.ts +++ b/frontend/app/language/language.component.ts @@ -1,7 +1,7 @@ -import {Component, Input} from "@angular/core"; -import {Config} from "../../../common/config/public/Config"; -import {Cookie} from "ng2-cookies"; -import {CookieNames} from "../../../common/CookieNames"; +import {Component, Input} from '@angular/core'; +import {Config} from '../../../common/config/public/Config'; +import {Cookie} from 'ng2-cookies'; +import {CookieNames} from '../../../common/CookieNames'; @Component({ selector: 'language', diff --git a/frontend/app/login/login.component.ts b/frontend/app/login/login.component.ts index 08e1733..c2fd61e 100644 --- a/frontend/app/login/login.component.ts +++ b/frontend/app/login/login.component.ts @@ -1,9 +1,9 @@ -import {Component, OnInit} from "@angular/core"; -import {LoginCredential} from "../../../common/entities/LoginCredential"; -import {AuthenticationService} from "../model/network/authentication.service"; -import {ErrorCodes} from "../../../common/entities/Error"; -import {Config} from "../../../common/config/public/Config"; -import {NavigationService} from "../model/navigation.service"; +import {Component, OnInit} from '@angular/core'; +import {LoginCredential} from '../../../common/entities/LoginCredential'; +import {AuthenticationService} from '../model/network/authentication.service'; +import {ErrorCodes} from '../../../common/entities/Error'; +import {Config} from '../../../common/config/public/Config'; +import {NavigationService} from '../model/navigation.service'; @Component({ selector: 'login', diff --git a/frontend/app/model/IRenderable.ts b/frontend/app/model/IRenderable.ts index c95e07b..a012187 100644 --- a/frontend/app/model/IRenderable.ts +++ b/frontend/app/model/IRenderable.ts @@ -11,6 +11,6 @@ export interface Dimension { export module Dimension { export const toString = (dim: Dimension) => { - return {top: dim.top + "px", left: dim.left + "px", width: dim.width + "px", height: dim.height + "px"}; - } + return {top: dim.top + 'px', left: dim.left + 'px', width: dim.width + 'px', height: dim.height + 'px'}; + }; } diff --git a/frontend/app/model/navigation.service.ts b/frontend/app/model/navigation.service.ts index 56ed2d7..f72dcac 100644 --- a/frontend/app/model/navigation.service.ts +++ b/frontend/app/model/navigation.service.ts @@ -1,7 +1,7 @@ -import {Injectable} from "@angular/core"; +import {Injectable} from '@angular/core'; -import {Router} from "@angular/router"; -import {ShareService} from "../gallery/share.service"; +import {Router} from '@angular/router'; +import {ShareService} from '../gallery/share.service'; @Injectable() export class NavigationService { @@ -17,22 +17,22 @@ export class NavigationService { } public async toLogin() { - console.log("toLogin"); + console.log('toLogin'); await this._shareService.wait(); if (this._shareService.isSharing()) { - return this._router.navigate(["shareLogin"], {queryParams: {sk: this._shareService.getSharingKey()}}); + return this._router.navigate(['shareLogin'], {queryParams: {sk: this._shareService.getSharingKey()}}); } else { - return this._router.navigate(["login"]); + return this._router.navigate(['login']); } } public async toGallery() { - console.log("toGallery"); + console.log('toGallery'); await this._shareService.wait(); if (this._shareService.isSharing()) { - return this._router.navigate(["gallery", ""], {queryParams: {sk: this._shareService.getSharingKey()}}); + return this._router.navigate(['gallery', ''], {queryParams: {sk: this._shareService.getSharingKey()}}); } else { - return this._router.navigate(["gallery", ""]); + return this._router.navigate(['gallery', '']); } } } diff --git a/frontend/app/model/network/autehentication.service.spec.ts b/frontend/app/model/network/autehentication.service.spec.ts index 588b66f..e0ad245 100644 --- a/frontend/app/model/network/autehentication.service.spec.ts +++ b/frontend/app/model/network/autehentication.service.spec.ts @@ -1,15 +1,15 @@ -import {inject, TestBed} from "@angular/core/testing"; -import {UserService} from "./user.service"; -import {UserDTO} from "../../../../common/entities/UserDTO"; -import "rxjs/Rx"; -import {LoginCredential} from "../../../../common/entities/LoginCredential"; -import {AuthenticationService} from "./authentication.service"; -import {NetworkService} from "./network.service"; -import {ErrorDTO} from "../../../../common/entities/Error"; +import {inject, TestBed} from '@angular/core/testing'; +import {UserService} from './user.service'; +import {UserDTO} from '../../../../common/entities/UserDTO'; +import 'rxjs/Rx'; +import {LoginCredential} from '../../../../common/entities/LoginCredential'; +import {AuthenticationService} from './authentication.service'; +import {NetworkService} from './network.service'; +import {ErrorDTO} from '../../../../common/entities/Error'; class MockUserService { public login(credential: LoginCredential): Promise { - return Promise.resolve({name: "testUserName"}) + return Promise.resolve({name: 'testUserName'}); } public async getSessionUser() { @@ -35,7 +35,7 @@ describe('AuthenticationService', () => { it('should call UserDTO service login', inject([AuthenticationService, UserService], (authService, userService) => { - spyOn(userService, "login").and.callThrough(); + spyOn(userService, 'login').and.callThrough(); expect(userService.login).not.toHaveBeenCalled(); authService.login(); @@ -49,7 +49,7 @@ describe('AuthenticationService', () => { it('should have Authenticated use', inject([AuthenticationService], (authService: AuthenticationService) => { - spyOn(authService.user, "next").and.callThrough(); + spyOn(authService.user, 'next').and.callThrough(); authService.user.subscribe((user) => { if (user == null) { return; diff --git a/frontend/app/model/network/authentication.service.ts b/frontend/app/model/network/authentication.service.ts index 5dda5ea..0a94882 100644 --- a/frontend/app/model/network/authentication.service.ts +++ b/frontend/app/model/network/authentication.service.ts @@ -1,13 +1,13 @@ -import {Injectable} from "@angular/core"; -import {UserDTO, UserRoles} from "../../../../common/entities/UserDTO"; -import {BehaviorSubject} from "rxjs/BehaviorSubject"; -import {UserService} from "./user.service"; -import {LoginCredential} from "../../../../common/entities/LoginCredential"; -import {Cookie} from "ng2-cookies"; -import {Config} from "../../../../common/config/public/Config"; -import {NetworkService} from "./network.service"; -import {ErrorCodes, ErrorDTO} from "../../../../common/entities/Error"; -import {CookieNames} from "../../../../common/CookieNames"; +import {Injectable} from '@angular/core'; +import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {UserService} from './user.service'; +import {LoginCredential} from '../../../../common/entities/LoginCredential'; +import {Cookie} from 'ng2-cookies'; +import {Config} from '../../../../common/config/public/Config'; +import {NetworkService} from './network.service'; +import {ErrorCodes, ErrorDTO} from '../../../../common/entities/Error'; +import {CookieNames} from '../../../../common/CookieNames'; declare module ServerInject { export let user: UserDTO; @@ -24,13 +24,13 @@ export class AuthenticationService { //picking up session.. if (this.isAuthenticated() == false && Cookie.get(CookieNames.session) != null) { - if (typeof ServerInject !== "undefined" && typeof ServerInject.user !== "undefined") { + if (typeof ServerInject !== 'undefined' && typeof ServerInject.user !== 'undefined') { this.user.next(ServerInject.user); } this.getSessionUser(); } else { if (Config.Client.authenticationRequired === false) { - this.user.next({name: "", role: UserRoles.Admin}); + this.user.next({name: '', role: UserRoles.Admin}); } } diff --git a/frontend/app/model/network/network.service.spec.ts b/frontend/app/model/network/network.service.spec.ts index 38ee3c2..b3fda95 100644 --- a/frontend/app/model/network/network.service.spec.ts +++ b/frontend/app/model/network/network.service.spec.ts @@ -1,179 +1,207 @@ -import {inject, TestBed} from "@angular/core/testing"; -import {BaseRequestOptions, Http, Response, ResponseOptions} from "@angular/http"; -import {MockBackend, MockConnection} from "@angular/http/testing"; -import "rxjs/Rx"; -import {NetworkService} from "./network.service"; -import {Message} from "../../../../common/entities/Message"; -import {SlimLoadingBarService} from "ng2-slim-loading-bar"; +import {getTestBed, inject, TestBed} from '@angular/core/testing'; +import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; +import 'rxjs/Rx'; +import {NetworkService} from './network.service'; +import {Message} from '../../../../common/entities/Message'; +import {SlimLoadingBarService} from 'ng2-slim-loading-bar'; describe('NetworkService Success tests', () => { - let connection: MockConnection = null; - - let testUrl = "/test/url"; - let testData = {data: "testData"}; - let testResponse = "testResponse"; - let testResponseMessage = new Message(null, testResponse); + const testUrl = '/test/url'; + const testData = {data: 'testData'}; + const testResponse = 'testResponse'; + const testResponseMessage = new Message(null, testResponse); + let injector; + let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], providers: [ - MockBackend, - BaseRequestOptions, SlimLoadingBarService, - { - provide: Http, useFactory: (backend, options) => { - return new Http(backend, options); - }, deps: [MockBackend, BaseRequestOptions] - }, NetworkService ] }); + injector = getTestBed(); + httpMock = injector.get(HttpTestingController); }); - - beforeEach(inject([MockBackend], (backend) => { - - backend.connections.subscribe((c) => { - connection = c; - connection.mockRespond(new Response( - new ResponseOptions( - { - body: testResponseMessage - } - ))); - }); - })); - afterEach(() => { - - expect(connection.request.url).toBe("/api" + testUrl); + httpMock.verify(); }); it('should call GET', inject([NetworkService], (networkService) => { - networkService.getJson(testUrl).then((res: any) => { + networkService.getJson(testUrl).then((res: string) => { expect(res).toBe(testResponse); + }).catch((err) => { + console.error(err); + expect(err).toBeUndefined(); }); + const mockReq = httpMock.expectOne({method: 'GET'}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + mockReq.flush(testResponseMessage); + })); + + it('should call POST', inject([NetworkService], (networkService) => { + + networkService.postJson(testUrl, testData).then((res: string) => { + expect(res).toBe(testResponse); + }).catch((err) => { + console.error(err); + expect(err).toBeUndefined(); + }); + + let mockReq = httpMock.expectOne('/api' + testUrl); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + mockReq.flush(testResponseMessage); + expect(mockReq.request.body).toBe(testData); + + networkService.postJson(testUrl).then((res: string) => { + expect(res).toBe(testResponse); + }).catch((err) => { + console.error(err); + expect(err).toBeUndefined(); + }); + + mockReq = httpMock.expectOne('/api' + testUrl); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + expect(mockReq.request.body).toEqual({}); + mockReq.flush(testResponseMessage); + + })); - it('should call POST', inject([NetworkService, MockBackend], (networkService) => { - networkService.postJson(testUrl, testData).then((res: any) => { + it('should call DELETE', inject([NetworkService], (networkService) => { + + networkService.deleteJson(testUrl).then((res: any) => { expect(res).toBe(testResponse); }); - expect(connection.request.text()).toBe(JSON.stringify(testData)); - - networkService.postJson(testUrl).then((res: any) => { - expect(res).toBe(testResponse); - }); - expect(connection.request.text()).toBe(JSON.stringify({})); + const mockReq = httpMock.expectOne({method: 'DELETE'}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + mockReq.flush(testResponseMessage); })); - it('should call PUT', inject([NetworkService, MockBackend], (networkService) => { + it('should call PUT', inject([NetworkService], (networkService) => { networkService.putJson(testUrl, testData).then((res: any) => { expect(res).toBe(testResponse); }); - expect(connection.request.text()).toBe(JSON.stringify(testData)); + + let mockReq = httpMock.expectOne({}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + expect(mockReq.request.body).toEqual(testData); + mockReq.flush(testResponseMessage); networkService.putJson(testUrl).then((res: any) => { expect(res).toBe(testResponse); }); - expect(connection.request.text()).toBe(JSON.stringify({})); + + mockReq = httpMock.expectOne({}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + expect(mockReq.request.body).toEqual({}); + mockReq.flush(testResponseMessage); })); - it('should call DELETE', inject([NetworkService, MockBackend], (networkService) => { - - networkService.deleteJson(testUrl).then((res: any) => { - expect(res).toBe(testResponse); - }); - })); }); describe('NetworkService Fail tests', () => { - let connection: MockConnection = null; - let testUrl = "/test/url"; - let testData = {data: "testData"}; - let testError = "testError"; + const testUrl = '/test/url'; + const testData = {data: 'testData'}; + const testError = 'testError'; + let injector; + let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], providers: [ - MockBackend, - BaseRequestOptions, SlimLoadingBarService, - - { - provide: Http, useFactory: (backend, options) => { - return new Http(backend, options); - }, deps: [MockBackend, BaseRequestOptions] - }, NetworkService ] }); + injector = getTestBed(); + httpMock = injector.get(HttpTestingController); }); - beforeEach(inject([MockBackend], (backend) => { - - backend.connections.subscribe((c) => { - connection = c; - connection.mockError({name: "errorName", message: testError}); - - }); - })); - afterEach(() => { - - expect(connection.request.url).toBe("/api" + testUrl); + httpMock.verify(); }); + it('should call GET with error', inject([NetworkService], (networkService) => { networkService.getJson(testUrl).then((res: any) => { expect(res).toBe(null); }).catch((err) => { - expect(err).toBe(testError); + expect(err).toBe('Http failure response for /api/test/url: 0 ' + testError); }); + + const mockReq = httpMock.expectOne({method: 'GET'}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + mockReq.error(null, {statusText: testError}); })); - it('should call POST with error', inject([NetworkService, MockBackend], (networkService) => { + it('should call POST with error', inject([NetworkService], (networkService) => { networkService.postJson(testUrl, testData).then((res: any) => { expect(res).toBe(null); }).catch((err) => { - expect(err).toBe(testError); + expect(err).toBe('Http failure response for /api/test/url: 0 ' + testError); }); - expect(connection.request.text()).toBe(JSON.stringify(testData)); + + const mockReq = httpMock.expectOne({method: 'POST'}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + expect(mockReq.request.body).toEqual(testData); + mockReq.error(null, {statusText: testError}); })); - it('should call PUT with error', inject([NetworkService, MockBackend], (networkService) => { + it('should call PUT with error', inject([NetworkService], (networkService) => { networkService.putJson(testUrl, testData).then((res: any) => { expect(res).toBe(null); }).catch((err) => { - expect(err).toBe(testError); + expect(err).toBe('Http failure response for /api/test/url: 0 ' + testError); }); - expect(connection.request.text()).toBe(JSON.stringify(testData)); + + const mockReq = httpMock.expectOne({method: 'PUT'}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + expect(mockReq.request.body).toEqual(testData); + mockReq.error(null, {statusText: testError}); })); - it('should call DELETE with error', inject([NetworkService, MockBackend], (networkService) => { + it('should call DELETE with error', inject([NetworkService], (networkService) => { networkService.deleteJson(testUrl).then((res: any) => { expect(res).toBe(null); }).catch((err) => { - expect(err).toBe(testError); + expect(err).toBe('Http failure response for /api/test/url: 0 ' + testError); }); + + const mockReq = httpMock.expectOne({method: 'DELETE'}); + expect(mockReq.cancelled).toBeFalsy(); + expect(mockReq.request.responseType).toEqual('json'); + mockReq.error(null, {statusText: testError}); })); }); diff --git a/frontend/app/model/network/network.service.ts b/frontend/app/model/network/network.service.ts index 178d661..04588e4 100644 --- a/frontend/app/model/network/network.service.ts +++ b/frontend/app/model/network/network.service.ts @@ -1,34 +1,58 @@ -import {Injectable} from "@angular/core"; -import {Headers, Http, RequestOptions} from "@angular/http"; -import {Message} from "../../../../common/entities/Message"; -import {SlimLoadingBarService} from "ng2-slim-loading-bar"; -import "rxjs/Rx"; -import {ErrorCodes, ErrorDTO} from "../../../../common/entities/Error"; +import {Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Message} from '../../../../common/entities/Message'; +import {SlimLoadingBarService} from 'ng2-slim-loading-bar'; +import 'rxjs/Rx'; +import {ErrorCodes, ErrorDTO} from '../../../../common/entities/Error'; @Injectable() export class NetworkService { - _baseUrl = "/api"; + _baseUrl = '/api'; private globalErrorHandlers: Array<(error: ErrorDTO) => boolean> = []; - constructor(protected _http: Http, + constructor(private _http: HttpClient, private slimLoadingBarService: SlimLoadingBarService) { } + public postJson(url: string, data: any = {}): Promise { + return this.callJson('post', url, data); + } - private callJson(method: string, url: string, data: any = {}): Promise { - let body = JSON.stringify(data); - let headers = new Headers({'Content-Type': 'application/json'}); - let options = new RequestOptions({headers: headers}); + public putJson(url: string, data: any = {}): Promise { + return this.callJson('put', url, data); + } + + public getJson(url: string, data?: { [key: string]: any }): Promise { + if (data) { + const keys = Object.getOwnPropertyNames(data); + if (keys.length > 0) { + url += '?'; + for (let i = 0; i < keys.length; i++) { + url += keys[i] + '=' + data[keys[i]]; + if (i < keys.length - 1) { + url += '&'; + } + } + } + } + return this.callJson('get', url); + } + + public deleteJson(url: string): Promise { + return this.callJson('delete', url); + } + + private callJson(method: 'get' | 'post' | 'delete' | 'put', url: string, data: any = {}): Promise { + const body = data; this.slimLoadingBarService.visible = true; this.slimLoadingBarService.start(() => { this.slimLoadingBarService.visible = false; }); - const process = (data: any): T => { + const process = (res: Message): T => { this.slimLoadingBarService.complete(); - let res = > data.json(); if (!!res.error) { if (res.error.code) { res.error['title'] = ErrorCodes[res.error.code]; @@ -38,63 +62,49 @@ export class NetworkService { return res.result; }; - const err = (err) => { + const err = (error) => { this.slimLoadingBarService.complete(); - return this.handleError(err); + return this.handleError(error); }; - if (method == "get" || method == "delete") { - return this._http[method](this._baseUrl + url, options) - .toPromise() - .then(process) - .catch(err); + switch (method) { + case 'get': + return this._http.get>(this._baseUrl + url) + .toPromise() + .then(process) + .catch(err); + case 'delete': + return this._http.delete>(this._baseUrl + url) + .toPromise() + .then(process) + .catch(err); + case 'post': + return this._http.post>(this._baseUrl + url, body) + .toPromise() + .then(process) + .catch(err); + case 'put': + return this._http.put>(this._baseUrl + url, body) + .toPromise() + .then(process) + .catch(err); + default: + throw new Error('Unknown method'); } - return this._http[method](this._baseUrl + url, body, options) - .toPromise() - .then(process) - .catch(err); - } - public postJson(url: string, data: any = {}): Promise { - return this.callJson("post", url, data); - } - - public putJson(url: string, data: any = {}): Promise { - return this.callJson("put", url, data); - } - - public getJson(url: string, data?: { [key: string]: any }): Promise { - if (data) { - const keys = Object.getOwnPropertyNames(data); - if (keys.length > 0) { - url += "?"; - for (let i = 0; i < keys.length; i++) { - url += keys[i] + "=" + data[keys[i]]; - if (i < keys.length - 1) { - url += "&"; - } - } - } - } - return this.callJson("get", url); - } - - - public deleteJson(url: string): Promise { - return this.callJson("delete", url); } private handleError(error: any) { - if (typeof error.code !== "undefined") { + if (typeof error.code !== 'undefined') { for (let i = 0; i < this.globalErrorHandlers.length; i++) { - if (this.globalErrorHandlers[i](error) == true) { + if (this.globalErrorHandlers[i](error) === true) { return; } } return Promise.reject(error); } // instead of just logging it to the console - console.error(error); + console.error('error:', error); return Promise.reject(error.message || error || 'Server error'); } diff --git a/frontend/app/model/network/user.service.spec.ts b/frontend/app/model/network/user.service.spec.ts index fe8214a..86abf4f 100644 --- a/frontend/app/model/network/user.service.spec.ts +++ b/frontend/app/model/network/user.service.spec.ts @@ -1,10 +1,10 @@ -import {inject, TestBed} from "@angular/core/testing"; -import {BaseRequestOptions, Http} from "@angular/http"; -import {MockBackend} from "@angular/http/testing"; -import "rxjs/Rx"; -import {NetworkService} from "./network.service"; -import {UserService} from "./user.service"; -import {LoginCredential} from "../../../../common/entities/LoginCredential"; +import {inject, TestBed} from '@angular/core/testing'; +import {BaseRequestOptions, Http} from '@angular/http'; +import {MockBackend} from '@angular/http/testing'; +import 'rxjs/Rx'; +import {NetworkService} from './network.service'; +import {UserService} from './user.service'; +import {LoginCredential} from '../../../../common/entities/LoginCredential'; describe('UserService', () => { @@ -16,8 +16,8 @@ describe('UserService', () => { BaseRequestOptions, { provide: Http, useFactory: (backend, options) => { - return new Http(backend, options); - }, deps: [MockBackend, BaseRequestOptions] + return new Http(backend, options); + }, deps: [MockBackend, BaseRequestOptions] }, NetworkService, UserService] @@ -25,18 +25,18 @@ describe('UserService', () => { it('should call postJson at login', inject([UserService, NetworkService], (userService, networkService) => { - spyOn(networkService, "postJson"); - let credential = new LoginCredential("name", "pass"); + spyOn(networkService, 'postJson'); + let credential = new LoginCredential('name', 'pass'); userService.login(credential); expect(networkService.postJson).toHaveBeenCalled(); - expect(networkService.postJson.calls.argsFor(0)).toEqual(["/user/login", {"loginCredential": credential}]); + expect(networkService.postJson.calls.argsFor(0)).toEqual(['/user/login', {'loginCredential': credential}]); })); it('should call getJson at getSessionUser', inject([UserService, NetworkService], (userService, networkService) => { - spyOn(networkService, "getJson"); + spyOn(networkService, 'getJson'); userService.getSessionUser(); expect(networkService.getJson).toHaveBeenCalled(); - expect(networkService.getJson.calls.argsFor(0)).toEqual(["/user/login"]); + expect(networkService.getJson.calls.argsFor(0)).toEqual(['/user/login']); })); diff --git a/frontend/app/model/network/user.service.ts b/frontend/app/model/network/user.service.ts index 4b5d842..ed0a5db 100644 --- a/frontend/app/model/network/user.service.ts +++ b/frontend/app/model/network/user.service.ts @@ -1,9 +1,9 @@ -import {Injectable} from "@angular/core"; -import {LoginCredential} from "../../../../common/entities/LoginCredential"; -import {NetworkService} from "./network.service"; -import {UserDTO} from "../../../../common/entities/UserDTO"; -import {Config} from "../../../../common/config/public/Config"; -import {ShareService} from "../../gallery/share.service"; +import {Injectable} from '@angular/core'; +import {LoginCredential} from '../../../../common/entities/LoginCredential'; +import {NetworkService} from './network.service'; +import {UserDTO} from '../../../../common/entities/UserDTO'; +import {Config} from '../../../../common/config/public/Config'; +import {ShareService} from '../../gallery/share.service'; @Injectable() export class UserService { @@ -14,25 +14,25 @@ export class UserService { } public logout(): Promise { - return this._networkService.postJson("/user/logout"); + return this._networkService.postJson('/user/logout'); } public login(credential: LoginCredential): Promise { - return this._networkService.postJson("/user/login", {"loginCredential": credential}); + return this._networkService.postJson('/user/login', {'loginCredential': credential}); } public async shareLogin(password: string): Promise { - return this._networkService.postJson("/share/login?sk=" + this._shareService.getSharingKey(), {"password": password}); + return this._networkService.postJson('/share/login?sk=' + this._shareService.getSharingKey(), {'password': password}); } public async getSessionUser(): Promise { await this._shareService.wait(); if (Config.Client.Sharing.enabled == true) { if (this._shareService.isSharing()) { - return this._networkService.getJson("/user/login?sk=" + this._shareService.getSharingKey()); + return this._networkService.getJson('/user/login?sk=' + this._shareService.getSharingKey()); } } - return this._networkService.getJson("/user/login"); + return this._networkService.getJson('/user/login'); } } diff --git a/frontend/app/model/notification.service.ts b/frontend/app/model/notification.service.ts index 93957fa..93b3f71 100644 --- a/frontend/app/model/notification.service.ts +++ b/frontend/app/model/notification.service.ts @@ -1,17 +1,17 @@ -import {Injectable, ViewContainerRef} from "@angular/core"; -import {ToastsManager} from "ng2-toastr/ng2-toastr"; -import {NetworkService} from "./network/network.service"; -import {AuthenticationService} from "./network/authentication.service"; -import {NotificationDTO, NotificationType} from "../../../common/entities/NotificationDTO"; -import {UserDTO, UserRoles} from "../../../common/entities/UserDTO"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Injectable, ViewContainerRef} from '@angular/core'; +import {ToastsManager} from 'ng2-toastr/ng2-toastr'; +import {NetworkService} from './network/network.service'; +import {AuthenticationService} from './network/authentication.service'; +import {NotificationDTO, NotificationType} from '../../../common/entities/NotificationDTO'; +import {UserDTO, UserRoles} from '../../../common/entities/UserDTO'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Injectable() export class NotificationService { options = { - positionClass: "toast-top-center", - animate: "flyLeft" + positionClass: 'toast-top-center', + animate: 'flyLeft' }; notifications: NotificationDTO[] = []; lastUser: UserDTO = null; @@ -33,24 +33,24 @@ export class NotificationService { } async getServerNotifications() { - this.notifications = await this._networkService.getJson("/notifications"); + this.notifications = await this._networkService.getJson('/notifications'); this.notifications.forEach((noti) => { let msg = noti.message; if (noti.details) { - msg += " Details: " + JSON.stringify(noti.details); + msg += ' Details: ' + JSON.stringify(noti.details); } switch (noti.type) { case NotificationType.error: - this.error(msg, this.i18n("Server error")); + this.error(msg, this.i18n('Server error')); break; case NotificationType.warning: - this.warning(msg, this.i18n("Server error")); + this.warning(msg, this.i18n('Server error')); break; case NotificationType.info: - this.info(msg, this.i18n("Server info")); + this.info(msg, this.i18n('Server info')); break; } - }) + }); } setRootViewContainerRef(vcr: ViewContainerRef) { diff --git a/frontend/app/pipes/StringifyRolePipe.ts b/frontend/app/pipes/StringifyRolePipe.ts index bb27616..e36de05 100644 --- a/frontend/app/pipes/StringifyRolePipe.ts +++ b/frontend/app/pipes/StringifyRolePipe.ts @@ -1,5 +1,5 @@ -import {Pipe, PipeTransform} from "@angular/core"; -import {UserRoles} from "../../../common/entities/UserDTO"; +import {Pipe, PipeTransform} from '@angular/core'; +import {UserRoles} from '../../../common/entities/UserDTO'; @Pipe({name: 'stringifyRole'}) diff --git a/frontend/app/settings/_abstract/abstract.settings.component.ts b/frontend/app/settings/_abstract/abstract.settings.component.ts index b8d9749..e02bf7c 100644 --- a/frontend/app/settings/_abstract/abstract.settings.component.ts +++ b/frontend/app/settings/_abstract/abstract.settings.component.ts @@ -1,13 +1,13 @@ -import {Input, OnChanges, OnDestroy, OnInit, Output, ViewChild} from "@angular/core"; -import {AuthenticationService} from "../../model/network/authentication.service"; -import {UserRoles} from "../../../../common/entities/UserDTO"; -import {Utils} from "../../../../common/Utils"; -import {ErrorDTO} from "../../../../common/entities/Error"; -import {NotificationService} from "../../model/notification.service"; -import {NavigationService} from "../../model/navigation.service"; -import {AbstractSettingsService} from "./abstract.settings.service"; -import {IPrivateConfig} from "../../../../common/config/private/IPrivateConfig"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Input, OnChanges, OnDestroy, OnInit, Output, ViewChild} from '@angular/core'; +import {AuthenticationService} from '../../model/network/authentication.service'; +import {UserRoles} from '../../../../common/entities/UserDTO'; +import {Utils} from '../../../../common/Utils'; +import {ErrorDTO} from '../../../../common/entities/Error'; +import {NotificationService} from '../../model/notification.service'; +import {NavigationService} from '../../model/navigation.service'; +import {AbstractSettingsService} from './abstract.settings.service'; +import {IPrivateConfig} from '../../../../common/config/private/IPrivateConfig'; +import {I18n} from '@ngx-translate/i18n-polyfill'; export abstract class SettingsComponent=AbstractSettingsService> @@ -32,10 +32,10 @@ export abstract class SettingsComponent= public original: T = {}; text = { - Enabled: "Enabled", - Disabled: "Disabled", - Low: "Low", - High: "High" + Enabled: 'Enabled', + Disabled: 'Disabled', + Low: 'Low', + High: 'High' }; constructor(private name, @@ -49,10 +49,10 @@ export abstract class SettingsComponent= this._settingsSubscription = this._settingsService.Settings.subscribe(this.onNewSettings); this.onNewSettings(this._settingsService._settingsService.settings.value); } - this.text.Enabled = i18n("Enabled"); - this.text.Disabled = i18n("Disabled"); - this.text.Low = i18n("Low"); - this.text.High = i18n("High"); + this.text.Enabled = i18n('Enabled'); + this.text.Disabled = i18n('Disabled'); + this.text.Low = i18n('Low'); + this.text.High = i18n('High'); } onNewSettings = (s) => { @@ -101,11 +101,11 @@ export abstract class SettingsComponent= public async save() { this.inProgress = true; - this.error = ""; + this.error = ''; try { await this._settingsService.updateSettings(this.settings); await this.getSettings(); - this.notification.success(this.name + this.i18n(' settings saved'), this.i18n("Success")); + this.notification.success(this.name + this.i18n(' settings saved'), this.i18n('Success')); this.inProgress = false; return true; } catch (err) { diff --git a/frontend/app/settings/_abstract/abstract.settings.service.ts b/frontend/app/settings/_abstract/abstract.settings.service.ts index 129e568..72892e0 100644 --- a/frontend/app/settings/_abstract/abstract.settings.service.ts +++ b/frontend/app/settings/_abstract/abstract.settings.service.ts @@ -1,4 +1,5 @@ -import {SettingsService} from "../settings.service"; +import {SettingsService} from '../settings.service'; + export abstract class AbstractSettingsService { constructor(public _settingsService: SettingsService) { @@ -18,5 +19,5 @@ export abstract class AbstractSettingsService { return true; } - abstract updateSettings(settings: T): Promise; + abstract updateSettings(settings: T): Promise; } diff --git a/frontend/app/settings/basic/basic.settings.component.ts b/frontend/app/settings/basic/basic.settings.component.ts index 372b338..a81039d 100644 --- a/frontend/app/settings/basic/basic.settings.component.ts +++ b/frontend/app/settings/basic/basic.settings.component.ts @@ -1,11 +1,11 @@ -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 {BasicSettingsService} from "./basic.settings.service"; -import {BasicConfigDTO} from "../../../../common/entities/settings/BasicConfigDTO"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +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 {BasicSettingsService} from './basic.settings.service'; +import {BasicConfigDTO} from '../../../../common/entities/settings/BasicConfigDTO'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-basic', @@ -23,7 +23,7 @@ export class BasicSettingsComponent extends SettingsComponent { _settingsService: BasicSettingsService, notification: NotificationService, i18n: I18n) { - super(i18n("Basic"), _authService, _navigation, _settingsService, notification, i18n, s => ({ + super(i18n('Basic'), _authService, _navigation, _settingsService, notification, i18n, s => ({ port: s.Server.port, imagesFolder: s.Server.imagesFolder, applicationTitle: s.Client.applicationTitle, diff --git a/frontend/app/settings/basic/basic.settings.service.ts b/frontend/app/settings/basic/basic.settings.service.ts index 7b4b4c0..d925b0f 100644 --- a/frontend/app/settings/basic/basic.settings.service.ts +++ b/frontend/app/settings/basic/basic.settings.service.ts @@ -1,8 +1,8 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; -import {SettingsService} from "../settings.service"; -import {BasicConfigDTO} from "../../../../common/entities/settings/BasicConfigDTO"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; +import {SettingsService} from '../settings.service'; +import {BasicConfigDTO} from '../../../../common/entities/settings/BasicConfigDTO'; @Injectable() export class BasicSettingsService extends AbstractSettingsService { @@ -13,7 +13,7 @@ export class BasicSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/basic", {settings: settings}); + return this._networkService.putJson('/settings/basic', {settings: settings}); } } diff --git a/frontend/app/settings/database/database.settings.component.ts b/frontend/app/settings/database/database.settings.component.ts index 40f15a3..ad2c3ec 100644 --- a/frontend/app/settings/database/database.settings.component.ts +++ b/frontend/app/settings/database/database.settings.component.ts @@ -1,12 +1,12 @@ -import {Component} from "@angular/core"; -import {AuthenticationService} from "../../model/network/authentication.service"; -import {DataBaseConfig, DatabaseType} from "../../../../common/config/private/IPrivateConfig"; -import {Utils} from "../../../../common/Utils"; -import {NotificationService} from "../../model/notification.service"; -import {NavigationService} from "../../model/navigation.service"; -import {SettingsComponent} from "../_abstract/abstract.settings.component"; -import {DatabaseSettingsService} from "./database.settings.service"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component} from '@angular/core'; +import {AuthenticationService} from '../../model/network/authentication.service'; +import {DataBaseConfig, DatabaseType} from '../../../../common/config/private/IPrivateConfig'; +import {Utils} from '../../../../common/Utils'; +import {NotificationService} from '../../model/notification.service'; +import {NavigationService} from '../../model/navigation.service'; +import {SettingsComponent} from '../_abstract/abstract.settings.component'; +import {DatabaseSettingsService} from './database.settings.service'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-database', @@ -25,7 +25,7 @@ export class DatabaseSettingsComponent extends SettingsComponent _settingsService: DatabaseSettingsService, notification: NotificationService, i18n: I18n) { - super(i18n("Database"), _authService, _navigation, _settingsService, notification, i18n, s => s.Server.database); + super(i18n('Database'), _authService, _navigation, _settingsService, notification, i18n, s => s.Server.database); } ngOnInit() { diff --git a/frontend/app/settings/database/database.settings.service.ts b/frontend/app/settings/database/database.settings.service.ts index 1064240..f7e7de3 100644 --- a/frontend/app/settings/database/database.settings.service.ts +++ b/frontend/app/settings/database/database.settings.service.ts @@ -1,8 +1,8 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {DataBaseConfig} from "../../../../common/config/private/IPrivateConfig"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; -import {SettingsService} from "../settings.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {DataBaseConfig} from '../../../../common/config/private/IPrivateConfig'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; +import {SettingsService} from '../settings.service'; @Injectable() export class DatabaseSettingsService extends AbstractSettingsService { @@ -13,7 +13,7 @@ export class DatabaseSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/database", {settings: settings}); + return this._networkService.putJson('/settings/database', {settings: settings}); } } diff --git a/frontend/app/settings/indexing/indexing.settings.component.ts b/frontend/app/settings/indexing/indexing.settings.component.ts index 4b10593..ded5b0a 100644 --- a/frontend/app/settings/indexing/indexing.settings.component.ts +++ b/frontend/app/settings/indexing/indexing.settings.component.ts @@ -1,14 +1,14 @@ -import {Component} from "@angular/core"; -import {IndexingSettingsService} from "./indexing.settings.service"; -import {AuthenticationService} from "../../model/network/authentication.service"; -import {NavigationService} from "../../model/navigation.service"; -import {NotificationService} from "../../model/notification.service"; -import {ErrorDTO} from "../../../../common/entities/Error"; -import {Observable} from "rxjs/Rx"; -import {IndexingConfig, ReIndexingSensitivity} from "../../../../common/config/private/IPrivateConfig"; -import {SettingsComponent} from "../_abstract/abstract.settings.component"; -import {Utils} from "../../../../common/Utils"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component} from '@angular/core'; +import {IndexingSettingsService} from './indexing.settings.service'; +import {AuthenticationService} from '../../model/network/authentication.service'; +import {NavigationService} from '../../model/navigation.service'; +import {NotificationService} from '../../model/notification.service'; +import {ErrorDTO} from '../../../../common/entities/Error'; +import {Observable} from 'rxjs/Rx'; +import {IndexingConfig, ReIndexingSensitivity} from '../../../../common/config/private/IPrivateConfig'; +import {SettingsComponent} from '../_abstract/abstract.settings.component'; +import {Utils} from '../../../../common/Utils'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-indexing', @@ -54,7 +54,7 @@ export class IndexingSettingsComponent extends SettingsComponent_settingsService, notification, i18n, s => s.Server.indexing); + super(i18n('Indexing'), _authService, _navigation, _settingsService, notification, i18n, s => s.Server.indexing); } @@ -79,11 +79,11 @@ export class IndexingSettingsComponent extends SettingsComponentthis._settingsService).cancel(); - this.notification.success(this.i18n("Folder indexed"), this.i18n("Success")); + this.notification.success(this.i18n('Folder indexed'), this.i18n('Success')); this.inProgress = false; return true; } catch (err) { @@ -118,10 +118,10 @@ export class IndexingSettingsComponent extends SettingsComponentthis._settingsService).reset(); - this.notification.success(this.i18n('Database reset'), this.i18n("Success")); + this.notification.success(this.i18n('Database reset'), this.i18n('Success')); this.inProgress = false; return true; } catch (err) { diff --git a/frontend/app/settings/indexing/indexing.settings.service.ts b/frontend/app/settings/indexing/indexing.settings.service.ts index 4666942..9985074 100644 --- a/frontend/app/settings/indexing/indexing.settings.service.ts +++ b/frontend/app/settings/indexing/indexing.settings.service.ts @@ -1,10 +1,10 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {SettingsService} from "../settings.service"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; -import {DatabaseType, IndexingConfig} from "../../../../common/config/private/IPrivateConfig"; -import {IndexingProgressDTO} from "../../../../common/entities/settings/IndexingProgressDTO"; -import {BehaviorSubject} from "rxjs/BehaviorSubject"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {SettingsService} from '../settings.service'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; +import {DatabaseType, IndexingConfig} from '../../../../common/config/private/IPrivateConfig'; +import {IndexingProgressDTO} from '../../../../common/entities/settings/IndexingProgressDTO'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; @Injectable() export class IndexingSettingsService extends AbstractSettingsService { @@ -19,7 +19,7 @@ export class IndexingSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/indexing", {settings: settings}); + return this._networkService.putJson('/settings/indexing', {settings: settings}); } @@ -28,19 +28,19 @@ export class IndexingSettingsService extends AbstractSettingsService("/admin/indexes/job/progress")); + this.progress.next(await this._networkService.getJson('/admin/indexes/job/progress')); } public reset() { - return this._networkService.deleteJson("/admin/indexes"); + return this._networkService.deleteJson('/admin/indexes'); } diff --git a/frontend/app/settings/map/map.settings.component.ts b/frontend/app/settings/map/map.settings.component.ts index 33f1dc2..dd45446 100644 --- a/frontend/app/settings/map/map.settings.component.ts +++ b/frontend/app/settings/map/map.settings.component.ts @@ -1,11 +1,11 @@ -import {Component} from "@angular/core"; -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"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component} from '@angular/core'; +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'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ @@ -22,7 +22,7 @@ export class MapSettingsComponent extends SettingsComponent_settingsService, notification, i18n, s => s.Client.Map); + super(i18n('Map'), _authService, _navigation, _settingsService, notification, i18n, s => s.Client.Map); } diff --git a/frontend/app/settings/map/map.settings.service.ts b/frontend/app/settings/map/map.settings.service.ts index 7e7b10c..74cf58c 100644 --- a/frontend/app/settings/map/map.settings.service.ts +++ b/frontend/app/settings/map/map.settings.service.ts @@ -1,8 +1,8 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {ClientConfig} from "../../../../common/config/public/ConfigClass"; -import {SettingsService} from "../settings.service"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {ClientConfig} from '../../../../common/config/public/ConfigClass'; +import {SettingsService} from '../settings.service'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; @Injectable() export class MapSettingsService extends AbstractSettingsService { @@ -13,7 +13,7 @@ export class MapSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/map", {settings: settings}); + return this._networkService.putJson('/settings/map', {settings: settings}); } } diff --git a/frontend/app/settings/other/other.settings.component.ts b/frontend/app/settings/other/other.settings.component.ts index 9e41a90..87ebecb 100644 --- a/frontend/app/settings/other/other.settings.component.ts +++ b/frontend/app/settings/other/other.settings.component.ts @@ -1,11 +1,11 @@ -import {Component, OnChanges} 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 {OtherSettingsService} from "./other.settings.service"; -import {OtherConfigDTO} from "../../../../common/entities/settings/OtherConfigDTO"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component, OnChanges} 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 {OtherSettingsService} from './other.settings.service'; +import {OtherConfigDTO} from '../../../../common/entities/settings/OtherConfigDTO'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-other', @@ -21,7 +21,7 @@ export class OtherSettingsComponent extends SettingsComponent im _settingsService: OtherSettingsService, notification: NotificationService, i18n: I18n) { - super(i18n("Other"), _authService, _navigation, _settingsService, notification, i18n, s => ({ + super(i18n('Other'), _authService, _navigation, _settingsService, notification, i18n, s => ({ enableThreading: s.Server.enableThreading, enableOnScrollThumbnailPrioritising: s.Client.enableOnScrollThumbnailPrioritising, enableOnScrollRendering: s.Client.enableOnScrollRendering, @@ -38,7 +38,7 @@ export class OtherSettingsComponent extends SettingsComponent im const val = await super.save(); if (val == true) { - this.notification.info(this.i18n('Restart the server to apply the new settings'), this.i18n("Info")); + this.notification.info(this.i18n('Restart the server to apply the new settings'), this.i18n('Info')); } return val; } diff --git a/frontend/app/settings/other/other.settings.service.ts b/frontend/app/settings/other/other.settings.service.ts index f0b3462..aa396cf 100644 --- a/frontend/app/settings/other/other.settings.service.ts +++ b/frontend/app/settings/other/other.settings.service.ts @@ -1,8 +1,8 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; -import {SettingsService} from "../settings.service"; -import {OtherConfigDTO} from "../../../../common/entities/settings/OtherConfigDTO"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; +import {SettingsService} from '../settings.service'; +import {OtherConfigDTO} from '../../../../common/entities/settings/OtherConfigDTO'; @Injectable() export class OtherSettingsService extends AbstractSettingsService { @@ -13,7 +13,7 @@ export class OtherSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/other", {settings: settings}); + return this._networkService.putJson('/settings/other', {settings: settings}); } } diff --git a/frontend/app/settings/search/search.settings.component.ts b/frontend/app/settings/search/search.settings.component.ts index a178fbd..3b1eee9 100644 --- a/frontend/app/settings/search/search.settings.component.ts +++ b/frontend/app/settings/search/search.settings.component.ts @@ -1,11 +1,11 @@ -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 {ClientConfig} from "../../../../common/config/public/ConfigClass"; -import {SearchSettingsService} from "./search.settings.service"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +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 {ClientConfig} from '../../../../common/config/public/ConfigClass'; +import {SearchSettingsService} from './search.settings.service'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-search', @@ -21,7 +21,7 @@ export class SearchSettingsComponent extends SettingsComponent s.Client.Search); + super(i18n('Search'), _authService, _navigation, _settingsService, notification, i18n, s => s.Client.Search); } diff --git a/frontend/app/settings/search/search.settings.service.ts b/frontend/app/settings/search/search.settings.service.ts index c098a30..c0a49b4 100644 --- a/frontend/app/settings/search/search.settings.service.ts +++ b/frontend/app/settings/search/search.settings.service.ts @@ -1,15 +1,15 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {DatabaseType} from "../../../../common/config/private/IPrivateConfig"; -import {ClientConfig} from "../../../../common/config/public/ConfigClass"; -import {SettingsService} from "../settings.service"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {DatabaseType} from '../../../../common/config/private/IPrivateConfig'; +import {ClientConfig} from '../../../../common/config/public/ConfigClass'; +import {SettingsService} from '../settings.service'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; @Injectable() export class SearchSettingsService extends AbstractSettingsService { constructor(private _networkService: NetworkService, _settingsService: SettingsService) { - super(_settingsService) + super(_settingsService); } public isSupported(): boolean { @@ -17,7 +17,7 @@ export class SearchSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/search", {settings: settings}); + return this._networkService.putJson('/settings/search', {settings: settings}); } } diff --git a/frontend/app/settings/settings.service.ts b/frontend/app/settings/settings.service.ts index b962e29..97f8fb0 100644 --- a/frontend/app/settings/settings.service.ts +++ b/frontend/app/settings/settings.service.ts @@ -1,10 +1,7 @@ -import {Injectable} from "@angular/core"; -import {BehaviorSubject} from "rxjs/BehaviorSubject"; -import { - DatabaseType, IPrivateConfig, ReIndexingSensitivity, - ThumbnailProcessingLib -} from "../../../common/config/private/IPrivateConfig"; -import {NetworkService} from "../model/network/network.service"; +import {Injectable} from '@angular/core'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {DatabaseType, IPrivateConfig, ReIndexingSensitivity, ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig'; +import {NetworkService} from '../model/network/network.service'; @Injectable() export class SettingsService { @@ -33,10 +30,10 @@ export class SettingsService { }, Map: { enabled: true, - googleApiKey: "" + googleApiKey: '' }, - publicUrl: "", - applicationTitle: "", + publicUrl: '', + applicationTitle: '', enableCache: true, enableOnScrollRendering: true, enableOnScrollThumbnailPrioritising: true, @@ -50,11 +47,11 @@ export class SettingsService { sharing: { updateTimeout: 2000 }, - imagesFolder: "", + imagesFolder: '', enableThreading: true, port: 80, thumbnail: { - folder: "", + folder: '', qualityPriority: true, processingLibrary: ThumbnailProcessingLib.sharp }, @@ -69,7 +66,7 @@ export class SettingsService { } public async getSettings(): Promise { - this.settings.next(await >this._networkService.getJson("/settings")); + this.settings.next(await >this._networkService.getJson('/settings')); } diff --git a/frontend/app/settings/share/share.settings.component.ts b/frontend/app/settings/share/share.settings.component.ts index 8bb0ad2..df7e9f2 100644 --- a/frontend/app/settings/share/share.settings.component.ts +++ b/frontend/app/settings/share/share.settings.component.ts @@ -1,11 +1,11 @@ -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 {ClientConfig} from "../../../../common/config/public/ConfigClass"; -import {ShareSettingsService} from "./share.settings.service"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +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 {ClientConfig} from '../../../../common/config/public/ConfigClass'; +import {ShareSettingsService} from './share.settings.service'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-share', @@ -21,7 +21,7 @@ export class ShareSettingsComponent extends SettingsComponent s.Client.Sharing); + super(i18n('Share'), _authService, _navigation, _settingsService, notification, i18n, s => s.Client.Sharing); } diff --git a/frontend/app/settings/share/share.settings.service.ts b/frontend/app/settings/share/share.settings.service.ts index 659387f..0696977 100644 --- a/frontend/app/settings/share/share.settings.service.ts +++ b/frontend/app/settings/share/share.settings.service.ts @@ -1,9 +1,9 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {DatabaseType} from "../../../../common/config/private/IPrivateConfig"; -import {ClientConfig} from "../../../../common/config/public/ConfigClass"; -import {SettingsService} from "../settings.service"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {DatabaseType} from '../../../../common/config/private/IPrivateConfig'; +import {ClientConfig} from '../../../../common/config/public/ConfigClass'; +import {SettingsService} from '../settings.service'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; @Injectable() export class ShareSettingsService extends AbstractSettingsService { @@ -14,12 +14,12 @@ export class ShareSettingsService extends AbstractSettingsService { - return this._networkService.putJson("/settings/share", {settings: settings}); + return this._networkService.putJson('/settings/share', {settings: settings}); } } diff --git a/frontend/app/settings/thumbnail/thumbanil.settings.component.ts b/frontend/app/settings/thumbnail/thumbanil.settings.component.ts index 0ca4067..649d6de 100644 --- a/frontend/app/settings/thumbnail/thumbanil.settings.component.ts +++ b/frontend/app/settings/thumbnail/thumbanil.settings.component.ts @@ -1,13 +1,13 @@ -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"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +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'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-thumbnail', @@ -25,28 +25,28 @@ export class ThumbnailSettingsComponent extends SettingsComponent<{ server: Thum _settingsService: ThumbnailSettingsService, notification: NotificationService, i18n: I18n) { - super(i18n("Thumbnail"), _authService, _navigation, _settingsService, notification, i18n, s => ({ + super(i18n('Thumbnail'), _authService, _navigation, _settingsService, notification, i18n, s => ({ client: s.Client.Thumbnail, server: s.Server.thumbnail })); } get ThumbnailSizes(): string { - return this.settings.client.thumbnailSizes.join("; "); + 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); + 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 += " " + this.i18n("(recommended)"); + if (v.value.toLowerCase() == 'sharp') { + v.value += ' ' + this.i18n('(recommended)'); } return v; }); diff --git a/frontend/app/settings/thumbnail/thumbanil.settings.service.ts b/frontend/app/settings/thumbnail/thumbanil.settings.service.ts index d527f75..af8a063 100644 --- a/frontend/app/settings/thumbnail/thumbanil.settings.service.ts +++ b/frontend/app/settings/thumbnail/thumbanil.settings.service.ts @@ -1,9 +1,9 @@ -import {Injectable} from "@angular/core"; -import {NetworkService} from "../../model/network/network.service"; -import {ClientConfig} from "../../../../common/config/public/ConfigClass"; -import {ThumbnailConfig} from "../../../../common/config/private/IPrivateConfig"; -import {AbstractSettingsService} from "../_abstract/abstract.settings.service"; -import {SettingsService} from "../settings.service"; +import {Injectable} from '@angular/core'; +import {NetworkService} from '../../model/network/network.service'; +import {ClientConfig} from '../../../../common/config/public/ConfigClass'; +import {ThumbnailConfig} from '../../../../common/config/private/IPrivateConfig'; +import {AbstractSettingsService} from '../_abstract/abstract.settings.service'; +import {SettingsService} from '../settings.service'; @Injectable() export class ThumbnailSettingsService extends AbstractSettingsService<{ server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }> { @@ -14,7 +14,7 @@ export class ThumbnailSettingsService extends AbstractSettingsService<{ server: public updateSettings(settings: { server: ThumbnailConfig, client: ClientConfig.ThumbnailConfig }): Promise { - return this._networkService.putJson("/settings/thumbnail", {settings: settings}); + return this._networkService.putJson('/settings/thumbnail', {settings: settings}); } } diff --git a/frontend/app/settings/usermanager/usermanager.settings.component.ts b/frontend/app/settings/usermanager/usermanager.settings.component.ts index 5a677cb..3ddc40c 100644 --- a/frontend/app/settings/usermanager/usermanager.settings.component.ts +++ b/frontend/app/settings/usermanager/usermanager.settings.component.ts @@ -1,13 +1,13 @@ -import {Component, OnInit, ViewChild} from "@angular/core"; -import {AuthenticationService} from "../../model/network/authentication.service"; -import {UserDTO, UserRoles} from "../../../../common/entities/UserDTO"; -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"; -import {I18n} from "@ngx-translate/i18n-polyfill"; +import {Component, OnInit, ViewChild} from '@angular/core'; +import {AuthenticationService} from '../../model/network/authentication.service'; +import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO'; +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'; +import {I18n} from '@ngx-translate/i18n-polyfill'; @Component({ selector: 'settings-usermanager', @@ -27,10 +27,10 @@ export class UserMangerSettingsComponent implements OnInit { text = { - Enabled: "Enabled", - Disabled: "Disabled", - Low: "Low", - High: "High" + Enabled: 'Enabled', + Disabled: 'Disabled', + Low: 'Low', + High: 'High' }; @@ -39,10 +39,10 @@ export class UserMangerSettingsComponent implements OnInit { private _userSettings: UserManagerSettingsService, private notification: NotificationService, public i18n: I18n) { - this.text.Enabled = i18n("Enabled"); - this.text.Disabled = i18n("Disabled"); - this.text.Low = i18n("Low"); - this.text.High = i18n("High"); + this.text.Enabled = i18n('Enabled'); + this.text.Disabled = i18n('Disabled'); + this.text.Low = i18n('Low'); + this.text.High = i18n('High'); } @@ -112,16 +112,16 @@ export class UserMangerSettingsComponent implements OnInit { async switched(event: { previousValue: false, currentValue: true }) { this.inProgress = true; - this.error = ""; + this.error = ''; this.enabled = event.currentValue; try { await this._userSettings.updateSettings(this.enabled); await this.getSettings(); if (this.enabled == true) { - this.notification.success(this.i18n('Password protection enabled'), this.i18n("Success")); + this.notification.success(this.i18n('Password protection enabled'), this.i18n('Success')); this.getUsersList(); } else { - this.notification.success(this.i18n('Password protection disabled'), this.i18n("Success")); + this.notification.success(this.i18n('Password protection disabled'), this.i18n('Success')); } } catch (err) { console.log(err); diff --git a/frontend/app/settings/usermanager/usermanager.settings.service.ts b/frontend/app/settings/usermanager/usermanager.settings.service.ts index c29025e..2ae3b6d 100644 --- a/frontend/app/settings/usermanager/usermanager.settings.service.ts +++ b/frontend/app/settings/usermanager/usermanager.settings.service.ts @@ -1,7 +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"; +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 { @@ -11,27 +11,27 @@ export class UserManagerSettingsService { } public createUser(user: UserDTO): Promise { - return this._networkService.putJson("/user", {newUser: user}); + return this._networkService.putJson('/user', {newUser: user}); } - public async getSettings(): Promise { - return (await >this._networkService.getJson("/settings")).Client.authenticationRequired; + public async getSettings(): Promise { + return (await >this._networkService.getJson('/settings')).Client.authenticationRequired; } public updateSettings(settings: boolean): Promise { - return this._networkService.putJson("/settings/authentication", {settings: settings}); + return this._networkService.putJson('/settings/authentication', {settings: settings}); } public getUsers(): Promise> { - return this._networkService.getJson("/user/list"); + return this._networkService.getJson('/user/list'); } public deleteUser(user: UserDTO): Promise { - return this._networkService.deleteJson("/user/" + user.id); + return this._networkService.deleteJson('/user/' + user.id); } public updateRole(user: UserDTO): Promise { - return this._networkService.postJson("/user/" + user.id + "/role", {newRole: user.role}); + return this._networkService.postJson('/user/' + user.id + '/role', {newRole: user.role}); } } diff --git a/frontend/app/sharelogin/share-login.component.css b/frontend/app/sharelogin/share-login.component.css index 8495a2b..97d9929 100644 --- a/frontend/app/sharelogin/share-login.component.css +++ b/frontend/app/sharelogin/share-login.component.css @@ -22,12 +22,11 @@ max-width: 350px; width: 100% !important; background-color: #F7F7F7; - margin: 0 auto; border-radius: 2px; box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); overflow: hidden; height: 150px; - margin-top: 0px; + margin: 0px auto 0; } /*Margin by pixel:*/ diff --git a/frontend/app/sharelogin/share-login.component.ts b/frontend/app/sharelogin/share-login.component.ts index 0d00a24..de83096 100644 --- a/frontend/app/sharelogin/share-login.component.ts +++ b/frontend/app/sharelogin/share-login.component.ts @@ -1,8 +1,8 @@ -import {Component, OnInit} from "@angular/core"; -import {AuthenticationService} from "../model/network/authentication.service"; -import {ErrorCodes} from "../../../common/entities/Error"; -import {Config} from "../../../common/config/public/Config"; -import {NavigationService} from "../model/navigation.service"; +import {Component, OnInit} from '@angular/core'; +import {AuthenticationService} from '../model/network/authentication.service'; +import {ErrorCodes} from '../../../common/entities/Error'; +import {Config} from '../../../common/config/public/Config'; +import {NavigationService} from '../model/navigation.service'; @Component({ selector: 'share-login', @@ -11,7 +11,7 @@ import {NavigationService} from "../model/navigation.service"; }) export class ShareLoginComponent implements OnInit { password: string; - loginError: boolean = false; + loginError = false; title: string; constructor(private _authService: AuthenticationService, private _navigation: NavigationService) { diff --git a/frontend/index.html b/frontend/index.html index 884384e..164b325 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -16,7 +16,7 @@ -Loading... +Loading... diff --git a/karma.conf.js b/karma.conf.js index 51329f3..8933009 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -7,7 +7,7 @@ module.exports = function (config) { frameworks: ['jasmine', '@angular/cli'], plugins: [ require('karma-jasmine'), - require('karma-phantomjs-launcher'), + require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), require('@angular/cli/plugins/karma') @@ -27,7 +27,7 @@ module.exports = function (config) { colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['PhantomJS'], + browsers: ["ChromeHeadless"], singleRun: false }); }; diff --git a/package.json b/package.json index 015c71f..54c76ab 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "main": "./backend/index.js", "bin": "./backend/index.js", "scripts": { - "install": "tsc && gulp build-prod", "build-release": "gulp build-release", "pretest": "tsc", "test": "ng test --single-run && mocha --recursive test/backend/unit && mocha --recursive test/backend/integration && mocha --recursive test/common/unit ", @@ -85,6 +84,7 @@ "jasmine-spec-reporter": "~4.2.1", "jw-bootstrap-switch-ng2": "1.0.10", "karma": "^2.0.0", + "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-coverage-istanbul-reporter": "^1.4.2", "karma-jasmine": "^1.1.1", @@ -99,7 +99,6 @@ "ng2-toastr": "^4.1.2", "ngx-bootstrap": "^2.0.3", "ngx-clipboard": "^10.0.0", - "phantomjs-prebuilt": "^2.1.16", "protractor": "^5.3.0", "remap-istanbul": "^0.11.0", "rimraf": "^2.6.2", @@ -110,7 +109,7 @@ "tslint": "^5.9.1", "typescript": "^2.8.1", "xlf-google-translate": "^1.0.0-beta.8", - "zone.js": "^0.8.20" + "zone.js": "git://github.com/JiaLiPassion/zone.js#jasmine-dist" }, "optionalDependencies": { "bcrypt": "^1.0.3", diff --git a/test/backend/integration/model/sql/typeorm.ts b/test/backend/integration/model/sql/typeorm.ts index df601e2..213353d 100644 --- a/test/backend/integration/model/sql/typeorm.ts +++ b/test/backend/integration/model/sql/typeorm.ts @@ -1,13 +1,13 @@ -import {expect} from "chai"; -import * as fs from "fs"; -import * as path from "path"; -import {Config} from "../../../../../common/config/private/Config"; -import {DatabaseType} from "../../../../../common/config/private/IPrivateConfig"; -import {SQLConnection} from "../../../../../backend/model/sql/SQLConnection"; -import {UserEntity} from "../../../../../backend/model/sql/enitites/UserEntity"; -import {UserRoles} from "../../../../../common/entities/UserDTO"; -import {PasswordHelper} from "../../../../../backend/model/PasswordHelper"; -import {DirectoryEntity} from "../../../../../backend/model/sql/enitites/DirectoryEntity"; +import {expect} from 'chai'; +import * as fs from 'fs'; +import * as path from 'path'; +import {Config} from '../../../../../common/config/private/Config'; +import {DatabaseType} from '../../../../../common/config/private/IPrivateConfig'; +import {SQLConnection} from '../../../../../backend/model/sql/SQLConnection'; +import {UserEntity} from '../../../../../backend/model/sql/enitites/UserEntity'; +import {UserRoles} from '../../../../../common/entities/UserDTO'; +import {PasswordHelper} from '../../../../../backend/model/PasswordHelper'; +import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity'; import { CameraMetadataEntity, GPSMetadataEntity, @@ -15,13 +15,13 @@ import { PhotoEntity, PhotoMetadataEntity, PositionMetaDataEntity -} from "../../../../../backend/model/sql/enitites/PhotoEntity"; +} from '../../../../../backend/model/sql/enitites/PhotoEntity'; describe('Typeorm integration', () => { - const tempDir = path.join(__dirname, "../../tmp"); - const dbPath = path.join(tempDir, "test.db"); + const tempDir = path.join(__dirname, '../../tmp'); + const dbPath = path.join(tempDir, 'test.db'); const setUpSqlDB = () => { if (fs.existsSync(dbPath)) { fs.unlinkSync(dbPath); @@ -56,8 +56,8 @@ describe('Typeorm integration', () => { const getDir = () => { const d = new DirectoryEntity(); - d.name = "test dir"; - d.path = "."; + d.name = 'test dir'; + d.path = '.'; d.lastModified = Date.now(); d.lastScanned = null; d.parent = null; @@ -76,20 +76,20 @@ describe('Typeorm integration', () => { gps.latitude = 1; gps.longitude = 1; const pd = new PositionMetaDataEntity(); - pd.city = "New York"; - pd.country = "Alderan"; - pd.state = "Death star"; + pd.city = 'New York'; + pd.country = 'Alderan'; + pd.state = 'Death star'; pd.GPSData = gps; const cd = new CameraMetadataEntity(); cd.ISO = 100; - cd.model = "60D"; - cd.maker = "Canon"; + cd.model = '60D'; + cd.maker = 'Canon'; cd.fStop = 1; cd.exposure = 1; cd.focalLength = 1; - cd.lens = "Lens"; + cd.lens = 'Lens'; const m = new PhotoMetadataEntity(); - m.keywords = ["apple"]; + m.keywords = ['apple']; m.cameraData = cd; m.positionData = pd; m.size = sd; @@ -98,7 +98,7 @@ describe('Typeorm integration', () => { const d = new PhotoEntity(); - d.name = "test photo.jpg"; + d.name = 'test photo.jpg'; d.directory = null; d.metadata = m; return d; @@ -127,8 +127,8 @@ describe('Typeorm integration', () => { const conn = await SQLConnection.getConnection(); const userRepository = conn.getRepository(UserEntity); const a = new UserEntity(); - a.name = "test"; - a.password = PasswordHelper.cryptPassword("test"); + a.name = 'test'; + a.password = PasswordHelper.cryptPassword('test'); a.role = UserRoles.Admin; await userRepository.save(a); expect((await userRepository.find()).length).to.equal(1); @@ -161,10 +161,10 @@ describe('Typeorm integration', () => { await pr.save(photo); let photos = await pr - .createQueryBuilder("photo") - .orderBy("photo.metadata.creationDate", "ASC") - .where('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + photo.metadata.positionData.city + "%"}) - .innerJoinAndSelect("photo.directory", "directory") + .createQueryBuilder('photo') + .orderBy('photo.metadata.creationDate', 'ASC') + .where('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + photo.metadata.positionData.city + '%'}) + .innerJoinAndSelect('photo.directory', 'directory') .limit(10) .getMany(); @@ -183,10 +183,10 @@ describe('Typeorm integration', () => { photo.metadata.positionData = null; await pr.save(photo); let photos = await pr - .createQueryBuilder("photo") - .orderBy("photo.metadata.creationDate", "ASC") - .where('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + city + "%"}) - .innerJoinAndSelect("photo.directory", "directory") + .createQueryBuilder('photo') + .orderBy('photo.metadata.creationDate', 'ASC') + .where('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + city + '%'}) + .innerJoinAndSelect('photo.directory', 'directory') .limit(10) .getMany(); diff --git a/test/backend/unit/middlewares/user/AuthenticationMWs.ts b/test/backend/unit/middlewares/user/AuthenticationMWs.ts index 6c19cd6..e97e0c0 100644 --- a/test/backend/unit/middlewares/user/AuthenticationMWs.ts +++ b/test/backend/unit/middlewares/user/AuthenticationMWs.ts @@ -1,11 +1,11 @@ -import {expect} from "chai"; -import {AuthenticationMWs} from "../../../../../backend/middlewares/user/AuthenticationMWs"; -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"; -import {Config} from "../../../../../common/config/private/Config"; -import {IUserManager} from "../../../../../backend/model/interfaces/IUserManager"; +import {expect} from 'chai'; +import {AuthenticationMWs} from '../../../../../backend/middlewares/user/AuthenticationMWs'; +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'; +import {Config} from '../../../../../common/config/private/Config'; +import {IUserManager} from '../../../../../backend/model/interfaces/IUserManager'; describe('Authentication middleware', () => { @@ -18,7 +18,7 @@ describe('Authentication middleware', () => { it('should call next on authenticated', (done) => { let req: any = { session: { - user: "A user" + user: 'A user' }, sessionOptions: {}, query: {}, @@ -71,7 +71,7 @@ describe('Authentication middleware', () => { it('should call next error on authenticated', (done) => { let req: any = { session: { - user: "A user" + user: 'A user' }, sessionOptions: {}, }; @@ -181,8 +181,8 @@ describe('Authentication middleware', () => { let req: any = { body: { loginCredential: { - username: "aa", - password: "bb" + username: 'aa', + password: 'bb' } }, query: {}, @@ -208,8 +208,8 @@ describe('Authentication middleware', () => { session: {}, body: { loginCredential: { - username: "aa", - password: "bb" + username: 'aa', + password: 'bb' } }, query: {}, @@ -217,12 +217,12 @@ describe('Authentication middleware', () => { }; let next: any = (err: ErrorDTO) => { expect(err).to.be.undefined; - expect(req.session.user).to.be.eql("test user"); + expect(req.session.user).to.be.eql('test user'); done(); }; ObjectManagerRepository.getInstance().UserManager = { findOne: (filter) => { - return Promise.resolve("test user"); + return Promise.resolve('test user'); } }; AuthenticationMWs.login(req, null, next); diff --git a/test/backend/unit/model/sql/SearchManager.ts b/test/backend/unit/model/sql/SearchManager.ts index 28263f3..ce93694 100644 --- a/test/backend/unit/model/sql/SearchManager.ts +++ b/test/backend/unit/model/sql/SearchManager.ts @@ -1,9 +1,9 @@ -import {expect} from "chai"; -import * as fs from "fs"; -import * as path from "path"; -import {Config} from "../../../../../common/config/private/Config"; -import {DatabaseType} from "../../../../../common/config/private/IPrivateConfig"; -import {SQLConnection} from "../../../../../backend/model/sql/SQLConnection"; +import {expect} from 'chai'; +import * as fs from 'fs'; +import * as path from 'path'; +import {Config} from '../../../../../common/config/private/Config'; +import {DatabaseType} from '../../../../../common/config/private/IPrivateConfig'; +import {SQLConnection} from '../../../../../backend/model/sql/SQLConnection'; import { CameraMetadataEntity, GPSMetadataEntity, @@ -11,21 +11,21 @@ import { PhotoEntity, PhotoMetadataEntity, PositionMetaDataEntity -} from "../../../../../backend/model/sql/enitites/PhotoEntity"; -import {SearchManager} from "../../../../../backend/model/sql/SearchManager"; -import {AutoCompleteItem, SearchTypes} from "../../../../../common/entities/AutoCompleteItem"; -import {SearchResultDTO} from "../../../../../common/entities/SearchResultDTO"; -import {DirectoryEntity} from "../../../../../backend/model/sql/enitites/DirectoryEntity"; +} from '../../../../../backend/model/sql/enitites/PhotoEntity'; +import {SearchManager} from '../../../../../backend/model/sql/SearchManager'; +import {AutoCompleteItem, SearchTypes} from '../../../../../common/entities/AutoCompleteItem'; +import {SearchResultDTO} from '../../../../../common/entities/SearchResultDTO'; +import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity'; describe('SearchManager', () => { - const tempDir = path.join(__dirname, "../../tmp"); - const dbPath = path.join(tempDir, "test.db"); + const tempDir = path.join(__dirname, '../../tmp'); + const dbPath = path.join(tempDir, 'test.db'); const dir = new DirectoryEntity(); - dir.name = "wars dir"; - dir.path = "."; + dir.name = 'wars dir'; + dir.path = '.'; dir.lastModified = Date.now(); dir.lastScanned = null; @@ -49,9 +49,9 @@ describe('SearchManager', () => { cd.fStop = 1; cd.exposure = 1; cd.focalLength = 1;*/ - cd.lens = "Lens"; + cd.lens = 'Lens'; const m = new PhotoMetadataEntity(); - m.keywords = ["apple"]; + m.keywords = ['apple']; m.cameraData = cd; m.positionData = pd; m.size = sd; @@ -60,24 +60,24 @@ describe('SearchManager', () => { const d = new PhotoEntity(); - d.name = "test photo.jpg"; + d.name = 'test photo.jpg'; d.directory = dir; d.metadata = m; return d; }; let p = getPhoto(); - p.metadata.keywords = ["Boba Fett", "star wars", "Anakin", "death star"]; - p.metadata.positionData.city = "Mos Eisley"; - p.metadata.positionData.country = "Tatooine"; - p.name = "sw1"; + p.metadata.keywords = ['Boba Fett', 'star wars', 'Anakin', 'death star']; + p.metadata.positionData.city = 'Mos Eisley'; + p.metadata.positionData.country = 'Tatooine'; + p.name = 'sw1'; let p2 = getPhoto(); - p2.metadata.keywords = ["Padmé Amidala", "star wars", "Natalie Portman", "death star"]; - p2.metadata.positionData.city = "Derem City"; - p2.metadata.positionData.state = "Research City"; - p2.metadata.positionData.country = "Kamino"; - p2.name = "sw2"; + p2.metadata.keywords = ['Padmé Amidala', 'star wars', 'Natalie Portman', 'death star']; + p2.metadata.positionData.city = 'Derem City'; + p2.metadata.positionData.state = 'Research City'; + p2.metadata.positionData.country = 'Kamino'; + p2.name = 'sw2'; const setUpSqlDB = async () => { if (fs.existsSync(dbPath)) { @@ -127,68 +127,68 @@ describe('SearchManager', () => { return a.text.localeCompare(b.text); }; - expect((await sm.autocomplete("tat"))).to.deep.equal([new AutoCompleteItem("Tatooine", SearchTypes.position)]); - expect((await sm.autocomplete("star"))).to.deep.equal([new AutoCompleteItem("star wars", SearchTypes.keyword), - new AutoCompleteItem("death star", SearchTypes.keyword)]); + expect((await sm.autocomplete('tat'))).to.deep.equal([new AutoCompleteItem('Tatooine', SearchTypes.position)]); + expect((await sm.autocomplete('star'))).to.deep.equal([new AutoCompleteItem('star wars', SearchTypes.keyword), + new AutoCompleteItem('death star', SearchTypes.keyword)]); - expect((await sm.autocomplete("wars"))).to.deep.equal([new AutoCompleteItem("star wars", SearchTypes.keyword), - new AutoCompleteItem("wars dir", SearchTypes.directory)]); + expect((await sm.autocomplete('wars'))).to.deep.equal([new AutoCompleteItem('star wars', SearchTypes.keyword), + new AutoCompleteItem('wars dir', SearchTypes.directory)]); - expect((await sm.autocomplete("arch"))).eql([new AutoCompleteItem("Research City", SearchTypes.position)]); - expect((await sm.autocomplete("a")).sort(cmp)).eql([ - new AutoCompleteItem("Boba Fett", SearchTypes.keyword), - new AutoCompleteItem("star wars", SearchTypes.keyword), - new AutoCompleteItem("Anakin", SearchTypes.keyword), - new AutoCompleteItem("death star", SearchTypes.keyword), - new AutoCompleteItem("Padmé Amidala", SearchTypes.keyword), - new AutoCompleteItem("Natalie Portman", SearchTypes.keyword), - new AutoCompleteItem("Kamino", SearchTypes.position), - new AutoCompleteItem("Tatooine", SearchTypes.position), - new AutoCompleteItem("wars dir", SearchTypes.directory), - new AutoCompleteItem("Research City", SearchTypes.position)].sort(cmp)); + expect((await sm.autocomplete('arch'))).eql([new AutoCompleteItem('Research City', SearchTypes.position)]); + expect((await sm.autocomplete('a')).sort(cmp)).eql([ + new AutoCompleteItem('Boba Fett', SearchTypes.keyword), + new AutoCompleteItem('star wars', SearchTypes.keyword), + new AutoCompleteItem('Anakin', SearchTypes.keyword), + new AutoCompleteItem('death star', SearchTypes.keyword), + new AutoCompleteItem('Padmé Amidala', SearchTypes.keyword), + new AutoCompleteItem('Natalie Portman', SearchTypes.keyword), + new AutoCompleteItem('Kamino', SearchTypes.position), + new AutoCompleteItem('Tatooine', SearchTypes.position), + new AutoCompleteItem('wars dir', SearchTypes.directory), + new AutoCompleteItem('Research City', SearchTypes.position)].sort(cmp)); - expect((await sm.autocomplete("sw")).sort(cmp)).to.deep.equal([new AutoCompleteItem("sw1", SearchTypes.image), - new AutoCompleteItem("sw2", SearchTypes.image)].sort(cmp)); + expect((await sm.autocomplete('sw')).sort(cmp)).to.deep.equal([new AutoCompleteItem('sw1', SearchTypes.image), + new AutoCompleteItem('sw2', SearchTypes.image)].sort(cmp)); }); it('should search', async () => { let sm = new SearchManager(); - expect((await sm.search("sw", null))).to.deep.equal({ - searchText: "sw", + expect((await sm.search('sw', null))).to.deep.equal({ + searchText: 'sw', searchType: null, directories: [], photos: [p, p2], resultOverflow: false }); - expect((await sm.search("Tatooine", SearchTypes.position))).to.deep.equal({ - searchText: "Tatooine", + expect((await sm.search('Tatooine', SearchTypes.position))).to.deep.equal({ + searchText: 'Tatooine', searchType: SearchTypes.position, directories: [], photos: [p], resultOverflow: false }); - expect((await sm.search("ortm", SearchTypes.keyword))).to.deep.equal({ - searchText: "ortm", + expect((await sm.search('ortm', SearchTypes.keyword))).to.deep.equal({ + searchText: 'ortm', searchType: SearchTypes.keyword, directories: [], photos: [p2], resultOverflow: false }); - expect((await sm.search("ortm", SearchTypes.keyword))).to.deep.equal({ - searchText: "ortm", + expect((await sm.search('ortm', SearchTypes.keyword))).to.deep.equal({ + searchText: 'ortm', searchType: SearchTypes.keyword, directories: [], photos: [p2], resultOverflow: false }); - expect((await sm.search("wa", SearchTypes.keyword))).to.deep.equal({ - searchText: "wa", + expect((await sm.search('wa', SearchTypes.keyword))).to.deep.equal({ + searchText: 'wa', searchType: SearchTypes.keyword, directories: [dir], photos: [p, p2], @@ -200,36 +200,36 @@ describe('SearchManager', () => { it('should instant search', async () => { let sm = new SearchManager(); - expect((await sm.instantSearch("sw"))).to.deep.equal({ - searchText: "sw", + expect((await sm.instantSearch('sw'))).to.deep.equal({ + searchText: 'sw', directories: [], photos: [p, p2], resultOverflow: false }); - expect((await sm.instantSearch("Tatooine"))).to.deep.equal({ - searchText: "Tatooine", + expect((await sm.instantSearch('Tatooine'))).to.deep.equal({ + searchText: 'Tatooine', directories: [], photos: [p], resultOverflow: false }); - expect((await sm.instantSearch("ortm"))).to.deep.equal({ - searchText: "ortm", + expect((await sm.instantSearch('ortm'))).to.deep.equal({ + searchText: 'ortm', directories: [], photos: [p2], resultOverflow: false }); - expect((await sm.instantSearch("ortm"))).to.deep.equal({ - searchText: "ortm", + expect((await sm.instantSearch('ortm'))).to.deep.equal({ + searchText: 'ortm', directories: [], photos: [p2], resultOverflow: false }); - expect((await sm.instantSearch("wa"))).to.deep.equal({ - searchText: "wa", + expect((await sm.instantSearch('wa'))).to.deep.equal({ + searchText: 'wa', directories: [dir], photos: [p, p2], resultOverflow: false diff --git a/test/backend/unit/model/sql/SharingManager.ts b/test/backend/unit/model/sql/SharingManager.ts index 45c05fe..b46098b 100644 --- a/test/backend/unit/model/sql/SharingManager.ts +++ b/test/backend/unit/model/sql/SharingManager.ts @@ -1,19 +1,19 @@ -import {expect} from "chai"; -import * as fs from "fs"; -import * as path from "path"; -import {Config} from "../../../../../common/config/private/Config"; -import {DatabaseType} from "../../../../../common/config/private/IPrivateConfig"; -import {SQLConnection} from "../../../../../backend/model/sql/SQLConnection"; -import {SharingManager} from "../../../../../backend/model/sql/SharingManager"; -import {SharingDTO} from "../../../../../common/entities/SharingDTO"; -import {UserEntity} from "../../../../../backend/model/sql/enitites/UserEntity"; -import {UserDTO, UserRoles} from "../../../../../common/entities/UserDTO"; +import {expect} from 'chai'; +import * as fs from 'fs'; +import * as path from 'path'; +import {Config} from '../../../../../common/config/private/Config'; +import {DatabaseType} from '../../../../../common/config/private/IPrivateConfig'; +import {SQLConnection} from '../../../../../backend/model/sql/SQLConnection'; +import {SharingManager} from '../../../../../backend/model/sql/SharingManager'; +import {SharingDTO} from '../../../../../common/entities/SharingDTO'; +import {UserEntity} from '../../../../../backend/model/sql/enitites/UserEntity'; +import {UserDTO, UserRoles} from '../../../../../common/entities/UserDTO'; describe('SharingManager', () => { - const tempDir = path.join(__dirname, "../../tmp"); - const dbPath = path.join(tempDir, "test.db"); + const tempDir = path.join(__dirname, '../../tmp'); + const dbPath = path.join(tempDir, 'test.db'); let creator: UserDTO = null; @@ -32,8 +32,8 @@ describe('SharingManager', () => { creator = await conn.getRepository(UserEntity).save({ id: null, - name: "test use", - password: "", + name: 'test use', + password: '', role: UserRoles.User, permissions: null }); @@ -65,8 +65,8 @@ describe('SharingManager', () => { let sharing: SharingDTO = { id: null, - sharingKey: "testKey", - path: "/", + sharingKey: 'testKey', + path: '/', password: null, creator: creator, expires: Date.now() + 1000, @@ -90,8 +90,8 @@ describe('SharingManager', () => { let sharing: SharingDTO = { id: null, - sharingKey: "testKey", - path: "/", + sharingKey: 'testKey', + path: '/', password: null, creator: creator, expires: Date.now() + 1000, @@ -100,7 +100,7 @@ describe('SharingManager', () => { }; const saved = await sm.createSharing(sharing); - const found = await sm.findOne({sharingKey: "testKey"}); + const found = await sm.findOne({sharingKey: 'testKey'}); expect(found.id).to.not.equals(null); expect(found.sharingKey).to.equals(sharing.sharingKey); @@ -115,8 +115,8 @@ describe('SharingManager', () => { let sharing: SharingDTO = { id: null, - sharingKey: "testKey", - path: "/", + sharingKey: 'testKey', + path: '/', password: null, creator: creator, expires: Date.now() + 1000, diff --git a/test/backend/unit/model/threading/DiskMangerWorker.spec.ts b/test/backend/unit/model/threading/DiskMangerWorker.spec.ts index b54721b..d905f65 100644 --- a/test/backend/unit/model/threading/DiskMangerWorker.spec.ts +++ b/test/backend/unit/model/threading/DiskMangerWorker.spec.ts @@ -1,17 +1,17 @@ -import {expect} from "chai"; -import {DiskMangerWorker} from "../../../../../backend/model/threading/DiskMangerWorker"; -import * as path from "path"; -import {Config} from "../../../../../common/config/private/Config"; -import {ProjectPath} from "../../../../../backend/ProjectPath"; +import {expect} from 'chai'; +import {DiskMangerWorker} from '../../../../../backend/model/threading/DiskMangerWorker'; +import * as path from 'path'; +import {Config} from '../../../../../common/config/private/Config'; +import {ProjectPath} from '../../../../../backend/ProjectPath'; describe('DiskMangerWorker', () => { it('should parse metadata', async () => { - Config.Server.imagesFolder = path.join(__dirname, "/../../assets"); - ProjectPath.ImageFolder = path.join(__dirname, "/../../assets"); - const dir = await DiskMangerWorker.scanDirectory("/"); + Config.Server.imagesFolder = path.join(__dirname, '/../../assets'); + ProjectPath.ImageFolder = path.join(__dirname, '/../../assets'); + const dir = await DiskMangerWorker.scanDirectory('/'); expect(dir.photos.length).to.be.equals(1); - expect(dir.photos[0].name).to.be.equals("test image öüóőúéáű-.,.jpg"); + expect(dir.photos[0].name).to.be.equals('test image öüóőúéáű-.,.jpg'); expect(dir.photos[0].metadata.keywords).to.deep.equals(['Berkley', 'USA', 'űáéúőóüö ŰÁÉÚŐÓÜÖ']); expect(dir.photos[0].metadata.fileSize).to.deep.equals(62392); expect(dir.photos[0].metadata.size).to.deep.equals({width: 140, height: 93}); diff --git a/test/common/unit/UserDTO.ts b/test/common/unit/UserDTO.ts index 22ca9d6..b20e5bc 100644 --- a/test/common/unit/UserDTO.ts +++ b/test/common/unit/UserDTO.ts @@ -1,25 +1,25 @@ -import {expect} from "chai"; -import {UserDTO} from "../../../common/entities/UserDTO"; +import {expect} from 'chai'; +import {UserDTO} from '../../../common/entities/UserDTO'; describe('UserDTO', () => { it('should check available path', () => { - expect(UserDTO.isPathAvailable("/", ["/"])).to.be.equals(true); - expect(UserDTO.isPathAvailable("/", ["/subfolder", "/"])).to.be.equals(true); - expect(UserDTO.isPathAvailable("/abc", ["/subfolder", "/"])).to.be.equals(false); - expect(UserDTO.isPathAvailable("/abc", ["/subfolder", "/*"])).to.be.equals(true); - expect(UserDTO.isPathAvailable("/abc", ["/subfolder"])).to.be.equals(false); - expect(UserDTO.isPathAvailable("/abc/two", ["/subfolder"])).to.be.equals(false); - expect(UserDTO.isPathAvailable("/abc/two", ["/"])).to.be.equals(false); - expect(UserDTO.isPathAvailable("/abc/two", ["/*"])).to.be.equals(true); + expect(UserDTO.isPathAvailable('/', ['/'])).to.be.equals(true); + expect(UserDTO.isPathAvailable('/', ['/subfolder', '/'])).to.be.equals(true); + expect(UserDTO.isPathAvailable('/abc', ['/subfolder', '/'])).to.be.equals(false); + expect(UserDTO.isPathAvailable('/abc', ['/subfolder', '/*'])).to.be.equals(true); + expect(UserDTO.isPathAvailable('/abc', ['/subfolder'])).to.be.equals(false); + expect(UserDTO.isPathAvailable('/abc/two', ['/subfolder'])).to.be.equals(false); + expect(UserDTO.isPathAvailable('/abc/two', ['/'])).to.be.equals(false); + expect(UserDTO.isPathAvailable('/abc/two', ['/*'])).to.be.equals(true); }); it('should check directory', () => { - expect(UserDTO.isDirectoryAvailable({path: "/", name: "abc"}, ["/*"])).to.be.equals(true); - expect(UserDTO.isDirectoryAvailable({path: "/", name: "abc"}, ["/"])).to.be.equals(false); - expect(UserDTO.isDirectoryAvailable({path: ".\\", name: "."}, ["/"])).to.be.equals(true); - expect(UserDTO.isDirectoryAvailable({path: "/", name: "abc"}, ["/*", "/asdad"])).to.be.equals(true); + expect(UserDTO.isDirectoryAvailable({path: '/', name: 'abc'}, ['/*'])).to.be.equals(true); + expect(UserDTO.isDirectoryAvailable({path: '/', name: 'abc'}, ['/'])).to.be.equals(false); + expect(UserDTO.isDirectoryAvailable({path: '.\\', name: '.'}, ['/'])).to.be.equals(true); + expect(UserDTO.isDirectoryAvailable({path: '/', name: 'abc'}, ['/*', '/asdad'])).to.be.equals(true); }); diff --git a/test/e2e/app.e2e-spec.ts b/test/e2e/app.e2e-spec.ts index 68e409c..e52439d 100644 --- a/test/e2e/app.e2e-spec.ts +++ b/test/e2e/app.e2e-spec.ts @@ -1,4 +1,4 @@ -import {TestProjectPage} from "./app.po"; +import {TestProjectPage} from './app.po'; describe('test-project App', () => { let page: TestProjectPage; diff --git a/test/e2e/app.po.ts b/test/e2e/app.po.ts index 3edca35..f4eef22 100644 --- a/test/e2e/app.po.ts +++ b/test/e2e/app.po.ts @@ -1,4 +1,4 @@ -import {browser, by, element} from "protractor"; +import {browser, by, element} from 'protractor'; export class TestProjectPage { navigateTo() { diff --git a/tsconfig.json b/tsconfig.json index 348b3ae..51a61b1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,6 @@ { "compileOnSave": true, "compilerOptions": { - "skipLibCheck": true, "sourceMap": true, "declaration": false, "moduleResolution": "node", @@ -12,7 +11,7 @@ "node_modules/@types" ], "lib": [ - "es2016", + "es2017", "dom" ] } diff --git a/tslint.json b/tslint.json index dd117b3..9963d6c 100644 --- a/tslint.json +++ b/tslint.json @@ -11,11 +11,15 @@ "check-space" ], "curly": true, + "deprecation": { + "severity": "warn" + }, "eofline": true, "forin": true, "import-blacklist": [ true, - "rxjs" + "rxjs", + "rxjs/Rx" ], "import-spacing": true, "indent": [ @@ -31,8 +35,14 @@ "member-access": false, "member-ordering": [ true, - "static-before-instance", - "variables-before-functions" + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } ], "no-arg": true, "no-bitwise": true, @@ -80,6 +90,7 @@ ], "radix": true, "semicolon": [ + true, "always" ], "triple-equals": [ @@ -96,7 +107,6 @@ "variable-declaration": "nospace" } ], - "typeof-compare": true, "unified-signatures": true, "variable-name": false, "whitespace": [ @@ -119,6 +129,7 @@ "app", "kebab-case" ], + "no-output-on-prefix": true, "use-input-property-decorator": true, "use-output-property-decorator": true, "use-host-property-decorator": true, @@ -127,9 +138,6 @@ "use-life-cycle-interface": true, "use-pipe-transform-interface": true, "component-class-suffix": true, - "directive-class-suffix": true, - "no-access-missing-member": true, - "templates-use-public": true, - "invoke-injectable": true + "directive-class-suffix": true } }