BREAKING CHANGE(core): streamline scope to certificate retrieval using dns challenge
This commit is contained in:
parent
c2036bba90
commit
59173b3ca8
76
package-lock.json
generated
76
package-lock.json
generated
@ -71,24 +71,23 @@
|
||||
}
|
||||
},
|
||||
"@mojoio/cloudflare": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://verdaccio.lossless.one/@mojoio%2fcloudflare/-/cloudflare-3.0.5.tgz",
|
||||
"integrity": "sha512-jaJkWQGkc7uJ9L1AbuHXSuskBe8NehRE+N3gekztgWhzuH/AjZHGc0HlAE8qiO8su+tilXkuexbLElSF24W+Gw==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://verdaccio.lossless.one/@mojoio%2fcloudflare/-/cloudflare-4.0.3.tgz",
|
||||
"integrity": "sha512-QHjBXzechtg3U1mDqC1aJj8X1PB4eSlIWavFBPlif9F+2TetrTiyfU5LZlP1Z1rRDdTRygTvJXtohsz2BYRFgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/smartdelay": "^2.0.3",
|
||||
"@pushrocks/smartlog": "^2.0.19",
|
||||
"@pushrocks/smartpromise": "^3.0.2",
|
||||
"@pushrocks/smartrequest": "^1.1.16",
|
||||
"@pushrocks/smartstring": "^3.0.10",
|
||||
"@tsclass/tsclass": "^2.0.1"
|
||||
"@pushrocks/smartdelay": "^2.0.6",
|
||||
"@pushrocks/smartlog": "^2.0.21",
|
||||
"@pushrocks/smartpromise": "^3.0.6",
|
||||
"@pushrocks/smartrequest": "^1.1.47",
|
||||
"@pushrocks/smartstring": "^3.0.18",
|
||||
"@tsclass/tsclass": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"@pushrocks/consolecolor": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@pushrocks/consolecolor/-/consolecolor-2.0.1.tgz",
|
||||
"integrity": "sha512-iOFCHVeFZ2OywbdwSxVI4/wokkcLrXVdHLgvMmkNhJ220eeLgjNZWx3EJo3vNW3zq5ybCSCUIq0878djBxrWpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-256-colors": "^1.1.0"
|
||||
}
|
||||
@ -97,7 +96,6 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fearly/-/early-3.0.3.tgz",
|
||||
"integrity": "sha512-71/nwxTpqdp1glmHz4YaGusNl/XOOcPelAxC9RA6rpS/6280QyY2u4yx+mRdMrCzn7ruLYF5awbkS8llNZ94Pg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/consolecolor": "^2.0.1",
|
||||
"@pushrocks/smartpromise": "^2.0.5"
|
||||
@ -106,8 +104,7 @@
|
||||
"@pushrocks/smartpromise": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartpromise/-/smartpromise-2.0.5.tgz",
|
||||
"integrity": "sha512-9j/chLtIiNkR0MDw7Mpxg9slxAVvAQwUZuiaPYX5KpHdKxQaHLI1VZ8IN0vPhwlfgNO4i4vGXV0wB8BvSDj03g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-9j/chLtIiNkR0MDw7Mpxg9slxAVvAQwUZuiaPYX5KpHdKxQaHLI1VZ8IN0vPhwlfgNO4i4vGXV0wB8BvSDj03g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -426,7 +423,6 @@
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2ftapbundle/-/tapbundle-3.2.0.tgz",
|
||||
"integrity": "sha512-xnKIGe7NJqxWBaFeKIEXShDjV2wap1XJqmlp3m1MKqmIF62vRpZnkzpyE1ZAoNwiYQmIsXIpvP/PDv+iPevPfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/early": "^3.0.3",
|
||||
"@pushrocks/smartdelay": "^2.0.3",
|
||||
@ -439,7 +435,6 @@
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartdelay/-/smartdelay-2.0.6.tgz",
|
||||
"integrity": "sha512-4wUnzWNhRPODpaaL5GuRaje/C5dg+TMhBxmr57PKc2fqYpy6azWJwonf/s5xpcbJLCPJRbj1x8M5MqgCFq2uvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/smartpromise": "^3.0.6"
|
||||
}
|
||||
@ -448,7 +443,6 @@
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartfile/-/smartfile-7.0.6.tgz",
|
||||
"integrity": "sha512-X1kWg1HSQ/MqasRIHPCf6D9CRrcIrpTjW8KLc4GkApJ/W/IVaKsQkJQfdimlg1uc/9v8AYnoRdiGa51yxyghZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/smarthash": "^2.0.6",
|
||||
"@pushrocks/smartpath": "^4.0.1",
|
||||
@ -463,14 +457,12 @@
|
||||
"@pushrocks/smartpromise": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartpromise/-/smartpromise-3.0.6.tgz",
|
||||
"integrity": "sha512-vlQlBGNVIjfClgnsfgQBU6GIKcskYSFzEcKLt18ngPzPEcjKklXcxaqzLXpnoxR+KBh30QPE8255ncYHXuPPOg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-vlQlBGNVIjfClgnsfgQBU6GIKcskYSFzEcKLt18ngPzPEcjKklXcxaqzLXpnoxR+KBh30QPE8255ncYHXuPPOg=="
|
||||
},
|
||||
"@pushrocks/smartrequest": {
|
||||
"version": "1.1.47",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartrequest/-/smartrequest-1.1.47.tgz",
|
||||
"integrity": "sha512-0AuqtAI14VeWeXl2WpJbgCybVlG03rOjdGchAqy5k5lg9ACLhN3Z4kmoLgpBysWO/L2SjlAKB489SRyV3acykg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/smartpromise": "^3.0.5",
|
||||
"@types/form-data": "^2.5.0",
|
||||
@ -482,7 +474,6 @@
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2fform-data/-/form-data-2.5.0.tgz",
|
||||
"integrity": "sha512-23/wYiuckYYtFpL+4RPWiWmRQH2BjFuqCUi2+N3amB1a1Drv+i/byTrGvlLwRVLFNAZbwpbQ7JvTK+VCAPMbcg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"form-data": "*"
|
||||
}
|
||||
@ -491,7 +482,6 @@
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2ffs-extra/-/fs-extra-8.0.1.tgz",
|
||||
"integrity": "sha512-J00cVDALmi/hJOYsunyT52Hva5TnJeKP5yd1r+mH/ZU0mbYZflR0Z5kw5kITtKTRYMhm1JMClOFYdHnQszEvqw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@ -500,7 +490,6 @@
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://verdaccio.lossless.one/form-data/-/form-data-2.5.1.tgz",
|
||||
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
@ -511,7 +500,6 @@
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://verdaccio.lossless.one/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
@ -522,7 +510,6 @@
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://verdaccio.lossless.one/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@ -535,14 +522,12 @@
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://verdaccio.lossless.one/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://verdaccio.lossless.one/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
@ -551,10 +536,9 @@
|
||||
}
|
||||
},
|
||||
"@tsclass/tsclass": {
|
||||
"version": "2.0.13",
|
||||
"resolved": "https://verdaccio.lossless.one/@tsclass%2ftsclass/-/tsclass-2.0.13.tgz",
|
||||
"integrity": "sha512-ZhN3vLAahP4DOayACh/bskG4SpeqNpR4oH9776hZvz6GoFj7KQinzf03gzC5o2o6tnmOusQ1FYu1NGYmy6Rvdg==",
|
||||
"dev": true,
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://verdaccio.lossless.one/@tsclass%2ftsclass/-/tsclass-3.0.4.tgz",
|
||||
"integrity": "sha512-q9PnwBFDTTlwKp6jYn/tL6zhqWvwaKyGsf81xI8xcV6IhjmFo3hk0iM4L3ydw7iTwqR+WmhYaWO5WdMy3/KA+w==",
|
||||
"requires": {
|
||||
"@pushrocks/tapbundle": "^3.0.13"
|
||||
}
|
||||
@ -579,14 +563,12 @@
|
||||
"@types/chai": {
|
||||
"version": "4.2.7",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2fchai/-/chai-4.2.7.tgz",
|
||||
"integrity": "sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g=="
|
||||
},
|
||||
"@types/chai-as-promised": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2fchai-as-promised/-/chai-as-promised-7.1.2.tgz",
|
||||
"integrity": "sha512-PO2gcfR3Oxa+u0QvECLe1xKXOqYTzCmWf0FhLhjREoW3fPAVamjihL7v1MOVLJLsnAMdLcjkfrs01yvDMwVK4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/chai": "*"
|
||||
}
|
||||
@ -595,7 +577,6 @@
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2fchai-string/-/chai-string-1.4.2.tgz",
|
||||
"integrity": "sha512-ld/1hV5qcPRGuwlPdvRfvM3Ka/iofOk2pH4VkasK4b1JJP1LjNmWWn0LsISf6RRzyhVOvs93rb9tM09e+UuF8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/chai": "*"
|
||||
}
|
||||
@ -863,8 +844,7 @@
|
||||
"ansi-256-colors": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz",
|
||||
"integrity": "sha1-kQ3lDvzHwJ49gvL4er1rcAwYgYo=",
|
||||
"dev": true
|
||||
"integrity": "sha1-kQ3lDvzHwJ49gvL4er1rcAwYgYo="
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
@ -915,8 +895,7 @@
|
||||
"assertion-error": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
|
||||
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
@ -1046,7 +1025,6 @@
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://verdaccio.lossless.one/chai/-/chai-4.2.0.tgz",
|
||||
"integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assertion-error": "^1.1.0",
|
||||
"check-error": "^1.0.2",
|
||||
@ -1060,7 +1038,6 @@
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz",
|
||||
"integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"check-error": "^1.0.2"
|
||||
}
|
||||
@ -1068,8 +1045,7 @@
|
||||
"chai-string": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://verdaccio.lossless.one/chai-string/-/chai-string-1.5.0.tgz",
|
||||
"integrity": "sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
@ -1085,8 +1061,7 @@
|
||||
"check-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
|
||||
"dev": true
|
||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "2.1.0",
|
||||
@ -1262,7 +1237,6 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
|
||||
"integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-detect": "^4.0.0"
|
||||
}
|
||||
@ -1568,8 +1542,7 @@
|
||||
"get-func-name": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
|
||||
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
|
||||
"dev": true
|
||||
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE="
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
@ -2339,8 +2312,7 @@
|
||||
"pathval": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
|
||||
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
|
||||
"dev": true
|
||||
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA="
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
@ -2680,7 +2652,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/smartchai/-/smartchai-2.0.1.tgz",
|
||||
"integrity": "sha512-9M+R56OhAHXScxgr2vzQqxGx0XMS0QXriNZuP7hjlbVbo2FUT+l60iEzbwPt9Ga+5u2cEEjSSoZEQVqlROaddA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/chai": "^4.1.2",
|
||||
"@types/chai-as-promised": "^7.1.0",
|
||||
@ -2917,8 +2888,7 @@
|
||||
"type-detect": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
|
||||
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
|
@ -36,13 +36,14 @@
|
||||
"@pushrocks/smartstring": "^3.0.18",
|
||||
"@pushrocks/smarttime": "^3.0.12",
|
||||
"@pushrocks/smartunique": "^3.0.1",
|
||||
"@tsclass/tsclass": "^3.0.4",
|
||||
"acme-client": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gitzone/tsbuild": "^2.1.17",
|
||||
"@gitzone/tsrun": "^1.2.8",
|
||||
"@gitzone/tstest": "^1.0.28",
|
||||
"@mojoio/cloudflare": "^3.0.5",
|
||||
"@mojoio/cloudflare": "^4.0.3",
|
||||
"@pushrocks/qenv": "^4.0.6",
|
||||
"@pushrocks/tapbundle": "^3.2.0",
|
||||
"@types/node": "^13.7.0",
|
||||
|
13
test/test.ts
13
test/test.ts
@ -1,7 +1,12 @@
|
||||
import { tap, expect } from '@pushrocks/tapbundle';
|
||||
import { Qenv } from '@pushrocks/qenv';
|
||||
import * as cloudflare from '@mojoio/cloudflare';
|
||||
|
||||
const testQenv = new Qenv('./', './.nogit/');
|
||||
const testCloudflare = new cloudflare.CloudflareAccount({
|
||||
email: testQenv.getEnvVarOnDemand('CF_EMAIL'),
|
||||
key: testQenv.getEnvVarOnDemand('CF_KEY')
|
||||
});
|
||||
|
||||
import * as smartacme from '../ts/index';
|
||||
|
||||
@ -16,11 +21,11 @@ tap.test('should create a valid instance of SmartAcme', async () => {
|
||||
mongoDbPass: testQenv.getEnvVarRequired('MONGODB_PASSWORD'),
|
||||
mongoDbUrl: testQenv.getEnvVarRequired('MONGODB_URL')
|
||||
},
|
||||
removeChallenge: async (...args) => {
|
||||
console.log(args);
|
||||
removeChallenge: async (dnsChallenge) => {
|
||||
testCloudflare.convenience.acmeRemoveDnsChallenge(dnsChallenge);
|
||||
},
|
||||
setChallenge: async (...args) => {
|
||||
console.log(args);
|
||||
setChallenge: async (dnsChallenge) => {
|
||||
testCloudflare.convenience.acmeSetDnsChallenge(dnsChallenge);
|
||||
},
|
||||
environment: 'integration'
|
||||
});
|
||||
|
@ -1,3 +1 @@
|
||||
export * from './smartacme.classes.smartacme';
|
||||
|
||||
export * from './smartacme.classes.certremoteclient';
|
||||
|
@ -1,6 +1,6 @@
|
||||
export type TCertStatus = 'existing' | 'nonexisting' | 'pending' | 'failed';
|
||||
|
||||
export interface ICert {
|
||||
export interface IOldCert {
|
||||
id: string;
|
||||
domainName: string;
|
||||
created: number;
|
||||
|
@ -9,7 +9,7 @@ import { Collection, svDb, unI } from '@pushrocks/smartdata';
|
||||
@plugins.smartdata.Collection(() => {
|
||||
return CertManager.activeDB;
|
||||
})
|
||||
export class Cert extends plugins.smartdata.SmartDataDbDoc<Cert> implements interfaces.ICert {
|
||||
export class Cert extends plugins.smartdata.SmartDataDbDoc<Cert> implements plugins.tsclass.network.ICert {
|
||||
@unI()
|
||||
public id: string;
|
||||
|
||||
@ -28,28 +28,30 @@ export class Cert extends plugins.smartdata.SmartDataDbDoc<Cert> implements inte
|
||||
@svDb()
|
||||
public csr: string;
|
||||
|
||||
/**
|
||||
* computed value for when the certificate is still valid
|
||||
*/
|
||||
get validUntil(): number {
|
||||
return (
|
||||
this.created +
|
||||
plugins.smarttime.getMilliSecondsFromUnits({
|
||||
days: 90
|
||||
})
|
||||
);
|
||||
@svDb()
|
||||
public validUntil: number;
|
||||
|
||||
public isStillValid(): boolean {
|
||||
return this.validUntil >= Date.now();
|
||||
}
|
||||
|
||||
get isStillValid(): boolean {
|
||||
const shouldBeValitAtLeastUntil =
|
||||
public shouldBeRenewed(): boolean {
|
||||
const shouldBeValidAtLeastUntil =
|
||||
Date.now() +
|
||||
plugins.smarttime.getMilliSecondsFromUnits({
|
||||
days: 10
|
||||
});
|
||||
return this.validUntil >= shouldBeValitAtLeastUntil;
|
||||
return this.validUntil >= shouldBeValidAtLeastUntil;
|
||||
}
|
||||
|
||||
constructor(optionsArg: interfaces.ICert) {
|
||||
public update(certDataArg: plugins.tsclass.network.ICert) {
|
||||
Object.keys(certDataArg).forEach(key => {
|
||||
this[key] = certDataArg[key];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
constructor(optionsArg: plugins.tsclass.network.ICert) {
|
||||
super();
|
||||
if (optionsArg) {
|
||||
Object.keys(optionsArg).forEach(key => {
|
||||
|
@ -16,7 +16,7 @@ export class CertManager {
|
||||
private mongoDescriptor: plugins.smartdata.IMongoDescriptor;
|
||||
public smartdataDb: plugins.smartdata.SmartdataDb;
|
||||
|
||||
public pendingMap: plugins.lik.Stringmap;
|
||||
public interestMap: plugins.lik.InterestMap<string, Cert>;
|
||||
|
||||
constructor(
|
||||
smartAcmeArg: SmartAcme,
|
||||
@ -34,18 +34,17 @@ export class CertManager {
|
||||
CertManager.activeDB = this.smartdataDb;
|
||||
|
||||
// Pending Map
|
||||
this.pendingMap = new plugins.lik.Stringmap();
|
||||
this.interestMap = new plugins.lik.InterestMap((certName) => certName);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves a certificate
|
||||
* @returns the Cert class or null
|
||||
* @param domainName the domain Name to retrieve the vcertificate for
|
||||
* @param certDomainNameArg the domain Name to retrieve the vcertificate for
|
||||
*/
|
||||
public async retrieveCertificate(domainName: string): Promise<Cert> {
|
||||
await this.checkCerts();
|
||||
public async retrieveCertificate(certDomainNameArg: string): Promise<Cert> {
|
||||
const existingCertificate: Cert = await Cert.getInstance({
|
||||
domainName
|
||||
domainName: certDomainNameArg
|
||||
});
|
||||
|
||||
if (existingCertificate) {
|
||||
@ -59,44 +58,20 @@ export class CertManager {
|
||||
* stores the certificate
|
||||
* @param optionsArg
|
||||
*/
|
||||
public async storeCertificate(optionsArg: interfaces.ICert) {
|
||||
public async storeCertificate(optionsArg: plugins.tsclass.network.ICert) {
|
||||
const cert = new Cert(optionsArg);
|
||||
await cert.save();
|
||||
this.pendingMap.removeString(optionsArg.domainName);
|
||||
}
|
||||
|
||||
public async deleteCertificate(domainNameArg: string) {}
|
||||
|
||||
/**
|
||||
* announce a certificate as being in the process of being retrieved
|
||||
*/
|
||||
public async announceCertificate(domainNameArg: string) {
|
||||
this.pendingMap.addString(domainNameArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the status of a certificate by certDomain name
|
||||
* @param certDomainArg
|
||||
*/
|
||||
public async getCertificateStatus(certDomainArg: string): Promise<interfaces.TCertStatus> {
|
||||
const isPending = this.pendingMap.checkString(certDomainArg);
|
||||
if (isPending) {
|
||||
return 'pending';
|
||||
const interest = this.interestMap.findInterest(cert.domainName);
|
||||
if (interest) {
|
||||
interest.fullfillInterest(cert);
|
||||
interest.markLost();
|
||||
}
|
||||
|
||||
// otherwise lets continue
|
||||
const existingCertificate = await this.retrieveCertificate(certDomainArg);
|
||||
if (existingCertificate) {
|
||||
return 'existing';
|
||||
}
|
||||
|
||||
return 'nonexisting';
|
||||
}
|
||||
|
||||
/**
|
||||
* checks all certs for expiration
|
||||
*/
|
||||
private async checkCerts() {
|
||||
// TODO
|
||||
public async deleteCertificate(certDomainNameArg: string) {
|
||||
const cert: Cert = await Cert.getInstance({
|
||||
domainName: certDomainNameArg
|
||||
});
|
||||
await cert.delete();
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
import * as plugins from './smartacme.plugins';
|
||||
import * as interfaces from './interfaces';
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class CertRemoteClient {
|
||||
private remoteUrl: string;
|
||||
private secret: string;
|
||||
private logger: plugins.smartlog.Smartlog;
|
||||
|
||||
constructor(optionsArg: {
|
||||
remoteUrl: string;
|
||||
secret: string;
|
||||
logger?: plugins.smartlog.Smartlog;
|
||||
}) {
|
||||
this.remoteUrl = optionsArg.remoteUrl;
|
||||
this.secret = optionsArg.secret;
|
||||
optionsArg.logger
|
||||
? (this.logger = optionsArg.logger)
|
||||
: (this.logger = plugins.smartlog.defaultLogger);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param domainNameArg
|
||||
*/
|
||||
public async getCertificateForDomain(domainNameArg: string): Promise<interfaces.ICert> {
|
||||
let certificate: interfaces.ICert;
|
||||
const doRequestCycle = async (): Promise<interfaces.ICert> => {
|
||||
const responseBody: interfaces.ICertRemoteResponse = (
|
||||
await plugins.smartrequest.postJson(this.remoteUrl, {
|
||||
requestBody: <interfaces.ICertRemoteRequest>{
|
||||
domainName: domainNameArg,
|
||||
secret: this.secret
|
||||
}
|
||||
})
|
||||
).body;
|
||||
switch (responseBody.status as interfaces.TCertStatus) {
|
||||
case 'pending':
|
||||
this.logger.log('info', `request for ${domainNameArg} still pending!`);
|
||||
await plugins.smartdelay.delayFor(5000);
|
||||
const finalResponse = await doRequestCycle();
|
||||
return finalResponse;
|
||||
case 'existing':
|
||||
this.logger.log('ok', `got certificate for ${domainNameArg}`);
|
||||
return responseBody.certificate;
|
||||
case 'failed':
|
||||
default:
|
||||
console.log(`could not retrieve certificate for ${domainNameArg}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
certificate = await doRequestCycle();
|
||||
return certificate;
|
||||
}
|
||||
}
|
@ -13,8 +13,8 @@ export interface ISmartAcmeOptions {
|
||||
accountPrivateKey?: string;
|
||||
accountEmail: string;
|
||||
mongoDescriptor: plugins.smartdata.IMongoDescriptor;
|
||||
setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>;
|
||||
removeChallenge: (domainName: string) => Promise<any>;
|
||||
setChallenge: (dnsChallengeArg: plugins.tsclass.network.IDnsChallenge) => Promise<any>;
|
||||
removeChallenge: (dnsChallengeArg: plugins.tsclass.network.IDnsChallenge) => Promise<any>;
|
||||
environment: 'production' | 'integration';
|
||||
logger?: plugins.smartlog.Smartlog;
|
||||
}
|
||||
@ -41,53 +41,13 @@ export class SmartAcme {
|
||||
private privateKey: string;
|
||||
|
||||
// challenge fullfillment
|
||||
private setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>;
|
||||
private removeChallenge: (domainName: string) => Promise<any>;
|
||||
private setChallenge: (dnsChallengeArg: plugins.tsclass.network.IDnsChallenge) => Promise<any>;
|
||||
private removeChallenge: (dnsChallengeArg: plugins.tsclass.network.IDnsChallenge) => Promise<any>;
|
||||
|
||||
// certmanager
|
||||
private certmanager: CertManager;
|
||||
private certmatcher: CertMatcher;
|
||||
|
||||
/**
|
||||
* the remote handler to hand the request and response to.
|
||||
*/
|
||||
public certremoteHandler = async (
|
||||
req: plugins.smartexpress.Request,
|
||||
res: plugins.smartexpress.Response
|
||||
) => {
|
||||
const requestBody: interfaces.ICertRemoteRequest = req.body;
|
||||
this.logger.log('ok', `got certificate request for ${requestBody.domainName}`);
|
||||
const certDomain = this.certmatcher.getCertificateDomainNameByDomainName(
|
||||
requestBody.domainName
|
||||
);
|
||||
this.logger.log('ok', `mapping ${requestBody.domainName} to ${certDomain}`);
|
||||
let status: interfaces.TCertStatus = await this.certmanager.getCertificateStatus(certDomain);
|
||||
let response: interfaces.ICertRemoteResponse;
|
||||
switch (status) {
|
||||
case 'existing':
|
||||
this.logger.log('ok', `certificate exists for ${certDomain}. Sending certificate!`);
|
||||
response = {
|
||||
status,
|
||||
certificate: await (
|
||||
await this.certmanager.retrieveCertificate(certDomain)
|
||||
).createSavableObject()
|
||||
};
|
||||
break;
|
||||
default:
|
||||
if (status === 'nonexisting') {
|
||||
this.getCertificateForDomain(certDomain);
|
||||
status = 'pending';
|
||||
}
|
||||
response = {
|
||||
status
|
||||
};
|
||||
break;
|
||||
}
|
||||
res.status(200);
|
||||
res.send(response);
|
||||
res.end();
|
||||
};
|
||||
|
||||
constructor(optionsArg: ISmartAcmeOptions) {
|
||||
this.options = optionsArg;
|
||||
this.options.logger
|
||||
@ -144,8 +104,8 @@ export class SmartAcme {
|
||||
* it runs through the following steps
|
||||
*
|
||||
* * look in the database
|
||||
* * if in the database return it
|
||||
* * of not in the database announce it
|
||||
* * if in the database and still valid return it
|
||||
* * if not in the database announce it
|
||||
* * then get it from letsencrypt
|
||||
* * store it
|
||||
* * remove it from the pending map (which it go onto by announcing it)
|
||||
@ -154,20 +114,28 @@ export class SmartAcme {
|
||||
* @param domainArg
|
||||
*/
|
||||
public async getCertificateForDomain(domainArg: string): Promise<Cert> {
|
||||
const certDomain = this.certmatcher.getCertificateDomainNameByDomainName(domainArg);
|
||||
const retrievedCertificate = await this.certmanager.retrieveCertificate(certDomain);
|
||||
const certDomainName = this.certmatcher.getCertificateDomainNameByDomainName(domainArg);
|
||||
const retrievedCertificate = await this.certmanager.retrieveCertificate(certDomainName);
|
||||
|
||||
if (retrievedCertificate) {
|
||||
if (!retrievedCertificate && await this.certmanager.interestMap.checkInterest(certDomainName)) {
|
||||
const existingCertificateInterest = this.certmanager.interestMap.findInterest(certDomainName);
|
||||
const certificate = existingCertificateInterest.interestFullfilled;
|
||||
return certificate;
|
||||
} else if (retrievedCertificate && !retrievedCertificate.shouldBeRenewed()) {
|
||||
return retrievedCertificate;
|
||||
} else {
|
||||
await this.certmanager.announceCertificate(certDomain);
|
||||
} else if (retrievedCertificate && retrievedCertificate.shouldBeRenewed) {
|
||||
await retrievedCertificate.delete();
|
||||
}
|
||||
|
||||
// lets make sure others get the same interest
|
||||
await this.certmanager.interestMap.addInterest(certDomainName);
|
||||
|
||||
|
||||
/* Place new order */
|
||||
const order = await this.client.createOrder({
|
||||
identifiers: [
|
||||
{ type: 'dns', value: certDomain },
|
||||
{ type: 'dns', value: `*.${certDomain}` }
|
||||
{ type: 'dns', value: certDomainName },
|
||||
{ type: 'dns', value: `*.${certDomainName}` }
|
||||
]
|
||||
});
|
||||
|
||||
@ -176,7 +144,7 @@ export class SmartAcme {
|
||||
|
||||
for (const authz of authorizations) {
|
||||
console.log(authz);
|
||||
const domainDnsName: string = `_acme-challenge.${authz.identifier.value}`;
|
||||
const fullHostName: string = `_acme-challenge.${authz.identifier.value}`;
|
||||
const dnsChallenge: string = authz.challenges.find(challengeArg => {
|
||||
return challengeArg.type === 'dns-01';
|
||||
});
|
||||
@ -185,8 +153,11 @@ export class SmartAcme {
|
||||
|
||||
try {
|
||||
/* Satisfy challenge */
|
||||
await this.setChallenge(domainDnsName, keyAuthorization);
|
||||
await this.smartdns.checkUntilAvailable(domainDnsName, 'TXT', keyAuthorization, 100, 5000);
|
||||
await this.setChallenge({
|
||||
hostName: fullHostName,
|
||||
challenge: keyAuthorization
|
||||
});
|
||||
await this.smartdns.checkUntilAvailable(fullHostName, 'TXT', keyAuthorization, 100, 5000);
|
||||
console.log('Cool down an extra 60 second for region availability');
|
||||
await plugins.smartdelay.delayFor(60000);
|
||||
|
||||
@ -201,7 +172,10 @@ export class SmartAcme {
|
||||
} finally {
|
||||
/* Clean up challenge response */
|
||||
try {
|
||||
await this.removeChallenge(domainDnsName);
|
||||
await this.removeChallenge({
|
||||
hostName: fullHostName,
|
||||
challenge: keyAuthorization
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
@ -210,8 +184,8 @@ export class SmartAcme {
|
||||
|
||||
/* Finalize order */
|
||||
const [key, csr] = await plugins.acme.forge.createCsr({
|
||||
commonName: `*.${certDomain}`,
|
||||
altNames: [certDomain]
|
||||
commonName: `*.${certDomainName}`,
|
||||
altNames: [certDomainName]
|
||||
});
|
||||
|
||||
await this.client.finalizeOrder(order, csr);
|
||||
@ -221,14 +195,19 @@ export class SmartAcme {
|
||||
|
||||
await this.certmanager.storeCertificate({
|
||||
id: plugins.smartunique.shortId(),
|
||||
domainName: certDomain,
|
||||
domainName: certDomainName,
|
||||
privateKey: key.toString(),
|
||||
publicKey: cert.toString(),
|
||||
csr: csr.toString(),
|
||||
created: Date.now()
|
||||
created: Date.now(),
|
||||
validUntil:
|
||||
Date.now() +
|
||||
plugins.smarttime.getMilliSecondsFromUnits({
|
||||
days: 90
|
||||
})
|
||||
});
|
||||
|
||||
const newCertificate = await this.certmanager.retrieveCertificate(certDomain);
|
||||
const newCertificate = await this.certmanager.retrieveCertificate(certDomainName);
|
||||
return newCertificate;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,14 @@ export {
|
||||
smarttime
|
||||
};
|
||||
|
||||
// thirs party scope
|
||||
// @tsclass scope
|
||||
import * as tsclass from '@tsclass/tsclass';
|
||||
|
||||
export {
|
||||
tsclass
|
||||
}
|
||||
|
||||
// third party scope
|
||||
import * as acme from 'acme-client';
|
||||
|
||||
export { acme };
|
||||
|
Loading…
Reference in New Issue
Block a user