#!/usr/bin/env node // Tests de l'alerte d'expiration des certificats (tools/certificats.mjs, 13/10/2026). // Releve reel du 13/10 ~05:15 : n8n expire le 12/10 15:52 UTC, openclaw le 13/10 20:29. import { certificatsAAlerter, PREAVIS_J } from '../../tools/certificats.mjs'; let echecs = 0; const ok = (id, cond, info = '') => { if (cond) console.log(`✅ ${id}`); else { echecs++; console.log(`❌ ${id} ${info}`); } }; const now = Date.parse('2026-10-13T03:15:00Z'); const L = (domaine, iso, noms = [domaine], erreur = null) => ({ domaine, expireMs: iso ? Date.parse(iso) : null, noms, erreur }); { const r = certificatsAAlerter([L('n8n.airtria.pro', '2026-10-12T15:52:00Z'), L('openclaw.airtria.pro', '2026-10-13T20:29:07Z')], now); const n = r.alertes.find((a) => a.domaine === 'n8n.airtria.pro'); const o = r.alertes.find((a) => a.domaine === 'openclaw.airtria.pro'); ok('releve-1310-n8n-expire', n && n.statut === 'expire' && /EXPIRE depuis le 12\/10\/2026/.test(n.texte), JSON.stringify(n)); ok('releve-1310-openclaw-bientot', o && o.statut === 'bientot' && o.jours_restants === 0, JSON.stringify(o)); ok('expire-avant-bientot', r.alertes[0].domaine === 'n8n.airtria.pro'); ok('prochaine-echeance-a-venir', r.prochaine?.domaine === 'openclaw.airtria.pro', JSON.stringify(r.prochaine)); ok('geste-dans-le-texte', /\.17/.test(r.texte) && /\.50/.test(r.texte), r.texte); } { const r = certificatsAAlerter([L('n8n.airtria.pro', '2027-01-10T00:00:00Z')], now); ok('valable-pas-d-alerte', r.alertes.length === 0 && r.prochaine.jours_restants > 80 && /valables/.test(r.texte), r.texte); } { // juste au preavis : 14 j pile -> pas d'alerte ; 13 j -> alerte const a = certificatsAAlerter([L('x.airtria.pro', new Date(now + PREAVIS_J * 86400000 + 3600000).toISOString())], now); const b = certificatsAAlerter([L('x.airtria.pro', new Date(now + (PREAVIS_J - 1) * 86400000 + 3600000).toISOString())], now); ok('preavis-borne', a.alertes.length === 0 && b.alertes.length === 1 && b.alertes[0].statut === 'bientot', JSON.stringify([a.alertes, b.alertes])); } { // import fait mais pas associe : le proxy sert son certificat par defaut (constate 13/10 pour airtria.fr) const r = certificatsAAlerter([L('n8n.airtria.pro', '2034-09-11T22:43:20Z', ['synology.com', 'email:product@synology.com'])], now); ok('mauvais-nom', r.alertes[0]?.statut === 'mauvais_nom' && /synology\.com/.test(r.alertes[0].texte), JSON.stringify(r.alertes)); } { const r = certificatsAAlerter([L('a.airtria.pro', '2027-01-10T00:00:00Z', ['*.airtria.pro'])], now); ok('joker-couvre', r.alertes.length === 0, JSON.stringify(r.alertes)); } { const r = certificatsAAlerter([L('n8n.airtria.pro', null, [], 'ECONNREFUSED')], now); ok('illisible', r.alertes[0]?.statut === 'illisible' && /ECONNREFUSED/.test(r.alertes[0].texte)); } console.log(echecs ? `\n${echecs} ECHEC(S)` : '\nCERTIFICATS OK'); process.exit(echecs ? 1 : 0);