2018-01-22 13:01:38 -08:00
'use strict' ;
angular . module ( 'Application' ) . controller ( 'AppsController' , [ '$scope' , '$location' , '$timeout' , '$interval' , 'Client' , 'ngTld' , 'AppStore' , function ( $scope , $location , $timeout , $interval , Client , ngTld , AppStore ) {
$scope . HOST _PORT _MIN = 1024 ;
$scope . HOST _PORT _MAX = 65535 ;
$scope . installedApps = Client . getInstalledApps ( ) ;
$scope . config = Client . getConfig ( ) ;
$scope . user = Client . getUserInfo ( ) ;
$scope . domains = [ ] ;
$scope . groups = [ ] ;
$scope . users = [ ] ;
$scope . backupConfig = { } ;
2018-08-28 12:07:55 -07:00
$scope . spacesSuffix = '' ;
2018-01-22 13:01:38 -08:00
$scope . appConfigure = {
busy : false ,
error : { } ,
app : { } ,
2018-09-04 12:10:21 -07:00
domain : null ,
2018-01-22 13:01:38 -08:00
location : '' ,
advancedVisible : false ,
portBindings : { } ,
portBindingsEnabled : { } ,
portBindingsInfo : { } ,
robotsTxt : '' ,
certificateFile : null ,
certificateFileName : '' ,
keyFile : null ,
keyFileName : '' ,
memoryLimit : 0 ,
memoryTicks : [ ] ,
2018-05-24 15:40:26 -07:00
mailboxName : '' ,
2018-01-22 13:01:38 -08:00
accessRestrictionOption : 'any' ,
accessRestriction : { users : [ ] , groups : [ ] } ,
xFrameOptions : '' ,
2019-01-15 11:13:41 -08:00
dataDir : null ,
2018-07-03 18:00:22 +02:00
alternateDomainEnabled : false ,
2018-09-25 11:26:10 -07:00
mailboxNameEnabled : false ,
2019-01-15 11:13:41 -08:00
dataDirEnabled : false ,
2018-06-29 16:38:40 +02:00
alternateSubdomain : '' ,
2018-09-04 12:10:21 -07:00
alternateDomain : null ,
2018-05-25 13:59:53 -07:00
ssoAuth : false ,
2018-01-22 13:01:38 -08:00
isAccessRestrictionValid : function ( ) {
var tmp = $scope . appConfigure . accessRestriction ;
return ! ! ( tmp . users . length || tmp . groups . length ) ;
} ,
show : function ( app ) {
$scope . reset ( ) ;
// fill relevant info from the app
$scope . appConfigure . app = app ;
2018-08-28 10:38:53 -07:00
if ( $scope . user . admin ) {
$scope . appConfigure . location = app . location ;
2018-08-28 18:55:13 -07:00
} else { // strip the trailing username in spaces mode
2018-08-28 12:07:55 -07:00
$scope . appConfigure . location = app . location === $scope . spacesSuffix ? '' : app . location . replace ( new RegExp ( '-' + $scope . spacesSuffix + '$' ) , '' ) ;
2018-08-28 10:38:53 -07:00
}
2018-01-22 13:01:38 -08:00
$scope . appConfigure . domain = $scope . domains . filter ( function ( d ) { return d . domain === app . domain ; } ) [ 0 ] ;
2018-08-13 08:38:47 -07:00
$scope . appConfigure . portBindingsInfo = angular . extend ( { } , app . manifest . tcpPorts , app . manifest . udpPorts ) ; // Portbinding map only for information
2018-01-22 13:01:38 -08:00
$scope . appConfigure . memoryLimit = app . memoryLimit || app . manifest . memoryLimit || ( 256 * 1024 * 1024 ) ;
$scope . appConfigure . xFrameOptions = app . xFrameOptions . indexOf ( 'ALLOW-FROM' ) === 0 ? app . xFrameOptions . split ( ' ' ) [ 1 ] : '' ;
2019-01-15 11:13:41 -08:00
$scope . appConfigure . dataDirEnabled = ! ! app . dataDir ;
$scope . appConfigure . dataDir = app . dataDir ;
2018-07-03 18:00:22 +02:00
$scope . appConfigure . alternateDomainEnabled = ! ! app . alternateDomains [ 0 ] ;
2018-06-29 16:38:40 +02:00
$scope . appConfigure . alternateSubdomain = app . alternateDomains [ 0 ] ? app . alternateDomains [ 0 ] . subdomain : '' ;
2018-09-04 12:10:21 -07:00
$scope . appConfigure . alternateDomain = app . alternateDomains [ 0 ] ? $scope . domains . filter ( function ( d ) { return d . domain === app . alternateDomains [ 0 ] . domain ; } ) [ 0 ] : $scope . appConfigure . domain ;
2018-01-22 13:01:38 -08:00
$scope . appConfigure . robotsTxt = app . robotsTxt ;
$scope . appConfigure . enableBackup = app . enableBackup ;
2018-12-07 09:04:06 -08:00
$scope . appConfigure . enableAutomaticUpdate = app . enableAutomaticUpdate ;
2018-09-25 11:26:10 -07:00
$scope . appConfigure . mailboxNameEnabled = app . mailboxName && ( app . mailboxName . match ( /\.app$/ ) === null ) ;
2018-05-24 15:40:26 -07:00
$scope . appConfigure . mailboxName = app . mailboxName || '' ;
2018-01-22 13:01:38 -08:00
2018-05-25 13:59:53 -07:00
$scope . appConfigure . ssoAuth = ( app . manifest . addons [ 'ldap' ] || app . manifest . addons [ 'oauth' ] ) && app . sso ;
2018-01-22 13:01:38 -08:00
// create ticks starting from manifest memory limit. the memory limit here is currently split into ram+swap (and thus *2 below)
// TODO: the *2 will overallocate since 4GB is max swap that cloudron itself allocates
$scope . appConfigure . memoryTicks = [ ] ;
var npow2 = Math . pow ( 2 , Math . ceil ( Math . log ( $scope . config . memory ) / Math . log ( 2 ) ) ) ;
for ( var i = 256 ; i <= ( npow2 * 2 / 1024 / 1024 ) ; i *= 2 ) {
if ( i >= ( app . manifest . memoryLimit / 1024 / 1024 || 0 ) ) $scope . appConfigure . memoryTicks . push ( i * 1024 * 1024 ) ;
}
if ( app . manifest . memoryLimit && $scope . appConfigure . memoryTicks [ 0 ] !== app . manifest . memoryLimit ) {
$scope . appConfigure . memoryTicks . unshift ( app . manifest . memoryLimit ) ;
}
$scope . appConfigure . accessRestrictionOption = app . accessRestriction ? 'groups' : 'any' ;
$scope . appConfigure . accessRestriction = { users : [ ] , groups : [ ] } ;
if ( app . accessRestriction ) {
var userSet = { } ;
app . accessRestriction . users . forEach ( function ( uid ) { userSet [ uid ] = true ; } ) ;
$scope . users . forEach ( function ( u ) { if ( userSet [ u . id ] === true ) $scope . appConfigure . accessRestriction . users . push ( u ) ; } ) ;
var groupSet = { } ;
app . accessRestriction . groups . forEach ( function ( gid ) { groupSet [ gid ] = true ; } ) ;
$scope . groups . forEach ( function ( g ) { if ( groupSet [ g . id ] === true ) $scope . appConfigure . accessRestriction . groups . push ( g ) ; } ) ;
}
// fill the portBinding structures. There might be holes in the app.portBindings, which signalizes a disabled port
for ( var env in $scope . appConfigure . portBindingsInfo ) {
if ( app . portBindings && app . portBindings [ env ] ) {
$scope . appConfigure . portBindings [ env ] = app . portBindings [ env ] ;
$scope . appConfigure . portBindingsEnabled [ env ] = true ;
} else {
$scope . appConfigure . portBindings [ env ] = $scope . appConfigure . portBindingsInfo [ env ] . defaultValue || 0 ;
$scope . appConfigure . portBindingsEnabled [ env ] = false ;
}
}
$ ( '#appConfigureModal' ) . modal ( 'show' ) ;
} ,
submit : function ( ) {
$scope . appConfigure . busy = true ;
$scope . appConfigure . error . other = null ;
$scope . appConfigure . error . location = null ;
$scope . appConfigure . error . xFrameOptions = null ;
2019-01-15 11:13:41 -08:00
$scope . appConfigure . error . dataDir = null ;
2018-06-29 16:38:40 +02:00
$scope . appConfigure . error . alternateDomains = null ;
2018-05-24 15:40:26 -07:00
$scope . appConfigure . error . mailboxName = null ;
2018-01-22 13:01:38 -08:00
// only use enabled ports from portBindings
var finalPortBindings = { } ;
for ( var env in $scope . appConfigure . portBindings ) {
if ( $scope . appConfigure . portBindingsEnabled [ env ] ) {
finalPortBindings [ env ] = $scope . appConfigure . portBindings [ env ] ;
}
}
var finalAccessRestriction = null ;
if ( $scope . appConfigure . accessRestrictionOption === 'groups' ) {
finalAccessRestriction = { users : [ ] , groups : [ ] } ;
finalAccessRestriction . users = $scope . appConfigure . accessRestriction . users . map ( function ( u ) { return u . id ; } ) ;
finalAccessRestriction . groups = $scope . appConfigure . accessRestriction . groups . map ( function ( g ) { return g . id ; } ) ;
}
var data = {
2018-02-08 09:44:35 +01:00
location : $scope . appConfigure . location ,
domain : $scope . appConfigure . domain . domain ,
2018-01-22 13:01:38 -08:00
portBindings : finalPortBindings ,
accessRestriction : finalAccessRestriction ,
cert : $scope . appConfigure . certificateFile ,
key : $scope . appConfigure . keyFile ,
xFrameOptions : $scope . appConfigure . xFrameOptions ? ( 'ALLOW-FROM ' + $scope . appConfigure . xFrameOptions ) : 'SAMEORIGIN' ,
memoryLimit : $scope . appConfigure . memoryLimit === $scope . appConfigure . memoryTicks [ 0 ] ? 0 : $scope . appConfigure . memoryLimit ,
robotsTxt : $scope . appConfigure . robotsTxt ,
2018-07-03 18:04:25 +02:00
enableBackup : $scope . appConfigure . enableBackup ,
2018-12-07 09:04:06 -08:00
enableAutomaticUpdate : $scope . appConfigure . enableAutomaticUpdate ,
2019-01-18 15:18:59 -08:00
alternateDomains : [ ] ,
dataDir : $scope . appConfigure . dataDirEnabled ? $scope . appConfigure . dataDir : ''
2018-01-22 13:01:38 -08:00
} ;
2018-06-29 16:38:40 +02:00
// The backend supports multiple alternateDomains, however we only have ui for one
2018-09-04 12:10:21 -07:00
if ( $scope . appConfigure . alternateDomainEnabled ) data . alternateDomains = [ { domain : $scope . appConfigure . alternateDomain . domain , subdomain : $scope . appConfigure . alternateSubdomain } ] ;
2018-06-29 16:38:40 +02:00
2018-09-25 11:26:10 -07:00
if ( $scope . appConfigure . mailboxNameEnabled ) {
data . mailboxName = $scope . appConfigure . mailboxName ;
2018-12-06 22:31:38 -08:00
// add mailbox automatically for convenience
if ( $scope . appConfigure . app . manifest . addons . recvmail ) {
Client . addMailbox ( data . domain , data . mailboxName , $scope . user . id , function ( error ) {
if ( error && error . statusCode !== 409 ) console . error ( error ) ; // it's fine if it already exists
} ) ;
}
2018-09-25 11:26:10 -07:00
} else { // setting to empty will reset to .app name
data . mailboxName = '' ;
}
2018-05-24 15:40:26 -07:00
2018-01-22 13:01:38 -08:00
Client . configureApp ( $scope . appConfigure . app . id , data , function ( error ) {
if ( error ) {
if ( error . statusCode === 409 && ( error . message . indexOf ( 'is reserved' ) !== - 1 || error . message . indexOf ( 'is already in use' ) !== - 1 ) ) {
$scope . appConfigure . error . port = error . message ;
2018-09-25 11:26:10 -07:00
} else if ( error . statusCode === 400 && error . message . indexOf ( 'mailbox' ) !== - 1 ) {
2018-05-24 20:15:08 -07:00
$scope . appConfigure . error . mailboxName = error . message ;
$scope . appConfigureForm . mailboxName . $setPristine ( ) ;
$ ( '#appConfigureMailboxNameInput' ) . focus ( ) ;
2018-01-22 13:01:38 -08:00
} else if ( error . statusCode === 409 ) {
2018-06-26 17:35:37 -07:00
$scope . appConfigure . error . location = error . message ;
2018-01-22 13:01:38 -08:00
$scope . appConfigureForm . location . $setPristine ( ) ;
$ ( '#appConfigureLocationInput' ) . focus ( ) ;
} else if ( error . statusCode === 400 && error . message . indexOf ( 'cert' ) !== - 1 ) {
$scope . appConfigure . error . cert = error . message ;
$scope . appConfigure . certificateFileName = '' ;
$scope . appConfigure . certificateFile = null ;
$scope . appConfigure . keyFileName = '' ;
$scope . appConfigure . keyFile = null ;
} else if ( error . statusCode === 400 && error . message . indexOf ( 'xFrameOptions' ) !== - 1 ) {
$scope . appConfigure . error . xFrameOptions = error . message ;
$scope . appConfigureForm . xFrameOptions . $setPristine ( ) ;
$ ( '#appConfigureXFrameOptionsInput' ) . focus ( ) ;
2018-06-29 16:38:40 +02:00
} else if ( error . statusCode === 400 && error . message . indexOf ( 'alternateDomains' ) !== - 1 ) {
$scope . appConfigure . error . alternateDomains = error . message ;
$scope . appConfigureForm . alternateDomains . $setPristine ( ) ;
$ ( '#appConfigureAlternateSubdomainInput' ) . focus ( ) ;
2019-01-15 11:13:41 -08:00
} else if ( error . statusCode === 400 && error . message . indexOf ( 'dataDir' ) !== - 1 ) {
$scope . appConfigure . error . dataDir = error . message ;
$scope . appConfigureForm . dataDir . $setPristine ( ) ;
$ ( '#appConfigureDataDirInput' ) . focus ( ) ;
2018-01-22 13:01:38 -08:00
} else {
$scope . appConfigure . error . other = error . message ;
}
$scope . appConfigure . busy = false ;
return ;
}
$scope . appConfigure . busy = false ;
2018-06-26 08:49:43 -07:00
Client . refreshAppCache ( $scope . appConfigure . app . id ) ; // reflect the new app state immediately
2018-01-22 13:01:38 -08:00
$ ( '#appConfigureModal' ) . modal ( 'hide' ) ;
$scope . reset ( ) ;
} ) ;
}
} ;
$scope . appUninstall = {
busy : false ,
error : { } ,
app : { } ,
password : ''
} ;
$scope . appRestore = {
busy : false ,
busyFetching : false ,
error : { } ,
app : { } ,
password : '' ,
backups : [ ] ,
selectedBackup : null ,
2018-05-28 00:47:53 -07:00
// from clone
location : '' ,
domain : null ,
portBindings : { } ,
portBindingsInfo : { } ,
portBindingsEnabled : { } ,
2018-05-28 10:00:12 -07:00
action : 'restore' ,
2018-01-22 13:01:38 -08:00
selectBackup : function ( backup ) {
$scope . appRestore . selectedBackup = backup ;
} ,
2018-05-23 20:36:54 -07:00
createBackup : function ( ) {
Client . backupApp ( $scope . appRestore . app . id , function ( error ) {
2018-05-29 22:05:18 +02:00
if ( error ) Client . error ( error ) ;
function waitForBackupFinish ( ) {
if ( $scope . appRestore . app . installationState === 'pending_backup' ) return $timeout ( waitForBackupFinish , 1000 ) ;
// we are done, refresh the backup list
Client . getAppBackups ( $scope . appRestore . app . id , function ( error , backups ) {
if ( error ) return Client . error ( error ) ;
$scope . appRestore . backups = backups ;
if ( backups . length ) $scope . appRestore . selectedBackup = backups [ 0 ] ; // pre-select first backup
} ) ;
2018-05-23 20:36:54 -07:00
}
2018-08-28 10:38:53 -07:00
// reflect the new app state immediately
2018-06-26 08:49:43 -07:00
Client . refreshAppCache ( $scope . appRestore . app . id , waitForBackupFinish ) ;
2018-05-23 20:36:54 -07:00
} ) ;
} ,
2018-05-28 00:47:53 -07:00
clone : function ( ) {
2018-05-29 22:53:51 +02:00
$scope . appRestore . busy = true ;
2018-05-28 00:47:53 -07:00
var data = {
location : $scope . appRestore . location ,
domain : $scope . appRestore . domain . domain ,
portBindings : $scope . appRestore . portBindings ,
backupId : $scope . appRestore . selectedBackup . id
} ;
2018-06-26 08:49:43 -07:00
Client . cloneApp ( $scope . appRestore . app . id , data , function ( error , clonedApp ) {
2018-05-29 22:53:51 +02:00
$scope . appRestore . busy = false ;
2018-05-28 00:47:53 -07:00
if ( error ) {
if ( error . statusCode === 409 && ( error . message . indexOf ( 'is reserved' ) !== - 1 || error . message . indexOf ( 'is already in use' ) !== - 1 ) ) {
$scope . appRestore . error . port = error . message ;
} else if ( error . statusCode === 409 ) {
$scope . appRestore . error . location = 'This name is already taken.' ;
$ ( '#appRestoreLocationInput' ) . focus ( ) ;
} else {
Client . error ( error ) ;
}
2018-08-06 00:41:06 -07:00
return ;
2018-05-28 00:47:53 -07:00
}
2018-08-06 00:41:06 -07:00
$ ( '#appRestoreModal' ) . modal ( 'hide' ) ;
2018-05-28 00:47:53 -07:00
2018-06-26 08:49:43 -07:00
Client . refreshAppCache ( clonedApp . id ) ; // reflect the new app state immediately
2018-05-28 00:47:53 -07:00
} ) ;
} ,
2018-01-22 13:01:38 -08:00
show : function ( app ) {
$scope . reset ( ) ;
$scope . appRestore . app = app ;
$scope . appRestore . busyFetching = true ;
2018-05-28 00:47:53 -07:00
$scope . appRestore . domain = $scope . domains . find ( function ( d ) { return app . domain === d . domain ; } ) ; // pre-select the app's domain
2018-08-13 08:38:47 -07:00
$scope . appRestore . portBindingsInfo = angular . extend ( { } , $scope . appRestore . app . manifest . tcpPorts , $scope . appRestore . app . manifest . udpPorts ) ; // Portbinding map only for information
2018-05-28 00:47:53 -07:00
// set default ports
2018-08-13 08:38:47 -07:00
for ( var env in $scope . appRestore . portBindingsInfo ) {
$scope . appRestore . portBindings [ env ] = $scope . appRestore . portBindingsInfo [ env ] . defaultValue || 0 ;
2018-05-28 00:47:53 -07:00
$scope . appRestore . portBindingsEnabled [ env ] = true ;
}
2018-05-28 10:00:12 -07:00
$scope . appRestore . action = 'restore' ;
2018-01-22 13:01:38 -08:00
$ ( '#appRestoreModal' ) . modal ( 'show' ) ;
Client . getAppBackups ( app . id , function ( error , backups ) {
if ( error ) {
Client . error ( error ) ;
} else {
$scope . appRestore . backups = backups ;
if ( backups . length ) $scope . appRestore . selectedBackup = backups [ 0 ] ; // pre-select first backup
$scope . appRestore . busyFetching = false ;
}
} ) ;
return false ; // prevent propagation and default
} ,
2018-05-23 20:36:54 -07:00
restore : function ( ) {
2018-01-22 13:01:38 -08:00
$scope . appRestore . busy = true ;
$scope . appRestore . error . password = null ;
Client . restoreApp ( $scope . appRestore . app . id , $scope . appRestore . selectedBackup . id , $scope . appRestore . password , function ( error ) {
2018-06-18 18:57:00 -07:00
if ( error && error . statusCode === 403 ) {
2018-01-22 13:01:38 -08:00
$scope . appRestore . password = '' ;
$scope . appRestore . error . password = true ;
$ ( '#appRestorePasswordInput' ) . focus ( ) ;
} else if ( error ) {
Client . error ( error ) ;
} else {
$ ( '#appRestoreModal' ) . modal ( 'hide' ) ;
}
$scope . appRestore . busy = false ;
2018-06-26 08:49:43 -07:00
Client . refreshAppCache ( $scope . appRestore . app . id ) ; // reflect the new app state immediately
2018-01-22 13:01:38 -08:00
} ) ;
}
} ;
$scope . appInfo = {
app : { } ,
message : ''
} ;
2018-06-14 15:46:55 +02:00
$scope . appPostInstallConfirm = {
app : { } ,
message : '' ,
confirmed : false ,
show : function ( app ) {
$scope . reset ( ) ;
$scope . appPostInstallConfirm . app = app ;
$scope . appPostInstallConfirm . message = app . manifest . postInstallMessage ;
$ ( '#appPostInstallConfirmModal' ) . modal ( 'show' ) ;
return false ; // prevent propagation and default
} ,
submit : function ( ) {
2018-06-15 13:39:30 +02:00
if ( ! $scope . appPostInstallConfirm . confirmed ) return ;
2018-06-14 15:46:55 +02:00
$scope . appPostInstallConfirm . app . pendingPostInstallConfirmation = false ;
delete localStorage [ 'confirmPostInstall_' + $scope . appPostInstallConfirm . app . id ] ;
$ ( '#appPostInstallConfirmModal' ) . modal ( 'hide' ) ;
}
} ;
2018-01-22 13:01:38 -08:00
$scope . appError = {
app : { }
} ;
$scope . appUpdate = {
busy : false ,
error : { } ,
app : { } ,
manifest : { } ,
portBindings : { }
} ;
$scope . reset = function ( ) {
// close all dialogs
$ ( '#appErrorModal' ) . modal ( 'hide' ) ;
$ ( '#appConfigureModal' ) . modal ( 'hide' ) ;
$ ( '#appRestoreModal' ) . modal ( 'hide' ) ;
$ ( '#appUpdateModal' ) . modal ( 'hide' ) ;
$ ( '#appInfoModal' ) . modal ( 'hide' ) ;
$ ( '#appUninstallModal' ) . modal ( 'hide' ) ;
2018-06-14 15:46:55 +02:00
$ ( '#appPostInstallConfirmModal' ) . modal ( 'hide' ) ;
2018-01-22 13:01:38 -08:00
// reset configure dialog
$scope . appConfigure . error = { } ;
$scope . appConfigure . app = { } ;
$scope . appConfigure . domain = null ;
$scope . appConfigure . location = '' ;
$scope . appConfigure . advancedVisible = false ;
$scope . appConfigure . portBindings = { } ; // This is the actual model holding the env:port pair
$scope . appConfigure . portBindingsEnabled = { } ; // This is the actual model holding the enabled/disabled flag
$scope . appConfigure . certificateFile = null ;
$scope . appConfigure . certificateFileName = '' ;
$scope . appConfigure . keyFile = null ;
$scope . appConfigure . keyFileName = '' ;
$scope . appConfigure . memoryLimit = 0 ;
$scope . appConfigure . memoryTicks = [ ] ;
$scope . appConfigure . accessRestrictionOption = 'any' ;
$scope . appConfigure . accessRestriction = { users : [ ] , groups : [ ] } ;
$scope . appConfigure . xFrameOptions = '' ;
2018-05-25 13:59:53 -07:00
$scope . appConfigure . ssoAuth = false ;
2018-01-22 13:01:38 -08:00
$scope . appConfigure . robotsTxt = '' ;
$scope . appConfigure . enableBackup = true ;
2018-12-07 09:04:06 -08:00
$scope . appConfigure . enableAutomaticUpdate = true ;
2018-01-22 13:01:38 -08:00
$scope . appConfigureForm . $setPristine ( ) ;
$scope . appConfigureForm . $setUntouched ( ) ;
// reset uninstall dialog
$scope . appUninstall . app = { } ;
$scope . appUninstall . error = { } ;
$scope . appUninstall . password = '' ;
$scope . appUninstallForm . $setPristine ( ) ;
$scope . appUninstallForm . $setUntouched ( ) ;
// reset update dialog
$scope . appUpdate . error = { } ;
$scope . appUpdate . app = { } ;
$scope . appUpdate . manifest = { } ;
// reset restore dialog
$scope . appRestore . error = { } ;
$scope . appRestore . app = { } ;
$scope . appRestore . password = '' ;
$scope . appRestore . selectedBackup = null ;
$scope . appRestore . backups = [ ] ;
2018-05-28 00:47:53 -07:00
$scope . appRestore . location = '' ;
$scope . appRestore . domain = null ;
$scope . appRestore . portBindings = { } ;
$scope . appRestore . portBindingsInfo = { } ;
$scope . appRestore . portBindingsEnabled = { } ;
2018-05-28 10:00:12 -07:00
$scope . appRestore . action = 'restore' ;
2018-06-14 15:46:55 +02:00
// post install confirmation dialog
$scope . appPostInstallConfirm . app = { } ;
$scope . appPostInstallConfirm . message = '' ;
$scope . appPostInstallConfirm . confirmed = false ;
2018-01-22 13:01:38 -08:00
} ;
2018-05-24 13:53:30 -07:00
$scope . readCertificate = function ( event ) {
2018-01-22 13:01:38 -08:00
$scope . $apply ( function ( ) {
$scope . appConfigure . certificateFile = null ;
$scope . appConfigure . certificateFileName = event . target . files [ 0 ] . name ;
var reader = new FileReader ( ) ;
reader . onload = function ( result ) {
if ( ! result . target || ! result . target . result ) return console . error ( 'Unable to read local file' ) ;
$scope . appConfigure . certificateFile = result . target . result ;
} ;
reader . readAsText ( event . target . files [ 0 ] ) ;
} ) ;
} ;
2018-05-24 13:53:30 -07:00
$scope . readKey = function ( event ) {
2018-01-22 13:01:38 -08:00
$scope . $apply ( function ( ) {
$scope . appConfigure . keyFile = null ;
$scope . appConfigure . keyFileName = event . target . files [ 0 ] . name ;
var reader = new FileReader ( ) ;
reader . onload = function ( result ) {
if ( ! result . target || ! result . target . result ) return console . error ( 'Unable to read local file' ) ;
$scope . appConfigure . keyFile = result . target . result ;
} ;
reader . readAsText ( event . target . files [ 0 ] ) ;
} ) ;
} ;
$scope . showInformation = function ( app ) {
$scope . reset ( ) ;
$scope . appInfo . app = app ;
$scope . appInfo . message = app . manifest . postInstallMessage ;
$ ( '#appInfoModal' ) . modal ( 'show' ) ;
return false ; // prevent propagation and default
} ;
$scope . showError = function ( app ) {
$scope . reset ( ) ;
$scope . appError . app = app ;
$ ( '#appErrorModal' ) . modal ( 'show' ) ;
return false ; // prevent propagation and default
} ;
$scope . showUninstall = function ( app ) {
$scope . reset ( ) ;
$scope . appUninstall . app = app ;
$ ( '#appUninstallModal' ) . modal ( 'show' ) ;
} ;
$scope . doUninstall = function ( ) {
$scope . appUninstall . busy = true ;
$scope . appUninstall . error . password = null ;
Client . uninstallApp ( $scope . appUninstall . app . id , $scope . appUninstall . password , function ( error ) {
if ( error && error . statusCode === 403 ) {
$scope . appUninstall . password = '' ;
$scope . appUninstall . error . password = true ;
$scope . appUninstallForm . password . $setPristine ( ) ;
$ ( '#appUninstallPasswordInput' ) . focus ( ) ;
} else if ( error && error . statusCode === 402 ) { // unpurchase failed
Client . error ( 'Relogin to Cloudron App Store' ) ;
} else if ( error ) {
Client . error ( error ) ;
} else {
$ ( '#appUninstallModal' ) . modal ( 'hide' ) ;
2018-06-26 19:47:39 -07:00
Client . refreshAppCache ( $scope . appUninstall . app . id ) ; // reflect the new app state immediately
2018-01-22 13:01:38 -08:00
$scope . reset ( ) ;
}
$scope . appUninstall . busy = false ;
} ) ;
} ;
$scope . showUpdate = function ( app , updateManifest ) {
$scope . reset ( ) ;
$scope . appUpdate . app = app ;
$scope . appUpdate . manifest = angular . copy ( updateManifest ) ;
$ ( '#appUpdateModal' ) . modal ( 'show' ) ;
} ;
$scope . doUpdate = function ( ) {
$scope . appUpdate . busy = true ;
Client . updateApp ( $scope . appUpdate . app . id , $scope . appUpdate . manifest , function ( error ) {
if ( error ) {
Client . error ( error ) ;
} else {
$scope . appUpdate . app = { } ;
$ ( '#appUpdateModal' ) . modal ( 'hide' ) ;
}
$scope . appUpdate . busy = false ;
2018-06-26 08:49:43 -07:00
Client . refreshAppCache ( $scope . appUpdate . app . id ) ; // reflect the new app state immediately
2018-01-22 13:01:38 -08:00
} ) ;
} ;
$scope . renderAccessRestrictionUser = function ( userId ) {
var user = $scope . users . filter ( function ( u ) { return u . id === userId ; } ) [ 0 ] ;
// user not found
if ( ! user ) return userId ;
return user . username ? user . username : user . email ;
} ;
$scope . cancel = function ( ) {
window . history . back ( ) ;
} ;
function fetchUsers ( ) {
Client . getUsers ( function ( error , users ) {
if ( error ) {
console . error ( error ) ;
return $timeout ( fetchUsers , 5000 ) ;
}
2018-03-05 12:14:20 +01:00
// ensure we have something to work with in the access restriction dropdowns
users . forEach ( function ( user ) { user . display = user . username || user . email ; } ) ;
2018-01-22 13:01:38 -08:00
$scope . users = users ;
} ) ;
}
function fetchGroups ( ) {
Client . getGroups ( function ( error , groups ) {
if ( error ) {
console . error ( error ) ;
return $timeout ( fetchUsers , 5000 ) ;
}
$scope . groups = groups ;
} ) ;
}
function getDomains ( ) {
Client . getDomains ( function ( error , result ) {
i f ( error ) {
console . error ( error ) ;
return $timeout ( getDomains , 5000 ) ;
}
$scope . domains = result ;
} ) ;
}
function getBackupConfig ( ) {
Client . getBackupConfig ( function ( error , backupConfig ) {
if ( error ) return console . error ( error ) ;
$scope . backupConfig = backupConfig ;
} ) ;
}
Client . onReady ( function ( ) {
2018-06-26 10:19:50 -07:00
Client . refreshInstalledApps ( ) ; // refresh the new list immediately when switching from another view (appstore)
2018-08-28 12:07:55 -07:00
$scope . spacesSuffix = $scope . user . username . replace ( /\./g , '-' ) ;
2018-08-28 21:35:17 -07:00
if ( $scope . user . admin || $scope . config . features . spaces ) {
2018-06-25 18:06:17 -07:00
fetchUsers ( ) ;
fetchGroups ( ) ;
getDomains ( ) ;
2018-10-30 21:07:37 -07:00
if ( $scope . user . admin && ! $scope . config . managed ) getBackupConfig ( ) ; // FIXME: detect disabled backups some other way
2018-06-25 18:06:17 -07:00
}
2018-01-22 13:01:38 -08:00
2018-06-25 18:06:17 -07:00
var refreshAppsTimer = $interval ( Client . refreshInstalledApps . bind ( Client ) , 5000 ) ;
2018-01-22 13:01:38 -08:00
2018-06-25 18:06:17 -07:00
$scope . $on ( '$destroy' , function ( ) {
$interval . cancel ( refreshAppsTimer ) ;
2018-01-22 13:01:38 -08:00
} ) ;
} ) ;
// setup all the dialog focus handling
[ 'appConfigureModal' , 'appUninstallModal' , 'appUpdateModal' , 'appRestoreModal' , 'appInfoModal' , 'appErrorModal' ] . forEach ( function ( id ) {
$ ( '#' + id ) . on ( 'shown.bs.modal' , function ( ) {
$ ( this ) . find ( "[autofocus]:first" ) . focus ( ) ;
} ) ;
} ) ;
$ ( '.modal-backdrop' ) . remove ( ) ;
} ] ) ;