@samitouri / QOSami-HFS / commits / e8f14448

acme: avoid overlapping manual and automatic certificate generation

Massimo Melina committed Sep 22, 2023 at 15:28 UTC e8f1444839d62d2b37e8bd90b84457253176f1be
1 file changed +9 -31
src/api.net.ts
+9 -31
@@ -245,7 +245,7 @@ const apis: ApiHandlers = {
245 export const acme_domain = defineConfig<string>('acme_domain', '')
246 export const acme_email = defineConfig<string>('acme_email', '')
247
248 -export async function makeCert(domain: string, email?: string) {
248 +export const makeCert = debounceAsync(async (domain: string, email?: string) => {
249 if (!domain) return new ApiError(HTTP_BAD_REQUEST, 'bad params')
250 const res = await generateSSLCert(domain, email)
251 const CERT_FILE = 'acme.cert'
@@ -254,33 +254,13 @@ export async function makeCert(domain: string, email?: string) {
254 await fs.writeFile(KEY_FILE, res.key)
255 cert.set(CERT_FILE) // update config
256 privateKey.set(KEY_FILE)
257 -}
258 -
259 -export const renewAcme = {
260 - timer: null,
261 - reset() {
262 - if (this.timer !== null)
263 - clearTimeout(this.timer)
264 - this.timer = null
265 - },
266 - set() {
267 - if (this.timer !== null) {
268 - setTimeout(this.set.bind(this), 5_000);
269 - } else {
270 - this.reset()
271 - setImmediate(() => repeat(DAY, renewCert)
272 - .then(v => ((this.timer as any) = v)))
273 - }
274 - }
275 -}
257 +}, 0)
258
259 defineConfig('acme_renew', false) // handle config changes
278 -events.once('https ready', () => renewAcme.set())
279 -/**
280 - * checks if the cert is near expiration date.
281 - * if so renews it
282 - */
283 -async function renewCert() {
260 +events.once('https ready', () => repeat(HOUR, renewCert))
261 +
262 +// checks if the cert is near expiration date, and if so renews it
263 +const renewCert = debounceAsync(async () => {
264 const acmeLog = (...args: any[]) => console.log('[acme-renew]:', ...args)
265 const now = new Date()
266 const cert = getCertObject()
@@ -288,11 +268,9 @@ async function renewCert() {
268 const validTo = new Date(cert.validTo)
269 const isValid = now > new Date(cert.validFrom) && now < validTo &&
270 validTo.getTime() - now.getTime() >= 30 * DAY // it's not expiring in a month
291 - if (isValid) return acmeLog("cert is valid")
271 + if (isValid) return acmeLog("certificate is good")
272 await makeCert(acme_domain.get(), acme_email.get())
293 - .catch(e => {
294 - acmeLog("error renewing cert:", e.toString())
295 - })
296 -}
273 + .catch(e => acmeLog("error: ", e.toString()))
274 +}, 0, { retain: DAY, retainFailure: HOUR })
275
276 export default apis
\ No newline at end of file