Get tenant logo with subdomain - Fix NPE in Billing settings
MODIFY
src/assets/server/rest/v1/schemas/tenant/tenant-create-req-super-admin.json
src/assets/server/rest/v1/schemas/tenant/tenant-create-req-super-admin.json
"title": "Create one Tenant",
"type": "object",
"properties": {
- "id": { "$ref": "common.json#/definitions/id" },
- "name": { "$ref": "common.json#/definitions/name"},
- "email": { "$ref": "common.json#/definitions/email" },
- "subdomain": { "$ref": "common.json#/definitions/subdomain" },
- "logo": { "$ref": "common.json#/definitions/logo" },
- "address": { "$ref": "common.json#/definitions/address" },
- "components": { "$ref": "tenant-components.json#/definitions/components" }
- },
- "required": ["name", "email", "subdomain"]
+ "id": {
+ "$ref": "common.json#/definitions/id"
+ },
+ "name": {
+ "$ref": "common.json#/definitions/name"
+ },
+ "email": {
+ "$ref": "common.json#/definitions/email"
+ },
+ "subdomain": {
+ "$ref": "common.json#/definitions/subdomain"
+ },
+ "logo": {
+ "$ref": "common.json#/definitions/logo"
+ },
+ "address": {
+ "$ref": "common.json#/definitions/address"
+ },
+ "components": {
+ "$ref": "tenant-components.json#/definitions/components"
+ }
+ },
+ "required": [
+ "name",
+ "email",
+ "subdomain"
+ ]
}

MODIFY
src/assets/server/rest/v1/schemas/tenant/tenant-delete-req-super-admin.json
src/assets/server/rest/v1/schemas/tenant/tenant-delete-req-super-admin.json
"title": "Delete one Tenants",
"type": "object",
"properties": {
- "ID": { "$ref": "common.json#/definitions/id" }
+ "ID": {
+ "$ref": "common.json#/definitions/id"
+ }
},
"required": [
"ID"

MODIFY
src/assets/server/rest/v1/schemas/tenant/tenant-get-logo-req-super-admin.json
src/assets/server/rest/v1/schemas/tenant/tenant-get-logo-req-super-admin.json
"title": "Get one Tenant Logo",
"type": "object",
"properties": {
- "ID": { "$ref": "common.json#/definitions/id" }
+ "ID": {
+ "$ref": "common.json#/definitions/id"
},
- "required": [
- "ID"
- ]
+ "Subdomain": {
+ "type": "string",
+ "sanitize": "mongo"
+ }
+ }
}

MODIFY
src/assets/server/rest/v1/schemas/tenant/tenant-get-req-super-admin.json
src/assets/server/rest/v1/schemas/tenant/tenant-get-req-super-admin.json
"title": "Get one Tenants",
"type": "object",
"properties": {
- "ID": { "$ref": "common.json#/definitions/id" }
+ "ID": {
+ "$ref": "common.json#/definitions/id"
+ }
},
"required": [
"ID"

MODIFY
src/assets/server/rest/v1/schemas/tenant/tenant-update-req-super-admin.json
src/assets/server/rest/v1/schemas/tenant/tenant-update-req-super-admin.json
"title": "Update one Tenant",
"type": "object",
"properties": {
- "id": { "$ref": "common.json#/definitions/id" },
- "name": { "$ref": "common.json#/definitions/name"},
- "email": { "$ref": "common.json#/definitions/email" },
- "subdomain": { "$ref": "common.json#/definitions/subdomain" },
- "logo": { "$ref": "common.json#/definitions/logo" },
- "address": { "$ref": "common.json#/definitions/address" },
- "components": { "$ref": "tenant-components.json#/definitions/components" }
- },
- "required": ["id", "name", "email", "subdomain"]
+ "id": {
+ "$ref": "common.json#/definitions/id"
+ },
+ "name": {
+ "$ref": "common.json#/definitions/name"
+ },
+ "email": {
+ "$ref": "common.json#/definitions/email"
+ },
+ "subdomain": {
+ "$ref": "common.json#/definitions/subdomain"
+ },
+ "logo": {
+ "$ref": "common.json#/definitions/logo"
+ },
+ "address": {
+ "$ref": "common.json#/definitions/address"
+ },
+ "components": {
+ "$ref": "tenant-components.json#/definitions/components"
+ }
+ },
+ "required": [
+ "id",
+ "name",
+ "email",
+ "subdomain"
+ ]
}

MODIFY
src/assets/server/rest/v1/schemas/tenant/tenants-get-req-super-admin.json
src/assets/server/rest/v1/schemas/tenant/tenants-get-req-super-admin.json
"title": "Get all the Tenants",
"type": "object",
"properties": {
- "Search": { "$ref": "common.json#/definitions/search" },
- "WithLogo": { "type": "boolean", "sanitize": "mongo" },
- "WithComponents": { "type": "boolean", "sanitize": "mongo" },
- "Limit": { "$ref": "common.json#/definitions/limit" },
- "SortFields": { "$ref": "common.json#/definitions/sortFields" }
+ "Search": {
+ "$ref": "common.json#/definitions/search"
+ },
+ "WithLogo": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ },
+ "WithComponents": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ },
+ "Limit": {
+ "$ref": "common.json#/definitions/limit"
+ },
+ "SortFields": {
+ "$ref": "common.json#/definitions/sortFields"
+ }
}
}

MODIFY
src/server/rest/v1/service/TenantService.ts
src/server/rest/v1/service/TenantService.ts
@@ -2,6 +2,7 @@ import { Action, Entity } from '../../../../types/Authorization';
import { HTTPAuthError, HTTPError } from '../../../../types/HTTPError';
import { NextFunction, Request, Response } from 'express';
import { SettingDB, SettingDBContent } from '../../../../types/Setting';
+import Tenant, { TenantLogo } from '../../../../types/Tenant';
import User, { UserRole } from '../../../../types/User';
import AppAuthError from '../../../../exception/AppAuthError';
@@ -16,7 +17,6 @@ import { ServerAction } from '../../../../types/Server';
import SettingStorage from '../../../../storage/mongodb/SettingStorage';
import SiteAreaStorage from '../../../../storage/mongodb/SiteAreaStorage';
import { StatusCodes } from 'http-status-codes';
-import Tenant from '../../../../types/Tenant';
import TenantStorage from '../../../../storage/mongodb/TenantStorage';
import TenantValidator from '../validator/TenantValidation';
import UserStorage from '../../../../storage/mongodb/UserStorage';
@@ -75,11 +75,19 @@ export default class TenantService {
public static async handleGetTenantLogo(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Validate
- const tenantID = TenantValidator.getInstance().validateGetLogoReqSuperAdmin(req.query);
- UtilsService.assertIdIsProvided(action, tenantID, MODULE_NAME, 'handleGetTenantLogo', req.user);
+ const filteredRequest = TenantValidator.getInstance().validateGetLogoReqSuperAdmin(req.query);
// Get Logo
- const tenantLogo = await TenantStorage.getTenantLogo(tenantID);
- // Return
+ let tenantLogo: TenantLogo;
+ // Get the logo using ID
+ if (filteredRequest.ID) {
+ tenantLogo = await TenantStorage.getTenantLogo(filteredRequest.ID);
+ // Get the logo using Subdomain
+ } else if (filteredRequest.Subdomain) {
+ const tenant = await TenantStorage.getTenantBySubdomain(filteredRequest.Subdomain, ['id']);
+ if (tenant) {
+ tenantLogo = await TenantStorage.getTenantLogo(tenant.id);
+ }
+ }
if (tenantLogo?.logo) {
let header = 'image';
let encoding: BufferEncoding = 'base64';

MODIFY
src/server/rest/v1/validator/TenantValidation.ts
src/server/rest/v1/validator/TenantValidation.ts
+import { HttpTenantLogoRequest, HttpTenantsRequest } from '../../../../types/requests/HttpTenantRequest';
+
import AppError from '../../../../exception/AppError';
import Constants from '../../../../utils/Constants';
import { HTTPError } from '../../../../types/HTTPError';
-import { HttpTenantsRequest } from '../../../../types/requests/HttpTenantRequest';
import SchemaValidator from './SchemaValidator';
import Tenant from '../../../../types/Tenant';
import UtilsService from '../service/UtilsService';
@@ -50,28 +51,28 @@ export default class TenantValidator extends SchemaValidator {
return tenant;
}
- public validateTenantDeleteRequestSuperAdmin(request: any): string {
+ public validateTenantDeleteRequestSuperAdmin(data: any): string {
// Validate schema
- this.validate(this._tenantDeleteReqSuperAdmin, request);
- return request.ID;
+ this.validate(this._tenantDeleteReqSuperAdmin, data);
+ return data.ID;
}
- public validateGetLogoReqSuperAdmin(request: any): string {
+ public validateGetLogoReqSuperAdmin(data: any): HttpTenantLogoRequest {
// Validate schema
- this.validate(this._tenantGetLogoReqSuperAdmin, request);
- return request.ID;
+ this.validate(this._tenantGetLogoReqSuperAdmin, data);
+ return data;
}
- public validateTenantGetReqSuperAdmin(request: any): string {
+ public validateTenantGetReqSuperAdmin(data: any): string {
// Validate schema
- this.validate(this._tenantGetReqSuperAdmin, request);
- return request.ID;
+ this.validate(this._tenantGetReqSuperAdmin, data);
+ return data.ID;
}
- public validateTenantsGetReqSuperAdmin(request: any): HttpTenantsRequest {
+ public validateTenantsGetReqSuperAdmin(data: any): HttpTenantsRequest {
// Validate schema
- this.validate(this._tenantsGetReqSuperAdmin, request);
- return request;
+ this.validate(this._tenantsGetReqSuperAdmin, data);
+ return data;
}
private validateComponentDependencies(tenant: Tenant) {

MODIFY
src/storage/mongodb/SettingStorage.ts
src/storage/mongodb/SettingStorage.ts
@@ -15,15 +15,16 @@ const MODULE_NAME = 'SettingStorage';
export default class SettingStorage {
public static async getSetting(tenantID: string, id: string = Constants.UNKNOWN_OBJECT_ID, projectFields?: string[]): Promise<SettingDB> {
- const settingMDB = await SettingStorage.getSettings(tenantID, {
- settingID: id
- }, Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
+ const settingMDB = await SettingStorage.getSettings(tenantID,
+ { settingID: id },
+ Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
return settingMDB.count === 1 ? settingMDB.result[0] : null;
}
public static async getSettingByIdentifier(tenantID: string, identifier: string = Constants.UNKNOWN_STRING_ID, projectFields?: string[]): Promise<SettingDB> {
- const settingsMDB = await SettingStorage.getSettings(
- tenantID, { identifier: identifier }, Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
+ const settingsMDB = await SettingStorage.getSettings(tenantID,
+ { identifier: identifier },
+ Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
return settingsMDB.count === 1 ? settingsMDB.result[0] : null;
}
@@ -73,7 +74,9 @@ export default class SettingStorage {
identifier: TenantComponents.OCPI,
} as RoamingSettings;
// Get the Ocpi settings
- const settings = await SettingStorage.getSettings(tenantID, { identifier: TenantComponents.OCPI }, Constants.DB_PARAMS_MAX_LIMIT);
+ const settings = await SettingStorage.getSettings(tenantID,
+ { identifier: TenantComponents.OCPI },
+ Constants.DB_PARAMS_MAX_LIMIT);
if (settings && settings.count > 0 && settings.result[0].content) {
const config = settings.result[0].content;
// ID
@@ -92,7 +95,9 @@ export default class SettingStorage {
identifier: TenantComponents.ANALYTICS,
} as AnalyticsSettings;
// Get the analytics settings
- const settings = await SettingStorage.getSettings(tenantID, { identifier: TenantComponents.ANALYTICS }, Constants.DB_PARAMS_MAX_LIMIT);
+ const settings = await SettingStorage.getSettings(tenantID,
+ { identifier: TenantComponents.ANALYTICS },
+ Constants.DB_PARAMS_MAX_LIMIT);
if (settings && settings.count > 0 && settings.result[0].content) {
const config = settings.result[0].content;
analyticsSettings.id = settings.result[0].id;
@@ -114,7 +119,9 @@ export default class SettingStorage {
identifier: TenantComponents.ASSET,
} as AssetSettings;
// Get the settings
- const settings = await SettingStorage.getSettings(tenantID, { identifier: TenantComponents.ASSET }, Constants.DB_PARAMS_MAX_LIMIT);
+ const settings = await SettingStorage.getSettings(tenantID,
+ { identifier: TenantComponents.ASSET },
+ Constants.DB_PARAMS_MAX_LIMIT);
if (settings && settings.count > 0 && settings.result[0].content) {
const config = settings.result[0].content;
assetSettings.id = settings.result[0].id;
@@ -134,7 +141,9 @@ export default class SettingStorage {
const refundSettings = {
identifier: TenantComponents.REFUND
} as RefundSettings;
- const settings = await SettingStorage.getSettings(tenantID, { identifier: TenantComponents.REFUND }, Constants.DB_PARAMS_MAX_LIMIT);
+ const settings = await SettingStorage.getSettings(tenantID,
+ { identifier: TenantComponents.REFUND },
+ Constants.DB_PARAMS_MAX_LIMIT);
if (settings && settings.count > 0 && settings.result[0].content) {
const config = settings.result[0].content;
refundSettings.id = settings.result[0].id;
@@ -162,10 +171,9 @@ export default class SettingStorage {
identifier: TenantComponents.PRICING,
} as PricingSettings;
// Get the Pricing settings
- const settings = await SettingStorage.getSettings(tenantID, { identifier: TenantComponents.PRICING, dateFrom: dateFrom, dateTo: dateTo }, {
- limit,
- skip
- });
+ const settings = await SettingStorage.getSettings(tenantID,
+ { identifier: TenantComponents.PRICING, dateFrom: dateFrom, dateTo: dateTo },
+ { limit, skip });
// Get the currency
if (settings && settings.count > 0 && settings.result[0].content) {
const config = settings.result[0].content;
@@ -253,10 +261,11 @@ export default class SettingStorage {
const billingSettings = {
identifier: TenantComponents.BILLING,
} as BillingSettings;
- const settings = await SettingStorage.getSettings(tenantID, { identifier: TenantComponents.BILLING }, Constants.DB_PARAMS_MAX_LIMIT);
- const config = settings.result[0].content;
+ const settings = await SettingStorage.getSettings(tenantID,
+ { identifier: TenantComponents.BILLING },
+ Constants.DB_PARAMS_MAX_LIMIT);
if (settings && settings.count > 0 && settings.result[0].content) {
- // ID
+ const config = settings.result[0].content;
billingSettings.id = settings.result[0].id;
billingSettings.sensitiveData = settings.result[0].sensitiveData;
// Currency

MODIFY
src/storage/mongodb/TenantStorage.ts
src/storage/mongodb/TenantStorage.ts
+import Tenant, { TenantLogo } from '../../types/Tenant';
import global, { FilterParams } from '../../types/GlobalType';
import BackendError from '../../exception/BackendError';
@@ -7,7 +8,6 @@ import DatabaseUtils from './DatabaseUtils';
import DbParams from '../../types/database/DbParams';
import Logging from '../../utils/Logging';
import { ObjectID } from 'mongodb';
-import Tenant from '../../types/Tenant';
import Utils from '../../utils/Utils';
const MODULE_NAME = 'TenantStorage';
@@ -42,17 +42,17 @@ export default class TenantStorage {
return tenant;
}
- public static async getTenantByName(name: string): Promise<Tenant> {
+ public static async getTenantByName(name: string, projectFields?: string[]): Promise<Tenant> {
const tenantsMDB = await TenantStorage.getTenants({
tenantName: name
- }, Constants.DB_PARAMS_SINGLE_RECORD);
+ }, Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
return tenantsMDB.count === 1 ? tenantsMDB.result[0] : null;
}
- public static async getTenantBySubdomain(subdomain: string): Promise<Tenant> {
+ public static async getTenantBySubdomain(subdomain: string, projectFields?: string[]): Promise<Tenant> {
const tenantsMDB = await TenantStorage.getTenants({
tenantSubdomain: subdomain
- }, Constants.DB_PARAMS_SINGLE_RECORD);
+ }, Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
return tenantsMDB.count === 1 ? tenantsMDB.result[0] : null;
}
@@ -264,7 +264,7 @@ export default class TenantStorage {
Logging.traceEnd(Constants.DEFAULT_TENANT, MODULE_NAME, 'deleteTenantDB', uniqueTimerID, { id });
}
- public static async getTenantLogo(tenantID: string): Promise<{ id: string; logo: string }> {
+ public static async getTenantLogo(tenantID: string): Promise<TenantLogo> {
// Debug
const uniqueTimerID = Logging.traceStart(tenantID, MODULE_NAME, 'getTenantLogo');
// Check Tenant

MODIFY
src/types/Tenant.ts
src/types/Tenant.ts
@@ -50,3 +50,8 @@ export default interface Tenant extends CreatedUpdatedProps {
};
};
}
+
+export interface TenantLogo {
+ id: string;
+ logo: string;
+}

MODIFY
src/types/requests/HttpTenantRequest.ts
src/types/requests/HttpTenantRequest.ts
@@ -9,3 +9,8 @@ export interface HttpTenantsRequest extends HttpDatabaseRequest {
WithLogo?: boolean;
WithComponents?: boolean;
}
+
+export interface HttpTenantLogoRequest {
+ ID?: string;
+ Subdomain?: string;
+}

Get tenant logo with subdomain - Fix NPE in Billing settings