@simplysm/service-server 14.0.100 → 14.0.101

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.
@@ -43,26 +43,10 @@ export interface ServiceDefinition<TMethods = Record<string, (...args: any[]) =>
43
43
  }
44
44
  /**
45
45
  * 이름과 팩토리 함수로 서비스를 정의한다.
46
- *
47
- * @example
48
- * // 기본 서비스
49
- * const HealthService = defineService("Health", (ctx) => ({
50
- * check: () => ({ status: "ok" }),
51
- * }));
52
- *
53
- * // 인증이 필요한 서비스
54
- * const UserService = defineService("User", auth((ctx) => ({
55
- * getProfile: () => ctx.authInfo,
56
- * adminOnly: auth(["admin"], () => "admin"),
57
- * })));
58
46
  */
59
47
  export declare function defineService<TMethods extends Record<string, (...args: any[]) => any>>(name: string | string[], factory: (ctx: ServiceContext) => TMethods): ServiceDefinition<TMethods>;
60
48
  /**
61
49
  * 클라이언트 측 타입 공유를 위해 ServiceDefinition에서 메서드 시그니처를 추출한다.
62
- *
63
- * @example
64
- * export type UserServiceType = ServiceMethods<typeof UserService>;
65
- * // 클라이언트: client.getService<UserServiceType>("User");
66
50
  */
67
51
  export type ServiceMethods<TDefinition> = TDefinition extends ServiceDefinition<infer M> ? M : never;
68
52
  //# sourceMappingURL=define-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"define-service.d.ts","sourceRoot":"","sources":["../../src/core/define-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAOnE,MAAM,WAAW,cAAc,CAAC,SAAS,GAAG,OAAO;IACjD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;KAChD,CAAC;IAEF,+BAA+B;IAC/B,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,IAAI,QAAQ,IAAI,SAAS,GAAG,SAAS,CAAC;IACtC,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAAC,SAAS,GAAG,OAAO,EACtD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,EAChC,MAAM,CAAC,EAAE,aAAa,EACtB,IAAI,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAA;CAAE,EAC7E,MAAM,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,cAAc,CAAC,SAAS,CAAC,CAoD3B;AAMD,+DAA+D;AAC/D,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,EAAE,GAAG,SAAS,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,SAAS,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,SAAS,GAAG,SAAS,CAAC;AAC1F,wBAAgB,IAAI,CAAC,SAAS,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC5D,WAAW,EAAE,MAAM,EAAE,EACrB,EAAE,EAAE,SAAS,GACZ,SAAS,CAAC;AAcb,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,QAAQ,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EACpF,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,QAAQ,GACzC,iBAAiB,CAAC,QAAQ,CAAC,CAa7B;AAID;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,WAAW,IACpC,WAAW,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"define-service.d.ts","sourceRoot":"","sources":["../../src/core/define-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAOnE,MAAM,WAAW,cAAc,CAAC,SAAS,GAAG,OAAO;IACjD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;KAChD,CAAC;IAEF,+BAA+B;IAC/B,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,IAAI,QAAQ,IAAI,SAAS,GAAG,SAAS,CAAC;IACtC,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAAC,SAAS,GAAG,OAAO,EACtD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,EAChC,MAAM,CAAC,EAAE,aAAa,EACtB,IAAI,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAA;CAAE,EAC7E,MAAM,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,cAAc,CAAC,SAAS,CAAC,CAoD3B;AAMD,+DAA+D;AAC/D,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,EAAE,GAAG,SAAS,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,SAAS,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,SAAS,GAAG,SAAS,CAAC;AAC1F,wBAAgB,IAAI,CAAC,SAAS,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC5D,WAAW,EAAE,MAAM,EAAE,EACrB,EAAE,EAAE,SAAS,GACZ,SAAS,CAAC;AAcb,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,QAAQ,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EACpF,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,QAAQ,GACzC,iBAAiB,CAAC,QAAQ,CAAC,CAa7B;AAID;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,WAAW,IACpC,WAAW,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC"}
@@ -61,18 +61,6 @@ export function auth(permissionsOrFn, maybeFn) {
61
61
  }
62
62
  /**
63
63
  * 이름과 팩토리 함수로 서비스를 정의한다.
64
- *
65
- * @example
66
- * // 기본 서비스
67
- * const HealthService = defineService("Health", (ctx) => ({
68
- * check: () => ({ status: "ok" }),
69
- * }));
70
- *
71
- * // 인증이 필요한 서비스
72
- * const UserService = defineService("User", auth((ctx) => ({
73
- * getProfile: () => ctx.authInfo,
74
- * adminOnly: auth(["admin"], () => "admin"),
75
- * })));
76
64
  */
77
65
  export function defineService(name, factory) {
78
66
  const names = Array.isArray(name) ? [...name] : [name];
@@ -1 +1 @@
1
- {"version":3,"file":"define-service.js","sourceRoot":"","sources":["../../src/core/define-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"define-service.js","sourceRoot":"","sources":["../../src/core/define-service.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"service-server.d.ts","sourceRoot":"","sources":["../src/service-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE,OAAO,EAAQ,YAAY,EAAO,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAgB/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,MAAM,WAAW,gBAAgB,CAAC,SAAS,SAAS,eAAe;IACjE,IAAI,CACF,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,OAAO,EACnD,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,GACvB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,qBAAa,aAAa,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;IAUY,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IATlD,MAAM,UAAS;IAEf,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IAEvD,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;gBAEb,OAAO,EAAE,oBAAoB;IAyD5C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAyKvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5B,QAAQ,CAAC,SAAS,SAAS,eAAe,EAAE,QAAQ,EAAE,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC;IAMvF,SAAS,CAAC,SAAS,SAAS,eAAe,EAC/C,QAAQ,EAAE,SAAS,EACnB,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,OAAO,EACnD,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC;IAKpB,aAAa,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAKlD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAK1E,OAAO,CAAC,yBAAyB;CA4BlC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,GAAG,OAAO,EACrD,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAAC,SAAS,CAAC,CAE1B"}
1
+ {"version":3,"file":"service-server.d.ts","sourceRoot":"","sources":["../src/service-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE,OAAO,EAAQ,YAAY,EAAO,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAgB/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,MAAM,WAAW,gBAAgB,CAAC,SAAS,SAAS,eAAe;IACjE,IAAI,CACF,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,OAAO,EACnD,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,GACvB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,qBAAa,aAAa,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;IAUY,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IATlD,MAAM,UAAS;IAEf,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IAEvD,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;gBAEb,OAAO,EAAE,oBAAoB;IAiE5C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA6KvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5B,QAAQ,CAAC,SAAS,SAAS,eAAe,EAAE,QAAQ,EAAE,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC;IAMvF,SAAS,CAAC,SAAS,SAAS,eAAe,EAC/C,QAAQ,EAAE,SAAS,EACnB,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,OAAO,EACnD,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC;IAKpB,aAAa,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAKlD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAK1E,OAAO,CAAC,yBAAyB;CA4BlC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,GAAG,OAAO,EACrD,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAAC,SAAS,CAAC,CAE1B"}
@@ -36,28 +36,37 @@ export class ServiceServer extends EventEmitter {
36
36
  let httpsConf = null;
37
37
  if (options.ssl != null) {
38
38
  if ("letsencrypt" in options.ssl) {
39
+ const letsencrypt = options.ssl.letsencrypt;
39
40
  const acmeManager = new AcmeManager({
40
41
  rootPath: options.rootPath,
41
- domains: options.ssl.letsencrypt.domains,
42
- email: options.ssl.letsencrypt.email,
43
- staging: options.ssl.letsencrypt.staging,
42
+ domains: letsencrypt.domains,
43
+ email: letsencrypt.email,
44
+ staging: letsencrypt.staging,
45
+ cloudflareApiToken: letsencrypt.cloudflareApiToken,
44
46
  });
45
47
  this._acmeManager = acmeManager;
46
- // 인증서 없이 ALPNCallback 만으로 HTTPS 서버 생성.
47
- // 발급 전엔 acme-tls/1 챌린지에만 응답하고, 실인증서는 listen() 에서 setSecureContext 주입한다.
48
- httpsConf = {
49
- ALPNCallback: function ({ protocols }) {
50
- if (protocols.includes("acme-tls/1")) {
51
- const ctx = acmeManager.getChallengeContext();
52
- if (ctx != null) {
53
- this.setKeyCert(ctx);
54
- return "acme-tls/1";
48
+ if (letsencrypt.cloudflareApiToken != null) {
49
+ // DNS-01: ALPN 챌린지가 없으므로 인증서 없이 HTTPS 서버를 생성하고,
50
+ // 실인증서는 listen() 에서 setSecureContext 로 주입한다.
51
+ httpsConf = {};
52
+ }
53
+ else {
54
+ // TLS-ALPN-01: 인증서 없이 ALPNCallback 만으로 HTTPS 서버 생성.
55
+ // 발급 전엔 acme-tls/1 챌린지에만 응답하고, 실인증서는 listen() 에서 setSecureContext 로 주입한다.
56
+ httpsConf = {
57
+ ALPNCallback: function ({ protocols }) {
58
+ if (protocols.includes("acme-tls/1")) {
59
+ const ctx = acmeManager.getChallengeContext();
60
+ if (ctx != null) {
61
+ this.setKeyCert(ctx);
62
+ return "acme-tls/1";
63
+ }
64
+ return undefined;
55
65
  }
56
- return undefined;
57
- }
58
- return protocols.includes("http/1.1") ? "http/1.1" : undefined;
59
- },
60
- };
66
+ return protocols.includes("http/1.1") ? "http/1.1" : undefined;
67
+ },
68
+ };
69
+ }
61
70
  }
62
71
  else if ("pfxBytes" in options.ssl) {
63
72
  httpsConf = {
@@ -79,8 +88,11 @@ export class ServiceServer extends EventEmitter {
79
88
  }
80
89
  async listen() {
81
90
  logger.info(`서버 시작 중... ${env("VER") ?? ""}`);
82
- // letsencrypt 핸드셰이크 중 인증서를 주입하는 TLSSocket.setKeyCert 가 필요 (Node 20.18.0+/22.9.0+)
83
- if (this._acmeManager != null) {
91
+ // TLS-ALPN-01 핸드셰이크 중 인증서를 주입하는 TLSSocket.setKeyCert 가 필요 (Node 20.18.0+/22.9.0+).
92
+ // DNS-01(cloudflareApiToken 지정) 은 ALPNCallback 을 쓰지 않으므로 이 요구가 없다.
93
+ const ssl = this.options.ssl;
94
+ const usesTlsAlpnChallenge = ssl != null && "letsencrypt" in ssl && ssl.letsencrypt.cloudflareApiToken == null;
95
+ if (this._acmeManager != null && usesTlsAlpnChallenge) {
84
96
  assertAcmeNodeSupport();
85
97
  }
86
98
  // auth 설정 검증: auth 미설정(undefined)인데 auth 요구 서비스가 있으면 에러
@@ -284,7 +296,7 @@ function assertAcmeNodeSupport() {
284
296
  const [major = 0, minor = 0] = process.versions.node.split(".").map((v) => Number(v));
285
297
  const supported = (major === 20 && minor >= 18) || (major === 22 && minor >= 9) || major >= 23;
286
298
  if (!supported) {
287
- throw new Error(`Let's Encrypt(letsencrypt) SSL 은 Node 20.18.0+ 또는 22.9.0+ 가 필요합니다. 현재 버전: ${process.versions.node}`);
299
+ throw new Error(`Let's Encrypt TLS-ALPN-01 SSL 은 Node 20.18.0+ 또는 22.9.0+ 가 필요합니다. 현재 버전: ${process.versions.node} (DNS-01 은 cloudflareApiToken 지정 시 사용 가능)`);
288
300
  }
289
301
  }
290
302
  //# sourceMappingURL=service-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-server.js","sourceRoot":"","sources":["../src/service-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service-server.js","sourceRoot":"","sources":["../src/service-server.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,8 @@ export interface AcmeManagerOptions {
4
4
  domains: string[];
5
5
  email: string;
6
6
  staging?: boolean;
7
+ /** 지정 시 DNS-01(Cloudflare) 로 발급. 미지정 시 TLS-ALPN-01 로 발급 */
8
+ cloudflareApiToken?: string;
7
9
  }
8
10
  export interface AcmeCertMaterial {
9
11
  /** 개인키 PEM */
@@ -14,8 +16,9 @@ export interface AcmeCertMaterial {
14
16
  /**
15
17
  * Let's Encrypt(ACME) 인증서 자동 발급·갱신 매니저.
16
18
  *
17
- * TLS-ALPN-01 챌린지로 발급한다. 챌린지 응답 인증서는 {@link getChallengeContext} 노출하여
18
- * 서버의 ALPNCallback `acme-tls/1` 핸드셰이크에 주입한다.
19
+ * `cloudflareApiToken` 이 있으면 DNS-01 챌린지(Cloudflare TXT 자동 등록)발급하고,
20
+ * 없으면 TLS-ALPN-01 챌린지로 발급한다. TLS-ALPN-01 챌린지 응답 인증서는
21
+ * {@link getChallengeContext} 로 노출하여 서버의 ALPNCallback 이 `acme-tls/1` 핸드셰이크에 주입한다.
19
22
  */
20
23
  export declare class AcmeManager {
21
24
  private readonly _options;
@@ -23,10 +26,13 @@ export declare class AcmeManager {
23
26
  private _challengeContext;
24
27
  private _renewTimer;
25
28
  private _onRenew;
29
+ /** DNS-01: 도메인별로 생성한 Cloudflare TXT 레코드 (challengeRemoveFn 에서 삭제용) */
30
+ private readonly _dnsRecords;
26
31
  constructor(_options: AcmeManagerOptions);
27
32
  private get _accountKeyPath();
28
33
  private get _certPath();
29
34
  private get _certKeyPath();
35
+ private get _metaPath();
30
36
  /** ALPNCallback 에서 사용할 현재 챌린지 컨텍스트 (챌린지 진행 중에만 존재) */
31
37
  getChallengeContext(): tls.SecureContext | undefined;
32
38
  /** 갱신 성공 시 호출될 핸들러 등록 (무중단 핫스왑용) */
@@ -41,8 +47,25 @@ export declare class AcmeManager {
41
47
  stop(): void;
42
48
  private _loadValidCachedCert;
43
49
  private _directoryUrl;
50
+ /** 캐시된 인증서의 발급 CA(directoryUrl). 메타 부재·파싱 실패 시 undefined */
51
+ private _readIssuedDirectoryUrl;
44
52
  private _getAccountKey;
45
53
  private _issue;
54
+ /** TLS-ALPN-01: 챌린지 응답 인증서를 ALPNCallback 용 컨텍스트로 노출 */
55
+ private _tlsAlpn01AutoOptions;
56
+ /** DNS-01: Cloudflare 에 `_acme-challenge` TXT 를 등록·삭제하고 전파를 확인 */
57
+ private _dns01AutoOptions;
58
+ private _cloudflareBaseUrl;
59
+ private _cloudflareRequest;
60
+ /** 도메인을 점 단위로 축소한 후보 중 등록된 가장 구체적인 zone 선택 */
61
+ private _cfFindZone;
62
+ private _cfCreateTxtRecord;
63
+ private _cfDeleteTxtRecord;
64
+ /**
65
+ * DNS-01: TXT 가 도메인 권위 NS 에 전파됐는지 best-effort 로 확인.
66
+ * 권위 NS 조회 실패·전파 타임아웃 시 경고 후 진행 (CA 가 최종 검증).
67
+ */
68
+ private _waitForDnsPropagation;
46
69
  private _scheduleRenewal;
47
70
  /** 긴 지연(>24.8일)은 setTimeout 오버플로를 피해 분할 무장 */
48
71
  private _armTimer;
@@ -1 +1 @@
1
- {"version":3,"file":"acme-manager.d.ts","sourceRoot":"","sources":["../../src/ssl/acme-manager.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,UAAU,CAAC;AAe3B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,qBAAa,WAAW;IAMV,OAAO,CAAC,QAAQ,CAAC,QAAQ;IALrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,QAAQ,CAAqD;gBAExC,QAAQ,EAAE,kBAAkB;IAIzD,OAAO,KAAK,eAAe,GAE1B;IACD,OAAO,KAAK,SAAS,GAEpB;IACD,OAAO,KAAK,YAAY,GAEvB;IAED,sDAAsD;IACtD,mBAAmB,IAAI,GAAG,CAAC,aAAa,GAAG,SAAS;IAIpD,oCAAoC;IACpC,OAAO,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI;IAI5D;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAYpD,gBAAgB;IAChB,IAAI,IAAI,IAAI;YAOE,oBAAoB;IAiClC,OAAO,CAAC,aAAa;YAUP,cAAc;YAUd,MAAM;IA0CpB,OAAO,CAAC,gBAAgB;IAKxB,8CAA8C;IAC9C,OAAO,CAAC,SAAS;YASH,MAAM;CAarB"}
1
+ {"version":3,"file":"acme-manager.d.ts","sourceRoot":"","sources":["../../src/ssl/acme-manager.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,UAAU,CAAC;AA4B3B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IAQV,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAPrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,QAAQ,CAAqD;IACrE,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2D;gBAE1D,QAAQ,EAAE,kBAAkB;IAIzD,OAAO,KAAK,eAAe,GAE1B;IACD,OAAO,KAAK,SAAS,GAEpB;IACD,OAAO,KAAK,YAAY,GAEvB;IACD,OAAO,KAAK,SAAS,GAEpB;IAED,sDAAsD;IACtD,mBAAmB,IAAI,GAAG,CAAC,aAAa,GAAG,SAAS;IAIpD,oCAAoC;IACpC,OAAO,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI;IAI5D;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAYpD,gBAAgB;IAChB,IAAI,IAAI,IAAI;YAOE,oBAAoB;IAyClC,OAAO,CAAC,aAAa;IAUrB,4DAA4D;YAC9C,uBAAuB;YAUvB,cAAc;YAUd,MAAM;IAsCpB,uDAAuD;IACvD,OAAO,CAAC,qBAAqB;IAc7B,kEAAkE;IAClE,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,kBAAkB;YAOZ,kBAAkB;IAsBhC,8CAA8C;YAChC,WAAW;YAcX,kBAAkB;YAalB,kBAAkB;IAUhC;;;OAGG;YACW,sBAAsB;IAoCpC,OAAO,CAAC,gBAAgB;IAKxB,8CAA8C;IAC9C,OAAO,CAAC,SAAS;YASH,MAAM;CAarB"}
@@ -1,5 +1,6 @@
1
1
  import * as acme from "acme-client";
2
2
  import tls from "node:tls";
3
+ import { Resolver, resolveNs, resolve4 } from "node:dns/promises";
3
4
  import { chmod } from "node:fs/promises";
4
5
  import path from "node:path";
5
6
  import { fsx } from "@simplysm/core-node";
@@ -11,11 +12,18 @@ const RENEW_BEFORE_MS = 30 * 24 * 60 * 60 * 1000;
11
12
  const RETRY_DELAY_MS = 60 * 60 * 1000;
12
13
  /** setTimeout 최대 지연 (약 24.8일). 초과 시 분할하여 재무장 */
13
14
  const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
15
+ /** DNS-01 전파 확인 최대 시도 횟수 */
16
+ const DNS_PROPAGATION_MAX_TRIES = 30;
17
+ /** DNS-01 전파 확인 간격 (2초). 최대 약 60초 대기 */
18
+ const DNS_PROPAGATION_INTERVAL_MS = 2000;
19
+ /** Cloudflare API 기본 base URL */
20
+ const CLOUDFLARE_API_BASE_URL = "https://api.cloudflare.com/client/v4";
14
21
  /**
15
22
  * Let's Encrypt(ACME) 인증서 자동 발급·갱신 매니저.
16
23
  *
17
- * TLS-ALPN-01 챌린지로 발급한다. 챌린지 응답 인증서는 {@link getChallengeContext} 노출하여
18
- * 서버의 ALPNCallback `acme-tls/1` 핸드셰이크에 주입한다.
24
+ * `cloudflareApiToken` 이 있으면 DNS-01 챌린지(Cloudflare TXT 자동 등록)발급하고,
25
+ * 없으면 TLS-ALPN-01 챌린지로 발급한다. TLS-ALPN-01 챌린지 응답 인증서는
26
+ * {@link getChallengeContext} 로 노출하여 서버의 ALPNCallback 이 `acme-tls/1` 핸드셰이크에 주입한다.
19
27
  */
20
28
  export class AcmeManager {
21
29
  _options;
@@ -23,6 +31,8 @@ export class AcmeManager {
23
31
  _challengeContext;
24
32
  _renewTimer;
25
33
  _onRenew;
34
+ /** DNS-01: 도메인별로 생성한 Cloudflare TXT 레코드 (challengeRemoveFn 에서 삭제용) */
35
+ _dnsRecords = new Map();
26
36
  constructor(_options) {
27
37
  this._options = _options;
28
38
  this._dir = path.resolve(_options.rootPath, ".acme");
@@ -36,6 +46,9 @@ export class AcmeManager {
36
46
  get _certKeyPath() {
37
47
  return path.resolve(this._dir, "cert.key");
38
48
  }
49
+ get _metaPath() {
50
+ return path.resolve(this._dir, "issued-meta.json");
51
+ }
39
52
  /** ALPNCallback 에서 사용할 현재 챌린지 컨텍스트 (챌린지 진행 중에만 존재) */
40
53
  getChallengeContext() {
41
54
  return this._challengeContext;
@@ -70,6 +83,13 @@ export class AcmeManager {
70
83
  if (!(await fsx.exists(this._certPath)) || !(await fsx.exists(this._certKeyPath))) {
71
84
  return undefined;
72
85
  }
86
+ // 발급에 사용한 CA(directoryUrl)가 현재 설정과 다르거나 메타가 없으면 캐시 무효화 (재발급).
87
+ // staging↔production↔사설 CA 전환 시 캐시된 이전 CA 인증서를 그대로 쓰는 것을 막는다.
88
+ const issuedDirectoryUrl = await this._readIssuedDirectoryUrl();
89
+ if (issuedDirectoryUrl !== this._directoryUrl()) {
90
+ logger.info("발급 CA(directoryUrl)가 현재 설정과 다름. 재발급을 진행합니다.");
91
+ return undefined;
92
+ }
73
93
  const cert = await fsx.read(this._certPath);
74
94
  const key = await fsx.read(this._certKeyPath);
75
95
  let info;
@@ -101,6 +121,18 @@ export class AcmeManager {
101
121
  ? acme.directory.letsencrypt.staging
102
122
  : acme.directory.letsencrypt.production;
103
123
  }
124
+ /** 캐시된 인증서의 발급 CA(directoryUrl). 메타 부재·파싱 실패 시 undefined */
125
+ async _readIssuedDirectoryUrl() {
126
+ if (!(await fsx.exists(this._metaPath)))
127
+ return undefined;
128
+ try {
129
+ const meta = JSON.parse(await fsx.read(this._metaPath));
130
+ return meta.directoryUrl;
131
+ }
132
+ catch {
133
+ return undefined;
134
+ }
135
+ }
104
136
  async _getAccountKey() {
105
137
  if (await fsx.exists(this._accountKeyPath)) {
106
138
  return fsx.read(this._accountKeyPath);
@@ -121,29 +153,144 @@ export class AcmeManager {
121
153
  csr,
122
154
  email: this._options.email,
123
155
  termsOfServiceAgreed: true,
124
- challengePriority: ["tls-alpn-01"],
125
- // 로컬 사전검증(발급 호스트가 자기 공개 도메인:443 으로 hairpin 접속) 생략.
126
- // 구성에 따라 hairpin 막힐 있고, 실검증은 CA(LE) 직접 수행한다.
156
+ // 로컬 사전검증 생략. 실검증은 CA(LE) 가 직접 수행한다.
157
+ // - TLS-ALPN-01: 발급 호스트의 hairpin(자기 공개 도메인:443) 접속이 막힐 있어 생략.
158
+ // - DNS-01: self-verify 호스트 resolver 쓰므로, 전파 확인은 challengeCreateFn 에서 직접 수행.
127
159
  skipChallengeVerification: true,
128
- // challengePriority 를 tls-alpn-01 로 고정했으므로 이 콜백은 항상 tls-alpn-01 챌린지로 호출된다.
129
- challengeCreateFn: async (authz, _challenge, keyAuthorization) => {
130
- const [alpnKey, alpnCert] = await acme.crypto.createAlpnCertificate(authz, keyAuthorization);
131
- this._challengeContext = tls.createSecureContext({ key: alpnKey, cert: alpnCert });
132
- },
133
- challengeRemoveFn: () => {
134
- this._challengeContext = undefined;
135
- return Promise.resolve();
136
- },
160
+ ...(this._options.cloudflareApiToken != null
161
+ ? this._dns01AutoOptions(this._options.cloudflareApiToken)
162
+ : this._tlsAlpn01AutoOptions()),
137
163
  });
138
164
  const keyPem = certKey.toString();
139
165
  await fsx.write(this._certPath, cert);
140
166
  await fsx.write(this._certKeyPath, keyPem);
141
167
  await chmod(this._certKeyPath, 0o600).catch(() => { });
168
+ // 발급에 사용한 CA(directoryUrl)를 기록 — 다음 기동 시 CA 전환 감지에 사용
169
+ await fsx.write(this._metaPath, JSON.stringify({ directoryUrl: this._directoryUrl() }));
142
170
  const info = acme.crypto.readCertificateInfo(cert);
143
171
  logger.info(`인증서 발급 완료 (도메인: ${this._options.domains.join(", ")}, 만료: ${info.notAfter.toISOString()})`);
144
172
  this._scheduleRenewal(info.notAfter);
145
173
  return { key: keyPem, cert };
146
174
  }
175
+ /** TLS-ALPN-01: 챌린지 응답 인증서를 ALPNCallback 용 컨텍스트로 노출 */
176
+ _tlsAlpn01AutoOptions() {
177
+ return {
178
+ challengePriority: ["tls-alpn-01"],
179
+ challengeCreateFn: async (authz, _challenge, keyAuthorization) => {
180
+ const [alpnKey, alpnCert] = await acme.crypto.createAlpnCertificate(authz, keyAuthorization);
181
+ this._challengeContext = tls.createSecureContext({ key: alpnKey, cert: alpnCert });
182
+ },
183
+ challengeRemoveFn: () => {
184
+ this._challengeContext = undefined;
185
+ return Promise.resolve();
186
+ },
187
+ };
188
+ }
189
+ /** DNS-01: Cloudflare 에 `_acme-challenge` TXT 를 등록·삭제하고 전파를 확인 */
190
+ _dns01AutoOptions(token) {
191
+ return {
192
+ challengePriority: ["dns-01"],
193
+ challengeCreateFn: async (authz, _challenge, keyAuthorization) => {
194
+ const domain = authz.identifier.value;
195
+ const zone = await this._cfFindZone(token, domain);
196
+ const recordName = `_acme-challenge.${domain}`;
197
+ const recordId = await this._cfCreateTxtRecord(token, zone.id, recordName, keyAuthorization);
198
+ this._dnsRecords.set(domain, { zoneId: zone.id, recordId });
199
+ await this._waitForDnsPropagation(zone.name, recordName, keyAuthorization);
200
+ },
201
+ challengeRemoveFn: async (authz) => {
202
+ const domain = authz.identifier.value;
203
+ const record = this._dnsRecords.get(domain);
204
+ if (record == null)
205
+ return;
206
+ await this._cfDeleteTxtRecord(token, record.zoneId, record.recordId);
207
+ this._dnsRecords.delete(domain);
208
+ },
209
+ };
210
+ }
211
+ _cloudflareBaseUrl() {
212
+ // 운영 환경 변수로 Cloudflare API base URL 재정의 가능 (테스트 mock 등)
213
+ const override = env("SD_CLOUDFLARE_API_BASE_URL");
214
+ if (override != null && override !== "")
215
+ return override;
216
+ return CLOUDFLARE_API_BASE_URL;
217
+ }
218
+ async _cloudflareRequest(token, apiPath, init) {
219
+ const res = await fetch(`${this._cloudflareBaseUrl()}${apiPath}`, {
220
+ method: init?.method ?? "GET",
221
+ headers: {
222
+ authorization: `Bearer ${token}`,
223
+ "content-type": "application/json",
224
+ },
225
+ ...(init?.body != null ? { body: init.body } : {}),
226
+ });
227
+ const body = (await res.json());
228
+ if (!res.ok || !body.success) {
229
+ throw new Error(`Cloudflare API 요청 실패 (${apiPath}): HTTP ${res.status} ${JSON.stringify(body.errors ?? [])}`);
230
+ }
231
+ return body.result;
232
+ }
233
+ /** 도메인을 점 단위로 축소한 후보 중 등록된 가장 구체적인 zone 선택 */
234
+ async _cfFindZone(token, domain) {
235
+ const labels = domain.split(".");
236
+ for (let i = 0; i < labels.length - 1; i++) {
237
+ const candidate = labels.slice(i).join(".");
238
+ const result = (await this._cloudflareRequest(token, `/zones?name=${encodeURIComponent(candidate)}`));
239
+ const zone = result.at(0);
240
+ if (zone != null)
241
+ return { id: zone.id, name: zone.name };
242
+ }
243
+ throw new Error(`Cloudflare 계정에서 도메인의 zone 을 찾지 못했습니다: ${domain}`);
244
+ }
245
+ async _cfCreateTxtRecord(token, zoneId, recordName, content) {
246
+ const result = (await this._cloudflareRequest(token, `/zones/${zoneId}/dns_records`, {
247
+ method: "POST",
248
+ body: JSON.stringify({ type: "TXT", name: recordName, content, ttl: 60 }),
249
+ }));
250
+ return result.id;
251
+ }
252
+ async _cfDeleteTxtRecord(token, zoneId, recordId) {
253
+ await this._cloudflareRequest(token, `/zones/${zoneId}/dns_records/${recordId}`, {
254
+ method: "DELETE",
255
+ });
256
+ }
257
+ /**
258
+ * DNS-01: TXT 가 도메인 권위 NS 에 전파됐는지 best-effort 로 확인.
259
+ * 권위 NS 조회 실패·전파 타임아웃 시 경고 후 진행 (CA 가 최종 검증).
260
+ */
261
+ async _waitForDnsPropagation(zoneName, recordName, expected) {
262
+ let resolver;
263
+ try {
264
+ const nsHosts = await resolveNs(zoneName);
265
+ const nsIps = [];
266
+ for (const nsHost of nsHosts) {
267
+ const ips = await resolve4(nsHost).catch(() => []);
268
+ nsIps.push(...ips);
269
+ }
270
+ if (nsIps.length === 0) {
271
+ logger.warn(`권위 NS 주소를 찾지 못해 DNS 전파 확인을 건너뜁니다 (CA 검증에 위임): ${zoneName}`);
272
+ return;
273
+ }
274
+ resolver = new Resolver();
275
+ resolver.setServers(nsIps);
276
+ }
277
+ catch {
278
+ logger.warn(`권위 NS 조회 실패로 DNS 전파 확인을 건너뜁니다 (CA 검증에 위임): ${zoneName}`);
279
+ return;
280
+ }
281
+ for (let i = 0; i < DNS_PROPAGATION_MAX_TRIES; i++) {
282
+ try {
283
+ const records = await resolver.resolveTxt(recordName);
284
+ if (records.some((chunks) => chunks.join("").includes(expected)))
285
+ return;
286
+ }
287
+ catch {
288
+ // 아직 미전파
289
+ }
290
+ await new Promise((resolve) => setTimeout(resolve, DNS_PROPAGATION_INTERVAL_MS));
291
+ }
292
+ logger.warn(`DNS 전파 확인 타임아웃. CA 검증에 위임합니다: ${recordName}`);
293
+ }
147
294
  _scheduleRenewal(notAfter) {
148
295
  this.stop();
149
296
  this._armTimer(notAfter.getTime() - RENEW_BEFORE_MS);
@@ -1 +1 @@
1
- {"version":3,"file":"acme-manager.js","sourceRoot":"","sources":["../../src/ssl/acme-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acme-manager.js","sourceRoot":"","sources":["../../src/ssl/acme-manager.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,12 @@ export interface ServiceServerOptions {
16
16
  domains: string[];
17
17
  email: string;
18
18
  staging?: boolean;
19
+ /**
20
+ * Cloudflare API 토큰(`Zone:Read` + `Zone.DNS:Edit` 권한).
21
+ * 지정 시 DNS-01 챌린지(Cloudflare 자동 TXT 등록)로 발급한다.
22
+ * 미지정 시 기존 TLS-ALPN-01 챌린지로 발급한다.
23
+ */
24
+ cloudflareApiToken?: string;
19
25
  };
20
26
  };
21
27
  auth?: {
@@ -1 +1 @@
1
- {"version":3,"file":"server-options.d.ts","sourceRoot":"","sources":["../../src/types/server-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EACA;QACE,QAAQ,EAAE,UAAU,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACD;QACE,WAAW,EAAE,UAAU,CAAC;QACxB,SAAS,EAAE,UAAU,CAAC;QACtB,OAAO,CAAC,EAAE,UAAU,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACD;QACE,WAAW,EAAE;YACX,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,OAAO,CAAC;SACnB,CAAC;KACH,CAAC;IACN,IAAI,CAAC,EACD;QACE,SAAS,EAAE,MAAM,CAAC;KACnB,GACD,KAAK,CAAC;IACV,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACvC"}
1
+ {"version":3,"file":"server-options.d.ts","sourceRoot":"","sources":["../../src/types/server-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EACA;QACE,QAAQ,EAAE,UAAU,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACD;QACE,WAAW,EAAE,UAAU,CAAC;QACxB,SAAS,EAAE,UAAU,CAAC;QACtB,OAAO,CAAC,EAAE,UAAU,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACD;QACE,WAAW,EAAE;YACX,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,OAAO,CAAC;YAClB;;;;eAIG;YACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;SAC7B,CAAC;KACH,CAAC;IACN,IAAI,CAAC,EACD;QACE,SAAS,EAAE,MAAM,CAAC;KACnB,GACD,KAAK,CAAC;IACV,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACvC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/service-server",
3
- "version": "14.0.100",
3
+ "version": "14.0.101",
4
4
  "description": "심플리즘 패키지 - 서비스 (server)",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",
@@ -30,11 +30,11 @@
30
30
  "semver": "^7.8.4",
31
31
  "utf-8-validate": "^6.0.6",
32
32
  "ws": "^8.21.0",
33
- "@simplysm/orm-common": "14.0.100",
34
- "@simplysm/core-common": "14.0.100",
35
- "@simplysm/service-common": "14.0.100",
36
- "@simplysm/core-node": "14.0.100",
37
- "@simplysm/orm-node": "14.0.100"
33
+ "@simplysm/orm-common": "14.0.101",
34
+ "@simplysm/orm-node": "14.0.101",
35
+ "@simplysm/service-common": "14.0.101",
36
+ "@simplysm/core-common": "14.0.101",
37
+ "@simplysm/core-node": "14.0.101"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/semver": "^7.7.1",
@@ -129,18 +129,6 @@ export interface ServiceDefinition<TMethods = Record<string, (...args: any[]) =>
129
129
 
130
130
  /**
131
131
  * 이름과 팩토리 함수로 서비스를 정의한다.
132
- *
133
- * @example
134
- * // 기본 서비스
135
- * const HealthService = defineService("Health", (ctx) => ({
136
- * check: () => ({ status: "ok" }),
137
- * }));
138
- *
139
- * // 인증이 필요한 서비스
140
- * const UserService = defineService("User", auth((ctx) => ({
141
- * getProfile: () => ctx.authInfo,
142
- * adminOnly: auth(["admin"], () => "admin"),
143
- * })));
144
132
  */
145
133
  export function defineService<TMethods extends Record<string, (...args: any[]) => any>>(
146
134
  name: string | string[],
@@ -164,10 +152,6 @@ export function defineService<TMethods extends Record<string, (...args: any[]) =
164
152
 
165
153
  /**
166
154
  * 클라이언트 측 타입 공유를 위해 ServiceDefinition에서 메서드 시그니처를 추출한다.
167
- *
168
- * @example
169
- * export type UserServiceType = ServiceMethods<typeof UserService>;
170
- * // 클라이언트: client.getService<UserServiceType>("User");
171
155
  */
172
156
  export type ServiceMethods<TDefinition> =
173
157
  TDefinition extends ServiceDefinition<infer M> ? M : never;
@@ -58,29 +58,37 @@ export class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
58
58
  let httpsConf: https.ServerOptions | null = null;
59
59
  if (options.ssl != null) {
60
60
  if ("letsencrypt" in options.ssl) {
61
+ const letsencrypt = options.ssl.letsencrypt;
61
62
  const acmeManager = new AcmeManager({
62
63
  rootPath: options.rootPath,
63
- domains: options.ssl.letsencrypt.domains,
64
- email: options.ssl.letsencrypt.email,
65
- staging: options.ssl.letsencrypt.staging,
64
+ domains: letsencrypt.domains,
65
+ email: letsencrypt.email,
66
+ staging: letsencrypt.staging,
67
+ cloudflareApiToken: letsencrypt.cloudflareApiToken,
66
68
  });
67
69
  this._acmeManager = acmeManager;
68
70
 
69
- // 인증서 없이 ALPNCallback 만으로 HTTPS 서버 생성.
70
- // 발급 전엔 acme-tls/1 챌린지에만 응답하고, 실인증서는 listen() 에서 setSecureContext 주입한다.
71
- httpsConf = {
72
- ALPNCallback: function (this: TLSSocket, { protocols }): string | undefined {
73
- if (protocols.includes("acme-tls/1")) {
74
- const ctx = acmeManager.getChallengeContext();
75
- if (ctx != null) {
76
- this.setKeyCert(ctx);
77
- return "acme-tls/1";
71
+ if (letsencrypt.cloudflareApiToken != null) {
72
+ // DNS-01: ALPN 챌린지가 없으므로 인증서 없이 HTTPS 서버를 생성하고,
73
+ // 실인증서는 listen() 에서 setSecureContext 로 주입한다.
74
+ httpsConf = {};
75
+ } else {
76
+ // TLS-ALPN-01: 인증서 없이 ALPNCallback 만으로 HTTPS 서버 생성.
77
+ // 발급 전엔 acme-tls/1 챌린지에만 응답하고, 실인증서는 listen() 에서 setSecureContext 로 주입한다.
78
+ httpsConf = {
79
+ ALPNCallback: function (this: TLSSocket, { protocols }): string | undefined {
80
+ if (protocols.includes("acme-tls/1")) {
81
+ const ctx = acmeManager.getChallengeContext();
82
+ if (ctx != null) {
83
+ this.setKeyCert(ctx);
84
+ return "acme-tls/1";
85
+ }
86
+ return undefined;
78
87
  }
79
- return undefined;
80
- }
81
- return protocols.includes("http/1.1") ? "http/1.1" : undefined;
82
- },
83
- };
88
+ return protocols.includes("http/1.1") ? "http/1.1" : undefined;
89
+ },
90
+ };
91
+ }
84
92
  } else if ("pfxBytes" in options.ssl) {
85
93
  httpsConf = {
86
94
  pfx: Buffer.from(options.ssl.pfxBytes),
@@ -107,8 +115,12 @@ export class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
107
115
  async listen(): Promise<void> {
108
116
  logger.info(`서버 시작 중... ${env("VER") ?? ""}`);
109
117
 
110
- // letsencrypt 핸드셰이크 중 인증서를 주입하는 TLSSocket.setKeyCert 가 필요 (Node 20.18.0+/22.9.0+)
111
- if (this._acmeManager != null) {
118
+ // TLS-ALPN-01 핸드셰이크 중 인증서를 주입하는 TLSSocket.setKeyCert 가 필요 (Node 20.18.0+/22.9.0+).
119
+ // DNS-01(cloudflareApiToken 지정) 은 ALPNCallback 을 쓰지 않으므로 이 요구가 없다.
120
+ const ssl = this.options.ssl;
121
+ const usesTlsAlpnChallenge =
122
+ ssl != null && "letsencrypt" in ssl && ssl.letsencrypt.cloudflareApiToken == null;
123
+ if (this._acmeManager != null && usesTlsAlpnChallenge) {
112
124
  assertAcmeNodeSupport();
113
125
  }
114
126
 
@@ -366,7 +378,7 @@ function assertAcmeNodeSupport(): void {
366
378
  (major === 20 && minor >= 18) || (major === 22 && minor >= 9) || major >= 23;
367
379
  if (!supported) {
368
380
  throw new Error(
369
- `Let's Encrypt(letsencrypt) SSL 은 Node 20.18.0+ 또는 22.9.0+ 가 필요합니다. 현재 버전: ${process.versions.node}`,
381
+ `Let's Encrypt TLS-ALPN-01 SSL 은 Node 20.18.0+ 또는 22.9.0+ 가 필요합니다. 현재 버전: ${process.versions.node} (DNS-01 은 cloudflareApiToken 지정 시 사용 가능)`,
370
382
  );
371
383
  }
372
384
  }
@@ -1,5 +1,6 @@
1
1
  import * as acme from "acme-client";
2
2
  import tls from "node:tls";
3
+ import { Resolver, resolveNs, resolve4 } from "node:dns/promises";
3
4
  import { chmod } from "node:fs/promises";
4
5
  import path from "node:path";
5
6
  import { fsx } from "@simplysm/core-node";
@@ -13,12 +14,26 @@ const RENEW_BEFORE_MS = 30 * 24 * 60 * 60 * 1000;
13
14
  const RETRY_DELAY_MS = 60 * 60 * 1000;
14
15
  /** setTimeout 최대 지연 (약 24.8일). 초과 시 분할하여 재무장 */
15
16
  const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
17
+ /** DNS-01 전파 확인 최대 시도 횟수 */
18
+ const DNS_PROPAGATION_MAX_TRIES = 30;
19
+ /** DNS-01 전파 확인 간격 (2초). 최대 약 60초 대기 */
20
+ const DNS_PROPAGATION_INTERVAL_MS = 2000;
21
+ /** Cloudflare API 기본 base URL */
22
+ const CLOUDFLARE_API_BASE_URL = "https://api.cloudflare.com/client/v4";
23
+
24
+ /** auto() 의 챌린지 방식별 옵션 (TLS-ALPN-01 / DNS-01 공통 부분 제외) */
25
+ type AcmeAutoChallengeOptions = Pick<
26
+ acme.ClientAutoOptions,
27
+ "challengePriority" | "challengeCreateFn" | "challengeRemoveFn"
28
+ >;
16
29
 
17
30
  export interface AcmeManagerOptions {
18
31
  rootPath: string;
19
32
  domains: string[];
20
33
  email: string;
21
34
  staging?: boolean;
35
+ /** 지정 시 DNS-01(Cloudflare) 로 발급. 미지정 시 TLS-ALPN-01 로 발급 */
36
+ cloudflareApiToken?: string;
22
37
  }
23
38
 
24
39
  export interface AcmeCertMaterial {
@@ -31,14 +46,17 @@ export interface AcmeCertMaterial {
31
46
  /**
32
47
  * Let's Encrypt(ACME) 인증서 자동 발급·갱신 매니저.
33
48
  *
34
- * TLS-ALPN-01 챌린지로 발급한다. 챌린지 응답 인증서는 {@link getChallengeContext} 노출하여
35
- * 서버의 ALPNCallback `acme-tls/1` 핸드셰이크에 주입한다.
49
+ * `cloudflareApiToken` 이 있으면 DNS-01 챌린지(Cloudflare TXT 자동 등록)발급하고,
50
+ * 없으면 TLS-ALPN-01 챌린지로 발급한다. TLS-ALPN-01 챌린지 응답 인증서는
51
+ * {@link getChallengeContext} 로 노출하여 서버의 ALPNCallback 이 `acme-tls/1` 핸드셰이크에 주입한다.
36
52
  */
37
53
  export class AcmeManager {
38
54
  private readonly _dir: string;
39
55
  private _challengeContext: tls.SecureContext | undefined;
40
56
  private _renewTimer: NodeJS.Timeout | undefined;
41
57
  private _onRenew: ((material: AcmeCertMaterial) => void) | undefined;
58
+ /** DNS-01: 도메인별로 생성한 Cloudflare TXT 레코드 (challengeRemoveFn 에서 삭제용) */
59
+ private readonly _dnsRecords = new Map<string, { zoneId: string; recordId: string }>();
42
60
 
43
61
  constructor(private readonly _options: AcmeManagerOptions) {
44
62
  this._dir = path.resolve(_options.rootPath, ".acme");
@@ -53,6 +71,9 @@ export class AcmeManager {
53
71
  private get _certKeyPath(): string {
54
72
  return path.resolve(this._dir, "cert.key");
55
73
  }
74
+ private get _metaPath(): string {
75
+ return path.resolve(this._dir, "issued-meta.json");
76
+ }
56
77
 
57
78
  /** ALPNCallback 에서 사용할 현재 챌린지 컨텍스트 (챌린지 진행 중에만 존재) */
58
79
  getChallengeContext(): tls.SecureContext | undefined {
@@ -96,6 +117,14 @@ export class AcmeManager {
96
117
  return undefined;
97
118
  }
98
119
 
120
+ // 발급에 사용한 CA(directoryUrl)가 현재 설정과 다르거나 메타가 없으면 캐시 무효화 (재발급).
121
+ // staging↔production↔사설 CA 전환 시 캐시된 이전 CA 인증서를 그대로 쓰는 것을 막는다.
122
+ const issuedDirectoryUrl = await this._readIssuedDirectoryUrl();
123
+ if (issuedDirectoryUrl !== this._directoryUrl()) {
124
+ logger.info("발급 CA(directoryUrl)가 현재 설정과 다름. 재발급을 진행합니다.");
125
+ return undefined;
126
+ }
127
+
99
128
  const cert = await fsx.read(this._certPath);
100
129
  const key = await fsx.read(this._certKeyPath);
101
130
 
@@ -132,6 +161,17 @@ export class AcmeManager {
132
161
  : acme.directory.letsencrypt.production;
133
162
  }
134
163
 
164
+ /** 캐시된 인증서의 발급 CA(directoryUrl). 메타 부재·파싱 실패 시 undefined */
165
+ private async _readIssuedDirectoryUrl(): Promise<string | undefined> {
166
+ if (!(await fsx.exists(this._metaPath))) return undefined;
167
+ try {
168
+ const meta = JSON.parse(await fsx.read(this._metaPath)) as { directoryUrl?: string };
169
+ return meta.directoryUrl;
170
+ } catch {
171
+ return undefined;
172
+ }
173
+ }
174
+
135
175
  private async _getAccountKey(): Promise<string> {
136
176
  if (await fsx.exists(this._accountKeyPath)) {
137
177
  return fsx.read(this._accountKeyPath);
@@ -155,25 +195,21 @@ export class AcmeManager {
155
195
  csr,
156
196
  email: this._options.email,
157
197
  termsOfServiceAgreed: true,
158
- challengePriority: ["tls-alpn-01"],
159
- // 로컬 사전검증(발급 호스트가 자기 공개 도메인:443 으로 hairpin 접속) 생략.
160
- // 구성에 따라 hairpin 막힐 있고, 실검증은 CA(LE) 직접 수행한다.
198
+ // 로컬 사전검증 생략. 실검증은 CA(LE) 가 직접 수행한다.
199
+ // - TLS-ALPN-01: 발급 호스트의 hairpin(자기 공개 도메인:443) 접속이 막힐 있어 생략.
200
+ // - DNS-01: self-verify 호스트 resolver 쓰므로, 전파 확인은 challengeCreateFn 에서 직접 수행.
161
201
  skipChallengeVerification: true,
162
- // challengePriority 를 tls-alpn-01 로 고정했으므로 이 콜백은 항상 tls-alpn-01 챌린지로 호출된다.
163
- challengeCreateFn: async (authz, _challenge, keyAuthorization) => {
164
- const [alpnKey, alpnCert] = await acme.crypto.createAlpnCertificate(authz, keyAuthorization);
165
- this._challengeContext = tls.createSecureContext({ key: alpnKey, cert: alpnCert });
166
- },
167
- challengeRemoveFn: () => {
168
- this._challengeContext = undefined;
169
- return Promise.resolve();
170
- },
202
+ ...(this._options.cloudflareApiToken != null
203
+ ? this._dns01AutoOptions(this._options.cloudflareApiToken)
204
+ : this._tlsAlpn01AutoOptions()),
171
205
  });
172
206
 
173
207
  const keyPem = certKey.toString();
174
208
  await fsx.write(this._certPath, cert);
175
209
  await fsx.write(this._certKeyPath, keyPem);
176
210
  await chmod(this._certKeyPath, 0o600).catch(() => {});
211
+ // 발급에 사용한 CA(directoryUrl)를 기록 — 다음 기동 시 CA 전환 감지에 사용
212
+ await fsx.write(this._metaPath, JSON.stringify({ directoryUrl: this._directoryUrl() }));
177
213
 
178
214
  const info = acme.crypto.readCertificateInfo(cert);
179
215
  logger.info(
@@ -184,6 +220,150 @@ export class AcmeManager {
184
220
  return { key: keyPem, cert };
185
221
  }
186
222
 
223
+ /** TLS-ALPN-01: 챌린지 응답 인증서를 ALPNCallback 용 컨텍스트로 노출 */
224
+ private _tlsAlpn01AutoOptions(): AcmeAutoChallengeOptions {
225
+ return {
226
+ challengePriority: ["tls-alpn-01"],
227
+ challengeCreateFn: async (authz, _challenge, keyAuthorization) => {
228
+ const [alpnKey, alpnCert] = await acme.crypto.createAlpnCertificate(authz, keyAuthorization);
229
+ this._challengeContext = tls.createSecureContext({ key: alpnKey, cert: alpnCert });
230
+ },
231
+ challengeRemoveFn: () => {
232
+ this._challengeContext = undefined;
233
+ return Promise.resolve();
234
+ },
235
+ };
236
+ }
237
+
238
+ /** DNS-01: Cloudflare 에 `_acme-challenge` TXT 를 등록·삭제하고 전파를 확인 */
239
+ private _dns01AutoOptions(token: string): AcmeAutoChallengeOptions {
240
+ return {
241
+ challengePriority: ["dns-01"],
242
+ challengeCreateFn: async (authz, _challenge, keyAuthorization) => {
243
+ const domain = authz.identifier.value;
244
+ const zone = await this._cfFindZone(token, domain);
245
+ const recordName = `_acme-challenge.${domain}`;
246
+ const recordId = await this._cfCreateTxtRecord(token, zone.id, recordName, keyAuthorization);
247
+ this._dnsRecords.set(domain, { zoneId: zone.id, recordId });
248
+ await this._waitForDnsPropagation(zone.name, recordName, keyAuthorization);
249
+ },
250
+ challengeRemoveFn: async (authz) => {
251
+ const domain = authz.identifier.value;
252
+ const record = this._dnsRecords.get(domain);
253
+ if (record == null) return;
254
+ await this._cfDeleteTxtRecord(token, record.zoneId, record.recordId);
255
+ this._dnsRecords.delete(domain);
256
+ },
257
+ };
258
+ }
259
+
260
+ private _cloudflareBaseUrl(): string {
261
+ // 운영 환경 변수로 Cloudflare API base URL 재정의 가능 (테스트 mock 등)
262
+ const override = env("SD_CLOUDFLARE_API_BASE_URL");
263
+ if (override != null && override !== "") return override;
264
+ return CLOUDFLARE_API_BASE_URL;
265
+ }
266
+
267
+ private async _cloudflareRequest(
268
+ token: string,
269
+ apiPath: string,
270
+ init?: { method: string; body?: string },
271
+ ): Promise<unknown> {
272
+ const res = await fetch(`${this._cloudflareBaseUrl()}${apiPath}`, {
273
+ method: init?.method ?? "GET",
274
+ headers: {
275
+ authorization: `Bearer ${token}`,
276
+ "content-type": "application/json",
277
+ },
278
+ ...(init?.body != null ? { body: init.body } : {}),
279
+ });
280
+ const body = (await res.json()) as { success: boolean; errors?: unknown[]; result?: unknown };
281
+ if (!res.ok || !body.success) {
282
+ throw new Error(
283
+ `Cloudflare API 요청 실패 (${apiPath}): HTTP ${res.status} ${JSON.stringify(body.errors ?? [])}`,
284
+ );
285
+ }
286
+ return body.result;
287
+ }
288
+
289
+ /** 도메인을 점 단위로 축소한 후보 중 등록된 가장 구체적인 zone 선택 */
290
+ private async _cfFindZone(token: string, domain: string): Promise<{ id: string; name: string }> {
291
+ const labels = domain.split(".");
292
+ for (let i = 0; i < labels.length - 1; i++) {
293
+ const candidate = labels.slice(i).join(".");
294
+ const result = (await this._cloudflareRequest(
295
+ token,
296
+ `/zones?name=${encodeURIComponent(candidate)}`,
297
+ )) as Array<{ id: string; name: string }>;
298
+ const zone = result.at(0);
299
+ if (zone != null) return { id: zone.id, name: zone.name };
300
+ }
301
+ throw new Error(`Cloudflare 계정에서 도메인의 zone 을 찾지 못했습니다: ${domain}`);
302
+ }
303
+
304
+ private async _cfCreateTxtRecord(
305
+ token: string,
306
+ zoneId: string,
307
+ recordName: string,
308
+ content: string,
309
+ ): Promise<string> {
310
+ const result = (await this._cloudflareRequest(token, `/zones/${zoneId}/dns_records`, {
311
+ method: "POST",
312
+ body: JSON.stringify({ type: "TXT", name: recordName, content, ttl: 60 }),
313
+ })) as { id: string };
314
+ return result.id;
315
+ }
316
+
317
+ private async _cfDeleteTxtRecord(
318
+ token: string,
319
+ zoneId: string,
320
+ recordId: string,
321
+ ): Promise<void> {
322
+ await this._cloudflareRequest(token, `/zones/${zoneId}/dns_records/${recordId}`, {
323
+ method: "DELETE",
324
+ });
325
+ }
326
+
327
+ /**
328
+ * DNS-01: TXT 가 도메인 권위 NS 에 전파됐는지 best-effort 로 확인.
329
+ * 권위 NS 조회 실패·전파 타임아웃 시 경고 후 진행 (CA 가 최종 검증).
330
+ */
331
+ private async _waitForDnsPropagation(
332
+ zoneName: string,
333
+ recordName: string,
334
+ expected: string,
335
+ ): Promise<void> {
336
+ let resolver: Resolver;
337
+ try {
338
+ const nsHosts = await resolveNs(zoneName);
339
+ const nsIps: string[] = [];
340
+ for (const nsHost of nsHosts) {
341
+ const ips = await resolve4(nsHost).catch(() => [] as string[]);
342
+ nsIps.push(...ips);
343
+ }
344
+ if (nsIps.length === 0) {
345
+ logger.warn(`권위 NS 주소를 찾지 못해 DNS 전파 확인을 건너뜁니다 (CA 검증에 위임): ${zoneName}`);
346
+ return;
347
+ }
348
+ resolver = new Resolver();
349
+ resolver.setServers(nsIps);
350
+ } catch {
351
+ logger.warn(`권위 NS 조회 실패로 DNS 전파 확인을 건너뜁니다 (CA 검증에 위임): ${zoneName}`);
352
+ return;
353
+ }
354
+
355
+ for (let i = 0; i < DNS_PROPAGATION_MAX_TRIES; i++) {
356
+ try {
357
+ const records = await resolver.resolveTxt(recordName);
358
+ if (records.some((chunks) => chunks.join("").includes(expected))) return;
359
+ } catch {
360
+ // 아직 미전파
361
+ }
362
+ await new Promise((resolve) => setTimeout(resolve, DNS_PROPAGATION_INTERVAL_MS));
363
+ }
364
+ logger.warn(`DNS 전파 확인 타임아웃. CA 검증에 위임합니다: ${recordName}`);
365
+ }
366
+
187
367
  private _scheduleRenewal(notAfter: Date): void {
188
368
  this.stop();
189
369
  this._armTimer(notAfter.getTime() - RENEW_BEFORE_MS);
@@ -20,6 +20,12 @@ export interface ServiceServerOptions {
20
20
  domains: string[];
21
21
  email: string;
22
22
  staging?: boolean;
23
+ /**
24
+ * Cloudflare API 토큰(`Zone:Read` + `Zone.DNS:Edit` 권한).
25
+ * 지정 시 DNS-01 챌린지(Cloudflare 자동 TXT 등록)로 발급한다.
26
+ * 미지정 시 기존 TLS-ALPN-01 챌린지로 발급한다.
27
+ */
28
+ cloudflareApiToken?: string;
23
29
  };
24
30
  };
25
31
  auth?: