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