Created the license.ts controller

This commit is contained in:
Mathias Wagner 2023-08-03 23:31:25 +02:00
parent dbfc0353f0
commit 8485b95428
Signed by: Mathias
GPG Key ID: B8DC354B0A1F5B44

145
src/controller/license.ts Normal file
View File

@ -0,0 +1,145 @@
import { checkProjectAccess } from "@controller/projects";
import { IKeyRole } from "@models/AccessKey";
import { decryptField, encryptClearField } from "@utils/decryption";
import { ILicense, License } from "@models/License";
import { planLimits } from "../limits/plans";
import { Permission } from "@models/Permission";
import { IProject } from "@models/Project";
import { Group } from "@models/Group";
import { MetaData } from "@models/MetaData";
import { convertIdsToPermissions } from "@controller/permission";
import { convertIdsToGroups } from "@controller/group";
import { convertIdsToMetaData, isValidMetaType } from "@controller/meta";
export const generateCharacter = () => {
return String.fromCharCode(Math.random() < 0.5 ? Math.floor(Math.random() * 26) + 65 : Math.floor(Math.random() * 26) + 97);
}
export const generateSpecialCharacter = () => {
const specialChars = "!@#$%^&*()_+-=[]{};':\",./<>?";
return specialChars[Math.floor(Math.random() * specialChars.length)];
}
export const generateAlphaNumeric = () => {
const alphanumericChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
return alphanumericChars[Math.floor(Math.random() * alphanumericChars.length)];
}
export const generateRandom = () => {
const allChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=[]{};':\",./<>?";
return allChars[Math.floor(Math.random() * allChars.length)];
}
export const replaceLicenseDefaults = (defaultKey: string) => {
return defaultKey.replace(/N/g, () => String(Math.floor(Math.random() * 10)))
.replace(/C/g, () => generateCharacter())
.replace(/L/g, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97))
.replace(/U/g, () => String.fromCharCode(Math.floor(Math.random() * 26) + 65))
.replace(/S/g, () => generateSpecialCharacter())
.replace(/A/g, () => generateAlphaNumeric())
.replace(/R/g, () => generateRandom());
}
export const checkLicenseConfiguration = async (access: IProject, config: ILicense) => {
if (config.groups) {
let groupsEncrypted = config.groups.map(group => encryptClearField(group));
config.groups = (await Group.find({ projectId: encryptClearField(String(access._id)),
name: { $in: groupsEncrypted }})).map(group => group.id);
}
if (config.permissions) {
let permissionsEncrypted = config.permissions.map(permission => encryptClearField(permission));
config.permissions = (await Permission.find({ projectId: encryptClearField(String(access._id)),
permission: { $in: permissionsEncrypted }})).map(permission => permission.id);
}
if (config.meta) {
let metaEncrypted = Object.keys(config.meta).map(meta => encryptClearField(meta));
let meta = (await MetaData.find({ projectId: encryptClearField(String(access._id)),
name: { $in: metaEncrypted }}));
let metaObj: { [key: string]: string } = {};
meta.forEach(meta => {
if (isValidMetaType(meta.type, config.meta[meta.name]))
metaObj[meta.id] = config.meta[meta.name];
});
config.meta = metaObj;
}
}
export const mapLicense = async (projectId: string, license: any, publicAccess: boolean) => {
return {
key: license.key, groups: await convertIdsToGroups(projectId, license.groups), permissions: await convertIdsToPermissions(projectId, license.permissions),
meta: await convertIdsToMetaData(projectId, publicAccess, license.meta), maxUses: license.maxUses, currentUses: license.currentUses,
expirationDate: license.expirationDate
}
}
export const listLicensesPaginated = async (userId: string, projectId: string, page: number, limit: number) => {
const access = await checkProjectAccess(IKeyRole.VIEW)(userId, projectId);
if ("code" in access) return access;
const licenses = await License.find({ projectId: encryptClearField(String(access._id)) }).skip(page * limit).limit(limit);
return {
total: await License.countDocuments({ projectId: encryptClearField(String(access._id)) }),
licenses: await Promise.all(licenses.map(license => mapLicense(projectId, license, false)))
}
}
export const getLicense = async (userId: string, projectId: string, licenseKey: string) => {
const access = await checkProjectAccess(IKeyRole.VIEW)(userId, projectId);
if ("code" in access) return access;
const license = await License.findOne({ projectId: encryptClearField(String(access._id)), key: encryptClearField(licenseKey) });
if (license === null) return { code: 4009, message: "The provided license key does not exist" };
return mapLicense(projectId, license, false);
}
export const createLicense = async (userId: string, projectId: string, config: ILicense) => {
const access = await checkProjectAccess(IKeyRole.MANAGE)(userId, projectId);
if ("code" in access) return access;
const count = await License.countDocuments({ projectId: encryptClearField(String(access._id)) });
if (count >= planLimits[access.plan].LICENSES) return { code: 95, message: "You have exceeded the license limit" };
if (!config.key) config.key = replaceLicenseDefaults(access.defaults.licenseKey);
if (!config.maxUses) config.maxUses = access.defaults.maxUses;
if (!config.groups) config.groups = access.defaults.groups;
if (!config.permissions) config.permissions = access.defaults.permissions;
if (!config.expirationDate) config.expirationDate = access.defaults.expirationDate;
const license = await License.findOne({ projectId: encryptClearField(String(access._id)), key: encryptClearField(config.key) });
if (license !== null) return { code: 4008, message: "The provided license key is already in use" };
await checkLicenseConfiguration(access, config);
const created = (await License.create({ ...config, projectId }));
return { key: decryptField(created.key)};
}
export const updateLicense = async (userId: string, projectId: string, licenseKey: string, config: ILicense) => {
const access = await checkProjectAccess(IKeyRole.MANAGE)(userId, projectId);
if ("code" in access) return access;
const license = await License.findOne({ projectId: encryptClearField(String(access._id)), key: encryptClearField(licenseKey) });
if (license === null) return { code: 4009, message: "The provided license key does not exist" };
await checkLicenseConfiguration(access, config);
await License.updateOne({ projectId: encryptClearField(String(access._id)), key: encryptClearField(licenseKey) }, config);
return { };
}
export const deleteLicense = async (userId: string, projectId: string, licenseKey: string) => {
const access = await checkProjectAccess(IKeyRole.MANAGE)(userId, projectId);
if ("code" in access) return access;
const license = await License.findOne({ projectId: encryptClearField(String(access._id)), key: encryptClearField(licenseKey) });
if (license === null) return { code: 4009, message: "The provided license key does not exist" };
await License.deleteOne({ projectId: encryptClearField(String(access._id)), key: encryptClearField(licenseKey) });
return { };
}