diff --git a/App/FeatureSet/BaseAPI/Index.ts b/App/FeatureSet/BaseAPI/Index.ts index e411aa4188..158d12cb2c 100644 --- a/App/FeatureSet/BaseAPI/Index.ts +++ b/App/FeatureSet/BaseAPI/Index.ts @@ -18,6 +18,7 @@ import WhatsAppLogAPI from "./WhatsAppLogAPI"; // Import API import ResellerPlanAPI from "Common/Server/API/ResellerPlanAPI"; +import EnterpriseLicenseAPI from "Common/Server/API/EnterpriseLicenseAPI"; import MonitorAPI from "Common/Server/API/MonitorAPI"; import ShortLinkAPI from "Common/Server/API/ShortLinkAPI"; import StatusPageAPI from "Common/Server/API/StatusPageAPI"; @@ -1645,6 +1646,10 @@ const BaseAPIFeatureSet: FeatureSet = { `/${APP_NAME.toLocaleLowerCase()}`, new ResellerPlanAPI().getRouter(), ); + app.use( + `/${APP_NAME.toLocaleLowerCase()}`, + new EnterpriseLicenseAPI().getRouter(), + ); app.use(`/${APP_NAME.toLocaleLowerCase()}`, new SlackAPI().getRouter()); app.use( `/${APP_NAME.toLocaleLowerCase()}`, diff --git a/Common/Models/DatabaseModels/EnterpriseLicense.ts b/Common/Models/DatabaseModels/EnterpriseLicense.ts new file mode 100644 index 0000000000..978a2913f0 --- /dev/null +++ b/Common/Models/DatabaseModels/EnterpriseLicense.ts @@ -0,0 +1,104 @@ +import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel"; +import Route from "../../Types/API/Route"; +import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl"; +import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl"; +import ColumnLength from "../../Types/Database/ColumnLength"; +import ColumnType from "../../Types/Database/ColumnType"; +import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint"; +import TableColumn from "../../Types/Database/TableColumn"; +import TableColumnType from "../../Types/Database/TableColumnType"; +import TableMetadata from "../../Types/Database/TableMetadata"; +import IconProp from "../../Types/Icon/IconProp"; +import { Column, Entity, Index } from "typeorm"; + +@TableAccessControl({ + create: [], + read: [], + update: [], + delete: [], +}) +@CrudApiEndpoint(new Route("/enterprise-license")) +@TableMetadata({ + tableName: "EnterpriseLicense", + singularName: "Enterprise License", + pluralName: "Enterprise Licenses", + icon: IconProp.Lock, + tableDescription: "Enterprise license keys issued by OneUptime.", +}) +@Entity({ + name: "EnterpriseLicense", +}) +export default class EnterpriseLicense extends BaseModel { + @ColumnAccessControl({ + create: [], + read: [], + update: [], + }) + @TableColumn({ + required: true, + type: TableColumnType.ShortText, + title: "Company Name", + description: "Company name associated with this license.", + }) + @Column({ + nullable: false, + type: ColumnType.ShortText, + length: ColumnLength.ShortText, + }) + public companyName?: string = undefined; + + @ColumnAccessControl({ + create: [], + read: [], + update: [], + }) + @TableColumn({ + required: true, + type: TableColumnType.ShortText, + title: "License Key", + description: "Enterprise license key.", + unique: true, + }) + @Index({ unique: true }) + @Column({ + nullable: false, + type: ColumnType.ShortText, + length: ColumnLength.ShortText, + unique: true, + }) + public licenseKey?: string = undefined; + + @ColumnAccessControl({ + create: [], + read: [], + update: [], + }) + @TableColumn({ + required: true, + type: TableColumnType.Date, + title: "Expires At", + description: "Expiration date of this license.", + }) + @Column({ + nullable: false, + type: ColumnType.Date, + }) + public expiresAt?: Date = undefined; + + @ColumnAccessControl({ + create: [], + read: [], + update: [], + }) + @TableColumn({ + required: false, + type: TableColumnType.Number, + title: "Annual Contract Value", + description: "Annual contract value (in USD) for this license.", + }) + @Column({ + nullable: true, + type: ColumnType.Number, + }) + public annualContractValue?: number = undefined; +} diff --git a/Common/Models/DatabaseModels/Index.ts b/Common/Models/DatabaseModels/Index.ts index 9515afb09b..c11e6b7d6c 100644 --- a/Common/Models/DatabaseModels/Index.ts +++ b/Common/Models/DatabaseModels/Index.ts @@ -81,6 +81,7 @@ import ProjectSmtpConfig from "./ProjectSmtpConfig"; //SSO import ProjectSSO from "./ProjectSso"; import PromoCode from "./PromoCode"; +import EnterpriseLicense from "./EnterpriseLicense"; import Reseller from "./Reseller"; import ResellerPlan from "./ResellerPlan"; // ScheduledMaintenances @@ -331,6 +332,7 @@ const AllModelTypes: Array<{ ResellerPlan, PromoCode, + EnterpriseLicense, GlobalConfig, diff --git a/Common/Server/EnvironmentConfig.ts b/Common/Server/EnvironmentConfig.ts index a8dbce614e..eb67685611 100644 --- a/Common/Server/EnvironmentConfig.ts +++ b/Common/Server/EnvironmentConfig.ts @@ -365,6 +365,9 @@ export const DocsClientUrl: URL = new URL( export const DisableTelemetry: boolean = process.env["DISABLE_TELEMETRY"] === "true"; +export const IsEnterpriseEdition: boolean = + process.env["IS_ENTERPRISE_EDITION"] === "true"; + export const AverageSpanRowSizeInBytes: number = parsePositiveNumberFromEnv( "AVERAGE_SPAN_ROW_SIZE_IN_BYTES", 1024, diff --git a/Common/Server/Services/EnterpriseLicenseService.ts b/Common/Server/Services/EnterpriseLicenseService.ts new file mode 100644 index 0000000000..8abd077280 --- /dev/null +++ b/Common/Server/Services/EnterpriseLicenseService.ts @@ -0,0 +1,10 @@ +import DatabaseService from "./DatabaseService"; +import EnterpriseLicense from "../../Models/DatabaseModels/EnterpriseLicense"; + +export class Service extends DatabaseService { + public constructor() { + super(EnterpriseLicense); + } +} + +export default new Service(); diff --git a/Common/Server/Services/Index.ts b/Common/Server/Services/Index.ts index 388ef1bdbb..a86aa39b46 100644 --- a/Common/Server/Services/Index.ts +++ b/Common/Server/Services/Index.ts @@ -71,6 +71,7 @@ import ProjectService from "./ProjectService"; import ProjectSmtpConfigService from "./ProjectSmtpConfigService"; import ProjectSsoService from "./ProjectSsoService"; import PromoCodeService from "./PromoCodeService"; +import EnterpriseLicenseService from "./EnterpriseLicenseService"; import ResellerPlanService from "./ResellerPlanService"; import ResellerService from "./ResellerService"; import ScheduledMaintenanceCustomFieldService from "./ScheduledMaintenanceCustomFieldService"; @@ -173,6 +174,7 @@ const services: Array = [ OnCallDutyPolicyTimeLogService, AcmeCertificateService, PromoCodeService, + EnterpriseLicenseService, ResellerService, ResellerPlanService,