add enterprise license system

This commit is contained in:
miloschwartz
2025-10-13 10:41:10 -07:00
parent 6b125bba7c
commit 37ceabdf5d
76 changed files with 3886 additions and 1931 deletions

View File

@@ -0,0 +1,91 @@
import { Request, Response, NextFunction } from "express";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { response as sendResponse } from "@server/lib/response";
import privateConfig from "@server/private/lib/config";
export type NewLicenseKey = {
licenseKey: {
id: number;
instanceName: string | null;
instanceId: string;
licenseKey: string;
tier: string;
type: string;
quantity: number;
isValid: boolean;
updatedAt: string;
createdAt: string;
expiresAt: string;
orgId: string;
};
};
export type GenerateNewLicenseResponse = NewLicenseKey;
async function createNewLicense(orgId: string, licenseData: any): Promise<any> {
try {
const response = await fetch(
`https://api.fossorial.io/api/v1/license-internal/enterprise/${orgId}/create`,
{
method: "PUT",
headers: {
"api-key":
privateConfig.getRawPrivateConfig().server
.fossorial_api_key!,
"Content-Type": "application/json"
},
body: JSON.stringify(licenseData)
}
);
const data = await response.json();
logger.debug("Fossorial API response:", {data});
return data;
} catch (error) {
console.error("Error creating new license:", error);
throw error;
}
}
export async function generateNewLicense(
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
try {
const { orgId } = req.params;
if (!orgId) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Organization ID is required"
)
);
}
logger.debug(`Generating new license for orgId: ${orgId}`);
const licenseData = req.body;
const apiResponse = await createNewLicense(orgId, licenseData);
return sendResponse<GenerateNewLicenseResponse>(res, {
data: apiResponse.data,
success: apiResponse.success,
error: apiResponse.error,
message: apiResponse.message,
status: apiResponse.status
});
} catch (error) {
logger.error(error);
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred while generating new license"
)
);
}
}

View File

@@ -0,0 +1,2 @@
export * from "./listGeneratedLicenses";
export * from "./generateNewLicense";

View File

@@ -0,0 +1,83 @@
import { Request, Response, NextFunction } from "express";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { response as sendResponse } from "@server/lib/response";
import privateConfig from "@server/private/lib/config";
export type GeneratedLicenseKey = {
instanceName: string | null;
licenseKey: string;
expiresAt: string;
isValid: boolean;
createdAt: string;
tier: string;
type: string;
};
export type ListGeneratedLicenseKeysResponse = GeneratedLicenseKey[];
async function fetchLicenseKeys(orgId: string): Promise<any> {
try {
const response = await fetch(
`https://api.fossorial.io/api/v1/license-internal/enterprise/${orgId}/list`,
{
method: "GET",
headers: {
"api-key":
privateConfig.getRawPrivateConfig().server
.fossorial_api_key!,
"Content-Type": "application/json"
}
}
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error("Error fetching license keys:", error);
throw error;
}
}
export async function listSaasLicenseKeys(
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
try {
const { orgId } = req.params;
if (!orgId) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Organization ID is required"
)
);
}
const apiResponse = await fetchLicenseKeys(orgId);
const keys: GeneratedLicenseKey[] = apiResponse.data.licenseKeys || [];
return sendResponse<ListGeneratedLicenseKeysResponse>(res, {
data: keys,
success: true,
error: false,
message: "Successfully retrieved license keys",
status: HttpCode.OK
});
} catch (error) {
logger.error(error);
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred while fetching license keys"
)
);
}
}