@certd/plugin-cert 1.41.2 → 1.41.4

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +6 -6
  3. package/dist/access/eab-access.d.ts +0 -6
  4. package/dist/access/eab-access.js +0 -62
  5. package/dist/access/google-access.d.ts +0 -8
  6. package/dist/access/google-access.js +0 -119
  7. package/dist/access/index.d.ts +0 -2
  8. package/dist/access/index.js +0 -3
  9. package/dist/dns-provider/api.d.ts +0 -76
  10. package/dist/dns-provider/api.js +0 -2
  11. package/dist/dns-provider/base.d.ts +0 -27
  12. package/dist/dns-provider/base.js +0 -49
  13. package/dist/dns-provider/decorator.d.ts +0 -3
  14. package/dist/dns-provider/decorator.js +0 -18
  15. package/dist/dns-provider/domain-parser.d.ts +0 -9
  16. package/dist/dns-provider/domain-parser.js +0 -64
  17. package/dist/dns-provider/index.d.ts +0 -5
  18. package/dist/dns-provider/index.js +0 -6
  19. package/dist/dns-provider/registry.d.ts +0 -1
  20. package/dist/dns-provider/registry.js +0 -3
  21. package/dist/libs/google.d.ts +0 -11
  22. package/dist/libs/google.js +0 -59
  23. package/dist/plugin/cert-plugin/acme.d.ts +0 -123
  24. package/dist/plugin/cert-plugin/acme.js +0 -362
  25. package/dist/plugin/cert-plugin/base-convert.d.ts +0 -25
  26. package/dist/plugin/cert-plugin/base-convert.js +0 -210
  27. package/dist/plugin/cert-plugin/base.d.ts +0 -27
  28. package/dist/plugin/cert-plugin/base.js +0 -175
  29. package/dist/plugin/cert-plugin/cert-reader.d.ts +0 -51
  30. package/dist/plugin/cert-plugin/cert-reader.js +0 -206
  31. package/dist/plugin/cert-plugin/convert.d.ts +0 -26
  32. package/dist/plugin/cert-plugin/convert.js +0 -124
  33. package/dist/plugin/cert-plugin/custom/index.d.ts +0 -24
  34. package/dist/plugin/cert-plugin/custom/index.js +0 -202
  35. package/dist/plugin/cert-plugin/getter/aliyun.d.ts +0 -19
  36. package/dist/plugin/cert-plugin/getter/aliyun.js +0 -165
  37. package/dist/plugin/cert-plugin/index.d.ts +0 -62
  38. package/dist/plugin/cert-plugin/index.js +0 -672
  39. package/dist/plugin/cert-plugin/lego/dns.d.ts +0 -1
  40. package/dist/plugin/cert-plugin/lego/dns.js +0 -2
  41. package/dist/plugin/cert-plugin/lego/index.d.ts +0 -21
  42. package/dist/plugin/cert-plugin/lego/index.js +0 -256
  43. package/dist/plugin/index.d.ts +0 -6
  44. package/dist/plugin/index.js +0 -7
  45. package/stats.html +0 -6177
  46. package/test/dist/cert-plugin.test.js +0 -14
  47. package/test/dist/test/cert-plugin.test.js +0 -15
@@ -1,672 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
11
- import { utils } from "@certd/basic";
12
- import { AcmeService } from "./acme.js";
13
- import * as _ from "lodash-es";
14
- import { createDnsProvider } from "../../dns-provider/index.js";
15
- import { CertReader } from "./cert-reader.js";
16
- import { CertApplyBasePlugin } from "./base.js";
17
- import { GoogleClient } from "../../libs/google.js";
18
- import { DomainParser } from "../../dns-provider/domain-parser.js";
19
- import { ossClientFactory } from "@certd/plugin-lib";
20
- export * from "./base.js";
21
- export * from "./cert-reader.js";
22
- const preferredChainConfigs = {
23
- letsencrypt: {
24
- helper: "如无特殊需求保持默认即可",
25
- options: [
26
- { value: "ISRG Root X1", label: "ISRG Root X1" },
27
- { value: "ISRG Root X2", label: "ISRG Root X2" },
28
- ],
29
- },
30
- google: {
31
- helper: "GlobalSign 提供对老旧设备更好的兼容性,但证书链会变长",
32
- options: [
33
- { value: "GTS Root R1", label: "GTS Root R1" },
34
- { value: "GlobalSign", label: "GlobalSign" },
35
- ],
36
- },
37
- };
38
- const preferredChainSupportedProviders = Object.keys(preferredChainConfigs);
39
- const preferredChainMergeScript = (() => {
40
- const configs = JSON.stringify(preferredChainConfigs);
41
- const supportedProviders = JSON.stringify(preferredChainSupportedProviders);
42
- const defaultProvider = JSON.stringify(preferredChainSupportedProviders[0]);
43
- return `
44
- const chainConfigs = ${configs};
45
- const supportedProviders = ${supportedProviders};
46
- const defaultProvider = ${defaultProvider};
47
- const getConfig = (provider)=> chainConfigs[provider] || chainConfigs[defaultProvider];
48
- return {
49
- show: ctx.compute(({form})=> supportedProviders.includes(form.sslProvider)),
50
- component: {
51
- options: ctx.compute(({form})=> getConfig(form.sslProvider).options)
52
- },
53
- helper: ctx.compute(({form})=> getConfig(form.sslProvider).helper),
54
- value: ctx.compute(({form})=>{
55
- const { options } = getConfig(form.sslProvider);
56
- const allowed = options.map(item=>item.value);
57
- const current = form.preferredChain;
58
- if(allowed.includes(current)){
59
- return current;
60
- }
61
- return allowed[0];
62
- })
63
- };
64
- `;
65
- })();
66
- let CertApplyPlugin = class CertApplyPlugin extends CertApplyBasePlugin {
67
- challengeType;
68
- sslProvider;
69
- dnsProviderType;
70
- // dns解析授权类型,勿删
71
- dnsProviderAccessType;
72
- dnsProviderAccess;
73
- domainsVerifyPlan;
74
- googleCommonEabAccessId;
75
- zerosslCommonEabAccessId;
76
- sslcomCommonEabAccessId;
77
- litesslCommonEabAccessId;
78
- eabAccessId;
79
- googleAccessId;
80
- privateKeyType;
81
- certProfile;
82
- preferredChain;
83
- useProxy = false;
84
- reverseProxy = "";
85
- skipLocalVerify = false;
86
- maxCheckRetryCount = 20;
87
- waitDnsDiffuseTime = 30;
88
- acme;
89
- eab;
90
- async onInit() {
91
- let eab = null;
92
- if (this.sslProvider && !this.sslProvider.startsWith("letsencrypt")) {
93
- if (this.sslProvider === "google" && this.googleAccessId) {
94
- this.logger.info("当前正在使用 google服务账号授权获取EAB");
95
- const googleAccess = await this.getAccess(this.googleAccessId);
96
- const googleClient = new GoogleClient({
97
- access: googleAccess,
98
- logger: this.logger,
99
- });
100
- eab = await googleClient.getEab();
101
- }
102
- else {
103
- const getEab = async (type) => {
104
- if (this.eabAccessId) {
105
- this.logger.info(`当前正在使用 ${type} EAB授权`);
106
- eab = await this.getAccess(this.eabAccessId);
107
- }
108
- else if (this[`${type}CommonEabAccessId`]) {
109
- this.logger.info(`当前正在使用 ${type} 公共EAB授权`);
110
- eab = await this.getAccess(this[`${type}CommonEabAccessId`], true);
111
- }
112
- else {
113
- throw new Error(`${type}需要配置EAB授权`);
114
- }
115
- };
116
- await getEab(this.sslProvider);
117
- }
118
- }
119
- this.eab = eab;
120
- const subDomainsGetter = await this.ctx.serviceGetter.get("subDomainsGetter");
121
- const domainParser = new DomainParser(subDomainsGetter, this.logger);
122
- this.acme = new AcmeService({
123
- userId: this.ctx.user.id,
124
- userContext: this.userContext,
125
- logger: this.logger,
126
- sslProvider: this.sslProvider,
127
- eab,
128
- skipLocalVerify: this.skipLocalVerify,
129
- useMappingProxy: this.useProxy,
130
- reverseProxy: this.reverseProxy,
131
- privateKeyType: this.privateKeyType,
132
- signal: this.ctx.signal,
133
- maxCheckRetryCount: this.maxCheckRetryCount,
134
- domainParser,
135
- waitDnsDiffuseTime: this.waitDnsDiffuseTime,
136
- });
137
- }
138
- async doCertApply() {
139
- let email = this.email;
140
- if (this.eab && this.eab.email) {
141
- email = this.eab.email;
142
- }
143
- const domains = this["domains"];
144
- const csrInfo = _.merge({
145
- // country: "CN",
146
- // state: "GuangDong",
147
- // locality: "ShengZhen",
148
- // organization: "CertD Org.",
149
- // organizationUnit: "IT Department",
150
- // emailAddress: email,
151
- }, this.csrInfo ? JSON.parse(this.csrInfo) : {});
152
- this.logger.info("开始申请证书,", email, domains);
153
- let dnsProvider = null;
154
- let domainsVerifyPlan = null;
155
- if (this.challengeType === "cname" || this.challengeType === "http" || this.challengeType === "dnses") {
156
- domainsVerifyPlan = await this.createDomainsVerifyPlan(domains, this.domainsVerifyPlan);
157
- }
158
- else if (this.challengeType === "auto") {
159
- domainsVerifyPlan = await this.createDomainsVerifyPlanByAuto(domains);
160
- }
161
- else {
162
- const dnsProviderType = this.dnsProviderType;
163
- const access = await this.getAccess(this.dnsProviderAccess);
164
- dnsProvider = await this.createDnsProvider(dnsProviderType, access);
165
- }
166
- try {
167
- const cert = await this.acme.order({
168
- email,
169
- domains,
170
- dnsProvider,
171
- domainsVerifyPlan,
172
- csrInfo,
173
- privateKeyType: this.privateKeyType,
174
- profile: this.certProfile,
175
- preferredChain: this.preferredChain,
176
- });
177
- const certInfo = this.formatCerts(cert);
178
- return new CertReader(certInfo);
179
- }
180
- catch (e) {
181
- const message = e?.message;
182
- if (message != null && message.indexOf("redundant with a wildcard domain in the same request") >= 0) {
183
- this.logger.error(e);
184
- throw new Error(`通配符域名已经包含了普通域名,请删除其中一个(${message})`);
185
- }
186
- if (e.name === "CancelError") {
187
- throw new CancelError(e.message);
188
- }
189
- throw e;
190
- }
191
- }
192
- async createDnsProvider(dnsProviderType, dnsProviderAccess) {
193
- const domainParser = this.acme.options.domainParser;
194
- const context = {
195
- access: dnsProviderAccess,
196
- logger: this.logger,
197
- http: this.ctx.http,
198
- utils,
199
- domainParser,
200
- serviceGetter: this.ctx.serviceGetter,
201
- };
202
- return await createDnsProvider({
203
- dnsProviderType,
204
- context,
205
- });
206
- }
207
- async createDomainsVerifyPlan(domains, verifyPlanSetting) {
208
- const plan = {};
209
- const domainParser = this.acme.options.domainParser;
210
- for (const fullDomain of domains) {
211
- const domain = fullDomain.replaceAll("*.", "");
212
- const mainDomain = await domainParser.parse(domain);
213
- const planSetting = verifyPlanSetting[mainDomain];
214
- if (planSetting == null) {
215
- throw new Error(`没有找到域名(${domain})的校验计划(如果您在流水线创建之后设置了子域名托管,需要重新编辑证书申请任务和重新校验cname记录的校验状态)`);
216
- }
217
- if (planSetting.type === "dns") {
218
- plan[domain] = await this.createDnsDomainVerifyPlan(planSetting, domain, mainDomain);
219
- }
220
- else if (planSetting.type === "cname") {
221
- plan[domain] = await this.createCnameDomainVerifyPlan(domain, mainDomain);
222
- }
223
- else if (planSetting.type === "http") {
224
- plan[domain] = await this.createHttpDomainVerifyPlan(planSetting.httpVerifyPlan[domain], domain, mainDomain);
225
- }
226
- }
227
- return plan;
228
- }
229
- async createDomainsVerifyPlanByAuto(domains) {
230
- //从数据库里面自动选择校验方式
231
- // domain list
232
- const domainList = new Set();
233
- //整理域名
234
- for (let domain of domains) {
235
- domain = domain.replaceAll("*.", "");
236
- domainList.add(domain);
237
- }
238
- const domainVerifierGetter = await this.ctx.serviceGetter.get("domainVerifierGetter");
239
- const verifiers = await domainVerifierGetter.getVerifiers([...domainList]);
240
- const plan = {};
241
- for (const domain in verifiers) {
242
- const verifier = verifiers[domain];
243
- if (verifier == null) {
244
- throw new Error(`没有找到与该域名(${domain})匹配的校验方式,请先到‘域名管理’页面添加校验方式`);
245
- }
246
- if (verifier.type === "dns") {
247
- plan[domain] = await this.createDnsDomainVerifyPlan(verifier.dns, domain, verifier.mainDomain);
248
- }
249
- else if (verifier.type === "cname") {
250
- plan[domain] = await this.createCnameDomainVerifyPlan(domain, verifier.mainDomain);
251
- }
252
- else if (verifier.type === "http") {
253
- plan[domain] = await this.createHttpDomainVerifyPlan(verifier.http, domain, verifier.mainDomain);
254
- }
255
- }
256
- return plan;
257
- }
258
- async createDnsDomainVerifyPlan(planSetting, domain, mainDomain) {
259
- const access = await this.getAccess(planSetting.dnsProviderAccessId);
260
- return {
261
- type: "dns",
262
- mainDomain,
263
- domain,
264
- dnsProvider: await this.createDnsProvider(planSetting.dnsProviderType, access),
265
- };
266
- }
267
- async createHttpDomainVerifyPlan(httpSetting, domain, mainDomain) {
268
- const httpUploaderContext = {
269
- accessService: this.ctx.accessService,
270
- logger: this.logger,
271
- utils,
272
- };
273
- const access = await this.getAccess(httpSetting.httpUploaderAccess);
274
- let rootDir = httpSetting.httpUploadRootDir;
275
- if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
276
- rootDir = rootDir + "/";
277
- }
278
- this.logger.info("上传方式", httpSetting.httpUploaderType);
279
- const httpUploader = await ossClientFactory.createOssClientByType(httpSetting.httpUploaderType, {
280
- access,
281
- rootDir: rootDir,
282
- ctx: httpUploaderContext,
283
- });
284
- return {
285
- type: "http",
286
- domain,
287
- mainDomain,
288
- httpVerifyPlan: {
289
- type: "http",
290
- domain,
291
- httpUploader,
292
- },
293
- };
294
- }
295
- async createCnameDomainVerifyPlan(domain, mainDomain) {
296
- const cnameRecord = await this.ctx.cnameProxyService.getByDomain(domain);
297
- if (cnameRecord == null) {
298
- throw new Error(`请先配置${domain}的CNAME记录,并通过校验`);
299
- }
300
- if (cnameRecord.status !== "valid") {
301
- throw new Error(`CNAME记录${domain}的校验状态为${cnameRecord.status},请等待校验通过`);
302
- }
303
- // 主域名异常
304
- if (cnameRecord.mainDomain && mainDomain && cnameRecord.mainDomain !== mainDomain) {
305
- throw new Error(`CNAME记录${domain}的域名与配置的主域名不一致(${cnameRecord.mainDomain}≠${mainDomain}),请确认是否在流水线创建之后修改了子域名托管,您需要重新校验CNAME记录的校验状态`);
306
- }
307
- let dnsProvider = cnameRecord.commonDnsProvider;
308
- if (cnameRecord.cnameProvider.id > 0) {
309
- dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
310
- }
311
- return {
312
- type: "cname",
313
- domain,
314
- mainDomain,
315
- cnameVerifyPlan: {
316
- domain: cnameRecord.cnameProvider.domain,
317
- fullRecord: cnameRecord.recordValue,
318
- dnsProvider,
319
- },
320
- };
321
- }
322
- };
323
- __decorate([
324
- TaskInput({
325
- title: "域名验证方式",
326
- value: "dns",
327
- component: {
328
- name: "a-select",
329
- vModel: "value",
330
- options: [
331
- { value: "dns", label: "DNS直接验证" },
332
- { value: "cname", label: "CNAME代理验证" },
333
- { value: "http", label: "HTTP文件验证(IP证书只能选它)" },
334
- { value: "dnses", label: "多DNS提供商" },
335
- { value: "auto", label: "自动匹配" },
336
- ],
337
- },
338
- required: true,
339
- helper: `1. <b>DNS直接验证</b>:当域名dns解析已被本系统支持时(即下方DNS解析服务商选项中可选),推荐选择此方式
340
- 2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加[CNAME记录](#/certd/cname/record)(如果经常申请失败,建议将DNS服务器修改为阿里云/腾讯云的,然后使用DNS直接验证)
341
- 3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传(IP证书必须选它)
342
- 4. <b>多DNS提供商</b>:每个域名可以选择独立的DNS提供商
343
- 5. <b>自动匹配</b>:此处无需选择校验方式,需要在[域名管理](#/certd/cert/domain)中提前配置好校验方式
344
- `,
345
- }),
346
- __metadata("design:type", String)
347
- ], CertApplyPlugin.prototype, "challengeType", void 0);
348
- __decorate([
349
- TaskInput({
350
- title: "证书颁发机构",
351
- value: "letsencrypt",
352
- component: {
353
- name: "icon-select",
354
- vModel: "value",
355
- options: [
356
- { value: "letsencrypt", label: "Let's Encrypt(免费,新手推荐,支持IP证书)", icon: "simple-icons:letsencrypt" },
357
- { value: "google", label: "Google(免费)", icon: "flat-color-icons:google" },
358
- { value: "zerossl", label: "ZeroSSL(免费)", icon: "emojione:digit-zero" },
359
- { value: "litessl", label: "litessl(免费)", icon: "roentgen:free" },
360
- { value: "sslcom", label: "SSL.com(仅主域名和www免费)", icon: "la:expeditedssl" },
361
- { value: "letsencrypt_staging", label: "Let's Encrypt测试环境(仅供测试)", icon: "simple-icons:letsencrypt" },
362
- ],
363
- },
364
- helper: "Let's Encrypt:申请最简单\nGoogle:大厂光环,兼容性好,仅首次需要翻墙获取EAB授权\nZeroSSL:需要EAB授权,无需翻墙\nSSL.com:仅主域名和www免费,必须设置CAA记录",
365
- required: true,
366
- }),
367
- __metadata("design:type", String)
368
- ], CertApplyPlugin.prototype, "sslProvider", void 0);
369
- __decorate([
370
- TaskInput({
371
- title: "DNS解析服务商",
372
- component: {
373
- name: "dns-provider-selector",
374
- },
375
- mergeScript: `
376
- return {
377
- show: ctx.compute(({form})=>{
378
- return form.challengeType === 'dns'
379
- }),
380
- component:{
381
- onSelectedChange: ctx.compute(({form})=>{
382
- return ($event)=>{
383
- form.dnsProviderAccessType = $event.accessType
384
- }
385
- })
386
- }
387
- }
388
- `,
389
- required: true,
390
- helper: "您的域名注册商,或者域名的dns服务器属于哪个平台\n如果这里没有,请选择CNAME代理验证校验方式",
391
- }),
392
- __metadata("design:type", String)
393
- ], CertApplyPlugin.prototype, "dnsProviderType", void 0);
394
- __decorate([
395
- TaskInput({
396
- title: "DNS解析授权",
397
- component: {
398
- name: "access-selector",
399
- },
400
- required: true,
401
- helper: "请选择dns解析服务商授权",
402
- mergeScript: `return {
403
- component:{
404
- type: ctx.compute(({form})=>{
405
- return form.dnsProviderAccessType || form.dnsProviderType
406
- })
407
- },
408
- show: ctx.compute(({form})=>{
409
- return form.challengeType === 'dns'
410
- })
411
- }
412
- `,
413
- }),
414
- __metadata("design:type", Number)
415
- ], CertApplyPlugin.prototype, "dnsProviderAccess", void 0);
416
- __decorate([
417
- TaskInput({
418
- title: "域名验证配置",
419
- component: {
420
- name: "domains-verify-plan-editor",
421
- },
422
- rules: [{ type: "checkDomainVerifyPlan" }],
423
- required: true,
424
- col: {
425
- span: 24,
426
- },
427
- mergeScript: `return {
428
- component:{
429
- domains: ctx.compute(({form})=>{
430
- return form.domains
431
- }),
432
- defaultType: ctx.compute(({form})=>{
433
- return form.challengeType || 'cname'
434
- })
435
- },
436
- show: ctx.compute(({form})=>{
437
- return form.challengeType === 'cname' || form.challengeType === 'http' || form.challengeType === 'dnses'
438
- }),
439
- helper: ctx.compute(({form})=>{
440
- if(form.challengeType === 'cname' ){
441
- return '请按照上面的提示,给要申请证书的域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它'
442
- }else if (form.challengeType === 'http'){
443
- return '请按照上面的提示,给每个域名设置文件上传配置,证书申请过程中会上传校验文件到网站根目录的.well-known/acme-challenge/目录下'
444
- }else if (form.challengeType === 'http'){
445
- return '给每个域名单独配置dns提供商'
446
- }
447
- })
448
- }
449
- `,
450
- }),
451
- __metadata("design:type", Object)
452
- ], CertApplyPlugin.prototype, "domainsVerifyPlan", void 0);
453
- __decorate([
454
- TaskInput({
455
- title: "Google公共EAB授权",
456
- isSys: true,
457
- show: false,
458
- }),
459
- __metadata("design:type", Number)
460
- ], CertApplyPlugin.prototype, "googleCommonEabAccessId", void 0);
461
- __decorate([
462
- TaskInput({
463
- title: "ZeroSSL公共EAB授权",
464
- isSys: true,
465
- show: false,
466
- }),
467
- __metadata("design:type", Number)
468
- ], CertApplyPlugin.prototype, "zerosslCommonEabAccessId", void 0);
469
- __decorate([
470
- TaskInput({
471
- title: "SSL.com公共EAB授权",
472
- isSys: true,
473
- show: false,
474
- }),
475
- __metadata("design:type", Number)
476
- ], CertApplyPlugin.prototype, "sslcomCommonEabAccessId", void 0);
477
- __decorate([
478
- TaskInput({
479
- title: "litessl公共EAB授权",
480
- isSys: true,
481
- show: false,
482
- }),
483
- __metadata("design:type", Number)
484
- ], CertApplyPlugin.prototype, "litesslCommonEabAccessId", void 0);
485
- __decorate([
486
- TaskInput({
487
- title: "EAB授权",
488
- component: {
489
- name: "access-selector",
490
- type: "eab",
491
- },
492
- maybeNeed: true,
493
- required: false,
494
- helper: "需要提供EAB授权" +
495
- "\nZeroSSL:请前往[zerossl开发者中心](https://app.zerossl.com/developer),生成 'EAB Credentials'" +
496
- "\nGoogle:请查看[google获取eab帮助文档](https://certd.docmirror.cn/guide/use/google/),用过一次后会绑定邮箱,后续复用EAB要用同一个邮箱" +
497
- "\nSSL.com:[SSL.com账号页面](https://secure.ssl.com/account),然后点击api credentials链接,然后点击编辑按钮,查看Secret key和HMAC key" +
498
- "\nlitessl:[litesslEAB页面](https://freessl.cn/automation/eab-manager),然后点击新增EAB",
499
- mergeScript: `
500
- return {
501
- show: ctx.compute(({form})=>{
502
- return (form.sslProvider === 'zerossl' && !form.zerosslCommonEabAccessId)
503
- || (form.sslProvider === 'google' && !form.googleCommonEabAccessId)
504
- || (form.sslProvider === 'sslcom' && !form.sslcomCommonEabAccessId)
505
- || (form.sslProvider === 'litessl' && !form.litesslCommonEabAccessId)
506
- })
507
- }
508
- `,
509
- }),
510
- __metadata("design:type", Number)
511
- ], CertApplyPlugin.prototype, "eabAccessId", void 0);
512
- __decorate([
513
- TaskInput({
514
- title: "服务账号授权",
515
- component: {
516
- name: "access-selector",
517
- type: "google",
518
- },
519
- maybeNeed: true,
520
- required: false,
521
- helper: "google服务账号授权与EAB授权选填其中一个,[服务账号授权获取方法](https://certd.docmirror.cn/guide/use/google/)\n服务账号授权需要配置代理或者服务器本身在海外",
522
- mergeScript: `
523
- return {
524
- show: ctx.compute(({form})=>{
525
- return form.sslProvider === 'google' && !form.googleCommonEabAccessId
526
- })
527
- }
528
- `,
529
- }),
530
- __metadata("design:type", Number)
531
- ], CertApplyPlugin.prototype, "googleAccessId", void 0);
532
- __decorate([
533
- TaskInput({
534
- title: "加密算法",
535
- value: "rsa_2048",
536
- component: {
537
- name: "a-select",
538
- vModel: "value",
539
- options: [
540
- { value: "rsa_1024", label: "RSA 1024" },
541
- { value: "rsa_2048", label: "RSA 2048" },
542
- { value: "rsa_3072", label: "RSA 3072" },
543
- { value: "rsa_4096", label: "RSA 4096" },
544
- { value: "rsa_2048_pkcs1", label: "RSA 2048 pkcs1 (旧版)" },
545
- { value: "ec_256", label: "EC 256" },
546
- { value: "ec_384", label: "EC 384" },
547
- // { value: "ec_521", label: "EC 521" },
548
- ],
549
- },
550
- helper: "如无特殊需求,默认即可\n选择RSA 2048 pkcs1可以获得旧版RSA证书",
551
- required: true,
552
- }),
553
- __metadata("design:type", String)
554
- ], CertApplyPlugin.prototype, "privateKeyType", void 0);
555
- __decorate([
556
- TaskInput({
557
- title: "证书配置",
558
- value: "classic",
559
- component: {
560
- name: "a-select",
561
- vModel: "value",
562
- options: [
563
- { value: "classic", label: "经典(classic)" },
564
- { value: "tlsserver", label: "TLS服务器(tlsserver)" },
565
- { value: "shortlived", label: "短暂的(shortlived)" },
566
- ],
567
- },
568
- helper: "如无特殊需求,默认即可",
569
- required: false,
570
- mergeScript: `
571
- return {
572
- show: ctx.compute(({form})=>{
573
- return form.sslProvider === 'letsencrypt'
574
- })
575
- }
576
- `,
577
- }),
578
- __metadata("design:type", String)
579
- ], CertApplyPlugin.prototype, "certProfile", void 0);
580
- __decorate([
581
- TaskInput({
582
- title: "首选链",
583
- component: {
584
- name: "a-select",
585
- vModel: "value",
586
- options: preferredChainConfigs.letsencrypt.options,
587
- },
588
- helper: preferredChainConfigs.letsencrypt.helper,
589
- required: false,
590
- mergeScript: preferredChainMergeScript,
591
- }),
592
- __metadata("design:type", String)
593
- ], CertApplyPlugin.prototype, "preferredChain", void 0);
594
- __decorate([
595
- TaskInput({
596
- title: "使用代理",
597
- value: false,
598
- component: {
599
- name: "a-switch",
600
- vModel: "checked",
601
- },
602
- helper: "如果acme-v02.api.letsencrypt.org或dv.acme-v02.api.pki.goog被墙无法访问,请尝试开启此选项\n默认情况会进行测试,如果无法访问,将会自动使用代理",
603
- }),
604
- __metadata("design:type", Object)
605
- ], CertApplyPlugin.prototype, "useProxy", void 0);
606
- __decorate([
607
- TaskInput({
608
- title: "自定义反代地址",
609
- component: {
610
- placeholder: "google.yourproxy.com",
611
- },
612
- helper: "填写你的自定义反代地址,不要带http://\nletsencrypt反代目标:acme-v02.api.letsencrypt.org\ngoogle反代目标:dv.acme-v02.api.pki.goog",
613
- }),
614
- __metadata("design:type", Object)
615
- ], CertApplyPlugin.prototype, "reverseProxy", void 0);
616
- __decorate([
617
- TaskInput({
618
- title: "跳过本地校验DNS",
619
- value: false,
620
- component: {
621
- name: "a-switch",
622
- vModel: "checked",
623
- },
624
- helper: "跳过本地校验可以加快申请速度,同时也会增加失败概率。",
625
- }),
626
- __metadata("design:type", Object)
627
- ], CertApplyPlugin.prototype, "skipLocalVerify", void 0);
628
- __decorate([
629
- TaskInput({
630
- title: "检查解析重试次数",
631
- value: 20,
632
- component: {
633
- name: "a-input-number",
634
- vModel: "value",
635
- },
636
- helper: "检查域名验证解析记录重试次数,如果你的域名服务商解析生效速度慢,可以适当增加此值",
637
- }),
638
- __metadata("design:type", Object)
639
- ], CertApplyPlugin.prototype, "maxCheckRetryCount", void 0);
640
- __decorate([
641
- TaskInput({
642
- title: "等待解析生效时长",
643
- value: 30,
644
- component: {
645
- name: "a-input-number",
646
- vModel: "value",
647
- },
648
- helper: "等待解析生效时长(秒),如果使用CNAME方式校验,本地验证失败,可以尝试延长此时间(比如5-10分钟)",
649
- }),
650
- __metadata("design:type", Object)
651
- ], CertApplyPlugin.prototype, "waitDnsDiffuseTime", void 0);
652
- CertApplyPlugin = __decorate([
653
- IsTaskPlugin({
654
- name: "CertApply",
655
- title: "证书申请(JS版)",
656
- icon: "ph:certificate",
657
- group: pluginGroups.cert.key,
658
- desc: "免费通配符域名证书申请,支持多个域名打到同一个证书上",
659
- default: {
660
- input: {
661
- renewDays: 18,
662
- forceUpdate: false,
663
- },
664
- strategy: {
665
- runStrategy: RunStrategy.AlwaysRun,
666
- },
667
- },
668
- })
669
- ], CertApplyPlugin);
670
- export { CertApplyPlugin };
671
- new CertApplyPlugin();
672
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcGx1Z2luL2NlcnQtcGx1Z2luL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbEcsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVyQyxPQUFPLEVBQUUsV0FBVyxFQUE4RSxNQUFNLFdBQVcsQ0FBQztBQUNwSCxPQUFPLEtBQUssQ0FBQyxNQUFNLFdBQVcsQ0FBQztBQUMvQixPQUFPLEVBQUUsaUJBQWlCLEVBQTBILE1BQU0sNkJBQTZCLENBQUM7QUFDeEwsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXJELGNBQWMsV0FBVyxDQUFDO0FBRTFCLGNBQWMsa0JBQWtCLENBQUM7QUF5QmpDLE1BQU0scUJBQXFCLEdBQUc7SUFDNUIsV0FBVyxFQUFFO1FBQ1gsTUFBTSxFQUFFLGNBQWM7UUFDdEIsT0FBTyxFQUFFO1lBQ1AsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUU7WUFDaEQsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUU7U0FDakQ7S0FDRjtJQUNELE1BQU0sRUFBRTtRQUNOLE1BQU0sRUFBRSxrQ0FBa0M7UUFDMUMsT0FBTyxFQUFFO1lBQ1AsRUFBRSxLQUFLLEVB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