@certd/plugin-cert 1.22.5 → 1.22.6

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.
@@ -1,213 +1,213 @@
1
- // @ts-ignore
2
- import * as acme from "@certd/acme-client";
3
- import _ from "lodash-es";
4
- import psl from "psl";
5
- export class AcmeService {
6
- options;
7
- userContext;
8
- logger;
9
- sslProvider;
10
- skipLocalVerify = true;
11
- eab;
12
- constructor(options) {
13
- this.options = options;
14
- this.userContext = options.userContext;
15
- this.logger = options.logger;
16
- this.sslProvider = options.sslProvider || "letsencrypt";
17
- this.eab = options.eab;
18
- this.skipLocalVerify = options.skipLocalVerify ?? false;
19
- acme.setLogger((text) => {
20
- this.logger.info(text);
21
- });
22
- }
23
- async getAccountConfig(email) {
24
- return (await this.userContext.getObj(this.buildAccountKey(email))) || {};
25
- }
26
- buildAccountKey(email) {
27
- return `acme.config.${this.sslProvider}.${email}`;
28
- }
29
- async saveAccountConfig(email, conf) {
30
- await this.userContext.setObj(this.buildAccountKey(email), conf);
31
- }
32
- async getAcmeClient(email, isTest = false) {
33
- const conf = await this.getAccountConfig(email);
34
- if (conf.key == null) {
35
- conf.key = await this.createNewKey();
36
- await this.saveAccountConfig(email, conf);
37
- }
38
- let directoryUrl = "";
39
- if (isTest) {
40
- directoryUrl = acme.directory[this.sslProvider].staging;
41
- }
42
- else {
43
- directoryUrl = acme.directory[this.sslProvider].production;
44
- }
45
- const urlMapping = { enabled: false, mappings: {} };
46
- if (this.options.useMappingProxy) {
47
- urlMapping.enabled = true;
48
- urlMapping.mappings = {
49
- "acme-v02.api.letsencrypt.org": "letsencrypt.proxy.handsfree.work",
50
- };
51
- }
52
- const client = new acme.Client({
53
- directoryUrl: directoryUrl,
54
- accountKey: conf.key,
55
- accountUrl: conf.accountUrl,
56
- externalAccountBinding: this.eab,
57
- backoffAttempts: 30,
58
- backoffMin: 5000,
59
- backoffMax: 10000,
60
- urlMapping,
61
- });
62
- if (conf.accountUrl == null) {
63
- const accountPayload = {
64
- termsOfServiceAgreed: true,
65
- contact: [`mailto:${email}`],
66
- externalAccountBinding: this.eab,
67
- };
68
- await client.createAccount(accountPayload);
69
- conf.accountUrl = client.getAccountUrl();
70
- await this.saveAccountConfig(email, conf);
71
- }
72
- return client;
73
- }
74
- async createNewKey() {
75
- const key = await acme.forge.createPrivateKey();
76
- return key.toString();
77
- }
78
- parseDomain(fullDomain) {
79
- const parsed = psl.parse(fullDomain);
80
- if (parsed.error) {
81
- throw new Error(`解析${fullDomain}域名失败:` + JSON.stringify(parsed.error));
82
- }
83
- return parsed.domain;
84
- }
85
- async challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider) {
86
- this.logger.info("Triggered challengeCreateFn()");
87
- /* http-01 */
88
- const fullDomain = authz.identifier.value;
89
- if (challenge.type === "http-01") {
90
- const filePath = `/var/www/html/.well-known/acme-challenge/${challenge.token}`;
91
- const fileContents = keyAuthorization;
92
- this.logger.info(`Creating challenge response for ${fullDomain} at path: ${filePath}`);
93
- /* Replace this */
94
- this.logger.info(`Would write "${fileContents}" to path "${filePath}"`);
95
- // await fs.writeFileAsync(filePath, fileContents);
96
- }
97
- else if (challenge.type === "dns-01") {
98
- /* dns-01 */
99
- const dnsRecord = `_acme-challenge.${fullDomain}`;
100
- const recordValue = keyAuthorization;
101
- this.logger.info(`Creating TXT record for ${fullDomain}: ${dnsRecord}`);
102
- /* Replace this */
103
- this.logger.info(`Would create TXT record "${dnsRecord}" with value "${recordValue}"`);
104
- const domain = this.parseDomain(fullDomain);
105
- this.logger.info("解析到域名domain=", domain);
106
- return await dnsProvider.createRecord({
107
- fullRecord: dnsRecord,
108
- type: "TXT",
109
- value: recordValue,
110
- domain,
111
- });
112
- }
113
- }
114
- /**
115
- * Function used to remove an ACME challenge response
116
- *
117
- * @param {object} authz Authorization object
118
- * @param {object} challenge Selected challenge
119
- * @param {string} keyAuthorization Authorization key
120
- * @param recordItem challengeCreateFn create record item
121
- * @param dnsProvider dnsProvider
122
- * @returns {Promise}
123
- */
124
- async challengeRemoveFn(authz, challenge, keyAuthorization, recordItem, dnsProvider) {
125
- this.logger.info("Triggered challengeRemoveFn()");
126
- /* http-01 */
127
- const fullDomain = authz.identifier.value;
128
- if (challenge.type === "http-01") {
129
- const filePath = `/var/www/html/.well-known/acme-challenge/${challenge.token}`;
130
- this.logger.info(`Removing challenge response for ${fullDomain} at path: ${filePath}`);
131
- /* Replace this */
132
- this.logger.info(`Would remove file on path "${filePath}"`);
133
- // await fs.unlinkAsync(filePath);
134
- }
135
- else if (challenge.type === "dns-01") {
136
- const dnsRecord = `_acme-challenge.${fullDomain}`;
137
- const recordValue = keyAuthorization;
138
- this.logger.info(`Removing TXT record for ${fullDomain}: ${dnsRecord}`);
139
- /* Replace this */
140
- this.logger.info(`Would remove TXT record "${dnsRecord}" with value "${recordValue}"`);
141
- const domain = this.parseDomain(fullDomain);
142
- try {
143
- await dnsProvider.removeRecord({
144
- fullRecord: dnsRecord,
145
- type: "TXT",
146
- value: keyAuthorization,
147
- record: recordItem,
148
- domain,
149
- });
150
- }
151
- catch (e) {
152
- this.logger.error("删除解析记录出错:", e);
153
- throw e;
154
- }
155
- }
156
- }
157
- async order(options) {
158
- const { email, isTest, domains, csrInfo, dnsProvider } = options;
159
- const client = await this.getAcmeClient(email, isTest);
160
- /* Create CSR */
161
- const { commonName, altNames } = this.buildCommonNameByDomains(domains);
162
- const [key, csr] = await acme.forge.createCsr({
163
- commonName,
164
- ...csrInfo,
165
- altNames,
166
- });
167
- if (dnsProvider == null) {
168
- throw new Error("dnsProvider 不能为空");
169
- }
170
- /* 自动申请证书 */
171
- const crt = await client.auto({
172
- csr,
173
- email: email,
174
- termsOfServiceAgreed: true,
175
- skipChallengeVerification: this.skipLocalVerify,
176
- challengePriority: ["dns-01"],
177
- challengeCreateFn: async (authz, challenge, keyAuthorization) => {
178
- return await this.challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider);
179
- },
180
- challengeRemoveFn: async (authz, challenge, keyAuthorization, recordItem) => {
181
- return await this.challengeRemoveFn(authz, challenge, keyAuthorization, recordItem, dnsProvider);
182
- },
183
- });
184
- const cert = {
185
- crt: crt.toString(),
186
- key: key.toString(),
187
- csr: csr.toString(),
188
- };
189
- /* Done */
190
- this.logger.debug(`CSR:\n${cert.csr}`);
191
- this.logger.debug(`Certificate:\n${cert.crt}`);
192
- this.logger.info("证书申请成功");
193
- return cert;
194
- }
195
- buildCommonNameByDomains(domains) {
196
- if (typeof domains === "string") {
197
- domains = domains.split(",");
198
- }
199
- if (domains.length === 0) {
200
- throw new Error("domain can not be empty");
201
- }
202
- const commonName = domains[0];
203
- let altNames = undefined;
204
- if (domains.length > 1) {
205
- altNames = _.slice(domains, 1);
206
- }
207
- return {
208
- commonName,
209
- altNames,
210
- };
211
- }
212
- }
213
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNtZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wbHVnaW4vY2VydC1wbHVnaW4vYWNtZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxhQUFhO0FBQ2IsT0FBTyxLQUFLLElBQUksTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLENBQUMsTUFBTSxXQUFXLENBQUM7QUFLMUIsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBa0J0QixNQUFNLE9BQU8sV0FBVztJQUN0QixPQUFPLENBQXFCO0lBQzVCLFdBQVcsQ0FBVztJQUN0QixNQUFNLENBQVM7SUFDZixXQUFXLENBQWM7SUFDekIsZUFBZSxHQUFHLElBQUksQ0FBQztJQUN2QixHQUFHLENBQXVDO0lBQzFDLFlBQVksT0FBMkI7UUFDckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDO1FBQ3hELElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxlQUFlLElBQUksS0FBSyxDQUFDO1FBQ3hELElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRTtZQUM5QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBYTtRQUNsQyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUss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
1
+ // @ts-ignore
2
+ import * as acme from "@certd/acme-client";
3
+ import _ from "lodash-es";
4
+ import psl from "psl";
5
+ export class AcmeService {
6
+ options;
7
+ userContext;
8
+ logger;
9
+ sslProvider;
10
+ skipLocalVerify = true;
11
+ eab;
12
+ constructor(options) {
13
+ this.options = options;
14
+ this.userContext = options.userContext;
15
+ this.logger = options.logger;
16
+ this.sslProvider = options.sslProvider || "letsencrypt";
17
+ this.eab = options.eab;
18
+ this.skipLocalVerify = options.skipLocalVerify ?? false;
19
+ acme.setLogger((text) => {
20
+ this.logger.info(text);
21
+ });
22
+ }
23
+ async getAccountConfig(email) {
24
+ return (await this.userContext.getObj(this.buildAccountKey(email))) || {};
25
+ }
26
+ buildAccountKey(email) {
27
+ return `acme.config.${this.sslProvider}.${email}`;
28
+ }
29
+ async saveAccountConfig(email, conf) {
30
+ await this.userContext.setObj(this.buildAccountKey(email), conf);
31
+ }
32
+ async getAcmeClient(email, isTest = false) {
33
+ const conf = await this.getAccountConfig(email);
34
+ if (conf.key == null) {
35
+ conf.key = await this.createNewKey();
36
+ await this.saveAccountConfig(email, conf);
37
+ }
38
+ let directoryUrl = "";
39
+ if (isTest) {
40
+ directoryUrl = acme.directory[this.sslProvider].staging;
41
+ }
42
+ else {
43
+ directoryUrl = acme.directory[this.sslProvider].production;
44
+ }
45
+ const urlMapping = { enabled: false, mappings: {} };
46
+ if (this.options.useMappingProxy) {
47
+ urlMapping.enabled = true;
48
+ urlMapping.mappings = {
49
+ "acme-v02.api.letsencrypt.org": "letsencrypt.proxy.handsfree.work",
50
+ };
51
+ }
52
+ const client = new acme.Client({
53
+ directoryUrl: directoryUrl,
54
+ accountKey: conf.key,
55
+ accountUrl: conf.accountUrl,
56
+ externalAccountBinding: this.eab,
57
+ backoffAttempts: 30,
58
+ backoffMin: 5000,
59
+ backoffMax: 10000,
60
+ urlMapping,
61
+ });
62
+ if (conf.accountUrl == null) {
63
+ const accountPayload = {
64
+ termsOfServiceAgreed: true,
65
+ contact: [`mailto:${email}`],
66
+ externalAccountBinding: this.eab,
67
+ };
68
+ await client.createAccount(accountPayload);
69
+ conf.accountUrl = client.getAccountUrl();
70
+ await this.saveAccountConfig(email, conf);
71
+ }
72
+ return client;
73
+ }
74
+ async createNewKey() {
75
+ const key = await acme.forge.createPrivateKey();
76
+ return key.toString();
77
+ }
78
+ parseDomain(fullDomain) {
79
+ const parsed = psl.parse(fullDomain);
80
+ if (parsed.error) {
81
+ throw new Error(`解析${fullDomain}域名失败:` + JSON.stringify(parsed.error));
82
+ }
83
+ return parsed.domain;
84
+ }
85
+ async challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider) {
86
+ this.logger.info("Triggered challengeCreateFn()");
87
+ /* http-01 */
88
+ const fullDomain = authz.identifier.value;
89
+ if (challenge.type === "http-01") {
90
+ const filePath = `/var/www/html/.well-known/acme-challenge/${challenge.token}`;
91
+ const fileContents = keyAuthorization;
92
+ this.logger.info(`Creating challenge response for ${fullDomain} at path: ${filePath}`);
93
+ /* Replace this */
94
+ this.logger.info(`Would write "${fileContents}" to path "${filePath}"`);
95
+ // await fs.writeFileAsync(filePath, fileContents);
96
+ }
97
+ else if (challenge.type === "dns-01") {
98
+ /* dns-01 */
99
+ const dnsRecord = `_acme-challenge.${fullDomain}`;
100
+ const recordValue = keyAuthorization;
101
+ this.logger.info(`Creating TXT record for ${fullDomain}: ${dnsRecord}`);
102
+ /* Replace this */
103
+ this.logger.info(`Would create TXT record "${dnsRecord}" with value "${recordValue}"`);
104
+ const domain = this.parseDomain(fullDomain);
105
+ this.logger.info("解析到域名domain=", domain);
106
+ return await dnsProvider.createRecord({
107
+ fullRecord: dnsRecord,
108
+ type: "TXT",
109
+ value: recordValue,
110
+ domain,
111
+ });
112
+ }
113
+ }
114
+ /**
115
+ * Function used to remove an ACME challenge response
116
+ *
117
+ * @param {object} authz Authorization object
118
+ * @param {object} challenge Selected challenge
119
+ * @param {string} keyAuthorization Authorization key
120
+ * @param recordItem challengeCreateFn create record item
121
+ * @param dnsProvider dnsProvider
122
+ * @returns {Promise}
123
+ */
124
+ async challengeRemoveFn(authz, challenge, keyAuthorization, recordItem, dnsProvider) {
125
+ this.logger.info("Triggered challengeRemoveFn()");
126
+ /* http-01 */
127
+ const fullDomain = authz.identifier.value;
128
+ if (challenge.type === "http-01") {
129
+ const filePath = `/var/www/html/.well-known/acme-challenge/${challenge.token}`;
130
+ this.logger.info(`Removing challenge response for ${fullDomain} at path: ${filePath}`);
131
+ /* Replace this */
132
+ this.logger.info(`Would remove file on path "${filePath}"`);
133
+ // await fs.unlinkAsync(filePath);
134
+ }
135
+ else if (challenge.type === "dns-01") {
136
+ const dnsRecord = `_acme-challenge.${fullDomain}`;
137
+ const recordValue = keyAuthorization;
138
+ this.logger.info(`Removing TXT record for ${fullDomain}: ${dnsRecord}`);
139
+ /* Replace this */
140
+ this.logger.info(`Would remove TXT record "${dnsRecord}" with value "${recordValue}"`);
141
+ const domain = this.parseDomain(fullDomain);
142
+ try {
143
+ await dnsProvider.removeRecord({
144
+ fullRecord: dnsRecord,
145
+ type: "TXT",
146
+ value: keyAuthorization,
147
+ record: recordItem,
148
+ domain,
149
+ });
150
+ }
151
+ catch (e) {
152
+ this.logger.error("删除解析记录出错:", e);
153
+ throw e;
154
+ }
155
+ }
156
+ }
157
+ async order(options) {
158
+ const { email, isTest, domains, csrInfo, dnsProvider } = options;
159
+ const client = await this.getAcmeClient(email, isTest);
160
+ /* Create CSR */
161
+ const { commonName, altNames } = this.buildCommonNameByDomains(domains);
162
+ const [key, csr] = await acme.forge.createCsr({
163
+ commonName,
164
+ ...csrInfo,
165
+ altNames,
166
+ });
167
+ if (dnsProvider == null) {
168
+ throw new Error("dnsProvider 不能为空");
169
+ }
170
+ /* 自动申请证书 */
171
+ const crt = await client.auto({
172
+ csr,
173
+ email: email,
174
+ termsOfServiceAgreed: true,
175
+ skipChallengeVerification: this.skipLocalVerify,
176
+ challengePriority: ["dns-01"],
177
+ challengeCreateFn: async (authz, challenge, keyAuthorization) => {
178
+ return await this.challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider);
179
+ },
180
+ challengeRemoveFn: async (authz, challenge, keyAuthorization, recordItem) => {
181
+ return await this.challengeRemoveFn(authz, challenge, keyAuthorization, recordItem, dnsProvider);
182
+ },
183
+ });
184
+ const cert = {
185
+ crt: crt.toString(),
186
+ key: key.toString(),
187
+ csr: csr.toString(),
188
+ };
189
+ /* Done */
190
+ this.logger.debug(`CSR:\n${cert.csr}`);
191
+ this.logger.debug(`Certificate:\n${cert.crt}`);
192
+ this.logger.info("证书申请成功");
193
+ return cert;
194
+ }
195
+ buildCommonNameByDomains(domains) {
196
+ if (typeof domains === "string") {
197
+ domains = domains.split(",");
198
+ }
199
+ if (domains.length === 0) {
200
+ throw new Error("domain can not be empty");
201
+ }
202
+ const commonName = domains[0];
203
+ let altNames = undefined;
204
+ if (domains.length > 1) {
205
+ altNames = _.slice(domains, 1);
206
+ }
207
+ return {
208
+ commonName,
209
+ altNames,
210
+ };
211
+ }
212
+ }
213
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNtZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wbHVnaW4vY2VydC1wbHVnaW4vYWNtZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxhQUFhO0FBQ2IsT0FBTyxLQUFLLElBQUksTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLENBQUMsTUFBTSxXQUFXLENBQUM7QUFLMUIsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBa0J0QixNQUFNLE9BQU8sV0FBVztJQUN0QixPQUFPLENBQXFCO0lBQzVCLFdBQVcsQ0FBVztJQUN0QixNQUFNLENBQVM7SUFDZixXQUFXLENBQWM7SUFDekIsZUFBZSxHQUFHLElBQUksQ0FBQztJQUN2QixHQUFHLENBQXVDO0lBQzFDLFlBQVksT0FBMkI7UUFDckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDO1FBQ3hELElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxlQUFlLElBQUksS0FBSyxDQUFDO1FBQ3hELElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRTtZQUM5QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBYTtRQUNsQyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUss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
@@ -1,49 +1,49 @@
1
- import { AbstractTaskPlugin, HttpClient, IAccessService, IContext, Step } from "@certd/pipeline";
2
- import type { CertInfo } from "./acme.js";
3
- import { Logger } from "log4js";
4
- import { CertReader } from "./cert-reader.js";
5
- export { CertReader };
6
- export type { CertInfo };
7
- export declare abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
8
- domains: string[];
9
- email: string;
10
- renewDays: number;
11
- forceUpdate: string;
12
- successNotify: boolean;
13
- intro: string;
14
- csrInfo: string;
15
- logger: Logger;
16
- userContext: IContext;
17
- accessService: IAccessService;
18
- http: HttpClient;
19
- lastStatus: Step;
20
- cert?: CertInfo;
21
- onInstance(): Promise<void>;
22
- abstract onInit(): Promise<void>;
23
- abstract doCertApply(): Promise<any>;
24
- execute(): Promise<void>;
25
- output(certReader: CertReader, isNew: boolean): Promise<void>;
26
- zipCert(cert: CertInfo, applyTime: string): Promise<void>;
27
- /**
28
- * 是否更新证书
29
- */
30
- condition(): Promise<CertReader>;
31
- formatCert(pem: string): string;
32
- formatCerts(cert: {
33
- crt: string;
34
- key: string;
35
- csr: string;
36
- }): CertInfo;
37
- readLastCert(): Promise<CertReader | undefined>;
38
- /**
39
- * 检查是否过期,默认提前20天
40
- * @param expires
41
- * @param maxDays
42
- * @returns {boolean}
43
- */
44
- isWillExpire(expires: number, maxDays?: number): {
45
- isWillExpire: boolean;
46
- leftDays: number;
47
- };
48
- private sendSuccessEmail;
49
- }
1
+ import { AbstractTaskPlugin, HttpClient, IAccessService, IContext, Step } from "@certd/pipeline";
2
+ import type { CertInfo } from "./acme.js";
3
+ import { Logger } from "log4js";
4
+ import { CertReader } from "./cert-reader.js";
5
+ export { CertReader };
6
+ export type { CertInfo };
7
+ export declare abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
8
+ domains: string[];
9
+ email: string;
10
+ renewDays: number;
11
+ forceUpdate: string;
12
+ successNotify: boolean;
13
+ intro: string;
14
+ csrInfo: string;
15
+ logger: Logger;
16
+ userContext: IContext;
17
+ accessService: IAccessService;
18
+ http: HttpClient;
19
+ lastStatus: Step;
20
+ cert?: CertInfo;
21
+ onInstance(): Promise<void>;
22
+ abstract onInit(): Promise<void>;
23
+ abstract doCertApply(): Promise<any>;
24
+ execute(): Promise<void>;
25
+ output(certReader: CertReader, isNew: boolean): Promise<void>;
26
+ zipCert(cert: CertInfo, applyTime: string): Promise<void>;
27
+ /**
28
+ * 是否更新证书
29
+ */
30
+ condition(): Promise<CertReader>;
31
+ formatCert(pem: string): string;
32
+ formatCerts(cert: {
33
+ crt: string;
34
+ key: string;
35
+ csr: string;
36
+ }): CertInfo;
37
+ readLastCert(): Promise<CertReader | undefined>;
38
+ /**
39
+ * 检查是否过期,默认提前20天
40
+ * @param expires
41
+ * @param maxDays
42
+ * @returns {boolean}
43
+ */
44
+ isWillExpire(expires: number, maxDays?: number): {
45
+ isWillExpire: boolean;
46
+ leftDays: number;
47
+ };
48
+ private sendSuccessEmail;
49
+ }