Files
DentalManagementMH06/apps/Backend/src/routes/license.ts
2026-05-26 21:50:30 -04:00

98 lines
2.7 KiB
TypeScript

import { Router } from "express";
import crypto from "crypto";
import fs from "fs";
import path from "path";
const router = Router();
const LICENSE_FILE = path.join(process.cwd(), "license.json");
const SECRET = process.env.LICENSE_SECRET || "";
function validateKey(key: string): { valid: boolean; expiry?: string; error?: string } {
// Format: DENTAL-{24-char-signature}-{YYYY-MM-DD}
const parts = key.trim().split("-");
if (parts.length !== 5 || parts[0] !== "DENTAL") {
return { valid: false, error: "Invalid license key format" };
}
const signature = parts[1];
const expiryStr = `${parts[2]}-${parts[3]}-${parts[4]}`;
// Verify signature
const payload = `DENTAL:${expiryStr}`;
const expectedSig = crypto
.createHmac("sha256", SECRET)
.update(payload)
.digest("hex")
.substring(0, 24)
.toUpperCase();
if (signature !== expectedSig) {
return { valid: false, error: "Invalid license key" };
}
// Check expiry
const expiry = new Date(expiryStr);
if (isNaN(expiry.getTime())) {
return { valid: false, error: "Invalid expiry date in key" };
}
if (new Date() > expiry) {
return { valid: false, expiry: expiryStr, error: "License key has expired" };
}
return { valid: true, expiry: expiryStr };
}
function loadLicense(): { key: string; expiry: string } | null {
try {
if (!fs.existsSync(LICENSE_FILE)) return null;
return JSON.parse(fs.readFileSync(LICENSE_FILE, "utf8"));
} catch {
return null;
}
}
function saveLicense(key: string, expiry: string) {
fs.writeFileSync(LICENSE_FILE, JSON.stringify({ key, expiry }, null, 2));
}
// GET /api/license/status
router.get("/status", (req, res) => {
const stored = loadLicense();
if (!stored) {
return res.json({ activated: false, expired: false, expiry: null, daysLeft: null });
}
const result = validateKey(stored.key);
if (!result.valid && result.expiry) {
return res.json({ activated: true, expired: true, expiry: stored.expiry, daysLeft: 0 });
}
if (!result.valid) {
return res.json({ activated: false, expired: false, expiry: null, daysLeft: null });
}
const expiry = new Date(stored.expiry);
const daysLeft = Math.ceil((expiry.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
return res.json({ activated: true, expired: false, expiry: stored.expiry, daysLeft });
});
// POST /api/license/activate
router.post("/activate", (req, res) => {
const { key } = req.body;
if (!key) {
return res.status(400).json({ error: "License key is required" });
}
const result = validateKey(key);
if (!result.valid) {
return res.status(400).json({ error: result.error });
}
saveLicense(key.trim(), result.expiry!);
return res.json({ success: true, expiry: result.expiry });
});
export default router;