mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
implementing improved error handling
This commit is contained in:
parent
d591204740
commit
34c508073f
@ -37,8 +37,7 @@ export class AdminMWs {
|
|||||||
|
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error saving database settings", err);
|
return next(new Error(ErrorCodes.SETTINGS_ERROR, "Error saving database settings", err));
|
||||||
return next(new Error(ErrorCodes.SETTINGS_ERROR, err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +55,7 @@ export class AdminMWs {
|
|||||||
}
|
}
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error saving database settings", err);
|
return next(new Error(ErrorCodes.SETTINGS_ERROR, "Error saving database settings", err));
|
||||||
return next(new Error(ErrorCodes.SETTINGS_ERROR, err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import {SearchTypes} from "../../common/entities/AutoCompleteItem";
|
|||||||
import {ContentWrapper} from "../../common/entities/ConentWrapper";
|
import {ContentWrapper} from "../../common/entities/ConentWrapper";
|
||||||
import {PhotoDTO} from "../../common/entities/PhotoDTO";
|
import {PhotoDTO} from "../../common/entities/PhotoDTO";
|
||||||
import {ProjectPath} from "../ProjectPath";
|
import {ProjectPath} from "../ProjectPath";
|
||||||
import {Logger} from "../Logger";
|
|
||||||
import {Config} from "../../common/config/private/Config";
|
import {Config} from "../../common/config/private/Config";
|
||||||
import {UserDTO} from "../../common/entities/UserDTO";
|
import {UserDTO} from "../../common/entities/UserDTO";
|
||||||
|
|
||||||
@ -38,9 +37,7 @@ export class GalleryMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error during listing the directory", err);
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during listing the directory", err));
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,10 +108,7 @@ export class GalleryMWs {
|
|||||||
req.resultPipe = new ContentWrapper(null, result);
|
req.resultPipe = new ContentWrapper(null, result);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||||
Logger.warn(LOG_TAG, "Error during searching", err);
|
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,9 +128,7 @@ export class GalleryMWs {
|
|||||||
req.resultPipe = new ContentWrapper(null, result);
|
req.resultPipe = new ContentWrapper(null, result);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error during searching", err);
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,9 +144,7 @@ export class GalleryMWs {
|
|||||||
req.resultPipe = await ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text);
|
req.resultPipe = await ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error during searching", err);
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
22
backend/middlewares/NotificationMWs.ts
Normal file
22
backend/middlewares/NotificationMWs.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import {NextFunction, Request, Response} from "express";
|
||||||
|
import {UserRoles} from "../../common/entities/UserDTO";
|
||||||
|
import {NotificationManager} from "../model/NotifocationManager";
|
||||||
|
|
||||||
|
const LOG_TAG = "[NotificationMWs]";
|
||||||
|
export class NotificationMWs {
|
||||||
|
|
||||||
|
|
||||||
|
public static list(req: Request, res: Response, next: NextFunction) {
|
||||||
|
|
||||||
|
if (req.session.user.role >= UserRoles.Admin) {
|
||||||
|
req.resultPipe = NotificationManager.notifications;
|
||||||
|
} else if (NotificationManager.notifications.length > 0) {
|
||||||
|
|
||||||
|
req.resultPipe = NotificationManager.HasNotification;
|
||||||
|
} else {
|
||||||
|
req.resultPipe = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ import {Message} from "../../common/entities/Message";
|
|||||||
import {SharingDTO} from "../../common/entities/SharingDTO";
|
import {SharingDTO} from "../../common/entities/SharingDTO";
|
||||||
import {Config} from "../../common/config/private/Config";
|
import {Config} from "../../common/config/private/Config";
|
||||||
import {PrivateConfigClass} from "../../common/config/private/PrivateConfigClass";
|
import {PrivateConfigClass} from "../../common/config/private/PrivateConfigClass";
|
||||||
|
import {UserRoles} from "../../common/entities/UserDTO";
|
||||||
|
import {NotificationManager} from "../model/NotifocationManager";
|
||||||
|
|
||||||
export class RenderingMWs {
|
export class RenderingMWs {
|
||||||
|
|
||||||
@ -55,10 +57,15 @@ export class RenderingMWs {
|
|||||||
|
|
||||||
|
|
||||||
public static renderError(err: any, req: Request, res: Response, next: NextFunction): any {
|
public static renderError(err: any, req: Request, res: Response, next: NextFunction): any {
|
||||||
|
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
|
if (!(req.session.user && req.session.user.role >= UserRoles.Developer)) {
|
||||||
|
delete (err.details);
|
||||||
|
}
|
||||||
let message = new Message<any>(err, null);
|
let message = new Message<any>(err, null);
|
||||||
return res.json(message);
|
return res.json(message);
|
||||||
}
|
}
|
||||||
|
NotificationManager.error("unknown server error", err);
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import {NextFunction, Request, Response} from "express";
|
import {NextFunction, Request, Response} from "express";
|
||||||
import {CreateSharingDTO, SharingDTO} from "../../common/entities/SharingDTO";
|
import {CreateSharingDTO, SharingDTO} from "../../common/entities/SharingDTO";
|
||||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||||
import {Logger} from "../Logger";
|
|
||||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||||
|
|
||||||
const LOG_TAG = "[SharingMWs]";
|
const LOG_TAG = "[SharingMWs]";
|
||||||
@ -27,9 +26,7 @@ export class SharingMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error during retrieving sharing link", err);
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during retrieving sharing link", err));
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -71,9 +68,7 @@ export class SharingMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error during creating sharing link", err);
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during creating sharing link", err));
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,9 +95,7 @@ export class SharingMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "Error during creating sharing link", err);
|
return next(new Error(ErrorCodes.GENERAL_ERROR, "Error during creating sharing link", err));
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -162,8 +162,7 @@ export class ThumbnailGeneratorMWs {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
return next(new Error(ErrorCodes.THUMBNAIL_GENERATION_ERROR, "Error during generating thumbnail", error));
|
||||||
return next(new Error(ErrorCodes.THUMBNAIL_GENERATION_ERROR, error));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,7 @@ export class AuthenticationMWs {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND, null, err));
|
||||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
|
||||||
}
|
}
|
||||||
if (typeof req.session.user === 'undefined') {
|
if (typeof req.session.user === 'undefined') {
|
||||||
return next(new Error(ErrorCodes.NOT_AUTHENTICATED));
|
return next(new Error(ErrorCodes.NOT_AUTHENTICATED));
|
||||||
@ -109,11 +108,9 @@ export class AuthenticationMWs {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND, null, err));
|
||||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error(err);
|
|
||||||
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +125,7 @@ export class AuthenticationMWs {
|
|||||||
}
|
}
|
||||||
//not enough parameter
|
//not enough parameter
|
||||||
if ((!req.query.sk && !req.params.sharingKey)) {
|
if ((!req.query.sk && !req.params.sharingKey)) {
|
||||||
return next(new Error(ErrorCodes.INPUT_ERROR));
|
return next(new Error(ErrorCodes.INPUT_ERROR, "no sharing key provided"));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -151,7 +148,7 @@ export class AuthenticationMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export class UserMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ export class UserMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(new Error(ErrorCodes.USER_CREATION_ERROR));
|
return next(new Error(ErrorCodes.USER_CREATION_ERROR, null, err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ export class UserMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ export class UserMWs {
|
|||||||
return next();
|
return next();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ export class UserMWs {
|
|||||||
req.resultPipe = result;
|
req.resultPipe = result;
|
||||||
next();
|
next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR));
|
return next(new Error(ErrorCodes.GENERAL_ERROR, null, err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
backend/model/NotifocationManager.ts
Normal file
28
backend/model/NotifocationManager.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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."
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
public static error(message: string, details?: any) {
|
||||||
|
NotificationManager.notifications.push({
|
||||||
|
type: NotificationType.error,
|
||||||
|
message: message,
|
||||||
|
details: details
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static warning(message: string, details?: any) {
|
||||||
|
NotificationManager.notifications.push({
|
||||||
|
type: NotificationType.warning,
|
||||||
|
message: message,
|
||||||
|
details: details
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -19,10 +19,9 @@ export class ErrorRouter {
|
|||||||
|
|
||||||
private static addGenericHandler(app) {
|
private static addGenericHandler(app) {
|
||||||
app.use((err: any, req: Request, res: Response, next: Function) => {
|
app.use((err: any, req: Request, res: Response, next: Function) => {
|
||||||
|
|
||||||
//Flush out the stack to the console
|
//Flush out the stack to the console
|
||||||
Logger.error(err);
|
Logger.error("Unexpected error:", err);
|
||||||
next(new Error(ErrorCodes.SERVER_ERROR, "Unknown server side error"));
|
next(new Error(ErrorCodes.SERVER_ERROR, "Unknown server side error", err));
|
||||||
},
|
},
|
||||||
RenderingMWs.renderError
|
RenderingMWs.renderError
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import {NextFunction, Request, Response} from "express";
|
import {NextFunction, Request, Response} from "express";
|
||||||
import {Logger} from "../Logger";
|
import {Logger} from "../Logger";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds logging to express
|
||||||
|
*/
|
||||||
export class LoggerRouter {
|
export class LoggerRouter {
|
||||||
public static route(app: any) {
|
public static route(app: any) {
|
||||||
|
|
||||||
|
24
backend/routes/NotificationRouter.ts
Normal file
24
backend/routes/NotificationRouter.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
export class NotificationRouter {
|
||||||
|
public static route(app: any) {
|
||||||
|
|
||||||
|
this.addGetNotifications(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static addGetNotifications(app) {
|
||||||
|
app.get("/api/notifications",
|
||||||
|
AuthenticationMWs.authenticate,
|
||||||
|
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||||
|
NotificationMWs.list,
|
||||||
|
RenderingMWs.renderResult
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -16,6 +16,8 @@ import {LoggerRouter} from "./routes/LoggerRouter";
|
|||||||
import {ProjectPath} from "./ProjectPath";
|
import {ProjectPath} from "./ProjectPath";
|
||||||
import {ThumbnailGeneratorMWs} from "./middlewares/thumbnail/ThumbnailGeneratorMWs";
|
import {ThumbnailGeneratorMWs} from "./middlewares/thumbnail/ThumbnailGeneratorMWs";
|
||||||
import {DiskManager} from "./model/DiskManger";
|
import {DiskManager} from "./model/DiskManger";
|
||||||
|
import {NotificationRouter} from "./routes/NotificationRouter";
|
||||||
|
import {NotificationManager} from "./model/NotifocationManager";
|
||||||
|
|
||||||
const LOG_TAG = "[server]";
|
const LOG_TAG = "[server]";
|
||||||
export class Server {
|
export class Server {
|
||||||
@ -72,6 +74,7 @@ export class Server {
|
|||||||
GalleryRouter.route(this.app);
|
GalleryRouter.route(this.app);
|
||||||
SharingRouter.route(this.app);
|
SharingRouter.route(this.app);
|
||||||
AdminRouter.route(this.app);
|
AdminRouter.route(this.app);
|
||||||
|
NotificationRouter.route(this.app);
|
||||||
|
|
||||||
ErrorRouter.route(this.app);
|
ErrorRouter.route(this.app);
|
||||||
|
|
||||||
@ -99,6 +102,8 @@ export class Server {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.warn(LOG_TAG, "[MYSQL error]", err);
|
Logger.warn(LOG_TAG, "[MYSQL error]", err);
|
||||||
Logger.warn(LOG_TAG, "Error during initializing mysql falling back to memory DB");
|
Logger.warn(LOG_TAG, "Error during initializing mysql falling back to memory DB");
|
||||||
|
|
||||||
|
NotificationManager.warning("Error during initializing mysql falling back to memory DB", err);
|
||||||
Config.setDatabaseType(DatabaseType.memory);
|
Config.setDatabaseType(DatabaseType.memory);
|
||||||
await ObjectManagerRepository.InitMemoryManagers();
|
await ObjectManagerRepository.InitMemoryManagers();
|
||||||
}
|
}
|
||||||
@ -112,6 +117,9 @@ export class Server {
|
|||||||
sharp();
|
sharp();
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
NotificationManager.warning("Thumbnail hardware acceleration is not possible." +
|
||||||
|
" 'Sharp' node module is not found." +
|
||||||
|
" Falling back to JS based thumbnail generation", err);
|
||||||
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] sharp module error: ", err);
|
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] sharp module error: ", err);
|
||||||
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
||||||
" 'Sharp' node module is not found." +
|
" 'Sharp' node module is not found." +
|
||||||
@ -128,6 +136,9 @@ export class Server {
|
|||||||
if (!err) {
|
if (!err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
NotificationManager.warning("Thumbnail hardware acceleration is not possible." +
|
||||||
|
" 'gm' node module is not found." +
|
||||||
|
" Falling back to JS based thumbnail generation", err);
|
||||||
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] gm module error: ", err);
|
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] gm module error: ", err);
|
||||||
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
||||||
" 'gm' node module is not found." +
|
" 'gm' node module is not found." +
|
||||||
@ -136,6 +147,9 @@ export class Server {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
NotificationManager.warning("Thumbnail hardware acceleration is not possible." +
|
||||||
|
" 'gm' node module is not found." +
|
||||||
|
" Falling back to JS based thumbnail generation", err);
|
||||||
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] gm module error: ", err);
|
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] gm module error: ", err);
|
||||||
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
||||||
" 'gm' node module is not found." +
|
" 'gm' node module is not found." +
|
||||||
@ -147,12 +161,14 @@ export class Server {
|
|||||||
if (Config.Client.Search.searchEnabled == true &&
|
if (Config.Client.Search.searchEnabled == true &&
|
||||||
ObjectManagerRepository.getInstance().SearchManager.isSupported() == false) {
|
ObjectManagerRepository.getInstance().SearchManager.isSupported() == false) {
|
||||||
|
|
||||||
|
NotificationManager.warning("Search is not supported with these settings, switching off..");
|
||||||
Logger.warn(LOG_TAG, "Search is not supported with these settings, switching off..");
|
Logger.warn(LOG_TAG, "Search is not supported with these settings, switching off..");
|
||||||
Config.Client.Search.searchEnabled = false;
|
Config.Client.Search.searchEnabled = false;
|
||||||
}
|
}
|
||||||
if (Config.Client.Sharing.enabled == true &&
|
if (Config.Client.Sharing.enabled == true &&
|
||||||
ObjectManagerRepository.getInstance().SharingManager.isSupported() == false) {
|
ObjectManagerRepository.getInstance().SharingManager.isSupported() == false) {
|
||||||
|
|
||||||
|
NotificationManager.warning("Sharing is not supported with these settings, switching off..");
|
||||||
Logger.warn(LOG_TAG, "Sharing is not supported with these settings, switching off..");
|
Logger.warn(LOG_TAG, "Sharing is not supported with these settings, switching off..");
|
||||||
Config.Client.Sharing.enabled = false;
|
Config.Client.Sharing.enabled = false;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,6 @@ export enum ErrorCodes{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Error {
|
export class Error {
|
||||||
constructor(public code: ErrorCodes, public message?: string) {
|
constructor(public code: ErrorCodes, public message?: string, public details?: any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
common/entities/NotificationDTO.ts
Normal file
9
common/entities/NotificationDTO.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export enum NotificationType{
|
||||||
|
error, warning, info
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NotificationDTO {
|
||||||
|
type: NotificationType;
|
||||||
|
message: string;
|
||||||
|
details?: any;
|
||||||
|
}
|
@ -1,6 +1,27 @@
|
|||||||
<app-frame>
|
<app-frame>
|
||||||
<div body class="container">
|
<div body class="container">
|
||||||
<settings-usermanager *ngIf="userManagementEnable"></settings-usermanager>
|
|
||||||
<settings-database></settings-database>
|
<div class="panel panel-default" *ngIf="notificationService.notifications.length>0">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">Server notifications</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<ng-container *ngFor="let notification of notificationService.notifications">
|
||||||
|
|
||||||
|
<div class="alert alert-{{NotificationType[notification.type]}}" role="alert">
|
||||||
|
{{notification.message}}
|
||||||
|
<br *ngIf="notification.details"/>
|
||||||
|
{{notification.details | json}}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-footer">
|
||||||
|
To dismiss these notifications, restart the server.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<settings-usermanager *ngIf="userManagementEnable"></settings-usermanager>
|
||||||
|
<settings-database></settings-database>
|
||||||
|
</div>
|
||||||
</app-frame>
|
</app-frame>
|
||||||
|
@ -3,6 +3,8 @@ import {AuthenticationService} from "../model/network/authentication.service";
|
|||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {UserRoles} from "../../../common/entities/UserDTO";
|
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||||
import {Config} from "../../../common/config/public/Config";
|
import {Config} from "../../../common/config/public/Config";
|
||||||
|
import {NotificationService} from "../model/notification.service";
|
||||||
|
import {NotificationType} from "../../../common/entities/NotificationDTO";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'admin',
|
selector: 'admin',
|
||||||
templateUrl: './admin.component.html',
|
templateUrl: './admin.component.html',
|
||||||
@ -11,8 +13,13 @@ import {Config} from "../../../common/config/public/Config";
|
|||||||
export class AdminComponent implements OnInit {
|
export class AdminComponent implements OnInit {
|
||||||
userManagementEnable: boolean = false;
|
userManagementEnable: boolean = false;
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService, private _router: Router) {
|
NotificationType: any;
|
||||||
|
|
||||||
|
constructor(private _authService: AuthenticationService,
|
||||||
|
private _router: Router,
|
||||||
|
public notificationService: NotificationService) {
|
||||||
this.userManagementEnable = Config.Client.authenticationRequired;
|
this.userManagementEnable = Config.Client.authenticationRequired;
|
||||||
|
this.NotificationType = NotificationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -38,3 +38,9 @@ ng2-slim-loading-bar {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
margin-left: -5px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
@ -29,7 +29,9 @@
|
|||||||
<li *ngIf="isAdmin()">
|
<li *ngIf="isAdmin()">
|
||||||
<a style="cursor: pointer"
|
<a style="cursor: pointer"
|
||||||
class="admin-link"
|
class="admin-link"
|
||||||
[routerLink]="['/admin']"><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
[routerLink]="['/admin']">
|
||||||
|
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||||
|
<span *ngIf="notificationService.notifications.length>0" class="badge">{{notificationService.notifications.length}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="authenticationRequired">
|
<li *ngIf="authenticationRequired">
|
||||||
|
@ -4,6 +4,7 @@ import {AuthenticationService} from "../model/network/authentication.service";
|
|||||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||||
import {Config} from "../../../common/config/public/Config";
|
import {Config} from "../../../common/config/public/Config";
|
||||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||||
|
import {NotificationService} from "../model/notification.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-frame',
|
selector: 'app-frame',
|
||||||
@ -19,7 +20,8 @@ export class FrameComponent {
|
|||||||
public title: string;
|
public title: string;
|
||||||
isIn: boolean = false;
|
isIn: boolean = false;
|
||||||
|
|
||||||
constructor(private _authService: AuthenticationService) {
|
constructor(private _authService: AuthenticationService,
|
||||||
|
public notificationService: NotificationService) {
|
||||||
this.user = this._authService.user;
|
this.user = this._authService.user;
|
||||||
this.authenticationRequired = Config.Client.authenticationRequired;
|
this.authenticationRequired = Config.Client.authenticationRequired;
|
||||||
this.title = Config.Client.applicationTitle;
|
this.title = Config.Client.applicationTitle;
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import {Injectable, ViewContainerRef} from "@angular/core";
|
import {Injectable, ViewContainerRef} from "@angular/core";
|
||||||
import {ToastsManager} from "ng2-toastr/ng2-toastr";
|
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} from "../../../common/entities/UserDTO";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NotificationService {
|
export class NotificationService {
|
||||||
@ -8,9 +12,42 @@ export class NotificationService {
|
|||||||
positionClass: "toast-top-center",
|
positionClass: "toast-top-center",
|
||||||
animate: "flyLeft"
|
animate: "flyLeft"
|
||||||
};
|
};
|
||||||
|
notifications: NotificationDTO[] = [];
|
||||||
|
lastUser: UserDTO = null;
|
||||||
|
|
||||||
constructor(private _toastr: ToastsManager) {
|
constructor(private _toastr: ToastsManager,
|
||||||
|
private _networkService: NetworkService,
|
||||||
|
private _authService: AuthenticationService) {
|
||||||
|
|
||||||
|
this._authService.user.subscribe(() => {
|
||||||
|
if (this._authService.isAuthenticated() &&
|
||||||
|
(!this.lastUser ||
|
||||||
|
this.lastUser.id != this._authService.user.value.id)) {
|
||||||
|
this.getServerNotifications();
|
||||||
|
}
|
||||||
|
this.lastUser = this._authService.user.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getServerNotifications() {
|
||||||
|
this.notifications = await this._networkService.getJson<NotificationDTO[]>("/notifications");
|
||||||
|
this.notifications.forEach((noti) => {
|
||||||
|
let msg = noti.message;
|
||||||
|
if (noti.details) {
|
||||||
|
msg += " Details: " + JSON.stringify(noti.details);
|
||||||
|
}
|
||||||
|
switch (noti.type) {
|
||||||
|
case NotificationType.error:
|
||||||
|
this.error(msg, "Server error");
|
||||||
|
break;
|
||||||
|
case NotificationType.warning:
|
||||||
|
this.warning(msg, "Server error");
|
||||||
|
break;
|
||||||
|
case NotificationType.info:
|
||||||
|
this.info(msg, "Server info");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setRootViewContainerRef(vcr: ViewContainerRef) {
|
setRootViewContainerRef(vcr: ViewContainerRef) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user