perf: 支持七牛云

pull/189/head
xiaojunnuo 2024-09-24 13:50:06 +08:00
parent 8de56feeb7
commit 8ecc2f9446
16 changed files with 240 additions and 8 deletions

View File

@ -201,9 +201,6 @@ async function getWebCryptoKeyPair(keyPem) {
}
/* Decode PEM and import into CryptoKeyPair */
if (encodingType === 'pkcs1') {
encodingType = 'pkcs8';
}
const privateKeyDec = x509.PemConverter.decodeFirst(keyPem.toString());
const privateKey = await crypto.webcrypto.subtle.importKey('pkcs8', privateKeyDec, sigalg, true, ['sign']);
const publicKey = await crypto.webcrypto.subtle.importKey('jwk', jwk, sigalg, true, ['verify']);

View File

@ -12,7 +12,7 @@ export type AccessDefine = Registrable & {
};
};
export interface IAccessService {
getById(id: any): Promise<any>;
getById<T = any>(id: any): Promise<T>;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface

View File

@ -54,6 +54,12 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe603;</span>
<div class="name">qiniuyun</div>
<div class="code-name">&amp;#xe603;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe601;</span>
<div class="name">aliyun</div>
@ -96,7 +102,7 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.svg?t=1726734453480#iconfont') format('svg');
src: url('iconfont.svg?t=1727153857332#iconfont') format('svg');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -122,6 +128,15 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-qiniuyun"></span>
<div class="name">
qiniuyun
</div>
<div class="code-name">.icon-qiniuyun
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-aliyun"></span>
<div class="name">
@ -185,6 +200,14 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-qiniuyun"></use>
</svg>
<div class="name">qiniuyun</div>
<div class="code-name">#icon-qiniuyun</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-aliyun"></use>

View File

@ -1,6 +1,6 @@
@font-face {
font-family: "iconfont"; /* Project id 4688792 */
src: url('iconfont.svg?t=1726734453480#iconfont') format('svg');
src: url('iconfont.svg?t=1727153857332#iconfont') format('svg');
}
.iconfont {
@ -11,6 +11,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-qiniuyun:before {
content: "\e603";
}
.icon-aliyun:before {
content: "\e601";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "9612999",
"name": "qiniuyun",
"font_class": "qiniuyun",
"unicode": "e603",
"unicode_decimal": 58883
},
{
"icon_id": "26492886",
"name": "aliyun",

View File

@ -14,6 +14,8 @@
/>
<missing-glyph />
<glyph glyph-name="qiniuyun" unicode="&#58883;" d="M53.684427 804.418697a705.73155 705.73155 0 0 1 52.395618-94.012709 810.709913 810.709913 0 0 1 74.626331-96.63249c6.100347-11.003079 18.301041-15.868388 24.438812-28.106506 10.965654-9.76804 21.968734-20.733695 32.971814-31.736775a1023.698102 1023.698102 0 0 1 119.761413-86.714748c17.103427-9.805465 33.009239-18.338467 50.112667-26.871467 3.742544-4.902733 1.197614-9.805465 2.432653-14.670773 6.100347-35.441893 8.533-72.0814 13.435733-107.485868 2.432654-20.77112 3.742544-42.777279 7.297962-63.623251 6.137772-35.441893 9.805465-72.0814 14.670773-107.523293 6.100347-40.3072 9.76804-80.576976 17.103427-120.884176 3.742544-19.573506 14.670773-35.441893 23.203773-53.78036 2.432654-3.742544 6.100347-6.100347 8.570427-10.965654 31.736774-40.3072 74.476628-57.410627 125.786909-57.410627h287.053136c73.279014 0 124.589295 35.404468 152.695801 103.818174 13.435733 32.971814 15.868388 68.413707 19.536081 102.620562l25.636427 208.871388c2.470079 10.965654-1.197614 12.200694-10.965654 12.200695-24.438814 0-46.444972-6.100347-68.413707-14.670774-17.103427-4.865307-28.106507-17.103427-40.3072-28.106507a21.220225 21.220225 0 0 1-8.533002-6.100347c-8.570426-13.435733-19.573506-24.438814-24.438813-39.07216a410.819071 410.819071 0 0 1-14.670773-41.54224c-9.76804-34.169428-19.536081-69.611321-29.304121-105.015789-3.742544-17.103427-13.435733-29.341546-24.438813-42.77728a40.906008 40.906008 0 0 0-29.304121-13.435734c-59.880706-3.742544-118.488948-2.432654-178.332228-1.197614a58.159136 58.159136 0 0 0-50.112667 30.501735c-8.533 14.670773-12.200694 29.341546-15.868387 45.209934-4.865307 22.00616-14.633347 42.739854-17.103426 65.981053a11.227632 11.227632 0 0 0-1.197615 6.062921c-17.103427 63.623251-35.441893 125.824334-52.395618 189.335309-1.197614 3.742544-3.742544 7.485088-1.197614 9.768041 2.432654 3.742544 7.297961 1.23504 10.965654 0a665.124946 665.124946 0 0 1 70.846362-14.633348 811.907528 811.907528 0 0 1 204.006081-6.100347 435.557288 435.557288 0 0 1 78.181747 13.435733c20.77112 8.533 42.739854 12.200694 64.708589 18.301041 28.106507 8.570426 54.977974 19.536081 83.084479 29.341547 12.200694 6.100347 25.636428 12.200694 37.837122 18.30104a839.826907 839.826907 0 0 1 90.419867 53.742934c4.865307 3.742544 9.76804 9.76804 14.633347 12.23812 13.435733 7.485088 24.438814 17.066002 36.639507 25.636427a52.395618 52.395618 0 0 1 20.771121 15.868387c6.100347 8.570426 14.670773 14.670773 22.00616 21.968735s15.868388 13.473159 21.968733 22.006159c6.100347 7.485088 14.670773 14.670773 22.00616 21.968734s7.485088 17.140853 17.103427 22.00616c7.485088 4.865307 10.965654 13.435733 17.103426 19.53608 2.432654 2.432654 4.865307 3.742544 6.100347 6.137773 1.197614 3.742544 3.742544 6.100347 4.865308 9.76804 14.670773 17.103427 25.673853 37.837121 39.109586 57.373202 10.965654 15.905812 17.103427 33.009239 28.069082 47.680012 1.23504 3.742544 0 7.485088 2.470079 10.965655 13.435733 18.338467 19.536081 40.3072 28.069081 61.07832 3.742544 7.485088 1.23504 9.76804-6.100348 9.76804-8.533 1.23504-17.103427 2.432654-23.203773-4.902732-1.23504-2.432654-3.742544-2.432654-6.100347-2.432654a15.419282 15.419282 0 0 1-15.868387-8.533001c-8.570426-14.670773-26.908893-23.203774-30.539161-41.54224h-1.235039c-8.570426 3.742544-12.200694-3.742544-15.868388-8.533a714.825933 714.825933 0 0 0-72.0814-64.746014 748.92051 748.92051 0 0 0-63.62325-45.209934c-28.106507-17.103427-53.742934-35.404468-84.282095-47.605161-1.23504-1.23504-2.432654-2.470079-2.432654-3.742544 0-3.742544-2.470079-2.470079-4.902732-2.470079a17.178278 17.178278 0 0 1-7.485088-2.432655c-32.971814-19.536081-69.611321-32.971814-105.015789-45.209933-50.112667-18.301041-103.8556-29.304121-156.363494-36.639507a510.370746 510.370746 0 0 0-74.514055-6.100347c-59.880706 0-118.488948-2.432654-178.332228 8.570426a1135.637597 1135.637597 0 0 0-124.589295 28.069082 8.944681 8.944681 0 0 0-7.485089 8.570425 134.057932 134.057932 0 0 1-8.570426 31.736775c-12.200694 40.3072-17.066002 83.047055-39.072161 120.921601-1.23504 1.23504-2.432654 1.23504-4.902732 1.23504a1.197614 1.197614 0 0 1-1.197614-1.23504v2.470079c-8.570426 11.003079-22.00616 15.868388-35.404468 18.301042-15.905812 3.742544-20.77112-1.197614-18.338467-15.868388 4.902733-37.874547 8.533-76.946708 14.633348-116.018869 1.23504-2.432654 2.470079-6.100347-1.197614-7.297961a7.709641 7.709641 0 0 0-7.485089 0c-17.103427 9.76804-32.971814 18.301041-50.07524 26.871467-23.203774 10.965654-43.974893 25.636428-64.746014 39.072161-9.76804 4.902733-17.103427 12.200694-25.636427 18.301041a620.438969 620.438969 0 0 0-81.849441 67.178668 444.988499 444.988499 0 0 0-67.365795 68.413707A49.888114 49.888114 0 0 1 47.022699 862.802386C32.38935 862.802386 28.721657 857.899653 34.822004 844.463919z" horiz-adv-x="1525" />
<glyph glyph-name="aliyun" unicode="&#58881;" d="M991.142857 521.25c-0.321428 87.964285-71.678572 159.214285-159.75 159.214285H580.464285l23.142858-91.285713 215.357142-46.821429a45.621428 45.621428 0 0 0 35.25-42.535715c0.107143-0.535715 0.107143-231.535715 0-232.071428a45.621428 45.621428 0 0 0-35.25-42.535715l-215.357142-46.821428-23.142858-91.392857h250.928572c87.964285 0 159.428572 71.25 159.75 159.214285V521.25zM205.035715 225a45.621428 45.621428 0 0 0-35.25 42.535715c-0.107143 0.642857-0.107143 231.535715 0 232.071428 0.857143 20.785715 15.642857 38.035715 35.25 42.535714l215.357142 46.821428 23.142858 91.285715H192.5c-87.964285 0-159.428572-71.142857-159.75-159.214285V245.785715c0.321428-87.964285 71.785715-159.214285 159.75-159.214287H443.428572l-23.142857 91.392857-215.25 47.035715z m215.25 170.142857h183.214285v-22.821429h-183.214285z" horiz-adv-x="1024" />
<glyph glyph-name="tencentcloud" unicode="&#59207;" d="M1224.103058 83.777804c-22.109216-22.109216-66.325973-55.270527-143.704042-55.270528H605.068459c143.702366 138.177156 265.300542 254.245096 276.354312 265.300542 11.05377 11.05377 38.689872 38.688196 66.324298 60.797413 55.272203 49.745318 99.48896 55.270527 138.177156 55.270527 55.272203 0 99.487284-22.107541 138.178833-55.270527 77.378068-71.852859 77.378068-198.974569 0-270.827427m93.960399 359.259265c-55.272203 60.799088-138.178832 99.48896-226.612346 99.48896-77.378068 0-143.702366-27.634426-204.501454-71.852858-22.109216-22.107541-55.270527-44.216757-82.906629-77.378068-22.107541-22.107541-497.436422-486.384328-497.436422-486.384328 27.634426-5.526885 60.799088-5.526885 88.433514-5.526885h602.450591c44.216757 0 77.378068 0 110.542731 5.526885 71.851183 5.526885 143.702366 33.164663 204.501454 88.433514 127.123386 121.596501 127.123386 326.099631 5.528561 447.694456zM544.271046 476.200056c-60.799088 44.216757-121.598177 66.325973-193.449359 66.325973-88.433514 0-171.338467-38.689872-226.608995-99.487284-121.598177-127.125062-121.598177-326.099631 5.52521-453.221341 55.272203-49.743642 110.542731-77.378068 176.867028-82.906629l127.125062 121.596501h-71.852859c-71.852859 5.526885-116.069616 27.634426-143.704041 55.270528-77.379744 77.378068-77.379744 198.974569-5.528561 276.354312 38.689872 38.689872 82.906629 55.270527 138.177156 55.270527 33.164663 0 82.906629-5.526885 132.651947-55.268851 22.105865-22.109216 82.904953-66.325973 105.012494-88.433514h5.528561l82.904953 82.903277v5.530237c-38.688196 38.688196-99.48896 88.431838-132.648596 116.06794M1124.614097 614.377212C1063.816685 780.193822 903.530312 896.25841 721.138075 896.25841c-215.558576 0-386.897043-160.284697-420.06003-359.259266 16.582331 0 33.164663 5.526885 55.272203 5.526885s49.743642-5.526885 71.851183-5.526885c27.634426 138.177156 149.229251 237.666117 292.934968 237.666117 121.596501-0.001676 226.61067-71.852859 276.354312-176.867028 0 0 5.528561-5.526885 5.528561 0 38.688196 5.526885 82.904953 16.580655 121.594825 16.580655 0-5.526885 0-5.526885 0 0" horiz-adv-x="1436" />

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -18,7 +18,6 @@
"up-mw-deps": "npx midway-version -u -w",
"heap": "clinic heapprofiler -- node ./bootstrap.js",
"flame": "clinic flame -- node ./bootstrap.js"
},
"dependencies": {
"@alicloud/cs20151215": "^3.0.3",
@ -65,6 +64,7 @@
"nanoid": "^4.0.0",
"nodemailer": "^6.9.3",
"pg": "^8.12.0",
"qiniu": "^7.12.0",
"querystring": "^0.2.1",
"reflect-metadata": "^0.1.13",
"ssh2": "^1.15.0",

View File

@ -8,3 +8,4 @@ export * from './plugin-demo/index.js';
export * from './plugin-other/index.js';
export * from './plugin-west/index.js';
export * from './plugin-doge/index.js';
export * from './plugin-qiniu/index.js';

View File

@ -0,0 +1,24 @@
import { AccessInput, IAccess, IsAccess } from '@certd/pipeline';
@IsAccess({
name: 'qiniu',
title: '七牛云授权',
desc: '',
input: {},
})
export class QiniuAccess implements IAccess {
@AccessInput({
title: 'AccessKey',
rules: [{ required: true, message: '此项必填' }],
helper: 'AK前往[密钥管理](https://portal.qiniu.com/developer/user/key)获取',
})
accessKey!: string;
@AccessInput({
title: 'SecretKey',
encrypt: true,
helper: 'SK',
})
secretKey!: string;
}
new QiniuAccess();

View File

@ -0,0 +1 @@
export * from './access.js';

View File

@ -0,0 +1,2 @@
export * from './plugin/index.js';
export * from './access/index.js';

View File

@ -0,0 +1,74 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import { QiniuAccess } from '../../access/index.js';
import { CertInfo } from '@certd/plugin-cert';
import { doRequest, uploadCert } from '../lib/sdk.js';
@IsTaskPlugin({
name: 'QiniuDeployCertToCDN',
title: '部署证书至七牛CDN',
icon: 'svg:icon-qiniuyun',
group: pluginGroups.cdn.key,
desc: '自动部署域名证书至七牛云CDN',
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class QiniuDeployCertToCDN extends AbstractTaskPlugin {
@TaskInput({
title: 'CDN加速域名',
helper: '你在七牛云上配置的CDN加速域名比如:certd.handsfree.work',
required: true,
})
domainName!: string;
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书或者上传到七牛云的证书id',
component: {
name: 'pi-output-selector',
from: ['CertApply', 'CertApplyLego', 'QiniuCertUpload'],
},
required: true,
})
cert!: CertInfo | string;
@TaskInput({
title: 'Access授权',
helper: '七牛云授权',
component: {
name: 'pi-access-selector',
type: 'qiniu',
},
required: true,
})
accessId!: string;
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始部署证书到七牛云cdn');
const access = await this.accessService.getById<QiniuAccess>(this.accessId);
const url = `https://api.qiniu.com/domain/${this.domainName}/httpsconf`;
let certId = null;
if (typeof this.cert !== 'string') {
// 是证书id直接上传即可
this.logger.info('先上传证书');
certId = await uploadCert(this.ctx.http, access, this.cert, this.appendTimeSuffix('certd'));
} else {
certId = this.cert;
}
//开始修改证书
this.logger.info('开始修改证书');
const body = {
certID: certId,
};
await doRequest(this.ctx.http, access, url, 'put', body);
this.logger.info('部署完成');
}
}
new QiniuDeployCertToCDN();

View File

@ -0,0 +1 @@
export * from './deploy-to-cdn/index.js';

View File

@ -0,0 +1,36 @@
import { HttpClient } from '@certd/pipeline';
import { QiniuAccess } from '../../access/index.js';
import { CertInfo } from '@certd/plugin-cert';
export async function doRequest(http: HttpClient, access: QiniuAccess, url: string, method: string, body: any) {
const { generateAccessToken } = await import('qiniu/qiniu/util.js');
const token = generateAccessToken(access, url);
const res = await http.request({
url,
method: method,
headers: {
Authorization: token,
},
data: body,
});
if (res.code !== 200 || res.error) {
throw new Error('请求失败:' + res.error);
}
return res;
}
export async function uploadCert(http: HttpClient, access: QiniuAccess, cert: CertInfo, certName?: string) {
const url = 'https://api.qiniu.com/sslcert';
const body = {
name: certName,
common_name: 'certd',
pri: cert.key,
ca: cert.crt,
};
const res = await doRequest(http, access, url, 'post', body);
return res.certID;
}

View File

@ -0,0 +1,60 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
import { QiniuAccess } from '../../access/index.js';
import { CertInfo } from '@certd/plugin-cert';
import { uploadCert } from '../lib/sdk.js';
@IsTaskPlugin({
name: 'QiniuCertUpload',
title: '上传到七牛云',
icon: 'svg:icon-qiniuyun',
group: pluginGroups.cdn.key,
desc: '上传到七牛云',
default: {
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed,
},
},
})
export class QiniuCertUpload extends AbstractTaskPlugin {
@TaskInput({
title: '证书名称',
helper: '上传后将以此名称作为前缀备注',
})
certName!: string;
@TaskInput({
title: '域名证书',
helper: '请选择前置任务输出的域名证书',
component: {
name: 'pi-output-selector',
from: ['CertApply', 'CertApplyLego'],
},
required: true,
})
cert!: CertInfo;
@TaskInput({
title: 'Access授权',
helper: '七牛云授权',
component: {
name: 'pi-access-selector',
type: 'qiniu',
},
required: true,
})
accessId!: string;
@TaskOutput({
title: '上传成功后的七牛云CertId',
})
qiniuCertId!: string;
async onInstance() {}
async execute(): Promise<void> {
this.logger.info('开始上传证书到七牛云');
const access = (await this.accessService.getById(this.accessId)) as QiniuAccess;
this.qiniuCertId = await uploadCert(this.ctx.http, access, this.cert, this.appendTimeSuffix(this.certName));
this.logger.info('上传完成,id:', this.qiniuCertId);
}
}
new QiniuCertUpload();