keycloak-uncached

Details

diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index 90bc5ff..f618052 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -535,6 +535,7 @@ module.directive('onoffswitch', function() {
         replace: true,
         scope: {
             ngModel: '=',
+            ngDisabled: '=',
             ngBind: '=',
             name: '=',
             id: '=',
@@ -544,9 +545,11 @@ module.directive('onoffswitch', function() {
         compile: function(element, attrs) {
             if (!attrs.onText) { attrs.onText = "ON"; }
             if (!attrs.offText) { attrs.offText = "OFF"; }
+            if (!attrs.ngDisabled) { attrs.ngDisabled = false; }
 
-            var html = "<div class=\"onoffswitch\">" +
-                "<input type=\"checkbox\" data-ng-model=\"ngModel\" class=\"onoffswitch-checkbox\" name=\"" + attrs.name + "\" id=\"" + attrs.id + "\">" +
+            var html = "<span><div class=\"onoffswitch\" data-ng-class=\"{disabled: ngDisabled}\">" +
+                "<input type=\"checkbox\" data-ng-model=\"ngModel\" ng-disabled=\"ngDisabled\"" +
+                " class=\"onoffswitch-checkbox\" name=\"" + attrs.name + "\" id=\"" + attrs.id + "\">" +
                 "<label for=\"" + attrs.id + "\" class=\"onoffswitch-label\">" +
                 "<span class=\"onoffswitch-inner\">" +
                 "<span class=\"onoffswitch-active\">{{onText}}</span>" +
@@ -554,14 +557,13 @@ module.directive('onoffswitch', function() {
                 "</span>" +
                 "<span class=\"onoffswitch-switch\"></span>" +
                 "</label>" +
-                "</div>";
+                "</div></span>";
 
             element.replaceWith($(html));
         }
     }
 });
 
-
 module.directive('kcInput', function() {
     var d = {
         scope : true,
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js
index 0ae5b79..de73f63 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/users.js
@@ -231,20 +231,27 @@ module.controller('UserCredentialsCtrl', function($scope, realm, user, User, Use
     $scope.realm = realm;
     $scope.user = angular.copy(user);
 
+    $scope.isTotp = false;
+    if(!!user.totp){
+        $scope.isTotp = user.totp;
+    }
+
     $scope.resetPassword = function() {
 
-        if ($scope.password != $scope.confirmPassword) {
-            Notifications.error("Password and confirmation does not match.");
-            $scope.password = "";
-            $scope.confirmPassword = "";
-            return;
-        }
+        if ($scope.pwdChange) {
+            if ($scope.password != $scope.confirmPassword) {
+                Notifications.error("Password and confirmation does not match.");
+                $scope.password = "";
+                $scope.confirmPassword = "";
+                return;
+            }
 
-        if (!$scope.user.hasOwnProperty('requiredActions')){
-            $scope.user.requiredActions = [];
-        }
-        if ($scope.user.requiredActions.indexOf("UPDATE_PASSWORD") < 0){
-            $scope.user.requiredActions.push("UPDATE_PASSWORD");
+            if (!$scope.user.hasOwnProperty('requiredActions')){
+                $scope.user.requiredActions = [];
+            }
+            if ($scope.user.requiredActions.indexOf("UPDATE_PASSWORD") < 0){
+                $scope.user.requiredActions.push("UPDATE_PASSWORD");
+            }
         }
 
         var credentials = [ { type : "password", value : $scope.password } ];
@@ -254,21 +261,65 @@ module.controller('UserCredentialsCtrl', function($scope, realm, user, User, Use
             userId: $scope.user.username
         }, $scope.user, function () {
 
-            UserCredentials.update({
-                realm: realm.id,
-                userId: $scope.user.username
-            }, credentials, function () {
-                Notifications.success("The user password has been reset. The user is required to change his password on" +
-                    " the next login.");
-            }, function () {
-                Notifications.error("Error while resetting user password. Be aware that the update password required action" +
-                    " was already set.");
-            });
+            $scope.isTotp = $scope.user.totp;
+
+            if ($scope.pwdChange){
+                UserCredentials.update({
+                    realm: realm.id,
+                    userId: $scope.user.username
+                }, credentials, function () {
+                    Notifications.success("The password has been reset. The user is required to change his password on" +
+                        " the next login.");
+                    $scope.password = "";
+                    $scope.confirmPassword = "";
+                    $scope.pwdChange = false;
+                    $scope.isTotp = user.totp;
+                    $scope.userChange = false;
+                }, function () {
+                    Notifications.error("Error while resetting user password. Be aware that the update password required action" +
+                        " was already set.");
+                });
+            } else {
+                Notifications.success("User settings was updated.");
+                $scope.isTotp = user.totp;
+                $scope.userChange = false;
+            }
 
         }, function () {
-            Notifications.error("Error while adding update password required action. Password was not reset.");
+            Notifications.error("Error while updating user settings.");
         });
     };
+
+    $scope.$watch('user', function() {
+        if (!angular.equals($scope.user, user)) {
+            $scope.userChange = true;
+        } else {
+            $scope.userChange = false;
+        }
+    }, true);
+
+    $scope.$watch('password', function() {
+        if (!!$scope.password){
+            $scope.pwdChange = true;
+        } else {
+            $scope.pwdChange = false;
+        }
+    }, true);
+
+    $scope.reset = function() {
+        $scope.password = "";
+        $scope.confirmPassword = "";
+
+        $scope.user = angular.copy(user);
+
+        $scope.isTotp = false;
+        if(!!user.totp){
+            $scope.isTotp = user.totp;
+        }
+
+        $scope.pwdChange = false;
+        $scope.userChange = false;
+    };
 });
 
 module.controller('RoleMappingCtrl', function($scope, realm, User, users, role, RoleMapping, Notifications) {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-credentials.html
index a732945..8f3de02 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-credentials.html
@@ -14,10 +14,11 @@
                     <li><a href="#/realms/{{realm.id}}">{{realm.realm}}</a></li>
                     <li class="active">Users</li>
                 </ol>
-                <h2><span>{{user.username}}'s</span> Reset Password</h2>
+                <h2><span>{{user.username}}'s</span> Credentials</h2>
 
                 <form name="userForm" novalidate>
                     <fieldset class="border-top">
+                        <legend uncollapsed><span class="text">Reset Password</span></legend>
                         <div class="form-group">
                             <label for="password">New Password</label>
                             <div class="controls">
@@ -28,14 +29,20 @@
                         <div class="form-group">
                             <label class="two-lines" for="password">New Password Confirmation</label>
                             <div class="controls">
-                                <input type="password" id="confirmPassword" name="confirmPassword" data-ng-model="confirmPassword"
-                                       required>
+                                <input type="password" id="confirmPassword" name="confirmPassword"
+                                       data-ng-model="confirmPassword" required>
                             </div>
                         </div>
+                        <div class="form-group clearfix block" >
+                            <label for="userTotp" class="control-label">TOTP Enabled</label>
+                            <input ng-model="user.totp" name="userTotp" class="kokosak"  ng-disabled="!isTotp" id="userTotp" onoffswitch/>
+                        </div>
                     </fieldset>
                     <div class="form-actions">
-                        <button type="submit" class="primary" data-ng-click="resetPassword()"
-                                ng-show="password != null">Reset Password</button>
+                        <button type="submit" data-ng-click="resetPassword()" class="primary" data-ng-show="userChange && !pwdChange">Save</button>
+                        <button type="submit" data-ng-click="resetPassword()" class="primary" data-ng-show="!userChange && pwdChange">Reset Password</button>
+                        <button type="submit" data-ng-click="resetPassword()" class="primary" data-ng-show="userChange && pwdChange">Save and Reset Password</button>
+                        <button type="submit" kc-reset data-ng-show="userChange || pwdChange">Clear changes</button>
                     </div>
                 </form>
 
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
index 13b60ce..0735afa 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/user-detail.html
@@ -71,10 +71,6 @@
                             <input ng-model="user.enabled" name="userEnabled" id="userEnabled" onoffswitch />
                         </div>
                         <div class="form-group clearfix block">
-                            <label for="userTotp" class="control-label">TOTP Enabled</label>
-                            <input ng-model="user.totp" name="userTotp" id="userTotp" onoffswitch />
-                        </div>
-                        <div class="form-group clearfix block">
                             <label for="emailVerified" class="control-label">Email verified</label>
                             <input ng-model="user.emailVerified" name="emailVerified" id="emailVerified" onoffswitch />
                         </div>