@certd/plugin-cert 1.25.9 → 1.26.1

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,24 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.26.1](https://github.com/certd/certd/compare/v1.26.0...v1.26.1) (2024-10-10)
7
+
8
+ **Note:** Version bump only for package @certd/plugin-cert
9
+
10
+ # [1.26.0](https://github.com/certd/certd/compare/v1.25.9...v1.26.0) (2024-10-10)
11
+
12
+ ### Features
13
+
14
+ * 域名验证方法支持CNAME间接方式,此方式支持所有域名注册商,且无需提供Access授权,但是需要手动添加cname解析 ([f3d3508](https://github.com/certd/certd/commit/f3d35084ed44f9f33845f7045e520be5c27eed93))
15
+
16
+ ### Performance Improvements
17
+
18
+ * 调整静态资源到static目录 ([0584b36](https://github.com/certd/certd/commit/0584b3672b40f9042a2ed87e5627022606d046cd))
19
+ * 检查cname是否正确配置 ([b5d8935](https://github.com/certd/certd/commit/b5d8935159374fbe7fc7d4c48ae0ed9396861bdd))
20
+ * 域名输入增加校验提示,避免输入错误的域名 ([0c8e83e](https://github.com/certd/certd/commit/0c8e83e1254a9ce4d5a4e7888eb1710394a4b77c))
21
+ * cname校验配置增加未校验通过提示 ([77cc3c4](https://github.com/certd/certd/commit/77cc3c4a5cbd81f8233a8e0bb33fab0621c0905f))
22
+ * google eab授权支持自动获取,不过要配置代理 ([592791d](https://github.com/certd/certd/commit/592791d1356fc252fbb70d7f168567aee9585507))
23
+
6
24
  ## [1.25.9](https://github.com/certd/certd/compare/v1.25.8...v1.25.9) (2024-10-01)
7
25
 
8
26
  ### Bug Fixes
@@ -0,0 +1,8 @@
1
+ import { BaseAccess } from "@certd/pipeline";
2
+ export declare class GoogleAccess extends BaseAccess {
3
+ type: string;
4
+ projectId: string;
5
+ apiKey: string;
6
+ serviceAccountSecret: string;
7
+ httpsProxy: string;
8
+ }
@@ -0,0 +1,118 @@
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 { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
11
+ let GoogleAccess = class GoogleAccess extends BaseAccess {
12
+ type = "";
13
+ projectId = "";
14
+ apiKey = "";
15
+ serviceAccountSecret = "";
16
+ httpsProxy = "";
17
+ };
18
+ __decorate([
19
+ AccessInput({
20
+ title: "密钥类型",
21
+ value: "serviceAccount",
22
+ component: {
23
+ placeholder: "密钥类型",
24
+ name: "a-select",
25
+ vModel: "value",
26
+ options: [
27
+ { value: "serviceAccount", label: "服务账号密钥" },
28
+ { value: "apiKey", label: "ApiKey,暂不可用", disabled: true },
29
+ ],
30
+ },
31
+ helper: "密钥类型",
32
+ required: true,
33
+ encrypt: false,
34
+ }),
35
+ __metadata("design:type", Object)
36
+ ], GoogleAccess.prototype, "type", void 0);
37
+ __decorate([
38
+ AccessInput({
39
+ title: "项目ID",
40
+ component: {
41
+ placeholder: "ProjectId",
42
+ },
43
+ helper: "ProjectId",
44
+ required: true,
45
+ encrypt: false,
46
+ mergeScript: `
47
+ return {
48
+ show:ctx.compute(({form})=>{
49
+ return form.access.type === 'apiKey'
50
+ })
51
+ }
52
+ `,
53
+ }),
54
+ __metadata("design:type", Object)
55
+ ], GoogleAccess.prototype, "projectId", void 0);
56
+ __decorate([
57
+ AccessInput({
58
+ title: "ApiKey",
59
+ component: {
60
+ placeholder: "ApiKey",
61
+ },
62
+ helper: "不要选,目前没有用",
63
+ required: true,
64
+ encrypt: true,
65
+ mergeScript: `
66
+ return {
67
+ show:ctx.compute(({form})=>{
68
+ return form.access.type === 'apiKey'
69
+ })
70
+ }
71
+ `,
72
+ }),
73
+ __metadata("design:type", Object)
74
+ ], GoogleAccess.prototype, "apiKey", void 0);
75
+ __decorate([
76
+ AccessInput({
77
+ title: "服务账号密钥",
78
+ component: {
79
+ placeholder: "serviceAccountSecret",
80
+ name: "a-textarea",
81
+ vModel: "value",
82
+ rows: 4,
83
+ },
84
+ helper: "[如何创建服务账号](https://cloud.google.com/iam/docs/service-accounts-create?hl=zh-CN) \n[获取密钥](https://console.cloud.google.com/iam-admin/serviceaccounts?hl=zh-cn),点击详情,点击创建密钥,将下载json文件,把内容填在此处",
85
+ required: true,
86
+ encrypt: true,
87
+ mergeScript: `
88
+ return {
89
+ show:ctx.compute(({form})=>{
90
+ return form.access.type === 'serviceAccount'
91
+ })
92
+ }
93
+ `,
94
+ }),
95
+ __metadata("design:type", Object)
96
+ ], GoogleAccess.prototype, "serviceAccountSecret", void 0);
97
+ __decorate([
98
+ AccessInput({
99
+ title: "https代理",
100
+ component: {
101
+ placeholder: "http://127.0.0.1:10811",
102
+ },
103
+ helper: "Google的请求需要走代理,如果不配置,则会使用环境变量中的全局HTTPS_PROXY配置\n或者服务器本身在海外,则不需要配置",
104
+ required: false,
105
+ encrypt: false,
106
+ }),
107
+ __metadata("design:type", Object)
108
+ ], GoogleAccess.prototype, "httpsProxy", void 0);
109
+ GoogleAccess = __decorate([
110
+ IsAccess({
111
+ name: "google",
112
+ title: "google cloud",
113
+ desc: "谷歌云授权",
114
+ })
115
+ ], GoogleAccess);
116
+ export { GoogleAccess };
117
+ new GoogleAccess();
118
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlLWFjY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hY2Nlc3MvZ29vZ2xlLWFjY2Vzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQU83RCxJQUFNLFlBQVksR0FBbEIsTUFBTSxZQUFhLFNBQVEsVUFBVTtJQWlCMUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQWtCVixTQUFTLEdBQUcsRUFBRSxDQUFDO0lBa0JmLE1BQU0sR0FBRyxFQUFFLENBQUM7SUFzQlosb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0lBVzFCLFVBQVUsR0FBRyxFQUFFLENBQUM7Q0FDakIsQ0FBQTtBQXRFQztJQWhCQyxXQUFXLENBQUM7UUFDWCxLQUFLLEVBQUUsTUFBTTtRQUNiLEtBQUssRUFBRSxnQkFBZ0I7UUFDdkIsU0FBUyxFQUFFO1lBQ1QsV0FBVyxFQUFFLE1BQU07WUFDbkIsSUFBSSxFQUFFLFVBQVU7WUFDaEIsTUFBTSxFQUFFLE9BQU87WUFDZixPQUFPLEVBQUU7Z0JBQ1AsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRTtnQkFDNUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTthQUMxRDtTQUNGO1FBQ0QsTUFBTSxFQUFFLE1BQU07UUFDZCxRQUFRLEVBQUUsSUFBSTtRQUNkLE9BQU8sRUFBRSxLQUFLO0tBQ2YsQ0FBQzs7MENBQ1E7QUFrQlY7SUFoQkMsV0FBVyxDQUFDO1FBQ1gsS0FBSyxFQUFFLE1BQU07UUFDYixTQUFTLEVBQUU7WUFDVCxXQUFXLEVBQUUsV0FBVztTQUN6QjtRQUNELE1BQU0sRUFBRSxXQUFXO1FBQ25CLFFBQVEsRUFBRSxJQUFJO1FBQ2QsT0FBTyxFQUFFLEtBQUs7UUFDZCxXQUFXLEVBQUU7Ozs7OztLQU1aO0tBQ0YsQ0FBQzs7K0NBQ2E7QUFrQmY7SUFoQkMsV0FBVyxDQUFDO1FBQ1gsS0FBSyxFQUFFLFFBQVE7UUFDZixTQUFTLEVBQUU7WUFDVCxXQUFXLEVBQUUsUUFBUTtTQUN0QjtRQUNELE1BQU0sRUFBRSxXQUFXO1FBQ25CLFFBQVEsRUFBRSxJQUFJO1FBQ2QsT0FBTyxFQUFFLElBQUk7UUFDYixXQUFXLEVBQUU7Ozs7OztLQU1aO0tBQ0YsQ0FBQzs7NENBQ1U7QUFzQlo7SUFwQkMsV0FBVyxDQUFDO1FBQ1gsS0FBSyxFQUFFLFFBQVE7UUFDZixTQUFTLEVBQUU7WUFDVCxXQUFXLEVBQUUsc0JBQXNCO1lBQ25DLElBQUksRUFBRSxZQUFZO1lBQ2xCLE1BQU0sRUFBRSxPQUFPO1lBQ2YsSUFBSSxFQUFFLENBQUM7U0FDUjtRQUNELE1BQU0sRUFDSiw0TEFBNEw7UUFDOUwsUUFBUSxFQUFFLElBQUk7UUFDZCxPQUFPLEVBQUUsSUFBSTtRQUNiLFdBQVcsRUFBRTs7Ozs7O0tBTVo7S0FDRixDQUFDOzswREFDd0I7QUFXMUI7SUFUQyxXQUFXLENBQUM7UUFDWCxLQUFLLEVBQUUsU0FBUztRQUNoQixTQUFTLEVBQUU7WUFDVCxXQUFXLEVBQUUsd0JBQXdCO1NBQ3RDO1FBQ0QsTUFBTSxFQUFFLG1FQUFtRTtRQUMzRSxRQUFRLEVBQUUsS0FBSztRQUNmLE9BQU8sRUFBRSxLQUFLO0tBQ2YsQ0FBQzs7Z0RBQ2M7QUF0RkwsWUFBWTtJQUx4QixRQUFRLENBQUM7UUFDUixJQUFJLEVBQUUsUUFBUTtRQUNkLEtBQUssRUFBRSxjQUFjO1FBQ3JCLElBQUksRUFBRSxPQUFPO0tBQ2QsQ0FBQztHQUNXLFlBQVksQ0F1RnhCOztBQUVELElBQUksWUFBWSxFQUFFLENBQUMifQ==
@@ -1 +1,2 @@
1
1
  export * from "./eab-access.js";
2
+ export * from "./google-access.js";
@@ -1,2 +1,3 @@
1
1
  export * from "./eab-access.js";
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWNjZXNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsaUJBQWlCLENBQUMifQ==
2
+ export * from "./google-access.js";
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWNjZXNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxvQkFBb0IsQ0FBQyJ9
@@ -6,13 +6,15 @@ export type DnsProviderDefine = Registrable & {
6
6
  };
7
7
  };
8
8
  export type CreateRecordOptions = {
9
+ domain: string;
9
10
  fullRecord: string;
11
+ hostRecord: string;
10
12
  type: string;
11
13
  value: any;
12
- domain: string;
13
14
  };
14
- export type RemoveRecordOptions<T> = CreateRecordOptions & {
15
- record: T;
15
+ export type RemoveRecordOptions<T> = {
16
+ recordReq: CreateRecordOptions;
17
+ recordRes: T;
16
18
  };
17
19
  export type DnsProviderContext = {
18
20
  access: IAccess;
@@ -6,3 +6,8 @@ export declare abstract class AbstractDnsProvider<T = any> implements IDnsProvid
6
6
  abstract onInstance(): Promise<void>;
7
7
  abstract removeRecord(options: RemoveRecordOptions<T>): Promise<void>;
8
8
  }
9
+ export declare function parseDomain(fullDomain: string): string;
10
+ export declare function createDnsProvider(opts: {
11
+ dnsProviderType: string;
12
+ context: DnsProviderContext;
13
+ }): Promise<IDnsProvider>;
@@ -1,7 +1,32 @@
1
+ import psl from "psl";
2
+ import { dnsProviderRegistry } from "./registry.js";
3
+ import { Decorator } from "@certd/pipeline";
1
4
  export class AbstractDnsProvider {
2
5
  ctx;
3
6
  setCtx(ctx) {
4
7
  this.ctx = ctx;
5
8
  }
6
9
  }
7
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kbnMtcHJvdmlkZXIvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLE9BQWdCLG1CQUFtQjtJQUN2QyxHQUFHLENBQXNCO0lBRXpCLE1BQU0sQ0FBQyxHQUF1QjtRQUM1QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNqQixDQUFDO0NBT0YifQ==
10
+ export function parseDomain(fullDomain) {
11
+ const parsed = psl.parse(fullDomain);
12
+ if (parsed.error) {
13
+ throw new Error(`解析${fullDomain}域名失败:` + JSON.stringify(parsed.error));
14
+ }
15
+ return parsed.domain;
16
+ }
17
+ export async function createDnsProvider(opts) {
18
+ const { dnsProviderType, context } = opts;
19
+ const dnsProviderPlugin = dnsProviderRegistry.get(dnsProviderType);
20
+ const DnsProviderClass = dnsProviderPlugin.target;
21
+ const dnsProviderDefine = dnsProviderPlugin.define;
22
+ if (dnsProviderDefine.deprecated) {
23
+ throw new Error(dnsProviderDefine.deprecated);
24
+ }
25
+ // @ts-ignore
26
+ const dnsProvider = new DnsProviderClass();
27
+ Decorator.inject(dnsProviderDefine.autowire, dnsProvider, context);
28
+ dnsProvider.setCtx(context);
29
+ await dnsProvider.onInstance();
30
+ return dnsProvider;
31
+ }
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kbnMtcHJvdmlkZXIvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEdBQUcsTUFBTSxLQUFLLENBQUM7QUFDdEIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUU1QyxNQUFNLE9BQWdCLG1CQUFtQjtJQUN2QyxHQUFHLENBQXNCO0lBRXpCLE1BQU0sQ0FBQyxHQUF1QjtRQUM1QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNqQixDQUFDO0NBT0Y7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLFVBQWtCO0lBQzVDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFxQixDQUFDO0lBQ3pELElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsS0FBSyxVQUFVLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFnQixDQUFDO0FBQ2pDLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGlCQUFpQixDQUFDLElBQThEO0lBQ3BHLE1BQU0sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQzFDLE1BQU0saUJBQWlCLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sZ0JBQWdCLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDO0lBQ2xELE1BQU0saUJBQWlCLEdBQUcsaUJBQWlCLENBQUMsTUFBMkIsQ0FBQztJQUN4RSxJQUFJLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUNELGFBQWE7SUFDYixNQUFNLFdBQVcsR0FBaUIsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO0lBRXpELFNBQVMsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuRSxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVCLE1BQU0sV0FBVyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQy9CLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUMifQ==
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
+ export * from "./access/index.js";
1
2
  export * from "./plugin/index.js";
2
3
  export * from "./dns-provider/index.js";
3
- export * from "./access/index.js";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
+ export * from "./access/index.js";
1
2
  export * from "./plugin/index.js";
2
3
  export * from "./dns-provider/index.js";
3
- export * from "./access/index.js";
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsbUJBQW1CLENBQUMifQ==
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMseUJBQXlCLENBQUMifQ==
@@ -0,0 +1,11 @@
1
+ import { EabAccess, GoogleAccess } from "../access/index.js";
2
+ import { ILogger } from "@certd/basic";
3
+ export declare class GoogleClient {
4
+ access: GoogleAccess;
5
+ logger: ILogger;
6
+ constructor(opts: {
7
+ logger: ILogger;
8
+ access: GoogleAccess;
9
+ });
10
+ getEab(): Promise<EabAccess>;
11
+ }
@@ -0,0 +1,59 @@
1
+ import { EabAccess } from "../access/index.js";
2
+ export class GoogleClient {
3
+ access;
4
+ logger;
5
+ constructor(opts) {
6
+ this.access = opts.access;
7
+ this.logger = opts.logger;
8
+ }
9
+ async getEab() {
10
+ // https://cloud.google.com/docs/authentication/api-keys-use#using-with-client-libs
11
+ const { v1 } = await import("@google-cloud/publicca");
12
+ // process.env.HTTPS_PROXY = "http://127.0.0.1:10811";
13
+ const access = this.access;
14
+ if (!access.serviceAccountSecret) {
15
+ throw new Error("服务账号密钥 不能为空");
16
+ }
17
+ const credentials = JSON.parse(access.serviceAccountSecret);
18
+ const client = new v1.PublicCertificateAuthorityServiceClient({ credentials });
19
+ const parent = `projects/${credentials.project_id}/locations/global`;
20
+ const externalAccountKey = {};
21
+ const request = {
22
+ parent,
23
+ externalAccountKey,
24
+ };
25
+ let envHttpsProxy = "";
26
+ try {
27
+ if (this.access.httpsProxy) {
28
+ //设置临时使用代理
29
+ envHttpsProxy = process.env.HTTPS_PROXY;
30
+ process.env.HTTPS_PROXY = this.access.httpsProxy;
31
+ }
32
+ this.logger.info("开始获取google eab授权");
33
+ const response = await client.createExternalAccountKey(request);
34
+ const { keyId, b64MacKey } = response[0];
35
+ const eabAccess = new EabAccess();
36
+ eabAccess.kid = keyId;
37
+ eabAccess.hmacKey = b64MacKey.toString();
38
+ this.logger.info(`google eab授权获取成功,kid: ${eabAccess.kid}`);
39
+ return eabAccess;
40
+ }
41
+ finally {
42
+ if (envHttpsProxy) {
43
+ process.env.HTTPS_PROXY = envHttpsProxy;
44
+ }
45
+ }
46
+ }
47
+ }
48
+ // const access = new GoogleAccess();
49
+ // access.projectId = "hip-light-432411-d4";
50
+ // access.serviceAccountSecret = `
51
+ //
52
+ //
53
+ // `;
54
+ // // process.env.HTTPS_PROXY = "http://127.0.0.1:10811";
55
+ // const client = new GoogleClient(access);
56
+ // client.getEab().catch((e) => {
57
+ // console.error(e);
58
+ // });
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYnMvZ29vZ2xlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWdCLE1BQU0sb0JBQW9CLENBQUM7QUFHN0QsTUFBTSxPQUFPLFlBQVk7SUFDdkIsTUFBTSxDQUFlO0lBQ3JCLE1BQU0sQ0FBVTtJQUNoQixZQUFZLElBQStDO1FBQ3pELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDNUIsQ0FBQztJQUNELEtBQUssQ0FBQyxNQUFNO1FBQ1YsbUZBQW1GO1FBQ25GLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQ3RELHNEQUFzRDtRQUN0RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBRTVELE1BQU0sTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDLHVDQUF1QyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUMvRSxNQUFNLE1BQU0sR0FBRyxZQUFZLFdBQVcsQ0FBQyxVQUFVLG1CQUFtQixDQUFDO1FBQ3JFLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxDQUFDO1FBQzlCLE1BQU0sT0FBTyxHQUFHO1lBQ2QsTUFBTTtZQUNOLGtCQUFrQjtTQUNuQixDQUFDO1FBRUYsSUFBSSxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDM0IsVUFBVTtnQkFDVixhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7Z0JBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1lBQ25ELENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sUUFBUSxHQUFHLE1BQU0sTUFBTSxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sU0FBUyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7WUFDbEMsU0FBUyxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUM7WUFDdEIsU0FBUyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMseUJBQXlCLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzNELE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQztZQUMxQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7Q0FDRjtBQUVELHFDQUFxQztBQUNyQyw0Q0FBNEM7QUFDNUMsa0NBQWtDO0FBQ2xDLEVBQUU7QUFDRixFQUFFO0FBQ0YsS0FBSztBQUNMLHlEQUF5RDtBQUN6RCwyQ0FBMkM7QUFDM0MsaUNBQWlDO0FBQ2pDLHNCQUFzQjtBQUN0QixNQUFNIn0=
@@ -1,8 +1,22 @@
1
1
  import * as acme from "@certd/acme-client";
2
+ import { ClientExternalAccountBindingOptions, UrlMapping } from "@certd/acme-client";
2
3
  import { Logger } from "log4js";
3
4
  import { IContext } from "@certd/pipeline";
4
5
  import { IDnsProvider } from "../../dns-provider/index.js";
5
- import { ClientExternalAccountBindingOptions, UrlMapping } from "@certd/acme-client";
6
+ export type CnameVerifyPlan = {
7
+ domain: string;
8
+ fullRecord: string;
9
+ dnsProvider: IDnsProvider;
10
+ };
11
+ export type DomainVerifyPlan = {
12
+ domain: string;
13
+ type: "cname" | "dns";
14
+ dnsProvider?: IDnsProvider;
15
+ cnameVerifyPlan?: Record<string, CnameVerifyPlan>;
16
+ };
17
+ export type DomainsVerifyPlan = {
18
+ [key: string]: DomainVerifyPlan;
19
+ };
6
20
  export type CertInfo = {
7
21
  crt: string;
8
22
  key: string;
@@ -20,6 +34,7 @@ type AcmeServiceOptions = {
20
34
  eab?: ClientExternalAccountBindingOptions;
21
35
  skipLocalVerify?: boolean;
22
36
  useMappingProxy?: boolean;
37
+ reverseProxy?: string;
23
38
  privateKeyType?: PrivateKeyType;
24
39
  signal?: AbortSignal;
25
40
  };
@@ -36,23 +51,34 @@ export declare class AcmeService {
36
51
  saveAccountConfig(email: string, conf: any): Promise<void>;
37
52
  getAcmeClient(email: string, isTest?: boolean): Promise<acme.Client>;
38
53
  createNewKey(): Promise<string>;
39
- parseDomain(fullDomain: string): string;
40
- challengeCreateFn(authz: any, challenge: any, keyAuthorization: string, dnsProvider: IDnsProvider): Promise<any>;
54
+ challengeCreateFn(authz: any, challenge: any, keyAuthorization: string, dnsProvider: IDnsProvider, domainsVerifyPlan: DomainsVerifyPlan): Promise<{
55
+ recordReq: {
56
+ domain: string;
57
+ fullRecord: string;
58
+ hostRecord: string;
59
+ type: string;
60
+ value: string;
61
+ };
62
+ recordRes: any;
63
+ dnsProvider: IDnsProvider<any>;
64
+ }>;
41
65
  /**
42
66
  * Function used to remove an ACME challenge response
43
67
  *
44
68
  * @param {object} authz Authorization object
45
69
  * @param {object} challenge Selected challenge
46
70
  * @param {string} keyAuthorization Authorization key
47
- * @param recordItem challengeCreateFn create record item
71
+ * @param recordReq
72
+ * @param recordRes
48
73
  * @param dnsProvider dnsProvider
49
74
  * @returns {Promise}
50
75
  */
51
- challengeRemoveFn(authz: any, challenge: any, keyAuthorization: string, recordItem: any, dnsProvider: IDnsProvider): Promise<void>;
76
+ challengeRemoveFn(authz: any, challenge: any, keyAuthorization: string, recordReq: any, recordRes: any, dnsProvider: IDnsProvider): Promise<void>;
52
77
  order(options: {
53
78
  email: string;
54
79
  domains: string | string[];
55
- dnsProvider: any;
80
+ dnsProvider?: any;
81
+ domainsVerifyPlan?: DomainsVerifyPlan;
56
82
  csrInfo: any;
57
83
  isTest?: boolean;
58
84
  privateKeyType?: string;
@@ -1,8 +1,8 @@
1
1
  // @ts-ignore
2
2
  import * as acme from "@certd/acme-client";
3
3
  import _ from "lodash-es";
4
- import psl from "psl";
5
4
  import { utils } from "@certd/pipeline";
5
+ import { parseDomain } from "../../dns-provider/index.js";
6
6
  export class AcmeService {
7
7
  options;
8
8
  userContext;
@@ -46,8 +46,8 @@ export class AcmeService {
46
46
  const urlMapping = {
47
47
  enabled: false,
48
48
  mappings: {
49
- "acme-v02.api.letsencrypt.org": "letsencrypt.proxy.handsfree.work",
50
- "dv.acme-v02.api.pki.goog": "google.proxy.handsfree.work",
49
+ "acme-v02.api.letsencrypt.org": this.options.reverseProxy || "letsencrypt.proxy.handsfree.work",
50
+ "dv.acme-v02.api.pki.goog": this.options.reverseProxy || "google.proxy.handsfree.work",
51
51
  },
52
52
  };
53
53
  const conf = await this.getAccountConfig(email, urlMapping);
@@ -101,14 +101,7 @@ export class AcmeService {
101
101
  const key = await acme.crypto.createPrivateKey(2048);
102
102
  return key.toString();
103
103
  }
104
- parseDomain(fullDomain) {
105
- const parsed = psl.parse(fullDomain);
106
- if (parsed.error) {
107
- throw new Error(`解析${fullDomain}域名失败:` + JSON.stringify(parsed.error));
108
- }
109
- return parsed.domain;
110
- }
111
- async challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider) {
104
+ async challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider, domainsVerifyPlan) {
112
105
  this.logger.info("Triggered challengeCreateFn()");
113
106
  /* http-01 */
114
107
  const fullDomain = authz.identifier.value;
@@ -122,19 +115,61 @@ export class AcmeService {
122
115
  }
123
116
  else if (challenge.type === "dns-01") {
124
117
  /* dns-01 */
125
- const dnsRecord = `_acme-challenge.${fullDomain}`;
118
+ let fullRecord = `_acme-challenge.${fullDomain}`;
126
119
  const recordValue = keyAuthorization;
127
- this.logger.info(`Creating TXT record for ${fullDomain}: ${dnsRecord}`);
120
+ this.logger.info(`Creating TXT record for ${fullDomain}: ${fullRecord}`);
128
121
  /* Replace this */
129
- this.logger.info(`Would create TXT record "${dnsRecord}" with value "${recordValue}"`);
130
- const domain = this.parseDomain(fullDomain);
122
+ this.logger.info(`Would create TXT record "${fullRecord}" with value "${recordValue}"`);
123
+ let domain = parseDomain(fullDomain);
131
124
  this.logger.info("解析到域名domain=", domain);
132
- return await dnsProvider.createRecord({
133
- fullRecord: dnsRecord,
125
+ if (domainsVerifyPlan) {
126
+ //按照计划执行
127
+ const domainVerifyPlan = domainsVerifyPlan[domain];
128
+ if (domainVerifyPlan) {
129
+ if (domainVerifyPlan.type === "dns") {
130
+ dnsProvider = domainVerifyPlan.dnsProvider;
131
+ }
132
+ else if (domainVerifyPlan.type === "cname") {
133
+ const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
134
+ if (cnameVerifyPlan) {
135
+ const cname = cnameVerifyPlan[fullDomain];
136
+ if (cname) {
137
+ dnsProvider = cname.dnsProvider;
138
+ domain = parseDomain(cname.domain);
139
+ fullRecord = cname.fullRecord;
140
+ }
141
+ }
142
+ else {
143
+ this.logger.error("未找到域名Cname校验计划,使用默认的dnsProvider");
144
+ }
145
+ }
146
+ else {
147
+ this.logger.error("不支持的校验类型", domainVerifyPlan.type);
148
+ }
149
+ }
150
+ else {
151
+ this.logger.info("未找到域名校验计划,使用默认的dnsProvider");
152
+ }
153
+ }
154
+ let hostRecord = fullRecord.replace(`${domain}`, "");
155
+ if (hostRecord.endsWith(".")) {
156
+ hostRecord = hostRecord.substring(0, hostRecord.length - 1);
157
+ }
158
+ const recordReq = {
159
+ domain,
160
+ fullRecord,
161
+ hostRecord,
134
162
  type: "TXT",
135
163
  value: recordValue,
136
- domain,
137
- });
164
+ };
165
+ this.logger.info("添加 TXT 解析记录", JSON.stringify(recordReq));
166
+ const recordRes = await dnsProvider.createRecord(recordReq);
167
+ this.logger.info("添加 TXT 解析记录成功", JSON.stringify(recordRes));
168
+ return {
169
+ recordReq,
170
+ recordRes,
171
+ dnsProvider,
172
+ };
138
173
  }
139
174
  }
140
175
  /**
@@ -143,11 +178,12 @@ export class AcmeService {
143
178
  * @param {object} authz Authorization object
144
179
  * @param {object} challenge Selected challenge
145
180
  * @param {string} keyAuthorization Authorization key
146
- * @param recordItem challengeCreateFn create record item
181
+ * @param recordReq
182
+ * @param recordRes
147
183
  * @param dnsProvider dnsProvider
148
184
  * @returns {Promise}
149
185
  */
150
- async challengeRemoveFn(authz, challenge, keyAuthorization, recordItem, dnsProvider) {
186
+ async challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider) {
151
187
  this.logger.info("Triggered challengeRemoveFn()");
152
188
  /* http-01 */
153
189
  const fullDomain = authz.identifier.value;
@@ -159,20 +195,13 @@ export class AcmeService {
159
195
  // await fs.unlinkAsync(filePath);
160
196
  }
161
197
  else if (challenge.type === "dns-01") {
162
- const dnsRecord = `_acme-challenge.${fullDomain}`;
163
- const recordValue = keyAuthorization;
164
- this.logger.info(`Removing TXT record for ${fullDomain}: ${dnsRecord}`);
165
- /* Replace this */
166
- this.logger.info(`Would remove TXT record "${dnsRecord}" with value "${recordValue}"`);
167
- const domain = this.parseDomain(fullDomain);
198
+ this.logger.info(`删除 TXT 解析记录:${JSON.stringify(recordReq)} ,recordRes = ${JSON.stringify(recordRes)}`);
168
199
  try {
169
200
  await dnsProvider.removeRecord({
170
- fullRecord: dnsRecord,
171
- type: "TXT",
172
- value: keyAuthorization,
173
- record: recordItem,
174
- domain,
201
+ recordReq,
202
+ recordRes,
175
203
  });
204
+ this.logger.info("删除解析记录成功");
176
205
  }
177
206
  catch (e) {
178
207
  this.logger.error("删除解析记录出错:", e);
@@ -181,7 +210,7 @@ export class AcmeService {
181
210
  }
182
211
  }
183
212
  async order(options) {
184
- const { email, isTest, domains, csrInfo, dnsProvider } = options;
213
+ const { email, isTest, domains, csrInfo, dnsProvider, domainsVerifyPlan } = options;
185
214
  const client = await this.getAcmeClient(email, isTest);
186
215
  /* Create CSR */
187
216
  const { commonName, altNames } = this.buildCommonNameByDomains(domains);
@@ -214,8 +243,8 @@ export class AcmeService {
214
243
  ...csrInfo,
215
244
  altNames,
216
245
  }, privateKey);
217
- if (dnsProvider == null) {
218
- throw new Error("dnsProvider 不能为空");
246
+ if (dnsProvider == null && domainsVerifyPlan == null) {
247
+ throw new Error("dnsProvider 、 domainsVerifyPlan 不能都为空");
219
248
  }
220
249
  /* 自动申请证书 */
221
250
  const crt = await client.auto({
@@ -225,10 +254,10 @@ export class AcmeService {
225
254
  skipChallengeVerification: this.skipLocalVerify,
226
255
  challengePriority: ["dns-01"],
227
256
  challengeCreateFn: async (authz, challenge, keyAuthorization) => {
228
- return await this.challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider);
257
+ return await this.challengeCreateFn(authz, challenge, keyAuthorization, dnsProvider, domainsVerifyPlan);
229
258
  },
230
- challengeRemoveFn: async (authz, challenge, keyAuthorization, recordItem) => {
231
- return await this.challengeRemoveFn(authz, challenge, keyAuthorization, recordItem, dnsProvider);
259
+ challengeRemoveFn: async (authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider) => {
260
+ return await this.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider);
232
261
  },
233
262
  signal: this.options.signal,
234
263
  });
@@ -277,4 +306,4 @@ export class AcmeService {
277
306
  return true;
278
307
  }
279
308
  }
280
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNtZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wbHVnaW4vY2VydC1wbHVnaW4vYWNtZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxhQUFhO0FBQ2IsT0FBTyxLQUFLLElBQUksTUFBTSxvQkFBb0IsQ0FBQztBQUMzQyxPQUFPLENBQUMsTUFBTSxXQUFXLENBQUM7QUFLMUIsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBRXRCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQXNCeEMsTUFBTSxPQUFPLFdBQVc7SUFDdEIsT0FBTyxDQUFxQjtJQUM1QixXQUFXLENBQVc7SUFDdEIsTUFBTSxDQUFTO0lBQ2YsV0FBVyxDQUFjO0lBQ3pCLGVBQWUsR0FBRyxJQUFJLENBQUM7SUFDdkIsR0FBRyxDQUF1QztJQUMxQyxZQUFZLE9BQTJCO1FBQ3JDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQztRQUN2QyxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLGFBQWEsQ0FBQztRQUN4RCxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7UUFDdkIsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxJQUFJLEtBQUssQ0FBQztRQUN4RCxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBWSxFQUFFLEVBQUU7WUFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxVQUFzQjtRQUMxRCxNQUFNLElBQUksR0FBRyxD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
309
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNtZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wbHVnaW4vY2VydC1wbHVnaW4vYWNtZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxhQUFhO0FBQ2IsT0FBTyxLQUFLLElBQUksTUFBTSxvQkFBb0IsQ0FBQztBQUUzQyxPQUFPLENBQUMsTUFBTSxXQUFXLENBQUM7QUFHMUIsT0FBTyxFQUFZLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sRUFBZ0IsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUF3Q3hFLE1BQU0sT0FBTyxXQUFXO0lBQ3RCLE9BQU8sQ0FBcUI7SUFDNUIsV0FBVyxDQUFXO0lBQ3RCLE1BQU0sQ0FBUztJQUNmLFdBQVcsQ0FBYztJQUN6QixlQUFlLEdBQUcsSUFBSSxDQUFDO0lBQ3ZCLEdBQUcsQ0FBdUM7SUFDMUMsWUFBWSxPQUEyQjtRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSxhQUFhLENBQUM7UUFDeEQsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFBSSxLQUFLLENBQUM7UUFDeEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQVksRUFBRSxFQUFFO1lBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFhLEVBQUUsVUFBc0I7UUFDMUQsTUFB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