2018-12-17 16:37:19 +01:00
'use strict' ;
exports = module . exports = {
2020-12-29 12:43:53 -08:00
get ,
ack ,
getAllPaged ,
2018-12-17 17:35:19 +01:00
2020-12-29 12:43:53 -08:00
onEvent ,
appUpdatesAvailable ,
boxUpdateAvailable ,
2019-02-27 16:10:54 -08:00
2019-02-28 14:52:14 -08:00
// NOTE: if you add an alert, be sure to add title below
ALERT _BACKUP _CONFIG : 'backupConfig' ,
ALERT _DISK _SPACE : 'diskSpace' ,
ALERT _MAIL _STATUS : 'mailStatus' ,
ALERT _REBOOT : 'reboot' ,
2019-03-07 13:34:46 -08:00
ALERT _BOX _UPDATE : 'boxUpdate' ,
2019-02-28 14:52:14 -08:00
2019-03-02 19:23:39 -08:00
alert : alert ,
// exported for testing
_add : add
2018-12-17 16:37:19 +01:00
} ;
2020-12-29 12:43:53 -08:00
let apps = require ( './apps.js' ) ,
assert = require ( 'assert' ) ,
2018-12-17 17:35:19 +01:00
async = require ( 'async' ) ,
2019-10-11 19:31:03 -07:00
auditSource = require ( './auditsource.js' ) ,
2019-10-22 12:59:26 -07:00
BoxError = require ( './boxerror.js' ) ,
2019-08-03 13:59:11 -07:00
changelog = require ( './changelog.js' ) ,
2020-12-29 12:43:53 -08:00
constants = require ( './constants.js' ) ,
2018-12-17 16:37:19 +01:00
debug = require ( 'debug' ) ( 'box:notifications' ) ,
2019-02-27 16:10:54 -08:00
eventlog = require ( './eventlog.js' ) ,
2018-12-17 17:35:19 +01:00
mailer = require ( './mailer.js' ) ,
2018-12-17 16:37:19 +01:00
notificationdb = require ( './notificationdb.js' ) ,
2019-07-26 10:49:29 -07:00
settings = require ( './settings.js' ) ,
2019-10-22 12:59:26 -07:00
users = require ( './users.js' ) ;
2018-12-17 16:37:19 +01:00
2019-02-28 14:59:33 -08:00
function add ( userId , eventId , title , message , callback ) {
2018-12-17 16:37:19 +01:00
assert . strictEqual ( typeof userId , 'string' ) ;
2019-02-06 16:18:12 +01:00
assert ( typeof eventId === 'string' || eventId === null ) ;
2018-12-17 16:37:19 +01:00
assert . strictEqual ( typeof title , 'string' ) ;
assert . strictEqual ( typeof message , 'string' ) ;
2018-12-17 17:40:53 +01:00
assert . strictEqual ( typeof callback , 'function' ) ;
2018-12-17 16:37:19 +01:00
2019-02-28 14:59:33 -08:00
debug ( 'add: ' , userId , title ) ;
2018-12-17 16:37:19 +01:00
notificationdb . add ( {
userId : userId ,
2019-01-19 13:22:29 +01:00
eventId : eventId ,
2018-12-17 16:37:19 +01:00
title : title ,
2019-03-04 20:44:41 -08:00
message : message ,
acknowledged : false
2018-12-17 16:37:19 +01:00
} , function ( error , result ) {
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( error ) ;
2018-12-17 16:37:19 +01:00
callback ( null , { id : result } ) ;
} ) ;
}
function get ( id , callback ) {
assert . strictEqual ( typeof id , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
notificationdb . get ( id , function ( error , result ) {
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( error ) ;
2018-12-17 16:37:19 +01:00
callback ( null , result ) ;
} ) ;
}
function ack ( id , callback ) {
assert . strictEqual ( typeof id , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
notificationdb . update ( id , { acknowledged : true } , function ( error ) {
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( error ) ;
2018-12-17 16:37:19 +01:00
callback ( null ) ;
} ) ;
}
// if acknowledged === null we return all, otherwise yes or no based on acknowledged as a boolean
2019-01-04 17:13:52 +01:00
function getAllPaged ( userId , acknowledged , page , perPage , callback ) {
2018-12-17 16:37:19 +01:00
assert . strictEqual ( typeof userId , 'string' ) ;
assert ( acknowledged === null || typeof acknowledged === 'boolean' ) ;
assert . strictEqual ( typeof page , 'number' ) ;
assert . strictEqual ( typeof perPage , 'number' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
notificationdb . listByUserIdPaged ( userId , page , perPage , function ( error , result ) {
2019-10-24 20:31:45 -07:00
if ( error ) return callback ( error ) ;
2018-12-17 16:37:19 +01:00
if ( acknowledged === null ) return callback ( null , result ) ;
callback ( null , result . filter ( function ( r ) { return r . acknowledged === acknowledged ; } ) ) ;
} ) ;
}
2018-12-17 17:35:19 +01:00
2019-01-07 14:56:43 +01:00
// Calls iterator with (admin, callback)
2020-12-21 17:51:48 -08:00
function forEachAdmin ( options , iterator , callback ) {
assert ( Array . isArray ( options . skip ) ) ;
2019-01-07 14:56:43 +01:00
assert . strictEqual ( typeof iterator , 'function' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2020-02-21 12:17:06 -08:00
users . getAdmins ( function ( error , result ) {
if ( error && error . reason === BoxError . NOT _FOUND ) return callback ( ) ;
2019-10-24 20:31:45 -07:00
if ( error ) return callback ( error ) ;
2019-01-17 13:36:54 +01:00
// filter out users we want to skip (like the user who did the action or the user the action was performed on)
2020-12-21 17:51:48 -08:00
result = result . filter ( function ( r ) { return options . skip . indexOf ( r . id ) === - 1 ; } ) ;
2019-01-17 13:36:54 +01:00
2019-01-07 14:56:43 +01:00
async . each ( result , iterator , callback ) ;
} ) ;
}
2019-03-01 15:14:35 -08:00
function userAdded ( performedBy , eventId , user , callback ) {
2019-01-17 13:36:54 +01:00
assert . strictEqual ( typeof performedBy , 'string' ) ;
2019-01-19 13:22:29 +01:00
assert . strictEqual ( typeof eventId , 'string' ) ;
2018-12-17 17:35:19 +01:00
assert . strictEqual ( typeof user , 'object' ) ;
2019-03-01 15:14:35 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2018-12-17 17:35:19 +01:00
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ performedBy , user . id ] } , function ( admin , done ) {
2019-08-03 10:21:41 -07:00
add ( admin . id , eventId , ` User ' ${ user . displayName } ' added ` , ` User ' ${ user . username || user . email || user . fallbackEmail } ' was added. ` , done ) ;
2019-03-01 15:14:35 -08:00
} , callback ) ;
2018-12-17 17:35:19 +01:00
}
2019-01-07 12:57:57 +01:00
2019-03-01 15:14:35 -08:00
function userRemoved ( performedBy , eventId , user , callback ) {
2019-01-17 13:36:54 +01:00
assert . strictEqual ( typeof performedBy , 'string' ) ;
2019-01-19 13:22:29 +01:00
assert . strictEqual ( typeof eventId , 'string' ) ;
2019-01-10 12:00:04 +01:00
assert . strictEqual ( typeof user , 'object' ) ;
2019-03-01 15:14:35 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2019-01-10 12:00:04 +01:00
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ performedBy , user . id ] } , function ( admin , done ) {
2019-08-03 10:21:41 -07:00
add ( admin . id , eventId , ` User ' ${ user . displayName } ' removed ` , ` User ' ${ user . username || user . email || user . fallbackEmail } ' was removed. ` , done ) ;
2019-03-01 15:14:35 -08:00
} , callback ) ;
2019-01-10 12:00:04 +01:00
}
2020-02-21 12:17:06 -08:00
function roleChanged ( performedBy , eventId , user , callback ) {
2019-01-17 13:36:54 +01:00
assert . strictEqual ( typeof performedBy , 'string' ) ;
2019-01-10 12:00:04 +01:00
assert . strictEqual ( typeof user , 'object' ) ;
2019-03-01 15:14:35 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2019-01-10 12:00:04 +01:00
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ performedBy , user . id ] } , function ( admin , done ) {
2020-03-07 19:12:39 -08:00
add ( admin . id , eventId , ` User ' ${ user . displayName } 's role changed ` , ` User ' ${ user . username || user . email || user . fallbackEmail } ' now has the role ${ user . role } . ` , done ) ;
2019-03-01 15:14:35 -08:00
} , callback ) ;
2019-01-10 12:00:04 +01:00
}
2019-03-06 11:54:37 -08:00
function oomEvent ( eventId , app , addon , containerId , event , callback ) {
2019-01-19 13:22:29 +01:00
assert . strictEqual ( typeof eventId , 'string' ) ;
2019-03-06 11:54:37 -08:00
assert . strictEqual ( typeof app , 'object' ) ;
assert . strictEqual ( typeof addon , 'object' ) ;
assert . strictEqual ( typeof containerId , 'string' ) ;
2019-03-01 15:14:35 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2019-01-07 12:57:57 +01:00
2021-01-02 11:07:44 -08:00
assert ( app || addon ) ;
let title , message ;
2019-03-06 11:54:37 -08:00
if ( app ) {
2020-09-03 13:26:51 -07:00
title = ` The application at ${ app . fqdn } ran out of memory. ` ;
2021-01-02 11:07:44 -08:00
message = ` The application has been restarted automatically. If you see this notification often, consider increasing the [memory limit]( ${ settings . adminOrigin ( ) } /#/app/ ${ app . id } /resources) ` ;
2019-03-06 11:54:37 -08:00
} else if ( addon ) {
title = ` The ${ addon . name } service ran out of memory ` ;
2021-01-02 11:07:44 -08:00
message = ` The service has been restarted automatically. If you see this notification often, consider increasing the [memory limit]( ${ settings . adminOrigin ( ) } /#/services) ` ;
2019-03-06 11:54:37 -08:00
}
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
2021-01-02 11:07:44 -08:00
mailer . oomEvent ( admin . email , app , addon , containerId , event ) ;
2019-01-08 14:20:08 +01:00
2019-03-06 11:54:37 -08:00
add ( admin . id , eventId , title , message , done ) ;
2019-03-01 15:14:35 -08:00
} , callback ) ;
2019-01-07 12:57:57 +01:00
}
2019-01-07 13:01:27 +01:00
2019-03-01 15:14:35 -08:00
function appUp ( eventId , app , callback ) {
2019-02-11 12:32:02 -08:00
assert . strictEqual ( typeof eventId , 'string' ) ;
assert . strictEqual ( typeof app , 'object' ) ;
2019-03-01 15:14:35 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2019-02-11 12:32:02 -08:00
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
2019-02-11 12:32:02 -08:00
mailer . appUp ( admin . email , app ) ;
2020-09-03 13:26:51 -07:00
add ( admin . id , eventId , ` App ${ app . fqdn } is back online ` , ` The application installed at ${ app . fqdn } is back online. ` , done ) ;
2019-03-01 15:14:35 -08:00
} , callback ) ;
2019-02-11 12:32:02 -08:00
}
2019-03-01 15:14:35 -08:00
function appDied ( eventId , app , callback ) {
2019-01-19 13:22:29 +01:00
assert . strictEqual ( typeof eventId , 'string' ) ;
2019-01-07 13:01:27 +01:00
assert . strictEqual ( typeof app , 'object' ) ;
2019-03-01 15:14:35 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2019-01-07 13:01:27 +01:00
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , callback ) {
2019-01-10 12:00:04 +01:00
mailer . appDied ( admin . email , app ) ;
2020-09-03 13:26:51 -07:00
add ( admin . id , eventId , ` App ${ app . fqdn } is down ` , ` The application installed at ${ app . fqdn } is not responding. ` , callback ) ;
2019-03-01 15:14:35 -08:00
} , callback ) ;
2019-01-07 13:01:27 +01:00
}
2019-01-10 13:57:47 +01:00
2019-05-07 12:04:43 +02:00
function appUpdated ( eventId , app , callback ) {
assert . strictEqual ( typeof eventId , 'string' ) ;
assert . strictEqual ( typeof app , 'object' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2020-09-03 13:26:51 -07:00
if ( ! app . appStoreId ) return callback ( ) ; // skip notification of dev apps
2019-08-02 20:56:25 -07:00
const tmp = app . manifest . description . match ( /<upstream>(.*)<\/upstream>/i ) ;
const upstreamVersion = ( tmp && tmp [ 1 ] ) ? tmp [ 1 ] : '' ;
const title = upstreamVersion ? ` ${ app . manifest . title } at ${ app . fqdn } updated to ${ upstreamVersion } (package version ${ app . manifest . version } ) `
: ` ${ app . manifest . title } at ${ app . fqdn } updated to package version ${ app . manifest . version } ` ;
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
2020-09-03 13:26:51 -07:00
add ( admin . id , eventId , title , ` The application installed at https:// ${ app . fqdn } was updated. \n \n Changelog: \n ${ app . manifest . changelog } \n ` , function ( error ) {
2019-05-07 14:22:51 +02:00
if ( error ) return callback ( error ) ;
mailer . appUpdated ( admin . email , app , function ( error ) {
2020-08-02 11:43:18 -07:00
if ( error ) debug ( 'appUpdated: Failed to send app updated email' , error ) ; // non fatal
2019-05-07 14:22:51 +02:00
done ( ) ;
} ) ;
} ) ;
2019-05-07 12:04:43 +02:00
} , callback ) ;
}
2020-12-29 12:43:53 -08:00
function boxUpdateAvailable ( updateInfo , callback ) {
assert . strictEqual ( typeof updateInfo , 'object' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
settings . getAutoupdatePattern ( function ( error , result ) {
if ( error ) return callback ( error ) ;
if ( result !== constants . AUTOUPDATE _PATTERN _NEVER ) return callback ( ) ;
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
mailer . boxUpdateAvailable ( admin . email , updateInfo , done ) ;
} , callback ) ;
} ) ;
}
function appUpdatesAvailable ( appUpdates , callback ) {
assert . strictEqual ( typeof appUpdates , 'object' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
settings . getAutoupdatePattern ( function ( error , result ) {
if ( error ) return callback ( error ) ;
// if we are auto updating, then just consider apps that cannot be auto updated
if ( result !== constants . AUTOUPDATE _PATTERN _NEVER ) appUpdates = appUpdates . filter ( update => ! apps . canAutoupdateApp ( update . app , update . updateInfo ) ) ;
if ( appUpdates . length === 0 ) return callback ( ) ;
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
mailer . appUpdatesAvailable ( admin . email , appUpdates , done ) ;
} , callback ) ;
} ) ;
}
2019-10-14 09:30:20 -07:00
function boxUpdated ( eventId , oldVersion , newVersion , callback ) {
assert . strictEqual ( typeof eventId , 'string' ) ;
2019-08-03 13:59:11 -07:00
assert . strictEqual ( typeof oldVersion , 'string' ) ;
assert . strictEqual ( typeof newVersion , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
const changes = changelog . getChanges ( newVersion ) ;
const changelogMarkdown = changes . map ( ( m ) => ` * ${ m } \n ` ) . join ( '' ) ;
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
2019-10-14 09:30:20 -07:00
add ( admin . id , eventId , ` Cloudron updated to v ${ newVersion } ` , ` Cloudron was updated from v ${ oldVersion } to v ${ newVersion } . \n \n Changelog: \n ${ changelogMarkdown } \n ` , done ) ;
} , callback ) ;
}
function boxUpdateError ( eventId , errorMessage , callback ) {
assert . strictEqual ( typeof eventId , 'string' ) ;
assert . strictEqual ( typeof errorMessage , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , done ) {
2019-10-14 09:30:20 -07:00
mailer . boxUpdateError ( admin . email , errorMessage ) ;
2020-08-15 10:07:05 -07:00
add ( admin . id , eventId , 'Cloudron update failed' , ` Failed to update Cloudron: ${ errorMessage } . ` , done ) ;
2019-08-03 13:59:11 -07:00
} , callback ) ;
}
2019-03-04 14:50:56 -08:00
function certificateRenewalError ( eventId , vhost , errorMessage , callback ) {
assert . strictEqual ( typeof eventId , 'string' ) ;
assert . strictEqual ( typeof vhost , 'string' ) ;
assert . strictEqual ( typeof errorMessage , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , callback ) {
2019-03-10 15:53:20 -07:00
mailer . certificateRenewalError ( admin . email , vhost , errorMessage ) ;
2019-03-04 14:50:56 -08:00
add ( admin . id , eventId , ` Certificate renewal of ${ vhost } failed ` , ` Failed to new certs of ${ vhost } : ${ errorMessage } . Renewal will be retried in 12 hours ` , callback ) ;
} , callback ) ;
}
2019-03-04 17:52:31 -08:00
function backupFailed ( eventId , taskId , errorMessage , callback ) {
2019-03-04 15:00:23 -08:00
assert . strictEqual ( typeof eventId , 'string' ) ;
2019-03-04 17:52:31 -08:00
assert . strictEqual ( typeof taskId , 'string' ) ;
2019-03-04 15:00:23 -08:00
assert . strictEqual ( typeof errorMessage , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , callback ) {
2019-07-26 10:49:29 -07:00
mailer . backupFailed ( admin . email , errorMessage , ` ${ settings . adminOrigin ( ) } /logs.html?taskId= ${ taskId } ` ) ;
2020-08-15 10:07:05 -07:00
add ( admin . id , eventId , 'Backup failed' , ` Backup failed: ${ errorMessage } . Logs are available [here](/logs.html?taskId= ${ taskId } ). ` , callback ) ;
2019-03-04 15:00:23 -08:00
} , callback ) ;
}
2019-04-30 16:26:16 +02:00
function alert ( id , title , message , callback ) {
assert . strictEqual ( typeof id , 'string' ) ;
2019-02-28 14:52:14 -08:00
assert . strictEqual ( typeof title , 'string' ) ;
2019-02-06 15:47:31 +01:00
assert . strictEqual ( typeof message , 'string' ) ;
2019-02-28 14:52:14 -08:00
assert . strictEqual ( typeof callback , 'function' ) ;
2019-02-06 15:47:31 +01:00
2019-03-04 20:58:27 -08:00
const acknowledged = ! message ;
2020-12-14 16:07:09 -08:00
debug ( ` alert: id= ${ id } title= ${ title } ack= ${ acknowledged } ` ) ;
2019-02-06 15:47:31 +01:00
2020-12-21 17:51:48 -08:00
forEachAdmin ( { skip : [ ] } , function ( admin , callback ) {
2019-04-30 16:26:16 +02:00
const data = {
userId : admin . id ,
eventId : null ,
title : title ,
message : message ,
acknowledged : acknowledged ,
creationTime : new Date ( )
} ;
2019-02-06 14:58:45 -08:00
2019-04-30 16:26:16 +02:00
notificationdb . getByUserIdAndTitle ( admin . id , title , function ( error , result ) {
2019-10-24 11:13:48 -07:00
if ( error && error . reason !== BoxError . NOT _FOUND ) return callback ( error ) ;
2019-03-04 20:58:27 -08:00
2019-04-30 16:26:16 +02:00
if ( ! result && acknowledged ) return callback ( ) ; // do not add acked alerts
2019-03-04 20:58:27 -08:00
2019-04-30 16:26:16 +02:00
let updateFunc = ! result ? notificationdb . add . bind ( null , data ) : notificationdb . update . bind ( null , result . id , data ) ;
2019-03-04 20:58:27 -08:00
2019-04-30 16:26:16 +02:00
updateFunc ( function ( error ) {
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( error ) ;
2019-03-04 20:58:27 -08:00
2019-04-30 16:26:16 +02:00
callback ( null ) ;
} ) ;
2019-03-04 20:58:27 -08:00
} ) ;
2019-02-06 15:47:31 +01:00
} , function ( error ) {
2020-08-02 11:43:18 -07:00
if ( error ) debug ( 'alert: error notifying' , error ) ;
2019-02-28 14:52:14 -08:00
2019-03-04 20:21:41 -08:00
callback ( ) ;
} ) ;
2019-02-06 15:47:31 +01:00
}
2019-02-27 16:10:54 -08:00
function onEvent ( id , action , source , data , callback ) {
assert . strictEqual ( typeof id , 'string' ) ;
assert . strictEqual ( typeof action , 'string' ) ;
assert . strictEqual ( typeof source , 'object' ) ;
assert . strictEqual ( typeof data , 'object' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2019-08-29 23:07:55 +02:00
// external ldap syncer does not generate notifications - FIXME username might be an issue here
2019-10-11 19:31:03 -07:00
if ( source . username === auditSource . EXTERNAL _LDAP _TASK . username ) return callback ( ) ;
2019-08-29 23:07:55 +02:00
2019-03-01 15:14:35 -08:00
switch ( action ) {
2019-03-25 14:02:23 -07:00
case eventlog . ACTION _USER _ADD :
return userAdded ( source . userId , id , data . user , callback ) ;
case eventlog . ACTION _USER _REMOVE :
return userRemoved ( source . userId , id , data . user , callback ) ;
case eventlog . ACTION _USER _UPDATE :
2020-02-21 12:17:06 -08:00
if ( ! data . roleChanged ) return callback ( ) ;
return roleChanged ( source . userId , id , data . user , callback ) ;
2019-03-25 14:02:23 -07:00
case eventlog . ACTION _APP _OOM :
return oomEvent ( id , data . app , data . addon , data . containerId , data . event , callback ) ;
case eventlog . ACTION _APP _DOWN :
return appDied ( id , data . app , callback ) ;
case eventlog . ACTION _APP _UP :
return appUp ( id , data . app , callback ) ;
2019-05-07 12:04:43 +02:00
case eventlog . ACTION _APP _UPDATE _FINISH :
return appUpdated ( id , data . app , callback ) ;
2019-03-04 14:50:56 -08:00
case eventlog . ACTION _CERTIFICATE _RENEWAL :
case eventlog . ACTION _CERTIFICATE _NEW :
2019-03-25 14:02:23 -07:00
if ( ! data . errorMessage ) return callback ( ) ;
return certificateRenewalError ( id , data . domain , data . errorMessage , callback ) ;
2019-03-04 14:50:56 -08:00
2019-03-25 14:02:23 -07:00
case eventlog . ACTION _BACKUP _FINISH :
2019-10-11 19:35:21 -07:00
if ( ! data . errorMessage ) return callback ( ) ;
if ( source . username !== auditSource . CRON . username && ! data . timedOut ) return callback ( ) ; // manual stop by user
return backupFailed ( id , data . taskId , data . errorMessage , callback ) ; // only notify for automated backups or timedout
2019-03-04 15:00:23 -08:00
2019-08-03 13:59:11 -07:00
case eventlog . ACTION _UPDATE _FINISH :
2019-10-14 09:30:20 -07:00
if ( ! data . errorMessage ) return boxUpdated ( id , data . oldVersion , data . newVersion , callback ) ;
if ( data . timedOut ) return boxUpdateError ( id , data . errorMessage , callback ) ;
return callback ( ) ;
2019-08-03 13:59:11 -07:00
2019-03-25 14:02:23 -07:00
default :
return callback ( ) ;
2019-02-27 16:10:54 -08:00
}
}