mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUAC-1161: Convert login page to directive which accepts a dynamic form. Display login directive when credentials are needed.
This commit is contained in:
		| @@ -1,31 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 Glyptodon LLC | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * The config block for setting up the authentication interceptor. | ||||
|  */ | ||||
| angular.module('index').config(['$httpProvider',  | ||||
|         function indexInterceptorConfig($httpProvider) { | ||||
|     $httpProvider.interceptors.push('authenticationInterceptor'); | ||||
| }]); | ||||
|  | ||||
|  | ||||
| @@ -161,15 +161,6 @@ angular.module('index').config(['$routeProvider', '$locationProvider', | ||||
|             resolve       : { updateCurrentToken: updateCurrentToken } | ||||
|         }) | ||||
|  | ||||
|         // Login screen | ||||
|         .when('/login/', { | ||||
|             title         : 'APP.NAME', | ||||
|             bodyClassName : 'login', | ||||
|             templateUrl   : 'app/login/templates/login.html', | ||||
|             controller    : 'loginController' | ||||
|             // No need to update token here - the login screen ignores all auth | ||||
|         }) | ||||
|  | ||||
|         // Client view | ||||
|         .when('/client/:type/:id/:params?', { | ||||
|             bodyClassName : 'client', | ||||
|   | ||||
| @@ -36,6 +36,14 @@ angular.module('index').controller('indexController', ['$scope', '$injector', | ||||
|      */ | ||||
|     $scope.guacNotification = guacNotification; | ||||
|  | ||||
|     /** | ||||
|      * The credentials that the authentication service is currently expecting, | ||||
|      * if any. If the user is logged in, this will be null. | ||||
|      * | ||||
|      * @type Form[]|Form|Field[]|Field | ||||
|      */ | ||||
|     $scope.expectedCredentials = null; | ||||
|  | ||||
|     /** | ||||
|      * Basic page-level information. | ||||
|      */ | ||||
| @@ -92,6 +100,21 @@ angular.module('index').controller('indexController', ['$scope', '$injector', | ||||
|         keyboard.reset(); | ||||
|     }; | ||||
|  | ||||
|     // Display login screen if a whole new set of credentials is needed | ||||
|     $scope.$on('guacInvalidCredentials', function loginInvalid(event, parameters, expected) { | ||||
|         $scope.expectedCredentials = expected; | ||||
|     }); | ||||
|  | ||||
|     // Prompt for remaining credentials if provided credentials were not enough | ||||
|     $scope.$on('guacInsufficientCredentials', function loginInsufficient(event, parameters, expected) { | ||||
|         // TODO: Implement insufficient credential prompting | ||||
|     }); | ||||
|  | ||||
|     // Clear login screen if login was successful | ||||
|     $scope.$on('guacLogin', function loginSuccessful() { | ||||
|         $scope.expectedCredentials = null; | ||||
|     }); | ||||
|  | ||||
|     // Update title and CSS class upon navigation | ||||
|     $scope.$on('$routeChangeSuccess', function(event, current, previous) { | ||||
|         | ||||
|   | ||||
| @@ -1,63 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 Glyptodon LLC | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| angular.module('index').factory('authenticationInterceptor', ['$injector', | ||||
|         function authenticationInterceptor($injector) { | ||||
|  | ||||
|     // Required services | ||||
|     var $location = $injector.get('$location'); | ||||
|     var $q        = $injector.get('$q'); | ||||
|  | ||||
|     var service = {}; | ||||
|  | ||||
|     /** | ||||
|      * Redirect users to login if authorization fails. This is called | ||||
|      * automatically when this service is registered as an interceptor, as | ||||
|      * documented at: | ||||
|      *  | ||||
|      * https://docs.angularjs.org/api/ng/service/$http#interceptors | ||||
|      * | ||||
|      * @param {HttpPromise} rejection | ||||
|      *     The promise associated with the HTTP request that failed. | ||||
|      * | ||||
|      * @returns {Promise} | ||||
|      *     A rejected promise containing the originally-rejected HttpPromise. | ||||
|      */ | ||||
|     service.responseError = function responseError(rejection) { | ||||
|  | ||||
|         // Only redirect failed authentication requests | ||||
|         if ((rejection.status === 401 || rejection.status === 403) | ||||
|                 && rejection.config.url  === 'api/tokens') { | ||||
|  | ||||
|             // Only redirect if not already on login page | ||||
|             if ($location.path() !== '/login/') | ||||
|                 $location.path('/login/'); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $q.reject(rejection); | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     return service; | ||||
|  | ||||
| }]); | ||||
| @@ -1,71 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 Glyptodon LLC | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| angular.module('login').controller('loginController', ['$scope', '$injector', | ||||
|         function loginController($scope, $injector) { | ||||
|              | ||||
|     // Required services | ||||
|     var $location             = $injector.get('$location'); | ||||
|     var authenticationService = $injector.get('authenticationService'); | ||||
|     var userPageService       = $injector.get('userPageService'); | ||||
|  | ||||
|     /** | ||||
|      * Whether an error occurred during login. | ||||
|      *  | ||||
|      * @type Boolean | ||||
|      */ | ||||
|     $scope.loginError = false; | ||||
|  | ||||
|     /** | ||||
|      * Whether the password field has focus. | ||||
|      *  | ||||
|      * @type Boolean | ||||
|      */ | ||||
|     $scope.passwordFocused = false; | ||||
|  | ||||
|     /** | ||||
|      * Submits the currently-specified username and password to the | ||||
|      * authentication service, redirecting to the main view if successful. | ||||
|      */ | ||||
|     $scope.login = function login() { | ||||
|  | ||||
|         // Attempt login once existing session is destroyed | ||||
|         authenticationService.login($scope.username, $scope.password) | ||||
|  | ||||
|         // Redirect to main view upon success | ||||
|         .then(function loginSuccessful() { | ||||
|             userPageService.getHomePage() | ||||
|             .then(function homePageRetrieved(homePage) { | ||||
|                 $location.url(homePage.url); | ||||
|             }); | ||||
|         }) | ||||
|  | ||||
|         // Reset and focus password upon failure | ||||
|         ['catch'](function loginFailed() { | ||||
|             $scope.loginError = true; | ||||
|             $scope.passwordFocused = true; | ||||
|             $scope.password = ''; | ||||
|         }); | ||||
|  | ||||
|     }; | ||||
|  | ||||
| }]); | ||||
							
								
								
									
										96
									
								
								guacamole/src/main/webapp/app/login/directives/login.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								guacamole/src/main/webapp/app/login/directives/login.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 Glyptodon LLC | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * A directive for displaying an arbitrary login form. | ||||
|  */ | ||||
| angular.module('login').directive('guacLogin', [function guacLogin() { | ||||
|  | ||||
|     // Login directive | ||||
|     var directive = { | ||||
|         restrict    : 'E', | ||||
|         replace     : true, | ||||
|         templateUrl : 'app/login/templates/login.html' | ||||
|     }; | ||||
|  | ||||
|     // Login directive scope | ||||
|     directive.scope = { | ||||
|  | ||||
|         /** | ||||
|          * The login form or set of fields. This will be displayed to the user | ||||
|          * to capture their credentials. | ||||
|          * | ||||
|          * @type Form[]|Form|Field[]|Field  | ||||
|          */ | ||||
|         form : '=' | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     // Controller for login directive | ||||
|     directive.controller = ['$scope', '$injector', | ||||
|         function loginController($scope, $injector) { | ||||
|          | ||||
|         // Required services | ||||
|         var $route                = $injector.get('$route'); | ||||
|         var authenticationService = $injector.get('authenticationService'); | ||||
|  | ||||
|         /** | ||||
|          * Whether an error occurred during login. | ||||
|          *  | ||||
|          * @type Boolean | ||||
|          */ | ||||
|         $scope.loginError = false; | ||||
|  | ||||
|         /** | ||||
|          * All form values entered by the user. | ||||
|          */ | ||||
|         $scope.values = {}; | ||||
|  | ||||
|         /** | ||||
|          * Submits the currently-specified username and password to the | ||||
|          * authentication service, redirecting to the main view if successful. | ||||
|          */ | ||||
|         $scope.login = function login() { | ||||
|  | ||||
|             // Attempt login once existing session is destroyed | ||||
|             authenticationService.authenticate($scope.values) | ||||
|  | ||||
|             // Clear and reload upon success | ||||
|             .then(function loginSuccessful() { | ||||
|                 $scope.loginError = false; | ||||
|                 $scope.values = {}; | ||||
|                 $route.reload(); | ||||
|             }) | ||||
|  | ||||
|             // Reset upon failure | ||||
|             ['catch'](function loginFailed() { | ||||
|                 $scope.loginError = true; | ||||
|                 $scope.values.password = ''; | ||||
|             }); | ||||
|  | ||||
|         }; | ||||
|  | ||||
|     }]; | ||||
|  | ||||
|     return directive; | ||||
|  | ||||
| }]); | ||||
| @@ -23,4 +23,8 @@ | ||||
| /** | ||||
|  * The module for the login functionality. | ||||
|  */ | ||||
| angular.module('login', ['element', 'navigation']); | ||||
| angular.module('login', [ | ||||
|     'element', | ||||
|     'form', | ||||
|     'navigation' | ||||
| ]); | ||||
|   | ||||
| @@ -27,6 +27,8 @@ div.login-ui { | ||||
|     left: 0; | ||||
|     top: 0; | ||||
|     display: table; | ||||
|     background: white; | ||||
|     z-index: 20; | ||||
| } | ||||
|  | ||||
| p.login-error { | ||||
| @@ -52,3 +54,35 @@ p.login-error { | ||||
|     text-align: center; | ||||
|     color: #964040; | ||||
| } | ||||
|  | ||||
| .login-fields .form-field .password-field .toggle-password { | ||||
|     display: none; | ||||
| } | ||||
|  | ||||
| .login-fields .labeled-field { | ||||
|     display: block; | ||||
|     position: relative; | ||||
| } | ||||
|  | ||||
| .login-fields .field-header { | ||||
|  | ||||
|   display: block; | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   overflow: hidden; | ||||
|  | ||||
|   z-index: -1; | ||||
|   margin: 0.5em; | ||||
|   font-size: 0.9em; | ||||
|   opacity: 0.5; | ||||
|  | ||||
| } | ||||
|  | ||||
| .login-fields .form-field.empty input { | ||||
|     background: transparent; | ||||
| } | ||||
|  | ||||
| .login-fields .form-field input:focus { | ||||
|     background: white; | ||||
| } | ||||
|   | ||||
| @@ -1,26 +1,25 @@ | ||||
| <!-- | ||||
| Copyright 2014 Glyptodon LLC. | ||||
|  | ||||
| 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. | ||||
| --> | ||||
|  | ||||
| <div class="login-ui" ng-class="{error: loginError}" > | ||||
|     <!-- | ||||
|     Copyright 2014 Glyptodon LLC. | ||||
|  | ||||
|     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. | ||||
|     --> | ||||
|  | ||||
|     <!-- Login error message --> | ||||
|     <p class="login-error">{{'LOGIN.ERROR_INVALID_LOGIN' | translate}}</p> | ||||
| @@ -35,10 +34,9 @@ THE SOFTWARE. | ||||
|                 <img class="logo" src="images/guac-tricolor.png" alt=""/> | ||||
|                 <div class="version">{{'APP.NAME' | translate}}</div> | ||||
|  | ||||
|                 <!-- Login fields (username + password) --> | ||||
|                 <!-- Login fields --> | ||||
|                 <div class="login-fields"> | ||||
|                     <input ng-model="username" placeholder="{{'LOGIN.FIELD_PLACEHOLDER_USERNAME' | translate}}" type="text" name="username" autofocus="autofocus" autocorrect="off" autocapitalize="off" class="username"/> | ||||
|                     <input ng-model="password" placeholder="{{'LOGIN.FIELD_PLACEHOLDER_PASSWORD' | translate}}" type="password" name="password" class="password" guac-focus="passwordFocused"/> | ||||
|                     <guac-form namespace="'LOGIN'" content="form" model="values"></guac-form> | ||||
|                 </div> | ||||
|  | ||||
|                 <!-- Submit button --> | ||||
|   | ||||
| @@ -48,6 +48,7 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu() | ||||
|             // Get required services | ||||
|             var $document             = $injector.get('$document'); | ||||
|             var $location             = $injector.get('$location'); | ||||
|             var $route                = $injector.get('$route'); | ||||
|             var authenticationService = $injector.get('authenticationService'); | ||||
|             var userPageService       = $injector.get('userPageService'); | ||||
|  | ||||
| @@ -100,12 +101,15 @@ angular.module('navigation').directive('guacUserMenu', [function guacUserMenu() | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Logs out the current user, redirecting them to back to the login | ||||
|              * screen after logout completes. | ||||
|              * Logs out the current user, redirecting them to back to the root | ||||
|              * after logout completes. | ||||
|              */ | ||||
|             $scope.logout = function logout() { | ||||
|                 authenticationService.logout()['finally'](function logoutComplete() { | ||||
|                     $location.path('/login/'); | ||||
|                     if ($location.path() !== '/') | ||||
|                         $location.url('/'); | ||||
|                     else | ||||
|                         $route.reload(); | ||||
|                 }); | ||||
|             }; | ||||
|  | ||||
|   | ||||
| @@ -34,22 +34,30 @@ THE SOFTWARE. | ||||
|     </head> | ||||
|     <body ng-class="page.bodyClassName"> | ||||
|  | ||||
|         <!-- Global status/error dialog --> | ||||
|         <div ng-class="{shown: guacNotification.status}" class="status-outer"> | ||||
|             <div class="status-middle"> | ||||
|                 <guac-notification notification="guacNotification.status"></guac-notification> | ||||
|         <!-- Content for logged-in users --> | ||||
|         <div ng-show="!expectedCredentials"> | ||||
|          | ||||
|             <!-- Global status/error dialog --> | ||||
|             <div ng-class="{shown: guacNotification.status}" class="status-outer"> | ||||
|                 <div class="status-middle"> | ||||
|                     <guac-notification notification="guacNotification.status"></guac-notification> | ||||
|                 </div> | ||||
|             </div> | ||||
|              | ||||
|             <div id="content" ng-view> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Notification area --> | ||||
|             <div id="notificationArea"> | ||||
|                 <div ng-repeat="wrapper in guacNotification.notifications"> | ||||
|                     <guac-notification notification="wrapper.notification"></guac-notification> | ||||
|                 </div>                 | ||||
|             </div> | ||||
|  | ||||
|         </div> | ||||
|          | ||||
|         <div id="content" ng-view> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Notification area --> | ||||
|         <div id="notificationArea"> | ||||
|             <div ng-repeat="wrapper in guacNotification.notifications"> | ||||
|                 <guac-notification notification="wrapper.notification"></guac-notification> | ||||
|             </div>                 | ||||
|         </div> | ||||
|  | ||||
|         <!-- Login screen for logged-out users --> | ||||
|         <guac-login ng-show="expectedCredentials" form="expectedCredentials"></guac-login> | ||||
|          | ||||
|         <script type="text/javascript" src="guacamole.min.js"></script> | ||||
|     </body> | ||||
|   | ||||
| @@ -141,12 +141,12 @@ | ||||
|  | ||||
|     "LOGIN": { | ||||
|  | ||||
|         "ACTION_LOGIN"               : "@:APP.ACTION_LOGIN", | ||||
|         "ACTION_LOGIN" : "@:APP.ACTION_LOGIN", | ||||
|  | ||||
|         "ERROR_INVALID_LOGIN"        : "Invalid Login", | ||||
|         "ERROR_INVALID_LOGIN" : "Invalid Login", | ||||
|  | ||||
|         "FIELD_PLACEHOLDER_USERNAME" : "Username", | ||||
|         "FIELD_PLACEHOLDER_PASSWORD" : "Password" | ||||
|         "FIELD_HEADER_USERNAME" : "Username", | ||||
|         "FIELD_HEADER_PASSWORD" : "Password" | ||||
|  | ||||
|     }, | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user