@ -6,11 +6,12 @@ dayjs.extend(utc);
dayjs . extend ( timezone ) ;
dayjs . extend ( timezone ) ;
const axios = require ( "axios" ) ;
const axios = require ( "axios" ) ;
const { Prometheus } = require ( "../prometheus" ) ;
const { Prometheus } = require ( "../prometheus" ) ;
const { debu g, UP , DOWN , PENDING , flipStatus , TimeLogger } = require ( "../../src/util" ) ;
const { lo g, UP , DOWN , PENDING , flipStatus , TimeLogger } = require ( "../../src/util" ) ;
const { tcping , ping , dnsResolve , checkCertificate , checkStatusCode , getTotalClientInRoom , setting , errorLog } = require ( "../util-server" ) ;
const { tcping , ping , dnsResolve , checkCertificate , checkStatusCode , getTotalClientInRoom , setting , errorLog , mqttAsync } = require ( "../util-server" ) ;
const { R } = require ( "redbean-node" ) ;
const { R } = require ( "redbean-node" ) ;
const { BeanModel } = require ( "redbean-node/dist/bean-model" ) ;
const { BeanModel } = require ( "redbean-node/dist/bean-model" ) ;
const { Notification } = require ( "../notification" ) ;
const { Notification } = require ( "../notification" ) ;
const { Proxy } = require ( "../proxy" ) ;
const { demoMode } = require ( "../config" ) ;
const { demoMode } = require ( "../config" ) ;
const version = require ( "../../package.json" ) . version ;
const version = require ( "../../package.json" ) . version ;
const apicache = require ( "../modules/apicache" ) ;
const apicache = require ( "../modules/apicache" ) ;
@ -41,7 +42,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Return an object that ready to parse to JSON
* Return an object that ready to parse to JSON
* /
* /
async toJSON ( ) {
async toJSON ( includeSensitiveData = true ) {
let notificationIDList = { } ;
let notificationIDList = { } ;
@ -55,15 +56,11 @@ class Monitor extends BeanModel {
const tags = await this . getTags ( ) ;
const tags = await this . getTags ( ) ;
return {
let data = {
id : this . id ,
id : this . id ,
name : this . name ,
name : this . name ,
url : this . url ,
url : this . url ,
method : this . method ,
method : this . method ,
body : this . body ,
headers : this . headers ,
basic _auth _user : this . basic _auth _user ,
basic _auth _pass : this . basic _auth _pass ,
hostname : this . hostname ,
hostname : this . hostname ,
port : this . port ,
port : this . port ,
maxretries : this . maxretries ,
maxretries : this . maxretries ,
@ -73,6 +70,7 @@ class Monitor extends BeanModel {
interval : this . interval ,
interval : this . interval ,
retryInterval : this . retryInterval ,
retryInterval : this . retryInterval ,
keyword : this . keyword ,
keyword : this . keyword ,
expiryNotification : this . isEnabledExpiryNotification ( ) ,
ignoreTls : this . getIgnoreTls ( ) ,
ignoreTls : this . getIgnoreTls ( ) ,
upsideDown : this . isUpsideDown ( ) ,
upsideDown : this . isUpsideDown ( ) ,
maxredirects : this . maxredirects ,
maxredirects : this . maxredirects ,
@ -80,14 +78,31 @@ class Monitor extends BeanModel {
dns _resolve _type : this . dns _resolve _type ,
dns _resolve _type : this . dns _resolve _type ,
dns _resolve _server : this . dns _resolve _server ,
dns _resolve _server : this . dns _resolve _server ,
dns _last _result : this . dns _last _result ,
dns _last _result : this . dns _last _result ,
p ushToken: this . pushToken ,
p roxyId: this . proxy _id ,
notificationIDList ,
notificationIDList ,
tags : tags ,
tags : tags ,
mqttUsername : this . mqttUsername ,
mqttPassword : this . mqttPassword ,
mqttTopic : this . mqttTopic ,
mqttSuccessMessage : this . mqttSuccessMessage
} ;
} ;
if ( includeSensitiveData ) {
data = {
... data ,
headers : this . headers ,
body : this . body ,
basic _auth _user : this . basic _auth _user ,
basic _auth _pass : this . basic _auth _pass ,
pushToken : this . pushToken ,
} ;
}
return data ;
}
}
async getTags ( ) {
async getTags ( ) {
return await R . getAll ( "SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?" , [ this . id ] ) ;
return await R . getAll ( "SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?" , [ this . id ] ) ;
}
}
/ * *
/ * *
@ -99,6 +114,10 @@ class Monitor extends BeanModel {
return Buffer . from ( user + ":" + pass ) . toString ( "base64" ) ;
return Buffer . from ( user + ":" + pass ) . toString ( "base64" ) ;
}
}
isEnabledExpiryNotification ( ) {
return Boolean ( this . expiryNotification ) ;
}
/ * *
/ * *
* Parse to boolean
* Parse to boolean
* @ returns { boolean }
* @ returns { boolean }
@ -144,7 +163,7 @@ class Monitor extends BeanModel {
// undefined if not https
// undefined if not https
let tlsInfo = undefined ;
let tlsInfo = undefined ;
if ( ! previousBeat ) {
if ( ! previousBeat ) {
previousBeat = await R . findOne ( "heartbeat" , " monitor_id = ? ORDER BY time DESC" , [
previousBeat = await R . findOne ( "heartbeat" , " monitor_id = ? ORDER BY time DESC" , [
this . id ,
this . id ,
] ) ;
] ) ;
@ -162,7 +181,7 @@ class Monitor extends BeanModel {
}
}
// Duration
// Duration
if ( ! isFirstBeat ) {
if ( ! isFirstBeat ) {
bean . duration = dayjs ( bean . time ) . diff ( dayjs ( previousBeat . time ) , "second" ) ;
bean . duration = dayjs ( bean . time ) . diff ( dayjs ( previousBeat . time ) , "second" ) ;
} else {
} else {
bean . duration = 0 ;
bean . duration = 0 ;
@ -181,7 +200,12 @@ class Monitor extends BeanModel {
} ;
} ;
}
}
debug ( ` [ ${ this . name } ] Prepare Options for axios ` ) ;
const httpsAgentOptions = {
maxCachedSessions : 0 , // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized : ! this . getIgnoreTls ( ) ,
} ;
log . debug ( "monitor" , ` [ ${ this . name } ] Prepare Options for axios ` ) ;
const options = {
const options = {
url : this . url ,
url : this . url ,
@ -194,17 +218,33 @@ class Monitor extends BeanModel {
... ( this . headers ? JSON . parse ( this . headers ) : { } ) ,
... ( this . headers ? JSON . parse ( this . headers ) : { } ) ,
... ( basicAuthHeader ) ,
... ( basicAuthHeader ) ,
} ,
} ,
httpsAgent : new https . Agent ( {
maxCachedSessions : 0 , // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized : ! this . getIgnoreTls ( ) ,
} ) ,
maxRedirects : this . maxredirects ,
maxRedirects : this . maxredirects ,
validateStatus : ( status ) => {
validateStatus : ( status ) => {
return checkStatusCode ( status , this . getAcceptedStatuscodes ( ) ) ;
return checkStatusCode ( status , this . getAcceptedStatuscodes ( ) ) ;
} ,
} ,
} ;
} ;
debug ( ` [ ${ this . name } ] Axios Request ` ) ;
if ( this . proxy _id ) {
const proxy = await R . load ( "proxy" , this . proxy _id ) ;
if ( proxy && proxy . active ) {
const { httpAgent , httpsAgent } = Proxy . createAgents ( proxy , {
httpsAgentOptions : httpsAgentOptions ,
} ) ;
options . proxy = false ;
options . httpAgent = httpAgent ;
options . httpsAgent = httpsAgent ;
}
}
if ( ! options . httpsAgent ) {
options . httpsAgent = new https . Agent ( httpsAgentOptions ) ;
}
log . debug ( "monitor" , ` [ ${ this . name } ] Axios Options: ${ JSON . stringify ( options ) } ` ) ;
log . debug ( "monitor" , ` [ ${ this . name } ] Axios Request ` ) ;
let res = await axios . request ( options ) ;
let res = await axios . request ( options ) ;
bean . msg = ` ${ res . status } - ${ res . statusText } ` ;
bean . msg = ` ${ res . status } - ${ res . statusText } ` ;
bean . ping = dayjs ( ) . valueOf ( ) - startTime ;
bean . ping = dayjs ( ) . valueOf ( ) - startTime ;
@ -212,29 +252,30 @@ class Monitor extends BeanModel {
// Check certificate if https is used
// Check certificate if https is used
let certInfoStartTime = dayjs ( ) . valueOf ( ) ;
let certInfoStartTime = dayjs ( ) . valueOf ( ) ;
if ( this . getUrl ( ) ? . protocol === "https:" ) {
if ( this . getUrl ( ) ? . protocol === "https:" ) {
debug( ` [ ${ this . name } ] Check cert ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] Check cert ` ) ;
try {
try {
let tlsInfoObject = checkCertificate ( res ) ;
let tlsInfoObject = checkCertificate ( res ) ;
tlsInfo = await this . updateTlsInfo ( tlsInfoObject ) ;
tlsInfo = await this . updateTlsInfo ( tlsInfoObject ) ;
if ( ! this . getIgnoreTls ( ) ) {
if ( ! this . getIgnoreTls ( ) && this . isEnabledExpiryNotification ( ) ) {
debug( ` [ ${ this . name } ] call sendCertNotification ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] call sendCertNotification ` ) ;
await this . sendCertNotification ( tlsInfoObject ) ;
await this . sendCertNotification ( tlsInfoObject ) ;
}
}
} catch ( e ) {
} catch ( e ) {
if ( e . message !== "No TLS certificate in response" ) {
if ( e . message !== "No TLS certificate in response" ) {
console . error ( e . message ) ;
log . error ( "monitor" , "Caught error" ) ;
log . error ( "monitor" , e . message ) ;
}
}
}
}
}
}
if ( process . env . TIMELOGGER === "1" ) {
if ( process . env . TIMELOGGER === "1" ) {
debug( "Cert Info Query Time: " + ( dayjs ( ) . valueOf ( ) - certInfoStartTime ) + "ms" ) ;
log. debug( "monitor" , "Cert Info Query Time: " + ( dayjs ( ) . valueOf ( ) - certInfoStartTime ) + "ms" ) ;
}
}
if ( process . env . UPTIME _KUMA _LOG _RESPONSE _BODY _MONITOR _ID == this . id ) {
if ( process . env . UPTIME _KUMA _LOG _RESPONSE _BODY _MONITOR _ID == = this . id ) {
console. log ( res . data ) ;
log. info ( "monitor" , res . data ) ;
}
}
if ( this . type === "http" ) {
if ( this . type === "http" ) {
@ -273,24 +314,24 @@ class Monitor extends BeanModel {
let dnsRes = await dnsResolve ( this . hostname , this . dns _resolve _server , this . dns _resolve _type ) ;
let dnsRes = await dnsResolve ( this . hostname , this . dns _resolve _server , this . dns _resolve _type ) ;
bean . ping = dayjs ( ) . valueOf ( ) - startTime ;
bean . ping = dayjs ( ) . valueOf ( ) - startTime ;
if ( this . dns _resolve _type == "A" || this . dns _resolve _type == "AAAA" || this . dns _resolve _type == "TXT" ) {
if ( this . dns _resolve _type == = "A" || this . dns _resolve _type = == "AAAA" || this . dns _resolve _type = == "TXT" ) {
dnsMessage += "Records: " ;
dnsMessage += "Records: " ;
dnsMessage += dnsRes . join ( " | " ) ;
dnsMessage += dnsRes . join ( " | " ) ;
} else if ( this . dns _resolve _type == "CNAME" || this . dns _resolve _type == "PTR" ) {
} else if ( this . dns _resolve _type == = "CNAME" || this . dns _resolve _type = == "PTR" ) {
dnsMessage = dnsRes [ 0 ] ;
dnsMessage = dnsRes [ 0 ] ;
} else if ( this . dns _resolve _type == "CAA" ) {
} else if ( this . dns _resolve _type == = "CAA" ) {
dnsMessage = dnsRes [ 0 ] . issue ;
dnsMessage = dnsRes [ 0 ] . issue ;
} else if ( this . dns _resolve _type == "MX" ) {
} else if ( this . dns _resolve _type == = "MX" ) {
dnsRes . forEach ( record => {
dnsRes . forEach ( record => {
dnsMessage += ` Hostname: ${ record . exchange } - Priority: ${ record . priority } | ` ;
dnsMessage += ` Hostname: ${ record . exchange } - Priority: ${ record . priority } | ` ;
} ) ;
} ) ;
dnsMessage = dnsMessage . slice ( 0 , - 2 ) ;
dnsMessage = dnsMessage . slice ( 0 , - 2 ) ;
} else if ( this . dns _resolve _type == "NS" ) {
} else if ( this . dns _resolve _type == = "NS" ) {
dnsMessage += "Servers: " ;
dnsMessage += "Servers: " ;
dnsMessage += dnsRes . join ( " | " ) ;
dnsMessage += dnsRes . join ( " | " ) ;
} else if ( this . dns _resolve _type == "SOA" ) {
} else if ( this . dns _resolve _type == = "SOA" ) {
dnsMessage += ` NS-Name: ${ dnsRes . nsname } | Hostmaster: ${ dnsRes . hostmaster } | Serial: ${ dnsRes . serial } | Refresh: ${ dnsRes . refresh } | Retry: ${ dnsRes . retry } | Expire: ${ dnsRes . expire } | MinTTL: ${ dnsRes . minttl } ` ;
dnsMessage += ` NS-Name: ${ dnsRes . nsname } | Hostmaster: ${ dnsRes . hostmaster } | Serial: ${ dnsRes . serial } | Refresh: ${ dnsRes . refresh } | Retry: ${ dnsRes . retry } | Expire: ${ dnsRes . expire } | MinTTL: ${ dnsRes . minttl } ` ;
} else if ( this . dns _resolve _type == "SRV" ) {
} else if ( this . dns _resolve _type == = "SRV" ) {
dnsRes . forEach ( record => {
dnsRes . forEach ( record => {
dnsMessage += ` Name: ${ record . name } | Port: ${ record . port } | Priority: ${ record . priority } | Weight: ${ record . weight } | ` ;
dnsMessage += ` Name: ${ record . name } | Port: ${ record . port } | Priority: ${ record . priority } | Weight: ${ record . weight } | ` ;
} ) ;
} ) ;
@ -314,7 +355,7 @@ class Monitor extends BeanModel {
time
time
] ) ;
] ) ;
debug( "heartbeatCount" + heartbeatCount + " " + time ) ;
log. debug( "monitor" , "heartbeatCount" + heartbeatCount + " " + time ) ;
if ( heartbeatCount <= 0 ) {
if ( heartbeatCount <= 0 ) {
// Fix #922, since previous heartbeat could be inserted by api, it should get from database
// Fix #922, since previous heartbeat could be inserted by api, it should get from database
@ -345,7 +386,7 @@ class Monitor extends BeanModel {
} ,
} ,
httpsAgent : new https . Agent ( {
httpsAgent : new https . Agent ( {
maxCachedSessions : 0 , // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
maxCachedSessions : 0 , // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized : ! this . getIgnoreTls ( ) ,
rejectUnauthorized : ! this . getIgnoreTls ( ) ,
} ) ,
} ) ,
maxRedirects : this . maxredirects ,
maxRedirects : this . maxredirects ,
validateStatus : ( status ) => {
validateStatus : ( status ) => {
@ -367,7 +408,14 @@ class Monitor extends BeanModel {
} else {
} else {
throw new Error ( "Server not found on Steam" ) ;
throw new Error ( "Server not found on Steam" ) ;
}
}
} else if ( this . type === "mqtt" ) {
bean . msg = await mqttAsync ( this . hostname , this . mqttTopic , this . mqttSuccessMessage , {
port : this . port ,
username : this . mqttUsername ,
password : this . mqttPassword ,
interval : this . interval ,
} ) ;
bean . status = UP ;
} else {
} else {
bean . msg = "Unknown Monitor Type" ;
bean . msg = "Unknown Monitor Type" ;
bean . status = PENDING ;
bean . status = PENDING ;
@ -398,7 +446,7 @@ class Monitor extends BeanModel {
}
}
}
}
debug( ` [ ${ this . name } ] Check isImportant ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] Check isImportant ` ) ;
let isImportant = Monitor . isImportantBeat ( isFirstBeat , previousBeat ? . status , bean . status ) ;
let isImportant = Monitor . isImportantBeat ( isFirstBeat , previousBeat ? . status , bean . status ) ;
// Mark as important if status changed, ignore pending pings,
// Mark as important if status changed, ignore pending pings,
@ -406,11 +454,11 @@ class Monitor extends BeanModel {
if ( isImportant ) {
if ( isImportant ) {
bean . important = true ;
bean . important = true ;
debug( ` [ ${ this . name } ] sendNotification ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] sendNotification ` ) ;
await Monitor . sendNotification ( isFirstBeat , this , bean ) ;
await Monitor . sendNotification ( isFirstBeat , this , bean ) ;
// Clear Status Page Cache
// Clear Status Page Cache
debug( ` [ ${ this . name } ] apicache clear ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] apicache clear ` ) ;
apicache . clear ( ) ;
apicache . clear ( ) ;
} else {
} else {
@ -418,33 +466,33 @@ class Monitor extends BeanModel {
}
}
if ( bean . status === UP ) {
if ( bean . status === UP ) {
console. info ( ` Monitor # ${ this . id } ' ${ this . name } ': Successful Response: ${ bean . ping } ms | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
log. info ( "monitor" , ` Monitor # ${ this . id } ' ${ this . name } ': Successful Response: ${ bean . ping } ms | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
} else if ( bean . status === PENDING ) {
} else if ( bean . status === PENDING ) {
if ( this . retryInterval > 0 ) {
if ( this . retryInterval > 0 ) {
beatInterval = this . retryInterval ;
beatInterval = this . retryInterval ;
}
}
console. warn ( ` Monitor # ${ this . id } ' ${ this . name } ': Pending: ${ bean . msg } | Max retries: ${ this . maxretries } | Retry: ${ retries } | Retry Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
log. warn ( "monitor" , ` Monitor # ${ this . id } ' ${ this . name } ': Pending: ${ bean . msg } | Max retries: ${ this . maxretries } | Retry: ${ retries } | Retry Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
} else {
} else {
console. warn ( ` Monitor # ${ this . id } ' ${ this . name } ': Failing: ${ bean . msg } | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
log. warn ( "monitor" , ` Monitor # ${ this . id } ' ${ this . name } ': Failing: ${ bean . msg } | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
}
}
debug( ` [ ${ this . name } ] Send to socket ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] Send to socket ` ) ;
io . to ( this . user _id ) . emit ( "heartbeat" , bean . toJSON ( ) ) ;
io . to ( this . user _id ) . emit ( "heartbeat" , bean . toJSON ( ) ) ;
Monitor . sendStats ( io , this . id , this . user _id ) ;
Monitor . sendStats ( io , this . id , this . user _id ) ;
debug( ` [ ${ this . name } ] Store ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] Store ` ) ;
await R . store ( bean ) ;
await R . store ( bean ) ;
debug( ` [ ${ this . name } ] prometheus.update ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] prometheus.update ` ) ;
prometheus . update ( bean , tlsInfo ) ;
prometheus . update ( bean , tlsInfo ) ;
previousBeat = bean ;
previousBeat = bean ;
if ( ! this . isStop ) {
if ( ! this . isStop ) {
debug( ` [ ${ this . name } ] SetTimeout for next check. ` ) ;
log. debug( "monitor" , ` [ ${ this . name } ] SetTimeout for next check. ` ) ;
this . heartbeatInterval = setTimeout ( safeBeat , beatInterval * 1000 ) ;
this . heartbeatInterval = setTimeout ( safeBeat , beatInterval * 1000 ) ;
} else {
} else {
console. log ( ` [ ${ this . name } ] isStop = true, no next check. ` ) ;
log. info ( "monitor" , ` [ ${ this . name } ] isStop = true, no next check. ` ) ;
}
}
} ;
} ;
@ -455,10 +503,10 @@ class Monitor extends BeanModel {
} catch ( e ) {
} catch ( e ) {
console . trace ( e ) ;
console . trace ( e ) ;
errorLog ( e , false ) ;
errorLog ( e , false ) ;
console. error ( "Please report to https://github.com/louislam/uptime-kuma/issues" ) ;
log. error ( "monitor" , "Please report to https://github.com/louislam/uptime-kuma/issues" ) ;
if ( ! this . isStop ) {
if ( ! this . isStop ) {
console. log ( "Try to restart the monitor" ) ;
log. info ( "monitor" , "Try to restart the monitor" ) ;
this . heartbeatInterval = setTimeout ( safeBeat , this . interval * 1000 ) ;
this . heartbeatInterval = setTimeout ( safeBeat , this . interval * 1000 ) ;
}
}
}
}
@ -505,41 +553,41 @@ class Monitor extends BeanModel {
* @ returns { Promise < object > }
* @ returns { Promise < object > }
* /
* /
async updateTlsInfo ( checkCertificateResult ) {
async updateTlsInfo ( checkCertificateResult ) {
let tls _info _b ean = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
let tls InfoB ean = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
this . id ,
this . id ,
] ) ;
] ) ;
if ( tls _info _b ean == null ) {
if ( tls InfoB ean == null ) {
tls _info _b ean = R . dispense ( "monitor_tls_info" ) ;
tls InfoB ean = R . dispense ( "monitor_tls_info" ) ;
tls _info _b ean. monitor _id = this . id ;
tls InfoB ean. monitor _id = this . id ;
} else {
} else {
// Clear sent history if the cert changed.
// Clear sent history if the cert changed.
try {
try {
let oldCertInfo = JSON . parse ( tls _info _b ean. info _json ) ;
let oldCertInfo = JSON . parse ( tls InfoB ean. info _json ) ;
let isValidObjects = oldCertInfo && oldCertInfo . certInfo && checkCertificateResult && checkCertificateResult . certInfo ;
let isValidObjects = oldCertInfo && oldCertInfo . certInfo && checkCertificateResult && checkCertificateResult . certInfo ;
if ( isValidObjects ) {
if ( isValidObjects ) {
if ( oldCertInfo . certInfo . fingerprint256 !== checkCertificateResult . certInfo . fingerprint256 ) {
if ( oldCertInfo . certInfo . fingerprint256 !== checkCertificateResult . certInfo . fingerprint256 ) {
debug( "Resetting sent_history" ) ;
log. debug( "monitor" , "Resetting sent_history" ) ;
await R . exec ( "DELETE FROM notification_sent_history WHERE type = 'certificate' AND monitor_id = ?" , [
await R . exec ( "DELETE FROM notification_sent_history WHERE type = 'certificate' AND monitor_id = ?" , [
this . id
this . id
] ) ;
] ) ;
} else {
} else {
debug( "No need to reset sent_history" ) ;
log. debug( "monitor" , "No need to reset sent_history" ) ;
debug( oldCertInfo . certInfo . fingerprint256 ) ;
log. debug( "monitor" , oldCertInfo . certInfo . fingerprint256 ) ;
debug( checkCertificateResult . certInfo . fingerprint256 ) ;
log. debug( "monitor" , checkCertificateResult . certInfo . fingerprint256 ) ;
}
}
} else {
} else {
debug( "Not valid object" ) ;
log. debug( "monitor" , "Not valid object" ) ;
}
}
} catch ( e ) { }
} catch ( e ) { }
}
}
tls _info _b ean. info _json = JSON . stringify ( checkCertificateResult ) ;
tls InfoB ean. info _json = JSON . stringify ( checkCertificateResult ) ;
await R . store ( tls _info _b ean) ;
await R . store ( tls InfoB ean) ;
return checkCertificateResult ;
return checkCertificateResult ;
}
}
@ -553,7 +601,7 @@ class Monitor extends BeanModel {
await Monitor . sendUptime ( 24 * 30 , io , monitorID , userID ) ;
await Monitor . sendUptime ( 24 * 30 , io , monitorID , userID ) ;
await Monitor . sendCertInfo ( io , monitorID , userID ) ;
await Monitor . sendCertInfo ( io , monitorID , userID ) ;
} else {
} else {
debug( "No clients in the room, no need to send stats" ) ;
log. debug( "monitor" , "No clients in the room, no need to send stats" ) ;
}
}
}
}
@ -580,11 +628,11 @@ class Monitor extends BeanModel {
}
}
static async sendCertInfo ( io , monitorID , userID ) {
static async sendCertInfo ( io , monitorID , userID ) {
let tls _i nfo = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
let tls I nfo = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
monitorID ,
monitorID ,
] ) ;
] ) ;
if ( tls _i nfo != null ) {
if ( tls I nfo != null ) {
io . to ( userID ) . emit ( "certInfo" , monitorID , tls _i nfo. info _json ) ;
io . to ( userID ) . emit ( "certInfo" , monitorID , tls I nfo. info _json ) ;
}
}
}
}
@ -646,7 +694,7 @@ class Monitor extends BeanModel {
} else {
} else {
// Handle new monitor with only one beat, because the beat's duration = 0
// Handle new monitor with only one beat, because the beat's duration = 0
let status = parseInt ( await R . getCell ( "SELECT `status` FROM heartbeat WHERE monitor_id = ?" , [ monitorID ] ) ) ;
let status = parseInt ( await R . getCell ( "SELECT `status` FROM heartbeat WHERE monitor_id = ?" , [ monitorID ] ) ) ;
if ( status === UP ) {
if ( status === UP ) {
uptime = 1 ;
uptime = 1 ;
@ -698,10 +746,10 @@ class Monitor extends BeanModel {
for ( let notification of notificationList ) {
for ( let notification of notificationList ) {
try {
try {
await Notification . send ( JSON . parse ( notification . config ) , msg , await monitor . toJSON ( ) , bean . toJSON ( ) ) ;
await Notification . send ( JSON . parse ( notification . config ) , msg , await monitor . toJSON ( false ) , bean . toJSON ( ) ) ;
} catch ( e ) {
} catch ( e ) {
console. error ( "Cannot send notification to " + notification . name ) ;
log. error ( "monitor" , "Cannot send notification to " + notification . name ) ;
console. log ( e ) ;
log. error ( "monitor" , e ) ;
}
}
}
}
}
}
@ -718,7 +766,7 @@ class Monitor extends BeanModel {
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 ) ;
debug( "call sendCertNotificationByTargetDays" ) ;
log. debug( "monitor" , "call sendCertNotificationByTargetDays" ) ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , 21 , notificationList ) ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , 21 , notificationList ) ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , 14 , notificationList ) ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , 14 , notificationList ) ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , 7 , notificationList ) ;
await this . sendCertNotificationByTargetDays ( tlsInfoObject . certInfo . daysRemaining , 7 , notificationList ) ;
@ -728,7 +776,7 @@ class Monitor extends BeanModel {
async sendCertNotificationByTargetDays ( daysRemaining , targetDays , notificationList ) {
async sendCertNotificationByTargetDays ( daysRemaining , targetDays , notificationList ) {
if ( daysRemaining > targetDays ) {
if ( daysRemaining > targetDays ) {
debug( ` No need to send cert notification. ${ daysRemaining } > ${ targetDays } ` ) ;
log. debug( "monitor" , ` No need to send cert notification. ${ daysRemaining } > ${ targetDays } ` ) ;
return ;
return ;
}
}
@ -742,21 +790,21 @@ class Monitor extends BeanModel {
// Sent already, no need to send again
// Sent already, no need to send again
if ( row ) {
if ( row ) {
debug( "Sent already, no need to send again" ) ;
log. debug( "monitor" , "Sent already, no need to send again" ) ;
return ;
return ;
}
}
let sent = false ;
let sent = false ;
debug( "Send certificate notification" ) ;
log. debug( "monitor" , "Send certificate notification" ) ;
for ( let notification of notificationList ) {
for ( let notification of notificationList ) {
try {
try {
debug( "Sending to " + notification . name ) ;
log. debug( "monitor" , "Sending to " + notification . name ) ;
await Notification . send ( JSON . parse ( notification . config ) , ` [ ${ this . name } ][ ${ this . url } ] Certificate will be expired in ${ daysRemaining } days ` ) ;
await Notification . send ( JSON . parse ( notification . config ) , ` [ ${ this . name } ][ ${ this . url } ] Certificate will be expired in ${ daysRemaining } days ` ) ;
sent = true ;
sent = true ;
} catch ( e ) {
} catch ( e ) {
console. error ( "Cannot send cert notification to " + notification . name ) ;
log. error ( "monitor" , "Cannot send cert notification to " + notification . name ) ;
console. error ( e ) ;
log. error ( "monitor" , e ) ;
}
}
}
}
@ -768,7 +816,7 @@ class Monitor extends BeanModel {
] ) ;
] ) ;
}
}
} else {
} else {
debug( "No notification, no need to send cert notification" ) ;
log. debug( "monitor" , "No notification, no need to send cert notification" ) ;
}
}
}
}