Sanitize HTTP params on Export feature only once
MODIFY
src/server/rest/v1/service/ChargingStationService.ts
src/server/rest/v1/service/ChargingStationService.ts
import { Action, Entity } from '../../../../types/Authorization';
import ChargingStation, { ChargingStationOcppParameters, ChargingStationQRCode, Command, OCPPParams, OcppParameter, StaticLimitAmps } from '../../../../types/ChargingStation';
import { HTTPAuthError, HTTPError } from '../../../../types/HTTPError';
-import { HttpChargingStationChangeConfigurationRequest, HttpChargingStationGetCompositeScheduleRequest, HttpChargingStationStartTransactionRequest, HttpChargingStationStopTransactionRequest } from '../../../../types/requests/HttpChargingStationRequest';
+import { HttpChargingStationChangeConfigurationRequest, HttpChargingStationGetCompositeScheduleRequest, HttpChargingStationStartTransactionRequest, HttpChargingStationStopTransactionRequest, HttpChargingStationsRequest } from '../../../../types/requests/HttpChargingStationRequest';
import { NextFunction, Request, Response } from 'express';
import { OCPPChangeConfigurationResponse, OCPPConfigurationStatus, OCPPGetCompositeScheduleResponse, OCPPStatus, OCPPUnlockStatus } from '../../../../types/ocpp/OCPPClient';
@@ -934,7 +934,10 @@ export default class ChargingStationService {
}
public static async handleGetChargingStations(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- res.json(await ChargingStationService.getChargingStations(req));
+ // Filter
+ const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationsGetReq(req.query);
+ // Get Charging Stations
+ res.json(await ChargingStationService.getChargingStations(req, filteredRequest));
next();
}
@@ -942,8 +945,10 @@ export default class ChargingStationService {
// Always with site
req.query.WithSite = 'true';
req.query.WithSiteArea = 'true';
+ // Filter
+ const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationsGetReq(req.query);
// Get Charging Stations
- const chargingStations = await ChargingStationService.getChargingStations(req);
+ const chargingStations = await ChargingStationService.getChargingStations(req, filteredRequest);
for (const chargingStation of chargingStations.result) {
// Check all chargers
if (!await Authorizations.canExportParams(req.user, chargingStation.siteArea.siteID)) {
@@ -978,8 +983,12 @@ export default class ChargingStationService {
}
public static async handleExportChargingStations(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ // Force params
+ req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
+ // Filter
+ const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationsGetReq(req.query);
// Export
- await UtilsService.exportToCSV(req, res, 'exported-charging-stations.csv',
+ await UtilsService.exportToCSV(req, res, 'exported-charging-stations.csv', filteredRequest,
ChargingStationService.getChargingStations.bind(this),
ChargingStationService.convertToCSV.bind(this));
}
@@ -1398,7 +1407,7 @@ export default class ChargingStationService {
next();
}
- private static async getChargingStations(req: Request, projectFields?: string[]): Promise<DataResult<ChargingStation>> {
+ private static async getChargingStations(req: Request, filteredRequest: HttpChargingStationsRequest, projectFields?: string[]): Promise<DataResult<ChargingStation>> {
// Check auth
if (!await Authorizations.canListChargingStations(req.user)) {
throw new AppAuthError({
@@ -1408,8 +1417,6 @@ export default class ChargingStationService {
module: MODULE_NAME, method: 'getChargingStations',
});
}
- // Filter
- const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationsGetReq(req.query);
// Create GPS Coordinates
if (filteredRequest.LocLongitude && filteredRequest.LocLatitude) {
filteredRequest.LocCoordinates = [
@@ -1569,7 +1576,10 @@ export default class ChargingStationService {
}
private static async getChargingStationsForQrCode(req: Request): Promise<DataResult<ChargingStation>> {
- return ChargingStationService.getChargingStations(req, ['id', 'connectors.connectorId', 'siteArea.name']);
+ // Filter
+ const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationsGetReq(req.query);
+ // Get Charging Stations
+ return ChargingStationService.getChargingStations(req, filteredRequest, ['id', 'connectors.connectorId', 'siteArea.name']);
}
private static async convertQrCodeToPDF(req: Request, pdfDocument: PDFKit.PDFDocument, chargingStations: ChargingStation[]): Promise<void> {

MODIFY
src/server/rest/v1/service/LoggingService.ts
src/server/rest/v1/service/LoggingService.ts
@@ -4,6 +4,7 @@ import { NextFunction, Request, Response } from 'express';
import { Action } from '../../../../types/Authorization';
import AuthorizationService from './AuthorizationService';
import Constants from '../../../../utils/Constants';
+import { HttpLogsRequest } from '../../../../types/requests/HttpLoggingRequest';
import { Log } from '../../../../types/Log';
import LoggingStorage from '../../../../storage/mongodb/LoggingStorage';
import LoggingValidator from '../validator/LoggingValidator';
@@ -16,13 +17,20 @@ const MODULE_NAME = 'LoggingService';
export default class LoggingService {
public static async handleGetLogs(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- // Get logs
- res.json(await LoggingService.getLogs(req));
+ // Filter
+ const filteredRequest = LoggingValidator.getInstance().validateLoggingsGetReq(req.query);
+ // Get Logs
+ res.json(await LoggingService.getLogs(req, filteredRequest));
next();
}
public static async handleExportLogs(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- await UtilsService.exportToCSV(req, res, 'exported-logs.csv',
+ // Force params
+ req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
+ // Filter
+ const filteredRequest = LoggingValidator.getInstance().validateLoggingsGetReq(req.query);
+ // Export
+ await UtilsService.exportToCSV(req, res, 'exported-logs.csv', filteredRequest,
LoggingService.getLogs.bind(this),
LoggingService.convertToCSV.bind(this));
}
@@ -75,16 +83,14 @@ export default class LoggingService {
return Utils.isNullOrUndefined(headers) ? Constants.CR_LF + rows : [headers, rows].join(Constants.CR_LF);
}
- private static async getLogs(req: Request): Promise<DataResult<Log>> {
- // Filter
- const filteredRequest = LoggingValidator.getInstance().validateLoggingsGetReq(req.query);
+ private static async getLogs(req: Request, filteredRequest: HttpLogsRequest): Promise<DataResult<Log>> {
// Check dynamic auth
const authorizationSitesFilter = await AuthorizationService.checkAndGetLoggingsAuthorizations(
req.tenant, req.user, filteredRequest);
if (!authorizationSitesFilter.authorized) {
return Constants.DB_EMPTY_DATA_RESULT;
}
- // Get logs
+ // Get Logs
const logs = await LoggingStorage.getLogs(req.tenant, {
search: filteredRequest.Search,
startDateTime: filteredRequest.StartDateTime,

MODIFY
src/server/rest/v1/service/TagService.ts
src/server/rest/v1/service/TagService.ts
@@ -16,6 +16,7 @@ import Authorizations from '../../../../authorization/Authorizations';
import CSVError from 'csvtojson/v2/CSVError';
import Constants from '../../../../utils/Constants';
import EmspOCPIClient from '../../../../client/ocpi/EmspOCPIClient';
+import { HttpTagsRequest } from '../../../../types/requests/HttpTagRequest';
import { ImportedUser } from '../../../../types/User';
import JSONStream from 'JSONStream';
import LockingHelper from '../../../../locking/LockingHelper';
@@ -52,7 +53,10 @@ export default class TagService {
}
public static async handleGetTags(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- res.json(await TagService.getTags(req));
+ // Filter
+ const filteredRequest = TagValidator.getInstance().validateTagsGetReq(req.query);
+ // Get Tags
+ res.json(await TagService.getTags(req, filteredRequest));
next();
}
@@ -605,8 +609,12 @@ export default class TagService {
module: MODULE_NAME, method: 'handleImportTags'
});
}
- // Export with users
- await UtilsService.exportToCSV(req, res, 'exported-tags.csv',
+ // Force params
+ req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
+ // Filter
+ const filteredRequest = TagValidator.getInstance().validateTagsGetReq(req.query);
+ // Export
+ await UtilsService.exportToCSV(req, res, 'exported-tags.csv', filteredRequest,
TagService.getTags.bind(this),
TagService.convertToCSV.bind(this));
}
@@ -760,9 +768,7 @@ export default class TagService {
return Utils.isNullOrUndefined(headers) ? Constants.CR_LF + rows : [headers, rows].join(Constants.CR_LF);
}
- private static async getTags(req: Request): Promise<DataResult<Tag>> {
- // Filter
- const filteredRequest = TagValidator.getInstance().validateTagsGetReq(req.query);
+ private static async getTags(req: Request, filteredRequest: HttpTagsRequest): Promise<DataResult<Tag>> {
// Get authorization filters
const authorizationTagsFilters = await AuthorizationService.checkAndGetTagsAuthorizations(
req.tenant, req.user, filteredRequest);

MODIFY
src/server/rest/v1/service/TransactionService.ts
src/server/rest/v1/service/TransactionService.ts
@@ -16,6 +16,7 @@ import Constants from '../../../../utils/Constants';
import Consumption from '../../../../types/Consumption';
import ConsumptionStorage from '../../../../storage/mongodb/ConsumptionStorage';
import { DataResult } from '../../../../types/DataResult';
+import { HttpTransactionsRequest } from '../../../../types/requests/HttpTransactionRequest';
import LockingHelper from '../../../../locking/LockingHelper';
import LockingManager from '../../../../locking/LockingManager';
import Logging from '../../../../utils/Logging';
@@ -40,10 +41,11 @@ import moment from 'moment-timezone';
const MODULE_NAME = 'TransactionService';
export default class TransactionService {
-
public static async handleGetTransactions(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- // Get transactions
- const transactions = await TransactionService.getTransactions(req, action, {}, [
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
+ // Get Transactions
+ const transactions = await TransactionService.getTransactions(req, action, {}, filteredRequest, [
'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
'currentTotalDurationSecs', 'currentTotalInactivitySecs', 'currentInstantWatts', 'currentTotalConsumptionWh', 'currentStateOfCharge',
'currentCumulatedPrice', 'currentInactivityStatus', 'roundedPrice', 'price', 'priceUnit',
@@ -56,7 +58,7 @@ export default class TransactionService {
next();
}
- static async handleSynchronizeRefundedTransactions(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleSynchronizeRefundedTransactions(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
try {
if (!Authorizations.isAdmin(req.user)) {
throw new AppAuthError({
@@ -585,8 +587,10 @@ export default class TransactionService {
}
public static async handleGetChargingStationTransactions(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- // Get transaction
- const transactions = await TransactionService.getTransactions(req, action, {}, [
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
+ // Get Transactions
+ const transactions = await TransactionService.getTransactions(req, action, {}, filteredRequest, [
'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
'currentTotalDurationSecs', 'currentTotalInactivitySecs', 'currentInstantWatts', 'currentTotalConsumptionWh', 'currentStateOfCharge', 'currentInactivityStatus',
'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
@@ -611,7 +615,10 @@ export default class TransactionService {
public static async handleGetTransactionsActive(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
req.query.Status = 'active';
- const transactions = await TransactionService.getTransactions(req, action, {}, [
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
+ // Get Transactions
+ const transactions = await TransactionService.getTransactions(req, action, {}, filteredRequest, [
'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'status', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
'currentTotalDurationSecs', 'currentTotalInactivitySecs', 'currentInstantWatts', 'currentTotalConsumptionWh', 'currentStateOfCharge',
'currentCumulatedPrice', 'currentInactivityStatus', 'roundedPrice', 'price', 'priceUnit', 'tagID', 'tag.visualID', 'site.name', 'siteArea.name', 'company.name'
@@ -623,7 +630,10 @@ export default class TransactionService {
public static async handleGetTransactionsCompleted(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Get transaction
req.query.Status = 'completed';
- const transactions = await TransactionService.getTransactions(req, action, {}, [
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
+ // Get Transactions
+ const transactions = await TransactionService.getTransactions(req, action, {}, filteredRequest, [
'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
'stop.totalDurationSecs', 'stop.totalInactivitySecs', 'stop.extraInactivitySecs', 'stop.meterStop',
@@ -638,11 +648,13 @@ export default class TransactionService {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.REFUND,
Action.LIST, Entity.TRANSACTION, MODULE_NAME, 'handleGetTransactionsToRefund');
- // Only e-Mobility transactions
+ // Set filter
req.query.issuer = 'true';
- // Call
req.query.Status = 'completed';
- const transactions = await TransactionService.getTransactions(req, action, {}, [
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
+ // Get Transactions
+ const transactions = await TransactionService.getTransactions(req, action, {}, filteredRequest, [
'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
'refundData.reportId', 'refundData.refundedAt', 'refundData.status', 'site.name', 'siteArea.name', 'company.name',
'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
@@ -699,42 +711,30 @@ export default class TransactionService {
}
public static async handleExportTransactions(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ // Force params
+ req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
+ req.query.Status = 'completed';
+ req.query.WithTag = 'true';
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
// Export
- await UtilsService.exportToCSV(req, res, 'exported-sessions.csv',
+ await UtilsService.exportToCSV(req, res, 'exported-sessions.csv', filteredRequest,
TransactionService.getCompletedTransactionsToExport.bind(this),
TransactionService.convertToCSV.bind(this));
}
- public static async getCompletedTransactionsToExport(req: Request): Promise<DataResult<Transaction>> {
- // Get transaction
- req.query.Status = 'completed';
- req.query.WithTag = 'true';
- return TransactionService.getTransactions(req, ServerAction.TRANSACTIONS_EXPORT, {}, [
- 'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
- 'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
- 'stop.totalDurationSecs', 'stop.totalInactivitySecs', 'stop.extraInactivitySecs', 'site.name', 'siteArea.name', 'company.name',
- 'billingData.stop.invoiceNumber', 'stop.reason', 'ocpi', 'ocpiWithCdr', 'tagID', 'stop.tagID', 'tag.description', 'stop.tag.description', 'tag.visualID', 'stop.tag.visualID'
- ]);
- }
-
public static async handleExportTransactionsToRefund(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ // Force params
+ req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
+ req.query.Status = 'completed';
+ // Filter
+ const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
// Export
- await UtilsService.exportToCSV(req, res, 'exported-refund-sessions.csv',
+ await UtilsService.exportToCSV(req, res, 'exported-refund-sessions.csv', filteredRequest,
TransactionService.getRefundedTransactionsToExport.bind(this),
TransactionService.convertToCSV.bind(this));
}
- public static async getRefundedTransactionsToExport(req: Request): Promise<DataResult<Transaction>> {
- req.query.Status = 'completed';
- return TransactionService.getTransactions(req, ServerAction.TRANSACTIONS_TO_REFUND_EXPORT, {}, [
- 'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
- 'refundData.reportId', 'refundData.refundedAt', 'refundData.status', 'site.name', 'siteArea.name', 'company.name',
- 'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
- 'stop.totalDurationSecs', 'stop.totalInactivitySecs', 'stop.extraInactivitySecs',
- 'billingData.stop.invoiceNumber', 'stop.reason', 'tagID', 'stop.tagID',
- ]);
- }
-
public static async handleExportTransactionOcpiCdr(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check auth
if (!await Authorizations.canListTransactions(req.user)) {
@@ -970,8 +970,8 @@ export default class TransactionService {
return result;
}
- private static async getTransactions(req: Request, action: ServerAction,
- params: { completedTransactions?: boolean, withTag?: boolean } = {}, projectFields): Promise<DataResult<Transaction>> {
+ private static async getTransactions(req: Request, action: ServerAction, params: { completedTransactions?: boolean, withTag?: boolean } = {},
+ filteredRequest: HttpTransactionsRequest, projectFields): Promise<DataResult<Transaction>> {
// Check Transactions
if (!await Authorizations.canListTransactions(req.user)) {
throw new AppAuthError({
@@ -1006,8 +1006,6 @@ export default class TransactionService {
];
}
}
- // Filter
- const filteredRequest = TransactionValidator.getInstance().validateTransactionsGetReq(req.query);
// Build
const extrafilters: any = {};
if (filteredRequest.Status === 'completed') {
@@ -1062,4 +1060,25 @@ export default class TransactionService {
);
return transactions;
}
+
+ private static async getCompletedTransactionsToExport(req: Request, filteredRequest: HttpTransactionsRequest): Promise<DataResult<Transaction>> {
+ // Get Transactions
+ return TransactionService.getTransactions(req, ServerAction.TRANSACTIONS_EXPORT, {}, filteredRequest, [
+ 'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
+ 'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
+ 'stop.totalDurationSecs', 'stop.totalInactivitySecs', 'stop.extraInactivitySecs', 'site.name', 'siteArea.name', 'company.name',
+ 'billingData.stop.invoiceNumber', 'stop.reason', 'ocpi', 'ocpiWithCdr', 'tagID', 'stop.tagID', 'tag.description', 'stop.tag.description', 'tag.visualID', 'stop.tag.visualID'
+ ]);
+ }
+
+ private static async getRefundedTransactionsToExport(req: Request, filteredRequest: HttpTransactionsRequest): Promise<DataResult<Transaction>> {
+ // Get Transactions
+ return TransactionService.getTransactions(req, ServerAction.TRANSACTIONS_TO_REFUND_EXPORT, {}, filteredRequest, [
+ 'id', 'chargeBoxID', 'timestamp', 'issuer', 'stateOfCharge', 'timezone', 'connectorId', 'meterStart', 'siteAreaID', 'siteID', 'companyID',
+ 'refundData.reportId', 'refundData.refundedAt', 'refundData.status', 'site.name', 'siteArea.name', 'company.name',
+ 'stop.roundedPrice', 'stop.price', 'stop.priceUnit', 'stop.inactivityStatus', 'stop.stateOfCharge', 'stop.timestamp', 'stop.totalConsumptionWh',
+ 'stop.totalDurationSecs', 'stop.totalInactivitySecs', 'stop.extraInactivitySecs',
+ 'billingData.stop.invoiceNumber', 'stop.reason', 'tagID', 'stop.tagID',
+ ]);
+ }
}

MODIFY
src/server/rest/v1/service/UserService.ts
src/server/rest/v1/service/UserService.ts
@@ -19,6 +19,7 @@ import CSVError from 'csvtojson/v2/CSVError';
import CarStorage from '../../../../storage/mongodb/CarStorage';
import Constants from '../../../../utils/Constants';
import EmspOCPIClient from '../../../../client/ocpi/EmspOCPIClient';
+import { HttpUsersRequest } from '../../../../types/requests/HttpUserRequest';
import JSONStream from 'JSONStream';
import LockingHelper from '../../../../locking/LockingHelper';
import LockingManager from '../../../../locking/LockingManager';
@@ -306,7 +307,12 @@ export default class UserService {
}
public static async handleExportUsers(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- await UtilsService.exportToCSV(req, res, 'exported-users.csv',
+ // Force params
+ req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
+ // Filter
+ const filteredRequest = UserValidator.getInstance().validateUsersGetReq(req.query);
+ // Get Users
+ await UtilsService.exportToCSV(req, res, 'exported-users.csv', filteredRequest,
UserService.getUsers.bind(this),
UserService.convertToCSV.bind(this));
}
@@ -358,7 +364,10 @@ export default class UserService {
}
public static async handleGetUsers(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- res.json(await UserService.getUsers(req));
+ // Filter
+ const filteredRequest = UserValidator.getInstance().validateUsersGetReq(req.query);
+ // Get Users
+ res.json(await UserService.getUsers(req, filteredRequest));
next();
}
@@ -722,9 +731,7 @@ export default class UserService {
return Utils.isNullOrUndefined(headers) ? Constants.CR_LF + rows : [headers, rows].join(Constants.CR_LF);
}
- private static async getUsers(req: Request): Promise<DataResult<User>> {
- // Filter
- const filteredRequest = UserValidator.getInstance().validateUsersGetReq(req.query);
+ private static async getUsers(req: Request, filteredRequest: HttpUsersRequest): Promise<DataResult<User>> {
// Get authorization filters
const authorizationUsersFilters = await AuthorizationService.checkAndGetUsersAuthorizations(
req.tenant, req.user, filteredRequest);

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -1068,16 +1068,16 @@ export default class UtilsService {
}
}
- public static async exportToCSV(req: Request, res: Response, attachmentName: string,
- handleGetData: (req: Request) => Promise<DataResult<any>>,
+ public static async exportToCSV(req: Request, res: Response, attachmentName: string, filteredRequest: any,
+ handleGetData: (req: Request, filteredRequest: any) => Promise<DataResult<any>>,
handleConvertToCSV: (req: Request, data: any[], writeHeader: boolean) => string): Promise<void> {
- // Override
+ // Force params
req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
// Set the attachment name
res.attachment(attachmentName);
// Get the total number of Logs
req.query.OnlyRecordCount = 'true';
- let data = await handleGetData(req);
+ let data = await handleGetData(req, filteredRequest);
let count = data.count;
delete req.query.OnlyRecordCount;
let skip = 0;
@@ -1097,7 +1097,7 @@ export default class UtilsService {
}
// Get the data
req.query.Skip = skip.toString();
- data = await handleGetData(req);
+ data = await handleGetData(req, filteredRequest);
// Sanitize against csv formula injection
data.result = await Utils.sanitizeCSVExport(data.result, req.tenant?.id);
// Get CSV data

Sanitize HTTP params on Export feature only once