Aligned authorization
MODIFY
src/authorization/Authorizations.ts
src/authorization/Authorizations.ts
@@ -496,7 +496,7 @@ export default class Authorizations {
}
public static canSynchronizeCarCatalogs(loggedUser: UserToken): boolean {
- return Authorizations.canPerformAction(loggedUser, Entity.CAR_CATALOGS, Action.SYNCHRONIZE_CAR_CATALOGS);
+ return Authorizations.canPerformAction(loggedUser, Entity.CAR_CATALOGS, Action.SYNCHRONIZE);
}
public static canCreateCar(loggedUser: UserToken): boolean {
@@ -582,27 +582,28 @@ export default class Authorizations {
}
public static canSynchronizeUsersBilling(loggedUser: UserToken): boolean {
- return Authorizations.canPerformAction(loggedUser, Entity.BILLING, Action.SYNCHRONIZE_USERS);
+ return Authorizations.canPerformAction(loggedUser, Entity.USERS, Action.SYNCHRONIZE_BILLING_USERS);
}
public static canSynchronizeUserBilling(loggedUser: UserToken): boolean {
- return Authorizations.canPerformAction(loggedUser, Entity.BILLING, Action.SYNCHRONIZE_USER);
+ return Authorizations.canPerformAction(loggedUser, Entity.USER, Action.SYNCHRONIZE_BILLING_USER);
}
public static canReadTaxesBilling(loggedUser: UserToken): boolean {
return Authorizations.canPerformAction(loggedUser, Entity.TAXES, Action.LIST);
}
- public static canReadInvoicesBilling(loggedUser: UserToken): boolean {
+ public static canListInvoicesBilling(loggedUser: UserToken): boolean {
return Authorizations.canPerformAction(loggedUser, Entity.INVOICES, Action.LIST);
}
public static canSynchronizeInvoicesBilling(loggedUser: UserToken): boolean {
- return Authorizations.canPerformAction(loggedUser, Entity.INVOICES, Action.SYNCHRONIZE_INVOICES);
+ return Authorizations.canPerformAction(loggedUser, Entity.INVOICES, Action.SYNCHRONIZE);
}
- public static canDownloadInvoiceBilling(loggedUser: UserToken): boolean {
- return Authorizations.canPerformAction(loggedUser, Entity.INVOICE, Action.DOWNLOAD);
+ public static canDownloadInvoiceBilling(loggedUser: UserToken, userId: string): boolean {
+ return Authorizations.canPerformAction(loggedUser, Entity.INVOICE, Action.DOWNLOAD,
+ { user: userId, owner: loggedUser.id });
}
public static canCheckAssetConnection(loggedUser: UserToken): boolean {

MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -19,14 +19,14 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{ resource: Entity.TENANTS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.TENANT, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE], attributes: ['*'] },
{ resource: Entity.CAR_CATALOGS, action: Action.LIST, attributes: ['*'] },
- { resource: Entity.CAR_CATALOGS, action: Action.SYNCHRONIZE_CAR_CATALOGS, attributes: ['*'] },
+ { resource: Entity.CAR_CATALOGS, action: Action.SYNCHRONIZE, attributes: ['*'] },
{ resource: Entity.CAR_CATALOG, action: Action.READ, attributes: ['*'] },
]
},
admin: {
grants: [
- { resource: Entity.USERS, action: Action.LIST, attributes: ['*'] },
- { resource: Entity.USER, action: [Action.CREATE, Action.READ, Action.UPDATE], attributes: ['*'] },
+ { resource: Entity.USERS, action: [Action.LIST, Action.SYNCHRONIZE_BILLING_USERS], attributes: ['*'] },
+ { resource: Entity.USER, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.SYNCHRONIZE_BILLING_USER], attributes: ['*'] },
{
resource: Entity.USER, action: Action.DELETE, attributes: ['*'],
condition: { Fn: 'NOT_EQUALS', args: { 'user': '$.owner' } }
@@ -59,12 +59,9 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{ resource: Entity.LOGGINGS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.LOGGING, action: Action.READ, attributes: ['*'] },
{ resource: Entity.PRICING, action: [Action.READ, Action.UPDATE], attributes: ['*'] },
- {
- resource: Entity.BILLING,
- action: [Action.CHECK_CONNECTION, Action.SYNCHRONIZE_USER, Action.SYNCHRONIZE_USERS]
- },
+ { resource: Entity.BILLING, action: [Action.CHECK_CONNECTION] },
{ resource: Entity.TAXES, action: [Action.LIST], attributes: ['*'] },
- { resource: Entity.INVOICES, action: [Action.LIST, Action.SYNCHRONIZE_INVOICES], attributes: ['*'] },
+ { resource: Entity.INVOICES, action: [Action.LIST, Action.SYNCHRONIZE], attributes: ['*'] },
{ resource: Entity.INVOICE, action: [Action.DOWNLOAD], attributes: ['*'] },
{ resource: Entity.ASSET, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE, Action.CHECK_CONNECTION, Action.RETRIEVE_CONSUMPTION], attributes: ['*'] },
{ resource: Entity.ASSETS, action: Action.LIST, attributes: ['*'] },
@@ -104,16 +101,19 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{ resource: Entity.CAR_CATALOGS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.CAR_CATALOG, action: Action.READ, attributes: ['*'] },
{ resource: Entity.CAR, action: Action.CREATE, attributes: ['*'] },
- { resource: Entity.CARS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.CAR, action: Action.UPDATE, attributes: ['*'] },
{ resource: Entity.CAR, action: Action.READ, attributes: ['*'] },
{ resource: Entity.CAR, action: Action.DELETE, attributes: ['*'] },
+ { resource: Entity.CARS, action: Action.LIST, attributes: ['*'] },
{
resource: Entity.COMPANY, action: Action.READ, attributes: ['*'],
condition: { Fn: 'LIST_CONTAINS', args: { 'companies': '$.company' } }
},
- { resource: Entity.INVOICES, action: [Action.LIST, Action.SYNCHRONIZE_INVOICES], attributes: ['*'] },
- { resource: Entity.INVOICE, action: [Action.DOWNLOAD], attributes: ['*'] },
+ { resource: Entity.INVOICES, action: [Action.LIST, Action.SYNCHRONIZE], attributes: ['*'] },
+ {
+ resource: Entity.INVOICE, action: [Action.DOWNLOAD], attributes: ['*'],
+ condition: { Fn: 'EQUALS', args: { 'user': '$.owner' } }
+ },
{ resource: Entity.SITES, action: Action.LIST, attributes: ['*'] },
{
resource: Entity.SITE, action: Action.READ, attributes: ['*'],

MODIFY
src/server/rest/CentralRestServerService.ts
src/server/rest/CentralRestServerService.ts
@@ -179,7 +179,7 @@ class RequestMapper {
[ServerAction.SETTING]: SettingService.handleGetSetting.bind(this),
[ServerAction.CHECK_BILLING_CONNECTION]: BillingService.handleCheckBillingConnection.bind(this),
[ServerAction.BILLING_TAXES]: BillingService.handleGetBillingTaxes.bind(this),
- [ServerAction.BILLING_USER_INVOICES]: BillingService.handleGetUserInvoices.bind(this),
+ [ServerAction.BILLING_INVOICES]: BillingService.handleGetInvoices.bind(this),
[ServerAction.BILLING_DOWNLOAD_INVOICE]: BillingService.handleDownloadInvoice.bind(this),
[ServerAction.OCPI_ENDPOINTS]: OCPIEndpointService.handleGetOcpiEndpoints.bind(this),
[ServerAction.OCPI_ENDPOINT]: OCPIEndpointService.handleGetOcpiEndpoint.bind(this),

MODIFY
src/server/rest/service/BillingService.ts
src/server/rest/service/BillingService.ts
@@ -72,13 +72,13 @@ export default class BillingService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- entity: Entity.USERS, action: Action.SYNCHRONIZE_USERS,
+ entity: Entity.USERS, action: Action.SYNCHRONIZE_BILLING_USERS,
module: MODULE_NAME, method: 'handleSynchronizeUsers',
});
}
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_USERS, Entity.BILLING, MODULE_NAME, 'handleSynchronizeUsers');
+ Action.SYNCHRONIZE_BILLING_USERS, Entity.USERS, MODULE_NAME, 'handleSynchronizeUsers');
const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
if (!billingImpl) {
throw new AppError({
@@ -125,13 +125,13 @@ export default class BillingService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- entity: Entity.USER, action: Action.SYNCHRONIZE_USER,
+ entity: Entity.USER, action: Action.SYNCHRONIZE_BILLING_USER,
module: MODULE_NAME, method: 'handleSynchronizeUser',
});
}
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_USERS, Entity.BILLING, MODULE_NAME, 'handleSynchronizeUser');
+ Action.SYNCHRONIZE_BILLING_USERS, Entity.USER, MODULE_NAME, 'handleSynchronizeUser');
const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
if (!billingImpl) {
throw new AppError({
@@ -178,13 +178,13 @@ export default class BillingService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- entity: Entity.USER, action: Action.SYNCHRONIZE_USER,
+ entity: Entity.USER, action: Action.SYNCHRONIZE_BILLING_USER,
module: MODULE_NAME, method: 'handleForceSynchronizeUser',
});
}
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_USER, Entity.BILLING, MODULE_NAME, 'handleForceSynchronizeUser');
+ Action.SYNCHRONIZE_BILLING_USER, Entity.USER, MODULE_NAME, 'handleForceSynchronizeUser');
const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
if (!billingImpl) {
throw new AppError({
@@ -276,42 +276,24 @@ export default class BillingService {
next();
}
- public static async handleGetUserInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleGetInvoices(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.LIST, Entity.INVOICES, MODULE_NAME, 'handleGetUserInvoices');
- if (!Authorizations.canReadInvoicesBilling(req.user)) {
+ Action.LIST, Entity.INVOICES, MODULE_NAME, 'handleGetInvoices');
+ if (!Authorizations.canListInvoicesBilling(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
entity: Entity.INVOICES, action: Action.LIST,
- module: MODULE_NAME, method: 'handleGetUserInvoices',
- });
- }
- // Get Billing implementation from factory
- const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
- if (!billingImpl) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'Billing service is not configured',
- module: MODULE_NAME, method: 'handleGetUserInvoices',
- action: action,
- user: req.user
+ module: MODULE_NAME, method: 'handleGetInvoices',
});
}
+ // Filter
const filteredRequest = BillingSecurity.filterGetUserInvoicesRequest(req.query);
- // Get user
- const billingUser = await billingImpl.getUserByEmail(req.user.email);
- UtilsService.assertObjectExists(action, billingUser, `Billing user with email '${req.user.email}' does not exist`,
- MODULE_NAME, 'handleGetUserInvoices', req.user);
- if (Authorizations.isBasic(req.user)) {
- filteredRequest.UserID = req.user.id;
- }
// Get invoices
const invoices = await BillingStorage.getInvoices(req.user.tenantID,
{
- userIDs: filteredRequest.UserID ? filteredRequest.UserID.split('|') : null,
+ userIDs: !Authorizations.isAdmin(req.user) ? [req.user.id] : (filteredRequest.UserID ? filteredRequest.UserID.split('|') : null),
invoiceStatus: filteredRequest.Status ? filteredRequest.Status.split('|') as BillingInvoiceStatus[] : null,
search: filteredRequest.Search ? filteredRequest.Search : null,
startDateTime: filteredRequest.StartDateTime ? filteredRequest.StartDateTime : null,
@@ -335,13 +317,22 @@ export default class BillingService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- entity: Entity.USER, action: Action.SYNCHRONIZE_INVOICES,
+ entity: Entity.INVOICES, action: Action.SYNCHRONIZE,
module: MODULE_NAME, method: 'handleSynchronizeInvoices',
});
}
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_INVOICES, Entity.BILLING, MODULE_NAME, 'handleSynchronizeInvoices');
+ Action.SYNCHRONIZE, Entity.INVOICES, MODULE_NAME, 'handleSynchronizeInvoices');
+ // Check user
+ let user: User;
+ if (!Authorizations.isAdmin(req.user)) {
+ // Get the User
+ user = await UserStorage.getUser(req.user.tenantID, req.user.id);
+ UtilsService.assertObjectExists(action, user, `User '${req.user.id}' does not exist`,
+ MODULE_NAME, 'handleSynchronizeUserInvoices', req.user);
+ }
+ // Get the billing impl
const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
if (!billingImpl) {
throw new AppError({
@@ -353,19 +344,11 @@ export default class BillingService {
user: req.user
});
}
- // Check user
- let user: User;
- if (Authorizations.isBasic(req.user)) {
- // Get the User
- user = await UserStorage.getUser(req.user.tenantID, req.user.id);
- UtilsService.assertObjectExists(action, user, `User '${req.user.id}' does not exist`,
- MODULE_NAME, 'handleSynchronizeUserInvoices', req.user);
- }
- // Get the Invoice lock
let synchronizeAction: BillingUserSynchronizeAction = {
inError: 0,
inSuccess: 0,
};
+ // Get the Invoice lock
const billingLock = await LockingHelper.createBillingSyncInvoicesLock(req.user.tenantID);
if (billingLock) {
try {
@@ -395,13 +378,13 @@ export default class BillingService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- entity: Entity.USER, action: Action.SYNCHRONIZE_INVOICES,
+ entity: Entity.INVOICES, action: Action.SYNCHRONIZE,
module: MODULE_NAME, method: 'handleForceSynchronizeUserInvoices',
});
}
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
- Action.SYNCHRONIZE_INVOICES, Entity.BILLING, MODULE_NAME, 'handleForceSynchronizeUserInvoices');
+ Action.SYNCHRONIZE, Entity.INVOICES, MODULE_NAME, 'handleForceSynchronizeUserInvoices');
const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
if (!billingImpl) {
throw new AppError({
@@ -451,8 +434,14 @@ export default class BillingService {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
Action.DOWNLOAD, Entity.BILLING, MODULE_NAME, 'handleDownloadInvoice');
+ // Filter
+ const filteredRequest = BillingSecurity.filterDownloadInvoiceRequest(req.query);
+ // Get the Invoice
+ const invoice = await BillingStorage.getInvoice(req.user.tenantID, filteredRequest.ID);
+ UtilsService.assertObjectExists(action, invoice, `Invoice ID '${filteredRequest.ID}' does not exist`,
+ MODULE_NAME, 'handleDownloadInvoice', req.user);
// Check Auth
- if (!Authorizations.canDownloadInvoiceBilling(req.user)) {
+ if (!Authorizations.canDownloadInvoiceBilling(req.user, invoice.userID)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
@@ -460,6 +449,7 @@ export default class BillingService {
module: MODULE_NAME, method: 'handleDownloadInvoice',
});
}
+ // Get the billing impl
const billingImpl = await BillingFactory.getBillingImpl(req.user.tenantID);
if (!billingImpl) {
throw new AppError({
@@ -471,20 +461,6 @@ export default class BillingService {
user: req.user
});
}
- const filteredRequest = BillingSecurity.filterDownloadInvoiceRequest(req.query);
- // Get the Invoice
- const invoice = await BillingStorage.getInvoice(req.user.tenantID, filteredRequest.ID);
- UtilsService.assertObjectExists(action, invoice, `Invoice ID '${filteredRequest.ID}' does not exist`,
- MODULE_NAME, 'handleDownloadInvoice', req.user);
- // Check if belonging to the logged user
- if (!Authorizations.isAdmin(req.user) && invoice.userID.toString() !== req.user.id) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.ERROR,
- user: req.user,
- entity: Entity.INVOICE, action: Action.DOWNLOAD,
- module: MODULE_NAME, method: 'handleDownloadInvoice',
- });
- }
// Get the Invoice Document
const invoiceDocument = await BillingStorage.getInvoiceDocument(req.user.tenantID, invoice.id);
UtilsService.assertObjectExists(action, invoiceDocument, `Invoice Document ID '${filteredRequest.ID}' does not exist`,

MODIFY
src/server/rest/service/CarService.ts
src/server/rest/service/CarService.ts
@@ -131,17 +131,15 @@ export default class CarService {
if (!Authorizations.isSuperAdmin(req.user)) {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.CAR,
- Action.SYNCHRONIZE_CAR_CATALOGS, Entity.CAR_CATALOGS, MODULE_NAME, 'handleSynchronizeCarCatalogs');
+ Action.SYNCHRONIZE, Entity.CAR_CATALOGS, MODULE_NAME, 'handleSynchronizeCarCatalogs');
}
// Check auth
if (!Authorizations.canSynchronizeCarCatalogs(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- action: Action.SYNCHRONIZE_CAR_CATALOGS,
- entity: Entity.CAR_CATALOGS,
- module: MODULE_NAME,
- method: 'handleSynchronizeCarCatalogs'
+ action: Action.SYNCHRONIZE, entity: Entity.CAR_CATALOGS,
+ module: MODULE_NAME, method: 'handleSynchronizeCarCatalogs'
});
}
const carDatabaseImpl = await CarFactory.getCarImpl();
@@ -149,8 +147,7 @@ export default class CarService {
throw new BackendError({
source: Constants.CENTRAL_SERVER,
message: 'Car service is not configured',
- module: MODULE_NAME,
- method: 'handleSynchronizeCarCatalogs'
+ module: MODULE_NAME, method: 'handleSynchronizeCarCatalogs'
});
}
const result = await carDatabaseImpl.synchronizeCarCatalogs();
@@ -169,10 +166,8 @@ export default class CarService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- action: Action.READ,
- entity: Entity.CAR_CATALOG,
- module: MODULE_NAME,
- method: 'handleGetCarMakers'
+ action: Action.READ, entity: Entity.CAR_CATALOG,
+ module: MODULE_NAME, method: 'handleGetCarMakers'
});
}
// Filter

MODIFY
src/server/rest/service/security/BillingSecurity.ts
src/server/rest/service/security/BillingSecurity.ts
@@ -63,7 +63,7 @@ export default class BillingSecurity {
return null;
}
// Check auth
- if (Authorizations.canReadInvoicesBilling(loggedUser)) {
+ if (Authorizations.canListInvoicesBilling(loggedUser)) {
// Set only necessary info
filteredInvoice.id = invoice.id;
filteredInvoice.invoiceID = invoice.invoiceID;

MODIFY
src/storage/mongodb/BillingStorage.ts
src/storage/mongodb/BillingStorage.ts
@@ -17,7 +17,7 @@ export default class BillingStorage {
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'getInvoice');
// Query single Site
const invoicesMDB = await BillingStorage.getInvoices(tenantID,
- { invoiceID: id },
+ { invoiceIDs: [id] },
Constants.DB_PARAMS_SINGLE_RECORD);
// Debug
Logging.traceEnd(MODULE_NAME, 'getInvoice', uniqueTimerID, { id });
@@ -38,7 +38,7 @@ export default class BillingStorage {
public static async getInvoices(tenantID: string,
params: {
- invoiceID?: string; billingInvoiceID?: string; search?: string; userIDs?: string[]; invoiceStatus?: BillingInvoiceStatus[];
+ invoiceIDs?: string[]; billingInvoiceID?: string; search?: string; userIDs?: string[]; invoiceStatus?: BillingInvoiceStatus[];
startDateTime?: Date; endDateTime?: Date;
} = {},
dbParams: DbParams, projectFields?: string[]): Promise<DataResult<BillingInvoice>> {
@@ -52,17 +52,17 @@ export default class BillingStorage {
const skip = Utils.checkRecordSkip(dbParams.skip);
// Search filters
const filters: any = {};
- // Filter by ID
- if (params.invoiceID) {
- filters._id = Utils.convertToObjectID(params.invoiceID);
// Filter by other properties
- } else if (params.search) {
+ if (params.search) {
filters.$or = [
{ 'number': { $regex: Utils.escapeSpecialCharsInRegex(params.search), $options: 'i' } }
];
}
// Create Aggregation
const aggregation = [];
+ if (params.invoiceIDs) {
+ filters._id = { $in: params.invoiceIDs.map((invoiceID) => Utils.convertToObjectID(invoiceID)) };
+ }
if (params.userIDs) {
filters.userID = { $in: params.userIDs.map((userID) => Utils.convertToObjectID(userID)) };
}
@@ -131,6 +131,8 @@ export default class BillingStorage {
DatabaseUtils.pushCreatedLastChangedInAggregation(tenantID, aggregation);
// Handle the ID
DatabaseUtils.pushRenameDatabaseID(aggregation);
+ // Convert Object ID to string
+ DatabaseUtils.pushConvertObjectIDToString(aggregation, 'userID');
// Project
DatabaseUtils.projectFields(aggregation, projectFields);
// Read DB

MODIFY
src/types/Authorization.ts
src/types/Authorization.ts
@@ -91,6 +91,7 @@ export enum Action {
RESET = 'Reset',
ASSIGN = 'Assign',
CLEAR_CACHE = 'ClearCache',
+ SYNCHRONIZE = 'Synchronize',
GET_CONFIGURATION = 'GetConfiguration',
CHANGE_CONFIGURATION = 'ChangeConfiguration',
SYNCHRONIZE_CAR_CATALOGS = 'SynchronizeCarCatalogs',
@@ -106,9 +107,8 @@ export enum Action {
EXPORT_PARAMS = 'ExportParams',
CHANGE_AVAILABILITY = 'ChangeAvailability',
REFUND_TRANSACTION = 'RefundTransaction',
- SYNCHRONIZE_USERS = 'SynchronizeUsers',
- SYNCHRONIZE_USER = 'SynchronizeUser',
- SYNCHRONIZE_INVOICES = 'SynchronizeInvoices',
+ SYNCHRONIZE_BILLING_USERS = 'SynchronizeBillingUsers',
+ SYNCHRONIZE_BILLING_USER = 'SynchronizeBillingUser',
CHECK_CONNECTION = 'CheckConnection',
RETRIEVE_CONSUMPTION = 'RetrieveConsumption',
PING = 'Ping',

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -339,7 +339,7 @@ export enum ServerAction {
BILLING_FORCE_SYNCHRONIZE_USER = 'BillingForceSynchronizeUser',
CHECK_BILLING_CONNECTION = 'CheckBillingConnection',
BILLING_TAXES = 'BillingTaxes',
- BILLING_USER_INVOICES = 'BillingUserInvoices',
+ BILLING_INVOICES = 'BillingUserInvoices',
BILLING_USER_INVOICE = 'BillingUserInvoice',
BILLING_SYNCHRONIZE_INVOICES = 'BillingSynchronizeInvoices',
BILLING_FORCE_SYNCHRONIZE_USER_INVOICES = 'BillingForceSynchronizeUserInvoices',

Aligned authorization