v.1.0.0. initial push of license-lib
This commit is contained in:
13
server/config.js
Normal file
13
server/config.js
Normal 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
19
server/database.js
Normal 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
26
server/index.js
Normal 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
14
server/keygen.js
Normal 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
21
server/models/license.js
Normal 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
8
server/utils/crypto.js
Normal 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
23
server/verify.js
Normal 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 };
|
Reference in New Issue
Block a user