mirror of
https://github.com/certd/certd.git
synced 2026-05-16 21:27:34 +08:00
feat: 【破坏性更新】插件改为metadata加载模式,plugin-cert、plugin-lib包部分代码转移到certd-server中,影响自定义插件,需要修改相关import引用
ssh、aliyun、tencent、qiniu、oss等 access和client需要转移import
This commit is contained in:
@@ -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";
|
||||
+111
@@ -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();
|
||||
Reference in New Issue
Block a user