feat: 【破坏性更新】插件改为metadata加载模式,plugin-cert、plugin-lib包部分代码转移到certd-server中,影响自定义插件,需要修改相关import引用

ssh、aliyun、tencent、qiniu、oss等 access和client需要转移import
This commit is contained in:
xiaojunnuo
2025-12-31 17:01:37 +08:00
parent 9c26598831
commit a3fb24993d
312 changed files with 14321 additions and 597 deletions
@@ -0,0 +1,34 @@
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
/**
*/
@IsAccess({
name: "unicloud",
title: "uniCloud",
icon: "material-symbols:shield-outline",
desc: "unicloud授权",
})
export class UniCloudAccess extends BaseAccess {
@AccessInput({
title: "账号",
component: {
placeholder: "email",
},
helper: "登录邮箱",
required: true,
encrypt: false,
})
email = "";
@AccessInput({
title: "密码",
component: {
placeholder: "密码",
},
required: true,
encrypt: true,
})
password = "";
}
new UniCloudAccess();
@@ -0,0 +1,169 @@
import { UniCloudAccess } from "./access.js";
import { http, HttpClient, HttpRequestConfig, ILogger } from "@certd/basic";
import { CertInfo } from "@certd/plugin-cert";
type UniCloudClientOpts = { access: UniCloudAccess; logger: ILogger; http: HttpClient };
export class UniCloudClient {
opts: UniCloudClientOpts;
deviceId: string;
xToken: string;
token: string;
cookie: string;
constructor(opts: UniCloudClientOpts) {
this.opts = opts;
this.deviceId = new Date().getTime() + Math.floor(Math.random() * 1000000) + "";
}
async sign(data: any, secretKey: string) {
const Crypto = await import("crypto-js");
const CryptoJS = Crypto.default;
let content = "";
Object.keys(data)
.sort()
.forEach(function (key) {
if (data[key]) {
content = content + "&" + key + "=" + data[key];
}
});
content = content.slice(1);
return CryptoJS.HmacMD5(content, secretKey).toString();
}
async doRequest(req: HttpRequestConfig) {
const res = await http.request({
...req,
logRes: false,
returnOriginRes: true,
});
const data = res.data;
if (data.ret != null) {
if (data.ret !== 0) {
throw new Error(JSON.stringify(data));
}
return data.data;
}
if (!data.success) {
throw new Error(JSON.stringify(data.error));
}
if (data.data?.errCode) {
throw new Error(JSON.stringify(data.data));
}
return data.data;
}
async login() {
if (this.xToken) {
return this.xToken;
}
const deviceId = this.deviceId;
const username = this.opts.access.email;
const password = this.opts.access.password;
function getClientInfo(appId) {
return `{"PLATFORM":"web","OS":"windows","APPID":"${appId}","DEVICEID":"${deviceId}","scene":1001,"appId":"${appId}","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"}`;
}
const clientInfo = getClientInfo("__UNI__uniid_server");
const loginData = {
method: "serverless.function.runtime.invoke",
params: `{"functionTarget":"uni-id-co","functionArgs":{"method":"login","params":[{"password":"${password}","captcha":"","resetAppId":"__UNI__unicloud_console","resetUniPlatform":"web","isReturnToken":false,"email":"${username}"}],"clientInfo":${clientInfo}}}`,
spaceId: "uni-id-server",
timestamp: new Date().getTime(),
};
const secretKey = "ba461799-fde8-429f-8cc4-4b6d306e2339";
const xSign = await this.sign(loginData, secretKey);
const res = await this.doRequest({
url: "https://account.dcloud.net.cn/client",
method: "POST",
data: loginData,
headers: {
"X-Serverless-Sign": xSign,
Origin: "https://account.dcloud.net.cn",
Referer: "https://account.dcloud.net.cn",
},
});
const token = res.newToken.token;
// const uid = res.data.uid;
this.xToken = token;
this.opts.logger.info("登录成功:", token);
return token;
}
async getToken() {
if (this.token) {
return {
token: this.token,
cookie: this.cookie,
};
}
const xToken = await this.login();
const deviceId = this.deviceId;
const secretKey = "4c1f7fbf-c732-42b0-ab10-4634a8bbe834";
const clientInfo = `{"PLATFORM":"web","OS":"windows","APPID":"__UNI__unicloud_console","DEVICEID":"${deviceId}","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":"${deviceId}","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"}`;
const body = {
method: "serverless.function.runtime.invoke",
params: `{"functionTarget":"uni-cloud-kernel","functionArgs":{"action":"user/getUserToken","data":{"isLogin":true},"clientInfo":${clientInfo},"uniIdToken":"${xToken}"}}`,
spaceId: "dc-6nfabcn6ada8d3dd",
timestamp: new Date().getTime(),
};
const xSign = await this.sign(body, secretKey);
const res = await this.doRequest({
url: "https://unicloud.dcloud.net.cn/client",
method: "POST",
data: body,
headers: {
"X-Client-Info": encodeURIComponent(clientInfo),
"X-Serverless-Sign": xSign,
"X-Client-Token": xToken,
Origin: "https://unicloud.dcloud.net.cn",
Referer: "https://unicloud.dcloud.net.cn",
},
});
const token = res.data.data.token;
const cookies = res.headers["set-cookie"];
let cookie = "";
for (let i = 0; i < cookies.length; i++) {
const item = cookies[i].substring(0, cookies[i].indexOf(";"));
cookie += item + ";";
}
this.token = token;
this.opts.logger.info("获取token成功:", token);
this.cookie = cookie;
return {
token,
cookie,
};
}
async createCert(req: { spaceId: string; domain: string; provider: string; cert: CertInfo }) {
await this.getToken();
const { spaceId, domain, cert, provider } = req;
this.opts.logger.info(`开始部署证书, provider:${provider},spaceId:${spaceId},domain:${domain}`);
const crt = encodeURIComponent(cert.crt);
const key = encodeURIComponent(cert.key);
const body = {
appid: "",
provider,
spaceId: spaceId,
domain: domain,
cert: crt,
key,
};
const res = await this.doRequest({
url: "https://unicloud-api.dcloud.net.cn/unicloud/api/host/create-domain-with-cert",
method: "POST",
data: body,
headers: {
Token: this.token,
Cookie: this.cookie,
},
});
this.opts.logger.info("证书部署成功:", JSON.stringify(res));
}
}
@@ -0,0 +1,3 @@
export * from "./plugins/index.js";
export * from "./access.js";
export * from "./client.js";
@@ -0,0 +1 @@
export * from "./plugin-deploy-to-space.js";
@@ -0,0 +1,111 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
import { UniCloudAccess } from "../access.js";
import { UniCloudClient } from "../client.js";
@IsTaskPlugin({
name: "UniCloudDeployToSpace",
title: "uniCloud-部署到服务空间",
icon: "material-symbols:shield-outline",
group: pluginGroups.panel.key,
desc: "部署到服务空间",
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
needPlus: false,
})
export class UniCloudDeployToSpace extends AbstractTaskPlugin {
//证书选择,此项必须要有
@TaskInput({
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames],
},
required: true,
})
cert!: CertInfo;
//授权选择框
@TaskInput({
title: "uniCloud授权",
helper: "uniCloud授权",
component: {
name: "access-selector",
type: "unicloud",
},
required: true,
})
accessId!: string;
//测试参数
@TaskInput({
title: "服务空间ID",
component: {
name: "a-input",
vModel: "value",
},
helper: "spaceId",
})
spaceId!: string;
@TaskInput({
title: "空间提供商",
component: {
name: "a-select",
vModel: "value",
options: [
{
label: "阿里云",
value: "aliyun",
},
{
label: "腾讯云",
value: "tencent",
},
{
label: "支付宝云",
value: "alipay",
},
],
},
helper: "空间提供商",
})
provider!: string;
@TaskInput({
title: "空间域名",
component: {
name: "a-select",
vModel: "value",
mode: "tags",
open: false,
},
helper: "空间域名",
})
domains!: string[];
async onInstance() {}
async execute(): Promise<void> {
const access = await this.getAccess<UniCloudAccess>(this.accessId);
const client = new UniCloudClient({
access,
logger: this.logger,
http: this.http,
});
for (const domain of this.domains) {
await client.createCert({
domain,
provider: this.provider,
spaceId: this.spaceId,
cert: this.cert,
});
}
this.logger.info("部署成功");
}
}
new UniCloudDeployToSpace();