mirror of https://github.com/certd/certd
chore: 单元测试
parent
9187e87419
commit
70ce6be0bf
|
@ -24,3 +24,4 @@ dist-ssr
|
|||
*.sw?
|
||||
|
||||
test/user.secret.*
|
||||
test/**/*.js
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"extension": ["ts"],
|
||||
"spec": "test/**/*.test.ts",
|
||||
"require": "ts-node/register"
|
||||
}
|
||||
"spec": "src/**/*.spec.ts"
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
node_modules
|
||||
src
|
||||
src
|
||||
dist/**/*.spec.*
|
|
@ -10,10 +10,10 @@
|
|||
"build": "tsc --skipLibCheck",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"test": "mocha --loader=ts-node/esm"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"axios": "^1.7.2",
|
||||
"fix-path": "^4.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
@ -22,6 +22,7 @@
|
|||
"qs": "^6.11.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@rollup/plugin-commonjs": "^23.0.4",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
|
|
|
@ -3,3 +3,4 @@ export * from "./run-history.js";
|
|||
export * from "./context.js";
|
||||
export * from "./storage.js";
|
||||
export * from "./file-store.js";
|
||||
export * from "./license.js";
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { isPlus, verify } from "./license.js";
|
||||
import { equal } from "assert";
|
||||
describe("license", function () {
|
||||
it("#license", async function () {
|
||||
const req = {
|
||||
appKey: "Certd",
|
||||
subjectId: "dev_xiao_001",
|
||||
license:
|
||||
"65794a7a64574a715a574e30535751694f694a6b5a585a6665476c68623138774d4445694c434a686348424c5a586b694f694a485233527953314a58556d7475526d524a53555177636c63694c434a6b64584a6864476c76626949364d7a59314c434a6859335270646d56556157316c496a6f784e7a49794e5459794e7a49334f4455344c434a325a584a7a61573975496a6f784c434a6a6232526c496a6f69516e464d4d335a754e5670564e457830527a6c685557785754544d7764454532636c5a6b563251334e474a664d534973496d563463476c795a565270625755694f6a45334e5451774f5467334d6a63344e546773496e4e6c59334a6c6443493649694973496e4e705a323568644856795a534936496d3535637a564461557475556b74614d31426b5231524c4e6b6f76513342334c7a523052334e7263537443624867784f4552534d556c3256314e5752545534565746365744465a546b706164575a4d5455706863474a356347704c557a4a6b53576f7a546d45344e47645553553434646b5236544568504e5570744f467051576d316d4c335236566d4653595556694f4768494f45706a53307777547a424353573530596d3133616d78595454645352544e344f44497963464d796432646c536d6b34556c64344d6b7832546a68715230394762546c535330644e596c5678556b4e7355305a6f59306c59596b5249615538786156425655305a5053484a7a6333646f4d6e70425a564654576a4276566b74464c316331556d5a745253387a5446517a646b68734f573951656e687161314a79553068794e55466c646d784a4c7a5647526b5a71526b4d76626b356a5a454a705a485a68616e51726556425a5458464e5a33466a616c6c78566a4a6e597939586145744b5a46464d53587035645856614b7a56335554684f64464e6851545272616a464d526d55775a574e4352306c50625751335132464e645774445a3235555644464f5233525a5a6e4650646c706965555636647a3039496e303d",
|
||||
};
|
||||
const plus = isPlus();
|
||||
equal(plus, false);
|
||||
const res = await verify(req);
|
||||
equal(res, true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,90 @@
|
|||
import { createVerify } from "node:crypto";
|
||||
import { logger } from "../utils/index.js";
|
||||
|
||||
const SecreteKey =
|
||||
"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQkNnS0NBUUVBMjdoZDM0NjRYbyt3TkpmTTNCWjE5MXlQK2NLaTd3ck9CbXdjTWJPZUdsNlJOMUVtTGhyMgplOFdvOGpmMW9IVXc5RFV6L2I2ZHU3Q3ZXMXZNUDA1Q3dSS3lNd2U3Q1BYRGQ2U01mSkwxRFZyUkw5Ylh0cEYzCjJkQVA5UENrakFJcFMvRE5jVkhLRXk1QW8yMnFFenpTKzlUT0JVY2srREdZcmo4KzI5U3h2aEZDRE5ZbEE2d1EKbEkyRWc5TWNBV2xDU3p1S1JWa2ZWUWdYVlU3SmE5OXp1Um1oWWtYZjFxQzBLcVAwQkpDakdDNEV6ZHorMmwyaAo2T3RxVHVVLzRkemlYYnRMUS8vU0JqNEgxdi9PZ3dUZjJkSVBjUnRHOXlWVTB2ZlQzVzdUTkdlMjU3em5ESDBYCkd6Wm4zdWJxTXJuL084b2ltMHRrS3ZHZXZ1V2ZraWNwVVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==";
|
||||
|
||||
export type LicenseVerifyReq = {
|
||||
appKey: string;
|
||||
subjectId: string;
|
||||
license: string;
|
||||
};
|
||||
|
||||
type License = {
|
||||
appKey: string;
|
||||
code: string;
|
||||
subjectId: string;
|
||||
expireTime: number;
|
||||
activeTime: number;
|
||||
duration: number;
|
||||
version: number;
|
||||
secret: string;
|
||||
signature: string;
|
||||
};
|
||||
|
||||
class LicenseHolder {
|
||||
isPlus = false;
|
||||
}
|
||||
const holder = new LicenseHolder();
|
||||
holder.isPlus = false;
|
||||
|
||||
class LicenseVerifier {
|
||||
checked = false;
|
||||
licenseReq?: LicenseVerifyReq = undefined;
|
||||
async reVerify(req: LicenseVerifyReq) {
|
||||
this.checked = false;
|
||||
//@ts-ignore
|
||||
// globalThis._certd_license_.isPlus = false;
|
||||
return await this.verify(req);
|
||||
}
|
||||
|
||||
setPlus(value: boolean) {
|
||||
//@ts-ignore
|
||||
holder.isPlus = value;
|
||||
return value;
|
||||
}
|
||||
async verify(req: LicenseVerifyReq) {
|
||||
this.licenseReq = req;
|
||||
if (this.checked) {
|
||||
return this.setPlus(false);
|
||||
}
|
||||
const license = req?.license;
|
||||
if (!license) {
|
||||
this.checked = true;
|
||||
return this.setPlus(false);
|
||||
}
|
||||
|
||||
const licenseJson = Buffer.from(Buffer.from(license, "hex").toString(), "base64").toString();
|
||||
const json: License = JSON.parse(licenseJson);
|
||||
if (json.expireTime < Date.now()) {
|
||||
logger.warn("授权已过期");
|
||||
return this.setPlus(false);
|
||||
}
|
||||
|
||||
const content = `${this.licenseReq.appKey},${this.licenseReq.subjectId},${json.code},${json.secret}${json.activeTime},${json.duration},${json.expireTime},${json.version}`;
|
||||
const publicKey = Buffer.from(SecreteKey, "base64").toString();
|
||||
const res = this.verifySignature(content, json.signature, publicKey);
|
||||
this.checked = true;
|
||||
if (!res) {
|
||||
logger.warn("授权校验失败");
|
||||
return this.setPlus(false);
|
||||
}
|
||||
return this.setPlus(true);
|
||||
}
|
||||
|
||||
verifySignature(content: string, signature: any, publicKey: string) {
|
||||
const verify = createVerify("RSA-SHA1");
|
||||
verify.update(content);
|
||||
return verify.verify(publicKey, signature, "base64");
|
||||
}
|
||||
}
|
||||
|
||||
const verifier = new LicenseVerifier();
|
||||
|
||||
export function isPlus() {
|
||||
return holder.isPlus;
|
||||
}
|
||||
|
||||
export async function verify(req: LicenseVerifyReq) {
|
||||
return await verifier.reVerify(req);
|
||||
}
|
|
@ -5,4 +5,3 @@ export default function (timeout: number) {
|
|||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { EchoPlugin } from "./echo-plugin";
|
||||
import { EchoPlugin } from "./echo-plugin.js";
|
||||
describe("task_plugin", function () {
|
||||
it("#taskplugin", function () {
|
||||
console.log("before new plugin");
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
license.*
|
|
@ -34,6 +34,7 @@
|
|||
"exclude": [
|
||||
"*.js",
|
||||
"*.ts",
|
||||
"*.spec.ts",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"test"
|
||||
|
|
|
@ -3,7 +3,8 @@ import { logger } from '../../utils/logger.js';
|
|||
import { UserService } from '../authority/service/user-service.js';
|
||||
import { SysSettingsService } from '../system/service/sys-settings-service.js';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { SysInstallInfo } from '../system/service/models.js';
|
||||
import { SysInstallInfo, SysLicenseInfo } from '../system/service/models.js';
|
||||
import { verify } from '@certd/pipeline';
|
||||
|
||||
export type InstallInfo = {
|
||||
installTime: number;
|
||||
|
@ -32,6 +33,10 @@ export class AutoInitSite {
|
|||
await this.sysSettingsService.saveSetting(installInfo);
|
||||
}
|
||||
|
||||
// 授权许可
|
||||
const licenseInfo: SysLicenseInfo = await this.sysSettingsService.getSetting(SysLicenseInfo);
|
||||
await verify(licenseInfo.license);
|
||||
|
||||
logger.info('初始化站点完成');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,3 +27,10 @@ export class SysInstallInfo extends BaseSettings {
|
|||
installTime: number;
|
||||
siteId?: string;
|
||||
}
|
||||
|
||||
export class SysLicenseInfo extends BaseSettings {
|
||||
static __title__ = '授权许可信息';
|
||||
static __key__ = 'sys.license';
|
||||
static __access__ = 'private';
|
||||
license: string;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue