You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by mj...@apache.org on 2018/04/26 16:56:52 UTC

[1/3] guacamole-client git commit: GUACAMOLE-526: Update webapp to angular 1.6.9.

Repository: guacamole-client
Updated Branches:
  refs/heads/master 74124ca52 -> 9a2e0c608


GUACAMOLE-526: Update webapp to angular 1.6.9.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/b3eeb36b
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/b3eeb36b
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/b3eeb36b

Branch: refs/heads/master
Commit: b3eeb36b8726211597bdc921a632dbbc5c87ee16
Parents: 0328166
Author: James Muehlner <ja...@guac-dev.org>
Authored: Wed Apr 25 22:25:02 2018 -0700
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Wed Apr 25 22:25:02 2018 -0700

----------------------------------------------------------------------
 guacamole/pom.xml                               | 12 ++---
 guacamole/src/licenses/LICENSE                  | 12 ++---
 .../src/licenses/bundled/angular-1.6.9/LICENSE  | 21 +++++++++
 .../bundled/angular-translate-2.16.0/LICENSE    | 21 +++++++++
 .../app/auth/service/authenticationService.js   |  7 +--
 .../app/client/controllers/clientController.js  |  2 +-
 .../webapp/app/client/types/ManagedClient.js    |  6 +--
 .../webapp/app/index/config/indexRouteConfig.js |  3 ++
 .../index/config/templateRequestDecorator.js    |  2 +-
 .../webapp/app/index/filters/arrayFilter.js     | 41 +++++++++++++++++
 .../app/locale/services/translationLoader.js    | 15 +++----
 .../controllers/manageConnectionController.js   | 22 ++++-----
 .../manageConnectionGroupController.js          | 16 +++----
 .../manageSharingProfileController.js           | 24 +++++-----
 .../manage/controllers/manageUserController.js  | 20 ++++-----
 .../app/manage/templates/manageConnection.html  |  2 +-
 .../app/navigation/directives/guacUserMenu.js   |  2 +-
 .../main/webapp/app/osk/directives/guacOsk.js   |  4 +-
 .../rest/services/activeConnectionService.js    | 10 ++---
 .../app/rest/services/connectionGroupService.js | 18 ++++----
 .../app/rest/services/connectionService.js      | 22 ++++-----
 .../app/rest/services/dataSourceService.js      | 14 +++---
 .../webapp/app/rest/services/historyService.js  |  4 +-
 .../webapp/app/rest/services/languageService.js |  4 +-
 .../webapp/app/rest/services/patchService.js    |  4 +-
 .../app/rest/services/permissionService.js      | 10 ++---
 .../webapp/app/rest/services/requestService.js  | 47 ++++++++++++++++++++
 .../webapp/app/rest/services/schemaService.js   | 12 ++---
 .../app/rest/services/sharingProfileService.js  | 20 ++++-----
 .../webapp/app/rest/services/tunnelService.js   |  8 ++--
 .../webapp/app/rest/services/userService.js     | 20 ++++-----
 .../directives/guacSettingsConnectionHistory.js |  2 +-
 .../directives/guacSettingsConnections.js       |  2 +-
 .../directives/guacSettingsPreferences.js       | 17 ++++---
 .../settings/templates/settingsPreferences.html |  2 +-
 guacamole/src/main/webapp/index.html            | 12 ++---
 36 files changed, 301 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/pom.xml
----------------------------------------------------------------------
diff --git a/guacamole/pom.xml b/guacamole/pom.xml
index 12d6c5c..5adee65 100644
--- a/guacamole/pom.xml
+++ b/guacamole/pom.xml
@@ -324,19 +324,19 @@
         <dependency>
             <groupId>org.webjars.bower</groupId>
             <artifactId>angular</artifactId>
-            <version>1.3.16</version>
+            <version>1.6.9</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.webjars.bower</groupId>
             <artifactId>angular-route</artifactId>
-            <version>1.3.16</version>
+            <version>1.6.9</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.webjars.bower</groupId>
             <artifactId>angular-touch</artifactId>
-            <version>1.3.16</version>
+            <version>1.6.9</version>
             <scope>runtime</scope>
         </dependency>
 
@@ -358,13 +358,13 @@
         <dependency>
             <groupId>org.webjars.bower</groupId>
             <artifactId>angular-translate</artifactId>
-            <version>2.8.0</version>
+            <version>2.16.0</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.webjars.bower</groupId>
             <artifactId>angular-translate-interpolation-messageformat</artifactId>
-            <version>2.8.0</version>
+            <version>2.16.0</version>
             <scope>runtime</scope>
             <exclusions>
                 <exclusion>
@@ -382,7 +382,7 @@
         <dependency>
             <groupId>org.webjars.bower</groupId>
             <artifactId>angular-translate-loader-static-files</artifactId>
-            <version>2.8.0</version>
+            <version>2.16.0</version>
             <scope>runtime</scope>
         </dependency>
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/licenses/LICENSE
----------------------------------------------------------------------
diff --git a/guacamole/src/licenses/LICENSE b/guacamole/src/licenses/LICENSE
index dd70b1c..c2e6bf5 100644
--- a/guacamole/src/licenses/LICENSE
+++ b/guacamole/src/licenses/LICENSE
@@ -214,14 +214,14 @@ terms and conditions of the following licenses.
 AngularJS (https://angularjs.org/)
 ----------------------------------
 
-    Version: 1.3.16
+    Version: 1.6.9
     From: 'Google Inc.' (http://www.google.com/)
     License(s):
-        MIT (bundled/angular-1.3.16/LICENSE)
+        MIT (bundled/angular-1.6.9/LICENSE)
 
 The MIT License
 
-Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
+Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -276,14 +276,14 @@ SOFTWARE.
 angular-translate (https://angular-translate.github.io/)
 --------------------------------------------------------
 
-    Version: 2.8.0
+    Version: 2.16.0
     From: 'Pascal Precht' (https://github.com/PascalPrecht)
     License(s):
-        MIT (bundled/angular-translate-2.8.0/LICENSE)
+        MIT (bundled/angular-translate-2.16.0/LICENSE)
 
 The MIT License (MIT)
 
-Copyright (c) <2014> <pa...@gmail.com>
+Copyright (c) 2013-2017 The angular-translate team and Pascal Precht
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/licenses/bundled/angular-1.6.9/LICENSE
----------------------------------------------------------------------
diff --git a/guacamole/src/licenses/bundled/angular-1.6.9/LICENSE b/guacamole/src/licenses/bundled/angular-1.6.9/LICENSE
new file mode 100644
index 0000000..6e46a70
--- /dev/null
+++ b/guacamole/src/licenses/bundled/angular-1.6.9/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/licenses/bundled/angular-translate-2.16.0/LICENSE
----------------------------------------------------------------------
diff --git a/guacamole/src/licenses/bundled/angular-translate-2.16.0/LICENSE b/guacamole/src/licenses/bundled/angular-translate-2.16.0/LICENSE
new file mode 100644
index 0000000..85a3888
--- /dev/null
+++ b/guacamole/src/licenses/bundled/angular-translate-2.16.0/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2017 The angular-translate team and Pascal Precht
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/auth/service/authenticationService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/auth/service/authenticationService.js b/guacamole/src/main/webapp/app/auth/service/authenticationService.js
index 2b64a5b..7f74fea 100644
--- a/guacamole/src/main/webapp/app/auth/service/authenticationService.js
+++ b/guacamole/src/main/webapp/app/auth/service/authenticationService.js
@@ -185,7 +185,8 @@ angular.module('auth').factory('authenticationService', ['$injector',
         })
 
         // If authentication succeeds, handle received auth data
-        .success(function authenticationSuccessful(data) {
+        .then(function authenticationSuccessful(response) {
+            var data = response.data;
 
             var currentToken = service.getCurrentToken();
 
@@ -217,11 +218,11 @@ angular.module('auth').factory('authenticationService', ['$injector',
         })
 
         // If authentication fails, propogate failure to returned promise
-        .error(function authenticationFailed(error) {
+        ['catch'](function authenticationFailed(response) {
 
             // Ensure error object exists, even if the error response is not
             // coming from the authentication REST endpoint
-            error = new Error(error);
+            var error = new Error(response.data);
 
             // Request credentials if provided credentials were invalid
             if (error.type === Error.Type.INVALID_CREDENTIALS)

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/client/controllers/clientController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js
index a21c0a2..8a2f935 100644
--- a/guacamole/src/main/webapp/app/client/controllers/clientController.js
+++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js
@@ -464,7 +464,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
 
         // Pull sharing profiles for the current connection
         tunnelService.getSharingProfiles(uuid)
-        .success(function sharingProfilesRetrieved(sharingProfiles) {
+        .then(function sharingProfilesRetrieved(sharingProfiles) {
             $scope.sharingProfiles = sharingProfiles;
         });
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/client/types/ManagedClient.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/client/types/ManagedClient.js b/guacamole/src/main/webapp/app/client/types/ManagedClient.js
index 72481eb..32acd8d 100644
--- a/guacamole/src/main/webapp/app/client/types/ManagedClient.js
+++ b/guacamole/src/main/webapp/app/client/types/ManagedClient.js
@@ -512,7 +512,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
         // If using a connection, pull connection name
         if (clientIdentifier.type === ClientIdentifier.Types.CONNECTION) {
             connectionService.getConnection(clientIdentifier.dataSource, clientIdentifier.id)
-            .success(function connectionRetrieved(connection) {
+            .then(function connectionRetrieved(connection) {
                 managedClient.name = managedClient.title = connection.name;
             });
         }
@@ -520,7 +520,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
         // If using a connection group, pull connection name
         else if (clientIdentifier.type === ClientIdentifier.Types.CONNECTION_GROUP) {
             connectionGroupService.getConnectionGroup(clientIdentifier.dataSource, clientIdentifier.id)
-            .success(function connectionGroupRetrieved(group) {
+            .then(function connectionGroupRetrieved(group) {
                 managedClient.name = managedClient.title = group.name;
             });
         }
@@ -631,7 +631,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
                 client.tunnel.uuid, sharingProfile.identifier);
 
         // Add a new share link once the credentials are ready
-        credentialRequest.success(function sharingCredentialsReceived(sharingCredentials) {
+        credentialRequest.then(function sharingCredentialsReceived(sharingCredentials) {
             client.shareLinks[sharingProfile.identifier] =
                 ManagedShareLink.getInstance(sharingProfile, sharingCredentials);
         });

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
index dd2ec6d..d662266 100644
--- a/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
+++ b/guacamole/src/main/webapp/app/index/config/indexRouteConfig.js
@@ -26,6 +26,9 @@ angular.module('index').config(['$routeProvider', '$locationProvider',
     // Disable HTML5 mode (use # for routing)
     $locationProvider.html5Mode(false);
 
+    // Clear hash prefix to keep /#/thing/bat URL style
+    $locationProvider.hashPrefix('');
+
     /**
      * Attempts to re-authenticate with the Guacamole server, sending any
      * query parameters in the URL, along with the current auth token, and

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/index/config/templateRequestDecorator.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/index/config/templateRequestDecorator.js b/guacamole/src/main/webapp/app/index/config/templateRequestDecorator.js
index e28e09f..2f832de 100644
--- a/guacamole/src/main/webapp/app/index/config/templateRequestDecorator.js
+++ b/guacamole/src/main/webapp/app/index/config/templateRequestDecorator.js
@@ -337,7 +337,7 @@ angular.module('index').config(['$provide', function($provide) {
             $delegate.apply(this, arguments).then(function patchTemplate(data) {
 
                 // Retrieve and apply all patches
-                patchService.getPatches().success(function applyRetrievedPatches(patches) {
+                patchService.getPatches().then(function applyRetrievedPatches(patches) {
 
                     // Parse HTML into DOM tree
                     var root = $('<div></div>').html(data);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/index/filters/arrayFilter.js b/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
new file mode 100644
index 0000000..f0429c8
--- /dev/null
+++ b/guacamole/src/main/webapp/app/index/filters/arrayFilter.js
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A filter for transforming an object into an array of all non-inherited
+ * property values.
+ */
+angular.module('index').filter('toArray', [function toArrayFactory() {
+
+    return function toArrayFiter(input) {
+
+
+        console.log(input)
+
+        // If no object is available, just return an empty array
+        if (!input) {
+            return [];
+        }
+
+        return Object.keys(input).map(function fetchValueByKey(key) {
+            return input[key];
+        });
+    };
+
+}]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/locale/services/translationLoader.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/locale/services/translationLoader.js b/guacamole/src/main/webapp/app/locale/services/translationLoader.js
index 6ff492d..2be5e6a 100644
--- a/guacamole/src/main/webapp/app/locale/services/translationLoader.js
+++ b/guacamole/src/main/webapp/app/locale/services/translationLoader.js
@@ -74,7 +74,7 @@ angular.module('locale').factory('translationLoader', ['$injector', function tra
         languageService.getLanguages()
 
         // Attempt to retrieve translation if language is supported
-        .success(function retrievedLanguages(languages) {
+        .then(function retrievedLanguages(languages) {
 
             // Skip retrieval if language is not supported
             if (!(currentKey in languages)) {
@@ -90,18 +90,17 @@ angular.module('locale').factory('translationLoader', ['$injector', function tra
             })
 
             // Resolve promise if translation retrieved successfully
-            .success(function translationFileRetrieved(translation) {
-                deferred.resolve(translation);
-            })
+            .then(function translationFileRetrieved(request) {
+                deferred.resolve(request.data);
+            },
 
             // Retry with remaining languages if translation file could not be
             // retrieved
-            .error(tryNextTranslation);
-
-        })
+            tryNextTranslation);
+        },
 
         // Retry with remaining languages if translation does not exist
-        .error(tryNextTranslation);
+        tryNextTranslation);
 
     };
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
index 2220e4d..2fd8156 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionController.js
@@ -184,7 +184,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
 
     // Pull connection attribute schema
     schemaService.getConnectionAttributes($scope.selectedDataSource)
-    .success(function attributesReceived(attributes) {
+    .then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
     });
 
@@ -194,13 +194,13 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
         ConnectionGroup.ROOT_IDENTIFIER,
         [PermissionSet.ObjectPermissionType.ADMINISTER]
     )
-    .success(function connectionGroupReceived(rootGroup) {
+    .then(function connectionGroupReceived(rootGroup) {
         $scope.rootGroup = rootGroup;
     });
     
     // Query the user's permissions for the current connection
     permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
-    .success(function permissionsReceived(permissions) {
+    .then(function permissionsReceived(permissions) {
                 
         $scope.permissions = permissions;
                         
@@ -230,7 +230,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
    
     // Get protocol metadata
     schemaService.getProtocols($scope.selectedDataSource)
-    .success(function protocolsReceived(protocols) {
+    .then(function protocolsReceived(protocols) {
         $scope.protocols = protocols;
     });
 
@@ -244,13 +244,13 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
 
         // Pull data from existing connection
         connectionService.getConnection($scope.selectedDataSource, identifier)
-        .success(function connectionRetrieved(connection) {
+        .then(function connectionRetrieved(connection) {
             $scope.connection = connection;
         });
 
         // Pull connection history
         connectionService.getConnectionHistory($scope.selectedDataSource, identifier)
-        .success(function historyReceived(historyEntries) {
+        .then(function historyReceived(historyEntries) {
 
             // Wrap all history entries for sake of display
             $scope.historyEntryWrappers = [];
@@ -262,7 +262,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
 
         // Pull connection parameters
         connectionService.getConnectionParameters($scope.selectedDataSource, identifier)
-        .success(function parametersReceived(parameters) {
+        .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
         });
     }
@@ -272,7 +272,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
 
         // Pull data from cloned connection
         connectionService.getConnection($scope.selectedDataSource, cloneSourceIdentifier)
-        .success(function connectionRetrieved(connection) {
+        .then(function connectionRetrieved(connection) {
             $scope.connection = connection;
             
             // Clear the identifier field because this connection is new
@@ -284,7 +284,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
         
         // Pull connection parameters from cloned connection
         connectionService.getConnectionParameters($scope.selectedDataSource, cloneSourceIdentifier)
-        .success(function parametersReceived(parameters) {
+        .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
         });
     }
@@ -388,7 +388,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
 
         // Save the connection
         connectionService.saveConnection($scope.selectedDataSource, $scope.connection)
-        .success(function savedConnection() {
+        .then(function savedConnection() {
             $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
         })
 
@@ -438,7 +438,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
 
         // Delete the connection
         connectionService.deleteConnection($scope.selectedDataSource, $scope.connection)
-        .success(function deletedConnection() {
+        .then(function deletedConnection() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
         })
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
index f342f4d..6cdda80 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageConnectionGroupController.js
@@ -129,13 +129,13 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
     
     // Pull connection group attribute schema
     schemaService.getConnectionGroupAttributes($scope.selectedDataSource)
-    .success(function attributesReceived(attributes) {
+    .then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
     });
 
     // Query the user's permissions for the current connection group
     permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
-    .success(function permissionsReceived(permissions) {
+    .then(function permissionsReceived(permissions) {
                 
         $scope.permissions = permissions;
                         
@@ -161,14 +161,14 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
         ConnectionGroup.ROOT_IDENTIFIER,
         [PermissionSet.ObjectPermissionType.ADMINISTER]
     )
-    .success(function connectionGroupReceived(rootGroup) {
+    .then(function connectionGroupReceived(rootGroup) {
         $scope.rootGroup = rootGroup;
     });
 
     // If we are editing an existing connection group, pull its data
     if (identifier) {
         connectionGroupService.getConnectionGroup($scope.selectedDataSource, identifier)
-        .success(function connectionGroupReceived(connectionGroup) {
+        .then(function connectionGroupReceived(connectionGroup) {
             $scope.connectionGroup = connectionGroup;
         });
     }
@@ -230,12 +230,12 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
 
         // Save the connection
         connectionGroupService.saveConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
-        .success(function savedConnectionGroup() {
+        .then(function savedConnectionGroup() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
         })
 
         // Notify of any errors
-        .error(function connectionGroupSaveFailed(error) {
+        ['catch'](function connectionGroupSaveFailed(error) {
             guacNotification.showStatus({
                 'className'  : 'error',
                 'title'      : 'MANAGE_CONNECTION_GROUP.DIALOG_HEADER_ERROR',
@@ -280,12 +280,12 @@ angular.module('manage').controller('manageConnectionGroupController', ['$scope'
 
         // Delete the connection group
         connectionGroupService.deleteConnectionGroup($scope.selectedDataSource, $scope.connectionGroup)
-        .success(function deletedConnectionGroup() {
+        .then(function deletedConnectionGroup() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
         })
 
         // Notify of any errors
-        .error(function connectionGroupDeletionFailed(error) {
+        ['catch'](function connectionGroupDeletionFailed(error) {
             guacNotification.showStatus({
                 'className'  : 'error',
                 'title'      : 'MANAGE_CONNECTION_GROUP.DIALOG_HEADER_ERROR',

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
index 0583a69..1adead8 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageSharingProfileController.js
@@ -170,13 +170,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
     // Pull sharing profile attribute schema
     schemaService.getSharingProfileAttributes($scope.selectedDataSource)
-    .success(function attributesReceived(attributes) {
+    .then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
     });
 
     // Query the user's permissions for the current sharing profile
     permissionService.getEffectivePermissions($scope.selectedDataSource, authenticationService.getCurrentUsername())
-    .success(function permissionsReceived(permissions) {
+    .then(function permissionsReceived(permissions) {
 
         $scope.permissions = permissions;
 
@@ -212,7 +212,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
     // Get protocol metadata
     schemaService.getProtocols($scope.selectedDataSource)
-    .success(function protocolsReceived(protocols) {
+    .then(function protocolsReceived(protocols) {
         $scope.protocols = protocols;
     });
 
@@ -221,13 +221,13 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
         // Pull data from existing sharing profile
         sharingProfileService.getSharingProfile($scope.selectedDataSource, identifier)
-        .success(function sharingProfileRetrieved(sharingProfile) {
+        .then(function sharingProfileRetrieved(sharingProfile) {
             $scope.sharingProfile = sharingProfile;
         });
 
         // Pull sharing profile parameters
         sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, identifier)
-        .success(function parametersReceived(parameters) {
+        .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
         });
 
@@ -238,7 +238,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
         // Pull data from cloned sharing profile
         sharingProfileService.getSharingProfile($scope.selectedDataSource, cloneSourceIdentifier)
-        .success(function sharingProfileRetrieved(sharingProfile) {
+        .then(function sharingProfileRetrieved(sharingProfile) {
 
             // Store data of sharing profile being cloned
             $scope.sharingProfile = sharingProfile;
@@ -250,7 +250,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
         // Pull sharing profile parameters from cloned sharing profile
         sharingProfileService.getSharingProfileParameters($scope.selectedDataSource, cloneSourceIdentifier)
-        .success(function parametersReceived(parameters) {
+        .then(function parametersReceived(parameters) {
             $scope.parameters = parameters;
         });
 
@@ -274,7 +274,7 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
         // Pull data from existing sharing profile
         connectionService.getConnection($scope.selectedDataSource, identifier)
-        .success(function connectionRetrieved(connection) {
+        .then(function connectionRetrieved(connection) {
             $scope.primaryConnection = connection;
         });
 
@@ -351,12 +351,12 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
         // Save the sharing profile
         sharingProfileService.saveSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
-        .success(function savedSharingProfile() {
+        .then(function savedSharingProfile() {
             $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
         })
 
         // Notify of any errors
-        .error(function sharingProfileSaveFailed(error) {
+        ['catch'](function sharingProfileSaveFailed(error) {
             guacNotification.showStatus({
                 'className'  : 'error',
                 'title'      : 'MANAGE_SHARING_PROFILE.DIALOG_HEADER_ERROR',
@@ -389,12 +389,12 @@ angular.module('manage').controller('manageSharingProfileController', ['$scope',
 
         // Delete the sharing profile
         sharingProfileService.deleteSharingProfile($scope.selectedDataSource, $scope.sharingProfile)
-        .success(function deletedSharingProfile() {
+        .then(function deletedSharingProfile() {
             $location.path('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
         })
 
         // Notify of any errors
-        .error(function sharingProfileDeletionFailed(error) {
+        ['catch'](function sharingProfileDeletionFailed(error) {
             guacNotification.showStatus({
                 'className'  : 'error',
                 'title'      : 'MANAGE_SHARING_PROFILE.DIALOG_HEADER_ERROR',

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
index 48519d5..76a8376 100644
--- a/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
+++ b/guacamole/src/main/webapp/app/manage/controllers/manageUserController.js
@@ -529,7 +529,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
     });
 
     // Pull user attribute schema
-    schemaService.getUserAttributes(selectedDataSource).success(function attributesReceived(attributes) {
+    schemaService.getUserAttributes(selectedDataSource).then(function attributesReceived(attributes) {
         $scope.attributes = attributes;
     });
 
@@ -557,12 +557,12 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
         $scope.selfUsername = username;
 
         // Pull user permissions
-        permissionService.getPermissions(selectedDataSource, username).success(function gotPermissions(permissions) {
+        permissionService.getPermissions(selectedDataSource, username).then(function gotPermissions(permissions) {
             $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions);
         })
 
         // If permissions cannot be retrieved, use empty permissions
-        .error(function permissionRetrievalFailed() {
+        ['catch'](function permissionRetrievalFailed() {
             $scope.permissionFlags = new PermissionFlagSet();
         });
     }
@@ -585,13 +585,13 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
 
         // Pull user permissions
         permissionService.getPermissions(selectedDataSource, cloneSourceUsername)
-        .success(function gotPermissions(permissions) {
+        .then(function gotPermissions(permissions) {
             $scope.permissionFlags = PermissionFlagSet.fromPermissionSet(permissions);
             permissionsAdded = permissions;
         })
 
         // If permissions cannot be retrieved, use empty permissions
-        .error(function permissionRetrievalFailed() {
+        ['catch'](function permissionRetrievalFailed() {
             $scope.permissionFlags = new PermissionFlagSet();
         });
     }
@@ -1117,7 +1117,7 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
         else
             saveUserPromise = userService.createUser(selectedDataSource, $scope.user);
 
-        saveUserPromise.success(function savedUser() {
+        saveUserPromise.then(function savedUser() {
 
             // Move permission flags if username differs from marker
             if ($scope.selfUsername !== $scope.user.username) {
@@ -1138,12 +1138,12 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
 
             // Upon success, save any changed permissions
             permissionService.patchPermissions(selectedDataSource, $scope.user.username, permissionsAdded, permissionsRemoved)
-            .success(function patchedUserPermissions() {
+            .then(function patchedUserPermissions() {
                 $location.url('/settings/users');
             })
 
             // Notify of any errors
-            .error(function userPermissionsPatchFailed(error) {
+            ['catch'](function userPermissionsPatchFailed(error) {
                 guacNotification.showStatus({
                     'className'  : 'error',
                     'title'      : 'MANAGE_USER.DIALOG_HEADER_ERROR',
@@ -1201,12 +1201,12 @@ angular.module('manage').controller('manageUserController', ['$scope', '$injecto
 
         // Delete the user 
         userService.deleteUser(selectedDataSource, $scope.user)
-        .success(function deletedUser() {
+        .then(function deletedUser() {
             $location.path('/settings/users');
         })
 
         // Notify of any errors
-        .error(function userDeletionFailed(error) {
+        ['catch'](function userDeletionFailed(error) {
             guacNotification.showStatus({
                 'className'  : 'error',
                 'title'      : 'MANAGE_USER.DIALOG_HEADER_ERROR',

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
index 737ace3..112f715 100644
--- a/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
+++ b/guacamole/src/main/webapp/app/manage/templates/manageConnection.html
@@ -32,7 +32,7 @@
             <tr>
                 <th>{{'MANAGE_CONNECTION.FIELD_HEADER_PROTOCOL' | translate}}</th>
                 <td>
-                    <select ng-model="connection.protocol" ng-options="name as getProtocolName(protocol.name) | translate for (name, protocol) in protocols | orderBy: name"></select>
+                    <select ng-model="connection.protocol" ng-options="protocol.name as getProtocolName(protocol.name) | translate for protocol in protocols | toArray | orderBy: name"></select>
                 </td>
             </tr>
         </table>

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
index 9534dd4..13de858 100644
--- a/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
+++ b/guacamole/src/main/webapp/app/navigation/directives/guacUserMenu.js
@@ -96,7 +96,7 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu()
 
             // Pull user data
             userService.getUser(authenticationService.getDataSource(), $scope.username)
-                    .success(function userRetrieved(user) {
+                    .then(function userRetrieved(user) {
 
                 // Store retrieved user object
                 $scope.user = user;

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
index 4797f12..968e86e 100644
--- a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
+++ b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js
@@ -88,7 +88,9 @@ angular.module('osk').directive('guacOsk', [function guacOsk() {
                     })
 
                     // Build OSK with retrieved layout
-                    .success(function layoutRetrieved(layout) {
+                    .then(function layoutRetrieved(request) {
+
+                        var layout = request.data;
 
                         // Abort if the layout changed while we were waiting for a response
                         if ($scope.layout !== url)

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
index 7c8fb6a..b548c86 100644
--- a/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/activeConnectionService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
         function activeConnectionService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
 
@@ -58,7 +58,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
             httpParameters.permission = permissionTypes;
 
         // Retrieve tunnels
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/activeConnections',
             params  : httpParameters
@@ -102,7 +102,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
         angular.forEach(dataSources, function retrieveActiveConnections(dataSource) {
             activeConnectionRequests.push(
                 service.getActiveConnections(dataSource, permissionTypes)
-                .success(function activeConnectionsRetrieved(activeConnections) {
+                .then(function activeConnectionsRetrieved(activeConnections) {
                     activeConnectionMaps[dataSource] = activeConnections;
                 })
             );
@@ -157,7 +157,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
         });
 
         // Perform active connection deletion via PATCH
-        return $http({
+        return requestService({
             method  : 'PATCH',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/activeConnections',
             params  : httpParameters,
@@ -191,7 +191,7 @@ angular.module('rest').factory('activeConnectionService', ['$injector',
         };
 
         // Generate sharing credentials
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource)
                         + '/activeConnections/' + encodeURIComponent(id)

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
index 5e554c1..b7e78e3 100644
--- a/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
+++ b/guacamole/src/main/webapp/app/rest/services/connectionGroupService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         function connectionGroupService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
@@ -70,7 +70,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
             httpParameters.permission = permissionTypes;
 
         // Retrieve connection group 
-        return $http({
+        return requestService({
             cache   : cacheService.connections,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroupID) + '/tree',
@@ -103,7 +103,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         };
 
         // Retrieve connection group
-        return $http({
+        return requestService({
             cache   : cacheService.connections,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroupID),
@@ -134,7 +134,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
 
         // If connection group is new, add it and set the identifier automatically
         if (!connectionGroup.identifier) {
-            return $http({
+            return requestService({
                 method  : 'POST',
                 url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups',
                 params  : httpParameters,
@@ -142,7 +142,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
             })
 
             // Set the identifier on the new connection group and clear the cache
-            .success(function connectionGroupCreated(newConnectionGroup){
+            .then(function connectionGroupCreated(newConnectionGroup){
                 connectionGroup.identifier = newConnectionGroup.identifier;
                 cacheService.connections.removeAll();
 
@@ -154,7 +154,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
 
         // Otherwise, update the existing connection group
         else {
-            return $http({
+            return requestService({
                 method  : 'PUT',
                 url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroup.identifier),
                 params  : httpParameters,
@@ -162,7 +162,7 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
             })
 
             // Clear the cache
-            .success(function connectionGroupUpdated(){
+            .then(function connectionGroupUpdated(){
                 cacheService.connections.removeAll();
 
                 // Clear users cache to force reload of permissions for this
@@ -191,14 +191,14 @@ angular.module('rest').factory('connectionGroupService', ['$injector',
         };
 
         // Delete connection group
-        return $http({
+        return requestService({
             method  : 'DELETE',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connectionGroups/' + encodeURIComponent(connectionGroup.identifier),
             params  : httpParameters
         })
 
         // Clear the cache
-        .success(function connectionGroupDeleted(){
+        .then(function connectionGroupDeleted(){
             cacheService.connections.removeAll();
         });
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/connectionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/connectionService.js b/guacamole/src/main/webapp/app/rest/services/connectionService.js
index e3ca620..8b9360d 100644
--- a/guacamole/src/main/webapp/app/rest/services/connectionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/connectionService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         function connectionService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
     
@@ -41,7 +41,7 @@ angular.module('rest').factory('connectionService', ['$injector',
      * 
      * @example
      * 
-     * connectionService.getConnection('myConnection').success(function(connection) {
+     * connectionService.getConnection('myConnection').then(function(connection) {
      *     // Do something with the connection
      * });
      */
@@ -53,7 +53,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         };
 
         // Retrieve connection
-        return $http({
+        return requestService({
             cache   : cacheService.connections,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id),
@@ -82,7 +82,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         };
 
         // Retrieve connection history
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id) + '/history',
             params  : httpParameters
@@ -110,7 +110,7 @@ angular.module('rest').factory('connectionService', ['$injector',
         };
 
         // Retrieve connection parameters
-        return $http({
+        return requestService({
             cache   : cacheService.connections,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(id) + '/parameters',
@@ -141,7 +141,7 @@ angular.module('rest').factory('connectionService', ['$injector',
 
         // If connection is new, add it and set the identifier automatically
         if (!connection.identifier) {
-            return $http({
+            return requestService({
                 method  : 'POST',
                 url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections',
                 params  : httpParameters,
@@ -149,7 +149,7 @@ angular.module('rest').factory('connectionService', ['$injector',
             })
 
             // Set the identifier on the new connection and clear the cache
-            .success(function connectionCreated(newConnection){
+            .then(function connectionCreated(newConnection){
                 connection.identifier = newConnection.identifier;
                 cacheService.connections.removeAll();
 
@@ -161,7 +161,7 @@ angular.module('rest').factory('connectionService', ['$injector',
 
         // Otherwise, update the existing connection
         else {
-            return $http({
+            return requestService({
                 method  : 'PUT',
                 url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(connection.identifier),
                 params  : httpParameters,
@@ -169,7 +169,7 @@ angular.module('rest').factory('connectionService', ['$injector',
             })
             
             // Clear the cache
-            .success(function connectionUpdated(){
+            .then(function connectionUpdated(){
                 cacheService.connections.removeAll();
 
                 // Clear users cache to force reload of permissions for this
@@ -198,14 +198,14 @@ angular.module('rest').factory('connectionService', ['$injector',
         };
 
         // Delete connection
-        return $http({
+        return requestService({
             method  : 'DELETE',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/connections/' + encodeURIComponent(connection.identifier),
             params  : httpParameters
         })
 
         // Clear the cache
-        .success(function connectionDeleted(){
+        .then(function connectionDeleted(){
             cacheService.connections.removeAll();
         });
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/dataSourceService.js b/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
index 4dd5a2f..783aa10 100644
--- a/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
+++ b/guacamole/src/main/webapp/app/rest/services/dataSourceService.js
@@ -23,6 +23,9 @@
 angular.module('rest').factory('dataSourceService', ['$injector',
         function dataSourceService($injector) {
 
+    // Required types
+    var Error = $injector.get('Error');
+
     // Required services
     var $q = $injector.get('$q');
 
@@ -83,21 +86,20 @@ angular.module('rest').factory('dataSourceService', ['$injector',
             fn.apply(this, [dataSource].concat(args))
 
             // Store result on success
-            .then(function immediateRequestSucceeded(response) {
-                results[dataSource] = response.data;
+            .then(function immediateRequestSucceeded(data) {
+                results[dataSource] = data;
                 deferredRequest.resolve();
             },
 
             // Fail on any errors (except "NOT FOUND")
-            function immediateRequestFailed(response) {
+            function immediateRequestFailed(error) {
 
-                // Ignore "NOT FOUND" errors
-                if (response.status === 404)
+                if (error.type === Error.Type.NOT_FOUND)
                     deferredRequest.resolve();
 
                 // Explicitly abort for all other errors
                 else
-                    deferredRequest.reject(response);
+                    deferredRequest.reject(error);
 
             });
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/historyService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/historyService.js b/guacamole/src/main/webapp/app/rest/services/historyService.js
index c77c4ab..f4e5027 100644
--- a/guacamole/src/main/webapp/app/rest/services/historyService.js
+++ b/guacamole/src/main/webapp/app/rest/services/historyService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('historyService', ['$injector',
         function historyService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var authenticationService = $injector.get('authenticationService');
 
     var service = {};
@@ -74,7 +74,7 @@ angular.module('rest').factory('historyService', ['$injector',
             httpParameters.order = sortPredicates;
 
         // Retrieve connection history
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/history/connections',
             params  : httpParameters

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/languageService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/languageService.js b/guacamole/src/main/webapp/app/rest/services/languageService.js
index 32696d5..5b1ecde 100644
--- a/guacamole/src/main/webapp/app/rest/services/languageService.js
+++ b/guacamole/src/main/webapp/app/rest/services/languageService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('languageService', ['$injector',
         function languageService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
 
@@ -47,7 +47,7 @@ angular.module('rest').factory('languageService', ['$injector',
         };
 
         // Retrieve available languages
-        return $http({
+        return requestService({
             cache   : cacheService.languages,
             method  : 'GET',
             url     : 'api/languages',

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/patchService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/patchService.js b/guacamole/src/main/webapp/app/rest/services/patchService.js
index 65818c2..de9f6bc 100644
--- a/guacamole/src/main/webapp/app/rest/services/patchService.js
+++ b/guacamole/src/main/webapp/app/rest/services/patchService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('patchService', ['$injector',
         function patchService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
 
@@ -48,7 +48,7 @@ angular.module('rest').factory('patchService', ['$injector',
         };
 
         // Retrieve all applicable HTML patches
-        return $http({
+        return requestService({
             cache   : cacheService.patches,
             method  : 'GET',
             url     : 'api/patches',

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/permissionService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/permissionService.js b/guacamole/src/main/webapp/app/rest/services/permissionService.js
index f108dfa..ec0a0d5 100644
--- a/guacamole/src/main/webapp/app/rest/services/permissionService.js
+++ b/guacamole/src/main/webapp/app/rest/services/permissionService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         function permissionService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
@@ -103,7 +103,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         };
 
         // Retrieve user permissions
-        return $http({
+        return requestService({
             cache   : cacheService.users,
             method  : 'GET',
             url     : getEffectivePermissionsResourceURL(dataSource, userID),
@@ -182,7 +182,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         };
 
         // Retrieve user permissions
-        return $http({
+        return requestService({
             cache   : cacheService.users,
             method  : 'GET',
             url     : getPermissionsResourceURL(dataSource, identifier),
@@ -315,7 +315,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         addPatchOperations(permissionPatch, PermissionPatch.Operation.REMOVE, permissionsToRemove);
 
         // Patch user permissions
-        return $http({
+        return requestService({
             method  : 'PATCH', 
             url     : getPermissionsResourceURL(dataSource, identifier),
             params  : httpParameters,
@@ -323,7 +323,7 @@ angular.module('rest').factory('permissionService', ['$injector',
         })
         
         // Clear the cache
-        .success(function permissionsPatched(){
+        .then(function permissionsPatched(){
             cacheService.users.removeAll();
         });
     };

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/requestService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/requestService.js b/guacamole/src/main/webapp/app/rest/services/requestService.js
new file mode 100644
index 0000000..e06b0d7
--- /dev/null
+++ b/guacamole/src/main/webapp/app/rest/services/requestService.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Service for converting $http promises that pass the entire response into
+ * promises that pass only the data from that response.
+ */
+angular.module('rest').factory('requestService', ['$q', '$http', 'Error',
+        function requestService($q, $http, Error) {
+
+    /**
+     * Given a configuration object formatted for the $http service, returns
+     * a promise that will resolve or reject with only the data from the $http
+     * response.
+     *
+     * @param {Object} object
+     *   Configuration object for $http service call.
+     *
+     * @returns {Promise}
+     *   A promise that will resolve or reject with the data from the response
+     *   to the $http call.
+     */
+    var wrappedHttpCall = function wrappedHttpCall(object) {
+        return $http(object).then(
+            function success(request) { return request.data; },
+            function failure(request) { throw new Error(request.data); }
+        );
+    }
+
+    return wrappedHttpCall;
+}]);

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/schemaService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/schemaService.js b/guacamole/src/main/webapp/app/rest/services/schemaService.js
index 851bffe..cc871d8 100644
--- a/guacamole/src/main/webapp/app/rest/services/schemaService.js
+++ b/guacamole/src/main/webapp/app/rest/services/schemaService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         function schemaService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
 
@@ -55,7 +55,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         };
 
         // Retrieve available user attributes
-        return $http({
+        return requestService({
             cache   : cacheService.schema,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/userAttributes',
@@ -89,7 +89,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         };
 
         // Retrieve available connection attributes
-        return $http({
+        return requestService({
             cache   : cacheService.schema,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/connectionAttributes',
@@ -123,7 +123,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         };
 
         // Retrieve available sharing profile attributes
-        return $http({
+        return requestService({
             cache   : cacheService.schema,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/sharingProfileAttributes',
@@ -157,7 +157,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         };
 
         // Retrieve available connection group attributes
-        return $http({
+        return requestService({
             cache   : cacheService.schema,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/connectionGroupAttributes',
@@ -188,7 +188,7 @@ angular.module('rest').factory('schemaService', ['$injector',
         };
 
         // Retrieve available protocols
-        return $http({
+        return requestService({
             cache   : cacheService.schema,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/schema/protocols',

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/sharingProfileService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/sharingProfileService.js b/guacamole/src/main/webapp/app/rest/services/sharingProfileService.js
index 4f1f905..0d8b66d 100644
--- a/guacamole/src/main/webapp/app/rest/services/sharingProfileService.js
+++ b/guacamole/src/main/webapp/app/rest/services/sharingProfileService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
         function sharingProfileService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
     
@@ -43,7 +43,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
      * 
      * @example
      * 
-     * sharingProfileService.getSharingProfile('mySharingProfile').success(function(sharingProfile) {
+     * sharingProfileService.getSharingProfile('mySharingProfile').then(function(sharingProfile) {
      *     // Do something with the sharing profile
      * });
      */
@@ -55,7 +55,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
         };
 
         // Retrieve sharing profile
-        return $http({
+        return requestService({
             cache   : cacheService.connections,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/sharingProfiles/' + encodeURIComponent(id),
@@ -84,7 +84,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
         };
 
         // Retrieve sharing profile parameters
-        return $http({
+        return requestService({
             cache   : cacheService.connections,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/sharingProfiles/' + encodeURIComponent(id) + '/parameters',
@@ -116,7 +116,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
 
         // If sharing profile is new, add it and set the identifier automatically
         if (!sharingProfile.identifier) {
-            return $http({
+            return requestService({
                 method  : 'POST',
                 url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/sharingProfiles',
                 params  : httpParameters,
@@ -124,7 +124,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
             })
 
             // Set the identifier on the new sharing profile and clear the cache
-            .success(function sharingProfileCreated(newSharingProfile){
+            .then(function sharingProfileCreated(newSharingProfile){
                 sharingProfile.identifier = newSharingProfile.identifier;
                 cacheService.connections.removeAll();
 
@@ -136,7 +136,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
 
         // Otherwise, update the existing sharing profile
         else {
-            return $http({
+            return requestService({
                 method  : 'PUT',
                 url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/sharingProfiles/' + encodeURIComponent(sharingProfile.identifier),
                 params  : httpParameters,
@@ -144,7 +144,7 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
             })
             
             // Clear the cache
-            .success(function sharingProfileUpdated(){
+            .then(function sharingProfileUpdated(){
                 cacheService.connections.removeAll();
 
                 // Clear users cache to force reload of permissions for this
@@ -174,14 +174,14 @@ angular.module('rest').factory('sharingProfileService', ['$injector',
         };
 
         // Delete sharing profile
-        return $http({
+        return requestService({
             method  : 'DELETE',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/sharingProfiles/' + encodeURIComponent(sharingProfile.identifier),
             params  : httpParameters
         })
 
         // Clear the cache
-        .success(function sharingProfileDeleted(){
+        .then(function sharingProfileDeleted(){
             cacheService.connections.removeAll();
         });
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/tunnelService.js b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
index f8ee543..1dba527 100644
--- a/guacamole/src/main/webapp/app/rest/services/tunnelService.js
+++ b/guacamole/src/main/webapp/app/rest/services/tunnelService.js
@@ -28,10 +28,10 @@ angular.module('rest').factory('tunnelService', ['$injector',
     var Error = $injector.get('Error');
 
     // Required services
-    var $http                 = $injector.get('$http');
     var $q                    = $injector.get('$q');
     var $window               = $injector.get('$window');
     var authenticationService = $injector.get('authenticationService');
+    var requestService        = $injector.get('requestService');
 
     var service = {};
 
@@ -71,7 +71,7 @@ angular.module('rest').factory('tunnelService', ['$injector',
         };
 
         // Retrieve tunnels
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/tunnels',
             params  : httpParameters
@@ -100,7 +100,7 @@ angular.module('rest').factory('tunnelService', ['$injector',
         };
 
         // Retrieve all associated sharing profiles
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/tunnels/' + encodeURIComponent(tunnel)
                         + '/activeConnection/connection/sharingProfiles',
@@ -136,7 +136,7 @@ angular.module('rest').factory('tunnelService', ['$injector',
         };
 
         // Generate sharing credentials
-        return $http({
+        return requestService({
             method  : 'GET',
             url     : 'api/session/tunnels/' + encodeURIComponent(tunnel)
                         + '/activeConnection/sharingCredentials/'

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/rest/services/userService.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/rest/services/userService.js b/guacamole/src/main/webapp/app/rest/services/userService.js
index 659aed7..bbf5fcf 100644
--- a/guacamole/src/main/webapp/app/rest/services/userService.js
+++ b/guacamole/src/main/webapp/app/rest/services/userService.js
@@ -24,7 +24,7 @@ angular.module('rest').factory('userService', ['$injector',
         function userService($injector) {
 
     // Required services
-    var $http                 = $injector.get('$http');
+    var requestService        = $injector.get('requestService');
     var $q                    = $injector.get('$q');
     var authenticationService = $injector.get('authenticationService');
     var cacheService          = $injector.get('cacheService');
@@ -67,7 +67,7 @@ angular.module('rest').factory('userService', ['$injector',
             httpParameters.permission = permissionTypes;
 
         // Retrieve users
-        return $http({
+        return requestService({
             cache   : cacheService.users,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users',
@@ -100,7 +100,7 @@ angular.module('rest').factory('userService', ['$injector',
         };
 
         // Retrieve user
-        return $http({
+        return requestService({
             cache   : cacheService.users,
             method  : 'GET',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username),
@@ -133,14 +133,14 @@ angular.module('rest').factory('userService', ['$injector',
         };
 
         // Delete user
-        return $http({
+        return requestService({
             method  : 'DELETE',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(user.username),
             params  : httpParameters
         })
 
         // Clear the cache
-        .success(function userDeleted(){
+        .then(function userDeleted(){
             cacheService.users.removeAll();
         });
 
@@ -171,7 +171,7 @@ angular.module('rest').factory('userService', ['$injector',
         };
 
         // Create user
-        return $http({
+        return requestService({
             method  : 'POST',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users',
             params  : httpParameters,
@@ -179,7 +179,7 @@ angular.module('rest').factory('userService', ['$injector',
         })
 
         // Clear the cache
-        .success(function userCreated(){
+        .then(function userCreated(){
             cacheService.users.removeAll();
         });
 
@@ -209,7 +209,7 @@ angular.module('rest').factory('userService', ['$injector',
         };
 
         // Update user
-        return $http({
+        return requestService({
             method  : 'PUT',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(user.username),
             params  : httpParameters,
@@ -217,7 +217,7 @@ angular.module('rest').factory('userService', ['$injector',
         })
 
         // Clear the cache
-        .success(function userUpdated(){
+        .then(function userUpdated(){
             cacheService.users.removeAll();
         });
 
@@ -254,7 +254,7 @@ angular.module('rest').factory('userService', ['$injector',
         };
 
         // Update user password
-        return $http({
+        return requestService({
             method  : 'PUT',
             url     : 'api/session/data/' + encodeURIComponent(dataSource) + '/users/' + encodeURIComponent(username) + '/password',
             params  : httpParameters,

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
index 09ce841..36da4ad 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnectionHistory.js
@@ -169,7 +169,7 @@ angular.module('settings').directive('guacSettingsConnectionHistory', [function
                         return predicate === 'startDate' || predicate === '-startDate';
                     })
                 )
-                .success(function historyRetrieved(historyEntries) {
+                .then(function historyRetrieved(historyEntries) {
 
                     // Wrap all history entries for sake of display
                     $scope.historyEntryWrappers = [];

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
index a245fb2..dd9f5c8 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsConnections.js
@@ -405,7 +405,7 @@ angular.module('settings').directive('guacSettingsConnections', [function guacSe
 
             // Retrieve current permissions
             permissionService.getEffectivePermissions($scope.dataSource, currentUsername)
-            .success(function permissionsRetrieved(permissions) {
+            .then(function permissionsRetrieved(permissions) {
 
                 // Store retrieved permissions
                 $scope.permissions = permissions;

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
index 655f233..12039b1 100644
--- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
+++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js
@@ -150,7 +150,7 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
                 
                 // Save the user with the new password
                 userService.updateUserPassword(dataSource, username, $scope.oldPassword, $scope.newPassword)
-                .success(function passwordUpdated() {
+                .then(function passwordUpdated() {
                 
                     // Clear the password fields
                     $scope.oldPassword      = null;
@@ -167,7 +167,7 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
                 })
                 
                 // Notify of any errors
-                .error(function passwordUpdateFailed(error) {
+                ['catch'](function passwordUpdateFailed(error) {
                     guacNotification.showStatus({
                         className  : 'error',
                         title      : 'SETTINGS_PREFERENCES.DIALOG_HEADER_ERROR',
@@ -180,20 +180,25 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
 
             // Retrieve defined languages
             languageService.getLanguages()
-            .success(function languagesRetrieved(languages) {
-                $scope.languages = languages;
+            .then(function languagesRetrieved(languages) {
+                $scope.languages = Object.keys(languages).map(function(key) {
+                    return {
+                        key: key,
+                        value: languages[key]
+                    };
+                })
             });
 
             // Retrieve current permissions
             permissionService.getEffectivePermissions(dataSource, username)
-            .success(function permissionsRetrieved(permissions) {
+            .then(function permissionsRetrieved(permissions) {
 
                 // Add action for changing password if permission is granted
                 $scope.canChangePassword = PermissionSet.hasUserPermission(permissions,
                         PermissionSet.ObjectPermissionType.UPDATE, username);
                         
             })
-            .error(function permissionsFailed(error) {
+            ['catch'](function permissionsFailed(error) {
                 $scope.canChangePassword = false;
             });
 

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/app/settings/templates/settingsPreferences.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/app/settings/templates/settingsPreferences.html b/guacamole/src/main/webapp/app/settings/templates/settingsPreferences.html
index 9ce0f90..826a5cd 100644
--- a/guacamole/src/main/webapp/app/settings/templates/settingsPreferences.html
+++ b/guacamole/src/main/webapp/app/settings/templates/settingsPreferences.html
@@ -9,7 +9,7 @@
             <table class="fields">
                 <tr>
                     <th>{{'SETTINGS_PREFERENCES.FIELD_HEADER_LANGUAGE' | translate}}</th>
-                    <td><select ng-model="preferences.language" ng-change="changeLanguage()" ng-options="key as name for (key, name) in languages | orderBy: name"></select></td>
+                    <td><select ng-model="preferences.language" ng-change="changeLanguage()" ng-options="language.key as language.value for language in languages | orderBy: key"></select></td>
                 </tr>
             </table>
         </div>

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/b3eeb36b/guacamole/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/guacamole/src/main/webapp/index.html b/guacamole/src/main/webapp/index.html
index 14321de..fd5dba4 100644
--- a/guacamole/src/main/webapp/index.html
+++ b/guacamole/src/main/webapp/index.html
@@ -61,15 +61,15 @@
         <script type="text/javascript" src="webjars/lodash/2.4.1/dist/lodash.min.js"></script>
 
         <!-- AngularJS -->
-        <script type="text/javascript" src="webjars/angular/1.3.16/angular.min.js"></script>
-        <script type="text/javascript" src="webjars/angular-route/1.3.16/angular-route.min.js"></script>
-        <script type="text/javascript" src="webjars/angular-touch/1.3.16/angular-touch.min.js"></script>
+        <script type="text/javascript" src="webjars/angular/1.6.9/angular.min.js"></script>
+        <script type="text/javascript" src="webjars/angular-route/1.6.9/angular-route.min.js"></script>
+        <script type="text/javascript" src="webjars/angular-touch/1.6.9/angular-touch.min.js"></script>
 
         <!-- Internationalization -->
         <script type="text/javascript" src="webjars/messageformat/1.0.2/messageformat.min.js"></script>
-        <script type="text/javascript" src="webjars/angular-translate/2.8.0/angular-translate.min.js"></script>
-        <script type="text/javascript" src="webjars/angular-translate-interpolation-messageformat/2.8.0/angular-translate-interpolation-messageformat.min.js"></script>
-        <script type="text/javascript" src="webjars/angular-translate-loader-static-files/2.8.0/angular-translate-loader-static-files.min.js"></script>
+        <script type="text/javascript" src="webjars/angular-translate/2.16.0/angular-translate.min.js"></script>
+        <script type="text/javascript" src="webjars/angular-translate-interpolation-messageformat/2.16.0/angular-translate-interpolation-messageformat.min.js"></script>
+        <script type="text/javascript" src="webjars/angular-translate-loader-static-files/2.16.0/angular-translate-loader-static-files.min.js"></script>
 
         <!-- Polyfills for Blob and the FileSaver API -->
         <script type="text/javascript" src="webjars/blob-polyfill/1.0.20150320/Blob.js"></script>


[2/3] guacamole-client git commit: GUACAMOLE-526: Remove no-longer-used licenses.

Posted by mj...@apache.org.
GUACAMOLE-526: Remove no-longer-used licenses.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/197ffc76
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/197ffc76
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/197ffc76

Branch: refs/heads/master
Commit: 197ffc76d069645f64f5be17b970d29da51c91fa
Parents: b3eeb36
Author: James Muehlner <ja...@guac-dev.org>
Authored: Wed Apr 25 22:32:46 2018 -0700
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Wed Apr 25 23:37:46 2018 -0700

----------------------------------------------------------------------
 .../src/licenses/bundled/angular-1.3.16/LICENSE | 21 --------------------
 .../bundled/angular-translate-2.8.0/LICENSE     | 21 --------------------
 2 files changed, 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/197ffc76/guacamole/src/licenses/bundled/angular-1.3.16/LICENSE
----------------------------------------------------------------------
diff --git a/guacamole/src/licenses/bundled/angular-1.3.16/LICENSE b/guacamole/src/licenses/bundled/angular-1.3.16/LICENSE
deleted file mode 100644
index 22fb301..0000000
--- a/guacamole/src/licenses/bundled/angular-1.3.16/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2014-2016 Google, Inc. http://angular.io
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/197ffc76/guacamole/src/licenses/bundled/angular-translate-2.8.0/LICENSE
----------------------------------------------------------------------
diff --git a/guacamole/src/licenses/bundled/angular-translate-2.8.0/LICENSE b/guacamole/src/licenses/bundled/angular-translate-2.8.0/LICENSE
deleted file mode 100644
index f3e753f..0000000
--- a/guacamole/src/licenses/bundled/angular-translate-2.8.0/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) <2014> <pa...@gmail.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.


[3/3] guacamole-client git commit: GUACAMOLE-526: Merge changes updating AngularJS to the latest stable (1.6.9).

Posted by mj...@apache.org.
GUACAMOLE-526: Merge changes updating AngularJS to the latest stable (1.6.9).


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/9a2e0c60
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/9a2e0c60
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/9a2e0c60

Branch: refs/heads/master
Commit: 9a2e0c60879ce0b7dc14870cdb5fe686e2c22eef
Parents: 74124ca 197ffc7
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Apr 26 09:55:31 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Apr 26 09:55:31 2018 -0700

----------------------------------------------------------------------
 guacamole/pom.xml                               | 12 ++---
 guacamole/src/licenses/LICENSE                  | 12 ++---
 .../src/licenses/bundled/angular-1.3.16/LICENSE | 21 ---------
 .../src/licenses/bundled/angular-1.6.9/LICENSE  | 21 +++++++++
 .../bundled/angular-translate-2.16.0/LICENSE    | 21 +++++++++
 .../bundled/angular-translate-2.8.0/LICENSE     | 21 ---------
 .../app/auth/service/authenticationService.js   |  7 +--
 .../app/client/controllers/clientController.js  |  2 +-
 .../webapp/app/client/types/ManagedClient.js    |  6 +--
 .../webapp/app/index/config/indexRouteConfig.js |  3 ++
 .../index/config/templateRequestDecorator.js    |  2 +-
 .../webapp/app/index/filters/arrayFilter.js     | 41 +++++++++++++++++
 .../app/locale/services/translationLoader.js    | 15 +++----
 .../controllers/manageConnectionController.js   | 22 ++++-----
 .../manageConnectionGroupController.js          | 16 +++----
 .../manageSharingProfileController.js           | 24 +++++-----
 .../manage/controllers/manageUserController.js  | 20 ++++-----
 .../app/manage/templates/manageConnection.html  |  2 +-
 .../app/navigation/directives/guacUserMenu.js   |  2 +-
 .../main/webapp/app/osk/directives/guacOsk.js   |  4 +-
 .../rest/services/activeConnectionService.js    | 10 ++---
 .../app/rest/services/connectionGroupService.js | 18 ++++----
 .../app/rest/services/connectionService.js      | 22 ++++-----
 .../app/rest/services/dataSourceService.js      | 14 +++---
 .../webapp/app/rest/services/historyService.js  |  4 +-
 .../webapp/app/rest/services/languageService.js |  4 +-
 .../webapp/app/rest/services/patchService.js    |  4 +-
 .../app/rest/services/permissionService.js      | 10 ++---
 .../webapp/app/rest/services/requestService.js  | 47 ++++++++++++++++++++
 .../webapp/app/rest/services/schemaService.js   | 12 ++---
 .../app/rest/services/sharingProfileService.js  | 20 ++++-----
 .../webapp/app/rest/services/tunnelService.js   |  8 ++--
 .../webapp/app/rest/services/userService.js     | 20 ++++-----
 .../directives/guacSettingsConnectionHistory.js |  2 +-
 .../directives/guacSettingsConnections.js       |  2 +-
 .../directives/guacSettingsPreferences.js       | 17 ++++---
 .../settings/templates/settingsPreferences.html |  2 +-
 guacamole/src/main/webapp/index.html            | 12 ++---
 38 files changed, 301 insertions(+), 201 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/9a2e0c60/guacamole/pom.xml
----------------------------------------------------------------------