@certd/plus-core 1.38.4 → 1.38.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/d/license.d.ts +4 -0
- package/dist/d/service.d.ts +6 -2
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.38.6](https://github.com/certd/certd/compare/v1.38.5...v1.38.6) (2026-02-04)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @certd/plus-core
|
|
9
|
+
|
|
10
|
+
## [1.38.5](https://github.com/certd/certd/compare/v1.38.4...v1.38.5) (2026-02-02)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @certd/plus-core
|
|
13
|
+
|
|
6
14
|
## [1.38.4](https://github.com/certd/certd/compare/v1.38.3...v1.38.4) (2026-01-31)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @certd/plus-core
|
package/dist/d/license.d.ts
CHANGED
|
@@ -9,15 +9,18 @@ export type LicenseVerifyReq = {
|
|
|
9
9
|
subjectId: string;
|
|
10
10
|
license: string;
|
|
11
11
|
bindUrl?: string;
|
|
12
|
+
bindUrl2?: string;
|
|
12
13
|
doCheckFromRemote: () => Promise<CheckRes>;
|
|
13
14
|
};
|
|
14
15
|
export type LicenseLocalVerifyReq = {
|
|
15
16
|
subjectId: string;
|
|
16
17
|
license: string;
|
|
17
18
|
bindUrl?: string;
|
|
19
|
+
bindUrl2?: string;
|
|
18
20
|
};
|
|
19
21
|
export declare function isPlus(): boolean;
|
|
20
22
|
export declare function getSecret(): string;
|
|
23
|
+
export declare function getPlusMessage(): string;
|
|
21
24
|
export declare function getExpiresTime(): number;
|
|
22
25
|
export declare function getVipType(): string;
|
|
23
26
|
export declare function isComm(): boolean;
|
|
@@ -28,6 +31,7 @@ export declare function getPlusInfo(): {
|
|
|
28
31
|
expireTime: number;
|
|
29
32
|
secret: string;
|
|
30
33
|
originVipType: string;
|
|
34
|
+
message: string;
|
|
31
35
|
};
|
|
32
36
|
export declare function getLicense(): any;
|
|
33
37
|
export declare function getLicenseReq(): any;
|
package/dist/d/service.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare class PlusRequestService {
|
|
|
8
8
|
siteInfo: {
|
|
9
9
|
subjectId: string;
|
|
10
10
|
bindUrl?: string;
|
|
11
|
+
bindUrl2?: string;
|
|
11
12
|
installTime: number;
|
|
12
13
|
};
|
|
13
14
|
saveLicense: any;
|
|
@@ -15,6 +16,7 @@ export declare class PlusRequestService {
|
|
|
15
16
|
subjectId: string;
|
|
16
17
|
installTime: number;
|
|
17
18
|
bindUrl?: string;
|
|
19
|
+
bindUrl2?: string;
|
|
18
20
|
saveLicense: (license: string) => Promise<void>;
|
|
19
21
|
});
|
|
20
22
|
getSubjectId(): string;
|
|
@@ -41,7 +43,7 @@ export declare class PlusRequestService {
|
|
|
41
43
|
getBaseURL(): string;
|
|
42
44
|
request(config: any): Promise<any>;
|
|
43
45
|
sign(body: any, timestamps: number): Promise<string>;
|
|
44
|
-
bindUrl(url: string): Promise<any>;
|
|
46
|
+
bindUrl(url: string, url2?: string): Promise<any>;
|
|
45
47
|
register(): Promise<any>;
|
|
46
48
|
updateLicense(opts: {
|
|
47
49
|
license: string;
|
|
@@ -50,8 +52,10 @@ export declare class PlusRequestService {
|
|
|
50
52
|
accessToken: any;
|
|
51
53
|
expiresIn: any;
|
|
52
54
|
}>;
|
|
53
|
-
doVipCheck(
|
|
55
|
+
doVipCheck(req: {
|
|
54
56
|
bindUrl?: string;
|
|
57
|
+
bindUrl2?: string;
|
|
55
58
|
}): Promise<any>;
|
|
56
59
|
active(code: string, inviteCode?: string): Promise<void>;
|
|
60
|
+
getOrderCount(): Promise<any>;
|
|
57
61
|
}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"node:crypto";import{createVerify as t}from"node:crypto";import i from"dayjs";import{cloneDeep as s}from"lodash-es";import{logger as r,http as n}from"@certd/basic";const o={logger:{info(...e){console.log(...e)},warn(...e){console.warn(...e)},error(...e){console.error(...e)},debug(...e){console.log(...e)}}};function c(e){o.logger=e}function a(){return o.logger}let
|
|
1
|
+
import*as e from"node:crypto";import{createVerify as t}from"node:crypto";import i from"dayjs";import{cloneDeep as s}from"lodash-es";import{logger as r,http as n}from"@certd/basic";const o={logger:{info(...e){console.log(...e)},warn(...e){console.warn(...e)},error(...e){console.error(...e)},debug(...e){console.log(...e)}}};function c(e){o.logger=e}function a(){return o.logger}let l="LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQW9VWE1EWUhjdi82WFROWEZFSUI2RlpuR2FER0cwZnR5bTV1dVhPck9NaVl0UkxSb1lvSGMKNVZxenE0N00rdEFqRFBhaTBlOFhWS1c3aytUQUw3MUs0N2JCQVEyWTBxNU5Ya3lYcE5PTVdueVFMYXBwb0tWNgpPMkFJMnpFVURWMVJVa0ZtMFZTVjU0VXNzMDcrdjI2aW5aQU1CWitDMU42eWFDc2tZL3grNnVlNkVRNVcyZXdFCjZOWEhJcUU1bHdEUmU2SXJtdEpnU2doSnlHTS91azIyejN6NGEraFVPVUlWMy9DbEhYV0VhRHBBRFFsakt3NSsKeHR0dURiTHZyUmdzdWp6czB0dEI2OE1SbXE0R0FJL0JtNWVPWkhlNGxFQjBFVVhFUXdVWE1jV1N1VFZSMUE2cApUM21LRGo5MGcwVDFZUlNOdE5TMm9aRzgvRWIwOVlxK3Z3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K",p="kQth6FHM71IPV3qdWc";"false"===process.env.plus_use_prod&&(l="LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQXY3TGtMaUp1dGM0NzhTU3RaTExjajVGZXh1YjJwR2NLMGxwa0hwVnlZWjhMY29rRFhuUlAKUGQ5UlJSTVRTaGJsbFl2Mzd4QUhOV1ZIQ0ZsWHkrQklVU001bUlBU1NDQTV0azlJNmpZZ2F4bEFDQm1BY0lGMwozKzBjeGZIYVkrVW9YdVluMkZ6YUt2Ym5GdFZIZ0lkMDg4a3d4clZTZzlCT3BDRVZIR1pxR2I5TWN5MXVHVXhUClFTVENCbmpoTWZlZ0p6cXVPYWVOY0ZPSE5tbmtWRWpLTythbTBPeEhNS1lyS3ZnQnVEbzdoVnFENlBFMUd6V3AKZHdwZUV4QXZDSVJxL2pWTkdRK3FtMkRWOVNJZ3U5bmF4MktmSUtFeU50dUFFS1VpekdqL0VmRFhDM1cxMExhegpKaGNYNGw1SUFZU1o3L3JWVmpGbExWSVl0WDU1T054L1Z3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K",p="z4nXOeTeSnnpUpnmsV"),"true"===process.env.plus_off&&(p="12132");const u=p;const h=new class{verified=!1;isPlus=!1;isComm=!1;expireTime=0;vipType="free";message=void 0;secret=void 0;originVipType="free"};h.isPlus=!1,h.isComm=!1;const d=new class{checked=!1;licenseReq=void 0;doCheckFromRemote;async reLocalVerify(e){return this.checked=!1,await this.localVerify(e)}setLicenseInfo(e,t={}){return e?(h.verified=!0,h.expireTime=t.expireTime,h.vipType=t.vipType,h.originVipType=t.vipType,h.isPlus=t.vipType&&"free"!==t.vipType,h.isComm="comm"===t.vipType,h.message=t.message):(h.verified=!1,h.isPlus=!1,h.isComm=!1,h.expireTime=t.expireTime??0,h.vipType="free",h.message=t.message,t.originVipType&&(h.originVipType=t.originVipType)),t.secret&&(h.secret=t.secret),{...h}}async localVerify(e){if(this.licenseReq=e,this.checked)return this.setLicenseInfo(!1);const t=e?.license;if(!t)return this.checked=!0,this.setLicenseInfo(!1);const s=Buffer.from(t,"base64").toString(),r=JSON.parse(s),n=a();if(r.expireTime>0&&r.expireTime<(new Date).getTime())return n.warn("授权已过期"),this.setLicenseInfo(!1,{message:"授权已过期",originVipType:r.vipType,secret:r.secret,expireTime:r.expireTime});const o=`${p},${this.licenseReq.subjectId},${r.code},${r.secret},${r.vipType},${r.activeTime},${r.duration},${r.expireTime},${r.version}`;n.info("content:",o);const c=Buffer.from(l,"base64").toString(),u=this.verifySignature(o,r.signature,c);return this.checked=!0,u?(console.log(r.expireTime),n.info(`授权校验成功:${r.vipType||"free"},到期时间:${-1===r.expireTime?"永久":i(r.expireTime).format("YYYY-MM-DD HH:mm:ss")}`),this.setLicenseInfo(!0,{expireTime:r.expireTime,vipType:r.vipType||"free",secret:r.secret})):(n.warn("授权校验失败"),this.setLicenseInfo(!1,{message:"授权校验失败",originVipType:r.vipType,secret:r.secret,expireTime:r.expireTime}))}verifySignature(e,i,s){const r=t("RSA-SHA256");return r.update(e),r.verify(s,i,"base64")}async verifyFromRemote(){try{const e=await this.doCheckFromRemote();if(e.ok)m()||await this.reLocalVerify(this.licenseReq);else if(!1===e.ok){const t=e.message;return m()?(r.error("vip校验失败,退回基础版,原因:"+t),this.setLicenseInfo(!1,{message:t,expireTime:e.expiresAt})):void 0}}catch(e){r.error(e.message)}}};function m(){return h.isPlus&&(-1===h.expireTime||h.expireTime>Date.now())}function f(){return h.secret}function T(){return h.message}function U(){return h.expireTime}function y(){return h.vipType}function g(){return h.isComm&&(-1===h.expireTime||h.expireTime>Date.now())}function S(){return{isPlus:h.isPlus,isComm:h.isComm,vipType:h.vipType,expireTime:h.expireTime,secret:h.secret,originVipType:h.originVipType,message:h.message}}function V(){return v()?.license}function v(){if(null==d.licenseReq)throw new Error("请先调用verify方法");return s(d.licenseReq)}async function w(e){try{d.doCheckFromRemote=e.doCheckFromRemote;const t=await d.reLocalVerify(e);return setTimeout((()=>{d.verifyFromRemote()}),1e4),t}catch(e){return a().error(e),d.setLicenseInfo(!1,{message:"授权校验失败"})}}async function R(e){return await d.reLocalVerify(e)}!function(){async function e(){if(!m())return;const e=a();if(e.info("check license"),m()&&!h.secret)return e.info("license 校验失败!!!"),function(){const e=Math.floor(1e3*Math.random()*60*60);setTimeout((()=>{console.log("11111"),process.exit(0)}),e)}();await d.verifyFromRemote()}setInterval((async()=>{await e()}),864e5),setTimeout((async()=>{await e()}),2e4)}();class b{plusServerBaseUrls=["https://api.handfree.work/api","https://api.ai.docmirror.cn/api"];_validPlusServerBaseUrl;_lastCheckTime=0;http;logger;siteInfo;saveLicense;constructor(e){this.http=n,this.logger=r,this.siteInfo={bindUrl:e.bindUrl,bindUrl2:e.bindUrl2,subjectId:e.subjectId,installTime:e.installTime},this.saveLicense=e.saveLicense,process.env.PLUS_SERVER_BASE_URL&&(this.plusServerBaseUrls=[process.env.PLUS_SERVER_BASE_URL])}getSubjectId(){return this.siteInfo.subjectId}lastRequestRemoteTime=0;async verifyLocalOnly({license:e}){if(!e)return;const t=this.siteInfo.bindUrl;return await R({subjectId:this.getSubjectId(),bindUrl:t,license:e})}async verify({license:e}){if(!e)return;const t=this.siteInfo.bindUrl,i=this.siteInfo.bindUrl2,s=await w({subjectId:this.getSubjectId(),bindUrl:t,bindUrl2:i,license:e,doCheckFromRemote:async()=>{const e=await this.doVipCheck({bindUrl:t,bindUrl2:i}),s=U();if(console.log("expiresTime",s,"res.expiresAt",e.expiresAt,"getVipType()",y(),"res.vipType",e.vipType),s!=e.expiresAt||y()!=e.vipType){r.info("license需要更新"),await this.refreshLicense();const e=(new Date).getTime();if(e<this.lastRequestRemoteTime+3e5)throw new Error("更新license过于频繁");this.lastRequestRemoteTime=e}return e}});if(!s.verified){const e=s.message||"授权码校验失败";throw r.error(e),new Error(e)}}async refreshLicense(){const e=await this.request({url:"/activation/subject/license/update"});await this.updateLicense({license:e.license})}async checkServer(){if(this._validPlusServerBaseUrl&&Date.now()<this._lastCheckTime+828e5)return!0;for(const e of this.plusServerBaseUrls)try{const t=await this.sendCheckRequest(e);return this._validPlusServerBaseUrl=e,t}catch(t){this.logger.error(`server [${e}] is invalid:`,t)}this._lastCheckTime=Date.now()}async sendCheckRequest(e){const t={appKey:u};return await this.http.request({url:"/activation/app/get",method:"POST",data:t,baseURL:e})}async requestWithoutSign(e,t=!1){!0!==t&&await this.checkServer(),e.baseURL=this.getBaseURL(),e.method=e.method||"POST";const i=await this.http.request(e);if(!0===e.skipCheckRes)return i;if(0!==i.code)throw new Error("请求失败:"+i.message);return i.data}getBaseURL(){return this._validPlusServerBaseUrl||this.plusServerBaseUrls[0]}async request(e){if(!f())throw new Error("secret不存在");const{url:t}=e,i=e.data,s=Date.now(),r=await this.sign(i,s),n={subjectId:this.getSubjectId(),appKey:u,sign:r,timestamps:s};let o=JSON.stringify(n);o=Buffer.from(o).toString("base64");const c={"Content-Type":"application/json","X-Plus-Subject":o};return await this.requestWithoutSign({url:t,method:"POST",data:i,headers:c})}async sign(t,i){const s=t?JSON.stringify(t):"",r=f();if(!r)throw new Error("secret is not set");const n=`${s}.${i}.${r}`,o=e.createHash("sha256").update(n).digest("base64");return this.logger.info("content:",n??"","sign:",o),o}async bindUrl(e,t){const i=await this.request({url:"/activation/subject/urlBind",data:{subjectId:this.getSubjectId(),appKey:u,url:e,url2:t}});return this.siteInfo.bindUrl=e,this.siteInfo.bindUrl2=t,i}async register(){const e=(await this.requestWithoutSign({url:"/activation/subject/register",data:{appKey:u,subjectId:this.getSubjectId(),installTime:this.siteInfo.installTime}})).license;return await this.saveLicense(e),await this.verify({license:e}),e}async updateLicense(e){await this.saveLicense(e.license),await this.verifyLocalOnly({license:e.license})}async getAccessToken(){const e=await this.request({url:"/activation/subject/getAccessToken",data:{}});return{accessToken:e.accessToken,expiresIn:e.expiresIn}}async doVipCheck(e){const{bindUrl:t,bindUrl2:i}=e,s=await this.request({url:"/activation/subject/vip/check",data:{url:t,url2:i},skipCheckRes:!0});if(!s)throw new Error("check请求失败");if(1004===s?.code)throw console.log("请求参数错误:",s.message),new Error(s.message);return r.info(JSON.stringify(s)),s}async active(e,t){const i={appKey:u,code:e,subjectId:this.getSubjectId(),inviteCode:t},s=(await this.requestWithoutSign({url:"/activation/active",method:"post",data:i})).license;await this.updateLicense({license:s})}async getOrderCount(){return await this.request({url:"/activation/order/count",data:{appCode:"certd"}})}}function F(){if(!m())throw new Error("此为专业版功能,请升级到专业版")}function L(){if(!g())throw new Error("此为商业版功能,请升级到商业版")}c(r);export{u as AppKey,b as PlusRequestService,L as checkComm,F as checkPlus,U as getExpiresTime,V as getLicense,v as getLicenseReq,a as getLogger,S as getPlusInfo,T as getPlusMessage,f as getSecret,y as getVipType,g as isComm,m as isPlus,c as setLogger,w as verify,R as verifyLocalOnly};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@certd/plus-core",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.38.
|
|
4
|
+
"version": "1.38.6",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"types": "./dist/d/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"compile": "tsc --skipLibCheck --watch"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@certd/basic": "^1.38.
|
|
19
|
+
"@certd/basic": "^1.38.6",
|
|
20
20
|
"dayjs": "^1.11.7"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"tslib": "^2.8.1",
|
|
40
40
|
"typescript": "^5.4.2"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "1368259a1e780486204e9d814c88a741a373dcca"
|
|
43
43
|
}
|