fix: certificate expiration not detected if happened while running
Massimo Melina committed
Nov 6, 2023 at 00:41 UTC
98b7861457914d2a6485e7b243f6cb1ae848d683
2 files changed
+35
-4
src/cross.ts
+21
@@ -339,3 +339,24 @@ export async function promiseBestEffort<T>(promises: Promise<T>[]) {
339
const res = await Promise.allSettled(promises)
340
return res.filter(x => x.status === 'fulfilled').map((x: any) => x.value as T)
341
}
342
+
343
+export function runAt(ts: number, cb: Callback) {
344
+ let cancel = false
345
+ let t: any
346
+ setTimeout(async () => {
347
+ if (missing() < 0) return
348
+ const max = 0x7FFFFFFF
349
+ while (!cancel && missing() > max)
350
+ await wait(max)
351
+ if (cancel) return
352
+ t = setTimeout(cb, missing())
353
+
354
+ function missing() {
355
+ return ts - Date.now()
356
+ }
357
+ })
358
+ return () => {
359
+ cancel = true
360
+ clearTimeout(t)
361
+ }
362
+}
\ No newline at end of file
src/listen.ts
+14
-4
@@ -8,7 +8,7 @@ import { watchLoad } from './watchLoad'
8
import { networkInterfaces } from 'os';
9
import { newConnection } from './connections'
10
import open from 'open'
11
-import { debounceAsync, ipForUrl, objSameKeys, onlyTruthy, wait, waitFor } from './misc'
11
+import { debounceAsync, ipForUrl, objSameKeys, onlyTruthy, runAt, wait, waitFor } from './misc'
12
import { ADMIN_URI, argv, DEV, IS_WINDOWS } from './const'
13
import findProcess from 'find-process'
14
import { anyAccountCanLoginAdmin } from './adminApis'
@@ -96,9 +96,19 @@ const considerHttps = debounceAsync(async () => {
96
if (cn)
97
console.log("certificate loaded for", cn)
98
const now = new Date()
99
- httpsSrv.error = new Date(cert.validFrom) > now ? "certificate not valid yet"
100
- : new Date(cert.validTo) < now ? "certificate expired"
101
- : undefined
99
+ const from = new Date(cert.validFrom)
100
+ const to = new Date(cert.validTo)
101
+ updateError() // error will change at from and to dates of the certificate
102
+ const cancelTo = runAt(to.getTime(), updateError)
103
+ const cancelFrom = runAt(from.getTime(), updateError)
104
+ httpsSrv.on('close', () => {
105
+ cancelTo()
106
+ cancelFrom()
107
+ })
108
+ function updateError() {
109
+ if (!httpsSrv) return
110
+ httpsSrv.error = from > now ? "certificate not valid yet" : to < now ? "certificate expired" : undefined
111
+ }
112
113
const namesForOutput: any = { cert: 'certificate', private_key: 'private key' }
114
const missing = httpsNeeds.find(x => !x.get())?.key()