@ -1,21 +1,25 @@ 
			
		
	
		
		
			
				
					
					const  https  =  require ( 'https' ) ; const  https  =  require ( "https" ) ;  
			
				
				
			
		
	
		
		
	
		
		
			
				
					const  dayjs  =  require ( "dayjs" ) ; const  dayjs  =  require ( "dayjs" ) ;  
			
		
	
		
		
			
				
					
					const  utc  =  require ( 'dayjs/plugin/utc' ) const  utc  =  require ( "dayjs/plugin/utc" )  
			
				
				
			
		
	
		
		
			
				
					
					var timezone  =  require ( 'dayjs/plugin/timezone' ) let timezone  =  require ( "dayjs/plugin/timezone" )  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					dayjs . extend ( utc ) 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  { debug ,  UP ,  DOWN ,  PENDING }  =  require ( "../../src/util" ) ; const  {  
			
				
				
			
		
	
		
		
			
				
					
					const  { tcping ,  ping ,  checkCertificate }  =  require ( "../util-server" ) ;     debug ,  UP ,  DOWN ,  PENDING ,  
			
				
				
			
		
	
		
		
			
				
					
					const  { R }  =  require ( "redbean-node" ) ; }  =  require ( "../../src/util" ) ;  
			
				
				
			
		
	
		
		
			
				
					
					const  { BeanModel }  =  require ( "redbean-node/dist/bean-model" ) ; const  {  
			
				
				
			
		
	
		
		
			
				
					
					const  { Notification }  =  require ( "../notification" )     tcping ,  ping ,  checkCertificate ,  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					}  =  require ( "../util-server" ) ;  
			
		
	
		
		
			
				
					const  {  R  }  =  require ( "redbean-node" ) ;  
			
		
	
		
		
			
				
					const  {  BeanModel  }  =  require ( "redbean-node/dist/bean-model" ) ;  
			
		
	
		
		
			
				
					const  {  Notification  }  =  require ( "../notification" )  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					//  Use Custom agent to disable session reuse
 //  Use Custom agent to disable session reuse
  
			
		
	
		
		
			
				
					//  https://github.com/nodejs/node/issues/3940
 //  https://github.com/nodejs/node/issues/3940
  
			
		
	
		
		
			
				
					const  customAgent  =  new  https . Agent ( { const  customAgent  =  new  https . Agent ( {  
			
		
	
		
		
			
				
					
					    maxCachedSessions :  0     maxCachedSessions :  0 ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					} ) ; } ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					/ * * / * *  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -30,7 +34,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					        let  notificationIDList  =  { } ;         let  notificationIDList  =  { } ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					        let  list  =  await  R . find ( "monitor_notification" ,  " monitor_id = ? " ,  [         let  list  =  await  R . find ( "monitor_notification" ,  " monitor_id = ? " ,  [  
			
		
	
		
		
			
				
					
					            this . id             this . id ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					        ] )         ] )  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					        for  ( let  bean  of  list )  {         for  ( let  bean  of  list )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -49,7 +53,9 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					            type :  this . type ,             type :  this . type ,  
			
		
	
		
		
			
				
					            interval :  this . interval ,             interval :  this . interval ,  
			
		
	
		
		
			
				
					            keyword :  this . keyword ,             keyword :  this . keyword ,  
			
		
	
		
		
			
				
					
					            notificationIDList             ignoreTls :  Boolean ( this . ignoreTls ) ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					            upsideDown :  Boolean ( this . upsideDown ) ,  
			
		
	
		
		
			
				
					            notificationIDList ,  
			
		
	
		
		
			
				
					        } ;         } ;  
			
		
	
		
		
			
				
					    }     }  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -63,7 +69,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            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 ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                ] )                 ] )  
			
		
	
		
		
			
				
					            }             }  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -76,7 +82,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 ;  
			
		
	
		
		
			
				
					            }             }  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -85,7 +91,9 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					                if  ( this . type  ===  "http"  ||  this . type  ===  "keyword" )  {                 if  ( this . type  ===  "http"  ||  this . type  ===  "keyword" )  {  
			
		
	
		
		
			
				
					                    let  startTime  =  dayjs ( ) . valueOf ( ) ;                     let  startTime  =  dayjs ( ) . valueOf ( ) ;  
			
		
	
		
		
			
				
					                    let  res  =  await  axios . get ( this . url ,  {                     let  res  =  await  axios . get ( this . url ,  {  
			
		
	
		
		
			
				
					
					                        headers :  {  "User-Agent" :  "Uptime-Kuma"  } ,                         headers :  {  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            "User-Agent" :  "Uptime-Kuma" ,  
			
		
	
		
		
			
				
					                        } ,  
			
		
	
		
		
			
				
					                        httpsAgent :  customAgent ,                         httpsAgent :  customAgent ,  
			
		
	
		
		
			
				
					                    } ) ;                     } ) ;  
			
		
	
		
		
			
				
					                    bean . msg  =  ` ${ res . status }  -  ${ res . statusText } `                     bean . msg  =  ` ${ res . status }  -  ${ res . statusText } `  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -124,7 +132,6 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    }                     }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                }  else  if  ( this . type  ===  "port" )  {                 }  else  if  ( this . type  ===  "port" )  {  
			
		
	
		
		
			
				
					                    bean . ping  =  await  tcping ( this . hostname ,  this . port ) ;                     bean . ping  =  await  tcping ( this . hostname ,  this . port ) ;  
			
		
	
		
		
			
				
					                    bean . msg  =  ""                     bean . msg  =  ""  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -168,8 +175,8 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                // Send only if the first beat is DOWN
                 // Send only if the first beat is DOWN
  
			
		
	
		
		
			
				
					                if  ( ! isFirstBeat  ||  bean . status  ===  DOWN )  {                 if  ( ! isFirstBeat  ||  bean . status  ===  DOWN )  {  
			
		
	
		
		
			
				
					
					                    let  notificationList  =  await  R . getAll ( ` SELECT notification.* FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id  ` ,  [                     let  notificationList  =  await  R . getAll ( " SELECT notification.* FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id " ,  [  
			
				
				
			
		
	
		
		
			
				
					
					                        this . id                         this . id ,  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					                    ] )                     ] )  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    let  text ;                     let  text ;  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -181,7 +188,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    let  msg  =  ` [ ${ this . name } ] [ ${ text } ]  ${ bean . msg } ` ;                     let  msg  =  ` [ ${ this . name } ] [ ${ text } ]  ${ bean . msg } ` ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					                    for ( let  notification  of  notificationList )  {                     for   ( let  notification  of  notificationList )  {  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                        try  {                         try  {  
			
		
	
		
		
			
				
					                            await  Notification . send ( JSON . parse ( notification . config ) ,  msg ,  await  this . toJSON ( ) ,  bean . toJSON ( ) )                             await  Notification . send ( JSON . parse ( notification . config ) ,  msg ,  await  this . toJSON ( ) ,  bean . toJSON ( ) )  
			
		
	
		
		
			
				
					                        }  catch  ( e )  {                         }  catch  ( e )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -194,7 +201,6 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					                bean . important  =  false ;                 bean . important  =  false ;  
			
		
	
		
		
			
				
					            }             }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            if  ( bean . status  ===  UP )  {             if  ( bean . status  ===  UP )  {  
			
		
	
		
		
			
				
					                console . info ( ` Monitor # ${ this . id }  ' ${ this . name } ': Successful Response:  ${ bean . ping }  ms | Interval:  ${ this . interval }  seconds | Type:  ${ this . type } ` )                 console . info ( ` Monitor # ${ this . id }  ' ${ this . name } ': Successful Response:  ${ bean . ping }  ms | Interval:  ${ this . interval }  seconds | Type:  ${ this . type } ` )  
			
		
	
		
		
			
				
					            }  else  if  ( bean . status  ===  PENDING )  {             }  else  if  ( bean . status  ===  PENDING )  {  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -242,7 +248,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					     * /      * /  
			
		
	
		
		
			
				
					    async  updateTlsInfo ( checkCertificateResult )  {     async  updateTlsInfo ( checkCertificateResult )  {  
			
		
	
		
		
			
				
					        let  tls_info_bean  =  await  R . findOne ( "monitor_tls_info" ,  "monitor_id = ?" ,  [         let  tls_info_bean  =  await  R . findOne ( "monitor_tls_info" ,  "monitor_id = ?" ,  [  
			
		
	
		
		
			
				
					
					            this . id             this . id ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					        ] ) ;         ] ) ;  
			
		
	
		
		
			
				
					        if  ( tls_info_bean  ==  null )  {         if  ( tls_info_bean  ==  null )  {  
			
		
	
		
		
			
				
					            tls_info_bean  =  R . dispense ( "monitor_tls_info" ) ;             tls_info_bean  =  R . dispense ( "monitor_tls_info" ) ;  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -271,7 +277,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					            AND  ping  IS  NOT  NULL             AND  ping  IS  NOT  NULL  
			
		
	
		
		
			
				
					            AND  monitor_id  =  ?  ` , [
             AND  monitor_id  =  ?  ` , [
  
			
		
	
		
		
			
				
					            - duration ,             - duration ,  
			
		
	
		
		
			
				
					
					            monitorID             monitorID ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					        ] ) ) ;         ] ) ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					        io . to ( userID ) . emit ( "avgPing" ,  monitorID ,  avgPing ) ;         io . to ( userID ) . emit ( "avgPing" ,  monitorID ,  avgPing ) ;  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -279,7 +285,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    static  async  sendCertInfo ( io ,  monitorID ,  userID )  {     static  async  sendCertInfo ( io ,  monitorID ,  userID )  {  
			
		
	
		
		
			
				
					        let  tls_info  =  await  R . findOne ( "monitor_tls_info" ,  "monitor_id = ?" ,  [         let  tls_info  =  await  R . findOne ( "monitor_tls_info" ,  "monitor_id = ?" ,  [  
			
		
	
		
		
			
				
					
					            monitorID             monitorID ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					        ] ) ;         ] ) ;  
			
		
	
		
		
			
				
					        if  ( tls_info  !=  null )  {         if  ( tls_info  !=  null )  {  
			
		
	
		
		
			
				
					            io . to ( userID ) . emit ( "certInfo" ,  monitorID ,  tls_info . info_json ) ;             io . to ( userID ) . emit ( "certInfo" ,  monitorID ,  tls_info . info_json ) ;  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -301,7 +307,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					            WHERE  time  >  DATETIME ( 'now' ,  ?  ||  ' hours' )             WHERE  time  >  DATETIME ( 'now' ,  ?  ||  ' hours' )  
			
		
	
		
		
			
				
					            AND  monitor_id  =  ?  ` , [
             AND  monitor_id  =  ?  ` , [
  
			
		
	
		
		
			
				
					            - duration ,             - duration ,  
			
		
	
		
		
			
				
					
					            monitorID             monitorID ,  
			
				
				
			
		
	
		
		
	
		
		
			
				
					        ] ) ;         ] ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					        let  downtime  =  0 ;         let  downtime  =  0 ;  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -325,7 +331,7 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					                // Handle if heartbeat duration longer than the target duration
                 // Handle if heartbeat duration longer than the target duration
  
			
		
	
		
		
			
				
					                // e.g.   Heartbeat duration = 28hrs, but target duration = 24hrs
                 // e.g.   Heartbeat duration = 28hrs, but target duration = 24hrs
  
			
		
	
		
		
			
				
					                if  ( value  >  sec )  {                 if  ( value  >  sec )  {  
			
		
	
		
		
			
				
					
					                    let  trim  =  dayjs . utc ( ) . diff ( dayjs ( time ) ,  'second' ) ;                     let  trim  =  dayjs . utc ( ) . diff ( dayjs ( time ) ,  "second" ) ;  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    value  =  sec  -  trim ;                     value  =  sec  -  trim ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    if  ( value  <  0 )  {                     if  ( value  <  0 )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -346,8 +352,6 @@ class Monitor extends BeanModel { 
			
		
	
		
		
			
				
					            }             }  
			
		
	
		
		
			
				
					        }         }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					        io . to ( userID ) . emit ( "uptime" ,  monitorID ,  duration ,  uptime ) ;         io . to ( userID ) . emit ( "uptime" ,  monitorID ,  duration ,  uptime ) ;  
			
		
	
		
		
			
				
					    }     }  
			
		
	
		
		
			
				
					} }