@nodeart/cloudflare-provisioning 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cloudflare.js +128 -23
  2. package/package.json +1 -1
package/cloudflare.js CHANGED
@@ -208,7 +208,7 @@ class CloudFlare {
208
208
  throw new Error(`Could not get firewall rules: ${statusCode}, error: ${JSON.stringify(response)}`)
209
209
  }
210
210
 
211
- const { id, rules } = response
211
+ const { id, rules } = response?.result ?? {}
212
212
  if (!id) {
213
213
  throw new Error(`Could not get firewall rules ruleset ID: got ${id}, received value: ${JSON.stringify(response)}`)
214
214
  }
@@ -325,7 +325,7 @@ class CloudFlare {
325
325
  throw new Error(`Could not create redirect ruleset: ${statusCode}, error: ${JSON.stringify(createResponse)}`)
326
326
  }
327
327
 
328
- const { id, rules } = createResponse
328
+ const { id, rules } = createResponse?.result ?? {}
329
329
  if (!id) {
330
330
  throw new Error(`Could not get redirect rules ruleset ID: got ${id}, received value: ${JSON.stringify(response)}`)
331
331
  }
@@ -336,7 +336,7 @@ class CloudFlare {
336
336
  throw new Error(`Could not get redirect rules: ${statusCode}, error: ${JSON.stringify(response)}`)
337
337
  }
338
338
 
339
- const { id, rules } = response
339
+ const { id, rules } = response?.result ?? {}
340
340
  if (!id) {
341
341
  throw new Error(`Could not get redirect rules ruleset ID: got ${id}, received value: ${JSON.stringify(response)}`)
342
342
  }
@@ -804,29 +804,124 @@ class CloudFlare {
804
804
  return response
805
805
  }
806
806
 
807
- async uploadTlsClientAuth ({ clientKey, clientCert, caCert }) {
808
- try {
809
- await fs.access(clientKey, fs.constants.R_OK)
810
- await fs.access(clientCert, fs.constants.R_OK)
811
- await fs.access(caCert, fs.constants.R_OK)
812
- } catch (e) {
813
- throw new Error(`Cannot access file: ${e?.message}`)
807
+ async uploadTlsClientAuth ({ clientKey, clientCert, caCert, clear }) {
808
+ if (clear) {
809
+ await this.clearCustomCerts()
814
810
  }
815
811
 
816
- const clientKeyContents = await fs.readFile(clientKey, 'utf8')
817
- const clientCertContents = await fs.readFile(clientCert, 'utf8')
818
- const caCertContents = await fs.readFile(caCert, 'utf8')
812
+ if (clientKey && clientCert && caCert) {
813
+ try {
814
+ await fs.access(clientKey, fs.constants.R_OK)
815
+ await fs.access(clientCert, fs.constants.R_OK)
816
+ await fs.access(caCert, fs.constants.R_OK)
817
+ } catch (e) {
818
+ throw new Error(`Cancelling cert upload for domain ${this.domain}. Cannot access file: ${e?.message}`)
819
+ }
820
+
821
+ const clientKeyContents = await fs.readFile(clientKey, 'utf8')
822
+ const clientCertContents = await fs.readFile(clientCert, 'utf8')
823
+ const caCertContents = await fs.readFile(caCert, 'utf8')
824
+
825
+ await this.uploadCertAndKey(clientCertContents, clientKeyContents)
826
+ await this.uploadCaCert(caCertContents)
827
+ await this.enableTLSClientAuth()
828
+ }
829
+ }
830
+
831
+ async clearCustomCerts () {
832
+ const clientCertIds = await this.getClientCerts()
833
+ const caCertIds = await this.getCaCerts()
834
+
835
+ for (const cert of clientCertIds) {
836
+ try {
837
+ await this.deleteClientCert(cert)
838
+ } catch (e) {
839
+ console.error(`Failed to delete Client cert: ${e?.message}`)
840
+ }
841
+ }
842
+
843
+ for (const cert of caCertIds) {
844
+ try {
845
+ await this.deleteCaCert(cert)
846
+ } catch (e) {
847
+ console.error(`Failed to delete Client cert: ${e?.message}`)
848
+ }
849
+ }
850
+ }
851
+
852
+ async getClientCerts () {
853
+ const url = CLOUDFLARE_API_URL + `zones/${this.zoneId}/origin_tls_client_auth`
854
+ const { statusCode, body } = await request(url, {
855
+ method: 'GET',
856
+ headers: {
857
+ ...this.authorizationHeaders,
858
+ 'Content-Type': 'application/json'
859
+ }
860
+ })
861
+ const response = await body.json()
862
+
863
+ if (statusCode !== 200) {
864
+ throw new Error(`Could not get client certificate IDs: ${statusCode}, error: ${JSON.stringify(response)}`)
865
+ }
866
+
867
+ return response?.result?.map((cert) => cert?.id) ?? []
868
+ }
869
+
870
+ async getCaCerts () {
871
+ const url = CLOUDFLARE_API_URL + `zones/${this.zoneId}/acm/custom_trust_store`
872
+ const { statusCode, body } = await request(url, {
873
+ method: 'GET',
874
+ headers: {
875
+ ...this.authorizationHeaders,
876
+ 'Content-Type': 'application/json'
877
+ }
878
+ })
879
+ const response = await body.json()
880
+
881
+ if (statusCode !== 200) {
882
+ throw new Error(`Could not get CA certificate IDs: ${statusCode}, error: ${JSON.stringify(response)}`)
883
+ }
819
884
 
820
- await this.uploadCertAndKey(clientCertContents, clientKeyContents)
821
- await this.uploadCaCert(caCertContents)
822
- await this.enableTLSClientAuth()
885
+ return response?.result?.map((cert) => cert?.id) ?? []
886
+ }
887
+
888
+ async deleteClientCert (certId) {
889
+ const url = CLOUDFLARE_API_URL + `zones/${this.zoneId}/origin_tls_client_auth/${certId}`
890
+ const { statusCode, body } = await request(url, {
891
+ method: 'DELETE',
892
+ headers: {
893
+ ...this.authorizationHeaders,
894
+ 'Content-Type': 'application/json'
895
+ }
896
+ })
897
+ const response = await body.json()
898
+
899
+ if (statusCode !== 200) {
900
+ throw new Error(`Could not delete client certificate ID ${certId}: ${statusCode}, error: ${JSON.stringify(response)}`)
901
+ }
902
+ }
903
+
904
+ async deleteCaCert (certId) {
905
+ const url = CLOUDFLARE_API_URL + `zones/${this.zoneId}/acm/custom_trust_store/${certId}`
906
+ const { statusCode, body } = await request(url, {
907
+ method: 'DELETE',
908
+ headers: {
909
+ ...this.authorizationHeaders,
910
+ 'Content-Type': 'application/json'
911
+ }
912
+ })
913
+ const response = await body.json()
914
+
915
+ if (statusCode !== 200) {
916
+ throw new Error(`Could not delete CA certificate ID ${certId}: ${statusCode}, error: ${JSON.stringify(response)}`)
917
+ }
823
918
  }
824
919
 
825
920
  async uploadCertAndKey (clientCert, clientKey) {
826
921
  const url = CLOUDFLARE_API_URL + `zones/${this.zoneId}/origin_tls_client_auth`
827
922
  const payload = {
828
- certificate: clientCert,
829
- private_key: clientKey
923
+ certificate: clientCert.replace(/\r?\n/g, '\n'),
924
+ private_key: clientKey.replace(/\r?\n/g, '\n')
830
925
  }
831
926
 
832
927
  const { statusCode, body } = await request(url, {
@@ -840,15 +935,20 @@ class CloudFlare {
840
935
 
841
936
  const response = await body.json()
842
937
 
843
- if (statusCode !== 200) {
844
- throw new Error(`Could not upload certificate and private key: ${statusCode}, error: ${JSON.stringify(response)}`)
938
+ if (statusCode !== 200 && statusCode !== 201) {
939
+ const errors = response?.errors ?? []
940
+ if (errors.find((error) => error.code === 1406 && error.message === 'This certificate already exists for this zone.')) {
941
+ console.log(`This certificate already exists for domain ${this.domain}. Continuing...`)
942
+ } else {
943
+ throw new Error(`Could not upload certificate and private key: ${statusCode}, error: ${JSON.stringify(response)}`)
944
+ }
845
945
  }
846
946
  }
847
947
 
848
948
  async uploadCaCert (caCert) {
849
949
  const url = CLOUDFLARE_API_URL + `zones/${this.zoneId}/acm/custom_trust_store`
850
950
  const payload = {
851
- certificate: caCert
951
+ certificate: caCert.replace(/\r?\n/g, '\n')
852
952
  }
853
953
 
854
954
  const { statusCode, body } = await request(url, {
@@ -862,8 +962,13 @@ class CloudFlare {
862
962
 
863
963
  const response = await body.json()
864
964
 
865
- if (statusCode !== 200) {
866
- throw new Error(`Could not upload CA certificate: ${statusCode}, error: ${JSON.stringify(response)}`)
965
+ if (statusCode !== 200 && statusCode !== 201) {
966
+ const errors = response?.errors ?? []
967
+ if (errors.find((error) => error.code === 1406 && error.message === 'This certificate already exists for this zone.')) {
968
+ console.log(`This CA certificate already exists for domain ${this.domain}. Continuing...`)
969
+ } else {
970
+ throw new Error(`Could not upload CA certificate: ${statusCode}, error: ${JSON.stringify(response)}`)
971
+ }
867
972
  }
868
973
  }
869
974
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodeart/cloudflare-provisioning",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {