You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by sk...@apache.org on 2019/04/17 09:14:40 UTC

[syncope] branch master updated: [SYNCOPE-1421] Added 'Confirm password reset' page in Enduser, added style to 'Password reset' page in Enduser, added new style for 'Must change password' page in Admin Console, other fixes

This is an automated email from the ASF dual-hosted git repository.

skylark17 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new f7f4f0a  [SYNCOPE-1421] Added 'Confirm password reset' page in Enduser, added style to 'Password reset' page in Enduser, added new style for 'Must change password' page in Admin Console, other fixes
f7f4f0a is described below

commit f7f4f0ab2b79c4d7adfc993d2c3235a351040137
Author: skylark17 <ma...@tirasa.net>
AuthorDate: Wed Apr 17 10:26:52 2019 +0200

    [SYNCOPE-1421] Added 'Confirm password reset' page in Enduser, added style to 'Password reset' page in Enduser, added new style for 'Must change password' page in Admin Console, other fixes
---
 .../client/console/pages/MustChangePassword.java   |   3 +
 .../META-INF/resources/css/syncopeConsole.scss     |  25 ++-
 .../apache/syncope/client/console/pages/Login.html |   1 +
 .../client/console/pages/MustChangePassword.html   |  71 +++++--
 .../client/enduser/SyncopeWebApplication.java      |   6 +-
 .../Navbar.java}                                   |  18 +-
 .../client/enduser/pages/BaseEnduserWebPage.java   |   8 +
 .../enduser/pages/SelfConfirmPasswordReset.java    | 135 ++++++++++++
 .../client/enduser/pages/SelfPasswordReset.java    |   5 +-
 .../META-INF/resources/css/syncopeEnduser.scss     |  87 ++++++--
 .../syncope/client/enduser/navigation/Navbar.html  |  88 ++++++++
 .../client/enduser/pages/BaseEnduserWebPage.html   |  52 +----
 .../apache/syncope/client/enduser/pages/Login.html |   4 +-
 .../enduser/pages/SelfConfirmPasswordReset.html    |  59 ++++++
 .../SelfConfirmPasswordReset.properties}           |  16 +-
 .../SelfConfirmPasswordReset_it.properties}        |  14 +-
 .../SelfConfirmPasswordReset_ja.properties}        |  16 +-
 .../SelfConfirmPasswordReset_pt_BR.properties}     |  16 +-
 .../pages/SelfConfirmPasswordReset_ru.properties   |  24 +++
 .../client/enduser/pages/SelfPasswordReset.html    |  23 +-
 .../SelfPasswordReset.properties}                  |   2 +-
 .../SelfPasswordReset_it.properties}               |   2 +-
 .../SelfPasswordReset_ja.properties}               |   2 +-
 .../SelfPasswordReset_pt_BR.properties}            |   2 +-
 .../SelfPasswordReset_ru.properties}               |   2 +-
 .../client/enduser/panels/SelfPwdResetPanel.html   |  27 ++-
 .../enduser/panels/SelfPwdResetPanel_it.properties |   2 +-
 .../panels/SelfPwdResetPanel_pt_BR.properties      |   4 +-
 .../enduser/panels/SelfPwdResetPanel_ru.properties |   4 +-
 .../wizards/any/AbstractCaptchaPanel.properties    |   2 +-
 ...operties => AbstractCaptchaPanel_it.properties} |   2 +-
 ...operties => AbstractCaptchaPanel_ja.properties} |   2 +-
 ...rties => AbstractCaptchaPanel_pt_BR.properties} |   2 +-
 .../any/AbstractCaptchaPanel_ru.properties}        |   9 +-
 .../ui/commons/SyncopeUIRequestCycleListener.java  |   3 +-
 .../resources/ui-commons/css/animations.scss       |  61 ++----
 .../META-INF/resources/ui-commons/css/login.scss   |   3 +-
 .../resources/ui-commons/css/syncopeUI.scss        | 232 ++++++++++-----------
 .../META-INF/resources/ui-commons/css/utils.scss   |  30 ++-
 .../src/main/resources/domains/MasterContent.xml   |   4 +-
 .../src/test/resources/domains/MasterContent.xml   |   4 +-
 .../src/main/resources/domains/MasterContent.xml   |   4 +-
 .../src/test/resources/domains/MasterContent.xml   |   4 +-
 .../core/provisioning/java/MailTemplateTest.java   |   4 +-
 core/upgrade/src/test/resources/syncopedb20.sql    |   2 +-
 .../resources/domains/MasterContent.xml.pgjsonb    |   4 +-
 46 files changed, 739 insertions(+), 351 deletions(-)

diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
index f83ca8f..2ce4798 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
@@ -24,6 +24,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.UserSelfRestClient;
 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel;
 import org.apache.syncope.client.ui.commons.panels.NotificationPanel;
+import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.markup.html.WebPage;
@@ -113,5 +114,7 @@ public class MustChangePassword extends WebPage {
         form.setDefaultButton(submitButton);
 
         add(form);
+
+        add(new AttributeModifier("style", "height: \"100%\""));
     }
 }
diff --git a/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss b/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss
index 55ce70b..be5c813 100644
--- a/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss
+++ b/client/idrepo/console/src/main/resources/META-INF/resources/css/syncopeConsole.scss
@@ -19,6 +19,7 @@
 
 $background_console_darker: rgb(104, 145, 162);
 $background_console_dark: #00a65a;
+$background_console_white: #eee;
 
 
 
@@ -35,7 +36,6 @@ $background_console_dark: #00a65a;
 
 
 
-
 /* General
 ============================================================================= */
 
@@ -68,4 +68,25 @@ body {
       background-color: $background_console_dark;
     }
   }
-}
\ No newline at end of file
+}
+
+
+
+/* Must Change Password
+============================================================================= */
+
+#mcp_wrapper {
+  height: 100%;
+
+  #mcp_logo {
+    background: $background_console_white;
+  }
+
+  .card {
+    height: 100%;
+  }
+
+  .custom_content_wrapper {
+    padding: 2% 2% 0 2%;
+  }
+}
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
index c86fb43..dec4611 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/Login.html
@@ -53,6 +53,7 @@ under the License.
         </i>
       </div>
     </div>
+
     <div class="container">
       <div class="login-card card card-container">
         <img class="login-logo" src="ui-commons/img/logo-green.png" />
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/MustChangePassword.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/MustChangePassword.html
index f56c96d..2fe24b1 100644
--- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/MustChangePassword.html
+++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/MustChangePassword.html
@@ -17,7 +17,7 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org" class="max_height">
   <head>
     <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
     <meta charset="UTF-8"/>
@@ -33,23 +33,60 @@ under the License.
 
     <link href="ui-commons/css/syncopeUI.css" rel="stylesheet" type="text/css"/>
     <link href="css/syncopeConsole.css" rel="stylesheet" type="text/css"/>
+
+    <!-- accessibility -->
+    <link href="ui-commons/css/accessibility.css" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="ui-commons/js/accessibility.js"></script>
   </head>
-  <body>
-    <div class="container">
-      <div class="card card-container">
-        <img class="login-logo" src="ui-commons/img/logo-green.png" />
-
-        <span wicket:id="feedback"></span>
-
-        <div class="alert alert-success"><wicket:message key="passwordNeedsToBeUpdated"/></div>
-
-        <form class="form-signin" wicket:id="changePassword">
-          <input type="text" wicket:id="username" id="username" class="form-control" 
-                 wicket:message="placeholder:username" required="required" autofocus="autofocus" />
-          <span wicket:id="password" id="password"/>
-          <span wicket:id="confirmPassword" id="confirmPassword"/>
-          <button wicket:id="submit" type="submit" class="btn btn-lg btn-primary btn-block btn-signin"></button>
-        </form>
+
+  <body class="max_height">
+    <div id="accessibility">
+      <div id="change_contrast" class="btn-accessibility">
+        <i aria-label="Toggle high contrast colors mode" tabindex="0" accesskey="H"
+           class="fa fa-adjust">
+        </i>
+      </div>
+      <div id="change_fontSize" class="btn-accessibility">
+        <i aria-label="Toggle font size increment" tabindex="1" accesskey="F"
+           class="fa fa-font">
+        </i>
+      </div>
+    </div>
+
+    <div id="mcp_wrapper" class="container">
+      <div class="card card-container vertical_align">
+
+        <div class="custom_content_wrapper row">
+          <div class="col-xs-12">
+            <img id="mcp_logo" class="login-logo" src="ui-commons/img/logo-green.png" />
+
+            <span wicket:id="feedback"></span>
+
+            <div class="alert alert-success"><wicket:message key="passwordNeedsToBeUpdated"/></div>
+          </div>
+
+          <div class="col-xs-12">
+            <form id="mcp_form" class="form-group" wicket:id="changePassword">
+              <fieldset class="form-group">
+                <div class="form-group">
+                  <input type="text" wicket:id="username" id="username" class="form-control" 
+                         wicket:message="placeholder:username" required="required" autofocus="autofocus" />
+                </div>
+
+                <div class="form-group">
+                  <div wicket:id="password" id="password" class="form-group"/>
+                  <div wicket:id="confirmPassword" id="confirmPassword" class="form-group"/>
+                </div>
+
+                <div class="form-group" style="padding-top: 10px;">
+                  <input id="submit_button" wicket:id="submit" type="submit" wicket:message="value:submit" 
+                         class="btn btn-lg btn-primary btn-block btn-signin"/>
+                </div>
+              </fieldset>
+            </form>
+          </div>
+        </div>
+
       </div>
     </div>
 
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
index a6ccabe..4b57081 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java
@@ -47,6 +47,7 @@ import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
 import org.apache.syncope.client.enduser.pages.Login;
 import org.apache.syncope.client.enduser.pages.MustChangePassword;
 import org.apache.syncope.client.enduser.pages.Self;
+import org.apache.syncope.client.enduser.pages.SelfConfirmPasswordReset;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.client.ui.commons.SyncopeUIRequestCycleListener;
 import org.apache.syncope.common.lib.PropertyUtils;
@@ -283,6 +284,9 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
 
         });
 
+        // Confirm password reset page
+        mountPage("/confirmpasswordreset", SelfConfirmPasswordReset.class);
+
         for (Class<? extends AbstractResource> resource : lookup.getResources()) {
             Resource annotation = resource.getAnnotation(Resource.class);
             try {
@@ -301,7 +305,7 @@ public class SyncopeWebApplication extends WicketBootStandardWebApplication {
                 LOG.error("Could not instantiate {}", resource.getName(), e);
             }
         }
-        
+
         // enable component path
         if (getDebugSettings().isAjaxDebugModeEnabled()) {
             getDebugSettings().setComponentPathAttributeName("syncope-path");
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/navigation/Navbar.java
similarity index 64%
copy from client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java
copy to client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/navigation/Navbar.java
index 09f42b4..a0bd90a 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/navigation/Navbar.java
@@ -16,21 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.client.enduser.pages;
+package org.apache.syncope.client.enduser.navigation;
 
-import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.markup.html.panel.Panel;
 
-public class BaseEnduserWebPage extends BaseWebPage {
+public class Navbar extends Panel {
 
-    private static final long serialVersionUID = 5760583420031293480L;
+    private static final long serialVersionUID = 1323251762654401168L;
 
-    public BaseEnduserWebPage() {
-        this(null);
-    }
-
-    public BaseEnduserWebPage(final PageParameters parameters) {
-        super(parameters);
+    public Navbar(final String id) {
+        super(id);
+        setOutputMarkupId(true);
     }
 
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java
index 09f42b4..6a1b0b6 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.enduser.pages;
 
+import org.apache.syncope.client.enduser.navigation.Navbar;
 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
@@ -25,12 +26,19 @@ public class BaseEnduserWebPage extends BaseWebPage {
 
     private static final long serialVersionUID = 5760583420031293480L;
 
+    protected final Navbar navbar;
+
     public BaseEnduserWebPage() {
         this(null);
+
+        body.add(navbar);
     }
 
     public BaseEnduserWebPage(final PageParameters parameters) {
         super(parameters);
+
+        navbar = new Navbar("navbar");
+        body.add(navbar);
     }
 
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java
new file mode 100644
index 0000000..a511e90
--- /dev/null
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+package org.apache.syncope.client.enduser.pages;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPasswordFieldPanel;
+import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.markup.html.form.StatelessForm;
+import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SelfConfirmPasswordReset extends BaseEnduserWebPage {
+
+    private static final long serialVersionUID = -2166782304542750726L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(SelfConfirmPasswordReset.class);
+
+    public SelfConfirmPasswordReset(final PageParameters parameters) {
+        super(parameters);
+
+        if (parameters == null
+                || parameters.isEmpty()
+                || parameters.get("token").isNull()
+                || parameters.get("token").isEmpty()) {
+
+            LOG.debug("No token parameter found in the request url");
+            parameters.add("errorMessage", getString("self.confirm.pwd.reset.error.empty"));
+            setResponsePage(Login.class, parameters);
+        }
+
+        navbar.setEnabled(false);
+        navbar.setVisible(false);
+
+        WebMarkupContainer content = new WebMarkupContainer("content");
+        content.setOutputMarkupId(true);
+        body.add(content);
+
+        Form<?> form = new StatelessForm<>("selfConfirmPwdResetForm");
+        form.setOutputMarkupId(true);
+        content.add(form);
+
+        AjaxPasswordFieldPanel passwordField = new AjaxPasswordFieldPanel(
+                "password", getString("password"), new Model<>());
+        passwordField.setRequired(true);
+        passwordField.setMarkupId("password");
+        passwordField.setPlaceholder(getString("password"));
+        ((PasswordTextField) passwordField.getField()).setResetPassword(false);
+        form.add(passwordField);
+
+        FieldPanel<String> confirmPasswordField = new AjaxPasswordFieldPanel(
+                "confirmPassword", getString("confirm-password"), new Model<>());
+        confirmPasswordField.setRequired(true);
+        confirmPasswordField.setMarkupId("confirmPassword");
+        confirmPasswordField.setPlaceholder(getString("confirm-password"));
+        ((PasswordTextField) confirmPasswordField.getField()).setResetPassword(false);
+        form.add(confirmPasswordField);
+
+        form.add(new EqualPasswordInputValidator(passwordField.getField(), confirmPasswordField.getField()));
+
+        AjaxButton submitButton = new AjaxButton("submit", new Model<>(getString("submit"))) {
+
+            private static final long serialVersionUID = 509325877101838812L;
+
+            @Override
+            protected void onSubmit(final AjaxRequestTarget target) {
+                try {
+                    SyncopeEnduserSession.get().getService(UserSelfService.class)
+                            .confirmPasswordReset(parameters.get("token").toString(),
+                                    passwordField.getDefaultModelObjectAsString());
+                    final PageParameters parameters = new PageParameters();
+                    parameters.add("successMessage", getString("self.confirm.pwd.reset.success"));
+                    setResponsePage(Login.class, parameters);
+
+                } catch (SyncopeClientException sce) {
+                    LOG.error("Unable to complete the 'Password Reset Confirmation' process", sce);
+                    SyncopeEnduserSession.get().error(StringUtils.isBlank(sce.getMessage())
+                            ? sce.getClass().getName()
+                            : sce.getMessage());
+                    ((BaseEnduserWebPage) getPageReference().getPage()).getNotificationPanel().refresh(target);
+                }
+            }
+
+            @Override
+            protected void onError(final AjaxRequestTarget target) {
+                notificationPanel.refresh(target);
+            }
+
+        };
+        form.setDefaultButton(submitButton);
+        form.add(submitButton);
+
+        Button cancel = new Button("cancel") {
+
+            private static final long serialVersionUID = 3669569969172391336L;
+
+            @Override
+            public void onSubmit() {
+                setResponsePage(Login.class);
+            }
+
+        };
+        cancel.setOutputMarkupId(true);
+        cancel.setDefaultFormProcessing(false);
+        form.add(cancel);
+    }
+
+}
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfPasswordReset.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfPasswordReset.java
index ccc05ab..94cb6a2 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfPasswordReset.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfPasswordReset.java
@@ -32,13 +32,16 @@ public class SelfPasswordReset extends BaseEnduserWebPage {
     public SelfPasswordReset(final PageParameters parameters) {
         super(parameters);
 
+        navbar.setEnabled(false);
+        navbar.setVisible(false);
+
         WebMarkupContainer content = new WebMarkupContainer("content");
         content.setOutputMarkupId(true);
         body.add(content);
 
         Form<?> form = new Form<>("selfPwdResetForm");
         content.add(form);
-        
+
         pwdResetPanel = new SelfPwdResetPanel("selfPwdResetPanel", getPageReference());
         pwdResetPanel.setOutputMarkupId(true);
 
diff --git a/client/idrepo/enduser/src/main/resources/META-INF/resources/css/syncopeEnduser.scss b/client/idrepo/enduser/src/main/resources/META-INF/resources/css/syncopeEnduser.scss
index ad2d14c..33b9d88 100644
--- a/client/idrepo/enduser/src/main/resources/META-INF/resources/css/syncopeEnduser.scss
+++ b/client/idrepo/enduser/src/main/resources/META-INF/resources/css/syncopeEnduser.scss
@@ -120,16 +120,13 @@ body {
   > .wrapper .content-wrapper {
     width: 100%;
     margin: 0 2%;
-
-    background-color: #ffffff;
-    border-radius: 10px;
-
-    @include shadow(0px 0px 20px 1px rgba(0,0,0,0.75));
   }
 }
 
 
 
+
+
 /* Login
 ============================================================================= */
 
@@ -156,6 +153,15 @@ body {
   }
 }
 
+.login_link {
+  margin: 8px 0;
+
+  a {
+    text-decoration: none;
+  }
+}
+
+
 
 
 /* Wizard layout
@@ -203,7 +209,6 @@ body {
 
 }
 
-
 .wizard-buttons {
   display: table;
   height: 65px;
@@ -217,7 +222,7 @@ body {
 
   border-bottom-left-radius: 10px;
   border-bottom-right-radius: 10px;
-  background-color: #718a99;
+  background-color: $palette_darker;
 
   > div {
     display: table-cell;
@@ -246,6 +251,7 @@ body {
       &:active {
       color: inherit;
       background-color: $palette_lighter;
+      border-color: transparent;
     }
   }
 }
@@ -305,13 +311,6 @@ fieldset[disabled] .form-control {
 }
 
 
-/* 
-* Remove input placeholder on focus
-* ------------------------------ */
-input:focus::-webkit-input-placeholder { color:transparent; }
-input:focus:-moz-placeholder { color:transparent; } /* FF 4-18 */
-input:focus::-moz-placeholder { color:transparent; } /* FF 19+ */
-input:focus:-ms-input-placeholder { color:transparent; } /* IE 10+ */
 
 
 /* 
@@ -449,6 +448,15 @@ option {
     a {
       height: auto;
     }
+
+    > li {
+      > a {
+        &:focus, 
+          &:hover {
+          background-color: $palette_light;
+        }
+      }
+    }
   }
 
   .navbar-brand {
@@ -477,15 +485,32 @@ option {
       background-color: $palette_light;
     }
 
-    > li:not(.active):not(:hover):not(.open) > a {
-      color: #ffffff;
-      @include transition(.25s all ease);
+    > li {
+      &:not(.active):not(:hover):not(.open) {
+        > a {
+          &:not(:focus) {
+            color: #ffffff;
+          }
+          @include transition(.25s all ease);
+        }
+      }
     }
 
     @include phone {
-      .open {
-        .dropdown-menu > li > a {
-          color: #ffffff;
+      .dropdown {
+        a {
+          &.dropdown-toggle {
+            &:not(:focus) {
+              color: #ffffff;
+            }
+          }
+        }
+        &.open {
+          .dropdown-menu {
+            > li > a {
+              color: #ffffff;
+            }
+          }
         }
       }
     }
@@ -506,7 +531,7 @@ option {
     display: inline-block;
     position: absolute;
     border: 28px solid white;
-    border-color: transparent #718a99 transparent transparent; /* use the background color here */
+    border-color: transparent $palette_darker transparent transparent; /* use the background color here */
     top: 0px;
     right: -1px; /* 1px less than the other "before" element */
   }
@@ -536,3 +561,23 @@ option {
   }
 }
 
+
+
+/* Password Reset / Confirm Password Reset
+============================================================================= */
+
+.password_reset_wrapper {
+  padding-top: 25px;
+  padding-bottom: 25px;
+
+  .page-header {
+    text-align: center;
+  }
+  form {
+    text-align: center;
+
+    .password_reset_buttons {
+      padding-top: 30px;
+    }
+  }
+}
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/navigation/Navbar.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/navigation/Navbar.html
new file mode 100644
index 0000000..2ed32ca
--- /dev/null
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/navigation/Navbar.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:panel>
+    <nav class="enduser_navbar navbar navbar-default">
+      <div class="container-fluid">
+        <div class="navbar-header">
+          <button type="button" 
+                  class="navbar-toggle" 
+                  data-toggle="collapse" 
+                  data-target="#navbar"
+                  tabindex="1"
+                  aria-label="Toggle navigation bar"
+                  aria-expanded="true" 
+                  aria-controls="navbar">
+            <span class="sr-only">Toggle navigation</span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+          </button>
+
+          <a class="navbar-brand" href="#">
+            <span class="logo-mini"
+                  aria-label="Enduser logo"
+                  tabindex="0">
+              <img alt="Brand" src="ui-commons/img/logo-mini.png"/>
+            </span>
+          </a>
+        </div>
+
+        <div id="navbar" class="navbar-collapse collapse in" aria-expanded="true">
+          <ul class="nav navbar-nav">
+            <li class="active">
+              <a href="#"
+                 aria-label="'Details' menu element"
+                 tabindex="1"> 
+                Details 
+                <span class="sr-only">(current)</span>
+              </a>
+            </li>
+
+            <li class="dropdown">
+              <a href="#" class="dropdown-toggle" 
+                 data-toggle="dropdown" 
+                 role="button" 
+                 aria-label="'User requests' menu element"
+                 tabindex="2"
+                 aria-haspopup="true" 
+                 aria-expanded="false">
+                User Requests
+                <span class="caret"></span>
+              </a>
+              <ul class="dropdown-menu">
+                <li>
+                  <a href="#" aria-label="'Start new requests' menu element" tabindex="3">
+                    Start new requests
+                  </a>
+                </li>
+                <li>
+                  <a href="#" aria-label="'View ongoing requests' menu element" tabindex="4">
+                    View ongoing requests
+                  </a>
+                </li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </nav>
+  </wicket:panel>
+</html>
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.html
index a51d0f5..a77aa86 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseEnduserWebPage.html
@@ -43,7 +43,7 @@ under the License.
     <script type="text/javascript" src="webjars/bootbox/${bootbox.version}/bootbox.js"></script>
     <script type="text/javascript" src="webjars/jQuery-slimScroll/${jquery-slimscroll.version}/jquery.slimscroll.min.js"></script>
   </head>
-  <body class="skin-green-light hold-transition sidebar-mini" wicket:id="body">
+  <body wicket:id="body" class="skin-green-light hold-transition sidebar-mini">
     <div id="accessibility">
       <div id="change_contrast" class="btn-accessibility">
         <i aria-label="Toggle high contrast colors mode" tabindex="0" accesskey="H"
@@ -57,58 +57,12 @@ under the License.
       </div>
     </div>
 
-    <nav class="enduser_navbar navbar navbar-default">
-      <div class="container-fluid">
-        <div class="navbar-header">
-
-          <button type="button" 
-                  class="navbar-toggle" 
-                  data-toggle="collapse" 
-                  data-target="#navbar"
-                  aria-expanded="true" 
-                  aria-controls="navbar">
-            <span class="sr-only">Toggle navigation</span>
-            <span class="icon-bar"></span>
-            <span class="icon-bar"></span>
-            <span class="icon-bar"></span>
-          </button>
-
-          <a class="navbar-brand" href="#">
-            <span class="logo-mini"><img alt="Brand" src="ui-commons/img/logo-mini.png"/></span>
-          </a>
-        </div>
-
-        <div id="navbar" class="navbar-collapse collapse in" aria-expanded="true">
-          <ul class="nav navbar-nav">
-            <li class="active">
-              <a href="#"> Details 
-                <span class="sr-only">(current)</span>
-              </a>
-            </li>
-
-            <li class="dropdown">
-              <a href="#" class="dropdown-toggle" 
-                 data-toggle="dropdown" 
-                 role="button" 
-                 aria-haspopup="true" 
-                 aria-expanded="false">
-                User Requests
-                <span class="caret"></span>
-              </a>
-              <ul class="dropdown-menu">
-                <li><a href="#">Start new requests</a></li>
-                <li><a href="#">View ongoing requests</a></li>
-              </ul>
-            </li>
-          </ul>
-        </div>
-      </div>
-    </nav>
+    <span wicket:id="navbar">[NAVBAR]</span>
 
     <div class="wrapper">
       <span wicket:id="feedback"></span>
 
-      <div class="content-wrapper">
+      <div class="content-wrapper custom_content_wrapper">
         <wicket:child/>
       </div>
     </div>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login.html
index f9564c4..24ffede 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Login.html
@@ -79,10 +79,10 @@ under the License.
           </div>
         </form>
 
-        <div class="text-center">
+        <div class="text-center login_link">
           <a wicket:id="self-registration"><wicket:message key="self-registration">[SELFREGISTRATION]</wicket:message></a>
         </div>
-        <div class="text-center">
+        <div class="text-center login_link">
           <a wicket:id="self-pwd-reset"><wicket:message key="self-pwd-reset">[SELFPWDRESET]</wicket:message></a>
         </div>
       </div>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.html
new file mode 100644
index 0000000..3988782
--- /dev/null
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.html
@@ -0,0 +1,59 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+
+    <section class="content" wicket:id="content">
+      <div id="confirm_password_reset" class="container-fluid password_reset_wrapper">
+
+        <div class="row">
+          <div class="col-md-6 col-md-offset-3">
+
+            <div class="page-header">
+              <h1>
+                <wicket:message key="confirm-reset">[CONFIRM_PASSWORD_RESET]</wicket:message>
+              </h1>
+            </div>
+
+            <form wicket:id="selfConfirmPwdResetForm" class="form-horizontal">
+              <fieldset class="form-group">
+                <span id="password" wicket:id="password" class="form-group input-md"/>
+                <span id="confirmPassword" wicket:id="confirmPassword" class="form-group input-md"/>
+
+                <div class="password_reset_buttons form-group">
+                  <div class="col-md-6">
+                    <input id="cancel_button" wicket:id="cancel" type="submit" wicket:message="value:cancel" 
+                           class="btn btn-default pull-left"/>
+                  </div>
+                  <div class="col-md-6">
+                    <input id="submit_button" wicket:id="submit" type="submit" wicket:message="value:submit" 
+                           class="btn btn-primary pull-right"/>
+                  </div>
+                </div>
+              </fieldset>
+            </form>
+
+          </div> <!-- col -->
+        </div> <!-- row -->
+
+      </div>
+    </section>
+
+  </wicket:extend>
+</html>
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
similarity index 71%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
index 285d736..1aee4dd 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties
@@ -14,11 +14,11 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-username=Username
-securityQuestion=Security Question
-securityAnswer=Risposta di sicurezza
-reload=Ricarica
-not.loading=Non carica?
-submit=Salva
-cancel=Annulla
-self.pwd.reset.success=La password \u00e8 stata resettata con successo
+confirm-reset=Confirm password reset
+password=Password
+confirm-password=Confirm password
+password-strength=Password strength:
+cancel=Cancel
+submit=Submit
+self.confirm.pwd.reset.success=Password successfully reset
+self.confirm.pwd.reset.error.empty=No token was specified in the url, cannot access to the requested page
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
similarity index 69%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
index 285d736..17fca32 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties
@@ -14,11 +14,11 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-username=Username
-securityQuestion=Security Question
-securityAnswer=Risposta di sicurezza
-reload=Ricarica
-not.loading=Non carica?
-submit=Salva
+confirm-reset=Conferma reset della password
+password=Password
+confirm-password=Conferma password
+password-strength=Sicurezza della password:
 cancel=Annulla
-self.pwd.reset.success=La password \u00e8 stata resettata con successo
+submit=Invia
+self.confirm.pwd.reset.success=Password resettata con successo
+self.confirm.pwd.reset.error.empty=Nessun token \u00e8 specifico nell'url, non \u00e8 possibile accedere alla pagina richiesta
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties
similarity index 52%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties
index 285d736..ae8981e 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties
@@ -14,11 +14,11 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-username=Username
-securityQuestion=Security Question
-securityAnswer=Risposta di sicurezza
-reload=Ricarica
-not.loading=Non carica?
-submit=Salva
-cancel=Annulla
-self.pwd.reset.success=La password \u00e8 stata resettata con successo
+confirm-reset=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u518d\u8a2d\u5b9a\u3092\u78ba\u8a8d
+password=\u30d1\u30b9\u30ef\u30fc\u30c9
+confirm-password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u8a8d\u8a3c\u3059\u308b
+password-strength=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5f37\u5ea6\uff1a
+cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
+submit=\u63d0\u51fa\u3059\u308b
+self.confirm.pwd.reset.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u307e\u3057\u305f
+self.confirm.pwd.reset.error.empty=URL\u306b\u30c8\u30fc\u30af\u30f3\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u8981\u6c42\u3055\u308c\u305f\u30da\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u305b\u3093
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties
similarity index 68%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties
index 285d736..eb3f08a 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties
@@ -14,11 +14,11 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-username=Username
-securityQuestion=Security Question
-securityAnswer=Risposta di sicurezza
-reload=Ricarica
-not.loading=Non carica?
-submit=Salva
-cancel=Annulla
-self.pwd.reset.success=La password \u00e8 stata resettata con successo
+confirm-reset=Confirme a redefini\u00e7\u00e3o da senha
+password=Senha
+confirm-password=Confirme a Senha
+password-strength=For\u00e7a da senha:
+cancel=Cancelar
+submit=Enviar
+self.confirm.pwd.reset.success=Senha redefinida com sucesso
+self.confirm.pwd.reset.error.empty=Nenhum token foi especificado na URL, n\u00e3o pode acessar a p\u00e1gina solicitada
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties
new file mode 100644
index 0000000..19643d8
--- /dev/null
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties
@@ -0,0 +1,24 @@
+# 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.
+confirm-reset=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0441\u0431\u0440\u043e\u0441 \u043f\u0430\u0440\u043e\u043b\u044f
+password=\u043f\u0430\u0440\u043e\u043b\u044c
+confirm-password=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u041f\u0430\u0440\u043e\u043b\u044c
+password-strength=\u041d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u041f\u0430\u0440\u043e\u043b\u044f:
+cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+submit=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c
+self.confirm.pwd.reset.success==\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d
+self.confirm.pwd.reset.error.empty=\u0412 URL \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u0442\u043e\u043a\u0435\u043d, \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.html
index be995c7..e97fac0 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.html
@@ -19,11 +19,26 @@ under the License.
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:extend>
     <section class="content" wicket:id="content">
-      <div class="box">
-        <form wicket:id="selfPwdResetForm">
-          <div class="box-body" wicket:id="selfPwdResetPanel"/>
-        </form>
+      <div id="password_reset" class="container-fluid password_reset_wrapper">
+
+        <div class="row">
+          <div class="col-md-6 col-md-offset-3">
+
+            <div class="page-header">
+              <h1>
+                <wicket:message key="password-reset">[PASSWORD_RESET]</wicket:message>
+              </h1>
+            </div>
+
+            <form wicket:id="selfPwdResetForm" class="form-horizontal">
+              <div wicket:id="selfPwdResetPanel"/>
+            </form>
+
+          </div> <!-- col -->
+        </div> <!-- row -->
+
       </div>
     </section>
+
   </wicket:extend>
 </html>
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.properties
similarity index 92%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.properties
index 1d2b1df..182037d 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+password-reset=Password reset
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_it.properties
similarity index 92%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_it.properties
index 1d2b1df..7d26f21 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_it.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+password-reset=Reset della password
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_ja.properties
similarity index 91%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_ja.properties
index 1d2b1df..1ed1c75 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_ja.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+password-reset=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u30ea\u30bb\u30c3\u30c8
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_pt_BR.properties
similarity index 92%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_pt_BR.properties
index 1d2b1df..f5b2d64 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_pt_BR.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+password-reset=Resetar a senha
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_ru.properties
similarity index 85%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_ru.properties
index 1d2b1df..d937584 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset_ru.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+password-reset=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f
\ No newline at end of file
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.html
index f9fadd2..0c8f541 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.html
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.html
@@ -19,14 +19,15 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
   <wicket:panel>
+
     <fieldset class="form-group">
-      <div class="form-group">
+      <div class="form-group input-md">
         <label for="username"><wicket:message key="username"/></label>
         <input id="username" type="text" wicket:id="username" class="form-control" 
                wicket:message="placeholder:username" 
                autofocus="autofocus" />
       </div>
-      <div class="form-group">
+      <div class="form-group input-md">
         <label for="securityQuestion"><wicket:message key="securityQuestion"/></label>
         <input id="securityQuestion" type="text" wicket:id="securityQuestion" class="form-control" 
                wicket:message="placeholder:securityQuestion" 
@@ -34,18 +35,24 @@ under the License.
         <div class="suggestions">(<wicket:message key="not.loading">
           </wicket:message><a wicket:id="reloadLink"> <wicket:message key="reload"></wicket:message></a>)</div>
       </div>
-      <div class="form-group">
+      <div class="form-group input-md">
         <span wicket:id="securityAnswer">[SECURITY ANSWER]</span>
       </div>
-      <div class="form-group">
+      <div class="form-group input-md">
         <span wicket:id="captchaPanel">[CAPTCHA]</span>
       </div>
+
+      <div class="password_reset_buttons form-group">
+        <div class="col-md-6">
+          <input wicket:id="cancel" type="submit" wicket:message="value:cancel" 
+                 class="btn btn-default pull-left"/>
+        </div>
+        <div class="col-md-6">
+          <input wicket:id="submit" type="submit" wicket:message="value:submit" 
+                 class="btn btn-primary pull-right"/>
+        </div>
+      </div>
     </fieldset>
-    <div class="pull-left">
-      <input wicket:id="cancel" type="submit" wicket:message="value:cancel" class="btn btn-default pull-left"/>
-    </div>
-    <div class="pull-right">
-      <input wicket:id="submit" type="submit" wicket:message="value:submit" class="btn btn-primary"/>
-    </div>
+
   </wicket:panel>
 </html>
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
index 285d736..c090f85 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 username=Username
-securityQuestion=Security Question
+securityQuestion=Domanda di sicurezza
 securityAnswer=Risposta di sicurezza
 reload=Ricarica
 not.loading=Non carica?
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_pt_BR.properties
index 9307da2..400bbea 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_pt_BR.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_pt_BR.properties
@@ -18,7 +18,7 @@ username=Nome de usu\u00e1rio\n
 securityQuestion=Pergunta de Seguran\u00e7a
 securityAnswer=Resposta de seguran\u00e7a
 reload=recarregar
-not.loading=N\u00e3o est\u00e1 carregando?\n
+not.loading=N\u00e3o est\u00e1 carregando?
 submit=Enviar
 cancel=Cancelar
-self.pwd.reset.success=Senha redefinida com sucesso\nSenha\nTraduzioni di senha\nSostantivoFrequenza\npassword\nsenha, palavra de passe, contra-senha\nwatchword\nlema, palavra de ordem, senha, divisa, passe\nparole\npalavra de honra, senha\nshibboleth\nsenha, palavra, prova, pedra-de-toque\nSinonimi di senha\nSostantivo\ncontra-senha\n
+self.pwd.reset.success=Senha redefinida com sucesso
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_ru.properties
index fc5b52f..18fcf79 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_ru.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_ru.properties
@@ -18,7 +18,7 @@ username=\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u04
 securityQuestion=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441
 securityAnswer=\u041e\u0442\u0432\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438
 reload=\u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c
-not.loading=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f?\n
+not.loading=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f?
 submit=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c
 cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
-self.pwd.reset.success=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d\n
+self.pwd.reset.success=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
index 1d2b1df..f75bf08 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+captcha.message=Please, enter the code displayed within the image.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_it.properties
similarity index 91%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_it.properties
index 1d2b1df..eab994e 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_it.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+captcha.message=Per favore, inserisci il codice mostrato nell'immagine.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_ja.properties
similarity index 82%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_ja.properties
index 1d2b1df..0399f3d 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_ja.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+captcha.message=\u753b\u50cf\u5185\u306b\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u30b3\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_pt_BR.properties
similarity index 91%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_pt_BR.properties
index 1d2b1df..d21fb6b 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_pt_BR.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-captcha.message=Please enter the code displayed within the image.
+captcha.message=Por favor, insira o c\u00f3digo exibido dentro da imagem.
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_ru.properties
similarity index 75%
copy from client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
copy to client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_ru.properties
index 285d736..9a077bd 100644
--- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel_it.properties
+++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/wizards/any/AbstractCaptchaPanel_ru.properties
@@ -14,11 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-username=Username
-securityQuestion=Security Question
-securityAnswer=Risposta di sicurezza
-reload=Ricarica
-not.loading=Non carica?
-submit=Salva
-cancel=Annulla
-self.pwd.reset.success=La password \u00e8 stata resettata con successo
+captcha.message=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043a\u043e\u0434, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435.
diff --git a/client/idrepo/ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java b/client/idrepo/ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java
index efcd994..1415eb6 100644
--- a/client/idrepo/ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java
+++ b/client/idrepo/ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java
@@ -22,7 +22,6 @@ import java.security.AccessControlException;
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.ForbiddenException;
 import javax.xml.ws.WebServiceException;
-import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.wicket.authorization.UnauthorizedInstantiationException;
 import org.apache.wicket.core.request.handler.PageProvider;
@@ -62,7 +61,7 @@ public abstract class SyncopeUIRequestCycleListener implements IRequestCycleList
 
     @Override
     public IRequestHandler onException(final RequestCycle cycle, final Exception e) {
-        LOG.error("Exception found", ExceptionUtils.getStackTrace(e));
+        LOG.error("Exception found", e);
 
         PageParameters errorParameters = new PageParameters();
 
diff --git a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/animations.scss b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/animations.scss
index 4e75a4d..924b11f 100644
--- a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/animations.scss
+++ b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/animations.scss
@@ -17,67 +17,48 @@
  * under the License.
  */
 
+@import 'utils';
+
+
 @-webkit-keyframes spinner {
   0% {
-    -webkit-transform: rotate(0deg);
-    -moz-transform: rotate(0deg);
-    -ms-transform: rotate(0deg);
-    -o-transform: rotate(0deg);
-    transform: rotate(0deg);
+    @include transform(rotate(0deg));
   }
+
   100% {
-    -webkit-transform: rotate(360deg);
-    -moz-transform: rotate(360deg);
-    -ms-transform: rotate(360deg);
-    -o-transform: rotate(360deg);
-    transform: rotate(360deg);
+    @include transform(rotate(360deg));
   }
 }
+
+
 @-moz-keyframes spinner {
   0% {
-    -webkit-transform: rotate(0deg);
-    -moz-transform: rotate(0deg);
-    -ms-transform: rotate(0deg);
-    -o-transform: rotate(0deg);
-    transform: rotate(0deg);
+    @include transform(rotate(0deg));
   }
+
   100% {
-    -webkit-transform: rotate(360deg);
-    -moz-transform: rotate(360deg);
-    -ms-transform: rotate(360deg);
-    -o-transform: rotate(360deg);
-    transform: rotate(360deg);
+    @include transform(rotate(360deg));
   }
 }
+
+
 @-o-keyframes spinner {
   0% {
-    -webkit-transform: rotate(0deg);
-    -moz-transform: rotate(0deg);
-    -ms-transform: rotate(0deg);
-    -o-transform: rotate(0deg);
-    transform: rotate(0deg);
+    @include transform(rotate(0deg));
   }
+
   100% {
-    -webkit-transform: rotate(360deg);
-    -moz-transform: rotate(360deg);
-    -ms-transform: rotate(360deg);
-    -o-transform: rotate(360deg);
-    transform: rotate(360deg);
+    @include transform(rotate(360deg));
   }
 }
+
+
 @keyframes spinner {
   0% {
-    -webkit-transform: rotate(0deg);
-    -moz-transform: rotate(0deg);
-    -ms-transform: rotate(0deg);
-    -o-transform: rotate(0deg);
-    transform: rotate(0deg);
+    @include transform(rotate(0deg));
   }
+
   100% {
-    -webkit-transform: rotate(360deg);
-    -moz-transform: rotate(360deg);
-    -ms-transform: rotate(360deg);
-    -o-transform: rotate(360deg);
-    transform: rotate(360deg);
+    @include transform(rotate(360deg));
   }
 }
\ No newline at end of file
diff --git a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/login.scss b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/login.scss
index cf12511..1b7a626 100644
--- a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/login.scss
+++ b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/login.scss
@@ -82,7 +82,8 @@ body {
   .form-control:focus {
     outline: 0;
   }
-  .form-signin .dropdown {
+
+  .dropdown {
     width: 100% !important;
   }
 }
diff --git a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss
index e2d391f..656965f 100644
--- a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss
+++ b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/syncopeUI.scss
@@ -24,7 +24,6 @@ pre {
   @include white_space_pre_wrap;
 }
 
-/* Absolute Center Spinner */
 
 #veil {
   display: none;
@@ -79,53 +78,12 @@ pre {
   }
 }
 
-/* Transparent Overlay */
 
-/* Animation */
-
-@-webkit-keyframes spinner {
-  0% {
-    @include transform(rotate(0deg));
-  }
-
-  100% {
-    @include transform(rotate(360deg));
-  }
-}
-
-
-@-moz-keyframes spinner {
-  0% {
-    @include transform(rotate(0deg));
-  }
-
-  100% {
-    @include transform(rotate(360deg));
-  }
-}
 
 
-@-o-keyframes spinner {
-  0% {
-    @include transform(rotate(0deg));
-  }
-
-  100% {
-    @include transform(rotate(360deg));
-  }
-}
-
-
-@keyframes spinner {
-  0% {
-    @include transform(rotate(0deg));
-  }
-
-  100% {
-    @include transform(rotate(360deg));
-  }
-}
 
+/* General
+============================================================================= */
 
 .block-sidebar {
   max-height: 100% !important;
@@ -434,9 +392,11 @@ td.checkGroupColumn {
   text-align: center;
 }
 
-/**
-  BEGIN - Style for Information panel
-*/
+
+
+
+/* Style for Information panel
+============================================================================= */
 
 .information {
   margin: 30px 0px 0px 0px;
@@ -478,9 +438,6 @@ td.checkGroupColumn {
   margin-left: 155px;
 }
 
-/**
-END - Style for Information panel
-*/
 
 #ownership div.toggle {
   width: 110px !important;
@@ -532,6 +489,13 @@ END - Style for Information panel
   list-style: none;
   padding-left: 15px;
 }
+
+
+
+
+/* Startat
+============================================================================= */
+
 #startAt {
   background-color: rgba(98, 98, 98, 0.98) !important;
   color: #CCC;
@@ -551,17 +515,12 @@ END - Style for Information panel
   }
 }
 
-/**
-START - startAt
-*/
 
-/**
-END - startAt
-*/
 
-/**
-START - Notifications
-*/
+
+
+/* Notifications
+============================================================================= */
 /*Temporany fix diagonal stacking*/
 
 .k-popup.k-notification {
@@ -614,13 +573,13 @@ START - Notifications
   }
 }
 
-/**
-EN - Notifications
-*/
 
-/**
-START - Actions
-*/
+
+
+
+
+/* Actions
+============================================================================= */
 
 .actions > li > a {
   padding: 5px 0px 5px 0px !important;
@@ -680,25 +639,26 @@ div.listview-actions a {
   margin: 0px;
 }
 
-/**
-END - Actions
-*/
 
-/**
-START - DataTable
-*/
+
+
+
+
+
+/* Datatable
+============================================================================= */
 
 .dataTable {
   clear: both;
 }
 
-/**
-END - DataTable
-*/
 
-/**
-START - Result page
-*/
+
+
+
+
+/* Result page
+============================================================================= */
 
 .attribute {
   padding: 0px 4px 0px 4px;
@@ -718,10 +678,6 @@ span.highlight .attribute label {
   color: red;
 }
 
-/**
-END - Result page
-*/
-
 .navbar-nav > .user-menu > .dropdown-menu > li.user-header {
   height: auto !important;
   padding: 10px;
@@ -742,9 +698,11 @@ END - Result page
   border-color: #c1e9c1;
 }
 
-/**
-START - AjaxDateTimePicker
-*/
+
+
+
+/* AjaxDateTimePicker
+============================================================================= */
 
 .input-auto-width {
   width: auto !important;
@@ -754,13 +712,12 @@ START - AjaxDateTimePicker
   top: 5px !important;
 }
 
-/**
-END - AjaxDateTimePicker
-*/
 
-/**
-START - Search - AjaxDateTimePicker
-*/
+
+
+
+/* Search - AjaxDateTimePicker
+============================================================================= */
 
 .searchBox .col-xs-12 {
   padding-left: 0px !important;
@@ -833,20 +790,17 @@ START - Search - AjaxDateTimePicker
   background-color: #eee;
 }
 
-/**
-END - Search - AjaxDateTimePicker
-*/
-/**
-START - Parameters Details
-*/
+
+
+
+/* Parameters Details
+============================================================================= */
 
 div#parametersForm {
   min-height: 220px;
 }
 
-/**
-END - Parameters Details
-*/
+
 
 li.todoitem a {
   cursor: default;
@@ -893,9 +847,13 @@ div#userFilter {
   width: 20px;
 }
 
-/**
-START - Alert widget onside menu
-*/
+
+
+
+
+
+/* Alert widget onside menu
+============================================================================= */
 
 .alert-widget {
   > a {
@@ -944,13 +902,12 @@ START - Alert widget onside menu
   }
 }
 
-/**
-END - Alert widget onside menu
-*/
 
-/**
-START - Transformers toggle panel
-*/
+
+
+
+/* Transformers toggle panel
+============================================================================= */
 
 .transformersTogglePanel {
   background-color: rgba(140, 140, 140, 0.99) !important;
@@ -986,13 +943,13 @@ START - Transformers toggle panel
   right: 400px;
 }
 
-/**
-END - Transformers toggle panel
-*/
 
-/**
-START - CRONTAB
-*/
+
+
+
+
+/* Crontab
+============================================================================= */
 
 #schedule {
   input, fieldset {
@@ -1005,13 +962,11 @@ START - CRONTAB
   clear: both;
 }
 
-/**
-END - CRONTAB
-*/
 
-/**
-START - EVENTS
-*/
+
+
+/* Events
+============================================================================= */
 
 .events {
   display: table-row;
@@ -1049,9 +1004,11 @@ START - EVENTS
   min-width: 585px;
 }
 
-/**
-END - EVENTS
-*/
+
+
+
+/* Others
+============================================================================= */
 
 fieldset.input-group {
   width: 100%;
@@ -1153,4 +1110,33 @@ ul.menu {
 
 div#tablehandling ul.menu li a {
   padding: 0px !important;
+}
+
+
+
+
+
+/* Form wrappers
+============================================================================= */
+
+.custom_content_wrapper {
+  background-color: #ffffff;
+  border-radius: 10px;
+  @include shadow(0px 0px 20px 1px rgba(0,0,0,0.75));
+}
+
+
+
+
+/* Utility classes
+============================================================================= */
+
+.vertical_align {
+  @include flex;
+  @include flex_direction_column;
+  @include justify_content(center);
+}
+
+.max_height {
+  height: 100% !important;
 }
\ No newline at end of file
diff --git a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/utils.scss b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/utils.scss
index 5ed5791..37b0643 100644
--- a/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/utils.scss
+++ b/client/idrepo/ui/src/main/resources/META-INF/resources/ui-commons/css/utils.scss
@@ -20,6 +20,7 @@
 
 /* SCSS Methods
 ============================================================================= */
+
 @mixin user_select($value) {
   webkit-user-select: $value;
   -moz-user-select: $value;
@@ -92,11 +93,38 @@
   -webkit-box-align: $value;
   align-items: $value;
 }
+@mixin flex_direction_row() {
+  -webkit-box-orient: horizontal;
+  -webkit-box-direction: normal;
+  -webkit-flex-direction: row;
+  -ms-flex-direction: row;
+  flex-direction: row;
+}
+@mixin flex_direction_column() {
+  -webkit-box-orient: vertical;
+  -webkit-box-direction: normal;
+  -webkit-flex-direction: column;
+  -ms-flex-direction: column;
+  flex-direction: column;
+}
+@mixin flex_grow($value) {
+  -webkit-box-flex: $value;
+  -webkit-flex-grow: $value;
+  -ms-flex-positive: $value;
+  flex-grow: $value;
+}
+@mixin justify_content($value) {
+  -webkit-box-pack: $value;
+  -webkit-justify-content: $value;
+  -ms-flex-pack: $value;
+  justify-content: $value;
+}
 
 
 
 /* Breakpoints
 ============================================================================= */
+
 $tablet-width: 768px;
 $desktop-width: 1024px;
 
@@ -116,4 +144,4 @@ $desktop-width: 1024px;
   @media (min-width: #{$desktop-width}) {
     @content;
   }
-}
\ No newline at end of file
+}
diff --git a/core/persistence-jpa-json/src/main/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/main/resources/domains/MasterContent.xml
index 814b3c6..02b9a25 100644
--- a/core/persistence-jpa-json/src/main/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/main/resources/domains/MasterContent.xml
@@ -130,7 +130,7 @@ a password reset was request for ${user.getUsername()}.
 
 In order to complete this request, you need to visit this link:
 
-http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
+http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
 
 If you did not request this reset, just ignore the present e-mail.
 
@@ -141,7 +141,7 @@ Best regards."
 a password reset was request for ${user.getUsername()}.&lt;/p&gt;
 
 &lt;p&gt;In order to complete this request, you need to visit this 
-&lt;a href=&quot;http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
+&lt;a href=&quot;http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
 
 &lt;p&gt;If you did not request this reset, just ignore the present e-mail.&lt;/p&gt;
 
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index 9bbfcbf..7fff7f2 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -1180,7 +1180,7 @@ a password reset was request for ${user.getUsername()}.
 
 In order to complete this request, you need to visit this link:
 
-http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
+http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
 
 If you did not request this reset, just ignore the present e-mail.
 
@@ -1191,7 +1191,7 @@ Best regards."
 a password reset was request for ${user.getUsername()}.&lt;/p&gt;
 
 &lt;p&gt;In order to complete this request, you need to visit this 
-&lt;a href=&quot;http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
+&lt;a href=&quot;http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
 
 &lt;p&gt;If you did not request this reset, just ignore the present e-mail.&lt;/p&gt;
 
diff --git a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
index fd66eb6..182cdc6 100644
--- a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml
@@ -193,7 +193,7 @@ a password reset was request for ${user.getUsername()}.
 
 In order to complete this request, you need to visit this link:
 
-http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
+http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
 
 If you did not request this reset, just ignore the present e-mail.
 
@@ -204,7 +204,7 @@ Best regards."
 a password reset was request for ${user.getUsername()}.&lt;/p&gt;
 
 &lt;p&gt;In order to complete this request, you need to visit this 
-&lt;a href=&quot;http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
+&lt;a href=&quot;http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
 
 &lt;p&gt;If you did not request this reset, just ignore the present e-mail.&lt;/p&gt;
 
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 4bf6a5e..b61ff3f 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -1332,7 +1332,7 @@ a password reset was request for ${user.getUsername()}.
 
 In order to complete this request, you need to visit this link:
 
-http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
+http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
 
 If you did not request this reset, just ignore the present e-mail.
 
@@ -1343,7 +1343,7 @@ Best regards."
 a password reset was request for ${user.getUsername()}.&lt;/p&gt;
 
 &lt;p&gt;In order to complete this request, you need to visit this 
-&lt;a href=&quot;http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
+&lt;a href=&quot;http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
 
 &lt;p&gt;If you did not request this reset, just ignore the present e-mail.&lt;/p&gt;
 
diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
index 685e507..bcfcce5 100644
--- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
+++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/MailTemplateTest.java
@@ -85,10 +85,10 @@ public class MailTemplateTest extends AbstractTest {
         assertNotNull(htmlBody);
         assertTrue(htmlBody.contains("a password reset was request for " + username + "."));
         assertFalse(htmlBody.contains(
-                "http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token="
+                "http://localhost:9080/syncope-enduser/confirmpasswordreset?token="
                 + token));
         assertTrue(htmlBody.contains(
-                "http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token="
+                "http://localhost:9080/syncope-enduser/confirmpasswordreset?token="
                 + token.replaceAll(" ", "%20")));
     }
 
diff --git a/core/upgrade/src/test/resources/syncopedb20.sql b/core/upgrade/src/test/resources/syncopedb20.sql
index 0ff3717..ff5ab06 100644
--- a/core/upgrade/src/test/resources/syncopedb20.sql
+++ b/core/upgrade/src/test/resources/syncopedb20.sql
@@ -797,7 +797,7 @@ CREATE MEMORY TABLE PUBLIC.MAILTEMPLATE(
 ALTER TABLE PUBLIC.MAILTEMPLATE ADD CONSTRAINT PUBLIC.CONSTRAINT_AB PRIMARY KEY(ID);           
 -- 4 +/- SELECT COUNT(*) FROM PUBLIC.MAILTEMPLATE;             
 INSERT INTO PUBLIC.MAILTEMPLATE(ID, HTMLTEMPLATE, TEXTTEMPLATE) VALUES
-('requestPasswordReset', '<html> <body> <p>Hi, a password reset was request for ${user.getUsername()}.</p>  <p>In order to complete this request, you need to visit this  <a href="http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll('' '', ''%20'')}">link</a></p>.  <p>If you did not request this reset, just ignore the present e-mail.</p>  <p>Best regards.</p> </body> </html>', 'Hi, a password reset was request for ${user.getUsername()}.  In ord [...]
+('requestPasswordReset', '<html> <body> <p>Hi, a password reset was request for ${user.getUsername()}.</p>  <p>In order to complete this request, you need to visit this  <a href="http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll('' '', ''%20'')}">link</a></p>.  <p>If you did not request this reset, just ignore the present e-mail.</p>  <p>Best regards.</p> </body> </html>', 'Hi, a password reset was request for ${user.getUsername()}.  In order to c [...]
 ('confirmPasswordReset', '<html> <body> <p>Hi,<br/> we are happy to inform you that the password request was successfully executed for your account.</p>  <p>Best regards.</p> </body> </html>', 'Hi, we are happy to inform you that the password request was successfully executed for your account.  Best regards.'),
 ('test', NULL, NULL),
 ('optin', STRINGDECODE('<html> <body> <h3>Hi ${user.getPlainAttr(\"firstname\").values[0]} ${user.getPlainAttr(\"surname\").values[0]}, welcome to Syncope!</h3>  <p>    Your username is ${user.username}.<br/>    Your email address is ${user.getPlainAttr(\"email\").values[0]}.    Your email address inside a <a href=\"http://localhost/?email=${user.getPlainAttr(\"email\").values[0].replace(''@'', ''%40'')}\">link</a>. </p>  <p>     This message was sent to the following recipients: <ul>\n  [...]
diff --git a/docker/core/src/main/resources/domains/MasterContent.xml.pgjsonb b/docker/core/src/main/resources/domains/MasterContent.xml.pgjsonb
index 814b3c6..02b9a25 100644
--- a/docker/core/src/main/resources/domains/MasterContent.xml.pgjsonb
+++ b/docker/core/src/main/resources/domains/MasterContent.xml.pgjsonb
@@ -130,7 +130,7 @@ a password reset was request for ${user.getUsername()}.
 
 In order to complete this request, you need to visit this link:
 
-http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
+http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}
 
 If you did not request this reset, just ignore the present e-mail.
 
@@ -141,7 +141,7 @@ Best regards."
 a password reset was request for ${user.getUsername()}.&lt;/p&gt;
 
 &lt;p&gt;In order to complete this request, you need to visit this 
-&lt;a href=&quot;http://localhost:9080/syncope-enduser/app/#!/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
+&lt;a href=&quot;http://localhost:9080/syncope-enduser/confirmpasswordreset?token=${input.get(0).replaceAll(' ', '%20')}&quot;&gt;link&lt;/a&gt;&lt;/p&gt;.
 
 &lt;p&gt;If you did not request this reset, just ignore the present e-mail.&lt;/p&gt;