diff --git a/themes/src/main/resources/theme/base/admin/resources/js/app.js b/themes/src/main/resources/theme/base/admin/resources/js/app.js
index c4a134b..5f58e88 100755
--- a/themes/src/main/resources/theme/base/admin/resources/js/app.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/app.js
@@ -2168,15 +2168,29 @@ module.directive('kcEnter', function() {
};
});
-module.directive('kcSave', function ($compile, Notifications) {
+module.directive('kcSave', function ($compile, $timeout, Notifications) {
+ var clickDelay = 500; // 500 ms
+
return {
restrict: 'A',
link: function ($scope, elem, attr, ctrl) {
elem.addClass("btn btn-primary");
elem.attr("type","submit");
- elem.bind('click', function() {
+
+ var disabled = false;
+ elem.on('click', function(evt) {
if ($scope.hasOwnProperty("changed") && !$scope.changed) return;
+ // KEYCLOAK-4121: Prevent double form submission
+ if (disabled) {
+ evt.preventDefault();
+ evt.stopImmediatePropagation();
+ return;
+ } else {
+ disabled = true;
+ $timeout(function () { disabled = false; }, clickDelay, false);
+ }
+
$scope.$apply(function() {
var form = elem.closest('form');
if (form && form.attr('name')) {