Reduce only needed HTTP params for User Send Error
MODIFY
src/assets/i18n/de.json
src/assets/i18n/de.json
},
"endUserErrorNotification": {
"title": "Ein Nutzer hat einen Fehler gemeldet",
- "body": "Der Nutzer '{{userName}}' hat foglenden Fehler: '{{errorTitle}}' mit der Beschreibung: '{{errorDescription}}' in Organisaion '{{tenantName}}' gemeldet"
+ "body": "'{{userName}}' hat foglenden Fehler: '{{errorTitle}}' - '{{errorDescription}}' in Organisaion '{{tenantName}}' gemeldet"
}
},
"billing": {

MODIFY
src/assets/i18n/en.json
src/assets/i18n/en.json
"body": "Unable to synchronize {{nbrInvoicesInError}} invoice(s) with the billing service provider in organization '{{tenantName}}'"
},
"endUserErrorNotification": {
- "title": "A User reported an error",
- "body": "The user '{{userName}}' reported the following error: '{{errorTitle}}' with the description: '{{errorDescription}}' in organization '{{tenantName}}'"
+ "title": "An user reported an error",
+ "body": "'{{userName}}' reported: '{{errorTitle}}' - '{{errorDescription}}' in organization '{{tenantName}}'"
}
},
"billing": {

MODIFY
src/assets/i18n/es.json
src/assets/i18n/es.json
"body": "Unable to synchronize {{nbrInvoicesInError}} invoice(s) with the billing service provider in organization '{{tenantName}}'"
},
"endUserErrorNotification": {
- "title": "A User reported an error",
- "body": "The user '{{userName}}' reported the following error: '{{errorTitle}}' with the description: '{{errorDescription}}' in organization '{{tenantName}}'"
+ "title": "An user reported an error",
+ "body": "'{{userName}}' reported: '{{errorTitle}}' - '{{errorDescription}}' in organization '{{tenantName}}'"
}
},
"billing": {

MODIFY
src/authorization/Authorizations.ts
src/authorization/Authorizations.ts
@@ -157,6 +157,7 @@ export default class Authorizations {
'id': user.id,
'role': user.role,
'name': user.name,
+ 'mobile': user.mobile,
'email': user.email,
'tagIDs': user.tags ? user.tags.filter((tag) => tag.active).map((tag) => tag.id) : [],
'firstName': user.firstName,

MODIFY
src/server/rest/service/NotificationService.ts
src/server/rest/service/NotificationService.ts
@@ -12,6 +12,7 @@ import Logging from '../../../utils/Logging';
import Utils from '../../../utils/Utils';
import NotificationSecurity from './security/NotificationSecurity';
import UtilsService from './UtilsService';
+import { EndUserErrorNotification } from '../../../types/UserNotifications';
const MODULE_NAME = 'NotificationService';
@@ -58,14 +59,25 @@ export default class NotificationService {
const user = await UserStorage.getUser(req.user.tenantID, req.user.id);
UtilsService.assertObjectExists(action, user, `User '${req.user.id}' does not exist`,
MODULE_NAME, 'handleEndUserErrorNotification', req.user);
+ // Save mobile number
+ if (filteredRequest.phone && (user.mobile !== filteredRequest.phone)) {
+ user.mobile = filteredRequest.phone;
+ await UserStorage.saveUserMobilePhone(req.user.tenantID, user.id, { mobile: filteredRequest.phone });
+ }
// Set
- filteredRequest.userID = req.user.id;
+ const endUserErrorNotification: EndUserErrorNotification = {
+ userID: user.id,
+ email: user.email,
+ phone: user.mobile,
+ name: Utils.buildUserFullName(user, false, false),
+ errorTitle: filteredRequest.errorTitle,
+ errorDescription: filteredRequest.errorDescription,
+ evseDashboardURL: Utils.buildEvseURL(),
+ };
// Check if Notification is valid
- Utils.checkIfEndUserErrorNotificationValid(filteredRequest, request);
- // Build URL
- filteredRequest.evseDashboardURL = Utils.buildEvseURL();
+ Utils.checkIfEndUserErrorNotificationValid(filteredRequest, req);
// Send Notification
- await NotificationHandler.sendEndUserErrorNotification(req.user.tenantID, filteredRequest);
+ await NotificationHandler.sendEndUserErrorNotification(req.user.tenantID, endUserErrorNotification);
// Ok
res.json(Constants.REST_RESPONSE_SUCCESS);
next();

MODIFY
src/server/rest/service/security/NotificationSecurity.ts
src/server/rest/service/security/NotificationSecurity.ts
+import sanitize from 'mongo-sanitize';
import Authorizations from '../../../../authorization/Authorizations';
import { DataResult } from '../../../../types/DataResult';
-import { EndUserErrorNotification } from '../../../../types/UserNotifications';
-import HttpDatabaseRequest from '../../../../types/requests/HttpDatabaseRequest';
+import { HttpEndUserErrorNotificationRequest, HttpNotificationRequest } from '../../../../types/requests/HttpNotificationRequest';
import { Notification } from '../../../../types/UserNotifications';
-import UserSecurity from './UserSecurity';
import UserToken from '../../../../types/UserToken';
+import UserSecurity from './UserSecurity';
import UtilsSecurity from './UtilsSecurity';
-import sanitize from 'mongo-sanitize';
-
-interface HttpNotificationRequest extends HttpDatabaseRequest {
- UserID: string;
- DateFrom: Date;
- Channel: string;
-}
export default class NotificationSecurity {
static filterNotificationsRequest(request: any): HttpNotificationRequest {
@@ -25,14 +18,12 @@ export default class NotificationSecurity {
return filteredRequest;
}
- static filterEndUserErrorNotificationRequest(request: any): EndUserErrorNotification {
- const filteredRequest = {
- email: sanitize(request.email),
- name: sanitize(request.name),
+ static filterEndUserErrorNotificationRequest(request: any): HttpEndUserErrorNotificationRequest {
+ const filteredRequest: HttpEndUserErrorNotificationRequest = {
errorTitle: sanitize(request.errorTitle),
errorDescription: sanitize(request.errorDescription),
phone: sanitize(request.phone),
- } as EndUserErrorNotification;
+ };
return filteredRequest;
}

MODIFY
src/storage/mongodb/UserStorage.ts
src/storage/mongodb/UserStorage.ts
@@ -375,6 +375,20 @@ export default class UserStorage {
Logging.traceEnd(MODULE_NAME, 'saveUserMobileToken', uniqueTimerID);
}
+ public static async saveUserMobilePhone(tenantID: string, userID: string,
+ params: { mobile?: string; phone?: string; }): Promise<void> {
+ // Debug
+ const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'saveUserMobilePhone');
+ // Check Tenant
+ await Utils.checkTenant(tenantID);
+ // Modify and return the modified document
+ await global.database.getCollection<any>(tenantID, 'users').findOneAndUpdate(
+ { '_id': Utils.convertToObjectID(userID) },
+ { $set: params });
+ // Debug
+ Logging.traceEnd(MODULE_NAME, 'saveUserMobilePhone', uniqueTimerID);
+ }
+
public static async saveUserRole(tenantID: string, userID: string, role: string): Promise<void> {
// Debug
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'saveUserRole');

MODIFY
src/types/UserToken.ts
src/types/UserToken.ts
@@ -4,6 +4,7 @@ export default interface UserToken {
role?: string;
name?: string;
email?: string;
+ mobile?: string;
firstName?: string;
locale?: string;
language?: string;

ADD
src/types/requests/HttpNotificationRequest.ts
+import HttpDatabaseRequest from './HttpDatabaseRequest';
+
+export interface HttpNotificationRequest extends HttpDatabaseRequest {
+ UserID: string;
+ DateFrom: Date;
+ Channel: string;
+}
+
+export interface HttpEndUserErrorNotificationRequest {
+ errorTitle: string;
+ errorDescription: string;
+ phone: string;
+}

MODIFY
src/utils/Utils.ts
src/utils/Utils.ts
@@ -32,6 +32,7 @@ import { ActionsResponse } from '../types/GlobalType';
import { HTTPError } from '../types/HTTPError';
import OCPIEndpoint from '../types/ocpi/OCPIEndpoint';
import { ChargePointStatus, OCPPProtocol, OCPPVersion } from '../types/ocpp/OCPPServer';
+import { HttpEndUserErrorNotificationRequest } from '../types/requests/HttpNotificationRequest';
import { ServerAction } from '../types/Server';
import { AnalyticsSettingsType, AssetSettingsType, BillingSettingsType, PricingSettingsType, RefundSettingsType, RoamingSettingsType, SettingDBContent, SmartChargingContentType } from '../types/Setting';
import Site from '../types/Site';
@@ -41,7 +42,6 @@ import Tenant from '../types/Tenant';
import TenantComponents from '../types/TenantComponents';
import Transaction, { InactivityStatus } from '../types/Transaction';
import User, { UserRole, UserStatus } from '../types/User';
-import { EndUserErrorNotification } from '../types/UserNotifications';
import UserToken from '../types/UserToken';
import Configuration from './Configuration';
import Constants from './Constants';
@@ -2049,30 +2049,12 @@ export default class Utils {
}
}
- public static checkIfEndUserErrorNotificationValid(endUserErrorNotificationValid: Partial<EndUserErrorNotification>, req: Request): void {
- if (!this._isUserEmailValid(endUserErrorNotificationValid.email)) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'E-Mail is invalid',
- module: MODULE_NAME, method: 'checkIfEndUserErrorNotificationValid',
- user: req.user.id
- });
- }
- if (!endUserErrorNotificationValid.name) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'User name is mandatory.',
- module: MODULE_NAME, method: 'checkIfEndUserErrorNotificationValid',
- user: req.user.id
- });
- }
+ public static checkIfEndUserErrorNotificationValid(endUserErrorNotificationValid: HttpEndUserErrorNotificationRequest, req: Request): void {
if (!endUserErrorNotificationValid.errorTitle || !endUserErrorNotificationValid.errorDescription) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
- message: 'Error Title and error description are mandatory.',
+ message: 'Error Title and Description are mandatory.',
module: MODULE_NAME, method: 'checkIfEndUserErrorNotificationValid',
user: req.user.id
});

Reduce only needed HTTP params for User Send Error