Added billing webhook/getone/getmany/download schemas + doc
ADD
src/assets/server/rest/v1/schemas/billing/billing-webhook.json
+{
+ "$id": "billing-webhook",
+ "title": "Billing webhook Request",
+ "type": "object",
+ "properties": {
+ "TenantID": {
+ "$ref": "common#/definitions/id"
+ }
+ },
+ "required": [
+ "TenantID"
+ ]
+}

ADD
src/assets/server/rest/v1/schemas/billing/invoice-get-by-id.json
+{
+ "$id": "invoice-get-by-id",
+ "title": "Get invoice by id Request",
+ "type": "object",
+ "properties": {
+ "ID": {
+ "$ref": "common#/definitions/id"
+ }
+ },
+ "required": [
+ "ID"
+ ]
+}

ADD
src/assets/server/rest/v1/schemas/billing/invoices-get.json
+{
+ "$id": "invoices-get",
+ "title": "Get invoices list Request",
+ "type": "object",
+ "properties": {
+ "UserID": {
+ "$ref": "common#/definitions/ids"
+ },
+ "Status": {
+ "type": "string",
+ "pattern": "^((paid|open|draft|void|uncollectible|deleted)(\\||paid|open|draft|void|uncollectible|deleted)*)?$",
+ "sanitize": "mongo"
+ },
+ "StartDateTime": {
+ "type": "string",
+ "format": "date-time",
+ "sanitize": "mongo"
+ },
+ "EndDateTime": {
+ "type": "string",
+ "format": "date-time",
+ "sanitize": "mongo"
+ },
+ "Search": {
+ "$ref": "common#/definitions/search"
+ },
+ "Limit": {
+ "$ref": "common#/definitions/limit"
+ },
+ "SortFields": {
+ "$ref": "common#/definitions/sortFields"
+ },
+ "Skip": {
+ "$ref": "common#/definitions/skip"
+ },
+ "OnlyRecordCount": {
+ "$ref": "common#/definitions/onlyRecordCount"
+ },
+ "ProjectFields": {
+ "$ref": "common#/definitions/projectFields"
+ }
+ },
+ "required": [
+ "Limit"
+ ]
+}

MODIFY
src/server/rest/v1/service/BillingService.ts
src/server/rest/v1/service/BillingService.ts
@@ -318,7 +318,7 @@ export default class BillingService {
userProject = [ 'userID', 'user.id', 'user.name', 'user.firstName', 'user.email' ];
}
// Filter
- const filteredRequest = BillingSecurity.filterGetInvoicesRequest(req.query);
+ const filteredRequest = BillingValidator.getInstance().validateBillingInvoicesGetReq(req.query);
// Get invoices
const invoices = await BillingStorage.getInvoices(req.tenant,
{
@@ -331,7 +331,7 @@ export default class BillingService {
{
limit: filteredRequest.Limit,
skip: filteredRequest.Skip,
- sort: filteredRequest.SortFields,
+ sort: UtilsService.httpSortFieldsToMongoDB(filteredRequest.SortFields),
onlyRecordCount: filteredRequest.OnlyRecordCount
},
[
@@ -347,7 +347,7 @@ export default class BillingService {
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
Action.LIST, Entity.INVOICE, MODULE_NAME, 'handleGetInvoice');
// Filter
- const filteredRequest = BillingSecurity.filterGetInvoiceRequest(req.query);
+ const filteredRequest = BillingValidator.getInstance().validateBillingInvoicesGetByIdReq(req.query);
UtilsService.assertIdIsProvided(action, filteredRequest.ID, MODULE_NAME, 'handleGetInvoice', req.user);
// Check Users
let userProject: string[] = [];
@@ -618,7 +618,7 @@ export default class BillingService {
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.BILLING,
Action.DOWNLOAD, Entity.BILLING, MODULE_NAME, 'handleDownloadInvoice');
// Filter
- const filteredRequest = BillingSecurity.filterDownloadInvoiceRequest(req.query);
+ const filteredRequest = BillingValidator.getInstance().validateBillingInvoicesGetByIdReq(req.query);
// Get the Invoice
const billingInvoice = await BillingStorage.getInvoice(req.tenant, filteredRequest.ID);
UtilsService.assertObjectExists(action, billingInvoice, `Invoice ID '${filteredRequest.ID}' does not exist`,
@@ -667,11 +667,11 @@ export default class BillingService {
// Check if component is active
// ?? How to do it in this context
// Filter
- const filteredRequest = BillingSecurity.filterBillingWebHookRequest(req.query);
+ const filteredRequest = BillingValidator.getInstance().validateBillingWebhookReq(req.query);
// Check Auth
// How to check it - no JWT!
// Retrieve Tenant ID from the URL Query Parameters
- if (!filteredRequest.tenantID) {
+ if (!filteredRequest.TenantID) {
throw new AppError({
errorCode: HTTPError.GENERAL_ERROR,
message: 'Unexpected situation - TenantID is not set',
@@ -680,13 +680,13 @@ export default class BillingService {
});
}
// Get Tenant
- const tenant = await TenantStorage.getTenant(filteredRequest.tenantID);
+ const tenant = await TenantStorage.getTenant(filteredRequest.TenantID);
if (!tenant) {
throw new AppError({
errorCode: HTTPError.GENERAL_ERROR,
action: action,
module: MODULE_NAME, method: 'handleBillingWebHook',
- message: `Tenant ID '${filteredRequest.tenantID}' does not exist!`
+ message: `Tenant ID '${filteredRequest.TenantID}' does not exist!`
});
}
const billingImpl = await BillingFactory.getBillingImpl(tenant);

MODIFY
src/server/rest/v1/service/security/BillingSecurity.ts
src/server/rest/v1/service/security/BillingSecurity.ts
@@ -65,7 +65,7 @@ export default class BillingSecurity {
static filterBillingWebHookRequest(requestQuery: any): HttpBillingWebHookRequest {
return {
- tenantID: sanitize(requestQuery.TenantID)
+ TenantID: sanitize(requestQuery.TenantID)
};
}

MODIFY
src/server/rest/v1/validator/BillingValidator.ts
src/server/rest/v1/validator/BillingValidator.ts
-import { HttpDeletePaymentMethod, HttpPaymentMethods } from '../../../../types/requests/HttpBillingRequest';
+import { HttpBillingInvoiceRequest, HttpBillingRequest, HttpBillingWebHookRequest, HttpDeletePaymentMethod, HttpPaymentMethods } from '../../../../types/requests/HttpBillingRequest';
import { BillingSettings } from '../../../../types/Setting';
import Schema from '../../../../types/validator/Schema';
@@ -12,6 +12,9 @@ export default class BillingValidator extends SchemaValidator {
private billingGetUserPaymentMethods: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/billing/billing-payment-methods-get.json`, 'utf8'));
private billingDeleteUserPaymentMethod: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/billing/billing-delete-payment-method.json`, 'utf8'));
private billingSetupUserPaymentMethod: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/billing/billing-setup-payment-method.json`, 'utf8'));
+ private billingInvoicesGet: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/billing/invoices-get.json`, 'utf8'));
+ private billingInvoiceGetByID: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/billing/invoice-get-by-id.json`, 'utf8'));
+ private billingWebhook: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/billing/billing-webhook.json`, 'utf8'));
private constructor() {
super('BillingValidator');
@@ -39,4 +42,16 @@ export default class BillingValidator extends SchemaValidator {
public validateBillingSetupUserPaymentMethodReq(data: Record<string, unknown>): HttpDeletePaymentMethod {
return this.validate(this.billingSetupUserPaymentMethod, data);
}
+
+ public validateBillingInvoicesGetReq(data: Record<string, unknown>): HttpBillingInvoiceRequest {
+ return this.validate(this.billingInvoicesGet, data);
+ }
+
+ public validateBillingInvoicesGetByIdReq(data: Record<string, unknown>): HttpBillingRequest {
+ return this.validate(this.billingInvoiceGetByID, data);
+ }
+
+ public validateBillingWebhookReq(data: Record<string, unknown>): HttpBillingWebHookRequest {
+ return this.validate(this.billingWebhook, data);
+ }
}

MODIFY
src/types/requests/HttpBillingRequest.ts
src/types/requests/HttpBillingRequest.ts
@@ -16,7 +16,7 @@ export interface HttpBillingInvoiceRequest extends HttpDatabaseRequest {
}
export interface HttpBillingWebHookRequest {
- tenantID?: string
+ TenantID?: string
}
export interface HttpSetupPaymentMethod {

Added billing webhook/getone/getmany/download schemas + doc