@certd/plugin-plus 1.37.17 → 1.38.0
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 +133 -181
- package/build.md +1 -0
- package/dist/d/index.d.ts +1 -23
- package/dist/d/synology/client.d.ts +13 -3
- package/dist/d/synology/index.d.ts +0 -2
- package/dist/d/unicloud/client.d.ts +6 -3
- package/dist/index.js +1 -1
- package/fix-esm-import-paths.js +11 -11
- package/package.json +8 -25
- package/{rollup.config.mjs → rollup.config.js} +1 -19
- package/tsconfig.json +2 -1
- package/dist/d/1panel/access.d.ts +0 -17
- package/dist/d/1panel/client.d.ts +0 -37
- package/dist/d/1panel/index.d.ts +0 -3
- package/dist/d/1panel/plugins/deploy-to-website.d.ts +0 -18
- package/dist/d/1panel/plugins/index.d.ts +0 -1
- package/dist/d/1panel/util.d.ts +0 -1
- package/dist/d/alipay/access.d.ts +0 -11
- package/dist/d/alipay/index.d.ts +0 -1
- package/dist/d/aliyun/index.d.ts +0 -1
- package/dist/d/aliyun/plugins/deploy-to-ack/index.d.ts +0 -26
- package/dist/d/aliyun/plugins/deploy-to-all/index.d.ts +0 -39
- package/dist/d/aliyun/plugins/index.d.ts +0 -2
- package/dist/d/baidu/access.d.ts +0 -11
- package/dist/d/baidu/client.d.ts +0 -40
- package/dist/d/baidu/index.d.ts +0 -3
- package/dist/d/baidu/plugins/index.d.ts +0 -3
- package/dist/d/baidu/plugins/plugin-deploy-to-blb.d.ts +0 -17
- package/dist/d/baidu/plugins/plugin-deploy-to-cdn.d.ts +0 -11
- package/dist/d/baidu/plugins/plugin-upload-to-baidu.d.ts +0 -7
- package/dist/d/baishan/access.d.ts +0 -8
- package/dist/d/baishan/index.d.ts +0 -2
- package/dist/d/baishan/plugins/index.d.ts +0 -1
- package/dist/d/baishan/plugins/plugin-update-cert.d.ts +0 -10
- package/dist/d/baota/access.d.ts +0 -13
- package/dist/d/baota/index.d.ts +0 -4
- package/dist/d/baota/lib/client.d.ts +0 -14
- package/dist/d/baota/plugins/index.d.ts +0 -5
- package/dist/d/baota/plugins/plugin-delete-expiring-cert.d.ts +0 -6
- package/dist/d/baota/plugins/plugin-deploy-to-aawaf.d.ts +0 -15
- package/dist/d/baota/plugins/plugin-deploy-to-panel.d.ts +0 -8
- package/dist/d/baota/plugins/plugin-deploy-to-website-win.d.ts +0 -11
- package/dist/d/baota/plugins/plugin-deploy-to-website.d.ts +0 -17
- package/dist/d/baota/waf-access.d.ts +0 -19
- package/dist/d/cdnfly/access.d.ts +0 -19
- package/dist/d/cdnfly/index.d.ts +0 -2
- package/dist/d/cdnfly/plugins/index.d.ts +0 -1
- package/dist/d/cdnfly/plugins/plugin-deploy-to-cdn.d.ts +0 -25
- package/dist/d/ctyun/index.d.ts +0 -1
- package/dist/d/ctyun/lib.d.ts +0 -156
- package/dist/d/ctyun/plugins/index.d.ts +0 -1
- package/dist/d/ctyun/plugins/plugin-deploy-to-cdn.d.ts +0 -12
- package/dist/d/ftp/index.d.ts +0 -1
- package/dist/d/ftp/plugins/index.d.ts +0 -1
- package/dist/d/ftp/plugins/plugin-upload-to-ftp.d.ts +0 -16
- package/dist/d/host/index.d.ts +0 -1
- package/dist/d/host/plugins/index.d.ts +0 -1
- package/dist/d/host/plugins/plugin-deploy-to-iis.d.ts +0 -13
- package/dist/d/k8s/access.d.ts +0 -5
- package/dist/d/k8s/index.d.ts +0 -2
- package/dist/d/k8s/plugins/index.d.ts +0 -3
- package/dist/d/k8s/plugins/plugin-apply.d.ts +0 -12
- package/dist/d/k8s/plugins/plugin-ingress.d.ts +0 -15
- package/dist/d/k8s/plugins/plugin-secret.d.ts +0 -17
- package/dist/d/kuocai/access.d.ts +0 -9
- package/dist/d/kuocai/index.d.ts +0 -2
- package/dist/d/kuocai/plugins/index.d.ts +0 -1
- package/dist/d/kuocai/plugins/plugin-deploy-to-cdn.d.ts +0 -17
- package/dist/d/lecdn/access.d.ts +0 -10
- package/dist/d/lecdn/index.d.ts +0 -2
- package/dist/d/lecdn/plugins/index.d.ts +0 -2
- package/dist/d/lecdn/plugins/plugin-update-cert-v2.d.ts +0 -19
- package/dist/d/lecdn/plugins/plugin-update-cert.d.ts +0 -19
- package/dist/d/lib/index.d.ts +0 -6
- package/dist/d/lucky/access.d.ts +0 -16
- package/dist/d/lucky/index.d.ts +0 -2
- package/dist/d/lucky/plugins/index.d.ts +0 -1
- package/dist/d/lucky/plugins/plugin-upload.d.ts +0 -18
- package/dist/d/maoyun/access.d.ts +0 -8
- package/dist/d/maoyun/client.d.ts +0 -17
- package/dist/d/maoyun/index.d.ts +0 -2
- package/dist/d/maoyun/plugins/plugin-deploy-to-cdn.d.ts +0 -11
- package/dist/d/plesk/access.d.ts +0 -31
- package/dist/d/plesk/index.d.ts +0 -2
- package/dist/d/plesk/plugins/index.d.ts +0 -1
- package/dist/d/plesk/plugins/plugin-deploy-cert.d.ts +0 -11
- package/dist/d/plesk/plugins/plugin-refresh-cert.d.ts +0 -10
- package/dist/d/qiniu/index.d.ts +0 -1
- package/dist/d/qiniu/plugins/index.d.ts +0 -1
- package/dist/d/qiniu/plugins/plugin-deploy-to-oss.d.ts +0 -9
- package/dist/d/safeline/access.d.ts +0 -10
- package/dist/d/safeline/index.d.ts +0 -2
- package/dist/d/safeline/plugins/deploy-to-website.d.ts +0 -16
- package/dist/d/safeline/plugins/index.d.ts +0 -1
- package/dist/d/synology/access.d.ts +0 -22
- package/dist/d/synology/plugins/index.d.ts +0 -1
- package/dist/d/synology/plugins/plugin-deploy-to-panel.d.ts +0 -11
- package/dist/d/unicloud/access.d.ts +0 -7
- package/dist/d/unicloud/index.d.ts +0 -3
- package/dist/d/unicloud/plugins/index.d.ts +0 -1
- package/dist/d/unicloud/plugins/plugin-deploy-to-space.d.ts +0 -11
- package/dist/d/wxpay/access.d.ts +0 -13
- package/dist/d/wxpay/index.d.ts +0 -1
- package/dist/d/yidun/access-rcdn.d.ts +0 -9
- package/dist/d/yidun/access-sms.d.ts +0 -9
- package/dist/d/yidun/access.d.ts +0 -9
- package/dist/d/yidun/index.d.ts +0 -4
- package/dist/d/yidun/plugins/index.d.ts +0 -2
- package/dist/d/yidun/plugins/plugin-deploy-to-cdn.d.ts +0 -13
- package/dist/d/yidun/plugins/plugin-deploy-to-rcdn.d.ts +0 -17
- package/dist/d/yizhifu/access.d.ts +0 -8
- package/dist/d/yizhifu/index.d.ts +0 -1
- package/dist/util-9726341d.js +0 -1
- package/export-plugin-yaml.js +0 -99
- package/metadata/access_1panel.yaml +0 -81
- package/metadata/access_alipay.yaml +0 -29
- package/metadata/access_baidu.yaml +0 -22
- package/metadata/access_baishan.yaml +0 -15
- package/metadata/access_baota-waf.yaml +0 -36
- package/metadata/access_baota.yaml +0 -50
- package/metadata/access_cdnfly.yaml +0 -29
- package/metadata/access_k8s.yaml +0 -16
- package/metadata/access_kuocaicdn.yaml +0 -20
- package/metadata/access_lecdn.yaml +0 -27
- package/metadata/access_lucky.yaml +0 -29
- package/metadata/access_maoyun.yaml +0 -26
- package/metadata/access_plesk.yaml +0 -27
- package/metadata/access_safeline.yaml +0 -26
- package/metadata/access_synology.yaml +0 -80
- package/metadata/access_unicloud.yaml +0 -21
- package/metadata/access_wxpay.yaml +0 -40
- package/metadata/access_yfysms.yaml +0 -21
- package/metadata/access_yidun.yaml +0 -22
- package/metadata/access_yidunrcdn.yaml +0 -20
- package/metadata/access_yizhifu.yaml +0 -45
- package/metadata/deploy_1PanelDeployToWebsitePlugin.yaml +0 -60
- package/metadata/deploy_AliyunDeployCertToAll.yaml +0 -174
- package/metadata/deploy_BaiduDeployToCDN.yaml +0 -43
- package/metadata/deploy_BaishanUpdateCert.yaml +0 -47
- package/metadata/deploy_BaotaDeployPanelCert.yaml +0 -34
- package/metadata/deploy_BaotaDeployWebSiteCert.yaml +0 -85
- package/metadata/deploy_CdnflyDeployToCDN.yaml +0 -123
- package/metadata/deploy_CtyunDeployToCDN.yaml +0 -97
- package/metadata/deploy_DeployCertToAliyunAck.yaml +0 -122
- package/metadata/deploy_HostDeployToIIS.yaml +0 -76
- package/metadata/deploy_K8sDeployToIngress.yaml +0 -46
- package/metadata/deploy_K8sDeployToSecret.yaml +0 -50
- package/metadata/deploy_KuocaiDeployToRCDN.yaml +0 -59
- package/metadata/deploy_LeCDNUpdateCert.yaml +0 -57
- package/metadata/deploy_LeCDNUpdateCertV2.yaml +0 -58
- package/metadata/deploy_LuckyUpdateCert.yaml +0 -73
- package/metadata/deploy_MaoyunDeployToCdn.yaml +0 -72
- package/metadata/deploy_PleskDeploySiteCert.yaml +0 -72
- package/metadata/deploy_QiniuDeployCertToOSS.yaml +0 -39
- package/metadata/deploy_SafelineDeployToWebsitePlugin.yaml +0 -75
- package/metadata/deploy_SynologyDeployToPanel.yaml +0 -45
- package/metadata/deploy_UniCloudDeployToSpace.yaml +0 -64
- package/metadata/deploy_UploadCertToFTP.yaml +0 -171
- package/metadata/deploy_YidunDeployToCDN.yaml +0 -48
- package/metadata/deploy_YidunDeployToRCDN.yaml +0 -59
package/build.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
18:05
|
package/dist/d/index.d.ts
CHANGED
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
export * from "./lib/index.js";
|
|
2
|
-
export * from "./baota/index.js";
|
|
3
|
-
export * from "./yidun/index.js";
|
|
4
|
-
export * from "./ftp/index.js";
|
|
5
|
-
export * from "./cdnfly/index.js";
|
|
6
|
-
export * from "./aliyun/index.js";
|
|
7
1
|
export * from "./synology/index.js";
|
|
8
|
-
export * from "./k8s/index.js";
|
|
9
|
-
export * from "./1panel/index.js";
|
|
10
|
-
export * from "./qiniu/index.js";
|
|
11
|
-
export * from "./baidu/index.js";
|
|
12
|
-
export * from "./lecdn/index.js";
|
|
13
|
-
export * from "./baishan/index.js";
|
|
14
|
-
export * from "./host/index.js";
|
|
15
|
-
export * from "./plesk/index.js";
|
|
16
|
-
export * from "./yizhifu/index.js";
|
|
17
|
-
export * from "./alipay/index.js";
|
|
18
|
-
export * from "./wxpay/index.js";
|
|
19
|
-
export * from "./safeline/index.js";
|
|
20
|
-
export * from "./ctyun/index.js";
|
|
21
|
-
export * from "./lucky/index.js";
|
|
22
|
-
export * from "./kuocai/index.js";
|
|
23
|
-
export * from "./unicloud/index.js";
|
|
24
|
-
export * from "./maoyun/index.js";
|
|
25
2
|
export * from "./xinnet/index.js";
|
|
3
|
+
export * from "./unicloud/client.js";
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import { SynologyAccess } from "./access";
|
|
2
1
|
import { HttpClient, ILogger } from "@certd/basic";
|
|
2
|
+
import { CertInfo } from '@certd/plugin-lib';
|
|
3
|
+
export type SynologyAccessType = {
|
|
4
|
+
username: string;
|
|
5
|
+
password: string;
|
|
6
|
+
otp?: string;
|
|
7
|
+
deviceId?: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
};
|
|
3
12
|
export type SynologyAccessToken = {
|
|
4
13
|
sid: string;
|
|
5
14
|
did?: string;
|
|
@@ -19,12 +28,12 @@ export type SynologyRequest = {
|
|
|
19
28
|
useSynoToken?: boolean;
|
|
20
29
|
};
|
|
21
30
|
export declare class SynologyClient {
|
|
22
|
-
access:
|
|
31
|
+
access: SynologyAccessType;
|
|
23
32
|
http: HttpClient;
|
|
24
33
|
logger: ILogger;
|
|
25
34
|
skipSslVerify: boolean;
|
|
26
35
|
token: SynologyAccessToken;
|
|
27
|
-
constructor(access:
|
|
36
|
+
constructor(access: SynologyAccessType, http: HttpClient, logger: ILogger, skipSslVerify: boolean);
|
|
28
37
|
doLogin(): Promise<SynologyAccessToken>;
|
|
29
38
|
doLoginWithOTPCode(otpCode: string): Promise<SynologyAccessToken>;
|
|
30
39
|
private getLoginUrl;
|
|
@@ -32,4 +41,5 @@ export declare class SynologyClient {
|
|
|
32
41
|
doRequest(req: SynologyRequest): Promise<any>;
|
|
33
42
|
getCertList(): Promise<any>;
|
|
34
43
|
getInfo(): Promise<any>;
|
|
44
|
+
updateCertToPanel(certItem: any, cert: CertInfo): Promise<void>;
|
|
35
45
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { UniCloudAccess } from "./access";
|
|
2
1
|
import { HttpClient, HttpRequestConfig, ILogger } from "@certd/basic";
|
|
3
|
-
import { CertInfo } from "@certd/plugin-
|
|
2
|
+
import { CertInfo } from "@certd/plugin-lib";
|
|
3
|
+
export type UniCloudAccessType = {
|
|
4
|
+
email: string;
|
|
5
|
+
password: string;
|
|
6
|
+
};
|
|
4
7
|
type UniCloudClientOpts = {
|
|
5
|
-
access:
|
|
8
|
+
access: UniCloudAccessType;
|
|
6
9
|
logger: ILogger;
|
|
7
10
|
http: HttpClient;
|
|
8
11
|
};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AbstractTaskPlugin as e,TaskInput as t,IsTaskPlugin as s,pluginGroups as o,RunStrategy as i,AccessInput as n,IsAccess as r,BaseAccess as a,TaskOutput as c,Pager as p}from"@certd/pipeline";import{isPlus as d}from"@certd/plus-core";import l from"node:crypto";import*as h from"node:querystring";import{CertApplyPluginNames as u,CertReader as m}from"@certd/plugin-cert";import{createCertDomainGetterInputDefine as g,createRemoteSelectInputDefine as y,FtpClient as f,AliyunClient as w,AliyunSslClient as v,QiniuClient as S,SshClient as k}from"@certd/plugin-lib";import{uniq as b,get as I,merge as C,isArray as q}from"lodash-es";import x from"dayjs";import{utils as D,HttpError as T,http as A}from"@certd/basic";import P from"querystring";import R from"fs";import $ from"form-data";import N from"crypto";import{tmpdir as O}from"node:os";import L from"node:path";import E from"crypto-js";function j(){if(!d())throw new Error("此插件仅供专业版中使用")}class _ extends e{setCtx(e){super.setCtx(e),j()}}function K(e,t,s,o){var i,n=arguments.length,r=n<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,s):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,s,o);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(n<3?i(r):n>3?i(t,s,r):i(t,s))||r);return n>3&&r&&Object.defineProperty(t,s,r),r}function M(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}"function"==typeof SuppressedError&&SuppressedError;class G{access;http;constructor(e,t){this.access=e,this.http=t}getRequestToken(){const e=Math.floor((new Date).getTime()/1e3),t=e+this.getMd5(this.access.apiSecret);return{request_token:this.getMd5(t),request_time:""+e}}getMd5(e){return l.createHash("md5").update(e).digest("hex")}async doRequest(e,t,s={},o){const i={...this.getRequestToken(),...s},n=h.stringify(i);let r=this.access.panelUrl;r.endsWith("/")&&(r=r.substring(0,r.length-1));let a=`${r}${e}`;t&&(a=`${a}?action=${t}`);const c=await this.http.request({url:a,method:"post",headers:{"Content-Type":"application/x-www-form-urlencoded"},data:n,...o,skipSslVerify:this.access.skipSslVerify??!0});if(!o?.skipCheckRes&&!1===c.status)throw new Error(c.msg);return c}async doWindowsRequest(e,t,s){const o={...this.getRequestToken(),...t},i=`${this.access.panelUrl}${e}`,n=await this.http.request({url:i,method:"post",data:o,...s,skipSslVerify:this.access.skipSslVerify??!0});if(!s?.skipCheckRes&&!1===n.status)throw new Error(n.msg);return n}}let W=class extends _{cert;accessId;async onInstance(){}async execute(){const{cert:e,accessId:t}=this,s=await this.getAccess(t),o=this.ctx.http,i=new G(s,o),n=`baota-lock-${t}`;await this.ctx.utils.locker.execute(n,(async()=>{const t=await i.doRequest("/config","SavePanelSSL",{privateKey:e.key,certPem:e.crt},{skipSslVerify:!0});this.logger.info(t?.msg)}))}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],W.prototype,"cert",void 0),K([t({title:"宝塔授权",helper:"baota的接口密钥",component:{name:"access-selector",type:"baota"},required:!0}),M("design:type",String)],W.prototype,"accessId",void 0),W=K([s({name:"BaotaDeployPanelCert",title:"宝塔-面板证书部署",icon:"svg:icon-bt",group:o.panel.key,desc:"部署宝塔面板本身的ssl证书",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!0})],W),new W;let U=class extends e{cert;certDomains;accessId;isDockerSite=!1;siteName;async onInstance(){}async execute(){const{cert:e,accessId:t}=this,s=await this.getAccess(t),o=this.ctx.http,i=new G(s,o);this.logger.info(`siteName:${this.siteName}`);const n=[];"string"==typeof this.siteName?n.push(this.siteName):n.push(...this.siteName);const r=`baota-lock-${t}`;for(const t of n)await this.ctx.utils.locker.execute(r,(async()=>{if(this.logger.info(`为站点:${t}设置证书,目前支持宝塔网站站点、docker站点`),this.isDockerSite){const s=await i.doRequest("/mod/docker/com/set_ssl","",{site_name:t,key:e.key,csr:e.crt});this.logger.info(s?.msg)}else{const s=await i.doRequest("/site","SetSSL",{type:0,siteName:t,key:e.key,csr:e.crt});this.logger.info(s?.msg)}}))}async onGetSiteList(){const e=await this.getAccess(this.accessId),t=this.ctx.http,s=new G(e,t),o=this.certDomains;let i=[];const n=async()=>{const e={cert_list:JSON.stringify(o)},t=await s.doRequest("/ssl?action=GetSiteDomain",null,e,{skipCheckRes:!1});this.logger.info(t),i=t.all||[]},r=async()=>{const e=await s.doRequest("/mod/docker/com/get_site_list",null,{});if(this.logger.info(e),e.data){const t=e.data.map((e=>e.name));i=[...i,...t],i=b(i)}};if(this.isDockerSite?await r():await n(),!i||0===i.length)throw new Error("未找到站点,你可以手动输入");const a=[];for(const e of i)a.push({value:e,label:e,domain:e});return this.ctx.utils.options.buildGroupOptions(a,o)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],U.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],U.prototype,"certDomains",void 0),K([t({title:"宝塔授权",helper:"baota的接口密钥",component:{name:"access-selector",type:"baota"},required:!0}),M("design:type",String)],U.prototype,"accessId",void 0),K([t({title:"是否Docker站点",value:!1,component:{name:"a-switch",vModel:"checked"},helper:"是否为docker站点",required:!0}),M("design:type",Object)],U.prototype,"isDockerSite",void 0),K([t({title:"站点名称",component:{name:"remote-select",vModel:"value",mode:"tags",action:"GetSiteList",watches:["certDomains","accessId","isDockerSite"]},required:!0,mergeScript:"\n return {\n component:{\n form: ctx.compute(({form})=>{\n return form\n })\n },\n }\n ",helper:"将会自动获取证书匹配的站点名称\n宝塔版本低于9.0.0时,此处会获取失败,忽略错误,手动输入站点域名即可"}),M("design:type",Object)],U.prototype,"siteName",void 0),U=K([s({name:"BaotaDeployWebSiteCert",title:"宝塔-网站证书部署",icon:"svg:icon-bt",group:o.panel.key,desc:"部署宝塔管理的站点的ssl证书,目前支持宝塔网站站点、docker站点等。本插件也支持aaPanel。",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],U),new U;let B=class extends e{cert;certDomains;accessId;siteIds;async onInstance(){}async execute(){const{cert:e,accessId:t}=this,s=await this.getAccess(t),o=`baota-lock-${t}`;for(const t of this.siteIds){this.logger.info(`为站点:${t}设置证书`);const i=(await this.getSiteInfo(s,t)).server.listen_ssl_port;await this.ctx.utils.locker.execute(o,(async()=>{await s.doRequest({url:"/api/wafmastersite/modify_site",data:{types:"openCert",site_id:t,server:{listen_ssl_port:i,ssl:{is_ssl:1,full_chain:e.crt,private_key:e.key}}}})})),this.logger.info(`站点:${t} 证书部署成功`)}this.logger.info("部署成功")}async getSiteInfo(e,t){const s=await e.doRequest({url:"/api/wafmastersite/get_site_list",data:{site_id:t,p_size:1,p:1,site_name:""}});if(!s.list||0===s.list.length)throw new Error(`未找到站点:${t}`);return s.list[0]}async onGetSiteList(e){const t=await this.getAccess(this.accessId),s=(await t.getSiteList({pageNo:1,pageSize:100,query:e.searchKey||""})).list;if(!s||0===s.length)throw new Error("未找到站点,你可以手动输入");const o=[];for(const e of s)o.push({value:e.site_id,label:`${e.site_name}<${e.site_id}>`,domain:e.server.server_name});return this.ctx.utils.options.buildGroupOptions(o,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],B.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],B.prototype,"certDomains",void 0),K([t({title:"宝塔WAF授权",helper:"aaWAF的接口密钥",component:{name:"access-selector",type:"baotawaf"},required:!0}),M("design:type",String)],B.prototype,"accessId",void 0),K([t({title:"站点ID",component:{name:"remote-select",vModel:"value",mode:"tags",action:"onGetSiteList",search:!0,watches:["certDomains","accessId"]},required:!0,helper:"将会自动获取证书匹配的站点,请选择要部署证书的站点"}),M("design:type",Array)],B.prototype,"siteIds",void 0),B=K([s({name:"BaotaDeployWAF",title:"宝塔-WAF证书部署",icon:"svg:icon-bt",group:o.panel.key,desc:"部署宝塔云WAF/aaWAF",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],B),new B;let V=class extends e{cert;certDomains;accessId;siteIds;async onInstance(){}async execute(){const{cert:e,accessId:t}=this,s=await this.getAccess(t),o=this.ctx.http,i=new G(s,o);this.logger.info(`siteIds:${this.siteIds}`);const n=this.siteIds??[],r=`baota-lock-${t}`;for(const t of n)await this.ctx.utils.locker.execute(r,(async()=>{this.logger.info(`为站点:${t}设置证书`);const s=await i.doWindowsRequest("/site/set_site_ssl",{siteid:t,status:!0,sslType:"",cert:e.crt,key:e.key});this.logger.info(s?.msg)}))}async onGetSiteList(){const e=await this.getAccess(this.accessId),t=this.ctx.http,s=new G(e,t),o=this.certDomains;let i=[];if(await(async()=>{const e=await s.doWindowsRequest("/datalist/get_data_list",{table:"sites",limit:500},{skipCheckRes:!1});this.logger.info(e.data),i=e.data||[]})(),!i||0===i.length)throw new Error("未找到站点,你可以手动输入");const n=[];for(const e of i)n.push({value:e.id,label:`${e.name}<${e.id}>`,domain:e.name});return this.ctx.utils.options.buildGroupOptions(n,o)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],V.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],V.prototype,"certDomains",void 0),K([t({title:"宝塔授权",helper:"baota的接口密钥",component:{name:"access-selector",type:"baota"},required:!0}),M("design:type",String)],V.prototype,"accessId",void 0),K([t({title:"站点Id",component:{name:"remote-select",vModel:"value",mode:"tags",action:"GetSiteList",watches:["certDomains","accessId"]},required:!0,mergeScript:"\n return {\n component:{\n form: ctx.compute(({form})=>{\n return form\n })\n },\n }\n ",helper:"将会自动获取证书匹配的站点名称"}),M("design:type",Array)],V.prototype,"siteIds",void 0),V=K([s({name:"BaotaDeployWebSiteWin",title:"宝塔win-网站证书部署",icon:"svg:icon-bt",group:o.panel.key,desc:"部署到Windows版宝塔管理的站点的ssl证书",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],V),new V;let F=class extends _{accessId;async onInstance(){}async execute(){const{accessId:e}=this,t=await this.getAccess(e),s=this.ctx.http,o=new G(t,s),i=await o.doRequest("/ssl","get_cert_list",null),n=(new Date).getTime();for(const e of i)if(x(e.not_after).valueOf()<n){this.logger.info(`证书: ${e.name} 过期时间: ${e.not_after},已过期,删除`);try{await o.doRequest("/ssl","remove_cloud_cert",{local:1,ssl_hash:e.hash})}catch(t){this.logger.error(`删除证书: ${e.name} 失败`,t)}await this.ctx.utils.sleep(1e3)}else this.logger.info(`证书: ${e.name} 过期时间: ${e.not_after},未过期`);this.logger.info(i?.msg)}};K([t({title:"宝塔授权",helper:"baota的接口密钥",component:{name:"access-selector",type:"baota"},required:!0}),M("design:type",String)],F.prototype,"accessId",void 0),F=K([s({name:"BaotaDeleteExpiringCert",title:"宝塔-删除过期证书",icon:"svg:icon-bt",group:o.panel.key,desc:"删除证书夹中过期证书",showRunStrategy:!0,default:{strategy:{runStrategy:i.AlwaysRun}},needPlus:!0})],F),new F;let H=class extends a{panelUrl="";apiSecret="";skipSslVerify=!0;isWindows=!1;testRequest=!0;async onTestRequest(){const e=this.ctx.http,t=new G(this,e);if(this.isWindows)return await t.doWindowsRequest("/site/get_site_types",{},{skipCheckRes:!1}),"ok";return await t.doRequest("/site?action=get_site_types",null,{},{skipCheckRes:!1}),"ok"}};K([n({title:"宝塔URL地址",component:{placeholder:"http://192.168.42.237:41896"},helper:"宝塔面板的url地址,不要带安全入口,例如:http://192.168.42.237:41896",required:!0}),M("design:type",Object)],H.prototype,"panelUrl",void 0),K([n({title:"接口密钥",component:{placeholder:"接口密钥"},helper:"宝塔面板设置->面板设置->API接口->接口配置->接口密钥。\n必须要加IP白名单,您可以点击下方测试按钮,报错之后会打印IP,将IP加入白名单之后再次测试即可",required:!0,encrypt:!0}),M("design:type",Object)],H.prototype,"apiSecret",void 0),K([n({title:"忽略证书校验",value:!0,component:{name:"a-switch",vModel:"checked"},helper:"如果面板的url是https,且使用的是自签名证书,则需要开启此选项,其他情况可以关闭"}),M("design:type",Object)],H.prototype,"skipSslVerify",void 0),K([n({title:"windows版",value:!1,component:{name:"a-switch",vModel:"checked"},helper:"是否是windows版"}),M("design:type",Object)],H.prototype,"isWindows",void 0),K([n({title:"测试",component:{name:"api-test",action:"TestRequest"},helper:"点击测试接口看是否正常"}),M("design:type",Object)],H.prototype,"testRequest",void 0),H=K([r({name:"baota",title:"baota授权",desc:"",icon:"svg:icon-bt",order:2})],H),new H;let z=class extends a{panelUrl="";apiSecret="";skipSslVerify=!1;testRequest=!0;async onTestRequest(){await this.doRequest({url:"/api/wafmastersite/get_site_list",data:{p:1,p_size:1,site_name:""}})}async getSiteList(e={}){const t={p:e.pageNo??1,p_size:e.pageSize??100,site_name:e.query??""};return await this.doRequest({url:"/api/wafmastersite/get_site_list",data:t})}async doRequest(e){const t=this.ctx.http;let s=this.panelUrl;s.endsWith("/")&&(s=s.substring(0,s.length-1));const o=Math.floor(Date.now()/1e3),i={waf_request_time:o,waf_request_token:D.hash.md5(o+D.hash.md5(this.apiSecret)),...e.headers},n=await t.request({baseURL:s,method:"POST",data:e.data,skipSslVerify:this.skipSslVerify,...e,headers:{...i}});if(n&&0===n.code)return n.res;throw new Error(`请求失败: ${n.msg||"未知错误"}`)}};K([n({title:"在宝塔WAF URL",component:{placeholder:"http://192.168.42.237:41896"},helper:"在宝塔WAF的URL地址,不要带安全入口,例如:http://192.168.42.237:41896",required:!0}),M("design:type",Object)],z.prototype,"panelUrl",void 0),K([n({title:"WAF API 密钥",component:{placeholder:"请输入WAF API接口密钥"},helper:"在宝塔WAF设置页面 - API接口中获取的API密钥。\n必须添加IP白名单,请确保已将CertD服务器IP加入白名单",required:!0,encrypt:!0}),M("design:type",Object)],z.prototype,"apiSecret",void 0),K([n({title:"忽略SSL证书校验",value:!1,component:{name:"a-switch",vModel:"checked"},helper:"如果面板使用的是自签名SSL证书,则需要开启此选项"}),M("design:type",Object)],z.prototype,"skipSslVerify",void 0),K([n({title:"测试",component:{name:"api-test",action:"onTestRequest"},helper:"点击测试WAF请求"}),M("design:type",Object)],z.prototype,"testRequest",void 0),z=K([r({name:"baotawaf",title:"宝塔云WAF授权",desc:"用于连接和管理宝塔云WAF服务的授权配置",icon:"svg:icon-bt"})],z),new z;let J=class extends e{certId;domain;cert;accessId;async onInstance(){}async execute(){const{domain:e,certId:t,cert:s}=this;if(!e&&!t)throw new Error("证书ID和网站域名必须填写一个");t>0?await this.updateByCertId(s,t):await this.updateByDomain(s)}async updateByCertId(e,t){this.logger.info(`更新证书,证书ID:${t}`);const s=`http://user.yiduncdn.com/v1/certs/${t}`;await this.doRequest(s,"PUT",{cert:e.crt,key:e.key})}async doRequest(e,t,s){const o=await this.getAccess(this.accessId),{apiKey:i,apiSecret:n}=o,r=this.ctx.http,a=await r.request({url:e,method:t,headers:{"api-key":i,"api-secret":n},data:s});if(0!=a.code)throw new Error(a.msg);return a}async updateByDomain(e){const t=await this.doRequest("http://user.yiduncdn.com/v1/sites","GET",{domain:this.domain});if(0===t.data.length)throw new Error(`未找到域名相关站点:${this.domain}`);let s=null;for(const e of t.data)e.domain===this.domain&&(s=e);if(!s)throw new Error(`未找到域名匹配的站点:${this.domain}`);if(s.https_listen?.cert){const t=s.https_listen.cert;await this.updateByCertId(e,t)}else{this.logger.info(`创建证书,域名:${this.domain}`);const t="http://user.yiduncdn.com/v1/certs",o=this.domain+"_"+(new Date).getTime();await this.doRequest(t,"POST",{name:o,type:"custom",cert:e.crt,key:e.key});const i=(await this.doRequest(t,"GET",{name:o})).data[0].id,n="http://user.yiduncdn.com/v1/sites";await this.doRequest(n,"PUT",{id:s.id,https_listen:{cert:i}})}}};K([t({title:"证书ID",component:{name:"a-input-number",vModel:"value"},helper:"证书ID,在证书管理页面查看,每条记录都有证书id"}),M("design:type",Number)],J.prototype,"certId",void 0),K([t({title:"网站域名",component:{name:"a-input",vModel:"value"},helper:"网站域名和证书ID选填其中一个,填了证书ID,则忽略网站域名"}),M("design:type",Number)],J.prototype,"domain",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],J.prototype,"cert",void 0),K([t({title:"易盾授权",helper:"易盾CDN授权",component:{name:"access-selector",type:"yidun"},required:!0}),M("design:type",String)],J.prototype,"accessId",void 0),J=K([s({name:"YidunDeployToCDN",title:"易盾-部署到易盾DCDN",icon:"material-symbols:shield-outline",group:o.cdn.key,desc:"主要是防御,http://user.yiduncdn.com/",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],J),new J;let X=class extends e{cert;accessId;domains;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=await this.getLoginToken(e);for(const e of this.domains){const s=this.cert,o={doMainId:e,https:{https_status:"on",certificate_name:this.appendTimeSuffix("certd"),certificate_source:"0",certificate_value:s.crt,private_key:s.key}};await this.doRequest("https://rhcdn.yiduncdn.com/CdnDomainHttps/httpsConfiguration",t,o),this.logger.info(`站点${e}证书更新成功`)}}async getLoginToken(e){const t={userAccount:e.username,userPwd:e.password,remember:!0},s=this.ctx.http,o=await s.request({url:"https://rhcdn.yiduncdn.com/login/loginUser",method:"POST",data:t,headers:{"Content-Type":"application/x-www-form-urlencoded"},returnOriginRes:!0});if(!o.data?.success)throw new Error(o.data?.message);const i=this.ctx.utils.request.getCookie(o,"JSESSIONID"),n=o.data?.data;return{jsessionId:i,token:n}}async getDomainList(e){const t=await this.doRequest("https://rhcdn.yiduncdn.com/CdnDomain/queryForDatatables",e,{draw:1,start:0,length:1e3,search:{value:"",regex:!1}});return t.data?.data}async doRequest(e,t,s){const o=this.ctx.http,i=await o.request({url:e,method:"POST",headers:{Cookie:`JSESSIONID=${t.jsessionId};kuocai_cdn_token=${t.token}`},data:s});if(!i.success)throw new Error(i.message);return i}async onGetDomainList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getAccess(this.accessId),s=await this.getLoginToken(t),o=await this.getDomainList(s);if(!o||0===o.length)throw new Error("您账户下还没有站点域名,请先添加域名");return o.map((e=>({label:`${e.domainName}<${e.id}>`,value:e.id})))}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],X.prototype,"cert",void 0),K([t({title:"易盾RCDN授权",helper:"易盾RCDN授权",component:{name:"access-selector",type:"yidunrcdn"},required:!0}),M("design:type",String)],X.prototype,"accessId",void 0),K([t(y({title:"域名列表",helper:"选择要部署证书的站点域名",typeName:"YidunDeployToRCDNPlugin",action:X.prototype.onGetDomainList.name})),M("design:type",Array)],X.prototype,"domains",void 0),X=K([s({name:"YidunDeployToRCDN",title:"易盾-部署到易盾RCDN",icon:"material-symbols:shield-outline",group:o.cdn.key,desc:"易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8)",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],X),new X;let Y=class extends a{apiKey="";apiSecret=""};K([n({title:"api_key",component:{placeholder:"api_key"},helper:"http://user.yiduncdn.com/console/index.html#/account/config/api,点击开启后获取",required:!0,encrypt:!0}),M("design:type",Object)],Y.prototype,"apiKey",void 0),K([n({title:"api_secret",component:{placeholder:"api_secret"},helper:"http://user.yiduncdn.com/console/index.html#/account/config/api,点击开启后获取",required:!0,encrypt:!0}),M("design:type",Object)],Y.prototype,"apiSecret",void 0),Y=K([r({name:"yidun",title:"易盾DCDN授权",icon:"material-symbols:shield-outline",desc:"https://user.yiduncdn.com"})],Y),new Y;let Q=class extends a{username="";password=""};K([n({title:"账户",component:{placeholder:"手机号"},required:!0,encrypt:!0}),M("design:type",Object)],Q.prototype,"username",void 0),K([n({title:"密码",component:{placeholder:"password"},required:!0,encrypt:!0}),M("design:type",Object)],Q.prototype,"password",void 0),Q=K([r({name:"yidunrcdn",title:"易盾rcdn授权",icon:"material-symbols:shield-outline",desc:"易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8)"})],Q),new Q;let Z=class extends a{keyId="";keySecret=""};K([n({title:"KeyID",component:{placeholder:"api_key"},helper:"[获取密钥](http://sms.yfyidc.cn/user/index#)",required:!0,encrypt:!0}),M("design:type",Object)],Z.prototype,"keyId",void 0),K([n({title:"KeySecret",component:{placeholder:""},required:!0,encrypt:!0}),M("design:type",Object)],Z.prototype,"keySecret",void 0),Z=K([r({name:"yfysms",title:"易发云短信",icon:"material-symbols:shield-outline",desc:"sms.yfyidc.cn/"})],Z),new Z;let ee=class extends e{certType;crtPath;keyPath;icPath;pfxPath;derPath;jksPath;onePath;cert;accessId;async onInstance(){}async execute(){const{cert:e,accessId:t}=this,s=await this.getAccess(t),o=new f({access:s,logger:this.logger});await o.connect((async()=>{const t=new m(e);await t.readCertFile({logger:this.logger,handle:async({reader:e,tmpCrtPath:t,tmpKeyPath:s,tmpDerPath:i,tmpPfxPath:n,tmpIcPath:r,tmpJksPath:a,tmpOnePath:c})=>{try{await o.upload(t,this.crtPath),await o.upload(s,this.keyPath),await o.upload(r,this.icPath),await o.upload(n,this.pfxPath),await o.upload(i,this.derPath),await o.upload(a,this.jksPath),await o.upload(c,this.onePath)}catch(e){throw this.logger.error("请确认路径是否包含文件名,路径本身不能是目录,路径不能有*?之类的特殊符号,要有写入权限"),e}}})})),this.logger.info("执行完成")}};K([t({title:"证书格式",helper:"要部署的证书格式,支持pem、pfx、der、jks",component:{name:"a-select",options:[{value:"pem",label:"pem,Nginx等大部分应用"},{value:"pfx",label:"pfx,一般用于IIS"},{value:"der",label:"der,一般用于Apache"},{value:"jks",label:"jks,一般用于JAVA应用"},{value:"one",label:"一体化证书,证书和私钥合并为一个pem文件"}]},required:!0}),M("design:type",String)],ee.prototype,"certType",void 0),K([t({title:"PEM证书保存路径",helper:"需要有写入权限,路径要包含文件名",component:{placeholder:"/test/fullchain.pem"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'pem';\n })\n }\n ",required:!0,rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"crtPath",void 0),K([t({title:"私钥保存路径",helper:"需要有写入权限,路径要包含文件名",component:{placeholder:"/test/privatekey.pem"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'pem';\n })\n }\n ",required:!0,rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"keyPath",void 0),K([t({title:"中间证书保存路径",helper:"需要有写入权限,路径要包含文件名",component:{placeholder:"/test/immediate.pem"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'pem';\n })\n }\n ",rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"icPath",void 0),K([t({title:"PFX证书保存路径",helper:"需要有写入权限,路径要包含文件名",component:{placeholder:"/test/cert.pfx"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'pfx';\n })\n }\n ",required:!0,rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"pfxPath",void 0),K([t({title:"DER证书保存路径",helper:"需要有写入权限,路径要包含文件名\n.der和.cer是相同的东西,改个后缀名即可",component:{placeholder:"/test/cert.der 或 /test/cert.cer"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'der';\n })\n }\n ",required:!0,rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"derPath",void 0),K([t({title:"jks证书保存路径",helper:"证书原本的保存路径,路径要包含文件名",component:{placeholder:"/test/javaapp/cert.jks"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'jks';\n })\n }\n ",required:!0,rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"jksPath",void 0),K([t({title:"一体化证书保存路径",helper:"证书原本的保存路径,路径要包含文件名",component:{placeholder:"/app/ssl/one.pem"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.certType === 'one';\n })\n }\n ",required:!0,rules:[{type:"filepath"}]}),M("design:type",String)],ee.prototype,"onePath",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],ee.prototype,"cert",void 0),K([t({title:"FTP授权",component:{name:"access-selector",type:"ftp"},required:!0}),M("design:type",String)],ee.prototype,"accessId",void 0),ee=K([s({name:"UploadCertToFTP",title:"FTP-上传证书到FTP",icon:"mdi:folder-upload-outline",group:o.host.key,desc:"将证书上传到FTP服务器",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],ee),new ee;let te=class extends e{cert;certDomains;accessId;autoMatch;certId;siteId;access;uploadCertId;async onInstance(){this.access=await this.getAccess(this.accessId)}async execute(){const{cert:e,siteId:t,certId:s}=this;if(this.autoMatch)return this.logger.info("自动匹配站点更新证书"),void await this.updateByDomain();if(null!=s){let t=s;Array.isArray(s)||(t=[s]);for(const s of t)await this.updateByCertId(e,s)}if(null!=t){let s=t;Array.isArray(t)||(s=[t]);for(const t of s)await this.updateBySiteId(e,t)}}async updateByCertId(e,t){this.logger.info(`更新证书,证书ID:${t}`);const s=`/v1/certs/${t}`;await this.doRequest(s,"PUT",{cert:e.crt,key:e.key})}async doRequest(e,t,s){return await this.access.doRequest({url:e,method:t,data:s})}async updateByDomain(){const e=await this.querySite();for(const t of e){const e=t.domain.split(" ");this.ctx.utils.domain.match(e,this.certDomains)?(this.logger.info(`站点:${t.id},${t.domain},域名已匹配`),await this.updateBySiteId(this.cert,t.id)):this.logger.info(`站点:${t.id},${t.domain},域名未匹配`)}}async updateBySiteId(e,t){const s=`/v1/sites/${t}`,o=await this.doRequest(s,"GET",{});if(!o)throw new Error(`站点:${t}不存在`);this.logger.info(`更新站点证书:${t}`);let i=o.data.https_listen;if(i&&"string"==typeof i&&(i=JSON.parse(i)),i?.cert){const t=i.cert;return this.logger.info(`该站点已有证书,更新证书,证书ID:${t}`),void await this.updateByCertId(e,t)}if(!this.uploadCertId){this.logger.info(`创建证书,域名:${this.certDomains}`);const t="/v1/certs",s=this.buildCertName(this.certDomains[0]);await this.doRequest(t,"POST",{name:s,type:"custom",cert:e.crt,key:e.key});const o=await this.doRequest(t,"GET",{name:s});this.uploadCertId=o.data[0].id}await this.doRequest("/v1/sites","PUT",{id:o.id,https_listen:{cert:this.uploadCertId}})}async querySite(e){const t={limit:100};e&&(t.domain=e);return(await this.doRequest("/v1/sites","GET",t)).data}async queryCert(e){const t={limit:100};e&&(t.domain=e);return(await this.doRequest("/v1/certs","GET",t)).data}async onGetSiteList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.querySite(e?.searchKey);if(!t||0===t.length)throw new Error("没有找到任何站点,您可以手动输入网站Id");const s=t.map((e=>({label:`${e.id}<${e.domain}>`,value:e.id,domain:e.domain.split(" ")})));return this.ctx.utils.options.buildGroupOptions(s,this.certDomains)}async onGetCertList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.queryCert(e?.searchKey);if(!t||0===t.length)throw new Error("没有找到证书列表,您可以手动输入证书Id");const s=t.map((e=>({label:`${e.id}<${e.domain}>`,value:e.id,domain:e.domain.split(" ")})));return this.ctx.utils.options.buildGroupOptions(s,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],te.prototype,"cert",void 0),K([t(g({props:{required:!1}})),M("design:type",Array)],te.prototype,"certDomains",void 0),K([t({title:"cdnfly授权",helper:"cdnfly授权",component:{name:"access-selector",type:"cdnfly"},required:!0}),M("design:type",String)],te.prototype,"accessId",void 0),K([t({title:"自动匹配站点",component:{name:"a-switch",vModel:"checked"},helper:"是否自动匹配站点进行部署\n如果选择自动匹配,则下方参数无需填写"}),M("design:type",Boolean)],te.prototype,"autoMatch",void 0),K([t(y({title:"证书ID",helper:"请选择证书Id,需要先手动上传一次证书,后续可以自动更新证书【推荐】",search:!0,typeName:"CdnflyDeployToCDNPlugin",action:te.prototype.onGetCertList.name,watches:["cert","accessId"],required:!1})),M("design:type",Object)],te.prototype,"certId",void 0),K([t(y({title:"网站Id",helper:"请选择要部署证书的网站Id",search:!0,action:te.prototype.onGetSiteList.name,watches:["url","cert","accessId"],required:!1})),M("design:type",Array)],te.prototype,"siteId",void 0),te=K([s({name:"CdnflyDeployToCDN",title:"cdnfly-部署证书到cdnfly",icon:"majesticons:cloud-line",group:o.cdn.key,desc:"cdnfly",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],te),new te;let se=class extends a{url;type="apikey";username="";password="";apiKey="";apiSecret="";testRequest=!0;accessToken;async onTestRequest(){return await this.doRequest({url:"/v1/certs",method:"GET",data:{limit:100}}),"ok"}async getToken(){if("password"!==this.type)throw new Error("only support password type");if(this.accessToken)return this.accessToken;const e=await this.ctx.http.request({url:"/v1/login",baseURL:this.url,method:"POST",data:{account:this.username,password:this.password}});if(0!=e.code)throw new Error(e.msg);return this.accessToken=e.data.access_token,this.accessToken}async doRequest(e){const t=this.ctx.http;let s={};if("password"===this.type)await this.getToken(),s={"Access-Token":`${this.accessToken}`};else{const{apiKey:e,apiSecret:t}=this;s={"api-key":e,"api-secret":t}}const o=e.data,i=e.method||"POST",n=e.baseURL||this.url;if(!n)throw new Error("请配置授权内的url参数");const r=await t.request({url:e.url,baseURL:n,method:i,headers:s,logRes:!1,params:"GET"===i?o:{},data:"GET"!==i?o:void 0});if(0!=r.code)throw new Error(r.msg);return r}};K([n({title:"cdnfly系统网址",component:{name:"a-input",vModel:"value"},required:!0,helper:"例如:http://demo.cdnfly.cn"}),M("design:type",String)],se.prototype,"url",void 0),K([n({title:"授权方式",value:"apikey",component:{name:"a-select",vModel:"value",options:[{label:"接口密钥",value:"apikey"},{label:"模拟登录",value:"password"}]},required:!0}),M("design:type",Object)],se.prototype,"type",void 0),K([n({title:"用户名",component:{placeholder:"username"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'password';\n })\n }\n ",required:!0}),M("design:type",Object)],se.prototype,"username",void 0),K([n({title:"密码",component:{placeholder:"password"},helper:"",mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'password';\n })\n }\n ",required:!0,encrypt:!0}),M("design:type",Object)],se.prototype,"password",void 0),K([n({title:"api_key",component:{placeholder:"api_key"},helper:"登录cdnfly控制台->账户中心->Api密钥,点击开启后获取",required:!0,encrypt:!0,mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'apikey';\n })\n }\n "}),M("design:type",Object)],se.prototype,"apiKey",void 0),K([n({title:"api_secret",component:{placeholder:"api_secret"},helper:"登录cdnfly控制台->账户中心->Api密钥,点击开启后获取",required:!0,encrypt:!0,mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'apikey';\n })\n }\n "}),M("design:type",Object)],se.prototype,"apiSecret",void 0),K([n({title:"测试",component:{name:"api-test",action:"onTestRequest"},helper:"点击测试接口看是否正常\nIP需要加白名单,如果是同一台机器部署的,可以试试面板的url使用网卡docker0的ip,白名单使用172.16.0.0/12"}),M("design:type",Object)],se.prototype,"testRequest",void 0),se=K([r({name:"cdnfly",title:"cdnfly授权",desc:"",icon:"majesticons:cloud-line"})],se),new se;let oe=class extends e{cert;accessId;regionId;clusterId;secretName;namespace="default";isPrivateIpAddress;skipTLSVerify;createOnNotFound;K8sClient;async onInstance(){const e=await import("@certd/lib-k8s");this.K8sClient=e.K8sClient}async execute(){this.logger.info("开始部署证书到阿里云Ack");const{regionId:e,clusterId:t,isPrivateIpAddress:s,cert:o}=this,i=await this.getAccess(this.accessId),n=await this.getClient(i,e),r=await this.getKubeConfig(n,t,s);this.logger.info("kubeconfig已成功获取");const a=new this.K8sClient({kubeConfigStr:r,logger:this.logger,skipTLSVerify:this.skipTLSVerify});await this.patchCertSecret({cert:o,k8sClient:a}),await D.sleep(5e3);try{await this.restartIngress({k8sClient:a})}catch(e){this.logger.warn(`重启ingress失败:${e.message}`)}}async restartIngress(e){const{k8sClient:t}=e,{namespace:s}=this,o={metadata:{labels:{certd:this.appendTimeSuffix("certd")}}},i=await t.getIngressList({namespace:s});if(this.logger.info("ingressList:",i),!i||!i.items)return;const n=i.items.filter((e=>{if(!e.spec.tls)return!1;for(const t of e.spec.tls)if(t.secretName===this.secretName)return!0;return!1})).map((e=>e.metadata.name));for(const e of n)await t.patchIngress({namespace:s,ingressName:e,body:o,createOnNotFound:this.createOnNotFound}),this.logger.info(`ingress已重启:${e}`)}async patchCertSecret(e){const{cert:t,k8sClient:s}=e,o=t.crt,i=t.key,n=Buffer.from(o).toString("base64"),r=Buffer.from(i).toString("base64"),{namespace:a,secretName:c}=this,p={data:{"tls.crt":n,"tls.key":r},metadata:{labels:{certd:this.appendTimeSuffix("certd")}}};let d=c;"string"==typeof c&&(d=[c]);for(const e of d)await s.patchSecret({namespace:a,secretName:e,body:p}),this.logger.info(`cert secret已更新: ${e}`)}async getClient(e,t){const s=new w({logger:this.logger,useROAClient:!0});return await s.init({accessKeyId:e.accessKeyId,accessKeySecret:e.accessKeySecret,endpoint:`https://cs.${t}.aliyuncs.com`,apiVersion:"2015-12-15"}),s}async getKubeConfig(e,t,s=!1){const o=`/k8s/${t}/user_config`,i={PrivateIpAddress:s,TemporaryDurationMinutes:15},n={},r={"Content-Type":"application/json"},a={};try{return(await e.request("GET",o,i,n,r,a)).config}catch(e){throw console.error("请求出错:",e),e}}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],oe.prototype,"cert",void 0),K([t({title:"Access授权",helper:"阿里云授权AccessKeyId、AccessKeySecret",component:{name:"access-selector",type:"aliyun"},required:!0}),M("design:type",String)],oe.prototype,"accessId",void 0),K([t({title:"大区",component:{name:"a-auto-complete",vModel:"value",options:[{value:"cn-qingdao",label:"华北1(青岛)"},{value:"cn-beijing",label:"华北2(北京)"},{value:"cn-zhangjiakou",label:"华北3(张家口)"},{value:"cn-huhehaote",label:"华北5(呼和浩特)"},{value:"cn-wulanchabu",label:"华北6(乌兰察布)"},{value:"cn-hangzhou",label:"华东1(杭州)"},{value:"cn-shanghai",label:"华东2(上海)"},{value:"cn-shenzhen",label:"华南1(深圳)"},{value:"cn-guangzhou",label:"华南3(广州)"},{value:"ap-southeast-2",label:"澳大利亚(悉尼)"},{value:"ap-southeast-3",label:"马来西亚(吉隆坡)"},{value:"ap-northeast-1",label:"日本(东京)"},{value:"cn-chengdu",label:"西南1(成都)"},{value:"ap-southeast-1",label:"新加坡"},{value:"ap-southeast-5",label:"印度尼西亚(雅加达)"},{value:"cn-hongkong",label:"中国香港"},{value:"eu-central-1",label:"德国(法兰克福)"},{value:"us-east-1",label:"美国(弗吉尼亚)"},{value:"us-west-1",label:"美国(硅谷)"},{value:"eu-west-1",label:"英国(伦敦)"},{value:"me-east-1",label:"阿联酋(迪拜)"},{value:"cn-beijing-finance-1",label:"华北2 金融云(邀测)"},{value:"cn-hangzhou-finance",label:"华东1 金融云"},{value:"cn-shanghai-finance-1",label:"华东2 金融云"},{value:"cn-shenzhen-finance-1",label:"华南1 金融云"}],placeholder:"集群所属大区"},required:!0}),M("design:type",String)],oe.prototype,"regionId",void 0),K([t({title:"集群id",component:{placeholder:"集群id"},required:!0}),M("design:type",String)],oe.prototype,"clusterId",void 0),K([t({title:"保密字典Id",component:{placeholder:"保密字典Id"},helper:"原本存储证书的secret的name",required:!0}),M("design:type",Object)],oe.prototype,"secretName",void 0),K([t({title:"命名空间",value:"default",component:{placeholder:"命名空间"},required:!0}),M("design:type",Object)],oe.prototype,"namespace",void 0),K([t({title:"是否私网ip",value:!1,component:{name:"a-switch",vModel:"checked",placeholder:"集群连接端点是否是私网ip"},helper:"如果您当前certd运行在同一个私网下,可以选择是。",required:!0}),M("design:type",Boolean)],oe.prototype,"isPrivateIpAddress",void 0),K([t({title:"忽略证书校验",required:!1,helper:"是否忽略证书校验",component:{name:"a-switch",vModel:"checked"}}),M("design:type",Boolean)],oe.prototype,"skipTLSVerify",void 0),K([t({title:"Secret自动创建",helper:"如果Secret不存在,则创建",value:!1,component:{name:"a-switch",vModel:"checked"}}),M("design:type",Boolean)],oe.prototype,"createOnNotFound",void 0),oe=K([s({name:"DeployCertToAliyunAck",title:"阿里云-部署到Ack",icon:"svg:icon-aliyun",desc:"部署到阿里云Ack集群Ingress等通过Secret管理证书的应用",group:o.aliyun.key,needPlus:!1,input:{},output:{},default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],oe),new oe;let ie=class extends e{cert;certDomains;endpoint;accessId;cloudProduct;productIds;contactIds;checkTimeout;async onInstance(){}async execute(){this.logger.info("开始部署证书到阿里云");const e=await this.getAccess(this.accessId),t=new v({access:e,logger:this.logger,endpoint:this.endpoint});let s=this.cert;"object"==typeof this.cert&&(s=await t.uploadCert({name:this.appendTimeSuffix("certd"),cert:this.cert}));const o=await this.createDeployJob(t,s);await this.updateJobStatus(t,o,"scheduling"),this.logger.info("开始检查部署任务执行结果");const i=Date.now();for(;Date.now()<i+60*this.checkTimeout*1e3;){this.checkSignal(),await this.ctx.utils.sleep(1e4);let e={};try{e=await this.getJobDetail(t,o)}catch(e){this.logger.error(e);break}const s=e.Status;if("success"==s)return void this.logger.info("部署任务执行成功:",s);if("error"==s)throw this.logger.error(`部署任务执行失败,请前往 https://yundun.console.aliyun.com/?p=cas#/deployDetail/user/${o} 查看失败原因: `,e),new Error("部署任务执行失败,");this.logger.info("部署任务正在执行中: ",s)}throw new Error("部署任务执行超时,请手动检查任务状态")}async updateJobStatus(e,t,s){const o={JobId:t,Status:s},i=await e.doRequest("UpdateDeploymentJobStatus",o,{method:"POST",formatParams:!1});this.logger.info("部署任务开始执行,部署需要时间,RequestId=",i.RequestId)}async onGetProductList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getAccess(this.accessId),s=new v({access:t,logger:this.logger,endpoint:this.endpoint});if(!this.cloudProduct)throw new Error("请选择云产品类型");const o=await s.getResourceList({cloudProduct:this.cloudProduct});if(!o?.Data||0===o?.Data.length)throw new Error("没有找到对应类型的云资源");const i=o.Data.map((e=>({label:`${e.Domain}<${e.Id}>`,value:e.Id,title:`${e.CloudProduct}:${e.CertName||"证书未命名"}`,domain:e.Domain})));return this.ctx.utils.options.buildGroupOptions(i,this.certDomains)}async onGetContactList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getAccess(this.accessId),s=new v({access:t,logger:this.logger,endpoint:this.endpoint}),o=await s.getContactList();if(!o?.ContactList||0===o?.ContactList.length)throw new Error("没有找到联系人");return o.ContactList.map((e=>({label:`${e.Name}<${e.Email}:${e.ContactId}>`,value:e.ContactId})))}async getJobDetail(e,t){const s={JobId:t};return await e.doRequest("DescribeDeploymentJob",s,{method:"POST",formatParams:!1})}async createDeployJob(e,t){const s=(await e.createDeploymentJob({name:"自动部署证书(By Certd)",jobType:"user",contactIds:this.contactIds,resourceIds:this.productIds,certIds:[t]})).JobId;return this.logger.info("部署任务创建成功: jobId=",s),s}};K([t({title:"域名证书",helper:"请选择证书申请任务输出的域名证书\n或者选择前置任务“上传证书到阿里云”任务的证书ID,可以减少上传到阿里云的证书数量",component:{name:"output-selector",from:[...u,"uploadCertToAliyun"]},required:!0}),M("design:type",Object)],ie.prototype,"cert",void 0),K([t(g({props:{required:!1}})),M("design:type",Array)],ie.prototype,"certDomains",void 0),K([t({title:"接入点",helper:"不会选就按默认",value:"cas.aliyuncs.com",component:{name:"a-select",options:[{value:"cas.aliyuncs.com",label:"中国大陆"},{value:"cas.ap-southeast-1.aliyuncs.com",label:"新加坡"},{value:"cas.eu-central-1.aliyuncs.com",label:"德国(法兰克福)"}]},required:!0}),M("design:type",String)],ie.prototype,"endpoint",void 0),K([t({title:"Access授权",helper:"阿里云授权AccessKeyId、AccessKeySecret",component:{name:"access-selector",type:"aliyun"},required:!0}),M("design:type",String)],ie.prototype,"accessId",void 0),K([t({title:"云产品类型",helper:"请选择云产品类型",component:{name:"a-select",vModel:"value",options:[{value:"SLB",label:"SLB-传统型负载均衡 CLB(仅中国站)"},{value:"LIVE",label:"LIVE-视频直播(仅中国站)"},{value:"webHosting",label:"webHosting-云虚拟主机(仅中国站)"},{value:"VOD",label:"VOD-视频点播(仅中国站)"},{value:"CR",label:"CR-容器镜像服务(仅中国站)"},{value:"DCDN",label:"DCDN-全站加速"},{value:"DDoS",label:"DDos 防护"},{value:"CDN",label:"CDN-内容分发网络"},{value:"ALB",label:"ALB-应用负载均衡"},{value:"APIGateway",label:"APIGateway-API 网关"},{value:"FC",label:"FC-函数计算"},{value:"GA",label:"GA-全球加速"},{value:"MSE",label:"MSE-微服务引擎"},{value:"NLB",label:"NLB-网络型负载均衡"},{value:"OSS",label:"OSS-对象存储"},{value:"SAE",label:"SAE-Serverless应用引擎"},{value:"WAF",label:"WAF-Web应用防火墙"}]},required:!0}),M("design:type",String)],ie.prototype,"cloudProduct",void 0),K([t(y({title:"要部署证书的云产品",helper:"请选择要部署证书的云产品,注意:新创建的云产品资源可能需要过1-2小时才会在此处显示",typeName:"AliyunDeployCertToAll",action:ie.prototype.onGetProductList.name,watches:["cloudProduct","accessId"]})),M("design:type",Array)],ie.prototype,"productIds",void 0),K([t(y({title:"联系人",helper:"请选择联系人,如果没有,需要先到[阿里云控制台创建联系人](https://yundun.console.aliyun.com/?p=cas#/informationManagement/person/)",typeName:"AliyunDeployCertToAll",action:ie.prototype.onGetContactList.name})),M("design:type",Array)],ie.prototype,"contactIds",void 0),K([t({title:"检查超时时间",helper:"检查部署任务超时时间,单位分钟",value:10,component:{name:"a-input-number",vModel:"value"},required:!0}),M("design:type",Number)],ie.prototype,"checkTimeout",void 0),ie=K([s({name:"AliyunDeployCertToAll",title:"阿里云-部署至任意云资源",icon:"svg:icon-aliyun",group:o.aliyun.key,desc:"【不建议使用】需要消耗阿里云自动部署次数,支持SLB、LIVE、webHosting、VOD、CR、DCDN、DDoS、CDN、ALB、APIGateway、FC、GA、MSE、NLB、OSS、SAE、WAF等云产品",needPlus:!1,default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],ie),new ie;const ne="certd";class re{access;http;logger;skipSslVerify;token;constructor(e,t,s,o){this.access=e,this.http=t,this.logger=s,this.skipSslVerify=o}async doLogin(){const e=this.access;if(e.otp&&null!=e.deviceId)return this.logger.info("OTP登录"),await this.doLoginWithDeviceId(e.deviceId);this.logger.info("使用普通登录");const t=this.getLoginUrl(),s=await this.http.request({url:t,method:"GET",params:{api:"SYNO.API.Auth",version:6,method:"login",account:e.username,passwd:e.password,session:"Certd",format:"sid",enable_syno_token:"yes"},skipSslVerify:this.skipSslVerify??!0,timeout:1e3*this.access.timeout||12e4});if(!s.success)throw new Error("登录失败: ",s.error);return this.logger.info("登录成功"),this.token=s.data,this.token}async doLoginWithOTPCode(e){const t=this.getLoginUrl(),s=this.access,o=await this.http.request({url:t,method:"GET",params:{api:"SYNO.API.Auth",version:6,method:"login",account:s.username,passwd:s.password,otp_code:e,enable_device_token:"yes",device_name:ne},timeout:1e3*this.access.timeout||3e4,skipSslVerify:this.skipSslVerify??!0});if(!o.success)throw new Error("登录失败: ",o.error);return this.logger.info("登录成功"),this.token=o.data,this.token}getLoginUrl(){const e=this.access,t="6"===e.version?"auth.cgi":"entry.cgi";return`${e.baseUrl}/webapi/${t}`}async doLoginWithDeviceId(e){const t=this.access,s=this.getLoginUrl(),o=await this.http.request({url:s,method:"GET",params:{api:"SYNO.API.Auth",version:6,method:"login",account:t.username,passwd:t.password,device_name:ne,device_id:e,session:"Certd",format:"sid",enable_syno_token:"yes"},timeout:1e3*this.access.timeout||3e4,skipSslVerify:this.skipSslVerify??!0});if(!o.success)throw new Error("登录失败: ",o.error);return this.logger.info("登录成功"),this.token=o.data,this.token}async doRequest(e){const t=this.token.sid,s=e.method||"POST",o={...e.apiParams,_sid:t,...e.params,SynoToken:this.token.synotoken},i=await this.http.request({url:`${this.access.baseUrl}/webapi/entry.cgi?${P.stringify(o)}`,method:s,data:e.data,headers:e.headers,skipSslVerify:this.skipSslVerify??!0,timeout:1e3*this.access.timeout||3e4});if(!i.success)throw new Error(`API 调用失败: ${JSON.stringify(i.error)}`);return i.data}async getCertList(){return this.logger.info("获取证书列表"),await this.doRequest({method:"GET",apiParams:{api:"SYNO.Core.Certificate.CRT",version:1,method:"list"}})}async getInfo(){return this.logger.info("获取信息"),await this.doRequest({method:"GET",apiParams:{api:"SYNO.API.Info",version:1,method:"query"}})}}let ae=class extends _{certName;cert;accessId;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=new re(e,this.ctx.http,this.ctx.logger,e.skipSslVerify);await t.doLogin();const s=await t.getCertList();if(this.certName){const e=s.certificates.find((e=>e.desc===this.certName||e.subject.common_name===this.certName));if(!e)throw new Error(`未找到证书: ${this.certName}`);this.logger.info(`找到证书: ${e.id}`),await this.updateCertToPanel(t,e)}else{this.logger.info("开始更新全部证书");for(const e of s.certificates)this.logger.info(`更新证书: ${e.id}`),await this.updateCertToPanel(t,e)}}async updateCertToPanel(e,t){this.logger.info(`更新证书:${t.id}`);const s=new m(this.cert);return s.readCertFile({logger:this.logger,handle:async o=>{const i=new $,{tmpCrtPath:n,tmpKeyPath:r,tmpIcPath:a}=o;return this.logger.info(`上传证书:${n},${r}`),i.append("key",R.createReadStream(r)),i.append("cert",R.createReadStream(n)),s.cert.ic&&(this.logger.info(`包含中间证书:${a}`),i.append("inter_cert",R.createReadStream(a))),i.append("id",t.id),i.append("desc",t.desc),console.log(JSON.stringify(i.getHeaders())),await e.doRequest({method:"POST",apiParams:{api:"SYNO.Core.Certificate",version:1,method:"import"},data:i,headers:{...i.getHeaders()}})}})}};K([t({title:"群晖证书描述",component:{name:"a-input",vModel:"value",placeholder:"群晖证书描述"},required:!1,helper:"在群晖证书管理页面里面,选择证书,点击操作,给证书设置描述,然后填写到这里\n如果不填,则覆盖更新全部证书"}),M("design:type",String)],ae.prototype,"certName",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],ae.prototype,"cert",void 0),K([t({title:"群晖授权",helper:"群晖登录授权,请确保账户是管理员用户组",component:{name:"access-selector",type:"synology"},required:!0}),M("design:type",String)],ae.prototype,"accessId",void 0),ae=K([s({name:"SynologyDeployToPanel",title:"群晖-部署证书到群晖面板",icon:"simple-icons:synology",group:o.panel.key,desc:"Synology,支持6.x以上版本",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!0})],ae),new ae;let ce=class extends a{version="7";baseUrl="";username="";password="";otp=!1;deviceId="";skipSslVerify=!0;timeout=120;onLoginWithOPTCode(e){console.log("onLoginWithOPTCode",this);const t=this.ctx;return new re(this,t.http,t.logger,this.skipSslVerify).doLoginWithOTPCode(e.otpCode)}};K([n({title:"群晖版本",component:{name:"a-select",vModel:"value",options:[{label:"7.x",value:"7"},{label:"6.x",value:"6"}]},required:!0}),M("design:type",Object)],ce.prototype,"version",void 0),K([n({title:"群晖面板的url",component:{placeholder:"https://yourdomain:5006"},helper:"群晖面板的访问地址,例如:https://yourdomain:5006",required:!0}),M("design:type",Object)],ce.prototype,"baseUrl",void 0),K([n({title:"账号",component:{placeholder:"账号"},helper:"群晖面板登录账号,必须是处于管理员用户组",required:!0}),M("design:type",Object)],ce.prototype,"username",void 0),K([n({title:"密码",component:{placeholder:"密码"},helper:"群晖面板登录密码",required:!0,encrypt:!0}),M("design:type",Object)],ce.prototype,"password",void 0),K([n({title:"双重认证",value:!1,component:{name:"a-switch",vModel:"checked"},helper:"是否启用了双重认证",required:!0}),M("design:type",Object)],ce.prototype,"otp",void 0),K([n({title:"设备ID",component:{placeholder:"设备ID",name:"synology-device-id-getter",type:"access",typeName:"synology"},mergeScript:"\n return {\n component:{\n form: ctx.compute(({form})=>{\n return form\n })\n },\n show: ctx.compute(({form})=>{\n return form.access.otp\n })\n }\n ",helper:"1.如果开启了双重认证,需要获取设备ID\n2.填好上面的必填项,然后点击获取设备ID,输入双重认证APP上的码,确认即可获得设备ID,此操作只需要做一次\n3.注意:必须勾选‘安全性->允许网页浏览器的用户通过信任设备来跳过双重验证\n4.注意:在群晖信任设备页面里面会生成一条记录,不要删除\n5.注意:需要将流水线证书申请过期前多少天设置为30天以下,避免设备ID过期",required:!1,encrypt:!0}),M("design:type",Object)],ce.prototype,"deviceId",void 0),K([n({title:"忽略证书校验",value:!0,component:{name:"a-switch",vModel:"checked"},helper:"如果面板的url是https,且使用的是自签名证书,则需要开启此选项,其他情况可以关闭"}),M("design:type",Object)],ce.prototype,"skipSslVerify",void 0),K([n({title:"请求超时",value:120,component:{name:"a-input-number",vModel:"value"},helper:"请求超时时间,单位:秒"}),M("design:type",Object)],ce.prototype,"timeout",void 0),ce=K([r({name:"synology",title:"群晖登录授权",desc:"",icon:"simple-icons:synology"})],ce),new ce;let pe=class extends a{kubeconfig="";skipTLSVerify};K([n({title:"kubeconfig",component:{name:"a-textarea",vModel:"value",placeholder:"kubeconfig"},required:!0,encrypt:!0}),M("design:type",Object)],pe.prototype,"kubeconfig",void 0),K([n({title:"忽略证书校验",component:{name:"a-switch",vModel:"checked"},required:!1,encrypt:!1}),M("design:type",Boolean)],pe.prototype,"skipTLSVerify",void 0),pe=K([r({name:"k8s",title:"k8s授权",desc:"",icon:"mdi:kubernetes"})],pe),new pe;let de=class extends e{namespace;secretName;accessId;cert;ingressName;createOnNotFound;K8sClient;async onInstance(){const e=await import("@certd/lib-k8s");this.K8sClient=e.K8sClient}async execute(){const e=await this.getAccess(this.accessId),t=new this.K8sClient({kubeConfigStr:e.kubeconfig,logger:this.logger,skipTLSVerify:e.skipTLSVerify});try{await this.patchCertSecret({cert:this.cert,k8sClient:t})}catch(e){if(e.response?.body)throw new Error(JSON.stringify(e.response.body));throw e}await D.sleep(5e3)}async patchCertSecret(e){const{cert:t,k8sClient:s}=e,o=t.crt,i=t.key,n=Buffer.from(o).toString("base64"),r=Buffer.from(i).toString("base64"),{namespace:a,secretName:c}=this,p={data:{"tls.crt":n,"tls.key":r},metadata:{labels:{certd:this.appendTimeSuffix("certd")}}};let d=c;"string"==typeof c&&(d=[c]);for(const e of d)p.metadata.name=e,await s.patchSecret({namespace:a,secretName:e,body:p,createOnNotFound:this.createOnNotFound}),this.logger.info(`ingress cert Secret已更新:${e}`);await D.sleep(5e3),this.ingressName&&this.ingressName.length>0&&await s.restartIngress(a,this.ingressName,{certd:this.appendTimeSuffix("certd")})}};K([t({title:"命名空间",value:"default",component:{placeholder:"命名空间"},required:!0}),M("design:type",String)],de.prototype,"namespace",void 0),K([t({title:"保密字典Id",component:{name:"a-select",vModel:"value",mode:"tags",open:!1},helper:"原本存储证书的secret的name",required:!0}),M("design:type",Object)],de.prototype,"secretName",void 0),K([t({title:"k8s授权",helper:"kubeconfig",component:{name:"access-selector",type:"k8s"},required:!0}),M("design:type",String)],de.prototype,"accessId",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],de.prototype,"cert",void 0),K([t({title:"ingress名称",required:!1,helper:"填写之后会自动重启ingress",component:{name:"a-select",vModel:"value",mode:"tags",open:!1}}),M("design:type",Array)],de.prototype,"ingressName",void 0),K([t({title:"Secret自动创建",helper:"如果Secret不存在,则创建",value:!1,component:{name:"a-switch",vModel:"checked"}}),M("design:type",Boolean)],de.prototype,"createOnNotFound",void 0),de=K([s({name:"K8sDeployToSecret",title:"K8S-部署证书到Secret",icon:"mdi:kubernetes",desc:"部署证书到k8s的secret",needPlus:!1,group:o.panel.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],de),new de;let le=class extends e{namespace;ingressName;accessId;cert;createOnNotFound;async execute(){const e=await this.getAccess(this.accessId),t=new(0,(await import("@certd/lib-k8s")).K8sClient)({kubeConfigStr:e.kubeconfig,logger:this.logger,skipTLSVerify:e.skipTLSVerify}),s=(await t.getIngressList({namespace:this.namespace})).items.find((e=>e.metadata.name===this.ingressName));if(!s)throw new Error(`Ingress不存在:${this.ingressName}`);if(!s.spec.tls)throw new Error(`Ingress:${this.ingressName} 还未配置证书,请先手动配置好证书,创建一个Secret`);const o=s.spec.tls.map((e=>e.secretName));if(!o||0===o.length)throw new Error(`Ingress:${this.ingressName} 未找到证书Secret`);await this.patchNginxCertSecret({cert:this.cert,k8sClient:t,secretNames:o}),await D.sleep(5e3)}async patchNginxCertSecret(e){const{cert:t,k8sClient:s}=e,o=t.crt,i=t.key,n=Buffer.from(o).toString("base64"),r=Buffer.from(i).toString("base64"),{namespace:a}=this,c={data:{"tls.crt":n,"tls.key":r},metadata:{labels:{certd:this.appendTimeSuffix("certd")}}};for(const t of e.secretNames)this.logger.info(`更新ingress cert Secret:${t}`),await s.patchSecret({namespace:a,secretName:t,body:c,createOnNotFound:this.createOnNotFound}),this.logger.info(`ingress cert Secret已更新:${t}`);await D.sleep(5e3),this.ingressName&&await s.restartIngress(a,[this.ingressName],{certd:this.appendTimeSuffix("certd")})}};K([t({title:"命名空间",value:"default",component:{placeholder:"命名空间"},required:!0}),M("design:type",String)],le.prototype,"namespace",void 0),K([t({title:"IngressName",required:!0,helper:"Ingress名称,根据名称查找证书Secret,然后更新"}),M("design:type",String)],le.prototype,"ingressName",void 0),K([t({title:"k8s授权",helper:"kubeconfig",component:{name:"access-selector",type:"k8s"},required:!0}),M("design:type",String)],le.prototype,"accessId",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],le.prototype,"cert",void 0),K([t({title:"Secret自动创建",helper:"如果Secret不存在,则创建",value:!1,component:{name:"a-switch",vModel:"checked"}}),M("design:type",Boolean)],le.prototype,"createOnNotFound",void 0),le=K([s({name:"K8sDeployToIngress",title:"K8S-Ingress 证书部署",icon:"mdi:kubernetes",desc:"部署证书到k8s的Ingress",needPlus:!1,group:o.panel.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],le),new le;let he=class extends _{cert;preOutput;accessId;yamlContent;K8sClient;async onInstance(){const e=await import("@certd/lib-k8s");this.K8sClient=e.K8sClient}async execute(){const e=await this.getAccess(this.accessId),t=new this.K8sClient({kubeConfigStr:e.kubeconfig,logger:this.logger,skipTLSVerify:e.skipTLSVerify});if(!this.yamlContent)throw new Error("yamlContent is empty");const s=new m(this.cert),o={mainDomain:s.getMainDomain(),domains:s.getAllDomains().join(","),expiresTime:x(s.expires).format("YYYY-MM-DD HH:mm:ss"),crt:this.cert.crt,key:this.cert.key,ic:this.cert.ic,preOutput:this.preOutput},i=this.compile(this.yamlContent)(o);try{const e=await t.apply(i);this.logger.info("apply result:",e)}catch(e){if(e.response?.body)throw new Error(JSON.stringify(e.response.body));throw e}await D.sleep(5e3)}compile(e){return function(t){return e.replace(/\${(.*?)}/g,((e,s)=>{const o=I(t,s,"");return String(o)}))}}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],he.prototype,"cert",void 0),K([t({title:"前置任务输出",helper:"请选择前置任务输出的内容",component:{name:"output-selector",from:["::"]},required:!1}),M("design:type",Object)],he.prototype,"preOutput",void 0),K([t({title:"k8s授权",helper:"kubeconfig",component:{name:"access-selector",type:"k8s"},required:!0}),M("design:type",String)],he.prototype,"accessId",void 0),K([t({title:"yaml",required:!0,helper:"apply yaml,模板变量:主域名=${mainDomain}、全部域名=${domains}、过期时间=${expiresTime}、证书PEM=${crt}、证书私钥=${key}、中间证书/CA证书=${ic}、前置任务输出=${preOutput}",component:{name:"a-textarea",vModel:"value",rows:6}}),M("design:type",String)],he.prototype,"yamlContent",void 0),he=K([s({name:"K8sApply",title:"K8S-Apply自定义yaml",icon:"mdi:kubernetes",desc:"apply自定义yaml到k8s",needPlus:!0,group:o.panel.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],he),new he;class ue{access;http;logger;utils;token;constructor(e){this.access=e.access,this.http=e.http,this.logger=e.logger,this.utils=e.utils}async get1PanelCertInfo(e){const t=await this.doRequest({url:`/api/${this.access.apiVersion}/websites/ssl/${e}`,method:"get"});if(!t)throw new Error(`没有找到证书(id:${e}),请先在1Panel中手动上传证书,后续才可以自动更新`);return t}async doRequest(e){const t=await this.getAccessToken();return e.headers={...t},e.currentNode&&(e.headers.CurrentNode=this.getNodeValue(e.currentNode),delete e.currentNode),await this.doRequestWithoutAuth(e)}async doRequestWithoutAuth(e){e.baseURL=this.access.baseUrl,e.skipSslVerify=this.access.skipSslVerify??!1,e.logRes=!1,e.logParams=!1;const t=await this.http.request(e);if(e.returnOriginRes)return t;if(200===t.code)return t.data;throw new Error(t.message)}async getCookie(e){const t=(await this.doRequestWithoutAuth({url:`/api/${this.access.apiVersion}/auth/language`,method:"GET",returnOriginRes:!0})).headers["set-cookie"].find((t=>t.includes(e)));if(!t)return null;const s=t.split(";")[0];return s.substring(s.indexOf("=")+1)}async encryptPassword(e){const t=await this.getCookie("panel_public_key");if(!t)return e;const{encryptPassword:s}=await import("./util-9726341d.js");return s(t,e)}async getAccessToken(){return"apikey"===this.access.type?this.getAccessTokenByApiKey():await this.getAccessTokenByPassword()}async getAccessTokenByApiKey(){const e=Math.floor(Date.now()/1e3);return{"1Panel-Token":this.utils.hash.md5(`1panel${this.access.apiKey}${e}`),"1Panel-Timestamp":e}}async getAccessTokenByPassword(){if(this.token)return{PanelAuthorization:this.token};let e=this.access.password;e=await this.encryptPassword(e);const t=await this.doRequestWithoutAuth({url:`/api/${this.access.apiVersion}/auth/login`,method:"post",headers:{EntranceCode:Buffer.from(this.access.safeEnter).toString("base64")},data:{name:this.access.username,password:e,ignoreCaptcha:!0,captcha:"",captchaID:"",authMethod:"jwt",language:"zh"}});return this.token=t.token,{PanelAuthorization:this.token}}async onGetSSLIds(){const e=await this.doRequest({url:`/api/${this.access.apiVersion}/websites/ssl/search`,method:"post",data:{page:1,pageSize:99999}});if(!e?.items)throw new Error("没有找到证书,请先在1Panel中手动上传证书,并关联站点,后续才可以自动更新");return e.items.map((e=>({label:`${e.primaryDomain}<${e.id},${e.description||"无备注"}>`,value:e.id})))}getNodeValue(e){return encodeURIComponent(e||"local")}}let me=class extends e{cert;certDomains;accessId;currentNode;sslIds;access;async onInstance(){this.access=await this.getAccess(this.accessId)}async execute(){const e=new ue({access:this.access,http:this.http,logger:this.logger,utils:this.ctx.utils}),t=this.sslIds;for(const s of t)try{const o=await this.get1PanelCertInfo(e,s);if(!this.isNeedUpdate(o))continue;const i=await e.doRequest({url:`/api/${this.access.apiVersion}/websites/ssl/upload`,method:"post",data:{sslIds:t,certificate:this.cert.crt,certificatePath:"",description:o.description||this.appendTimeSuffix("certd"),privateKey:this.cert.key,privateKeyPath:"",sslID:s,type:"paste"},currentNode:this.currentNode});console.log("uploadRes",JSON.stringify(i))}catch(t){this.logger.warn(`更新证书(id:${s})失败`,t),this.logger.info("可能1Panel正在重启,等待10秒后检查证书是否更新成功"),await this.ctx.utils.sleep(1e4);const o=await this.get1PanelCertInfo(e,s);if(!this.isNeedUpdate(o))continue;throw t}}isNeedUpdate(e){return e.pem!==this.cert.crt||e.key!==this.cert.key||(this.logger.info(`证书(id:${e.id})已经是最新的了,不需要更新`),!1)}async get1PanelCertInfo(e,t){const s=await e.doRequest({url:`/api/${this.access.apiVersion}/websites/ssl/${t}`,method:"get",currentNode:this.currentNode});if(!s)throw new Error(`没有找到证书(id:${t}),请先在1Panel中手动上传证书,后续才可以自动更新`);return s}async onGetNodes(){const e=[{label:"主节点",value:"local"}];if("v1"===this.access.apiVersion)return e;if(!this.access)throw new Error("请先选择授权");const t=new ue({access:this.access,http:this.http,logger:this.logger,utils:this.ctx.utils}),s=await t.doRequest({url:`/api/${this.access.apiVersion}/core/nodes/list`,method:"post",data:{}});return[...e,...s?.map((e=>({label:`${e.addr}(${e.name})`,value:e.name})))||[]]}async onGetSSLIds(){if(!this.access)throw new Error("请先选择授权");const e=new ue({access:this.access,http:this.http,logger:this.logger,utils:this.ctx.utils}),t=await e.doRequest({url:`api/${this.access.apiVersion}/websites/ssl/search`,method:"post",data:{page:1,pageSize:99999},currentNode:this.currentNode});if(!t?.items)throw new Error("没有找到证书,请先在1Panel中手动上传证书,并关联站点,后续才可以自动更新");const s=t.items.map((e=>{const t=e.domains?[]:e.domains.split(","),s=[e.primaryDomain,...t];return{label:`${e.primaryDomain}<${e.id},${e.description||"无备注"}>`,value:e.id,domain:s}}));return this.ctx.utils.options.buildGroupOptions(s,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],me.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],me.prototype,"certDomains",void 0),K([t({title:"1Panel授权",helper:"1Panel授权",component:{name:"access-selector",type:"1panel"},required:!0}),M("design:type",String)],me.prototype,"accessId",void 0),K([t(y({title:"1Panel节点",helper:"要更新的1Panel证书的节点信息,目前只有v2存在此概念",typeName:"OnePanelDeployToWebsitePlugin",action:me.prototype.onGetNodes.name,value:"local",required:!0})),M("design:type",String)],me.prototype,"currentNode",void 0),K([t(y({title:"1Panel证书ID",typeName:"1PanelDeployToWebsitePlugin",action:me.prototype.onGetSSLIds.name,watches:["accessId"],helper:"要更新的1Panel证书id,选择授权之后,从下拉框中选择\nIP需要加白名单,如果是同一台机器部署的,可以试试172.16.0.0/12",required:!0})),M("design:type",Array)],me.prototype,"sslIds",void 0),me=K([s({name:"1PanelDeployToWebsitePlugin",title:"1Panel-部署证书到1Panel",icon:"svg:icon-onepanel",desc:"更新1Panel的证书",group:o.panel.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],me),new me;let ge=class extends a{baseUrl="";safeEnter="";type="";apiVersion="v1";username="";password="";apiKey="";skipSslVerify=!0;testRequest=!0;async onTestRequest(){const e=this.ctx.http,t=new ue({logger:this.ctx.logger,http:e,access:this,utils:this.ctx.utils});return await t.doRequest({url:`/api/${this.apiVersion}/websites/ssl/search`,method:"post",data:{page:1,pageSize:1}}),"ok"}};K([n({title:"1Panel面板的url",component:{placeholder:"http://xxxx.com:1231"},helper:"不要带安全入口",required:!0}),M("design:type",Object)],ge.prototype,"baseUrl",void 0),K([n({title:"安全入口",component:{placeholder:"登录的安全入口"},encrypt:!0,required:!1}),M("design:type",Object)],ge.prototype,"safeEnter",void 0),K([n({title:"授权方式",component:{name:"a-select",vModel:"value",options:[{label:"模拟登录【不推荐】",value:"password"},{label:"接口密钥【推荐】",value:"apikey"}]},required:!0}),M("design:type",Object)],ge.prototype,"type",void 0),K([n({title:"接口版本",value:"v1",component:{placeholder:"v1 / v2",name:"a-select",vModel:"value",options:[{label:"v1",value:"v1"},{label:"v2",value:"v2"}]},required:!0}),M("design:type",Object)],ge.prototype,"apiVersion",void 0),K([n({title:"用户名",component:{placeholder:"username"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'password';\n })\n }\n ",required:!0}),M("design:type",Object)],ge.prototype,"username",void 0),K([n({title:"密码",component:{placeholder:"password"},helper:"",mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'password';\n })\n }\n ",required:!0,encrypt:!0}),M("design:type",Object)],ge.prototype,"password",void 0),K([n({title:"接口密钥",component:{placeholder:"接口密钥"},mergeScript:"\n return {\n show: ctx.compute(({form})=>{\n return form.access.type === 'apikey';\n })\n }\n ",helper:"面板设置->API接口中获取",required:!0,encrypt:!0}),M("design:type",Object)],ge.prototype,"apiKey",void 0),K([n({title:"忽略证书校验",value:!0,component:{name:"a-switch",vModel:"checked"},helper:"如果面板的url是https,且使用的是自签名证书,则需要开启此选项,其他情况可以关闭"}),M("design:type",Object)],ge.prototype,"skipSslVerify",void 0),K([n({title:"测试",component:{name:"api-test",action:"onTestRequest"},helper:"点击测试接口看是否正常\nIP需要加白名单,如果是同一台机器部署的,可以试试面板的url使用网卡docker0的ip,白名单使用172.16.0.0/12"}),M("design:type",Object)],ge.prototype,"testRequest",void 0),ge=K([r({name:"1panel",title:"1panel授权",desc:"账号和密码",icon:"svg:icon-onepanel"})],ge),new ge;let ye=class extends e{domainName;cert;accessId;async onInstance(){}async execute(){this.logger.info("开始部署证书到七牛云oss");const e=await this.getAccess(this.accessId),t=new S({http:this.ctx.http,access:e,logger:this.logger});let s=null;"string"!=typeof this.cert?(this.logger.info("先上传证书"),s=await t.uploadCert(this.cert,this.appendTimeSuffix("certd"))):s=this.cert,this.logger.info(`开始修改证书,certId:${s},domain:${this.domainName}`),await t.bindCert({certid:s,domain:this.domainName}),this.logger.info("部署完成")}};K([t({title:"自定义源站域名",helper:"你在七牛云上配置的OSS域名,比如:certd.handsfree.work",required:!0}),M("design:type",String)],ye.prototype,"domainName",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书,或者上传到七牛云的证书id",component:{name:"output-selector",from:[...u,"QiniuCertUpload"]},required:!0}),M("design:type",Object)],ye.prototype,"cert",void 0),K([t({title:"Access授权",helper:"七牛云授权",component:{name:"access-selector",type:"qiniu"},required:!0}),M("design:type",String)],ye.prototype,"accessId",void 0),ye=K([s({name:"QiniuDeployCertToOSS",title:"七牛云-部署证书至OSS",icon:"svg:icon-qiniuyun",group:o.qiniu.key,desc:"自动部署域名证书至七牛云KODO,注意是自定义源站域名,不是CDN域名",default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],ye),new ye;class fe{opts;constructor(e){this.opts=e}async doRequest(e,t){const s=e.host,o=this.getTimestampString(),i=this.getQueryString(e.query),n=this.getAuthString(s,e.method,e.uri,i,o);let r="https://"+s+e.uri;e.query&&(r+="?"+i);const a=await this.opts.http.request({url:r,method:e.method,data:e.body,headers:{Authorization:n,"Content-Type":"application/json; charset=utf-8",Host:s,"x-bce-date":o,...e.headers},...t});if(a.code)throw new Error(`请求失败:${a.message}`);return a}getTimestampString(){return(new Date).toISOString().replace(/\.\d*/,"")}getQueryString(e){let t="",s=[];if(e){for(const t in e)s.push(t);s=s.sort()}if(s&&s.length>0){for(const o of s)t+=encodeURIComponent(o)+"="+encodeURIComponent(e[o])+"&";t=t.substring(0,t.length-1)}return t}uriEncode(e,t=!1){let s="";for(let o=0;o<e.length;o++){const i=e.charAt(o);s+=i>="A"&&i<="Z"||i>="a"&&i<="z"||i>="0"&&i<="9"||"_"===i||"-"===i||"~"===i||"."===i?i:"/"===i?t?"%2F":i:this.toHexUTF8(i)}return s}toHexUTF8(e){const t=(new TextEncoder).encode(e);let s="";for(const e of t)s+="%"+e.toString(16).padStart(2,"0").toUpperCase();return s}getAuthString(e,t,s,o,i){const n=`bce-auth-v1/${this.opts.access.accessKey}/${i}/120`,r=encodeURIComponent("host")+":"+encodeURIComponent(e)+"\n"+encodeURIComponent("x-bce-date")+":"+encodeURIComponent(i),a=t.toUpperCase()+"\n"+this.uriEncode(s,!1)+"\n"+o+"\n"+r,c=N.createHmac("sha256",this.opts.access.secretKey).update(n).digest().toString("hex");return`${n}/host;x-bce-date/${N.createHmac("sha256",c).update(a).digest().toString("hex")}`}}class we{client;constructor(e){this.client=new fe(e)}async createCert(e){return await this.client.doRequest({host:"certificate.baidubce.com",uri:"/v1/certificate",method:"post",body:{certName:"certd_"+e.certName,certServerData:e.cert.crt,certPrivateData:e.cert.key}})}async getCertList(){return await this.client.doRequest({host:"certificate.baidubce.com",uri:"/v1/certificate",method:"get"})}async updateCert(e){return await this.client.doRequest({host:"certificate.baidubce.com",uri:`/v1/certificate/${e.certId}`,method:"put",body:{certName:e.certName,certServerData:e.cert.crt,certPrivateData:e.cert.key}})}}let ve=class extends e{cert;certDomains;accessId;domains;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=new fe({access:e,logger:this.logger,http:this.ctx.http}),s=new we({access:e,logger:this.logger,http:this.ctx.http});let o=this.cert;if("string"!=typeof this.cert){this.logger.info("上传证书到百度云");o=(await s.createCert({cert:this.cert,certName:m.buildCertName(this.cert)})).certId,this.logger.info(`上传证书到百度云成功:${o}`)}const i={https:{enabled:!0,certId:o}};for(const e of this.domains)await t.doRequest({host:"cdn.baidubce.com",uri:`/v2/domain/${e}/config`,body:i,query:{https:""},method:"put"}),this.logger.info(`部署证书到${e}成功`)}async onGetDomainList(){const e=await this.getAccess(this.accessId),t=new fe({access:e,logger:this.logger,http:this.ctx.http}),s=(await t.doRequest({host:"cdn.baidubce.com",uri:"/v2/domain",method:"GET",query:{maxItems:1e3}})).domains;if(!s||0===s.length)throw new Error("未找到加速域名,你可以手动输入");const o=[];for(const e of s)o.push({value:e.name,label:e.name,domain:e.name});return this.ctx.utils.options.buildGroupOptions(o,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u,"BaiduUploadCert"]},required:!0}),M("design:type",Object)],ve.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],ve.prototype,"certDomains",void 0),K([t({title:"百度云授权",helper:"百度云授权",component:{name:"access-selector",type:"baidu"},required:!0}),M("design:type",String)],ve.prototype,"accessId",void 0),K([t({title:"CDN域名",component:{name:"remote-select",vModel:"value",mode:"tags",action:"GetDomainList",watches:["certDomains","accessId"]},required:!0}),M("design:type",Array)],ve.prototype,"domains",void 0),ve=K([s({name:"BaiduDeployToCDN",title:"百度云-部署证书到CDN",icon:"ant-design:baidu-outlined",group:o.baidu.key,desc:"部署到百度云CDN",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],ve),new ve;let Se=class extends e{cert;certDomains;region;blbType;accessId;blbIds;listenerIds;async onInstance(){}async execute(){this.logger.info("开始更新百度云监听器证书");const e=await this.getAccess(this.accessId),t=new we({access:e,logger:this.logger,http:this.ctx.http});let s=this.cert;if("string"!=typeof this.cert){this.logger.info("上传证书到百度云");s=(await t.createCert({cert:this.cert,certName:m.buildCertName(this.cert)})).certId,this.logger.info(`上传证书到百度云成功:${s}`)}const o=new fe({access:e,logger:this.logger,http:this.ctx.http});for(const e of this.listenerIds){const t=e.split("_"),i=t[0],n=t[1],r=t[2];let a=null;if(t.length>3&&(a=t[3]),this.logger.info(`更新监听器证书开始:${e}`),a){const t=await this.getListeners(o,i,n,r);if(!t||0===t.length)throw new Error(`未找到监听器:${e}`);const c=t[0].additionalCertDomains;for(const e of c)e.host===a&&(e.certId=s);await this.updateListenerCert({client:o,blbId:i,listenerType:n,listenerPort:r,certId:s,additionalCertDomains:c})}else await this.updateListenerCert({client:o,blbId:i,listenerType:n,listenerPort:r,certId:s});this.logger.info(`更新监听器证书成功:${e}`),await this.ctx.utils.sleep(3e3)}this.logger.info("更新百度云监听器证书完成")}async onGetListenerList(e={}){const t=await this.getAccess(this.accessId),s=new fe({access:t,logger:this.logger,http:this.ctx.http}),o=[];for(const e of this.blbIds){const t=["HTTPSlistener","SSLlistener"];for(const i of t){const t=await this.getListeners(s,e,i);if(t&&t.length>0)for(const s of t){const t=`${e}_${i}_${s.listenerPort}`;if(o.push({value:t,label:t}),s.additionalCertDomains&&s.additionalCertDomains.length>0)for(const e of s.additionalCertDomains){const s=`${t}_${e.host}`;o.push({value:s,label:`${s}【扩展】`})}}}}if(!o||0===o.length)throw new Error("未找到https/SSL监听器");return o}async getListeners(e,t,s,o){const i={maxItems:1e3};o&&(i.listenerPort=o);return(await e.doRequest({host:`blb.${this.region}.baidubce.com`,uri:`/v1/${this.blbType}/${t}/${s}`,method:"GET",query:i})).listenerList}async onGetBLBList(e={}){const t=await this.getAccess(this.accessId),s=new fe({access:t,logger:this.logger,http:this.ctx.http}),o=(await s.doRequest({host:`blb.${this.region}.baidubce.com`,uri:`/v1/${this.blbType}`,method:"GET",query:{maxItems:1e3}})).blbList;if(!o||0===o.length)throw new Error("没有数据,你可以手动输入");const i=[];for(const e of o)i.push({value:e.blbId,label:e.name});return i}async updateListenerCert(e){const{client:t,blbId:s,listenerType:o,listenerPort:i,certId:n,additionalCertDomains:r}=e,a={};r&&(a.additionalCertDomains=r),n&&(a.certIds=[n]);return await t.doRequest({host:`blb.${this.region}.baidubce.com`,uri:`/v1/${this.blbType}/${s}/${o}`,method:"PUT",query:{listenerPort:i},body:a})}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u,"BaiduUploadCert"]},required:!0}),M("design:type",Object)],Se.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],Se.prototype,"certDomains",void 0),K([t({title:"区域",component:{name:"a-select",vModel:"value",options:[{value:"bj",label:"北京"},{value:"fsh",label:"上海"},{value:"gz",label:"广州"},{value:"fwh",label:"武汉"},{value:"su",label:"苏州"},{value:"bd",label:"保定"},{value:"hkg",label:"香港"},{value:"sin",label:"新加坡"}]},required:!0}),M("design:type",String)],Se.prototype,"region",void 0),K([t({title:"负载均衡类型",component:{name:"a-select",vModel:"value",options:[{value:"blb",label:"普通负载均衡"},{value:"appblb",label:"应用负载均衡"}]},required:!0}),M("design:type",String)],Se.prototype,"blbType",void 0),K([t({title:"百度云授权",helper:"百度云授权",component:{name:"access-selector",type:"baidu"},required:!0}),M("design:type",String)],Se.prototype,"accessId",void 0),K([t({title:"负载均衡ID",component:{name:"remote-select",vModel:"value",mode:"tags",action:"GetBLBList",watches:["certDomains","blbType","accessId"]},required:!0}),M("design:type",Array)],Se.prototype,"blbIds",void 0),K([t({title:"监听器ID",component:{name:"remote-select",vModel:"value",mode:"tags",action:"GetListenerList",watches:["certDomains","accessId","blbIds"]},required:!0}),M("design:type",Array)],Se.prototype,"listenerIds",void 0),Se=K([s({name:"BaiduDeployToBLB",title:"百度云-部署证书到负载均衡",icon:"ant-design:baidu-outlined",group:o.baidu.key,desc:"部署到百度云负载均衡,包括BLB、APPBLB",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],Se),new Se;let ke=class extends e{cert;accessId;baiduCertId;async execute(){const e=await this.getAccess(this.accessId),t=new we({access:e,logger:this.logger,http:this.http}),s=await t.createCert({cert:this.cert,certName:m.buildCertName(this.cert)});this.baiduCertId=s.certId,this.logger.info(`上传成功,证书ID:${s.certId}`)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],ke.prototype,"cert",void 0),K([t({title:"Access授权",helper:"access授权",component:{name:"access-selector",type:"baidu"},required:!0}),M("design:type",String)],ke.prototype,"accessId",void 0),K([c({title:"百度云CertId"}),M("design:type",String)],ke.prototype,"baiduCertId",void 0),ke=K([s({name:"BaiduUploadCert",title:"百度云-上传到证书托管",icon:"ant-design:baidu-outlined",desc:"上传证书到百度云证书托管中心",group:o.baidu.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],ke),new ke;let be=class extends a{accessKey="";secretKey="";testRequest=!0;async onTestRequest(){const e=new we({access:this,logger:this.ctx.logger,http:this.ctx.http}),t=await e.getCertList();return this.ctx.logger.info("测试接口返回",t),"ok"}};K([n({title:"AccessKey",component:{placeholder:"AccessKey"},helper:"[百度智能云->安全认证获取](https://console.bce.baidu.com/iam/#/iam/accesslist)",required:!0,encrypt:!1}),M("design:type",Object)],be.prototype,"accessKey",void 0),K([n({title:"SecretKey",component:{placeholder:"SecretKey"},helper:"",required:!0,encrypt:!0}),M("design:type",Object)],be.prototype,"secretKey",void 0),K([n({title:"测试",component:{name:"api-test",action:"onTestRequest"},helper:"点击测试接口看是否正常"}),M("design:type",Object)],be.prototype,"testRequest",void 0),be=K([r({name:"baidu",title:"百度云授权",desc:"",icon:"ant-design:baidu-outlined",order:2})],be),new be;let Ie=class extends e{accessId;certIds;cert;access;token;async onInstance(){this.access=await this.getAccess(this.accessId),this.token=await this.getToken()}async doRequest(e){const t=this.access,s=await this.ctx.http.request({baseURL:t.url,headers:{Authorization:`Bearer ${this.token}`},...e});return this.checkRes(s),s.data}async getToken(){const e=this.access,t=await this.ctx.http.request({url:"/prod-api/login",baseURL:e.url,method:"post",data:{username:e.username,password:e.password}});return this.checkRes(t),t.data.access_token}async getCertInfo(e){return await this.doRequest({url:`/prod-api/certificate/${e}`,method:"get"})}async updateCert(e,t){const s=await this.getCertInfo(e),o={ssl_key:t.key,ssl_pem:t.crt};return C(s,o),this.logger.info(`证书名称:${s.name}`),await this.doRequest({url:`/prod-api/certificate/${e}`,method:"put",data:s})}async execute(){for(const e of this.certIds)this.logger.info(`更新证书:${e}`),await this.updateCert(e,this.cert),this.logger.info(`更新证书成功:${e}`);this.logger.info("更新证书完成")}checkRes(e){if(0!==e.code)throw new Error(e.message)}async onGetCertList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getCerts();if(!t||0===t.data.length)throw new Error("没有找到证书,请先手动上传一次证书,并让站点使用该证书");return t.data.map((e=>({label:`${e.name}-${e.description}<${e.id}>`,value:e.id})))}async getCerts(){return await this.doRequest({url:"/prod-api/certificate",method:"get",params:{current_page:1,page_size:1e3}})}};K([t({title:"LeCDN授权",component:{name:"access-selector",type:"lecdn"},required:!0}),M("design:type",String)],Ie.prototype,"accessId",void 0),K([t(y({title:"证书ID",helper:"选择要更新的证书id,注意域名是否与证书匹配",typeName:"LeCDNUpdateCert",action:Ie.prototype.onGetCertList.name})),M("design:type",Array)],Ie.prototype,"certIds",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Ie.prototype,"cert",void 0),Ie=K([s({name:"LeCDNUpdateCert",title:"LeCDN-更新证书",icon:"material-symbols:shield-outline",group:o.cdn.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],Ie),new Ie;let Ce=class extends e{accessId;certIds;cert;access;token;async onInstance(){this.access=await this.getAccess(this.accessId),this.token=await this.getToken()}async doRequest(e){const t=this.access,s="token"===this.access.type?this.access.apiToken:`Bearer ${this.token}`,o=await this.ctx.http.request({baseURL:t.url,headers:{Authorization:s},...e});return this.checkRes(o),o.data}async getToken(){if("token"===this.access.type)return this.access.apiToken;const e=this.access,t=await this.ctx.http.request({url:"/prod-api/login",baseURL:e.url,method:"post",data:{email:e.username,username:e.username,password:e.password}});return this.checkRes(t),t.data.access_token||t.data.token}async getCertInfo(e){return await this.doRequest({url:`/prod-api/certificate/${e}`,method:"get"})}async updateCert(e,t){const s=await this.getCertInfo(e),o={ssl_key:D.hash.base64(t.key),ssl_pem:D.hash.base64(t.crt)};return C(s,o),this.logger.info(`证书名称:${s.name}`),await this.doRequest({url:`/prod-api/certificate/${e}`,method:"put",data:s})}async execute(){for(const e of this.certIds)this.logger.info(`更新证书:${e}`),await this.updateCert(e,this.cert),this.logger.info(`更新证书成功:${e}`);this.logger.info("更新证书完成")}checkRes(e){if(0!==e.code&&200!==e.code)throw new Error(e.message)}async onGetCertList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getCerts(),s=t.items||t.data;if(!t||0===s.length)throw new Error("没有找到证书,请先手动上传一次证书,并让站点使用该证书");return s.map((e=>({label:`${e.name}-${e.domain_name}<${e.id}>`,value:e.id})))}async getCerts(){return await this.doRequest({url:"/prod-api/certificate",method:"get",params:{current_page:1,page_size:1e3}})}};K([t({title:"LeCDN授权",component:{name:"access-selector",type:"lecdn"},required:!0}),M("design:type",String)],Ce.prototype,"accessId",void 0),K([t(y({title:"证书ID",helper:"选择要更新的证书id,注意域名是否与证书匹配",typeName:"LeCDNUpdateCertV2",action:Ce.prototype.onGetCertList.name})),M("design:type",Array)],Ce.prototype,"certIds",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Ce.prototype,"cert",void 0),Ce=K([s({name:"LeCDNUpdateCertV2",title:"LeCDN-更新证书V2",desc:"支持新版本LeCDN",icon:"material-symbols:shield-outline",group:o.cdn.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],Ce),new Ce;let qe=class extends a{url;type;username="";password="";apiToken=""};K([n({title:"LeCDN系统网址",component:{name:"a-input",vModel:"value"},required:!0,helper:"例如:http://demo.xxxx.cn"}),M("design:type",String)],qe.prototype,"url",void 0),K([n({title:"认证类型",component:{placeholder:"请选择",name:"a-select",vModel:"value",options:[{value:"token",label:"API访问令牌"},{value:"password",label:"账号密码(旧版本)"}]},required:!0}),M("design:type",String)],qe.prototype,"type",void 0),K([n({title:"用户名",component:{placeholder:"username"},mergeScript:"\n return {\n show:ctx.compute(({form})=>{\n return form.access.type === 'password';\n })\n }\n ",required:!0,encrypt:!1}),M("design:type",Object)],qe.prototype,"username",void 0),K([n({title:"登录密码",component:{placeholder:"password"},required:!0,encrypt:!0,mergeScript:"\n return {\n show:ctx.compute(({form})=>{\n return form.access.type === 'password';\n })\n }\n "}),M("design:type",Object)],qe.prototype,"password",void 0),K([n({title:"Api访问令牌",component:{placeholder:"apiToken"},required:!0,encrypt:!0,mergeScript:"\n return {\n show:ctx.compute(({form})=>{\n return form.access.type === 'token';\n })\n }\n "}),M("design:type",Object)],qe.prototype,"apiToken",void 0),qe=K([r({name:"lecdn",title:"LeCDN授权",desc:"",icon:"material-symbols:shield-outline"})],qe),new qe;let xe=class extends e{certId;certName;cert;accessId;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId);try{const t=await this.ctx.http.request({url:"/v2/domain/certificate?token="+e.token,baseURL:"https://cdn.api.baishan.com",method:"post",data:{cert_id:this.certId,name:this.certName,certificate:this.cert.crt,key:this.cert.key}});if(0!==t.code)throw new Error("修改证书失败:"+t.message||t.msg||JSON.stringify(t))}catch(e){if(e.message?.indexOf("this certificate is exists")>-1){const t=e.message.match(/\d+/);if(t&&t.length>0&&t[0]!==this.certId+"")throw new Error("证书已存在,但证书id不一致,当前证书id为"+this.certId+",已存在证书id为"+t);return void this.logger.info("证书已存在,无需更新")}throw e}this.logger.info("证书更新成功")}};K([t({title:"证书ID",component:{name:"a-input-number",vModel:"value"},helper:"证书ID,在证书管理页面查看,每条记录都有证书id"}),M("design:type",Number)],xe.prototype,"certId",void 0),K([t({title:"证书名称",component:{name:"a-input",vModel:"value"},helper:"给证书设置一个名字,便于区分"}),M("design:type",String)],xe.prototype,"certName",void 0),K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],xe.prototype,"cert",void 0),K([t({title:"白山云授权",helper:"白山云授权",component:{name:"access-selector",type:"baishan"},required:!0}),M("design:type",String)],xe.prototype,"accessId",void 0),xe=K([s({name:"BaishanUpdateCert",title:"白山云-更新证书",icon:"material-symbols:shield-outline",group:o.cdn.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],xe),new xe;let De=class extends a{token=""};K([n({title:"token",component:{placeholder:"token"},helper:"自行联系提供商申请",required:!0,encrypt:!0}),M("design:type",Object)],De.prototype,"token",void 0),De=K([r({name:"baishan",title:"白山云授权",desc:"",icon:"material-symbols:shield-outline"})],De),new De;let Te=class extends _{cert;certDomains;accessId;siteNames;pfxPassword;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=new k(this.logger);await this.checkTerminalType(t,e);const s=L.join(O(),"certd");R.existsSync(s)||R.mkdirSync(s,{recursive:!0});const o=L.join(s,this.appendTimeSuffix("cert")+".pfx");R.writeFileSync(o,Buffer.from(this.cert.pfx,"base64"));const i=await t.exec({connectConf:e,script:["$env:temp"]}),n=L.join(i.trim(),"certd","iis",L.basename(o));await t.uploadFiles({connectConf:e,transports:[{localPath:o,remotePath:n}],mkdirs:!0});try{for(const s of this.siteNames){const o=Ae.replaceAll("{SITE_NAME}",s).replaceAll("{PASSWORD}",this.pfxPassword||"").replaceAll("{CERT_PATH}",n);await t.exec({connectConf:e,script:[o],throwOnStdErr:!0})}}finally{R.unlinkSync(o)}this.logger.info("更新证书完成")}async onGetSiteList(){if(!this.accessId)throw new Error("请选择Access授权");const e=await this.getAccess(this.accessId),t=new k(this.logger);await this.checkTerminalType(t,e);const s=await t.exec({connectConf:e,script:[Pe]}),o=[];let i=!1;return s.split("\n").map((e=>{if(e.includes("-------result start--------"))return void(i=!0);if(e.includes("-------result end--------"))return void(i=!1);if(!i)return;if(""===(e=e.trim())||!e.includes(" | "))return;const[t,s]=e.split(" | "),n=t.trim();let r=s;s.includes(":")&&(r=s.split(":")[2].trim()),o.push({label:`${n}<${r}>`,value:n,domain:r})})),D.options.buildGroupOptions(o,this.certDomains)}async checkTerminalType(e,t){this.logger.info("检查终端类型");const s=await e.getIsCmd({connectConf:t});if(this.logger.info("isCmd",s),s)throw new Error("不支持cmd,请将OpenSSH的默认终端设置为powershell,如何设置请参考: https://certd.docmirror.cn/guide/use/host/windows.html")}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Te.prototype,"cert",void 0),K([t(g({props:{required:!1}})),M("design:type",Array)],Te.prototype,"certDomains",void 0),K([t({title:"主机SSH授权",component:{name:"access-selector",type:"ssh"},required:!0}),M("design:type",String)],Te.prototype,"accessId",void 0),K([t(y({title:"站点名称",helper:"选择或手动输入网站名称",action:Te.prototype.onGetSiteList.name})),M("design:type",Array)],Te.prototype,"siteNames",void 0),K([t({title:"证书密码",required:!1}),M("design:type",String)],Te.prototype,"pfxPassword",void 0),Te=K([s({name:"HostDeployToIIS",title:"IIS-部署到IIS站点",icon:"devicon:windows8",group:o.host.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!0})],Te);const Ae='\ntry{\n $siteName = "{SITE_NAME}"\n $password = "{PASSWORD}"\n $certPath = "{CERT_PATH}" \n if($password -eq "") {\n Write-Host "cert password is empty"\n }else{\n $password = ConvertTo-SecureString -String $password -AsPlainText -Force\n }\n \n # 导入 PFX 证书\n $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2\n # $cert.Import($certPath, $password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet)\n $cert.Import(\n $certPath,\n $password,\n [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor\n [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet\n)\n # 打开 LocalMachine 的证书存储\n $store = New-Object System.Security.Cryptography.X509Certificates.X509Store("My", "LocalMachine")\n $store.Open("ReadWrite")\n $store.Add($cert)\n $store.Close()\n \n Write-Host "import cert success"\n \n # 导入 IIS 模块\n Import-Module WebAdministration\n \n # 网站名称和证书指纹\n \n $thumbprint = $cert.Thumbprint # 获取证书指纹\n Write-Host \'site name:\' $siteName\n Write-Host \'cert info:\' $cert.Thumbprint\n \n # 绑定新的证书\n $binding = Get-WebBinding -Name $siteName -Protocol https\n if ($binding) {\n $binding.AddSslCertificate($thumbprint, \'My\')\n \tWrite-Host "update cert success"\n } else {\n Write-Error "HTTPS bind not found, cant add SSL cert,Https绑定不存在,请先创建https绑定"\n }\n \n # 确认更改\n Get-WebBinding -Name $siteName -Protocol https\n \n # 重启 IIS\n iisreset\n} catch {\n Write-Error "发生错误:$($_.Exception.Message)"\n}\n',Pe='\ntry{\n # 导入 WebAdministration 模块\n Import-Module WebAdministration\n \n # 获取所有 IIS 站点\n $sites = Get-IISSite\n \n # 创建一个列表用于存储结果\n $result = @()\n \n # 遍历每个站点\n foreach ($site in $sites) {\n # 获取该站点的所有绑定\n $bindings = Get-WebBinding -Name $site.Name\n \n # 筛选出 HTTPS 绑定\n $httpsBindings = $bindings | Where-Object { $_.protocol -eq "https" }\n \n # 将站点名称和 HTTPS 绑定信息添加到结果\n $result += [PSCustomObject]@{\n SiteName = $site.Name\n HttpsBindings = if ($httpsBindings) {\n $httpsBindings | ForEach-Object { $_.bindingInformation }\n } else {\n "No HTTPS bindings"\n }\n }\n }\n \n # 显示结果\n $result | Format-Table -AutoSize\n Write-Output "-------result start--------"\n foreach ($item in $result) {\n Write-Output "$($item.SiteName) | $($item.HttpsBindings)"\n }\n Write-Output "-------result end--------"\n} catch {\n Write-Error "发生错误:$($_.Exception.Message)"\n}\n';new Te;let Re=class extends _{cert;certDomains;accessId;siteDomainIds;clearUnused;async execute(){const e=await this.getAccess(this.accessId),t=await e.getSessionId();for(const s of this.siteDomainIds){const o=new $;o.append("id",s),o.append("fileContent",this.cert.one),o.append("fileName","cert.pem");const i=await e.doGetRequest({url:`/modules/sslit/index.php/index/certificate/id/${s}`,sessionId:t}),n=e.getTokenFromDetail(i);if(await e.doEditRequest({url:"/modules/sslit/index.php/index/upload/",sessionId:t,token:n,formData:o}),this.logger.info(`部署站点<${s}>证书成功`),this.clearUnused){await this.ctx.utils.sleep(3e3),this.logger.info("开始删除未使用的证书");try{await e.deleteUnusedCert({sessionId:t,token:n,siteDomainId:s})}catch(e){this.logger.warn(`删除未使用的证书失败:${e.message}`)}}}this.logger.info("部署证书完成")}async onGetDomainList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getAccess(this.accessId),s=await this.http.request({url:"/api/v2/domains",baseURL:t.url,method:"get",headers:{Authorization:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString("base64")}`}});if(!s||0===s.length)throw new Error("没有找站点域名");const o=s.map((e=>({label:e.name,value:e.id,domain:e.name})));return this.ctx.utils.options.buildGroupOptions(o,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Re.prototype,"cert",void 0),K([t(g({props:{required:!1}})),M("design:type",Array)],Re.prototype,"certDomains",void 0),K([t({title:"Plesk授权",component:{name:"access-selector",type:"plesk"},required:!0}),M("design:type",String)],Re.prototype,"accessId",void 0),K([t(y({title:"网站域名列表",helper:"选择要更新的站点域名,注意域名是否与证书匹配",action:Re.prototype.onGetDomainList.name})),M("design:type",Array)],Re.prototype,"siteDomainIds",void 0),K([t({title:"删除未使用证书",component:{name:"a-switch",vModel:"checked"},required:!1}),M("design:type",Boolean)],Re.prototype,"clearUnused",void 0),Re=K([s({name:"PleskDeploySiteCert",title:"Plesk-部署Plesk网站证书",icon:"svg:icon-plesk",group:o.panel.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!0})],Re),new Re;let $e=class extends a{url;username="";password="";testRequest=!0;async onTestRequest(){if(!await this.getSessionId())throw new Error("获取sessionId失败");return"ok"}async getSessionId(){const e=new $;e.append("login_name",this.username),e.append("passwd",this.password),e.append("locale_id","default");try{await this.ctx.http.request({url:"/login_up.php",baseURL:this.url,method:"post",headers:{origin:this.url,...e.getHeaders()},data:e,withCredentials:!0,logRes:!1,returnOriginRes:!0,maxRedirects:0})}catch(e){if(e&&e instanceof T&&303===e.status&&e.response){const t=e.response.headers.get("set-cookie")[0].match(/PLESKSESSID=(.*?);/)[1];if(t)return this.ctx.logger.info("获取Plesk SessionId 成功"),t}throw e}}async getCertList(e){const t=await this.doGetRequest({url:"modules/sslit/index.php/main-page/index",sessionId:e}),s=t.match(/"domainList":(.*?),"domainSummaryEnabled"/)[1];return{list:JSON.parse(s),token:this.getTokenFromDetail(t)}}getTokenFromDetail(e){return e.match(/forgery_protection_token" content="(.*?)"/)[1]}async doGetRequest(e){return await this.ctx.http.request({url:e.url,baseURL:this.url,method:e.method??"get",withCredentials:!0,headers:{Cookie:`PLESKSESSID=${e.sessionId}`},logRes:!1})}async doEditRequest(e){const t=await this.ctx.http.request({url:e.url,baseURL:this.url,method:e.method??"post",withCredentials:!0,headers:{Cookie:`PLESKSESSID=${e.sessionId}`,Origin:this.url,"X-Forgery-Protection-Token":e.token,...e.formData.getHeaders()},logRes:e.logRes??!1,data:e.formData});if(!1===e.checkRes)return t;if(t&&"success"===t.status)return t;throw new Error(`${JSON.stringify(t.actionMessages||t.statusMessages||t)}`)}async deleteUnusedCert(e){let t=await this.doGetRequest({url:`/smb/ssl-certificate/list/id/${e.siteDomainId}`,sessionId:e.sessionId});t=t.substring(t.indexOf("Plesk.require('app/ssl-certificate/list',"));const s=t.match(/"data":(.*?),"locale"/)[1].match(/"data":(.*)/)[1],o=JSON.parse(s).filter((e=>"0"===e.usageCount)).map((e=>e.id));if(0===o.length)return void this.ctx.logger.info("没有未使用的证书");const i=new $;for(let e=0;e<o.length;e++)i.append(`ids[${e}]`,o[e]);await this.doEditRequest({url:`/smb/ssl-certificate/delete/id/${e.siteDomainId}`,sessionId:e.sessionId,method:"post",formData:i,token:e.token,logRes:!1}),this.ctx.logger.info("删除未使用的证书成功")}};K([n({title:"Plesk网址",component:{name:"a-input",vModel:"value"},required:!0,helper:"例如:https://xxxx.xxxxx:8443/"}),M("design:type",String)],$e.prototype,"url",void 0),K([n({title:"用户名",component:{placeholder:"username"},required:!0,encrypt:!1}),M("design:type",Object)],$e.prototype,"username",void 0),K([n({title:"登录密码",component:{placeholder:"password"},required:!0,encrypt:!0}),M("design:type",Object)],$e.prototype,"password",void 0),K([n({title:"测试",component:{name:"api-test",action:"onTestRequest"},helper:"点击测试接口看是否正常"}),M("design:type",Object)],$e.prototype,"testRequest",void 0),$e=K([r({name:"plesk",title:"plesk授权",desc:"",icon:"svg:icon-plesk"})],$e),new $e;let Ne=class extends a{url;pid;key;payType;signType};K([n({title:"url",component:{placeholder:"https://pay.xxxx.com"},helper:"易支付系统地址",required:!0,encrypt:!1}),M("design:type",String)],Ne.prototype,"url",void 0),K([n({title:"商户id",component:{placeholder:"pid"},required:!0,encrypt:!1}),M("design:type",String)],Ne.prototype,"pid",void 0),K([n({title:"key",component:{placeholder:"key"},required:!0,encrypt:!0}),M("design:type",String)],Ne.prototype,"key",void 0),K([n({title:"固定支付方式",component:{placeholder:"固定一种支付方式,也就是submit.php中的type参数"},helper:"不填则跳转到收银台由用户自己选择,如果您的易支付系统不支持收银台,则必须填写",required:!1,encrypt:!1}),M("design:type",String)],Ne.prototype,"payType",void 0),K([n({title:"签名方式",component:{name:"a-select",vModel:"value",options:[{label:"MD5",value:"MD5"},{label:"SHA256",value:"SHA256"}]},required:!0,encrypt:!1}),M("design:type",String)],Ne.prototype,"signType",void 0),Ne=K([r({name:"yizhifu",title:"易支付",icon:"svg:icon-yizhifu"})],Ne),new Ne;let Oe=class extends a{appId;privateKey;alipayPublicKey};K([n({title:"AppId",component:{placeholder:"201909176714xxxx"},required:!0,encrypt:!1}),M("design:type",String)],Oe.prototype,"appId",void 0),K([n({title:"应用私钥",component:{placeholder:"MIIEvQIBADANB...",name:"a-textarea",rows:3},required:!0,encrypt:!0}),M("design:type",String)],Oe.prototype,"privateKey",void 0),K([n({title:"支付宝公钥",component:{name:"a-textarea",rows:3,placeholder:"MIIBIjANBg..."},required:!0,encrypt:!0}),M("design:type",String)],Oe.prototype,"alipayPublicKey",void 0),Oe=K([r({name:"alipay",title:"支付宝",icon:"ion:logo-alipay"})],Oe),new Oe;let Le=class extends a{appId;mchid;publicKey;privateKey;key};K([n({title:"AppId",component:{placeholder:"201909176714xxxx"},required:!0,encrypt:!1}),M("design:type",String)],Le.prototype,"appId",void 0),K([n({title:"商户ID",component:{placeholder:"201909176714xxxx"},required:!0,encrypt:!1}),M("design:type",String)],Le.prototype,"mchid",void 0),K([n({title:"公钥",component:{name:"a-textarea",rows:3,placeholder:"MIIBIjANBg..."},required:!0,encrypt:!0}),M("design:type",String)],Le.prototype,"publicKey",void 0),K([n({title:"私钥",component:{placeholder:"MIIEvQIBADANB...",name:"a-textarea",rows:3},required:!0,encrypt:!0}),M("design:type",String)],Le.prototype,"privateKey",void 0),K([n({title:"APIv3密钥",helper:"微信商户平台—>账户设置—>API安全—>设置APIv3密钥",required:!0,encrypt:!0}),M("design:type",String)],Le.prototype,"key",void 0),Le=K([r({name:"wxpay",title:"微信支付",icon:"tdesign:logo-wechatpay-filled"})],Le),new Le;let Ee=class extends e{cert;certDomains;accessId;certIds;access;async onInstance(){this.access=await this.getAccess(this.accessId)}async execute(){for(const e of this.certIds)await this.uploadCert(e);this.logger.info("雷池证书更新完成")}async uploadCert(e){await this.doRequest({url:"/api/open/cert",method:"post",data:{id:e,manual:{crt:this.cert.crt,key:this.cert.key},type:2}}),this.logger.info(`证书<${e}>更新成功`)}async doRequest(e){e.baseURL=this.access.baseUrl,e.skipSslVerify=this.access.skipSslVerify??!1,e.logRes=!1,e.logParams=!1,e.headers={"X-SLCE-API-TOKEN":this.access.apiToken};const t=await this.ctx.http.request(e);if(!t.err)return t.data;throw new Error(t.msg)}async onGetCertIds(){const e=await this.doRequest({url:"/api/open/cert",method:"get",data:{}}),t=e?.nodes;if(!t||0===t.length)throw new Error("没有找到证书,请先在雷池控制台中手动上传证书,并关联防护站点,后续才可以自动更新");const s=t.map((e=>({label:`<${e.id}>${e.domains.join(",")}`,value:e.id,domain:e.domains})));return this.ctx.utils.options.buildGroupOptions(s,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Ee.prototype,"cert",void 0),K([t(g({props:{required:!1}})),M("design:type",Array)],Ee.prototype,"certDomains",void 0),K([t({title:"雷池授权",helper:"长亭雷池授权",component:{name:"access-selector",type:"safeline"},required:!0}),M("design:type",String)],Ee.prototype,"accessId",void 0),K([t(y({title:"雷池证书",typeName:"SafelineDeployToWebsitePlugin",action:Ee.prototype.onGetCertIds.name,helper:"请选择要更新的雷池的证书Id,需要先手动到雷池控制台上传一次",required:!0})),M("design:type",Array)],Ee.prototype,"certIds",void 0),Ee=K([s({name:"SafelineDeployToWebsitePlugin",title:"雷池-更新证书",icon:"svg:icon-safeline",desc:"更新长亭雷池WAF的证书",group:o.panel.key,default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],Ee),new Ee;let je=class extends a{baseUrl="";apiToken="";skipSslVerify=!0};K([n({title:"雷池的访问url",component:{placeholder:"https://xxxx.com:9443"},required:!0}),M("design:type",Object)],je.prototype,"baseUrl",void 0),K([n({title:"ApiToken",component:{placeholder:"apiToken"},helper:"",required:!0,encrypt:!0}),M("design:type",Object)],je.prototype,"apiToken",void 0),K([n({title:"忽略证书校验",value:!0,component:{name:"a-switch",vModel:"checked"},helper:"如果面板的url是https,且使用的是自签名证书,则需要开启此选项,其他情况可以关闭"}),M("design:type",Object)],je.prototype,"skipSslVerify",void 0),je=K([r({name:"safeline",title:"长亭雷池授权",icon:"svg:icon-safeline"})],je),new je;class _e{opts;access;constructor(e){this.opts=e,this.access=e.access}encode(e){return Buffer.from(e,"utf-8").toString("base64")}decode(e){return Buffer.from(e,"base64").toString("utf-8")}urlEncode(e){return this.encode(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}urlDecode(e){for(e=e.replace(/-/g,"+").replace(/_/g,"/");e.length%4;)e+="=";return this.decode(e)}async hmacsha256(e,t){const s=(await import("crypto")).createHmac("sha256",Buffer.from(t,"base64")).update(e).digest();return this.urlEncode(s)}async getHeader(e){const t=this.access.accessKeyId,s=this.access.securityKey,o=+new Date,i=t+"\n"+o+"\n"+e,n=await this.hmacsha256(t+":"+parseInt(String(o/864e5)),s);return{"x-alogic-now":o,"x-alogic-app":t,"x-alogic-signature":await this.hmacsha256(i,n),"x-alogic-ac":"app"}}async doRequest({uri:e,method:t,data:s}){const o=this.opts.http,i={};"get"===t?s&&(e=e+"?"+h.stringify(s)):i.data=s;const n=await this.getHeader(e),r="https://open.ctcdn.cn"+e,a=await o.request({url:r,method:t,...i,headers:{...n,"Content-Type":"application/json"}});if(1e5!==a.code)throw new Error(`请求失败:${a.message}`);return a}async certCreate(e,t,s){const o={name:e,key:s,certs:t};return this.doRequest({uri:"/v1/cert/create",method:"post",data:o})}async getDomainList({productCode:e}){const t={product_code:e,page_size:100};return(await this.doRequest({uri:"/v2/domain/query",method:"get",data:t})).result}}let Ke=class extends e{cert;certDomains;productCode;accessId;domains;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=new _e({access:e,http:this.ctx.http,logger:this.ctx.logger}),s=this.appendTimeSuffix("certd");await t.certCreate(s,this.cert.crt,this.cert.key);const o=`ctyun-deploy-to-cdn-${this.accessId}`;await this.ctx.utils.locker.execute(o,(async()=>{const e=(await t.doRequest({uri:"/v1/domain/batch_update_configuration_information",method:"post",data:{domain:this.domains,product_code:this.productCode,cert_name:s,https_status:"on"}})).domain_details;for(const t of e)if(1e5!==t.code){const e=`部署失败[${t.code}]:${t.domain}:${t.message}`;(e.includes("已有进行中的工单")||"".includes("域名正在操作中"))&&this.logger.warn(e)}await this.ctx.utils.sleep(5e3)})),this.logger.info("部署成功")}async onGetDomainList(){const e=await this.getAccess(this.accessId),t=this.ctx.http,s=new _e({access:e,http:t,logger:this.ctx.logger}),o=await s.getDomainList({productCode:this.productCode});if(!o||0===o.length)throw new Error("未找到加速域名,你可以手动输入");const i=o.map((e=>({label:e.domain,value:e.domain})));return this.ctx.utils.options.buildGroupOptions(i,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Ke.prototype,"cert",void 0),K([t(g()),M("design:type",Array)],Ke.prototype,"certDomains",void 0),K([t({title:"产品类型",helper:"加速产品类型",component:{name:"a-select",options:[{label:"静态加速",value:"001"},{label:"下载加速",value:"003"},{label:"视频点播加速",value:"004"},{label:"CDN加速",value:"008"},{label:"全站加速",value:"006"},{label:"安全加速",value:"007"},{label:"下载加速闲时",value:"014"}]},required:!0}),M("design:type",String)],Ke.prototype,"productCode",void 0),K([t({title:"天翼云授权",helper:"天翼云授权",component:{name:"access-selector",type:"ctyun"},required:!0}),M("design:type",String)],Ke.prototype,"accessId",void 0),K([t(y({title:"加速域名",helper:"请选择加速域名",typeName:"CtyunDeployToCDN",action:Ke.prototype.onGetDomainList.name})),M("design:type",Array)],Ke.prototype,"domains",void 0),Ke=K([s({name:"CtyunDeployToCDN",title:"天翼云-部署证书到CDN",icon:"svg:icon-ctyun",group:o.cdn.key,desc:"部署证书到天翼云CDN和全站加速",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],Ke),new Ke;let Me=class extends _{cert;certDomains;accessId;certList;async onInstance(){}async execute(){const{cert:e}=this,t=await this.getAccess(this.accessId),s=await this.onGetCertList(),o={};s.forEach((e=>{o[e.value]=e.item}));for(const s of this.certList){this.logger.info(`开始更新证书:${s}`);const i=o[s];if(!i)throw new Error(`没有找到证书:Key=${s},请确认该证书是否存在`);const n=i.Remark,r=await this.doRequest({access:t,urlPath:"/api/ssl",method:"PUT",data:{AddFrom:"file",CertBase64:this.ctx.utils.hash.base64(e.crt),Enable:!0,Key:s,MappingChangeScript:"",MappingPath:"",MappingToPath:!1,KeyBase64:this.ctx.utils.hash.base64(e.key),IssuerCertificate:"",ExtParams:{},Remark:n}});this.logger.info(`更新成功:${JSON.stringify(r)}`)}this.logger.info("部署成功")}async doRequest(e){const{access:t,urlPath:s,data:o,method:i}=e;let n=`${t.url}/${t.safePath||""}${s}?_=${Math.floor((new Date).getTime())}`;const r=n.substring(0,7);let a=n.substring(7);a=a.replaceAll("//","/"),a=a.replaceAll("//","/"),n=r+a;const c={"Content-Type":"application/json"};c.openToken=t.openToken;const p=await this.http.request({method:i||"POST",url:n,data:o,headers:c,skipSslVerify:!0});if(0!==p.ret)throw new Error(`请求失败:${p.msg}`);return p}async onGetCertList(){const e=await this.getAccess(this.accessId),t=(await this.doRequest({access:e,urlPath:"/api/ssl",data:{},method:"GET"})).list;if(!t||0===t.length)throw new Error("没有找到证书,请先在SSL/TLS证书页面中手动上传一次证书");const s=t.map((e=>{const t=e.CertsInfo;let s="";return s=q(t)?e.CertsInfo[0].Domains:e.CertsInfo.Domains[0],{label:`${e.Remark}<${s}>`,value:e.Key,item:e}}));return this.ctx.utils.options.buildGroupOptions(s,this.certDomains)}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]}}),M("design:type",Object)],Me.prototype,"cert",void 0),K([t(g({props:{required:!1}})),M("design:type",Array)],Me.prototype,"certDomains",void 0),K([t({title:"Lucky授权",component:{name:"access-selector",type:"lucky"},required:!0}),M("design:type",String)],Me.prototype,"accessId",void 0),K([t(y({title:"Lucky证书",helper:"要更新的Lucky证书",typeName:"LuckyUpdateCert",action:Me.prototype.onGetCertList.name,watches:["accessId"]})),M("design:type",Array)],Me.prototype,"certList",void 0),Me=K([s({name:"LuckyUpdateCert",title:"lucky-更新Lucky证书",icon:"svg:icon-lucky",group:o.panel.key,needPlus:!0,default:{strategy:{runStrategy:i.SkipWhenSucceed}}})],Me),new Me;let Ge=class extends a{url="";safePath="";openToken=""};K([n({title:"访问url",component:{placeholder:"http://xxx.xx.xx:16301"},helper:"不要带安全入口",required:!0,encrypt:!1}),M("design:type",Object)],Ge.prototype,"url",void 0),K([n({title:"安全入口",component:{placeholder:"/your_safe_path"},helper:"请参考lucky设置中关于安全入口的配置,",required:!1,encrypt:!0}),M("design:type",Object)],Ge.prototype,"safePath",void 0),K([n({title:"OpenToken",component:{placeholder:"OpenToken"},helper:"设置->最下面开发者设置->启用OpenToken",required:!0,encrypt:!0}),M("design:type",Object)],Ge.prototype,"openToken",void 0),Ge=K([r({name:"lucky",title:"lucky",desc:"",icon:"svg:icon-lucky"})],Ge),new Ge;let We=class extends e{cert;accessId;domains;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=await this.getLoginToken(e);for(const e of this.domains){const s=this.cert,o={doMainId:e,https:{https_status:"on",certificate_name:this.appendTimeSuffix("certd"),certificate_source:"0",certificate_value:s.crt,private_key:s.key}};await this.doRequest("https://kuocaicdn.com/CdnDomainHttps/httpsConfiguration",t,o),this.logger.info(`站点${e}证书更新成功`)}}async getLoginToken(e){const t={userAccount:e.username,userPwd:e.password,remember:!0},s=this.ctx.http,o=await s.request({url:"https://kuocaicdn.com/login/loginUser",method:"POST",data:t,headers:{"Content-Type":"application/x-www-form-urlencoded"},returnOriginRes:!0});if(!o.data?.success)throw new Error(o.data?.message);const i=this.ctx.utils.request.getCookie(o,"JSESSIONID"),n=o.data?.data;return{jsessionId:i,token:n}}async getDomainList(e){const t=await this.doRequest("https://kuocaicdn.com/CdnDomain/queryForDatatables",e,{draw:1,start:0,length:1e3,search:{value:"",regex:!1}});return t.data?.data}async doRequest(e,t,s){const o=this.ctx.http,i=await o.request({url:e,method:"POST",headers:{Cookie:`JSESSIONID=${t.jsessionId};kuocai_cdn_token=${t.token}`},data:s});if(!i.success)throw new Error(i.message);return i}async onGetDomainList(e){if(!this.accessId)throw new Error("请选择Access授权");const t=await this.getAccess(this.accessId),s=await this.getLoginToken(t),o=await this.getDomainList(s);if(!o||0===o.length)throw new Error("您账户下还没有站点域名,请先添加域名");return o.map((e=>({label:`${e.domainName}<${e.id}>`,value:e.id})))}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],We.prototype,"cert",void 0),K([t({title:"括彩云CDN授权",helper:"括彩云CDN授权",component:{name:"access-selector",type:"kuocaicdn"},required:!0}),M("design:type",String)],We.prototype,"accessId",void 0),K([t(y({title:"域名列表",helper:"选择要部署证书的站点域名",typeName:"KuocaiDeployToCDNPlugin",action:We.prototype.onGetDomainList.name})),M("design:type",Array)],We.prototype,"domains",void 0),We=K([s({name:"KuocaiDeployToRCDN",title:"括彩云-部署到括彩云CDN",icon:"material-symbols:shield-outline",group:o.cdn.key,desc:"括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8)",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],We),new We;let Ue=class extends a{username="";password=""};K([n({title:"账户",component:{placeholder:"手机号"},required:!0,encrypt:!0}),M("design:type",Object)],Ue.prototype,"username",void 0),K([n({title:"密码",component:{placeholder:"password"},required:!0,encrypt:!0}),M("design:type",Object)],Ue.prototype,"password",void 0),Ue=K([r({name:"kuocaicdn",title:"括彩云cdn授权",icon:"material-symbols:shield-outline",desc:"括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8)"})],Ue),new Ue;class Be{opts;deviceId;xToken;token;cookie;constructor(e){this.opts=e,this.deviceId=(new Date).getTime()+Math.floor(1e6*Math.random())+""}async sign(e,t){const s=(await import("crypto-js")).default;let o="";return Object.keys(e).sort().forEach((function(t){e[t]&&(o=o+"&"+t+"="+e[t])})),o=o.slice(1),s.HmacMD5(o,t).toString()}async doRequest(e){const t=(await A.request({...e,logRes:!1,returnOriginRes:!0})).data;if(null!=t.ret){if(0!==t.ret)throw new Error(JSON.stringify(t));return t.data}if(!t.success)throw new Error(JSON.stringify(t.error));if(t.data?.errCode)throw new Error(JSON.stringify(t.data));return t.data}async login(){if(this.xToken)return this.xToken;const e=this.deviceId,t=this.opts.access.email;var s;const o={method:"serverless.function.runtime.invoke",params:`{"functionTarget":"uni-id-co","functionArgs":{"method":"login","params":[{"password":"${this.opts.access.password}","captcha":"","resetAppId":"__UNI__unicloud_console","resetUniPlatform":"web","isReturnToken":false,"email":"${t}"}],"clientInfo":${`{"PLATFORM":"web","OS":"windows","APPID":"${s="__UNI__uniid_server"}","DEVICEID":"${e}","scene":1001,"appId":"${s}","appLanguage":"zh-Hans","appName":"账号中心","appVersion":"1.0.0","appVersionCode":"100","browserName":"chrome","browserVersion":"122.0.6261.95","deviceId":"174585375190823882061","deviceModel":"PC","deviceType":"pc","hostName":"chrome","hostVersion":"122.0.6261.95","osName":"windows","osVersion":"10 x64","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36","uniCompilerVersion":"4.45","uniPlatform":"web","uniRuntimeVersion":"4.45","locale":"zh-Hans","LOCALE":"zh-Hans"}`}}}`,spaceId:"uni-id-server",timestamp:(new Date).getTime()},i=await this.sign(o,"ba461799-fde8-429f-8cc4-4b6d306e2339"),n=(await this.doRequest({url:"https://account.dcloud.net.cn/client",method:"POST",data:o,headers:{"X-Serverless-Sign":i,Origin:"https://account.dcloud.net.cn",Referer:"https://account.dcloud.net.cn"}})).newToken.token;return this.xToken=n,this.opts.logger.info("登录成功:",n),n}async getToken(){if(this.token)return{token:this.token,cookie:this.cookie};const e=await this.login(),t=this.deviceId,s=`{"PLATFORM":"web","OS":"windows","APPID":"__UNI__unicloud_console","DEVICEID":"${t}","scene":1001,"appId":"__UNI__unicloud_console","appLanguage":"zh-Hans","appName":"uniCloud控制台","appVersion":"1.0.0","appVersionCode":"100","browserName":"chrome","browserVersion":"122.0.6261.95","deviceId":"${t}","deviceModel":"PC","deviceType":"pc","hostName":"chrome","hostVersion":"122.0.6261.95","osName":"windows","osVersion":"10 x64","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36","uniCompilerVersion":"4.57","uniPlatform":"web","uniRuntimeVersion":"4.57","locale":"zh-Hans","LOCALE":"zh-Hans"}`,o={method:"serverless.function.runtime.invoke",params:`{"functionTarget":"uni-cloud-kernel","functionArgs":{"action":"user/getUserToken","data":{"isLogin":true},"clientInfo":${s},"uniIdToken":"${e}"}}`,spaceId:"dc-6nfabcn6ada8d3dd",timestamp:(new Date).getTime()},i=await this.sign(o,"4c1f7fbf-c732-42b0-ab10-4634a8bbe834"),n=await this.doRequest({url:"https://unicloud.dcloud.net.cn/client",method:"POST",data:o,headers:{"X-Client-Info":encodeURIComponent(s),"X-Serverless-Sign":i,"X-Client-Token":e,Origin:"https://unicloud.dcloud.net.cn",Referer:"https://unicloud.dcloud.net.cn"}}),r=n.data.data.token,a=n.headers["set-cookie"];let c="";for(let e=0;e<a.length;e++){c+=a[e].substring(0,a[e].indexOf(";"))+";"}return this.token=r,this.opts.logger.info("获取token成功:",r),this.cookie=c,{token:r,cookie:c}}async createCert(e){await this.getToken();const{spaceId:t,domain:s,cert:o,provider:i}=e;this.opts.logger.info(`开始部署证书, provider:${i},spaceId:${t},domain:${s}`);const n={appid:"",provider:i,spaceId:t,domain:s,cert:encodeURIComponent(o.crt),key:encodeURIComponent(o.key)},r=await this.doRequest({url:"https://unicloud-api.dcloud.net.cn/unicloud/api/host/create-domain-with-cert",method:"POST",data:n,headers:{Token:this.token,Cookie:this.cookie}});this.opts.logger.info("证书部署成功:",JSON.stringify(r))}}let Ve=class extends e{cert;accessId;spaceId;provider;domains;async onInstance(){}async execute(){const e=await this.getAccess(this.accessId),t=new Be({access:e,logger:this.logger,http:this.http});for(const e of this.domains)await t.createCert({domain:e,provider:this.provider,spaceId:this.spaceId,cert:this.cert});this.logger.info("部署成功")}};K([t({title:"域名证书",helper:"请选择前置任务输出的域名证书",component:{name:"output-selector",from:[...u]},required:!0}),M("design:type",Object)],Ve.prototype,"cert",void 0),K([t({title:"uniCloud授权",helper:"uniCloud授权",component:{name:"access-selector",type:"unicloud"},required:!0}),M("design:type",String)],Ve.prototype,"accessId",void 0),K([t({title:"服务空间ID",component:{name:"a-input",vModel:"value"},helper:"spaceId"}),M("design:type",String)],Ve.prototype,"spaceId",void 0),K([t({title:"空间提供商",component:{name:"a-select",vModel:"value",options:[{label:"阿里云",value:"aliyun"},{label:"腾讯云",value:"tencent"},{label:"支付宝云",value:"alipay"}]},helper:"空间提供商"}),M("design:type",String)],Ve.prototype,"provider",void 0),K([t({title:"空间域名",component:{name:"a-select",vModel:"value",mode:"tags",open:!1},helper:"空间域名"}),M("design:type",Array)],Ve.prototype,"domains",void 0),Ve=K([s({name:"UniCloudDeployToSpace",title:"uniCloud-部署到服务空间",icon:"material-symbols:shield-outline",group:o.panel.key,desc:"部署到服务空间",default:{strategy:{runStrategy:i.SkipWhenSucceed}},needPlus:!1})],Ve),new Ve;let Fe=class extends a{email="";password=""};K([n({title:"账号",component:{placeholder:"email"},helper:"登录邮箱",required:!0,encrypt:!1}),M("design:type",Object)],Fe.prototype,"email",void 0),K([n({title:"密码",component:{placeholder:"密码"},required:!0,encrypt:!0}),M("design:type",Object)],Fe.prototype,"password",void 0),Fe=K([r({name:"unicloud",title:"uniCloud",icon:"material-symbols:shield-outline",desc:"unicloud授权"})],Fe),new Fe;let He=class extends a{username;password;httpProxy};K([n({title:"用户名",component:{placeholder:"username/手机号/email",name:"a-input",vModel:"value"},helper:"用户名",required:!0}),M("design:type",String)],He.prototype,"username",void 0),K([n({title:"password",component:{placeholder:"密码",component:{name:"a-input-password",vModel:"value"}},encrypt:!0,helper:"密码",required:!0}),M("design:type",String)],He.prototype,"password",void 0),K([n({title:"HttpProxy",component:{placeholder:"http://192.168.x.x:10811",component:{name:"a-input",vModel:"value"}},encrypt:!1,required:!1}),M("design:type",String)],He.prototype,"httpProxy",void 0),He=K([r({name:"maoyun",title:"猫云授权",desc:"",icon:"svg:icon-lucky"})],He),new He;class ze{privateKeyPem="";http;logger;access;token;constructor(e){this.logger=e.logger,this.http=e.http,this.access=e.access,this.privateKeyPem="\n-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAt83xKlUSU0i09/pwwQ0MQQ0v71IULdVGJ3AFo+anwLX1TRCp\nxmY5i+xmT9tshHqiPGN8qeg+lDaqA+iwmS6zqi+KlNmmKJc3kUx/h24MI3nff0xy\nz605ZfDgJhwBkJpTI6Sk4+OLX+lZxOiET0nOT7jrhKiFCKX8+0ZXjTJ1cmdifKaj\nqXmjD+XYZzBwA2fCr1kPq2xKvU097Ksu6QvM+La5X/tt+FJOuedmuqZmsb6YQ+6O\n6mJ0bcY0kFDGNkoeY6dEyeJAkIDJbda3n0I71KwRR2J0CSN3TF+w1hSQa7Hp1rXw\n+zQvR6p7O2VY8zQeZZKRKGl7OGdKW5F79iz2fQIDAQABAoIBAEN0BaRGciI0VY2H\n0CdY1X1uDIBke9lSIpvIhZlfxYJ4hFxS2CtiSo4qJGX8HbgElVNaI17rR0P3R6+F\njoG43OCA7/euZEcTL6ZYD5kw7q16RWYfNSc36A+cNXZm4sAhko9LFeQ4FmcNaQ9V\nUXEToe4p6+zUN3Y0DEJezzSXJvjjjodT5L03i2HCW+/xZIHi6oh1DuXdy7h1Ah8s\nSxN188HsX7/SoDHAxDqi/SSGyoYg/SvtOetPtrcZCfqoHfxkR+jQHNaOTq3vGmsu\np8KPtRBoFvSPMxSSHNLb4qbIFvlWRLNXfIhYnenTPtmCnnqogotZZ9CoCHL9dX5R\nt4q5L6ECgYEA5jYhqpRIhqSZOTJopGgy3LBy5T1PHDTfedTuSxnoywYWCuGNwgjI\nRgd94jcUuizO9euobxvDUTdOZ6LdK1NStfwOspb2NojvlE+9SfC8JDv7ZeRz8egB\nClrT6jtCUr80K1I0eF31ha0YMjgi7WZJvTMp53fqI0b1yQO2FaBNgWUCgYEAzGT6\nay+QlO2Fdt9mqeIJy9QiugItC7lk75fQMg5fa8A8wj9DO86o/2k4rKhl7SPg0H+R\nSJQoZGuS4M2f9muEHnLmVF8EzizuHZoR3HO4mie2adVf9NfAmkFsCluRAZKtQkNc\nt/VwlJEC6dChoZkU8Wzd0fSJKrdhjik2ayGXmzkCgYEAuie9s5UyzIXfTSwhCAkm\nT+TzE8Iu7Y0nxPnVM6+g2kNyoZvgqK23XUGDnuCRhzbiqGPGkQovN8Z0RUOiev1m\n3bgUHoAKWvECYrjURS1AxkAmuy8wPsYvyTLHOBpxOD5bLkjMGyVHe7AL59gTDktv\nh2oPEZibIamo6MJyhCxbYC0CgYAIZhnYL7MsO3phgRqR3oTyiDwJEq/RLIQWSFG4\nzNhk8BhPDxRvL7XIEQXQKndNwEyrpKJOri/euIDnlet9z7s1GRmX2/OxmS0LsFoN\nif/K7djUDn2L7RWwAQI0hsC1pNZTw7raoE5I/JB3FSifIFA4/3U5/GdqhvCOS+k9\ni7rUGQKBgQDPspapfGj2ozgWChJ2xMTGBhJhynM81w3j9w7MLvO/7/U43zYzKzyc\n7YJzApQOSwX/nLdquzi+UIbvuCB3npZVZl52S4f7BBcgLNQpdmcfWrAbDv5lySfn\n/KTN22Wxmhh20QgiNSxj+o+KIgdAgZCgWt7NrkZ5UX7Lo+ZfYU1xbg==\n-----END RSA PRIVATE KEY-----"}async sign(e){const{KJUR:t,KEYUTIL:s,hextob64:o}=await import("jsrsasign"),i=s.getKey(this.privateKeyPem),n=new t.crypto.Signature({alg:"SHA256withRSA"});n.init(i),n.updateString(e);return o(n.sign())}async doRequest(e){const t=Date.now();let s="";if("get"===e.method.toLowerCase()){let o=[];for(const t in e.params)o.push(`${t}=${e.params[t]}`);o.push(`nonce=${t}`),o.push(`timestamp=${t}`),o=o.sort(),s=o.join("&")}else s=`body=${JSON.stringify(e.data||{})}&nonce=${t}×tamp=${t}`;const o={sign:await this.sign(s),timestamp:t,nonce:t};this.token&&(o.Token=this.token);const i=await this.http.request({...e,headers:o,baseURL:"https://testaa.5678.jp"});if(!i.success&&200!==i.code)throw new Error(`请求失败:${i.msg}`);return i.data}async login(){const e={email:this.access.username,password:this.access.password,accountType:1},t=await this.doRequest({url:"/api/vcloud/v1/userApi/noAuth/login",method:"post",data:e,logRes:!1,logParams:!1}),{token:s}=t;this.logger.info("登录成功"),this.token=s}}class Je{access=null;http=null;logger=null;xTickets=null;loginCookies=null;domainTokenCookie=null;userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0";constructor(e){this.access=e.access,this.http=e.http,this.logger=e.logger}async doRedirectRequest(e){let t=null;try{t=await this.http.request(e)}catch(e){if(t=e.response,this.logger.info(t.headers),!t)throw new Error("请求失败:",e)}return t}getCookie(e){const t=e.headers["set-cookie"];if(!t||0===t.length)throw new Error("未获取到cookie",e);return t.map((e=>e.split(";")[0])).join(";")}async getToken(){const e=await this.http.request({url:"https://login.xinnet.com/queryUOne",method:"get"});this.logger.info("queryUOne",e.data);const{uOne:t,uTwo:s}=e.data,o=await this.doRedirectRequest({url:"https://login.xinnet.com/newlogin",method:"get",headers:{Host:"login.xinnet.com",Origin:"https://login.xinnet.com",Referer:"https://login.xinnet.com/separatePage/?service=https://www.xinnet.com/"},maxRedirects:0,withCredentials:!0,returnOriginRes:!0}),i=this.getCookie(o);this.logger.info("firstCookie",i);const n={username:this.access.username,password:(r=this.access.password,a=s,E.AES.encrypt(r,a).toString()),uOne:t,randStr:"",ticket:"",service:"",isRemoteLogin:!1};var r,a;const c=new FormData;for(const e in n)c.append(e,n[e]);const p=await this.http.request({url:"https://login.xinnet.com/newlogin",method:"post",headers:{Origin:"https://login.xinnet.com",Referer:"https://login.xinnet.com/separatePage/?service=https://www.xinnet.com/","Content-Type":"multipart/form-data",Cookie:i},data:c,withCredentials:!0,returnOriginRes:!0}),d=this.getCookie(p);this.logger.info("登录成功,loginCookie:",d);const l=p.data.data.xTickets;this.logger.info("tickets:",l),this.xTickets=l,this.loginCookies=d;const h=`https://domain.xinnet.com/domainsso/getXtoken?xticket=${this.xTickets.split("###")[3]}&callback=${"jsonp_"+(Math.floor(1e5*Math.random())*Date.now()).toString(16)}`;console.log("getxtoken-------",h);const u=await this.doRedirectRequest({url:h,method:"get",headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0",cookie:d},maxRedirects:0,withCredentials:!0,returnOriginRes:!0}),m=this.getCookie(u);this.logger.info("获取domainXtoken成功:",m),this.domainTokenCookie=m}async getDomainList(e){this.domainTokenCookie||await this.getToken();const t=new p(e);return await this.doDomainRequest({url:"https://domain.xinnet.com/domainManage/domainList",method:"post",data:{pageNo:t.pageNo,pageSize:t.pageSize,domainName:e.searchKey??""}})}async doDomainRequest(e){this.domainTokenCookie||await this.getToken();return await this.http.request({url:e.url,method:e.method??"post",headers:{Host:"domain.xinnet.com",Origin:"https://domain.xinnet.com",Referer:"https://domain.xinnet.com/","User-Agent":this.userAgent,cookie:this.domainTokenCookie},data:e.data,withCredentials:!0})}async getDcpCookie(e){this.domainTokenCookie||await this.getToken();const t=this.domainTokenCookie,s="https://domain.xinnet.com/dcp?serviceCode="+e.serviceCode+"&type=analytic",o=(await this.doRedirectRequest({url:s,method:"get",headers:{cookie:t},maxRedirects:0,withCredentials:!0,returnOriginRes:!0})).headers.location;console.log("跳转到dcp:",o);const i=await this.doRedirectRequest({url:o,method:"get",maxRedirects:0,withCredentials:!0,returnOriginRes:!0}),n=this.getCookie(i);return this.logger.info("dcpCookie",n),n}async getDomainDnsList(e){const t=await this.http.request({url:"https://dcp.xinnet.com/dcp/domaincloudanalytic/list",method:"post",headers:{"Content-Type":"application/json; charset=UTF-8",Host:"dcp.xinnet.com",Origin:"https://dcp.xinnet.com",Referer:"https://dcp.xinnet.com/dcpProduct.html",cookie:e.dcpCookie},data:{type:"ALL",content:e.recordValue||"",skip:1,limit:10},withCredentials:!0});if(0!=t.code)throw this.logger.error("获取DNS列表失败",JSON.stringify(t)),new Error("获取DNS列表失败");return t.data?.list}async addDomainDnsRecord(e,t){const s=await this.doDcpRequest({url:"https://dcp.xinnet.com/dcp/domaincloudanalytic/add",method:"post",data:{recordName:e.recordName,type:e.type,content:e.recordValue,ttl:600,phoneCode:1}},t);this.logger.info(s),await D.sleep(3e3);const o=await this.getDomainDnsList({serviceCode:t.serviceCode,recordValue:e.recordValue,dcpCookie:t.dcpCookie});if(!o||0===o.length)throw new Error("未找到添加的DNS记录");const i=o[0];return{recordId:i.id,recordFullName:i.name,recordValue:i.content,type:i.type}}async deleteDomainDnsRecord(e,t){const s=await this.doDcpRequest({url:"https://dcp.xinnet.com/dcp/domaincloudanalytic/delete",method:"post",data:{recordId:e.recordId,recordName:e.recordFullName,content:e.recordValue,type:e.type,isBatch:0,phoneCode:1}},t);return console.log(s.data),s}async doDcpRequest(e,t){return await this.http.request({url:e.url,method:e.method??"post",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",Host:"dcp.xinnet.com",Origin:"https://dcp.xinnet.com",Referer:"https://dcp.xinnet.com/dcpProduct.html",cookie:t.dcpCookie},withCredentials:!0,data:e.data})}}export{_ as AbstractPlusTaskPlugin,Oe as AlipayAccess,ie as AliyunDeployCertToAll,be as BaiduAccess,Se as BaiduDeployToBLBPlugin,ve as BaiduDeployToCDNPlugin,ke as BaiduUploadCert,we as BaiduYunCertClient,fe as BaiduYunClient,De as BaishanAccess,xe as BaishanUpdateCert,H as BaotaAccess,G as BaotaClient,F as BaotaDeleteExpiringCert,W as BaotaDeployPanelCertPlugin,B as BaotaDeployWAF,U as BaotaDeployWebSiteCert,V as BaotaDeployWebSiteWin,z as BaotaWafAccess,se as CdnflyAccess,te as CdnflyDeployToCDNPlugin,Ke as CtyunDeployToCDN,oe as DeployCertToAliyunAckPlugin,Te as HostDeployToIIS,pe as K8sAccess,he as K8sApplyPlugin,le as K8sDeployToIngressPlugin,de as K8sDeployToSecretPlugin,Ue as KuocaiCdnAccess,We as KuocaiDeployToCDNPlugin,qe as LeCDNAccess,Ie as LeCDNUpdateCert,Ce as LeCDNUpdateCertV2,Ge as LuckyAccess,Me as LuckyUpdateCert,He as MaoyunAccess,ze as MaoyunClient,ge as OnePanelAccess,ue as OnePanelClient,me as OnePanelDeployToWebsitePlugin,$e as PleskAccess,Re as PleskDeploySiteCert,ye as QiniuDeployCertToOSS,je as SafelineAccess,Ee as SafelineDeployToWebsitePlugin,ce as SynologyAccess,re as SynologyClient,ae as SynologyDeployToPanel,Fe as UniCloudAccess,Be as UniCloudClient,Ve as UniCloudDeployToSpace,ee as UploadCertToFTPPlugin,Le as WxpayAccess,Je as XinnetClient,Z as YfySmsAccess,Y as YidunAccess,J as YidunDeployToCDNPlugin,X as YidunDeployToRCDNPlugin,Q as YidunRcdnAccess,Ne as YizhifuAccess,j as mustPlus};
|
|
1
|
+
import e from"querystring";import{CertReader as t}from"@certd/plugin-lib";import o from"fs";import i from"form-data";import s from"crypto-js";import{utils as n,http as r}from"@certd/basic";import{Pager as a}from"@certd/pipeline";const c="certd";class d{access;http;logger;skipSslVerify;token;constructor(e,t,o,i){this.access=e,this.http=t,this.logger=o,this.skipSslVerify=i}async doLogin(){const e=this.access;if(e.otp&&null!=e.deviceId)return this.logger.info("OTP登录"),await this.doLoginWithDeviceId(e.deviceId);this.logger.info("使用普通登录");const t=this.getLoginUrl(),o=await this.http.request({url:t,method:"GET",params:{api:"SYNO.API.Auth",version:6,method:"login",account:e.username,passwd:e.password,session:"Certd",format:"sid",enable_syno_token:"yes"},skipSslVerify:this.skipSslVerify??!0,timeout:1e3*this.access.timeout||12e4});if(!o.success)throw new Error("登录失败: ",o.error);return this.logger.info("登录成功"),this.token=o.data,this.token}async doLoginWithOTPCode(e){const t=this.getLoginUrl(),o=this.access,i=await this.http.request({url:t,method:"GET",params:{api:"SYNO.API.Auth",version:6,method:"login",account:o.username,passwd:o.password,otp_code:e,enable_device_token:"yes",device_name:c},timeout:1e3*this.access.timeout||3e4,skipSslVerify:this.skipSslVerify??!0});if(!i.success)throw new Error("登录失败: ",i.error);return this.logger.info("登录成功"),this.token=i.data,this.token}getLoginUrl(){const e=this.access,t="6"===e.version?"auth.cgi":"entry.cgi";return`${e.baseUrl}/webapi/${t}`}async doLoginWithDeviceId(e){const t=this.access,o=this.getLoginUrl(),i=await this.http.request({url:o,method:"GET",params:{api:"SYNO.API.Auth",version:6,method:"login",account:t.username,passwd:t.password,device_name:c,device_id:e,session:"Certd",format:"sid",enable_syno_token:"yes"},timeout:1e3*this.access.timeout||3e4,skipSslVerify:this.skipSslVerify??!0});if(!i.success)throw new Error("登录失败: ",i.error);return this.logger.info("登录成功"),this.token=i.data,this.token}async doRequest(t){const o=this.token.sid,i=t.method||"POST",s={...t.apiParams,_sid:o,...t.params,SynoToken:this.token.synotoken},n=await this.http.request({url:`${this.access.baseUrl}/webapi/entry.cgi?${e.stringify(s)}`,method:i,data:t.data,headers:t.headers,skipSslVerify:this.skipSslVerify??!0,timeout:1e3*this.access.timeout||3e4});if(!n.success)throw new Error(`API 调用失败: ${JSON.stringify(n.error)}`);return n.data}async getCertList(){return this.logger.info("获取证书列表"),await this.doRequest({method:"GET",apiParams:{api:"SYNO.Core.Certificate.CRT",version:1,method:"list"}})}async getInfo(){return this.logger.info("获取信息"),await this.doRequest({method:"GET",apiParams:{api:"SYNO.API.Info",version:1,method:"query"}})}async updateCertToPanel(e,s){this.logger.info(`更新证书:${e.id}`);const n=new t(s);return n.readCertFile({logger:this.logger,handle:async t=>{const s=new i,{tmpCrtPath:r,tmpKeyPath:a,tmpIcPath:c}=t;return this.logger.info(`上传证书:${r},${a}`),s.append("key",o.createReadStream(a)),s.append("cert",o.createReadStream(r)),n.cert.ic&&(this.logger.info(`包含中间证书:${c}`),s.append("inter_cert",o.createReadStream(c))),s.append("id",e.id),s.append("desc",e.desc),console.log(JSON.stringify(s.getHeaders())),await this.doRequest({method:"POST",apiParams:{api:"SYNO.Core.Certificate",version:1,method:"import"},data:s,headers:{...s.getHeaders()}})}})}}class h{access=null;http=null;logger=null;xTickets=null;loginCookies=null;domainTokenCookie=null;userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0";constructor(e){this.access=e.access,this.http=e.http,this.logger=e.logger}async doRedirectRequest(e){let t=null;try{t=await this.http.request(e)}catch(e){if(t=e.response,this.logger.info(t.headers),!t)throw new Error("请求失败:",e)}return t}getCookie(e){const t=e.headers["set-cookie"];if(!t||0===t.length)throw new Error("未获取到cookie",e);return t.map((e=>e.split(";")[0])).join(";")}async getToken(){const e=await this.http.request({url:"https://login.xinnet.com/queryUOne",method:"get"});this.logger.info("queryUOne",e.data);const{uOne:t,uTwo:o}=e.data,i=await this.doRedirectRequest({url:"https://login.xinnet.com/newlogin",method:"get",headers:{Host:"login.xinnet.com",Origin:"https://login.xinnet.com",Referer:"https://login.xinnet.com/separatePage/?service=https://www.xinnet.com/"},maxRedirects:0,withCredentials:!0,returnOriginRes:!0}),n=this.getCookie(i);this.logger.info("firstCookie",n);const r={username:this.access.username,password:(a=this.access.password,c=o,s.AES.encrypt(a,c).toString()),uOne:t,randStr:"",ticket:"",service:"",isRemoteLogin:!1};var a,c;const d=new FormData;for(const e in r)d.append(e,r[e]);const h=await this.http.request({url:"https://login.xinnet.com/newlogin",method:"post",headers:{Origin:"https://login.xinnet.com",Referer:"https://login.xinnet.com/separatePage/?service=https://www.xinnet.com/","Content-Type":"multipart/form-data",Cookie:n},data:d,withCredentials:!0,returnOriginRes:!0}),l=this.getCookie(h);this.logger.info("登录成功,loginCookie:",l);const p=h.data.data.xTickets;this.logger.info("tickets:",p),this.xTickets=p,this.loginCookies=l;const u=`https://domain.xinnet.com/domainsso/getXtoken?xticket=${this.xTickets.split("###")[3]}&callback=${"jsonp_"+(Math.floor(1e5*Math.random())*Date.now()).toString(16)}`;console.log("getxtoken-------",u);const m=await this.doRedirectRequest({url:u,method:"get",headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0",cookie:l},maxRedirects:0,withCredentials:!0,returnOriginRes:!0}),g=this.getCookie(m);this.logger.info("获取domainXtoken成功:",g),this.domainTokenCookie=g}async getDomainList(e){this.domainTokenCookie||await this.getToken();const t=new a(e);return await this.doDomainRequest({url:"https://domain.xinnet.com/domainManage/domainList",method:"post",data:{pageNo:t.pageNo,pageSize:t.pageSize,domainName:e.searchKey??""}})}async doDomainRequest(e){this.domainTokenCookie||await this.getToken();return await this.http.request({url:e.url,method:e.method??"post",headers:{Host:"domain.xinnet.com",Origin:"https://domain.xinnet.com",Referer:"https://domain.xinnet.com/","User-Agent":this.userAgent,cookie:this.domainTokenCookie},data:e.data,withCredentials:!0})}async getDcpCookie(e){this.domainTokenCookie||await this.getToken();const t=this.domainTokenCookie,o="https://domain.xinnet.com/dcp?serviceCode="+e.serviceCode+"&type=analytic",i=(await this.doRedirectRequest({url:o,method:"get",headers:{cookie:t},maxRedirects:0,withCredentials:!0,returnOriginRes:!0})).headers.location;console.log("跳转到dcp:",i);const s=await this.doRedirectRequest({url:i,method:"get",maxRedirects:0,withCredentials:!0,returnOriginRes:!0}),n=this.getCookie(s);return this.logger.info("dcpCookie",n),n}async getDomainDnsList(e){const t=await this.http.request({url:"https://dcp.xinnet.com/dcp/domaincloudanalytic/list",method:"post",headers:{"Content-Type":"application/json; charset=UTF-8",Host:"dcp.xinnet.com",Origin:"https://dcp.xinnet.com",Referer:"https://dcp.xinnet.com/dcpProduct.html",cookie:e.dcpCookie},data:{type:"ALL",content:e.recordValue||"",skip:1,limit:10},withCredentials:!0});if(0!=t.code)throw this.logger.error("获取DNS列表失败",JSON.stringify(t)),new Error("获取DNS列表失败");return t.data?.list}async addDomainDnsRecord(e,t){const o=await this.doDcpRequest({url:"https://dcp.xinnet.com/dcp/domaincloudanalytic/add",method:"post",data:{recordName:e.recordName,type:e.type,content:e.recordValue,ttl:600,phoneCode:1}},t);this.logger.info(o),await n.sleep(3e3);const i=await this.getDomainDnsList({serviceCode:t.serviceCode,recordValue:e.recordValue,dcpCookie:t.dcpCookie});if(!i||0===i.length)throw new Error("未找到添加的DNS记录");const s=i[0];return{recordId:s.id,recordFullName:s.name,recordValue:s.content,type:s.type}}async deleteDomainDnsRecord(e,t){const o=await this.doDcpRequest({url:"https://dcp.xinnet.com/dcp/domaincloudanalytic/delete",method:"post",data:{recordId:e.recordId,recordName:e.recordFullName,content:e.recordValue,type:e.type,isBatch:0,phoneCode:1}},t);return console.log(o.data),o}async doDcpRequest(e,t){return await this.http.request({url:e.url,method:e.method??"post",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",Host:"dcp.xinnet.com",Origin:"https://dcp.xinnet.com",Referer:"https://dcp.xinnet.com/dcpProduct.html",cookie:t.dcpCookie},withCredentials:!0,data:e.data})}}class l{opts;deviceId;xToken;token;cookie;constructor(e){this.opts=e,this.deviceId=(new Date).getTime()+Math.floor(1e6*Math.random())+""}async sign(e,t){const o=(await import("crypto-js")).default;let i="";return Object.keys(e).sort().forEach((function(t){e[t]&&(i=i+"&"+t+"="+e[t])})),i=i.slice(1),o.HmacMD5(i,t).toString()}async doRequest(e){const t=(await r.request({...e,logRes:!1,returnOriginRes:!0})).data;if(null!=t.ret){if(0!==t.ret)throw new Error(JSON.stringify(t));return t.data}if(!t.success)throw new Error(JSON.stringify(t.error));if(t.data?.errCode)throw new Error(JSON.stringify(t.data));return t.data}async login(){if(this.xToken)return this.xToken;const e=this.deviceId,t=this.opts.access.email;var o;const i={method:"serverless.function.runtime.invoke",params:`{"functionTarget":"uni-id-co","functionArgs":{"method":"login","params":[{"password":"${this.opts.access.password}","captcha":"","resetAppId":"__UNI__unicloud_console","resetUniPlatform":"web","isReturnToken":false,"email":"${t}"}],"clientInfo":${`{"PLATFORM":"web","OS":"windows","APPID":"${o="__UNI__uniid_server"}","DEVICEID":"${e}","scene":1001,"appId":"${o}","appLanguage":"zh-Hans","appName":"账号中心","appVersion":"1.0.0","appVersionCode":"100","browserName":"chrome","browserVersion":"122.0.6261.95","deviceId":"174585375190823882061","deviceModel":"PC","deviceType":"pc","hostName":"chrome","hostVersion":"122.0.6261.95","osName":"windows","osVersion":"10 x64","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36","uniCompilerVersion":"4.45","uniPlatform":"web","uniRuntimeVersion":"4.45","locale":"zh-Hans","LOCALE":"zh-Hans"}`}}}`,spaceId:"uni-id-server",timestamp:(new Date).getTime()},s=await this.sign(i,"ba461799-fde8-429f-8cc4-4b6d306e2339"),n=(await this.doRequest({url:"https://account.dcloud.net.cn/client",method:"POST",data:i,headers:{"X-Serverless-Sign":s,Origin:"https://account.dcloud.net.cn",Referer:"https://account.dcloud.net.cn"}})).newToken.token;return this.xToken=n,this.opts.logger.info("登录成功:",n),n}async getToken(){if(this.token)return{token:this.token,cookie:this.cookie};const e=await this.login(),t=this.deviceId,o=`{"PLATFORM":"web","OS":"windows","APPID":"__UNI__unicloud_console","DEVICEID":"${t}","scene":1001,"appId":"__UNI__unicloud_console","appLanguage":"zh-Hans","appName":"uniCloud控制台","appVersion":"1.0.0","appVersionCode":"100","browserName":"chrome","browserVersion":"122.0.6261.95","deviceId":"${t}","deviceModel":"PC","deviceType":"pc","hostName":"chrome","hostVersion":"122.0.6261.95","osName":"windows","osVersion":"10 x64","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36","uniCompilerVersion":"4.57","uniPlatform":"web","uniRuntimeVersion":"4.57","locale":"zh-Hans","LOCALE":"zh-Hans"}`,i={method:"serverless.function.runtime.invoke",params:`{"functionTarget":"uni-cloud-kernel","functionArgs":{"action":"user/getUserToken","data":{"isLogin":true},"clientInfo":${o},"uniIdToken":"${e}"}}`,spaceId:"dc-6nfabcn6ada8d3dd",timestamp:(new Date).getTime()},s=await this.sign(i,"4c1f7fbf-c732-42b0-ab10-4634a8bbe834"),n=await this.doRequest({url:"https://unicloud.dcloud.net.cn/client",method:"POST",data:i,headers:{"X-Client-Info":encodeURIComponent(o),"X-Serverless-Sign":s,"X-Client-Token":e,Origin:"https://unicloud.dcloud.net.cn",Referer:"https://unicloud.dcloud.net.cn"}}),r=n.data.data.token,a=n.headers["set-cookie"];let c="";for(let e=0;e<a.length;e++){c+=a[e].substring(0,a[e].indexOf(";"))+";"}return this.token=r,this.opts.logger.info("获取token成功:",r),this.cookie=c,{token:r,cookie:c}}async createCert(e){await this.getToken();const{spaceId:t,domain:o,cert:i,provider:s}=e;this.opts.logger.info(`开始部署证书, provider:${s},spaceId:${t},domain:${o}`);const n={appid:"",provider:s,spaceId:t,domain:o,cert:encodeURIComponent(i.crt),key:encodeURIComponent(i.key)},r=await this.doRequest({url:"https://unicloud-api.dcloud.net.cn/unicloud/api/host/create-domain-with-cert",method:"POST",data:n,headers:{Token:this.token,Cookie:this.cookie}});this.opts.logger.info("证书部署成功:",JSON.stringify(r))}}export{d as SynologyClient,l as UniCloudClient,h as XinnetClient};
|
package/fix-esm-import-paths.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as fs from
|
|
2
|
-
import * as path from
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
3
|
|
|
4
4
|
// https://gist.github.com/lovasoa/8691344
|
|
5
5
|
async function* walk(dir) {
|
|
@@ -20,16 +20,16 @@ function resolveImportPath(sourceFile, importPath, options) {
|
|
|
20
20
|
|
|
21
21
|
if (moduleFilter(importPath)) {
|
|
22
22
|
const importPathAbs = path.resolve(root, importPath);
|
|
23
|
-
let possiblePath = [path.resolve(importPathAbs,
|
|
23
|
+
let possiblePath = [path.resolve(importPathAbs, "./index.ts"), path.resolve(importPathAbs, "./index.js"), importPathAbs + ".ts", importPathAbs + ".js"];
|
|
24
24
|
|
|
25
25
|
if (possiblePath.length) {
|
|
26
26
|
for (let i = 0; i < possiblePath.length; i++) {
|
|
27
27
|
let entry = possiblePath[i];
|
|
28
28
|
if (fs.existsSync(entry)) {
|
|
29
|
-
const resolved = path.relative(root, entry.replace(/\.ts$/,
|
|
29
|
+
const resolved = path.relative(root, entry.replace(/\.ts$/, ".js"));
|
|
30
30
|
|
|
31
|
-
if (!resolved.startsWith(
|
|
32
|
-
return
|
|
31
|
+
if (!resolved.startsWith(".")) {
|
|
32
|
+
return "./" + resolved;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
return resolved;
|
|
@@ -48,8 +48,8 @@ function replace(filePath, outFilePath, options) {
|
|
|
48
48
|
let resolvedPath = resolveImportPath(filePath, importPath, options);
|
|
49
49
|
|
|
50
50
|
if (resolvedPath) {
|
|
51
|
-
resolvedPath = resolvedPath.replaceAll(
|
|
52
|
-
console.log(
|
|
51
|
+
resolvedPath = resolvedPath.replaceAll("\\", "/");
|
|
52
|
+
console.log("\t", importPath, resolvedPath);
|
|
53
53
|
return `${action} ${imported} from "${resolvedPath}";`;
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -78,7 +78,7 @@ const defaultSourceFileFilter = function (sourceFilePath) {
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
const defaultModuleFilter = function (importedModule) {
|
|
81
|
-
return !path.isAbsolute(importedModule) && !importedModule.startsWith(
|
|
81
|
+
return !path.isAbsolute(importedModule) && !importedModule.startsWith("@") && !importedModule.endsWith(".js");
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
const defaultOptions = {
|
|
@@ -90,7 +90,7 @@ const defaultOptions = {
|
|
|
90
90
|
const DEBUG = false;
|
|
91
91
|
|
|
92
92
|
if (DEBUG) {
|
|
93
|
-
replace(
|
|
93
|
+
replace("./src/index.ts", "./out.ts", defaultOptions);
|
|
94
94
|
} else {
|
|
95
|
-
await run(
|
|
95
|
+
await run("./src/", defaultOptions);
|
|
96
96
|
}
|