@ -365,8 +365,8 @@ class Monitor extends BeanModel {
tlsInfo = await this . updateTlsInfo ( tlsInfoObject ) ;
tlsInfo = await this . updateTlsInfo ( tlsInfoObject ) ;
if ( ! this . getIgnoreTls ( ) && this . isEnabledExpiryNotification ( ) ) {
if ( ! this . getIgnoreTls ( ) && this . isEnabledExpiryNotification ( ) ) {
log . debug ( "monitor" , ` [ ${ this . name } ] call sendCertNotification ` ) ;
log . debug ( "monitor" , ` [ ${ this . name } ] call checkCertExpiryNotifications ` ) ;
await this . sendCertNotification ( tlsInfoObject ) ;
await this . checkCertExpiryNotifications ( tlsInfoObject ) ;
}
}
} catch ( e ) {
} catch ( e ) {
@ -1212,13 +1212,19 @@ class Monitor extends BeanModel {
}
}
/ * *
/ * *
* Send notification about a certificate
* checks certificate chain for expiring certificates
* @ param { Object } tlsInfoObject Information about certificate
* @ param { Object } tlsInfoObject Information about certificate
* /
* /
async sendCertNotification ( tlsInfoObject ) {
async checkCertExpiryNotifications ( tlsInfoObject ) {
if ( tlsInfoObject && tlsInfoObject . certInfo && tlsInfoObject . certInfo . daysRemaining ) {
if ( tlsInfoObject && tlsInfoObject . certInfo && tlsInfoObject . certInfo . daysRemaining ) {
const notificationList = await Monitor . getNotificationList ( this ) ;
const notificationList = await Monitor . getNotificationList ( this ) ;
if ( ! notificationList . length > 0 ) {
// fail fast. If no notification is set, all the following checks can be skipped.
log . debug ( "monitor" , "No notification, no need to send cert notification" ) ;
return ;
}
let notifyDays = await setting ( "tlsExpiryNotifyDays" ) ;
let notifyDays = await setting ( "tlsExpiryNotifyDays" ) ;
if ( notifyDays == null || ! Array . isArray ( notifyDays ) ) {
if ( notifyDays == null || ! Array . isArray ( notifyDays ) ) {
// Reset Default
// Reset Default
@ -1226,10 +1232,19 @@ class Monitor extends BeanModel {
notifyDays = [ 7 , 14 , 21 ] ;
notifyDays = [ 7 , 14 , 21 ] ;
}
}
if ( notifyDays != null && Array . isArray ( notifyDays ) ) {
if ( Array . isArray ( notifyDays ) ) {
for ( const day of notifyDays ) {
for ( const targetDays of notifyDays ) {
log . debug ( "monitor" , "call sendCertNotificationByTargetDays" , day ) ;
let certInfo = tlsInfoObject . certInfo ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , day , notificationList ) ;
while ( certInfo ) {
let subjectCN = certInfo . subject [ "CN" ] ;
if ( certInfo . daysRemaining > targetDays ) {
log . debug ( "monitor" , ` No need to send cert notification for ${ certInfo . certType } certificate " ${ subjectCN } " ( ${ certInfo . daysRemaining } days valid) on ${ targetDays } deadline. ` ) ;
} else {
log . debug ( "monitor" , ` call sendCertNotificationByTargetDays for ${ targetDays } deadline on certificate ${ subjectCN } . ` ) ;
await this . sendCertNotificationByTargetDays ( subjectCN , certInfo . certType , certInfo . daysRemaining , targetDays , notificationList ) ;
}
certInfo = certInfo . issuerCertificate ;
}
}
}
}
}
}
}
@ -1238,55 +1253,47 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Send a certificate notification when certificate expires in less
* Send a certificate notification when certificate expires in less
* than target days
* than target days
* @ param { number } daysRemaining Number of days remaining on certifcate
* @ param { string } certCN Common Name attribute from the certificate subject
* @ param { string } certType certificate type
* @ param { number } daysRemaining Number of days remaining on certificate
* @ param { number } targetDays Number of days to alert after
* @ param { number } targetDays Number of days to alert after
* @ param { LooseObject < any > [ ] } notificationList List of notification providers
* @ param { LooseObject < any > [ ] } notificationList List of notification providers
* @ returns { Promise < void > }
* @ returns { Promise < void > }
* /
* /
async sendCertNotificationByTargetDays ( daysRemaining, targetDays , notificationList ) {
async sendCertNotificationByTargetDays ( certCN, certType , daysRemaining, targetDays , notificationList ) {
if ( daysRemaining > targetDays ) {
let row = await R . getRow ( "SELECT * FROM notification_sent_history WHERE type = ? AND monitor_id = ? AND days <= ?" , [
log . debug ( "monitor" , ` No need to send cert notification. ${ daysRemaining } > ${ targetDays } ` ) ;
"certificate" ,
this . id ,
targetDays ,
] ) ;
// Sent already, no need to send again
if ( row ) {
log . debug ( "monitor" , "Sent already, no need to send again" ) ;
return ;
return ;
}
}
if ( notificationList . length > 0 ) {
let sent = false ;
log . debug ( "monitor" , "Send certificate notification" ) ;
let row = await R . getRow ( "SELECT * FROM notification_sent_history WHERE type = ? AND monitor_id = ? AND days <= ?" , [
for ( let notification of notificationList ) {
try {
log . debug ( "monitor" , "Sending to " + notification . name ) ;
await Notification . send ( JSON . parse ( notification . config ) , ` [ ${ this . name } ][ ${ this . url } ] ${ certType } certificate ${ certCN } will be expired in ${ daysRemaining } days ` ) ;
sent = true ;
} catch ( e ) {
log . error ( "monitor" , "Cannot send cert notification to " + notification . name ) ;
log . error ( "monitor" , e ) ;
}
}
if ( sent ) {
await R . exec ( "INSERT INTO notification_sent_history (type, monitor_id, days) VALUES(?, ?, ?)" , [
"certificate" ,
"certificate" ,
this . id ,
this . id ,
targetDays ,
targetDays ,
] ) ;
] ) ;
// Sent already, no need to send again
if ( row ) {
log . debug ( "monitor" , "Sent already, no need to send again" ) ;
return ;
}
let sent = false ;
log . debug ( "monitor" , "Send certificate notification" ) ;
for ( let notification of notificationList ) {
try {
log . debug ( "monitor" , "Sending to " + notification . name ) ;
await Notification . send ( JSON . parse ( notification . config ) , ` [ ${ this . name } ][ ${ this . url } ] Certificate will expire in ${ daysRemaining } days ` ) ;
sent = true ;
} catch ( e ) {
log . error ( "monitor" , "Cannot send cert notification to " + notification . name ) ;
log . error ( "monitor" , e ) ;
}
}
if ( sent ) {
await R . exec ( "INSERT INTO notification_sent_history (type, monitor_id, days) VALUES(?, ?, ?)" , [
"certificate" ,
this . id ,
targetDays ,
] ) ;
}
} else {
log . debug ( "monitor" , "No notification, no need to send cert notification" ) ;
}
}
}
}