瀏覽代碼

dojo removal from user-facing jsps

Jason Rivard 2 年之前
父節點
當前提交
00e51c91ea
共有 37 個文件被更改,包括 732 次插入959 次删除
  1. 1 1
      docker/pom.xml
  2. 0 1
      server/src/main/java/password/pwm/AppProperty.java
  3. 1 0
      server/src/main/java/password/pwm/http/PwmRequestAttribute.java
  4. 1 0
      server/src/main/java/password/pwm/http/PwmRequestFlag.java
  5. 32 31
      server/src/main/java/password/pwm/http/servlet/ClientApiServlet.java
  6. 2 0
      server/src/main/java/password/pwm/http/servlet/GuestRegistrationServlet.java
  7. 9 1
      server/src/main/java/password/pwm/http/servlet/newuser/NewUserUtils.java
  8. 23 16
      server/src/main/java/password/pwm/util/macro/UserMacros.java
  9. 0 1
      server/src/main/resources/password/pwm/AppProperty.properties
  10. 5 9
      webapp/src/main/webapp/WEB-INF/jsp/changepassword-wait.jsp
  11. 2 1
      webapp/src/main/webapp/WEB-INF/jsp/changepassword.jsp
  12. 1 1
      webapp/src/main/webapp/WEB-INF/jsp/configeditor.jsp
  13. 10 6
      webapp/src/main/webapp/WEB-INF/jsp/fragment/footer.jsp
  14. 6 4
      webapp/src/main/webapp/WEB-INF/jsp/fragment/form-field-newpassword.jsp
  15. 9 14
      webapp/src/main/webapp/WEB-INF/jsp/fragment/form.jsp
  16. 1 1
      webapp/src/main/webapp/WEB-INF/jsp/fragment/header-body.jsp
  17. 1 1
      webapp/src/main/webapp/WEB-INF/jsp/fragment/header-menu.jsp
  18. 1 1
      webapp/src/main/webapp/WEB-INF/jsp/fragment/ldap-selector.jsp
  19. 0 1
      webapp/src/main/webapp/WEB-INF/jsp/fragment/message.jsp
  20. 4 5
      webapp/src/main/webapp/WEB-INF/jsp/guest-create.jsp
  21. 3 2
      webapp/src/main/webapp/WEB-INF/jsp/guest-update.jsp
  22. 0 4
      webapp/src/main/webapp/WEB-INF/jsp/newuser-wait.jsp
  23. 0 96
      webapp/src/main/webapp/public/randomgen.jsp
  24. 136 131
      webapp/src/main/webapp/public/resources/js/admin.js
  25. 2 10
      webapp/src/main/webapp/public/resources/js/changepassword.js
  26. 1 1
      webapp/src/main/webapp/public/resources/js/configeditor-settings-challenges.js
  27. 16 16
      webapp/src/main/webapp/public/resources/js/configeditor-settings.js
  28. 22 6
      webapp/src/main/webapp/public/resources/js/configeditor.js
  29. 4 4
      webapp/src/main/webapp/public/resources/js/configmanager.js
  30. 0 20
      webapp/src/main/webapp/public/resources/js/guest.js
  31. 189 329
      webapp/src/main/webapp/public/resources/js/main.js
  32. 15 24
      webapp/src/main/webapp/public/resources/js/newuser.js
  33. 2 2
      webapp/src/main/webapp/public/resources/js/otpsecret.js
  34. 25 33
      webapp/src/main/webapp/public/resources/js/responses.js
  35. 183 167
      webapp/src/main/webapp/public/resources/js/uilibrary.js
  36. 7 7
      webapp/src/main/webapp/public/resources/js/updateprofile.js
  37. 18 12
      webapp/src/main/webapp/public/resources/style.css

+ 1 - 1
docker/pom.xml

@@ -45,7 +45,7 @@
                         <configuration>
                             <skip>${skipDocker}</skip>
                             <from>
-                                <image>eclipse-temurin:18-jre</image>
+                                <image>eclipse-temurin:20-jre</image>
                             </from>
                             <to>
                                 <image>${dockerImageTag}</image>

+ 0 - 1
server/src/main/java/password/pwm/AppProperty.java

@@ -67,7 +67,6 @@ public enum AppProperty
     CLIENT_FORM_CLIENT_REGEX_ENABLED                ( "client.form.clientRegexEnable" ),
     CLIENT_WARNING_HEADER_SHOW                      ( "client.warningHeader.show" ),
     CLIENT_PW_SHOW_REVERT_TIMEOUT                   ( "client.pwShowRevertTimeout" ),
-    CLIENT_JS_ENABLE_HTML5DIALOG                    ( "client.js.enableHtml5Dialog" ),
     CLIENT_JSP_SHOW_ICONS                           ( "client.jsp.showIcons" ),
     CONFIG_MAX_FILEVALUE_SIZE                       ( "config.max.fileValue.size" ),
     CONFIG_RELOAD_ON_CHANGE                         ( "config.reloadOnChange" ),

+ 1 - 0
server/src/main/java/password/pwm/http/PwmRequestAttribute.java

@@ -88,6 +88,7 @@ public enum PwmRequestAttribute
 
     GuestCurrentExpirationDate,
     GuestMaximumExpirationDate,
+    GuestMinimumExpirationDate,
     GuestMaximumValidDays,
 
     NewUser_FormShowBackButton,

+ 1 - 0
server/src/main/java/password/pwm/http/PwmRequestFlag.java

@@ -32,6 +32,7 @@ public enum PwmRequestFlag
     NO_MOBILE_CSS,
     ALWAYS_EXPAND_MESSAGE_TEXT,
     INCLUDE_CONFIG_CSS,
+    INCLUDE_DOJO,
     INCLUDE_IAS_ANGULAR,
     INCLUDE_IAS_CSS
 }

+ 32 - 31
server/src/main/java/password/pwm/http/servlet/ClientApiServlet.java

@@ -47,7 +47,7 @@ import password.pwm.http.PwmRequest;
 import password.pwm.http.PwmSession;
 import password.pwm.http.PwmURL;
 import password.pwm.i18n.Display;
-import password.pwm.svc.sessiontrack.UserAgentUtils;
+import password.pwm.i18n.PwmDisplayBundle;
 import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsService;
@@ -310,7 +310,6 @@ public class ClientApiServlet extends ControlledPwmServlet
         settingMap.put( "client.ajaxTypingTimeout", Integer.parseInt( config.readAppProperty( AppProperty.CLIENT_AJAX_TYPING_TIMEOUT ) ) );
         settingMap.put( "client.ajaxTypingWait", Integer.parseInt( config.readAppProperty( AppProperty.CLIENT_AJAX_TYPING_WAIT ) ) );
         settingMap.put( "client.activityMaxEpsRate", Integer.parseInt( config.readAppProperty( AppProperty.CLIENT_ACTIVITY_MAX_EPS_RATE ) ) );
-        settingMap.put( "client.js.enableHtml5Dialog", Boolean.parseBoolean( config.readAppProperty( AppProperty.CLIENT_JS_ENABLE_HTML5DIALOG ) ) );
         settingMap.put( "client.locale", LocaleHelper.getBrowserLocaleString( pwmSession.getSessionStateBean().getLocale() ) );
         settingMap.put( "client.pwShowRevertTimeout", Integer.parseInt( config.readAppProperty( AppProperty.CLIENT_PW_SHOW_REVERT_TIMEOUT ) ) );
         settingMap.put( "enableIdleTimeout", config.readSettingAsBoolean( PwmSetting.DISPLAY_IDLE_TIMEOUT ) );
@@ -318,38 +317,12 @@ public class ClientApiServlet extends ControlledPwmServlet
         settingMap.put( "setting-showHidePasswordFields", pwmDomain.getConfig().readSettingAsBoolean( password.pwm.config.PwmSetting.DISPLAY_SHOW_HIDE_PASSWORD_FIELDS ) );
         settingMap.put( "setting-displayEula", PwmConstants.ENABLE_EULA_DISPLAY );
         settingMap.put( "setting-showStrengthMeter", config.readSettingAsBoolean( PwmSetting.PASSWORD_SHOW_STRENGTH_METER ) );
-
-        {
-            final Optional<UserAgentUtils.BrowserType> optionalBrowserType = UserAgentUtils.getBrowserType( pwmRequest );
-            final String browserTypeString = optionalBrowserType.isPresent() ? optionalBrowserType.get().toString() : "other";
-            settingMap.put( "browserType", browserTypeString );
-        }
-
-        {
-            long idleSeconds = config.readSettingAsLong( PwmSetting.IDLE_TIMEOUT_SECONDS );
-            if ( pageUrl == null || pageUrl.isEmpty() )
-            {
-                LOGGER.warn( pwmRequest, () -> "request to /client data did not include pageUrl" );
-            }
-            else
-            {
-                try
-                {
-                    final PwmURL pwmUrl = PwmURL.create( URI.create( pageUrl ), pwmRequest.getContextPath(), pwmRequest.getAppConfig() );
-                    final TimeDuration maxIdleTime = IdleTimeoutCalculator.idleTimeoutForRequest( pwmRequest, pwmUrl );
-                    idleSeconds = maxIdleTime.as( TimeDuration.Unit.SECONDS );
-                }
-                catch ( final Exception e )
-                {
-                    LOGGER.error( pwmRequest, () -> "error determining idle timeout time for request: " + e.getMessage() );
-                }
-            }
-            settingMap.put( "MaxInactiveInterval", idleSeconds );
-        }
         settingMap.put( "paramName.locale", config.readAppProperty( AppProperty.HTTP_PARAM_NAME_LOCALE ) );
         settingMap.put( "runtimeNonce", pwmDomain.getPwmApplication().getRuntimeNonce() );
         settingMap.put( "applicationMode", pwmDomain.getApplicationMode() );
 
+        settingMap.putAll( makeIdleTimeoutClientData( pwmRequest, config, pageUrl ) );
+
         {
             final String contextPath = pwmRequest.getBasePath();
             settingMap.put( "url-context", contextPath );
@@ -433,7 +406,7 @@ public class ClientApiServlet extends ControlledPwmServlet
     )
     {
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final Class displayClass = LocaleHelper.classForShortName( bundleName ).orElse( Display.class );
+        final Class<? extends PwmDisplayBundle> displayClass = LocaleHelper.classForShortName( bundleName ).orElse( Display.class );
 
         final Locale userLocale = pwmSession.getSessionStateBean().getLocale();
         final DomainConfig config = pwmDomain.getConfig();
@@ -530,5 +503,33 @@ public class ClientApiServlet extends ControlledPwmServlet
             }
         }
     }
+
+
+    private static Map<String, Object> makeIdleTimeoutClientData(
+            final PwmRequest pwmRequest,
+            final DomainConfig config,
+            final String pageUrl )
+    {
+        long idleSeconds = config.readSettingAsLong( PwmSetting.IDLE_TIMEOUT_SECONDS );
+        if ( StringUtil.isEmpty( pageUrl ) )
+        {
+            LOGGER.warn( pwmRequest, () -> "request to /client data did not include pageUrl" );
+        }
+        else
+        {
+            try
+            {
+                final PwmURL pwmUrl = PwmURL.create( URI.create( pageUrl ), pwmRequest.getContextPath(), pwmRequest.getAppConfig() );
+                final TimeDuration maxIdleTime = IdleTimeoutCalculator.idleTimeoutForRequest( pwmRequest, pwmUrl );
+                idleSeconds = maxIdleTime.as( TimeDuration.Unit.SECONDS );
+            }
+            catch ( final Exception e )
+            {
+                LOGGER.error( pwmRequest, () -> "error determining idle timeout time for request: " + e.getMessage() );
+            }
+        }
+
+        return Collections.singletonMap( "MaxInactiveInterval", idleSeconds );
+    }
 }
 

+ 2 - 0
server/src/main/java/password/pwm/http/servlet/GuestRegistrationServlet.java

@@ -686,6 +686,8 @@ public class GuestRegistrationServlet extends ControlledPwmServlet
         final long maxValidDays = pwmRequest.getDomainConfig().readSettingAsLong( PwmSetting.GUEST_MAX_VALID_DAYS );
         pwmRequest.setAttribute( PwmRequestAttribute.GuestMaximumValidDays, String.valueOf( maxValidDays ) );
 
+        pwmRequest.setAttribute( PwmRequestAttribute.GuestMinimumExpirationDate, dateFormat.format( Instant.now() ) );
+
 
         final String maxExpirationDate;
         {

+ 9 - 1
server/src/main/java/password/pwm/http/servlet/newuser/NewUserUtils.java

@@ -497,7 +497,15 @@ class NewUserUtils
 
         final String usernameAttribute = newUserProfile.getLdapProfile( pwmDomain.getConfig() ).readSettingAsString( PwmSetting.LDAP_USERNAME_ATTRIBUTE );
 
+        final String username = formValues.getOrDefault( usernameAttribute, "_NewUser_" );
+
+        final UserIdentity userIdentity = UserIdentity.create(
+                username,
+                newUserProfile.getLdapProfile( pwmDomain.getConfig() ).getId(),
+                pwmDomain.getDomainID() );
+
         return UserInfoBean.builder()
+                .userIdentity( userIdentity )
                 .userEmailAddress( formValues.get( emailAddressAttribute ) )
                 .username( formValues.get( usernameAttribute ) )
                 .attributes( formValues )
@@ -768,7 +776,7 @@ class NewUserUtils
                     TokenUtil.initializeAndSendToken(
                             pwmRequest.getPwmRequestContext(),
                             TokenUtil.TokenInitAndSendRequest.builder()
-                                    .userInfo(  null )
+                                    .userInfo(  macroRequest.getUserInfo() )
                                     .tokenDestinationItem( tokenDestinationItem )
                                     .emailToSend( PwmSetting.EMAIL_NEWUSER_VERIFICATION )
                                     .tokenType( TokenType.NEWUSER )

+ 23 - 16
server/src/main/java/password/pwm/util/macro/UserMacros.java

@@ -115,7 +115,7 @@ public class UserMacros
                 throw new MacroParseException( "too many parameters" );
             }
 
-           final String ldapValue = readLdapValue( macroRequest, ldapAttr, matchValue );
+            final String ldapValue = readLdapValue( macroRequest, ldapAttr, matchValue );
 
             final StringBuilder returnValue = new StringBuilder();
             returnValue.append( ldapValue == null
@@ -747,23 +747,30 @@ public class UserMacros
                 throws MacroParseException
         {
             final UserInfo userInfo = request.getUserInfo();
-            if ( userInfo != null )
+            if ( userInfo == null )
             {
-                final UserIdentity userIdentity = userInfo.getUserIdentity();
-                if ( userIdentity != null )
-                {
-                    final DomainID domainID = userIdentity.getDomainID();
-                    if ( domainID != null )
-                    {
-                        final PwmDomain pwmDomain = request.getPwmApplication().domains().get( domainID );
-                        if ( pwmDomain != null )
-                        {
-                            return pwmDomain.getConfig().readSettingAsString( PwmSetting.EMAIL_DOMAIN_FROM_ADDRESS );
-                        }
-                    }
-                }
+                throw new MacroParseException( "[DefaultEmailFromAddress]: userInfo unspecified on macro request" );
             }
-            throw new MacroParseException( "@DefaultEmailFromAddress@: domain unspecified on macro request" );
+
+            final UserIdentity userIdentity = userInfo.getUserIdentity();
+            if ( userIdentity == null )
+            {
+                throw new MacroParseException( "[DefaultEmailFromAddress]: userIdentity unspecified on macro request" );
+            }
+
+            final DomainID domainID = userIdentity.getDomainID();
+            if ( domainID == null )
+            {
+                throw new MacroParseException( "[DefaultEmailFromAddress]: domain unspecified on macro request" );
+            }
+
+            final PwmDomain pwmDomain = request.getPwmApplication().domains().get( domainID );
+            if ( pwmDomain == null )
+            {
+                throw new MacroParseException( "[DefaultEmailFromAddress]: domain invalid on macro request" );
+            }
+
+            return pwmDomain.getConfig().readSettingAsString( PwmSetting.EMAIL_DOMAIN_FROM_ADDRESS );
         }
     }
 

+ 0 - 1
server/src/main/resources/password/pwm/AppProperty.properties

@@ -55,7 +55,6 @@ client.formNonce.length=10
 client.form.clientRegexEnable=true
 client.warningHeader.show=true
 client.pwShowRevertTimeout=45000
-client.js.enableHtml5Dialog=true
 client.jsp.showIcons=true
 cluster.db.enable=true
 cluster.db.heartbeatSeconds=60

+ 5 - 9
webapp/src/main/webapp/WEB-INF/jsp/changepassword-wait.jsp

@@ -53,9 +53,8 @@
         <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
         <p><pwm:display key="Display_PleaseWaitPassword"/></p>
         <div class="meteredProgressBar">
-          <progress id="html5ProgressBar" max="100" value="0">
-              <div data-dojo-type="dijit/ProgressBar" style="width:100%" data-dojo-id="passwordProgressBar" id="passwordProgressBar" data-dojo-props="maximum:100"></div>
-          </progress>
+            <progress id="html5ProgressBar" max="100" value="0">
+            </progress>
         </div>
         <div style="text-align: center; width: 100%; padding-top: 50px">
             <%--
@@ -70,14 +69,11 @@
     <div class="push"></div>
 </div>
 <pwm:script>
-<script type="text/javascript">
-    PWM_GLOBAL['startupFunctions'].push(function(){
-        require(["dojo/parser", "dijit/ProgressBar","dojo/ready"], function(parser){
-            parser.parse();
+    <script type="text/javascript">
+        PWM_GLOBAL['startupFunctions'].push(function(){
             PWM_CHANGEPW.refreshCreateStatus(<%=checkIntervalSeconds * 1000%>);
         });
-    });
-</script>
+    </script>
 </pwm:script>
 <pwm:script-ref url="/public/resources/js/changepassword.js"/>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>

+ 2 - 1
webapp/src/main/webapp/WEB-INF/jsp/changepassword.jsp

@@ -52,13 +52,14 @@
         </div>
         <br/>
         <%@ include file="fragment/message.jsp" %>
+        <br/>
         <form action="<pwm:current-url/>" method="post" enctype="application/x-www-form-urlencoded" id="changePasswordForm" autocomplete="off">
             <jsp:include page="fragment/form-field-newpassword.jsp" />
 
             <input type="hidden" name="processAction" value="change"/>
             <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
 
-            <div class="buttonbar" style="width:100%">
+            <div class="buttonbar">
                 <button type="submit" name="password_button" class="btn" id="password_button" tabindex="<pwm:tabindex/>">
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-forward"></span></pwm:if>
                     <pwm:display key="Button_ChangePassword"/>

+ 1 - 1
webapp/src/main/webapp/WEB-INF/jsp/configeditor.jsp

@@ -33,10 +33,10 @@
 <%@ taglib uri="pwm" prefix="pwm" %>
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <% JspUtility.setFlag(pageContext, PwmRequestFlag.HIDE_LOCALE); %>
+<% JspUtility.setFlag(pageContext, PwmRequestFlag.INCLUDE_DOJO);%>
 <% JspUtility.setFlag(pageContext, PwmRequestFlag.HIDE_FOOTER_TEXT); %>
 <% JspUtility.setFlag(pageContext, PwmRequestFlag.INCLUDE_CONFIG_CSS); %>
 <% JspUtility.setFlag(pageContext, PwmRequestFlag.NO_MOBILE_CSS); %>
-<link href="<pwm:url url='/public/resources/webjars/dijit/themes/nihilo/nihilo.css' addContext="true"/>" rel="stylesheet" type="text/css"/>
 <%@ include file="fragment/header.jsp" %>
 <body class="nihilo">
 <style nonce="<pwm:value name="<%=PwmValue.cspNonce%>"/>" type="text/css">

+ 10 - 6
webapp/src/main/webapp/WEB-INF/jsp/fragment/footer.jsp

@@ -61,6 +61,7 @@
             </pwm:if>
         </div>
     </div>
+    <div id="capslockwarning" class="nodisplay"><pwm:display key="Display_CapsLockIsOn"/></div>
 </pwm:if>
 <pwm:if test="<%=PwmIfTest.requestFlag%>" requestFlag="<%=PwmRequestFlag.NO_IDLE_TIMEOUT%>">
     <pwm:script>
@@ -69,11 +70,15 @@
         </script>
     </pwm:script>
 </pwm:if>
-<pwm:script>
-    <script type="text/javascript">
-        var dojoConfig = { has: { "csp-restrictions":true }, async:true}
-    </script>
-</pwm:script>
+<pwm:if test="<%=PwmIfTest.requestFlag%>" requestFlag="<%=PwmRequestFlag.INCLUDE_DOJO%>">
+    <link href="<pwm:url url='/public/resources/webjars/dijit/themes/nihilo/nihilo.css' addContext="true"/>" rel="stylesheet" type="text/css"/>
+    <pwm:script>
+        <script type="text/javascript">
+            var dojoConfig = { has: { "csp-restrictions":true }, async:true}
+        </script>
+    </pwm:script>
+    <script nonce="<pwm:value name="<%=PwmValue.cspNonce%>"/>" dojo-sync-loader="false" type="text/javascript" src="<pwm:url addContext="true" url='/public/resources/webjars/dojo/dojo.js'/>"></script><noscript></noscript>
+</pwm:if>
 <pwm:if test="<%=PwmIfTest.hasCustomJavascript%>">
     <pwm:script>
         <script type="text/javascript">
@@ -83,5 +88,4 @@
         </script>
     </pwm:script>
 </pwm:if>
-<script nonce="<pwm:value name="<%=PwmValue.cspNonce%>"/>" dojo-sync-loader="false" type="text/javascript" src="<pwm:url addContext="true" url='/public/resources/webjars/dojo/dojo.js'/>"></script><noscript></noscript>
 <pwm:script-ref url="/public/resources/js/main.js"/>

+ 6 - 4
webapp/src/main/webapp/WEB-INF/jsp/fragment/form-field-newpassword.jsp

@@ -29,13 +29,15 @@
 <div class="formFieldWrapper" id="formFieldWrapper-password1">
     <div class="formFieldLabel">
         <label for="password1"><pwm:display key="Field_NewPassword"/></label>
-        <div class="pwm-icon pwm-icon-question-circle pwm-icon-button nodisplay" id="password-guide-icon"></div>
+        <div class="pwm-icon pwm-icon-question-circle pwm-icon-button nodisplay" id="password-guide-icon"
+        title="<pwm:display key="Display_ShowPasswordGuide"/>"></div>
         <pwm:if test="<%=PwmIfTest.showRandomPasswordGenerator%>">
-            <div class="pwm-icon pwm-icon-retweet pwm-icon-button nodisplay" id="autogenerate-icon"></div>
+            <div class="pwm-icon pwm-icon-retweet pwm-icon-button nodisplay" id="autogenerate-icon"
+            title="<pwm:display key="Display_AutoGeneratedPassword"/>2"></div>
         </pwm:if>
     </div>
     <input type="<pwm:value name="<%=PwmValue.passwordFieldType%>"/>" name="password1" id="password1"
-           class="inputfield" <pwm:autofocus/> tabindex="<pwm:tabindex/>"/>
+           class="inputfield passwordfield" <pwm:autofocus/> tabindex="<pwm:tabindex/>"/>
     <pwm:if test="<%=PwmIfTest.showStrengthMeter%>">
         <div id="strengthBox" class="noopacity">
             <div id="strengthLabel">
@@ -51,7 +53,7 @@
         <label for="password2"><pwm:display key="Field_ConfirmPassword"/></label>
     </div>
     <input type="<pwm:value name="<%=PwmValue.passwordFieldType%>"/>" name="password2" id="password2"
-           class="inputfield" tabindex="<pwm:tabindex/>"/>
+           class="inputfield passwordfield" tabindex="<pwm:tabindex/>"/>
     <%-- confirmation mark [not shown initially, enabled by javascript; see also changepassword.js:markConfirmationMark() --%>
     <div id="confirmMarkBox">
         <div class="confirmCheckMark nodisplay" id="confirmCheckMark"></div>

+ 9 - 14
webapp/src/main/webapp/WEB-INF/jsp/fragment/form.jsp

@@ -61,6 +61,7 @@
         String currentValue = formDataMap != null ? formDataMap.get(loopConfiguration) : "";
         currentValue = currentValue == null ? "" : currentValue;
         currentValue = StringUtil.escapeHtml(currentValue);
+        final String requiredLabel = PwmError.ERROR_FIELD_REQUIRED.getLocalizedMessage(formLocale,pwmDomain.getConfig(),new String[]{loopConfiguration.getLabel(formLocale)});
 
 %>
 <div class="formFieldWrapper" id="formFieldWrapper-<%=loopConfiguration.getName()%>">
@@ -74,7 +75,8 @@
                type="checkbox" <%=checked?"checked":""%> <pwm:autofocus/>/>
         <%=loopConfiguration.getLabel(formLocale)%>
         <%if(loopConfiguration.isRequired()){%>
-        <span class="formFieldRequiredAsterisk" id="label_required_<%=loopConfiguration.getName()%>">*</span>
+        <span class="formFieldRequiredAsterisk" id="label_required_<%=loopConfiguration.getName()%>"
+              title="<%=requiredLabel%>3">*</span>
         <%}%>
     </label>
     <% if (loopConfiguration.getDescription(formLocale) != null && loopConfiguration.getDescription(formLocale).length() > 0) { %>
@@ -85,7 +87,8 @@
         <label for="<%=loopConfiguration.getName()%>">
             <%= loopConfiguration.getLabel(formLocale) %>
             <%if(loopConfiguration.isRequired()){%>
-            <span class="formFieldRequiredAsterisk" id="label_required_<%=loopConfiguration.getName()%>">*</span>
+            <span class="formFieldRequiredAsterisk" id="label_required_<%=loopConfiguration.getName()%>"
+                  title="<%=requiredLabel%>2">*</span>
             <%}%>
         </label>
     </div>
@@ -167,7 +170,10 @@
     <label for="<%=loopConfiguration.getName()%>_confirm">
         <div class="formFieldLabel">
             <pwm:display key="Field_Confirm_Prefix"/>&nbsp;<%=loopConfiguration.getLabel(formLocale) %>
-            <%if(loopConfiguration.isRequired()){%>*<%}%>
+            <%if(loopConfiguration.isRequired()){%>
+            <span class="formFieldRequiredAsterisk" id="label_required_<%=loopConfiguration.getName()%>"
+                  title="<%=requiredLabel%>2">*</span>
+            <%}%>
         </div>
     </label>
     <input id="<%=loopConfiguration.getName()%>_confirm" type="<%=loopConfiguration.getType()%>" class="inputfield"
@@ -218,17 +224,6 @@
         </pwm:script>
         <% } %>
     </pwm:if>
-    <pwm:script>
-        <script type="text/javascript">
-            PWM_GLOBAL['startupFunctions'].push(function(){
-                PWM_MAIN.showTooltip({
-                    id: "label_required_<%=loopConfiguration.getName()%>",
-                    text: '<%=PwmError.ERROR_FIELD_REQUIRED.getLocalizedMessage(formLocale,pwmDomain.getConfig(),new String[]{loopConfiguration.getLabel(formLocale)})%>',
-                    position: ['above']
-                });
-            });
-        </script>
-    </pwm:script>
 </div>
 <% } %>
 <% if (showPasswordFields) { %>

+ 1 - 1
webapp/src/main/webapp/WEB-INF/jsp/fragment/header-body.jsp

@@ -52,7 +52,7 @@
             <div id="header-menu-wrapper">
                 <div id="header-menu">
                     <pwm:if test="<%=PwmIfTest.permission%>" permission="<%=Permission.PWMADMIN%>">
-                        <div id="header-menu-alert" class="pwm-icon pwm-icon-warning display-none" title="<pwm:display key="Header_HealthWarningsPresent" bundle="Admin"/>"></div>
+                        <div id="header-menu-alert" class="pwm-icon pwm-icon-warning nodisplay" title="<pwm:display key="Header_HealthWarningsPresent" bundle="Admin"/>"></div>
                     </pwm:if>
                     <div id="header-username-group">
                         <pwm:if test="<%=PwmIfTest.authenticated%>">

+ 1 - 1
webapp/src/main/webapp/WEB-INF/jsp/fragment/header-menu.jsp

@@ -76,7 +76,7 @@
                 </pwm:if>
             </pwm:if>
         </div>
-        <div id="panel-header-healthData" class="header-warning-row header-warning-healthDat display-none">
+        <div id="panel-header-healthData" class="header-warning-row header-warning-healthDat nodisplay">
             <div id="panel-healthHeaderErrors" class="header-error">
                 <span class="pwm-icon pwm-icon-warning"></span><pwm:display key="Header_HealthWarningsPresent" bundle="Admin"/>
             </div>

+ 1 - 1
webapp/src/main/webapp/WEB-INF/jsp/fragment/ldap-selector.jsp

@@ -69,7 +69,7 @@
     </select>
 </div>
 <% } %>
-<div <%=showContextSelector?"":"class=\"display-none\" "%> id="contextSelectorWrapper">
+<div <%=showContextSelector?"":"class=\"nodisplay\" "%> id="contextSelectorWrapper">
     <h2 class="loginFieldLabel"><label for="<%=PwmConstants.PARAM_CONTEXT%>"><pwm:display key="Field_Location"/></label></h2>
     <div class="formFieldWrapper">
         <select name="<%=PwmConstants.PARAM_CONTEXT%>" id="<%=PwmConstants.PARAM_CONTEXT%>" class="selectfield" title="<pwm:display key="Field_Location"/>">

+ 0 - 1
webapp/src/main/webapp/WEB-INF/jsp/fragment/message.jsp

@@ -40,5 +40,4 @@
 <% } else { %>
     <span id="message" class="message nodisplay">&nbsp;</span>
 <% } %>
-    <div id="capslockwarning" class="display-none"><pwm:display key="Display_CapsLockIsOn"/></div>
 </div>

+ 4 - 5
webapp/src/main/webapp/WEB-INF/jsp/guest-create.jsp

@@ -31,6 +31,7 @@
 <%@ taglib uri="pwm" prefix="pwm" %>
 <% final String maxValidDate = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestMaximumExpirationDate); %>
 <% final String selectedDate = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestCurrentExpirationDate); %>
+<% final String minValidDate = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestMinimumExpirationDate); %>
 <% final String maxValidDays = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestMaximumValidDays); %>
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <%@ include file="fragment/header.jsp" %>
@@ -50,12 +51,11 @@
             <p>
                 <label>
                     <pwm:display key="Display_ExpirationDate" value1="<%=String.valueOf(maxValidDays)%>"/>
-                    <input name="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>" id="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>" type="hidden" required="true" value="<%=selectedDate%>"/>
-                    <input name="expiredate-stub" id="expiredate-stub" type="date" required="true" value="<%=selectedDate%>"/>
+
                 </label>
             </p>
-            <pwm:script>
-            </pwm:script>
+            <input name="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>" id="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>"
+                   type="date" required="true" max="<%=maxValidDate%>" min="<%=minValidDate%>" value="<%=selectedDate%>"/>
 
             <div class="buttonbar">
                 <input type="hidden" name="processAction" value="create"/>
@@ -73,7 +73,6 @@
 <pwm:script>
     <script type="text/javascript">
         PWM_GLOBAL['startupFunctions'].push(function(){
-            PWM_GUEST.initDatePicker('<%=maxValidDate%>','<%=selectedDate%>');
         });
     </script>
 </pwm:script>

+ 3 - 2
webapp/src/main/webapp/WEB-INF/jsp/guest-update.jsp

@@ -31,6 +31,7 @@
 <%@ taglib uri="pwm" prefix="pwm" %>
 <% final String maxValidDate = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestMaximumExpirationDate); %>
 <% final String selectedDate = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestCurrentExpirationDate); %>
+<% final String minValidDate = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestMinimumExpirationDate); %>
 <% final String maxValidDays = (String)JspUtility.getAttribute(pageContext, PwmRequestAttribute.GuestMaximumValidDays); %>
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <%@ include file="fragment/header.jsp" %>
@@ -49,10 +50,10 @@
             <p>
                 <label>
                     <pwm:display key="Display_ExpirationDate" value1="<%=String.valueOf(maxValidDays)%>"/>
-                    <input name="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>" id="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>" type="hidden" required="true" value="<%=selectedDate%>"/>
-                    <input name="expiredate-stub" id="expiredate-stub" type="date" required="true" value="<%=selectedDate%>"/>
                 </label>
             </p>
+            <input name="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>" id="<%=GuestRegistrationServlet.HTTP_PARAM_EXPIRATION_DATE%>"
+                   type="date" required="true" max="<%=maxValidDate%>" min="<%=minValidDate%>" value="<%=selectedDate%>"/>
             <div class="buttonbar">
                 <input type="hidden" name="processAction" value="update"/>
                 <button type="submit" name="Update" class="btn" id="submitBtn">

+ 0 - 4
webapp/src/main/webapp/WEB-INF/jsp/newuser-wait.jsp

@@ -59,7 +59,6 @@
         <%@ include file="fragment/message.jsp" %>
         <div class="meteredProgressBar">
           <progress id="html5ProgressBar" max="100" value="0">
-            <div data-dojo-type="dijit/ProgressBar" style="width:100%" data-dojo-id="passwordProgressBar" id="passwordProgressBar" data-dojo-props="maximum:100"></div>
           </progress>
         </div>
         <div style="text-align: center; width: 100%; padding-top: 50px">
@@ -76,10 +75,7 @@
 <pwm:script>
 <script type="text/javascript">
     PWM_GLOBAL['startupFunctions'].push(function(){
-        require(["dojo/parser", "dijit/ProgressBar","dojo/ready"], function(parser,registry){
-            parser.parse();
             PWM_NEWUSER.refreshCreateStatus(<%=checkIntervalSeconds * 1000%>);
-        });
     });
 </script>
 </pwm:script>

+ 0 - 96
webapp/src/main/webapp/public/randomgen.jsp

@@ -1,96 +0,0 @@
-<%--
- ~ Password Management Servlets (PWM)
- ~ http://www.pwm-project.org
- ~
- ~ Copyright (c) 2006-2009 Novell, Inc.
- ~ Copyright (c) 2009-2021 The PWM Project
- ~
- ~ Licensed 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.
---%>
-<%--
-       THIS FILE IS NOT INTENDED FOR END USER MODIFICATION.
-       See the README.TXT file in WEB-INF/jsp before making changes.
---%>
-
-
-<!DOCTYPE html>
-<%@ page language="java" session="true" isThreadSafe="true"
-         contentType="text/html" %>
-<%@ taglib uri="pwm" prefix="pwm" %>
-<html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
-<%@ include file="/WEB-INF/jsp/fragment/header.jsp" %>
-<body>
-<div id="wrapper">
-    <jsp:include page="/WEB-INF/jsp/fragment/header-body.jsp">
-        <jsp:param name="pwm.PageName" value="Random Passwords"/>
-    </jsp:include>
-    <table id="mastertable">
-    </table>
-    <div class="push"></div>
-</div>
-<pwm:script>
-<script type="text/javascript">
-    var cellCount = 0;
-    function makeTable() {
-        require(["dojo","dojo/window"],function(dojo){
-            var vs = dojo.window.getBox();
-            var cellHeight = 20;
-            var cellWidth = 150;
-
-            var rows = Math.floor(vs.w / cellWidth);
-            var columns = Math.floor((vs.h - 70 - 20) / cellHeight); //70 for header, 50 for footer
-
-            var innerHtmlText = "";
-            var position = 0;
-            var fetchList = new Array();
-            for (var columnCounter = 0; columnCounter < columns; columnCounter++) {
-                innerHtmlText = innerHtmlText + '<tr>';
-                for (var rowCounter = 0; rowCounter < rows; rowCounter++) {
-                    position = position + 1;
-                    var idString = "randomGen" + position;
-                    fetchList[position] = idString;
-                    innerHtmlText = innerHtmlText + '<td id="' + idString + '" style="text-align: center;" width="'+cellWidth+'">&nbsp;</td>';
-                }
-                innerHtmlText = innerHtmlText + '</tr>';
-            }
-            PWM_MAIN.getObject('mastertable').innerHTML = innerHtmlText;
-            initFetchProcess(fetchList);
-            cellCount = position;
-        });
-    }
-
-    function initFetchProcess(fetchList) {
-        for (var i = 0; i < fetchList.length; i++) {
-            fetchList.sort(function() {
-                return 0.5 - Math.random()
-            });
-        }
-        var randomConfig = {};
-        randomConfig['fetchList'] = fetchList;
-        PWM_CHANGEPW.fetchRandoms(randomConfig);
-    }
-
-    PWM_GLOBAL['startupFunctions'].push(function(){
-        require(["dojo/ready"],function(){
-            makeTable();
-            window.onresize = function(event) {
-                makeTable();
-            }
-        });
-    });
-</script>
-</pwm:script>
-<pwm:script-ref url="/public/resources/js/changepassword.js"/>
-<%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
-</body>
-</html>

+ 136 - 131
webapp/src/main/webapp/public/resources/js/admin.js

@@ -23,29 +23,29 @@ var PWM_MAIN = PWM_MAIN || {};
 var PWM_GLOBAL = PWM_GLOBAL || {};
 
 PWM_ADMIN.initAdminNavMenu = function() {
-    var makeMenu = function(){
+    const makeMenu = function () {
 
-        require(["dijit/form/DropDownButton", "dijit/DropDownMenu", "dijit/Menu","dijit/MenuItem", "dijit/PopupMenuItem", "dojo/dom", "dijit/MenuSeparator"],
-            function(DropDownButton, DropDownMenu, Menu, MenuItem, PopupMenuItem, dom, MenuSeparator){
-                var pMenu = new DropDownMenu({ style: "display: none;"});
+        require(["dijit/form/DropDownButton", "dijit/DropDownMenu", "dijit/Menu", "dijit/MenuItem", "dijit/PopupMenuItem", "dojo/dom", "dijit/MenuSeparator"],
+            function (DropDownButton, DropDownMenu, Menu, MenuItem, PopupMenuItem, dom, MenuSeparator) {
+                const pMenu = new DropDownMenu({style: "display: none;"});
                 pMenu.addChild(new MenuItem({
                     label: PWM_ADMIN.showString('Title_LogViewer'),
                     id: 'eventLog_dropitem',
-                    onClick: function() {
+                    onClick: function () {
                         PWM_MAIN.gotoUrl(PWM_GLOBAL['url-context'] + '/private/admin/logs');
                     }
                 }));
                 pMenu.addChild(new MenuItem({
                     label: PWM_ADMIN.showString('Title_TokenLookup'),
                     id: 'tokenLookup_dropitem',
-                    onClick: function() {
+                    onClick: function () {
                         PWM_MAIN.gotoUrl(PWM_GLOBAL['url-context'] + '/private/admin/tokens');
                     }
                 }));
                 pMenu.addChild(new MenuItem({
                     label: PWM_ADMIN.showString('Title_URLReference'),
                     id: 'urlReference_dropitem',
-                    onClick: function() {
+                    onClick: function () {
                         PWM_MAIN.gotoUrl(PWM_GLOBAL['url-context'] + '/private/admin/urls');
                     }
                 }));
@@ -53,7 +53,7 @@ PWM_ADMIN.initAdminNavMenu = function() {
                 pMenu.addChild(new MenuItem({
                     label: 'Full Page Health Status',
                     id: 'fullPageHealthStatus_dropitem',
-                    onClick: function() {
+                    onClick: function () {
                         PWM_MAIN.gotoUrl(PWM_GLOBAL['url-context'] + '/public/health');
                     }
                 }));
@@ -61,16 +61,16 @@ PWM_ADMIN.initAdminNavMenu = function() {
                 pMenu.addChild(new MenuItem({
                     label: '<span class="pwm-icon pwm-icon-external-link"></span> Application Reference',
                     id: 'applictionReference_dropitem',
-                    onClick: function() {
-                        PWM_MAIN.newWindowOpen(PWM_GLOBAL['url-context'] + '/public/reference/','referencedoc');
+                    onClick: function () {
+                        PWM_MAIN.newWindowOpen(PWM_GLOBAL['url-context'] + '/public/reference/', 'referencedoc');
                     }
                 }));
                 if (PWM_GLOBAL['setting-displayEula'] === true) {
                     pMenu.addChild(new MenuItem({
                         label: 'View EULA',
                         id: 'viewEULA_dropitem',
-                        onClick: function() {
-                            PWM_MAIN.showEula(false,null);
+                        onClick: function () {
+                            PWM_MAIN.showEula(false, null);
                         }
                     }));
                 }
@@ -78,20 +78,20 @@ PWM_ADMIN.initAdminNavMenu = function() {
                 pMenu.addChild(new MenuItem({
                     label: 'Configuration Manager',
                     id: 'configurationManager_dropitem',
-                    onClick: function() {
+                    onClick: function () {
                         PWM_MAIN.gotoUrl(PWM_GLOBAL['url-context'] + '/private/config/manager');
                     }
                 }));
                 pMenu.addChild(new MenuItem({
                     label: 'Configuration Editor',
                     id: 'configurationEditor_dropitem',
-                    onClick: function() {
+                    onClick: function () {
                         PWM_MAIN.gotoUrl(PWM_GLOBAL['url-context'] + '/private/config/editor');
                     }
                 }));
 
 
-                var dropDownButton = new DropDownButton({
+                const dropDownButton = new DropDownButton({
                     label: "More Options",
                     name: "More Options",
                     dropDown: pMenu,
@@ -118,7 +118,7 @@ PWM_ADMIN.initDownloadProcessReportZipForm = function() {
     });
     PWM_MAIN.doQuery("#reportCancelButton", function(node){
         PWM_MAIN.addEventHandler(node, "click", function() {
-            var url = PWM_MAIN.addParamToUrl(window.location.href,'processAction','cancelDownload');
+            const url = PWM_MAIN.addParamToUrl(window.location.href, 'processAction', 'cancelDownload');
             PWM_MAIN.ajaxRequest(url, function(){
                 PWM_MAIN.showDialog({title:"Report Status",text:"Download Cancelled"})
             });
@@ -172,14 +172,14 @@ PWM_ADMIN.webSessionHeaders = function() {
 };
 
 PWM_ADMIN.initActiveSessionGrid=function() {
-    var headers = PWM_ADMIN.webSessionHeaders();
+    const headers = PWM_ADMIN.webSessionHeaders();
 
     require(["dojo","dojo/_base/declare", "dgrid/Grid", "dgrid/Keyboard", "dgrid/Selection", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnReorder", "dgrid/extensions/ColumnHider", "dgrid/extensions/DijitRegistry"],
         function(dojo, declare, Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry){
-            var columnHeaders = headers;
+            const columnHeaders = headers;
 
             // Create a new constructor by mixing in the components
-            var CustomGrid = declare([ Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry ]);
+            const CustomGrid = declare([Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry]);
 
             // Now, create an instance of our custom grid
             PWM_VAR['activeSessionsGrid'] = new CustomGrid({
@@ -195,15 +195,15 @@ PWM_ADMIN.initActiveSessionGrid=function() {
 };
 
 PWM_ADMIN.refreshActiveSessionGrid=function() {
-    var grid = PWM_VAR['activeSessionsGrid'];
+    const grid = PWM_VAR['activeSessionsGrid'];
     grid.refresh();
 
-    var maximum = PWM_MAIN.getObject('maxActiveSessionResults').value;
-    var url = PWM_MAIN.addParamToUrl(window.location.href,"processAction", "sessionData");
+    const maximum = PWM_MAIN.getObject('maxActiveSessionResults').value;
+    let url = PWM_MAIN.addParamToUrl(window.location.href, "processAction", "sessionData");
     url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
-    var loadFunction = function(data) {
+    const loadFunction = function (data) {
         grid.renderArray(data['data']);
-        grid.set("sort", { attribute : 'createTime', ascending: false, descending: true });
+        grid.set("sort", {attribute: 'createTime', ascending: false, descending: true});
     };
     PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET'});
 };
@@ -221,19 +221,19 @@ PWM_ADMIN.intruderHeaders = function(){
 
 PWM_ADMIN.initIntrudersGrid=function() {
     PWM_VAR['intruderRecordTypes'] = ["ADDRESS","USERNAME","USER_ID","ATTRIBUTE","TOKEN_DEST"];
-    var intruderGridHeaders = PWM_ADMIN.intruderHeaders();
+    const intruderGridHeaders = PWM_ADMIN.intruderHeaders();
 
     require(["dojo","dojo/_base/declare", "dgrid/Grid", "dgrid/Keyboard", "dgrid/Selection", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnReorder", "dgrid/extensions/ColumnHider", "dgrid/extensions/DijitRegistry"],
         function(dojo, declare, Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry){
             // Create a new constructor by mixing in the components
-            var CustomGrid = declare([ Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry ]);
+            const CustomGrid = declare([Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry]);
 
             // Now, create an instance of our custom grid
             PWM_VAR['intruderGrid'] = {};
-            for (var i = 0; i < PWM_VAR['intruderRecordTypes'].length; i++) {
+            for (let i = 0; i < PWM_VAR['intruderRecordTypes'].length; i++) {
                 (function(iter){
-                    var recordType = PWM_VAR['intruderRecordTypes'][iter];
-                    var grid = new CustomGrid({ columns: intruderGridHeaders}, recordType + "_Grid");
+                    const recordType = PWM_VAR['intruderRecordTypes'][iter];
+                    const grid = new CustomGrid({columns: intruderGridHeaders}, recordType + "_Grid");
                     PWM_VAR['intruderGrid'][recordType] = grid;
 
                     grid.on(".dgrid-row:click", function(evt){
@@ -248,8 +248,8 @@ PWM_ADMIN.initIntrudersGrid=function() {
 };
 
 PWM_ADMIN.refreshIntruderGrid=function() {
-    for (var i = 0; i < PWM_VAR['intruderRecordTypes'].length; i++) {
-        var recordType = PWM_VAR['intruderRecordTypes'][i];
+    for (let i = 0; i < PWM_VAR['intruderRecordTypes'].length; i++) {
+        const recordType = PWM_VAR['intruderRecordTypes'][i];
         PWM_VAR['intruderGrid'][recordType].refresh();
     }
     try {
@@ -257,11 +257,11 @@ PWM_ADMIN.refreshIntruderGrid=function() {
     } catch (e) {
         maximum = 1000;
     }
-    var url = PWM_MAIN.addParamToUrl(window.location.href,"processAction", "intruderData");
+    let url = PWM_MAIN.addParamToUrl(window.location.href, "processAction", "intruderData");
     url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
-    var loadFunction = function(data) {
-        for (var i = 0; i < PWM_VAR['intruderRecordTypes'].length; i++) {
-            var recordType = PWM_VAR['intruderRecordTypes'][i];
+    const loadFunction = function (data) {
+        for (let i = 0; i < PWM_VAR['intruderRecordTypes'].length; i++) {
+            const recordType = PWM_VAR['intruderRecordTypes'][i];
             PWM_VAR['intruderGrid'][recordType].renderArray(data['data'][recordType]);
         }
     };
@@ -331,7 +331,7 @@ PWM_ADMIN.initLogGrid=function() {
     require(["dojo","dojo/_base/declare", "dgrid/Grid", "dgrid/Keyboard", "dgrid/Selection", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnReorder", "dgrid/extensions/ColumnHider", "dgrid/extensions/DijitRegistry"],
         function(dojo, declare, Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry){
             // Create a new constructor by mixing in the components
-            var CustomGrid = declare([ Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry ]);
+            const CustomGrid = declare([Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry]);
 
             // Now, create an instance of our custom userGrid
             PWM_VAR['logViewerGrid'] = new CustomGrid({columns: PWM_ADMIN.logHeaders()}, "logViewerGrid");
@@ -341,23 +341,23 @@ PWM_ADMIN.initLogGrid=function() {
         }
     );
 
-    var saveSettings = function() {
-        var logSettings = PWM_ADMIN.readLogFormData();
-        PWM_MAIN.Preferences.writeSessionStorage('logSettings',logSettings);
+    const saveSettings = function () {
+        const logSettings = PWM_ADMIN.readLogFormData();
+        PWM_MAIN.Preferences.writeSessionStorage('logSettings', logSettings);
     };
 
     PWM_MAIN.addEventHandler('form-loadLog','change', saveSettings);
     PWM_MAIN.addEventHandler('form-downloadLog','change', saveSettings);
 
-    var loadSettings = function () {
-        var settings = PWM_MAIN.Preferences.readSessionStorage('logSettings');
+    const loadSettings = function () {
+        const settings = PWM_MAIN.Preferences.readSessionStorage('logSettings');
         if (settings) {
             PWM_MAIN.getObject('username').value = settings['username'];
             PWM_MAIN.getObject('text').value = settings['text'];
             PWM_MAIN.getObject('count').value = settings['count'];
             PWM_MAIN.getObject('maxTime').value = settings['maxTime'];
-            PWM_MAIN.JSLibrary.setValueOfSelectElement('type',settings['type']);
-            PWM_MAIN.JSLibrary.setValueOfSelectElement('level',settings['level']);
+            PWM_MAIN.JSLibrary.setValueOfSelectElement('type', settings['type']);
+            PWM_MAIN.JSLibrary.setValueOfSelectElement('level', settings['level']);
             PWM_MAIN.JSLibrary.setValueOfSelectElement('displayType', settings['displayType']);
             if (PWM_MAIN.getObject('form-downloadLog')) {
                 PWM_MAIN.JSLibrary.setValueOfSelectElement('downloadType', settings['downloadType']);
@@ -369,7 +369,7 @@ PWM_ADMIN.initLogGrid=function() {
 };
 
 PWM_ADMIN.readLogFormData = function() {
-    var settings = {};
+    const settings = {};
     settings['username'] = PWM_MAIN.getObject('username').value;
     settings['text'] = PWM_MAIN.getObject('text').value;
     settings['count'] = PWM_MAIN.getObject('count').value;
@@ -386,12 +386,12 @@ PWM_ADMIN.readLogFormData = function() {
 
 PWM_ADMIN.refreshLogData = function() {
     PWM_MAIN.getObject('button-search').disabled = true;
-    var logSettings = PWM_ADMIN.readLogFormData();
+    const logSettings = PWM_ADMIN.readLogFormData();
 
-    var processFunction = function(data) {
+    const processFunction = function (data) {
         console.time('someFunction');
 
-        var records = data['data']['records'];
+        const records = data['data']['records'];
         if (PWM_MAIN.JSLibrary.isEmpty(records)) {
             PWM_MAIN.removeCssClass('div-noResultsMessage', 'nodisplay');
             PWM_MAIN.addCssClass('wrapper-logViewerGrid', 'nodisplay');
@@ -402,18 +402,18 @@ PWM_ADMIN.refreshLogData = function() {
                 PWM_MAIN.addCssClass('div-noResultsMessage', 'nodisplay');
                 PWM_MAIN.removeCssClass('wrapper-logViewerGrid', 'nodisplay');
                 PWM_MAIN.addCssClass('wrapper-lineViewer', 'nodisplay');
-                var grid = PWM_VAR['logViewerGrid'];
+                const grid = PWM_VAR['logViewerGrid'];
                 grid.refresh();
                 grid.renderArray(records);
-                grid.set("timestamp", { attribute : 'createTime', ascending: false, descending: true });
+                grid.set("timestamp", {attribute: 'createTime', ascending: false, descending: true});
             } else {
                 PWM_MAIN.addCssClass('div-noResultsMessage', 'nodisplay');
                 PWM_MAIN.addCssClass('wrapper-logViewerGrid', 'nodisplay');
                 PWM_MAIN.removeCssClass('wrapper-lineViewer', 'nodisplay');
-                var textOutput = '';
+                let textOutput = '';
 
-                for (var iterator in records) {
-                    (function(record) {
+                for (let iterator in records) {
+                    (function (record) {
                         textOutput += records[record];
                         textOutput += "\n";
                     }(iterator));
@@ -427,8 +427,8 @@ PWM_ADMIN.refreshLogData = function() {
         PWM_MAIN.closeWaitDialog();
     };
 
-    var url = PWM_MAIN.addParamToUrl(PWM_GLOBAL['url-context'] + '/private/admin',  'processAction', 'readLogData');
-    var options = {};
+    const url = PWM_MAIN.addParamToUrl(PWM_GLOBAL['url-context'] + '/private/admin', 'processAction', 'readLogData');
+    const options = {};
     options.content = logSettings;
 
     PWM_MAIN.showWaitDialog({loadFunction:function(){
@@ -442,7 +442,7 @@ PWM_ADMIN.initAuditGrid=function() {
     require(["dojo","dojo/_base/declare", "dgrid/Grid", "dgrid/Keyboard", "dgrid/Selection", "dgrid/extensions/ColumnResizer", "dgrid/extensions/ColumnReorder", "dgrid/extensions/ColumnHider", "dgrid/extensions/DijitRegistry"],
         function(dojo, declare, Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry){
             // Create a new constructor by mixing in the components
-            var CustomGrid = declare([ Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry ]);
+            const CustomGrid = declare([Grid, Keyboard, Selection, ColumnResizer, ColumnReorder, ColumnHider, DijitRegistry]);
 
             // Now, create an instance of our custom userGrid
             PWM_VAR['auditUserGrid'] = new CustomGrid({columns: PWM_ADMIN.auditUserHeaders()}, "auditUserGrid");
@@ -486,10 +486,10 @@ PWM_ADMIN.refreshAuditGridData=function(maximum,type) {
         maximum = 100;
     }
 
-    var url = PWM_MAIN.addParamToUrl(window.location.href, "processAction", "auditData");
+    let url = PWM_MAIN.addParamToUrl(window.location.href, "processAction", "auditData");
     url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
     url = PWM_MAIN.addParamToUrl(url,'type',type);
-    var loadFunction = function(data) {
+    const loadFunction = function (data) {
         grid.renderArray(data['data']['records']);
     };
     PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET'});
@@ -497,12 +497,17 @@ PWM_ADMIN.refreshAuditGridData=function(maximum,type) {
 
 PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
     options = options === undefined ? {} : options;
-    var doRefresh = options['refreshTime']
-        ? function(){setTimeout(function(){PWM_ADMIN.showStatChart(statName,days,divName,options);},options['refreshTime']);}
-        : function(){};
-    var statsGetUrl = PWM_MAIN.addParamToUrl( PWM_GLOBAL['url-context'] + '/public/api',"processAction","statistics");
-    var epsTypes = PWM_GLOBAL['epsTypes'];
-    var epsDurations = PWM_GLOBAL['epsDurations'];
+    const doRefresh = options['refreshTime']
+        ? function () {
+            setTimeout(function () {
+                PWM_ADMIN.showStatChart(statName, days, divName, options);
+            }, options['refreshTime']);
+        }
+        : function () {
+        };
+    let statsGetUrl = PWM_MAIN.addParamToUrl(PWM_GLOBAL['url-context'] + '/public/api', "processAction", "statistics");
+    const epsTypes = PWM_GLOBAL['epsTypes'];
+    const epsDurations = PWM_GLOBAL['epsDurations'];
     require(["dojo",
             "dijit",
             "dijit/registry",
@@ -517,15 +522,15 @@ PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
             statsGetUrl = PWM_MAIN.addParamToUrl(statsGetUrl, "statName", statName);
             statsGetUrl = PWM_MAIN.addParamToUrl(statsGetUrl, "days", days);
 
-            var errorFunction = function() {
-                for (var loopEpsTypeIndex = 0; loopEpsTypeIndex < epsTypes.length; loopEpsTypeIndex++) { // clear all the gauges
-                    var loopEpsName = epsTypes[loopEpsTypeIndex] + '';
-                    for (var loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
-                        var loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
-                        var loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
+            const errorFunction = function () {
+                for (let loopEpsTypeIndex = 0; loopEpsTypeIndex < epsTypes.length; loopEpsTypeIndex++) { // clear all the gauges
+                    const loopEpsName = epsTypes[loopEpsTypeIndex] + '';
+                    for (let loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
+                        const loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
+                        const loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
                         if (PWM_MAIN.getObject(loopEpsID) !== null) {
                             if (registry.byId(loopEpsID)) {
-                                registry.byId(loopEpsID).setAttribute('value','0');
+                                registry.byId(loopEpsID).setAttribute('value', '0');
                             }
                         }
                     }
@@ -533,20 +538,20 @@ PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
                 doRefresh();
             };
 
-            var loadFunction = function(data) {
+            const loadFunction = function (data) {
                 {// gauges
                     console.log('Beginning stats update process...');
                     data = data['data'];
-                    var activityCount = 0;
-                    for (var loopEpsIndex = 0; loopEpsIndex < epsTypes.length; loopEpsIndex++) {
-                        var loopEpsName = epsTypes[loopEpsIndex] + '';
-                        for (var loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
-                            var loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
-                            var loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
-                            var loopFieldEpsID = "FIELD_" + loopEpsName + "_" + loopEpsDuration;
-                            var loopEpsValue = data['EPS'][loopEpsName + "_" + loopEpsDuration];
-                            var loopEpmValue = (loopEpsValue * 60).toFixed(3);
-                            var loopTop = PWM_GLOBAL['client.activityMaxEpsRate'];
+                    let activityCount = 0;
+                    for (let loopEpsIndex = 0; loopEpsIndex < epsTypes.length; loopEpsIndex++) {
+                        const loopEpsName = epsTypes[loopEpsIndex] + '';
+                        for (let loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
+                            const loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
+                            const loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
+                            const loopFieldEpsID = "FIELD_" + loopEpsName + "_" + loopEpsDuration;
+                            const loopEpsValue = data['EPS'][loopEpsName + "_" + loopEpsDuration];
+                            const loopEpmValue = (loopEpsValue * 60).toFixed(3);
+                            const loopTop = PWM_GLOBAL['client.activityMaxEpsRate'];
                             if (loopEpsDuration === "HOURLY") {
                                 activityCount += loopEpsValue;
                             }
@@ -556,10 +561,10 @@ PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
                             if (PWM_MAIN.getObject(loopEpsID) !== null) {
                                 console.log('EpsID=' + loopEpsID + ', ' + 'Eps=' + loopEpsValue + ', ' + 'Epm=' + loopEpmValue);
                                 if (registry.byId(loopEpsID)) {
-                                    registry.byId(loopEpsID).setAttribute('value',loopEpmValue);
-                                    registry.byId(loopEpsID).setAttribute('max',loopTop);
+                                    registry.byId(loopEpsID).setAttribute('value', loopEpmValue);
+                                    registry.byId(loopEpsID).setAttribute('max', loopTop);
                                 } else {
-                                    var glossyCircular = new dojox.gauges.GlossyCircularGauge({
+                                    const glossyCircular = new dojox.gauges.GlossyCircularGauge({
                                         background: [255, 255, 255, 0],
                                         noChange: true,
                                         value: loopEpmValue,
@@ -579,19 +584,19 @@ PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
                     PWM_GLOBAL['epsActivityCount'] = activityCount;
                 }
                 if (divName !== null && PWM_MAIN.getObject(divName)) { // stats chart
-                    var values = [];
-                    for(var key in data['nameData']) {
-                        var value = data['nameData'][key];
+                    const values = [];
+                    for (let key in data['nameData']) {
+                        const value = data['nameData'][key];
                         values.push(parseInt(value));
                     }
 
                     if (PWM_GLOBAL[divName + '-stored-reference']) {
-                        var existingChart = PWM_GLOBAL[divName + '-stored-reference'];
+                        const existingChart = PWM_GLOBAL[divName + '-stored-reference'];
                         existingChart.destroy();
                     }
-                    var c = new dojox.charting.Chart2D(divName);
+                    const c = new dojox.charting.Chart2D(divName);
                     PWM_GLOBAL[divName + '-stored-reference'] = c;
-                    c.addPlot("default", {type: "Columns", gap:'2'});
+                    c.addPlot("default", {type: "Columns", gap: '2'});
                     c.addAxis("x", {});
                     c.addAxis("y", {vertical: true});
                     c.setTheme(dojox.charting.themes.Wetland);
@@ -607,17 +612,17 @@ PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
 
 PWM_ADMIN.showAppHealth = function(parentDivID, options, refreshNow) {
 
-    var inputOpts = options || PWM_GLOBAL['showPwmHealthOptions'] || {};
+    const inputOpts = options || PWM_GLOBAL['showPwmHealthOptions'] || {};
     PWM_GLOBAL['showPwmHealthOptions'] = options;
-    var refreshUrl = inputOpts['sourceUrl'] || PWM_GLOBAL['url-context'] + "/public/api?processAction=health";
-    var showRefresh = inputOpts['showRefresh'];
-    var showTimestamp = inputOpts['showTimestamp'];
-    var refreshTime = inputOpts['refreshTime'] || 60 * 1000;
-    var finishFunction = inputOpts['finishFunction'];
+    let refreshUrl = inputOpts['sourceUrl'] || PWM_GLOBAL['url-context'] + "/public/api?processAction=health";
+    const showRefresh = inputOpts['showRefresh'];
+    const showTimestamp = inputOpts['showTimestamp'];
+    const refreshTime = inputOpts['refreshTime'] || 60 * 1000;
+    const finishFunction = inputOpts['finishFunction'];
 
     console.log('starting showPwmHealth: refreshTime=' + refreshTime);
     require(["dojo"],function(dojo){
-        var parentDiv = dojo.byId(parentDivID);
+        const parentDiv = dojo.byId(parentDivID);
         if (PWM_GLOBAL['inhibitHealthUpdate'] === true) {
             try { parentDiv.innerHTML = ''; } catch (e) { console.log('unable to update health div' + e) };
             return;
@@ -634,23 +639,23 @@ PWM_ADMIN.showAppHealth = function(parentDivID, options, refreshNow) {
             refreshUrl = PWM_MAIN.addParamToUrl(refreshUrl, 'refreshImmediate', 'true');
         }
 
-        var loadFunction = function(data) {
+        const loadFunction = function (data) {
             if (data['error']) {
                 PWM_MAIN.showErrorDialog(data);
             } else {
                 PWM_GLOBAL['pwm-health'] = data['data']['overall'];
-                var htmlBody = PWM_ADMIN.makeHealthHtml(data['data'], showTimestamp, showRefresh);
+                const htmlBody = PWM_ADMIN.makeHealthHtml(data['data'], showTimestamp, showRefresh);
                 parentDiv.innerHTML = htmlBody;
                 PWM_MAIN.TimestampHandler.initElement(PWM_MAIN.getObject('healthCheckTimestamp'));
 
-                PWM_MAIN.addEventHandler('button-refreshHealth','click',function(){
+                PWM_MAIN.addEventHandler('button-refreshHealth', 'click', function () {
                     PWM_ADMIN.showAppHealth(parentDivID, options, true);
                 });
 
                 PWM_GLOBAL['healthCheckInProgress'] = false;
 
                 if (refreshTime > 0) {
-                    setTimeout(function() {
+                    setTimeout(function () {
                         PWM_ADMIN.showAppHealth(parentDivID, options);
                     }, refreshTime);
                 }
@@ -663,11 +668,11 @@ PWM_ADMIN.showAppHealth = function(parentDivID, options, refreshNow) {
             }
         };
 
-        var errorFunction = function(error) {
+        const errorFunction = function (error) {
             if (error !== null) {
                 console.log('error reaching server: ' + error);
             }
-            var htmlBody = '<div style="text-align:center; background-color: #d20734">';
+            let htmlBody = '<div style="text-align:center; background-color: #d20734">';
             htmlBody += '<br/><span style="font-weight: bold;">unable to load health data from server</span></br>';
             htmlBody += '<br/>' + new Date().toLocaleString() + '&nbsp;&nbsp;&nbsp;';
             if (showRefresh) {
@@ -678,7 +683,7 @@ PWM_ADMIN.showAppHealth = function(parentDivID, options, refreshNow) {
             PWM_GLOBAL['healthCheckInProgress'] = false;
             PWM_GLOBAL['pwm-health'] = 'WARN';
             if (refreshTime > 0) {
-                setTimeout(function() {
+                setTimeout(function () {
                     PWM_ADMIN.showAppHealth(parentDivID, options);
                 }, refreshTime);
             }
@@ -692,12 +697,12 @@ PWM_ADMIN.showAppHealth = function(parentDivID, options, refreshNow) {
 };
 
 PWM_ADMIN.makeHealthHtml = function(healthData, showTimestamp, showRefresh) {
-    var healthRecords = healthData['records'];
-    var htmlBody = '<div>';
+    const healthRecords = healthData['records'];
+    let htmlBody = '<div>';
     htmlBody += '<div class="healthTable-wrapper"><table>';
-    for (var i = 0; i < healthRecords.length; i++) {
+    for (let i = 0; i < healthRecords.length; i++) {
         (function(iter){
-            var loopRecord = healthRecords[iter];
+            const loopRecord = healthRecords[iter];
             htmlBody += '<tr><td class="key" style="width:1px; white-space:nowrap;"">';
             htmlBody += loopRecord['topic'];
             htmlBody += '</td><td class="health-' + loopRecord['status'] + '">';
@@ -729,7 +734,7 @@ PWM_ADMIN.makeHealthHtml = function(healthData, showTimestamp, showRefresh) {
 PWM_ADMIN.initPwNotifyPage = function() {
     PWM_MAIN.addEventHandler('button-executePwNotifyJob','click',function(){
         PWM_MAIN.showWaitDialog({loadFunction:function(){
-                var url = PWM_MAIN.addParamToUrl(window.location.pathname, 'processAction','startPwNotifyJob');
+                const url = PWM_MAIN.addParamToUrl(window.location.pathname, 'processAction', 'startPwNotifyJob');
                 PWM_MAIN.ajaxRequest(url,function(data){
                     setTimeout(function(){
                         PWM_MAIN.showDialog({title:'Job Started',text:data['successMessage'],okAction:function(){
@@ -764,14 +769,14 @@ PWM_ADMIN.initPwNotifyPage = function() {
 };
 
 PWM_ADMIN.loadPwNotifyStatus = function () {
-    var processData = function (data) {
-        var statusData = data['data']['statusData'];
-        var htmlData = '<tr><td colspan="2" class="title">Password Expiration Notification Job Status</td></tr>';
+    const processData = function (data) {
+        const statusData = data['data']['statusData'];
+        let htmlData = '<tr><td colspan="2" class="title">Password Expiration Notification Job Status</td></tr>';
         for (var item in statusData) {
-            (function(key){
-                var item = statusData[key];
+            (function (key) {
+                const item = statusData[key];
                 htmlData += '<tr><td>' + item['label'] + '</td><td>';
-                if ( item['type'] === 'timestamp') {
+                if (item['type'] === 'timestamp') {
                     htmlData += '<span id="pwNotifyStatusRow-' + key + '" class="timestamp">' + item['value'] + '</span>';
                 } else {
                     htmlData += item['value'];
@@ -783,9 +788,9 @@ PWM_ADMIN.loadPwNotifyStatus = function () {
         PWM_MAIN.getObject('table-pwNotifyStatus').innerHTML = htmlData;
 
         for (var item in statusData) {
-            (function(key){
-                var item = statusData[key];
-                if ( item['type'] === 'timestamp') {
+            (function (key) {
+                const item = statusData[key];
+                if (item['type'] === 'timestamp') {
                     PWM_MAIN.TimestampHandler.initElement(PWM_MAIN.getObject('pwNotifyStatusRow-' + key));
                 }
             })(item);
@@ -793,14 +798,14 @@ PWM_ADMIN.loadPwNotifyStatus = function () {
 
         PWM_MAIN.getObject('button-executePwNotifyJob').disabled = !data['data']['enableStartButton'];
     };
-    var url = PWM_MAIN.addParamToUrl(window.location.href,'processAction','readPwNotifyStatus');
+    const url = PWM_MAIN.addParamToUrl(window.location.href, 'processAction', 'readPwNotifyStatus');
     PWM_MAIN.ajaxRequest(url, processData);
 
 };
 
 PWM_ADMIN.loadPwNotifyLog = function () {
-    var processData = function (data) {
-        var debugData = data['data'];
+    const processData = function (data) {
+        const debugData = data['data'];
         if (debugData && debugData.length > 0) {
             PWM_MAIN.getObject('div-pwNotifyDebugLog').innerHTML = '';
             PWM_MAIN.getObject('div-pwNotifyDebugLog').appendChild(document.createTextNode(debugData));
@@ -808,21 +813,21 @@ PWM_ADMIN.loadPwNotifyLog = function () {
             PWM_MAIN.getObject('div-pwNotifyDebugLog').innerHTML = '<span class="footnote">Job has not been run on this server since startup.</span>';
         }
     };
-    var url = PWM_MAIN.addParamToUrl(window.location.href,'processAction','readPwNotifyLog');
+    const url = PWM_MAIN.addParamToUrl(window.location.href, 'processAction', 'readPwNotifyLog');
     PWM_MAIN.ajaxRequest(url, processData);
 
 };
 
 PWM_ADMIN.detailView = function(evt, headers, grid){
-    var row = grid.row(evt);
-    var text = '<table>';
-    var postExecuteFunctions = [];
-    for (var item in headers) {
+    const row = grid.row(evt);
+    let text = '<table>';
+    const postExecuteFunctions = [];
+    for (let item in headers) {
         (function(key){
-            var field = headers[key]['field'];
-            var label = headers[key]['label'];
-            var value = field in row.data ? row.data[field] : '';
-            var id = "record-detail-" + key;
+            const field = headers[key]['field'];
+            const label = headers[key]['label'];
+            const value = field in row.data ? row.data[field] : '';
+            const id = "record-detail-" + key;
             text += '<tr><td class="key">' + label + '</td>';
             text += '<td><span id="' + id + '" style="max-height: 200px; overflow: auto; max-width: 400px" class="timestamp">';
             if (key.toLowerCase().indexOf('time') >= 0) {
@@ -840,7 +845,7 @@ PWM_ADMIN.detailView = function(evt, headers, grid){
     }
     text += '</table>';
     PWM_MAIN.showDialog({title:"Record Detail",text:text,showClose:true,allowMove:true,loadFunction:function(){
-            for (var i = 0; i < postExecuteFunctions.length; i++) {
+            for (let i = 0; i < postExecuteFunctions.length; i++) {
                 postExecuteFunctions[i]();
             }
         }});

+ 2 - 10
webapp/src/main/webapp/public/resources/js/changepassword.js

@@ -206,7 +206,7 @@ PWM_CHANGEPW.handleChangePasswordSubmit=function(event) {
                 PWM_CHANGEPW.validatePasswords();
             };
             const title = PWM_MAIN.showString('Title_ChangePassword');
-            const message = '<div style="height:20px">' + data['data']['message'] + '.</div>';
+            const message = '<div>' + data['data']['message'] + '</div>';
             PWM_MAIN.showDialog({text: message, title: title, okAction: okFunction});
         }
     };
@@ -261,7 +261,7 @@ PWM_CHANGEPW.doRandomGeneration=function(randomConfig) {
 
     dialogBody += '<table class="noborder">';
     dialogBody += '<tr class="noborder"><td class="noborder"><button class="btn" id="moreRandomsButton" disabled="true"><span class="btn-icon pwm-icon pwm-icon-refresh"></span>' + PWM_MAIN.showString('Button_More') + '</button></td>';
-    dialogBody += '<td class="noborder" style="text-align:right;"><button class="btn" id="cancelRandomsButton"><span class="btn-icon pwm-icon pwm-icon-times"></span>' + PWM_MAIN.showString('Button_Cancel') + '</button></td></tr>';
+    dialogBody += '<td class="noborder"><button class="btn" id="cancelRandomsButton"><span class="btn-icon pwm-icon pwm-icon-times"></span>' + PWM_MAIN.showString('Button_Cancel') + '</button></td></tr>';
     dialogBody += "</table>";
 
     randomConfig['dialogBody'] = dialogBody;
@@ -360,10 +360,6 @@ PWM_CHANGEPW.startupChangePasswordPage=function() {
         PWM_MAIN.addEventHandler(autoGenPasswordElement,'click',function(){
             PWM_CHANGEPW.doRandomGeneration();
         });
-        PWM_MAIN.showTooltip({
-            id: "autogenerate-icon",
-            text: PWM_MAIN.showString('Display_AutoGeneratedPassword')
-        });
     }
 
     PWM_MAIN.addEventHandler('button-reset','click',function(event){
@@ -405,10 +401,6 @@ PWM_CHANGEPW.startupChangePasswordPage=function() {
             PWM_MAIN.addEventHandler('password-guide-icon','click',function(){
                 PWM_CHANGEPW.showPasswordGuide();
             });
-            PWM_MAIN.showTooltip({
-                id: ["password-guide-icon"],
-                text: PWM_MAIN.showString('Display_ShowPasswordGuide')
-            });
         }
     }
 

+ 1 - 1
webapp/src/main/webapp/public/resources/js/configeditor-settings-challenges.js

@@ -170,7 +170,7 @@ ChallengeSettingHandler.editLocale = function(keyName, localeKey) {
             dialogBody += '<td colspan="200" style="border-width: 0;">';
 
             const inputID = "value-" + keyName + "-" + localeName + "-" + rowKey;
-            PWM_MAIN.clearDijitWidget(inputID);
+            PWM_CFGEDIT.clearDijitWidget(inputID);
 
             dialogBody += '<input class="configStringInput" id="' + inputID + '" style="width: 700px" required="required" disabled value="Loading"/>';
 

+ 16 - 16
webapp/src/main/webapp/public/resources/js/configeditor-settings.js

@@ -175,7 +175,7 @@ LocalizedStringValueHandler.addLocaleSetting = function(settingKey, localeKey) {
 
 // -------------------------- multi locale table handler ------------------------------------
 
-var MultiLocaleTableHandler = {};
+const MultiLocaleTableHandler = {};
 
 MultiLocaleTableHandler.initMultiLocaleTable = function(keyName) {
     console.log('MultiLocaleTableHandler init for ' + keyName);
@@ -337,7 +337,7 @@ MultiLocaleTableHandler.writeMultiLocaleSetting = function(settingKey, locale, i
 
 // -------------------------- change password handler ------------------------------------
 
-var ChangePasswordHandler = {};
+const ChangePasswordHandler = {};
 
 ChangePasswordHandler.init = function(settingKey) {
     const parentDiv = 'table_setting_' + settingKey;
@@ -585,7 +585,7 @@ ChangePasswordHandler.changePasswordPopup = function(settingKey) {
 
 // -------------------------- boolean handler ------------------------------------
 
-var BooleanHandler = {};
+const BooleanHandler = {};
 
 BooleanHandler.init = function(keyName) {
     console.log('BooleanHandler init for ' + keyName);
@@ -615,7 +615,7 @@ BooleanHandler.toggle = function(keyName,widget) {
 
 // -------------------------- option list handler ------------------------------------
 
-var OptionListHandler = {};
+const OptionListHandler = {};
 OptionListHandler.defaultItem = [];
 
 OptionListHandler.init = function(keyName) {
@@ -672,7 +672,7 @@ OptionListHandler.toggle = function(keyName,optionKey) {
 
 // -------------------------- numeric value handler ------------------------------------
 
-var NumericValueHandler = {};
+const NumericValueHandler = {};
 NumericValueHandler.init = function(settingKey) {
     NumericValueHandler.impl(settingKey, 'number', 0, 100);
 };
@@ -721,14 +721,14 @@ NumericValueHandler.updateDurationDisplay = function(settingKey, numberValue) {
 
 // -------------------------- duration value ---------------------------
 
-var DurationValueHandler = {};
+const DurationValueHandler = {};
 DurationValueHandler.init = function(settingKey) {
     NumericValueHandler.impl(settingKey, 'duration', -1, 365 * 24 * 60 * 60, 1 );
 };
 
 // -------------------------- numeric array value handler ------------------------------------
 
-var NumericArrayValueHandler = {};
+const NumericArrayValueHandler = {};
 NumericArrayValueHandler.init = function(settingKey) {
     NumericArrayValueHandler.impl(settingKey, 'number', 0, 100);
 };
@@ -824,7 +824,7 @@ NumericArrayValueHandler.draw = function(settingKey, type) {
 
 // -------------------------- duration array value ---------------------------
 
-var DurationArrayValueHandler = {};
+const DurationArrayValueHandler = {};
 DurationArrayValueHandler.init = function(settingKey) {
     NumericArrayValueHandler.impl(settingKey, 'duration');
 };
@@ -832,7 +832,7 @@ DurationArrayValueHandler.init = function(settingKey) {
 
 // -------------------------- string value handler ------------------------------------
 
-var StringValueHandler = {};
+const StringValueHandler = {};
 
 StringValueHandler.init = function(settingKey) {
     const parentDiv = 'table_setting_' + settingKey;
@@ -905,7 +905,7 @@ StringValueHandler.init = function(settingKey) {
 
 // -------------------------- text area handler ------------------------------------
 
-var TextAreaValueHandler = {};
+const TextAreaValueHandler = {};
 TextAreaValueHandler.init = function(settingKey) {
     StringValueHandler.init(settingKey);
 };
@@ -913,7 +913,7 @@ TextAreaValueHandler.init = function(settingKey) {
 
 // -------------------------- select value handler ------------------------------------
 
-var SelectValueHandler = {};
+const SelectValueHandler = {};
 SelectValueHandler.init = function(settingKey) {
     const parentDiv = 'table_setting_' + settingKey;
     const parentDivElement = PWM_MAIN.getObject(parentDiv);
@@ -990,7 +990,7 @@ SelectValueHandler.init = function(settingKey) {
 
 // -------------------------- x509 setting handler ------------------------------------
 
-var X509CertificateHandler = {};
+const X509CertificateHandler = {};
 
 X509CertificateHandler.init = function(keyName) {
     PWM_CFGEDIT.readSetting(keyName, function(resultValue) {
@@ -1071,7 +1071,7 @@ X509CertificateHandler.draw = function(keyName) {
 
 // -------------------------- verification method handler ------------------------------------
 
-var VerificationMethodHandler = {};
+const VerificationMethodHandler = {};
 VerificationMethodHandler.init = function(settingKey) {
     PWM_CFGEDIT.readSetting(settingKey, function(resultValue) {
         PWM_VAR['clientSettingCache'][settingKey] = resultValue;
@@ -1205,7 +1205,7 @@ VerificationMethodHandler.updateLabels = function(settingKey) {
 
 // -------------------------- file setting handler ------------------------------------
 
-var FileValueHandler = {};
+const FileValueHandler = {};
 
 FileValueHandler.init = function(keyName) {
     PWM_CFGEDIT.readSetting(keyName, function(resultValue) {
@@ -1280,7 +1280,7 @@ FileValueHandler.uploadFile = function(keyName) {
 
 // -------------------------- x509 setting handler ------------------------------------
 
-var PrivateKeyHandler = {};
+const PrivateKeyHandler = {};
 
 PrivateKeyHandler.init = function(keyName) {
     PWM_CFGEDIT.readSetting(keyName, function(resultValue) {
@@ -1368,7 +1368,7 @@ PrivateKeyHandler.draw = function(keyName) {
 
 
 //--------- named secret handler ---
-var NamedSecretHandler = {};
+const NamedSecretHandler = {};
 
 NamedSecretHandler.init = function(settingKey) {
     const parentDiv = 'table_setting_' + settingKey;

+ 22 - 6
webapp/src/main/webapp/public/resources/js/configeditor.js

@@ -396,7 +396,7 @@ PWM_CFGEDIT.setConfigurationPassword = function(password) {
             PWM_MAIN.closeWaitDialog();
             PWM_MAIN.showDialog ({title:PWM_MAIN.showString('Title_Error'),text:"error saving configuration password: " + errorObj});
         };
-        PWM_MAIN.clearDijitWidget('dialogPopup');
+        PWM_CFGEDIT.clearDijitWidget('dialogPopup');
         PWM_MAIN.showWaitDialog({loadFunction:function(){
                 PWM_MAIN.ajaxRequest(url,loadFunction,{errorFunction:errorFunction,content:{password:password}});
             }});
@@ -593,7 +593,7 @@ PWM_CFGEDIT.processSettingSearch = function(destinationDiv) {
                         toolBody += '<br/>' + PWM_SETTINGS['settings'][settingKey]['description'] + '<br/><br/>';
                         toolBody += '<span style="font-weight: bold">Value</span>';
                         toolBody += '<br/>' + value.replace('\n', '<br/>') + '<br/>';
-                        PWM_MAIN.showDijitTooltip({
+                        PWM_MAIN.showTooltip({
                             id: settingID + '_popup',
                             text: toolBody,
                             width: 500
@@ -785,7 +785,6 @@ PWM_CFGEDIT.showMacroHelp = function() {
     options['title'] = 'Macro Help'
     options['id'] = 'id-dialog-macroHelp'
     options['dialogClass'] = 'wide';
-    options['dojoStyle'] = 'width: 750px';
     options['showClose'] = true;
     options['href'] = PWM_GLOBAL['url-resources'] + "/text/macroHelp.html"
     options['loadFunction'] = loadFunction;
@@ -797,7 +796,6 @@ PWM_CFGEDIT.showTimezoneList = function() {
     options['title'] = 'Timezones'
     options['id'] = 'id-dialog-timeZoneHelp'
     options['dialogClass'] = 'wide';
-    options['dojoStyle'] = 'width: 750px';
     options['showClose'] = true;
     options['href'] = PWM_GLOBAL['url-context'] + "/public/reference/timezones.jsp"
     PWM_MAIN.showDialog( options );
@@ -808,7 +806,6 @@ PWM_CFGEDIT.showDateTimeFormatHelp = function() {
     options['title'] = 'Date & Time Formatting'
     options['id'] = 'id-dialog-dateTimePopup'
     options['dialogClass'] = 'wide';
-    options['dojoStyle'] = 'width: 750px';
     options['showClose'] = true;
     options['href'] = PWM_GLOBAL['url-resources'] + "/text/datetimeFormatHelp.html"
     PWM_MAIN.showDialog( options );
@@ -1100,7 +1097,7 @@ PWM_CFGEDIT.drawNavigationMenu = function(nextFunction) {
         require(["dojo","dojo/_base/window", "dojo/store/Memory", "dijit/tree/ObjectStoreModel", "dijit/Tree","dijit","dojo/domReady!"],
             function(dojo, win, Memory, ObjectStoreModel, Tree)
             {
-                PWM_MAIN.clearDijitWidget('navigationTree');
+                PWM_CFGEDIT.clearDijitWidget('navigationTree');
                 // Create test store, adding the getChildren() method required by ObjectStoreModel
                 const myStore = new Memory({
                     data: menuTreeData,
@@ -1373,3 +1370,22 @@ PWM_CFGEDIT.drawInfoPage = function(settingInfo) {
 };
 
 
+PWM_CFGEDIT.clearDijitWidget = function (widgetName) {
+    require(["dojo","dijit/registry"],function(dojo, registry){
+
+        const oldDijitNode = registry.byId(widgetName);
+        if (oldDijitNode) {
+            try {
+                oldDijitNode.destroyRecursive();
+            } catch (error) {
+                PWM_MAIN.log('error destroying old widget: ' + error);
+            }
+
+            try {
+                oldDijitNode.destroy();
+            } catch (error) {
+                PWM_MAIN.log('error destroying old widget: ' + error);
+            }
+        }
+    });
+};

+ 4 - 4
webapp/src/main/webapp/public/resources/js/configmanager.js

@@ -184,11 +184,11 @@ PWM_CONFIG.showHeaderHealth = function() {
             if (data['data'] && data['data']['overall']) {
                 const hasWarnTopics = data['data']['overall'] === 'WARN';
                 if (hasWarnTopics) {
-                    PWM_MAIN.removeCssClass('header-menu-alert', 'display-none');
-                    PWM_MAIN.removeCssClass('panel-header-healthData', 'display-none');
+                    PWM_MAIN.removeCssClass('header-menu-alert', 'nodisplay');
+                    PWM_MAIN.removeCssClass('panel-header-healthData', 'nodisplay');
                 } else {
-                    PWM_MAIN.addCssClass('header-menu-alert', 'display-none');
-                    PWM_MAIN.addCssClass('panel-header-healthData', 'display-none');
+                    PWM_MAIN.addCssClass('header-menu-alert', 'nodisplay');
+                    PWM_MAIN.addCssClass('panel-header-healthData', 'nodisplay');
                 }
                 setTimeout(function () {
                     PWM_CONFIG.showHeaderHealth();

+ 0 - 20
webapp/src/main/webapp/public/resources/js/guest.js

@@ -24,23 +24,3 @@
 var PWM_GUEST = PWM_GUEST || {};
 var PWM_VAR = PWM_VAR || {};
 
-
-PWM_GUEST.initDatePicker = function(maxValidDate,selectedDate) {
-    require(["dijit/form/DateTextBox"],function(DateTextBox){
-        new DateTextBox({
-            constraints: {
-                min: new Date(),
-                max: maxValidDate
-            },
-            value: selectedDate,
-            onChange: function(){
-                var selectedDate = new Date(Date.parse(this.value));
-                var isoDate = selectedDate.toISOString();
-                PWM_MAIN.getObject('_expirationDateFormInput').value = isoDate;
-            }
-        }, "expiredate-stub");
-    });
-
-};
-
-

文件差異過大導致無法顯示
+ 189 - 329
webapp/src/main/webapp/public/resources/js/main.js


+ 15 - 24
webapp/src/main/webapp/public/resources/js/newuser.js

@@ -80,29 +80,20 @@ PWM_NEWUSER.updateDisplay=function(data) {
 
 
 PWM_NEWUSER.refreshCreateStatus=function(refreshInterval) {
-    require(["dojo","dijit/registry"],function(dojo,registry){
-        const checkStatusUrl = PWM_MAIN.addParamToUrl(window.location.pathname, "processAction", "checkProgress");
-        const completedUrl = PWM_MAIN.addParamToUrl(window.location.pathname, "processAction", "complete");
-        const loadFunction = function (data) {
-            const supportsProgress = (document.createElement('progress').max !== undefined);
-            if (supportsProgress) {
-                console.log('beginning html5 progress refresh');
-                const html5passwordProgressBar = PWM_MAIN.getObject('html5ProgressBar');
-                dojo.setAttr(html5passwordProgressBar, "value", data['data']['percentComplete']);
-            } else {
-                console.log('beginning dojo progress refresh');
-                const progressBar = registry.byId('passwordProgressBar');
-                progressBar.set("value", data['data']['percentComplete']);
-            }
+    const checkStatusUrl = PWM_MAIN.addParamToUrl(window.location.pathname, "processAction", "checkProgress");
+    const completedUrl = PWM_MAIN.addParamToUrl(window.location.pathname, "processAction", "complete");
+    const loadFunction = function (data) {
+        console.log('beginning html5 progress refresh');
+        const html5passwordProgressBar = PWM_MAIN.getObject('html5ProgressBar');
+        html5passwordProgressBar.value = data['data']['percentComplete'];
 
-            if (data['data']['complete'] === true) {
-                PWM_MAIN.gotoUrl(completedUrl, {delay: 1000})
-            } else {
-                setTimeout(function () {
-                    PWM_NEWUSER.refreshCreateStatus(refreshInterval);
-                }, refreshInterval);
-            }
-        };
-        PWM_MAIN.ajaxRequest(checkStatusUrl, loadFunction, {method:'GET'});
-    });
+        if (data['data']['complete'] === true) {
+            PWM_MAIN.gotoUrl(completedUrl, {delay: 1000})
+        } else {
+            setTimeout(function () {
+                PWM_NEWUSER.refreshCreateStatus(refreshInterval);
+            }, refreshInterval);
+        }
+    };
+    PWM_MAIN.ajaxRequest(checkStatusUrl, loadFunction, {method:'GET'});
 };

+ 2 - 2
webapp/src/main/webapp/public/resources/js/otpsecret.js

@@ -28,7 +28,7 @@ PWM_OTP.checkExistingCode = function() {
     PWM_MAIN.pwmFormValidator({
         serviceURL: PWM_MAIN.addParamToUrl(window.location.href,"processAction","restValidateCode"),
         readDataFunction:function(){
-            var paramData = { };
+            const paramData = {};
             paramData['code'] = PWM_MAIN.getObject('verifyCodeInput').value;
             return paramData;
         },
@@ -52,7 +52,7 @@ PWM_OTP.checkExistingCode = function() {
 };
 
 PWM_OTP.openCheckCodeDialog = function() {
-    var templateHtml = '<div>'
+    const templateHtml = '<div>'
         + '<p>' + PWM_MAIN.showString("Display_RecoverOTP") + '</p>'
         + '<table class="noborder" style="width: 300px; table-layout: fixed">'
         + '<tr><td style="width:115px">'

+ 25 - 33
webapp/src/main/webapp/public/resources/js/responses.js

@@ -30,11 +30,11 @@ PWM_VAR['simpleRandomOptions'] = [];
 // takes response values in the fields, sends an http request to the servlet
 // and then parses (and displays) the response from the servlet.
 PWM_RESPONSES.validateResponses=function() {
-    var serviceUrl = PWM_MAIN.addParamToUrl(window.location.href,"processAction","validateResponses");
+    let serviceUrl = PWM_MAIN.addParamToUrl(window.location.href, "processAction", "validateResponses");
     if (PWM_GLOBAL['responseMode']) {
         serviceUrl += "&responseMode=" + PWM_GLOBAL['responseMode'];
     }
-    var validationProps = {};
+    const validationProps = {};
     validationProps['messageWorking'] = PWM_MAIN.showString('Display_CheckingResponses');
     validationProps['serviceURL'] = serviceUrl;
     validationProps['readDataFunction'] = function(){
@@ -58,7 +58,7 @@ PWM_RESPONSES.updateDisplay=function(resultInfo) {
         return;
     }
 
-    var result = resultInfo["message"];
+    const result = resultInfo["message"];
 
     if (resultInfo["success"] === true) {
         PWM_MAIN.getObject("button-setResponses").disabled = false;
@@ -70,25 +70,25 @@ PWM_RESPONSES.updateDisplay=function(resultInfo) {
 };
 
 PWM_RESPONSES.makeSelectOptionsDistinct=function() {
-    var startTime = (new Date()).getTime();
+    const startTime = (new Date()).getTime();
     console.log('entering makeSelectOptionsDistinct()');
 
     // all possible random questions (populated by the jsp)
-    var allPossibleTexts = PWM_VAR['simpleRandomOptions'];
+    const allPossibleTexts = PWM_VAR['simpleRandomOptions'];
 
     // string that is used at the top of unconfigured select list
-    var initialChoiceText = PWM_MAIN.showString('Display_SelectionIndicator');
+    const initialChoiceText = PWM_MAIN.showString('Display_SelectionIndicator');
 
     // the HTML select elements (populated by the jsp)
-    var simpleRandomSelectElements = PWM_VAR['simpleRandomSelectElements'];
+    const simpleRandomSelectElements = PWM_VAR['simpleRandomSelectElements'];
 
     // texts that are in use
-    var currentlySelectedTexts = [];
+    const currentlySelectedTexts = [];
 
     PWM_MAIN.JSLibrary.forEachInArray(simpleRandomSelectElements,function(questionID){
-        var selectedElement = PWM_MAIN.getObject(questionID);
-        var selectedIndex = selectedElement.selectedIndex;
-        var selectedValue = selectedElement.options[selectedIndex].value;
+        const selectedElement = PWM_MAIN.getObject(questionID);
+        const selectedIndex = selectedElement.selectedIndex;
+        const selectedValue = selectedElement.options[selectedIndex].value;
         if ('UNSELECTED' !== selectedValue) {
             currentlySelectedTexts.push(selectedValue);
         }
@@ -96,13 +96,13 @@ PWM_RESPONSES.makeSelectOptionsDistinct=function() {
 
     // repopulate the select elements
     PWM_MAIN.JSLibrary.forEachInArray(simpleRandomSelectElements,function(questionID){
-        var selectedElement = PWM_MAIN.getObject(questionID);
-        var selectedIndex = selectedElement.selectedIndex;
-        var selectedValue = selectedElement.options[selectedIndex].value;
-        var responseID = selectedElement.getAttribute('data-response-id');
+        const selectedElement = PWM_MAIN.getObject(questionID);
+        const selectedIndex = selectedElement.selectedIndex;
+        const selectedValue = selectedElement.options[selectedIndex].value;
+        const responseID = selectedElement.getAttribute('data-response-id');
         selectedElement.innerHTML = '<optgroup></optgroup>';
         if (selectedValue === 'UNSELECTED') {
-            var unselectedOption = document.createElement('option');
+            const unselectedOption = document.createElement('option');
             unselectedOption.value = 'UNSELECTED';
             unselectedOption.innerHTML = '&nbsp;&mdash;&nbsp;' + initialChoiceText + '&nbsp;&mdash;&nbsp;';
             unselectedOption.selected = true;
@@ -110,7 +110,7 @@ PWM_RESPONSES.makeSelectOptionsDistinct=function() {
         }
 
         PWM_MAIN.JSLibrary.forEachInArray(allPossibleTexts,function(loopText){
-            var optionElement = document.createElement('option');
+            const optionElement = document.createElement('option');
             optionElement.value = loopText;
             optionElement.innerHTML = loopText;
 
@@ -128,9 +128,9 @@ PWM_RESPONSES.makeSelectOptionsDistinct=function() {
 
 PWM_RESPONSES.startupResponsesPage=function() {
     PWM_MAIN.doIfQueryHasResults('#pwm-setupResponsesDiv',function(){
-        var initialPrompt = PWM_MAIN.showString('Display_ResponsesPrompt');
+        const initialPrompt = PWM_MAIN.showString('Display_ResponsesPrompt');
         if (initialPrompt !== null && initialPrompt.length > 1) {
-            var messageElement = PWM_MAIN.getObject("message");
+            const messageElement = PWM_MAIN.getObject("message");
             if (messageElement.firstChild.nodeValue.length < 2) {
                 PWM_MAIN.showInfo(initialPrompt);
             }
@@ -152,8 +152,8 @@ PWM_RESPONSES.initSimpleRandomElements = function() {
     PWM_VAR['simpleRandomSelectElements'] = [];
     PWM_VAR['focusInValues'] = {};
 
-    var updateResponseInputField = function(element) {
-        var responseID = element.getAttribute('data-response-id');
+    const updateResponseInputField = function (element) {
+        const responseID = element.getAttribute('data-response-id');
         if (element.value === 'UNSELECTED') {
             PWM_MAIN.getObject(responseID).disabled = true;
             PWM_MAIN.getObject(responseID).readonly = true;
@@ -175,23 +175,15 @@ PWM_RESPONSES.initSimpleRandomElements = function() {
         });
         PWM_MAIN.addEventHandler(element.id,"click,blur",function(){
             if (PWM_VAR['focusInValues'][element.id] !== element.selectedIndex) {
-                var selectedIndex = element.selectedIndex;
-                var selectedValue = element.options[selectedIndex].value;
+                const selectedIndex = element.selectedIndex;
+                const selectedValue = element.options[selectedIndex].value;
                 if (selectedValue !== 'UNSELECTED') {
-                    var responseID = element.getAttribute('data-response-id');
-                    var responseElement = PWM_MAIN.getObject(responseID);
+                    const responseID = element.getAttribute('data-response-id');
+                    const responseElement = PWM_MAIN.getObject(responseID);
                     responseElement.value = '';
                     responseElement.disabled = false;
                     responseElement.readonly = false;
                     PWM_RESPONSES.makeSelectOptionsDistinct();
-
-                    require(["dojo/has"], function(has){
-                        // ios safari seems to behave poorly when moving the focus away from an open drop down list
-                        if(!has("ios") && !has("safari")){
-                            responseElement.focus();
-                        }
-                    });
-
                 }
             }
         });

+ 183 - 167
webapp/src/main/webapp/public/resources/js/uilibrary.js

@@ -23,16 +23,18 @@
 var UILibrary = {};
 UILibrary.stringEditorDialog = function(options){
     options = options === undefined ? {} : options;
-    var title = 'title' in options ? options['title'] : 'Edit Value';
-    var instructions = 'instructions' in options ? options['instructions'] : null;
-    var completeFunction = 'completeFunction' in options ? options['completeFunction'] : function() {alert('no string editor dialog complete function')};
-    var regexString = 'regex' in options && options['regex'] ? options['regex'] : '.+';
-    var initialValue = 'value' in options ? options['value'] : '';
-    var placeholder = 'placeholder' in options ? options['placeholder'] : '';
-    var textarea = 'textarea' in options ? options['textarea'] : false;
-
-    var regexObject = new RegExp(regexString);
-    var text = '';
+    const title = 'title' in options ? options['title'] : 'Edit Value';
+    const instructions = 'instructions' in options ? options['instructions'] : null;
+    const completeFunction = 'completeFunction' in options ? options['completeFunction'] : function () {
+        alert('no string editor dialog complete function')
+    };
+    const regexString = 'regex' in options && options['regex'] ? options['regex'] : '.+';
+    const initialValue = 'value' in options ? options['value'] : '';
+    const placeholder = 'placeholder' in options ? options['placeholder'] : '';
+    const textarea = 'textarea' in options ? options['textarea'] : false;
+
+    const regexObject = new RegExp(regexString);
+    let text = '';
     text += '<div style="visibility: hidden;" id="panel-valueWarning"><span class="pwm-icon pwm-icon-warning message-error"></span>&nbsp;' + PWM_CONFIG.showString('Warning_ValueIncorrectFormat') + '</div>';
     text += '<br/>';
 
@@ -47,13 +49,13 @@ UILibrary.stringEditorDialog = function(options){
         text += '<input style="width: 480px" class="configStringInput" autofocus required id="addValueDialog_input"/>';
     }
 
-    var inputFunction = function() {
+    const inputFunction = function () {
         PWM_MAIN.getObject('dialog_ok_button').disabled = true;
         PWM_MAIN.getObject('panel-valueWarning').style.visibility = 'hidden';
 
-        var value = PWM_MAIN.getObject('addValueDialog_input').value;
+        const value = PWM_MAIN.getObject('addValueDialog_input').value;
         if (value.length > 0) {
-            var passedValidation = regexObject  !== null && regexObject.test(value);
+            const passedValidation = regexObject !== null && regexObject.test(value);
 
             if (passedValidation) {
                 PWM_MAIN.getObject('dialog_ok_button').disabled = false;
@@ -64,8 +66,8 @@ UILibrary.stringEditorDialog = function(options){
         }
     };
 
-    var okFunction = function() {
-        var value = PWM_VAR['temp-dialogInputValue'];
+    const okFunction = function () {
+        const value = PWM_VAR['temp-dialogInputValue'];
         completeFunction(value);
     };
 
@@ -95,16 +97,18 @@ UILibrary.stringEditorDialog = function(options){
 
 UILibrary.stringArrayEditorDialog = function(options){
     options = options === undefined ? {} : options;
-    var title = 'title' in options ? options['title'] : 'Edit Value';
-    var instructions = 'instructions' in options ? options['instructions'] : null;
-    var completeFunction = 'completeFunction' in options ? options['completeFunction'] : function() {alert('no string array editor dialog complete function')};
-    var regexString = 'regex' in options && options['regex'] ? options['regex'] : '.+';
-    var initialValues = 'value' in options ? options['value'] : [];
-    var placeholder = 'placeholder' in options ? options['placeholder'] : '';
-    var maxvalues = 'maxValues' in options ? options['maxValues'] : 10;
-
-    var regexObject = new RegExp(regexString);
-    var text = '';
+    const title = 'title' in options ? options['title'] : 'Edit Value';
+    const instructions = 'instructions' in options ? options['instructions'] : null;
+    const completeFunction = 'completeFunction' in options ? options['completeFunction'] : function () {
+        alert('no string array editor dialog complete function')
+    };
+    const regexString = 'regex' in options && options['regex'] ? options['regex'] : '.+';
+    const initialValues = 'value' in options ? options['value'] : [];
+    const placeholder = 'placeholder' in options ? options['placeholder'] : '';
+    const maxvalues = 'maxValues' in options ? options['maxValues'] : 10;
+
+    const regexObject = new RegExp(regexString);
+    let text = '';
     text += '<div style="visibility: hidden;" id="panel-valueWarning"><span class="pwm-icon pwm-icon-warning message-error"></span>&nbsp;' + PWM_CONFIG.showString('Warning_ValueIncorrectFormat') + '</div>';
     text += '<br/>';
 
@@ -129,16 +133,16 @@ UILibrary.stringArrayEditorDialog = function(options){
         text += '<button class="btn" id="button-addRow"><span class="btn-icon pwm-icon pwm-icon-plus-square"></span>Add Row</button></td>';
     }
 
-    var readCurrentValues = function() {
-        var output = [];
-        for (var i in initialValues) {
-            var value = PWM_MAIN.getObject('value_' + i).value;
+    const readCurrentValues = function () {
+        const output = [];
+        for (let i in initialValues) {
+            const value = PWM_MAIN.getObject('value_' + i).value;
             output.push(value);
         }
         return output;
     };
 
-    var inputFunction = function() {
+    const inputFunction = function () {
         PWM_MAIN.getObject('dialog_ok_button').disabled = true;
         if (PWM_MAIN.JSLibrary.itemCount(initialValues) < maxvalues) {
             PWM_MAIN.getObject('button-addRow').disabled = true;
@@ -146,14 +150,14 @@ UILibrary.stringArrayEditorDialog = function(options){
 
         PWM_MAIN.getObject('panel-valueWarning').style.visibility = 'hidden';
 
-        var passed = true;
-        var allHaveValues = true;
+        let passed = true;
+        let allHaveValues = true;
 
-        for (var i in initialValues) {
-            (function(iter) {
-                var value = PWM_MAIN.getObject('value_'+ iter).value;
+        for (let i in initialValues) {
+            (function (iter) {
+                const value = PWM_MAIN.getObject('value_' + iter).value;
                 if (value.length > 0) {
-                    var passedRegex = regexObject  !== null && regexObject.test(value);
+                    const passedRegex = regexObject !== null && regexObject.test(value);
                     if (!passedRegex) {
                         passed = false;
                     }
@@ -175,14 +179,14 @@ UILibrary.stringArrayEditorDialog = function(options){
         PWM_VAR['temp-dialogInputValue'] = readCurrentValues();
     };
 
-    var okFunction = function() {
-        var value =  PWM_VAR['temp-dialogInputValue'];
+    const okFunction = function () {
+        const value = PWM_VAR['temp-dialogInputValue'];
         completeFunction(value);
     };
 
-    var deleteRow = function(i) {
-        var values = readCurrentValues();
-        values.splice(i,1);
+    const deleteRow = function (i) {
+        const values = readCurrentValues();
+        values.splice(i, 1);
         options['value'] = values;
         UILibrary.stringArrayEditorDialog(options);
     };
@@ -196,9 +200,9 @@ UILibrary.stringArrayEditorDialog = function(options){
         allowMove: true,
         dialogClass: 'auto',
         loadFunction:function(){
-            for (var i in initialValues) {
+            for (let i in initialValues) {
                 (function(iter) {
-                    var loopValue = initialValues[iter];
+                    const loopValue = initialValues[iter];
                     PWM_MAIN.getObject('value_' + i).value = loopValue;
 
                     if (regexString && regexString.length > 1) {
@@ -219,7 +223,7 @@ UILibrary.stringArrayEditorDialog = function(options){
 
             if (PWM_MAIN.JSLibrary.itemCount(initialValues) < maxvalues) {
                 PWM_MAIN.addEventHandler('button-addRow','click',function(){
-                    var values = readCurrentValues();
+                    const values = readCurrentValues();
                     values.push('');
                     options['value'] = values;
                     UILibrary.stringArrayEditorDialog(options);
@@ -232,7 +236,7 @@ UILibrary.stringArrayEditorDialog = function(options){
 };
 
 UILibrary.addTextValueToElement = function(elementID, input) {
-    var element = PWM_MAIN.getObject(elementID);
+    const element = PWM_MAIN.getObject(elementID);
     if (element) {
         element.innerHTML = '';
         element.appendChild(document.createTextNode(input));
@@ -243,17 +247,17 @@ UILibrary.addAddLocaleButtonRow = function(parentDiv, keyName, addFunction, exis
     existingLocales === undefined ? [] : existingLocales;
     existingLocales.push('en');
 
-    var totalLocales = PWM_MAIN.JSLibrary.itemCount(PWM_GLOBAL['localeInfo']);
-    var excludeLocales = PWM_MAIN.JSLibrary.itemCount(existingLocales);
+    const totalLocales = PWM_MAIN.JSLibrary.itemCount(PWM_GLOBAL['localeInfo']);
+    const excludeLocales = PWM_MAIN.JSLibrary.itemCount(existingLocales);
 
     if (totalLocales < excludeLocales) {
         return;
     }
 
-    var tableRowElement = document.createElement('tr');
+    const tableRowElement = document.createElement('tr');
     tableRowElement.setAttribute("style","border-width: 0");
 
-    var bodyHtml = '';
+    let bodyHtml = '';
     bodyHtml += '<td style="border-width: 0" colspan="5">';
     bodyHtml += '<button type="button" class="btn" id="' + keyName + '-addLocaleButton"><span class="btn-icon pwm-icon pwm-icon-plus-square"></span>Add Locale</button>'
 
@@ -269,11 +273,11 @@ UILibrary.addAddLocaleButtonRow = function(parentDiv, keyName, addFunction, exis
 };
 
 UILibrary.manageNumericInput = function(elementID, readFunction) {
-    var element = PWM_MAIN.getObject(elementID);
+    const element = PWM_MAIN.getObject(elementID);
     if (!element) {
         return;
     }
-    var validChecker = function(value) {
+    const validChecker = function (value) {
         if (!value) {
             return false;
         }
@@ -293,7 +297,7 @@ UILibrary.manageNumericInput = function(elementID, readFunction) {
         return true;
     };
     PWM_MAIN.addEventHandler(elementID,'input',function(){
-        var value = element.value;
+        const value = element.value;
         if (validChecker(value)) {
             console.log('valid numerical input value: ' + value);
             readFunction(value);
@@ -305,18 +309,20 @@ UILibrary.manageNumericInput = function(elementID, readFunction) {
 
 UILibrary.editLdapDN = function(nextFunction, options) {
     options = options === undefined ? {} : options;
-    var profile = 'profile' in options ? options['profile'] : '';
-    var currentDN = 'currentDN' in options ? options['currentDN'] : '';
-    var processResults = function(data) {
-        var body = '';
+    const profile = 'profile' in options ? options['profile'] : '';
+    const currentDN = 'currentDN' in options ? options['currentDN'] : '';
+    const processResults = function (data) {
+        let body = '';
         if (data['error']) {
             body += '<div>Unable to browse LDAP directory: ' + data['errorMessage'] + '</div>';
             if (data['errorDetail']) {
                 body += '<br/><div>' + data['errorDetail'] + '</div>';
             }
-            PWM_MAIN.showDialog({title:'Error',text:body,okAction:function(){
-                    UILibrary.stringEditorDialog({value:currentDN,completeFunction:nextFunction});
-                }});
+            PWM_MAIN.showDialog({
+                title: 'Error', text: body, okAction: function () {
+                    UILibrary.stringEditorDialog({value: currentDN, completeFunction: nextFunction});
+                }
+            });
             return;
         }
 
@@ -324,7 +330,7 @@ UILibrary.editLdapDN = function(nextFunction, options) {
             body += '<div style="text-align: center">LDAP Profile <select id="select-profileList"></select></div><br/>';
         }
         body += '<div style="text-align: center">';
-        if (currentDN && currentDN.length > 0 ) {
+        if (currentDN && currentDN.length > 0) {
             body += '<div class="selectableDN" data-dn="' + currentDN + '"><a><code>' + currentDN + '</code></a></div>';
         } else {
             body += '<code>[root]</code>';
@@ -334,17 +340,17 @@ UILibrary.editLdapDN = function(nextFunction, options) {
         body += '<div style="min-width:500px; max-height: 400px; overflow-y: auto; overflow-x:hidden; white-space: nowrap">';
         body += '<table class="noborder">';
         if ('parentDN' in data['data']) {
-            var parentDN = data['data']['parentDN'];
+            const parentDN = data['data']['parentDN'];
             body += '<tr><td style="width:10px" class="navigableDN" data-dn="' + parentDN + '"><span class="pwm-icon pwm-icon-level-up"></span></td>';
             body += '<td title="' + parentDN + '">[parent]</td>';
             body += '</td>';
             body += '</tr>';
         }
 
-        var makeEntryHtml = function(dnInformation,navigable) {
-            var loopDN = dnInformation['dn'];
-            var entryName = dnInformation['entryName'];
-            var out = '';
+        const makeEntryHtml = function (dnInformation, navigable) {
+            const loopDN = dnInformation['dn'];
+            const entryName = dnInformation['entryName'];
+            let out = '';
             if (navigable) {
                 out += '<tr><td class="navigableDN" data-dn="' + loopDN + '"><span class="pwm-icon pwm-icon-level-down"></span></td>';
             } else {
@@ -356,15 +362,15 @@ UILibrary.editLdapDN = function(nextFunction, options) {
         };
 
         if (data['data']['navigableDNlist'] && !PWM_MAIN.JSLibrary.isEmpty(data['data']['navigableDNlist'])) {
-            var navigableDNlist = data['data']['navigableDNlist'];
-            PWM_MAIN.JSLibrary.forEachInArray(navigableDNlist,function (item) {
-                body += makeEntryHtml(item,true);
+            const navigableDNlist = data['data']['navigableDNlist'];
+            PWM_MAIN.JSLibrary.forEachInArray(navigableDNlist, function (item) {
+                body += makeEntryHtml(item, true);
             });
         }
         if (data['data']['selectableDNlist'] && !PWM_MAIN.JSLibrary.isEmpty(data['data']['selectableDNlist'])) {
-            var selectableDNlist = data['data']['selectableDNlist'];
-            PWM_MAIN.JSLibrary.forEachInArray(selectableDNlist,function (item){
-                body += makeEntryHtml(item,false);
+            const selectableDNlist = data['data']['selectableDNlist'];
+            PWM_MAIN.JSLibrary.forEachInArray(selectableDNlist, function (item) {
+                body += makeEntryHtml(item, false);
             });
         }
         body += '</table></div>';
@@ -377,22 +383,23 @@ UILibrary.editLdapDN = function(nextFunction, options) {
         body += '<button class="btn" id="button-refresh"><span class="btn-icon pwm-icon pwm-icon-refresh"></span>Refresh</button>';
         body += '<button class="btn" id="button-clearDN"><span class="btn-icon pwm-icon pwm-icon-times"></span>Clear Value</button></div>';
 
-        PWM_MAIN.showDialog({title:'LDAP Browser',dialogClass:'auto',showOk:false,showClose:true,text:body,loadFunction:function(){
-                PWM_MAIN.addEventHandler('button-editDN','click',function(){
-                    UILibrary.stringEditorDialog({value:currentDN,completeFunction:nextFunction});
+        PWM_MAIN.showDialog({
+            title: 'LDAP Browser', dialogClass: 'auto', showOk: false, showClose: true, text: body, loadFunction: function () {
+                PWM_MAIN.addEventHandler('button-editDN', 'click', function () {
+                    UILibrary.stringEditorDialog({value: currentDN, completeFunction: nextFunction});
                 });
-                PWM_MAIN.addEventHandler('button-refresh','click',function(){
-                    UILibrary.editLdapDN(nextFunction,{profile:profile,currentDN:currentDN});
+                PWM_MAIN.addEventHandler('button-refresh', 'click', function () {
+                    UILibrary.editLdapDN(nextFunction, {profile: profile, currentDN: currentDN});
                 });
-                PWM_MAIN.addEventHandler('button-clearDN','click',function(){
+                PWM_MAIN.addEventHandler('button-clearDN', 'click', function () {
                     nextFunction('');
                     PWM_MAIN.closeWaitDialog();
                 });
 
-                PWM_MAIN.doQuery(".selectableDN",function(element){
-                    var dnValue = element.getAttribute("data-dn");
-                    PWM_MAIN.addEventHandler(element,'click',function(){
-                        var ldapProfileID = "default";
+                PWM_MAIN.doQuery(".selectableDN", function (element) {
+                    const dnValue = element.getAttribute("data-dn");
+                    PWM_MAIN.addEventHandler(element, 'click', function () {
+                        let ldapProfileID = "default";
                         if (document.getElementById("select-profileList")) {
                             ldapProfileID = document.getElementById("select-profileList").value;
                         }
@@ -402,19 +409,19 @@ UILibrary.editLdapDN = function(nextFunction, options) {
                     });
                 });
 
-                PWM_MAIN.doQuery(".navigableDN",function(element){
-                    var dnValue = element.getAttribute("data-dn");
-                    PWM_MAIN.addEventHandler(element,'click',function(){
-                        UILibrary.editLdapDN(nextFunction,{profile:profile,currentDN:dnValue});
+                PWM_MAIN.doQuery(".navigableDN", function (element) {
+                    const dnValue = element.getAttribute("data-dn");
+                    PWM_MAIN.addEventHandler(element, 'click', function () {
+                        UILibrary.editLdapDN(nextFunction, {profile: profile, currentDN: dnValue});
                     });
                 });
 
                 if (!PWM_MAIN.JSLibrary.isEmpty(data['data']['profileList'])) {
-                    var profileList = data['data']['profileList'];
-                    var profileSelect = PWM_MAIN.getObject('select-profileList');
-                    for (var i in profileList) {
-                        (function(loopProfile) {
-                            var optionElement = document.createElement('option');
+                    const profileList = data['data']['profileList'];
+                    const profileSelect = PWM_MAIN.getObject('select-profileList');
+                    for (let i in profileList) {
+                        (function (loopProfile) {
+                            const optionElement = document.createElement('option');
                             optionElement.innerHTML = loopProfile;
                             optionElement.value = loopProfile;
                             if (loopProfile === profile) {
@@ -423,26 +430,27 @@ UILibrary.editLdapDN = function(nextFunction, options) {
                             profileSelect.appendChild(optionElement);
                         })(profileList[i]);
                     }
-                    PWM_MAIN.addEventHandler('select-profileList','change',function(){
-                        var value = profileSelect.options[profileSelect.selectedIndex].value;
-                        UILibrary.editLdapDN(nextFunction,{profile:value,currentDN:''});
+                    PWM_MAIN.addEventHandler('select-profileList', 'change', function () {
+                        const value = profileSelect.options[profileSelect.selectedIndex].value;
+                        UILibrary.editLdapDN(nextFunction, {profile: value, currentDN: ''});
                     });
                 }
-            }});
+            }
+        });
     };
 
     PWM_MAIN.showWaitDialog({loadFunction:function(){
-            var content = {};
+            const content = {};
             content['profile'] = profile;
             content['dn'] = currentDN;
-            var url = window.location.pathname + "?processAction=browseLdap";
+            const url = window.location.pathname + "?processAction=browseLdap";
             PWM_MAIN.ajaxRequest(url,processResults,{content:content});
         }});
 };
 
 UILibrary.uploadFileDialog = function(options) {
     options = options === undefined ? {} : options;
-    var body = '';
+    let body = '';
 
     if ('text' in options) {
         body += options['text'];
@@ -455,45 +463,49 @@ UILibrary.uploadFileDialog = function(options) {
     body += '<button class="btn" type="button" id="uploadButton" name="Upload" disabled><span class="pwm-icon pwm-icon-upload"></span>';
     body +=  PWM_MAIN.showString('Button_Upload') + '</button></div></div>';
 
-    var currentUrl = window.location.pathname;
-    var uploadUrl = 'url' in options ? options['url'] : currentUrl;
-    var title = 'title' in options ? options['title'] : PWM_MAIN.showString('Title_Upload');
+    const currentUrl = window.location.pathname;
+    let uploadUrl = 'url' in options ? options['url'] : currentUrl;
+    const title = 'title' in options ? options['title'] : PWM_MAIN.showString('Title_Upload');
 
     uploadUrl = PWM_MAIN.addPwmFormIDtoURL(uploadUrl);
 
-    var nextFunction = 'nextFunction' in options ? options['nextFunction'] : function(data){
-        PWM_MAIN.showDialog({title: PWM_MAIN.showString("Title_Success"), text: data['successMessage'],okAction:function(){
+    const nextFunction = 'nextFunction' in options ? options['nextFunction'] : function (data) {
+        PWM_MAIN.showDialog({
+            title: PWM_MAIN.showString("Title_Success"), text: data['successMessage'], okAction: function () {
                 PWM_MAIN.gotoUrl(currentUrl)
-            }});
+            }
+        });
     };
 
 
-    var completeFunction = function(data){
+    let completeFunction = function (data) {
         console.log('upload dialog completeFunction() starting');
         if (data['error'] === true) {
-            var errorText = PWM_MAIN.showString('Notice_UploadFailure');
-            PWM_MAIN.showErrorDialog(data,{text:errorText,okAction:function(){
+            const errorText = PWM_MAIN.showString('Notice_UploadFailure');
+            PWM_MAIN.showErrorDialog(data, {
+                text: errorText, okAction: function () {
                     location.reload();
-                }});
+                }
+            });
         } else {
             nextFunction(data);
         }
     };
 
-    var errorFunction = function(status,statusText) {
+    const errorFunction = function (status, statusText) {
         PWM_MAIN.closeWaitDialog();
-        var errorText = PWM_MAIN.showString('Notice_UploadFailure');
+        let errorText = PWM_MAIN.showString('Notice_UploadFailure');
         errorText += '<br/><br/>Status: ' + status;
         errorText += '<br/><br/>' + statusText;
-        PWM_MAIN.showErrorDialog('',{text:errorText});
+        PWM_MAIN.showErrorDialog('', {text: errorText});
         //PWM_MAIN.showErrorDialog(errorText);
     };
 
-    var progressFunction = function(data) {
+    const progressFunction = function (data) {
         if (data.lengthComputable) {
-            var decimal = data.loaded / data.total;
+            const decimal = data.loaded / data.total;
             console.log('upload progress: ' + decimal);
-            var waitProgressObject = PWM_MAIN.getObject('wait-progress');
+            const waitProgressObject = PWM_MAIN.getObject('wait-progress');
             if (waitProgressObject) {
                 waitProgressObject.setAttribute('value', decimal.toString());
             }
@@ -503,8 +515,8 @@ UILibrary.uploadFileDialog = function(options) {
         }
     };
 
-    var uploadFunction = function() {
-        var files = PWM_MAIN.getObject('uploadFile').files;
+    const uploadFunction = function () {
+        const files = PWM_MAIN.getObject('uploadFile').files;
         if (!files[0]) {
             alert('File is not selected.');
             return;
@@ -514,20 +526,20 @@ UILibrary.uploadFileDialog = function(options) {
             uploadUrl = options['urlUpdateFunction'](uploadUrl);
         }
 
-        var xhr = new XMLHttpRequest();
-        var fd = new FormData();
-        xhr.onreadystatechange = function() {
+        const xhr = new XMLHttpRequest();
+        const fd = new FormData();
+        xhr.onreadystatechange = function () {
             console.log('upload handler onreadystate change: ' + xhr.readyState);
             if (xhr.readyState === 4) {
                 xhr.upload.onprogress = null;
-                if( xhr.status === 200) {
+                if (xhr.status === 200) {
                     // Every thing ok, file uploaded
                     console.log(xhr.responseText); // handle response.
                     try {
-                        var response = JSON.parse(xhr.response);
-                        setTimeout(function(){
+                        const response = JSON.parse(xhr.response);
+                        setTimeout(function () {
                             completeFunction(response);
-                        },1000);
+                        }, 1000);
                     } catch (e) {
                         console.log('error parsing upload response log: ' + e)
                     }
@@ -537,33 +549,33 @@ UILibrary.uploadFileDialog = function(options) {
             }
         };
 
-        xhr.upload.addEventListener('progress',progressFunction,false);
+        xhr.upload.addEventListener('progress', progressFunction, false);
         xhr.upload.onprogress = progressFunction;
         xhr.open("POST", uploadUrl, true);
-        xhr.setRequestHeader('Accept',"application/json");
+        xhr.setRequestHeader('Accept', "application/json");
         fd.append("fileUpload", files[0]);
         xhr.send(fd);
         PWM_GLOBAL['inhibitHealthUpdate'] = true;
         PWM_MAIN.IdleTimeoutHandler.cancelCountDownTimer();
-        PWM_MAIN.showWaitDialog({title:PWM_MAIN.showString('Display_Uploading'),progressBar:true});
+        PWM_MAIN.showWaitDialog({title: PWM_MAIN.showString('Display_Uploading'), progressBar: true});
     };
 
     completeFunction = 'completeFunction' in options ? options['completeFunction'] : completeFunction;
 
-    var supportAjaxUploadWithProgress = function() {
-        var supportFileAPI = function () {
-            var fi = document.createElement('INPUT');
+    const supportAjaxUploadWithProgress = function () {
+        const supportFileAPI = function () {
+            const fi = document.createElement('INPUT');
             fi.type = 'file';
             return 'files' in fi;
         };
 
-        var supportAjaxUploadProgressEvents = function() {
-            var xhr = new XMLHttpRequest();
-            return !! (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
+        const supportAjaxUploadProgressEvents = function () {
+            const xhr = new XMLHttpRequest();
+            return !!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
         };
 
-        var supportFormData = function() {
-            return !! window.FormData;
+        const supportFormData = function () {
+            return !!window.FormData;
         };
 
         return supportFileAPI() && supportAjaxUploadProgressEvents() && supportFormData();
@@ -582,7 +594,7 @@ UILibrary.uploadFileDialog = function(options) {
         loadFunction:function(){
             PWM_MAIN.addEventHandler('uploadButton','click',uploadFunction);
             PWM_MAIN.addEventHandler('uploadFile','change',function(){
-                var btn = PWM_MAIN.getObject('uploadButton');
+                const btn = PWM_MAIN.getObject('uploadButton');
                 console.log('value=' + btn.value);
                 btn.disabled = btn.value ? true : false;
             });
@@ -596,19 +608,21 @@ UILibrary.passwordDialogPopup = function(options, state) {
     options = options === undefined ? {} : options;
     state = state === undefined ? {} : state;
 
-    var option_title = 'title' in options ? options['title'] : 'Set Password';
-    var option_writeFunction = 'writeFunction' in options ? options['writeFunction'] : function() {alert('No Password Write Function')};
-    var option_minLength = 'minimumLength' in options ? options['minimumLength'] : 1;
-    var option_showRandomGenerator = 'showRandomGenerator' in options ? options['showRandomGenerator'] : false;
-    var option_showValues = 'showValues' in options ? options['showValues'] : false;
-    var option_randomLength = 'randomLength' in options ? options['randomLength'] : 25;
+    const option_title = 'title' in options ? options['title'] : 'Set Password';
+    const option_writeFunction = 'writeFunction' in options ? options['writeFunction'] : function () {
+        alert('No Password Write Function')
+    };
+    const option_minLength = 'minimumLength' in options ? options['minimumLength'] : 1;
+    const option_showRandomGenerator = 'showRandomGenerator' in options ? options['showRandomGenerator'] : false;
+    const option_showValues = 'showValues' in options ? options['showValues'] : false;
+    let option_randomLength = 'randomLength' in options ? options['randomLength'] : 25;
     option_randomLength = option_randomLength < option_minLength ? option_minLength : option_randomLength;
 
     state['p1'] = 'p1' in state ? state['p1'] : '';
     state['p2'] = 'p2' in state ? state['p2'] : '';
     state['randomLength'] = 'randomLength' in state ? state['randomLength'] : option_randomLength;
 
-    var markConfirmationCheckFunction = function(matchStatus) {
+    const markConfirmationCheckFunction = function (matchStatus) {
         if (matchStatus === "MATCH") {
             PWM_MAIN.getObject("confirmCheckMark").style.visibility = 'visible';
             PWM_MAIN.getObject("confirmCrossMark").style.visibility = 'hidden';
@@ -627,51 +641,53 @@ UILibrary.passwordDialogPopup = function(options, state) {
         }
     };
 
-    var generateRandomFunction = function() {
-        var length = state['randomLength'];
-        var special = state['showSpecial'];
+    const generateRandomFunction = function () {
+        const length = state['randomLength'];
+        const special = state['showSpecial'];
 
         if (!state['showFields']) {
             state['showFields'] = true;
         }
 
-        var charMap = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+        let charMap = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
         if (special) {
             charMap += '~`!@#$%^&*()_-+=;:,.[]{}';
         }
-        var postData = { };
+        const postData = {};
         postData.maxLength = length;
         postData.minLength = length;
         postData.chars = charMap;
         postData.noUser = true;
         PWM_MAIN.getObject('button-storePassword').disabled = true;
 
-        var url = PWM_GLOBAL['url-restservice'] + "/randompassword";
-        var loadFunction = function(data) {
+        const url = PWM_GLOBAL['url-restservice'] + "/randompassword";
+        const loadFunction = function (data) {
             state['p1'] = data['data']['password'];
             state['p2'] = '';
-            UILibrary.passwordDialogPopup(options,state);
+            UILibrary.passwordDialogPopup(options, state);
         };
 
-        PWM_MAIN.showWaitDialog({loadFunction:function(){
-                PWM_MAIN.ajaxRequest(url,loadFunction,{content:postData});
-            }});
+        PWM_MAIN.showWaitDialog({
+            loadFunction: function () {
+                PWM_MAIN.ajaxRequest(url, loadFunction, {content: postData});
+            }
+        });
     };
 
 
-    var validateFunction = function() {
-        var password1 = state['p1'];
-        var password2 = state['p2'];
+    const validateFunction = function () {
+        const password1 = state['p1'];
+        const password2 = state['p2'];
 
-        var matchStatus = "";
+        let matchStatus = "";
 
         PWM_MAIN.getObject('field-password-length').innerHTML = password1.length;
         PWM_MAIN.getObject('button-storePassword').disabled = true;
 
         if (option_minLength > 1 && password1.length < option_minLength) {
-            PWM_MAIN.addCssClass('field-password-length','invalid-value');
+            PWM_MAIN.addCssClass('field-password-length', 'invalid-value');
         } else {
-            PWM_MAIN.removeCssClass('field-password-length','invalid-value');
+            PWM_MAIN.removeCssClass('field-password-length', 'invalid-value');
             if (password2.length > 0) {
                 if (password1 === password2) {
                     matchStatus = "MATCH";
@@ -685,7 +701,7 @@ UILibrary.passwordDialogPopup = function(options, state) {
         markConfirmationCheckFunction(matchStatus);
     };
 
-    var bodyText = '';
+    let bodyText = '';
     if (option_minLength > 1) {
         bodyText += 'Minimum Length: ' + option_minLength + '</span><br/><br/>'
     }
@@ -746,7 +762,7 @@ UILibrary.passwordDialogPopup = function(options, state) {
             ShowHidePasswordHandler.init('password2');
 
             PWM_MAIN.addEventHandler('button-storePassword','click',function() {
-                var passwordValue = PWM_MAIN.getObject('password1').value;
+                const passwordValue = PWM_MAIN.getObject('password1').value;
                 PWM_MAIN.closeWaitDialog();
                 option_writeFunction(passwordValue);
             });
@@ -781,19 +797,19 @@ UILibrary.passwordDialogPopup = function(options, state) {
 };
 
 UILibrary.displayElementsToTableContents = function(fields) {
-    var htmlTable = '';
-    for (var field in fields) {(function(field){
-        var fieldData = fields[field];
-        var classValue = fieldData['type'] === 'timestamp' ? 'timestamp' : '';
+    let htmlTable = '';
+    for (let field in fields) {(function(field){
+        const fieldData = fields[field];
+        const classValue = fieldData['type'] === 'timestamp' ? 'timestamp' : '';
         htmlTable += '<tr><td class="key">' + fieldData['label'] + '</td><td><span class="' + classValue + '" id="' + fieldData['key']  + '"</tr>';
     }(field)); }
     return htmlTable;
 };
 
 UILibrary.initElementsToTableContents = function(fields) {
-    for (var field in fields) {(function(field) {
-        var fieldData = fields[field];
-        var value = fieldData['value'];
+    for (let field in fields) {(function(field) {
+        const fieldData = fields[field];
+        let value = fieldData['value'];
         if (fieldData['type'] === 'number') {
             value = PWM_MAIN.numberFormat(value);
         }

+ 7 - 7
webapp/src/main/webapp/public/resources/js/updateprofile.js

@@ -27,13 +27,13 @@ var PWM_VAR = PWM_VAR || {};
 var PWM_UPDATE = PWM_UPDATE || {};
 
 PWM_UPDATE.validateForm = function() {
-    var validationProps = [];
+    const validationProps = [];
     validationProps['serviceURL'] = PWM_MAIN.addParamToUrl(window.location.href,"processAction","validate");
     validationProps['readDataFunction'] = function(){
-        var paramData = { };
-        for (var j = 0; j < document.forms.length; j++) {
-            for (var i = 0; i < document.forms[j].length; i++) {
-                var current = document.forms[j].elements[i];
+        const paramData = {};
+        for (let j = 0; j < document.forms.length; j++) {
+            for (let i = 0; i < document.forms[j].length; i++) {
+                const current = document.forms[j].elements[i];
                 paramData[current.name] = current.value;
             }
         }
@@ -55,11 +55,11 @@ PWM_UPDATE.validateForm = function() {
 
 
 PWM_UPDATE.uploadPhoto=function(fieldName,options) {
-    var url = PWM_MAIN.addParamToUrl(window.location.pathname, 'processAction', 'uploadPhoto');
+    let url = PWM_MAIN.addParamToUrl(window.location.pathname, 'processAction', 'uploadPhoto');
     url = PWM_MAIN.addParamToUrl(url, 'field', fieldName);
 
 
-    var uploadOptions = options === undefined ? {} : options;
+    const uploadOptions = options === undefined ? {} : options;
     uploadOptions['url'] = url;
 
     uploadOptions['title'] = PWM_MAIN.showString('Title_UploadPhoto');

+ 18 - 12
webapp/src/main/webapp/public/resources/style.css

@@ -785,6 +785,7 @@ html[dir="rtl"] #header-center-right {
     overflow: auto;
     font-family: monospace;
     white-space: pre-wrap;
+    height: 400px;
 }
 
 /* hide recaptcha iframe near footer */
@@ -883,6 +884,14 @@ select {
     float: right;
 }
 
+.locale-select-table {
+    width: auto;
+    margin-right: auto;
+    margin-left: auto;
+    overflow-x: scroll;
+    cursor: pointer;
+}
+
 #localeSelectionMenu {
     white-space: nowrap;
     cursor: pointer;
@@ -1035,6 +1044,7 @@ input[type=search] {
 progress:not([value]) {
     width: 100%;
     height: 20px;
+    transition: all 1s;
 }
 
 progress[value] {
@@ -1043,6 +1053,10 @@ progress[value] {
     color: orange;
 }
 
+progress::-webkit-progress-value {
+    transition: all 1s;
+}
+
 .blink {
     animation: blink 4s infinite;
 }
@@ -1401,10 +1415,6 @@ dialog .closeIcon {
     text-align: center;
 }
 
-.display-none {
-    display: none;
-}
-
 #header-menu-icon::after {
     content: "\f141";
     font: 12px FontAwesome;
@@ -1490,14 +1500,6 @@ dialog .closeIcon {
     z-index: 1002;
 }
 
-html[dir="rtl"] .nihilo .dijitTabContainerTop-tabs {
-    text-align: right;
-}
-
-html[dir="rtl"] .nihilo .dijitTabContainerTop-tabs > .dijitTabContent:first-child {
-    margin-right: 10px;
-}
-
 @keyframes wait-fadein {
     0% {
         opacity: 0
@@ -1570,10 +1572,14 @@ html[dir="rtl"] .errorDetail {
     direction: ltr;
     text-align: right;
     unicode-bidi: bidi-override;
+    max-height: 250px;
+    overflow-y: auto
 }
 
 html[dir="rtl"] .message.message-error .errorDetail {
     display: inline-block;
+    max-height: 250px;
+    overflow-y: auto
 }
 
 .pwm-icon-button {

部分文件因文件數量過多而無法顯示