mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-26 05:27:35 +02:00
Improving notification and CSRF error logging
This commit is contained in:
parent
3b82b71203
commit
b37d4ec8c8
@ -105,7 +105,7 @@ export class RenderingMWs {
|
||||
const message = new Message<any>(err, null);
|
||||
return res.json(message);
|
||||
}
|
||||
NotificationManager.error('Unknown server error', err);
|
||||
NotificationManager.error('Unknown server error', err, req);
|
||||
return next(err);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {NotificationDTO, NotificationType} from '../../common/entities/NotificationDTO';
|
||||
import {Request} from 'express';
|
||||
|
||||
export class NotificationManager {
|
||||
public static notifications: NotificationDTO[] = [];
|
||||
@ -11,19 +12,35 @@ export class NotificationManager {
|
||||
];
|
||||
|
||||
|
||||
public static error(message: string, details?: any) {
|
||||
NotificationManager.notifications.push({
|
||||
public static error(message: string, details?: any, req?: Request) {
|
||||
const noti: NotificationDTO = {
|
||||
type: NotificationType.error,
|
||||
message: message,
|
||||
details: details
|
||||
});
|
||||
};
|
||||
if (req) {
|
||||
noti.request = {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
statusCode: req.statusCode
|
||||
};
|
||||
}
|
||||
NotificationManager.notifications.push(noti);
|
||||
}
|
||||
|
||||
public static warning(message: string, details?: any) {
|
||||
NotificationManager.notifications.push({
|
||||
public static warning(message: string, details?: any, req?: Request) {
|
||||
const noti: NotificationDTO = {
|
||||
type: NotificationType.warning,
|
||||
message: message,
|
||||
details: details
|
||||
});
|
||||
};
|
||||
if (req) {
|
||||
noti.request = {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
statusCode: req.statusCode
|
||||
};
|
||||
}
|
||||
NotificationManager.notifications.push(noti);
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,18 @@ export class ErrorRouter {
|
||||
res.status(401);
|
||||
return next(new ErrorDTO(ErrorCodes.NOT_AUTHENTICATED, 'Invalid token'));
|
||||
}
|
||||
if (err.name === 'ForbiddenError' && err.code === 'EBADCSRFTOKEN') {
|
||||
// jwt authentication error
|
||||
res.status(401);
|
||||
return next(new ErrorDTO(ErrorCodes.NOT_AUTHENTICATED, 'Invalid CSRF token', err, req));
|
||||
}
|
||||
|
||||
console.log(err);
|
||||
|
||||
// Flush out the stack to the console
|
||||
Logger.error('Unexpected error:');
|
||||
console.error(err);
|
||||
return next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'Unknown server side error', err));
|
||||
return next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'Unknown server side error', err, req));
|
||||
},
|
||||
RenderingMWs.renderError
|
||||
);
|
||||
|
@ -1,3 +1,5 @@
|
||||
import {Request} from 'express';
|
||||
|
||||
export enum ErrorCodes {
|
||||
NOT_AUTHENTICATED = 1,
|
||||
ALREADY_AUTHENTICATED = 2,
|
||||
@ -25,9 +27,16 @@ export enum ErrorCodes {
|
||||
|
||||
export class ErrorDTO {
|
||||
public detailsStr: string;
|
||||
public request: {
|
||||
method: string, url: string
|
||||
} = {method: '', url: ''};
|
||||
|
||||
constructor(public code: ErrorCodes, public message?: string, public details?: any) {
|
||||
constructor(public code: ErrorCodes, public message?: string, public details?: any, req?: Request) {
|
||||
this.detailsStr = (this.details ? this.details.toString() : '') || ErrorCodes[code];
|
||||
this.request = {
|
||||
method: req.method,
|
||||
url: req.url
|
||||
};
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
@ -6,4 +6,9 @@ export interface NotificationDTO {
|
||||
type: NotificationType;
|
||||
message: string;
|
||||
details?: any;
|
||||
request?: {
|
||||
method: string,
|
||||
url: string,
|
||||
statusCode: number
|
||||
};
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ import {NotificationDTO, NotificationType} from '../../../common/entities/Notifi
|
||||
import {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
export interface CountedNotificationDTO extends NotificationDTO {
|
||||
count: number;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService {
|
||||
|
||||
@ -13,7 +17,8 @@ export class NotificationService {
|
||||
positionClass: 'toast-top-center',
|
||||
animate: 'flyLeft'
|
||||
};
|
||||
notifications: NotificationDTO[] = [];
|
||||
countedNotifications: CountedNotificationDTO[] = [];
|
||||
numberOfNotifications = 0;
|
||||
lastUser: UserDTO = null;
|
||||
|
||||
constructor(private _toastr: ToastrService,
|
||||
@ -36,11 +41,30 @@ export class NotificationService {
|
||||
return this._toastr;
|
||||
}
|
||||
|
||||
groupNotifications(notifications: NotificationDTO[]) {
|
||||
const groups: { [key: string]: { notification: NotificationDTO, count: number } } = {};
|
||||
notifications.forEach(n => {
|
||||
let key = n.message;
|
||||
if (n.details) {
|
||||
key += JSON.stringify(n.details);
|
||||
}
|
||||
groups[key] = groups[key] || {notification: n, count: 0};
|
||||
groups[key].count++;
|
||||
});
|
||||
this.numberOfNotifications = notifications.length;
|
||||
this.countedNotifications = [];
|
||||
for (const key of Object.keys(groups)) {
|
||||
(groups[key].notification as CountedNotificationDTO).count = groups[key].count;
|
||||
this.countedNotifications.push(groups[key].notification as CountedNotificationDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async getServerNotifications() {
|
||||
try {
|
||||
this.notifications = (await this._networkService.getJson<NotificationDTO[]>('/notifications')) || [];
|
||||
this.notifications.forEach((noti) => {
|
||||
let msg = noti.message;
|
||||
this.groupNotifications((await this._networkService.getJson<NotificationDTO[]>('/notifications')) || []);
|
||||
this.countedNotifications.forEach((noti) => {
|
||||
let msg = '(' + noti.count + ') ' + noti.message;
|
||||
if (noti.details) {
|
||||
msg += ' Details: ' + JSON.stringify(noti.details);
|
||||
}
|
||||
|
@ -12,17 +12,21 @@
|
||||
<app-frame>
|
||||
<div body class="container-fluid">
|
||||
|
||||
<div class="card mb-4" *ngIf="notificationService.notifications.length>0">
|
||||
<div class="card mb-4" *ngIf="notificationService.countedNotifications.length>0">
|
||||
<h5 class="card-header" i18n>
|
||||
Server notifications
|
||||
</h5>
|
||||
<div class="card-body">
|
||||
<ng-container *ngFor="let notification of notificationService.notifications">
|
||||
<ng-container *ngFor="let notification of notificationService.countedNotifications">
|
||||
|
||||
<div class="alert alert-{{getCss(notification.type)}}" role="alert">
|
||||
{{notification.message}}
|
||||
({{notification.count}}) {{notification.message}}
|
||||
<br *ngIf="notification.details"/>
|
||||
{{notification.details | json}}
|
||||
<ng-container *ngIf="notification.request">
|
||||
<br/>
|
||||
Request: "{{notification.request.method}}", url: "{{notification.request.url}}", status code: "{{notification.request.statusCode}}"
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
@ -40,7 +44,7 @@
|
||||
class="version"
|
||||
href="https://github.com/bpatrik/pigallery2/releases">
|
||||
<span
|
||||
i18n>App version:</span> <span>{{'v'+((settingsService.settings | async).Server.Environment.appVersion || '----')}}</span>
|
||||
i18n>App version:</span> <span>{{'v' + ((settingsService.settings | async).Server.Environment.appVersion || '----')}}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -38,8 +38,8 @@
|
||||
type="button" class="btn btn-dark dropdown-toggle"
|
||||
aria-controls="dropdown-alignment">
|
||||
<span class="oi oi-menu"></span>
|
||||
<span *ngIf="isAdmin() && notificationService.notifications.length>0"
|
||||
class="navbar-badge badge badge-warning">{{notificationService.notifications.length}}</span>
|
||||
<span *ngIf="isAdmin() && notificationService.numberOfNotifications>0"
|
||||
class="navbar-badge badge badge-warning">{{notificationService.numberOfNotifications}}</span>
|
||||
</button>
|
||||
<ul id="dropdown-alignment" *dropdownMenu
|
||||
class="dropdown-menu dropdown-menu-right"
|
||||
@ -54,8 +54,8 @@
|
||||
<li role="menuitem" *ngIf="isAdmin()">
|
||||
<a class="dropdown-item" [routerLink]="['/admin']">
|
||||
<span class="oi oi-wrench"></span>
|
||||
<span *ngIf="notificationService.notifications.length>0"
|
||||
class="badge">{{notificationService.notifications.length}}</span>
|
||||
<span *ngIf="notificationService.numberOfNotifications>0"
|
||||
class="badge">{{notificationService.numberOfNotifications}}</span>
|
||||
<ng-container i18n>Settings</ng-container>
|
||||
</a>
|
||||
</li>
|
||||
|
Loading…
x
Reference in New Issue
Block a user