1,339 bytes · the TypeScript implementation · view raw
import { type CertExpiry } from"./monitor_cert_expiry_types.ts";
/** * RFC 5280 makes validity inclusive of notAfter, so a certificate is expired * only after that second, not at it. Thresholds compare whole days left with * the day counts: fewer than N days (secondsLeft < N * 86400) is exactly * floor(secondsLeft / 86400) < N, with no multiplication to overflow. */exportfunction certExpiry(notAfter: number, now: number, warnDays: number, criticalDays: number): CertExpiry {
if (!Number.isSafeInteger(notAfter) || !Number.isSafeInteger(now)) {
thrownew RangeError(`notAfter and now must be whole seconds, received ${notAfter} and ${now}`);
}
if (!Number.isSafeInteger(criticalDays) || criticalDays < 0) {
thrownew RangeError(`criticalDays must be a whole number 0 or more, received ${criticalDays}`);
}
if (!Number.isSafeInteger(warnDays) || warnDays < criticalDays) {
thrownew RangeError(`warnDays must be a whole number at least criticalDays (${criticalDays}), received ${warnDays}`);
}
if (now > notAfter) return { state: "expired", secondsLeft: 0, daysLeft: 0 };
const secondsLeft = notAfter - now;
const daysLeft = Math.floor(secondsLeft / 86400);
const state = daysLeft < criticalDays ? "critical" : daysLeft < warnDays ? "warning" : "ok";
return { state, secondsLeft, daysLeft };
}