v.1.0.0. initial push of license-lib

This commit is contained in:
2025-03-19 09:37:30 -05:00
commit b22a1c973c
20 changed files with 433 additions and 0 deletions

13
server/config.js Normal file
View File

@ -0,0 +1,13 @@
// server/config.js
require('dotenv').config();
module.exports = {
JWT_SECRET: process.env.JWT_SECRET,
DB_HOST: process.env.DB_HOST,
DB_NAME: process.env.DB_NAME,
DB_USER_ADMIN: process.env.DB_USER_ADMIN,
DB_PASS_ADMIN: process.env.DB_PASS_ADMIN,
DB_USER_READER: process.env.DB_USER_READER,
DB_PASS_READER: process.env.DB_PASS_READER,
LICENSE_CHECK_INTERVAL: '7d',
};

19
server/database.js Normal file
View File

@ -0,0 +1,19 @@
// server/database.js
const mysql = require('mysql2/promise');
const config = require('./config');
const adminPool = mysql.createPool({
host: config.DB_HOST,
user: config.DB_USER_ADMIN,
password: config.DB_PASS_ADMIN,
database: config.DB_NAME,
});
const readerPool = mysql.createPool({
host: config.DB_HOST,
user: config.DB_USER_READER,
password: config.DB_PASS_READER,
database: config.DB_NAME,
});
module.exports = { adminPool, readerPool };

26
server/index.js Normal file
View File

@ -0,0 +1,26 @@
// server/index.js
const express = require('express');
const { generateLicenseKey, hashLicenseKey } = require('./keygen');
const { saveLicense } = require('./models/license');
const { verifyLicenseKey } = require('./verify');
const app = express();
app.use(express.json());
app.post('/generate-license', async (req, res) => {
const { userId, licenseType, tier, validUntil } = req.body;
const licenseKey = generateLicenseKey(userId, licenseType, tier);
const hashedKey = hashLicenseKey(JSON.parse(Buffer.from(licenseKey.split('.')[1], 'base64')).rawKey);
await saveLicense(userId, hashedKey, licenseType, tier, validUntil);
res.json({ licenseKey });
});
app.post('/validate-license', async (req, res) => {
const { userId, licenseKey } = req.body;
const valid = await verifyLicenseKey(userId, licenseKey);
res.json({ valid });
});
app.listen(3000, () => console.log('License server running on port 3000'));

14
server/keygen.js Normal file
View File

@ -0,0 +1,14 @@
// server/keygen.js
const crypto = require('crypto');
const { encrypt } = require('./utils/crypto');
const generateLicenseKey = (userId) => {
const rawKey = crypto.randomBytes(32).toString('hex');
const payload = { userId, rawKey, issued: Date.now() };
const encryptedKey = encrypt(payload);
return encryptedKey;
};
const hashLicenseKey = (key) => crypto.createHash('sha256').update(key).digest('hex');
module.exports = { generateLicenseKey, hashLicenseKey };

21
server/models/license.js Normal file
View File

@ -0,0 +1,21 @@
const { adminPool, readerPool } = require('../database');
const saveLicense = async (userId, hashedKey, licenseType, tier, validUntil = null) => {
const sql = `
INSERT INTO licenses (user_id, hashed_key, license_type, tier, valid_until, created_at)
VALUES (?, ?, ?, ?, ?, NOW())
`;
const [result] = await adminPool.execute(sql, [userId, hashedKey, licenseType, tier, validUntil]);
return result.insertId;
};
const getLicense = async (userId) => {
const sql = `
SELECT hashed_key, license_type, tier, valid_until
FROM licenses WHERE user_id = ?
`;
const [rows] = await readerPool.execute(sql, [userId]);
return rows[0];
};
module.exports = { saveLicense, getLicense };

8
server/utils/crypto.js Normal file
View File

@ -0,0 +1,8 @@
// server/utils/crypto.js
const jwt = require('jsonwebtoken');
const config = require('../config');
const encrypt = (data) => jwt.sign(data, config.JWT_SECRET);
const decrypt = (token) => jwt.verify(token, config.JWT_SECRET);
module.exports = { encrypt, decrypt };

23
server/verify.js Normal file
View File

@ -0,0 +1,23 @@
// server/verify.js
const { decrypt } = require('./utils/crypto');
const { hashLicenseKey } = require('./keygen');
const { getLicense } = require('./models/license');
const verifyLicenseKey = async (userId, token) => {
try {
const payload = decrypt(token);
if (payload.userId !== userId) return false;
const storedLicense = await getLicense(userId);
const hashed = hashLicenseKey(payload.rawKey);
if (storedLicense.hashed_key !== hashed) return false;
if (storedLicense.license_type !== 'one-time' && storedLicense.valid_until && new Date(storedLicense.valid_until) < new Date()) return false;
return true;
} catch (err) {
return false;
}
};
module.exports = { verifyLicenseKey };