浏览代码

minor fixes

jrivard 10 年之前
父节点
当前提交
b73d225ad3
共有 30 个文件被更改,包括 350 次插入161 次删除
  1. 1 1
      pwm/servlet/src/password/pwm/PwmApplication.java
  2. 6 2
      pwm/servlet/src/password/pwm/config/PwmSetting.java
  3. 20 8
      pwm/servlet/src/password/pwm/config/PwmSetting.xml
  4. 13 0
      pwm/servlet/src/password/pwm/error/PwmUnrecoverableException.java
  5. 1 1
      pwm/servlet/src/password/pwm/http/SessionManager.java
  6. 3 3
      pwm/servlet/src/password/pwm/http/servlet/peoplesearch/PeopleSearchServlet.java
  7. 1 1
      pwm/servlet/src/password/pwm/i18n/Config.properties
  8. 33 0
      pwm/servlet/src/password/pwm/util/macro/AbstractMacro.java
  9. 24 0
      pwm/servlet/src/password/pwm/util/macro/InternalMacros.java
  10. 12 2
      pwm/servlet/src/password/pwm/util/macro/MacroMachine.java
  11. 1 29
      pwm/servlet/src/password/pwm/util/macro/StandardMacros.java
  12. 3 2
      pwm/servlet/src/password/pwm/util/operations/ActionExecutor.java
  13. 4 4
      pwm/servlet/src/password/pwm/util/report/ReportService.java
  14. 1 1
      pwm/servlet/src/password/pwm/ws/server/rest/RestChallengesServer.java
  15. 3 1
      pwm/servlet/web/WEB-INF/jsp/changepassword-wait.jsp
  16. 3 1
      pwm/servlet/web/WEB-INF/jsp/fragment/header-body.jsp
  17. 15 16
      pwm/servlet/web/WEB-INF/jsp/fragment/header-warnings.jsp
  18. 2 6
      pwm/servlet/web/WEB-INF/jsp/helpdesk-detail.jsp
  19. 3 4
      pwm/servlet/web/WEB-INF/jsp/helpdesk.jsp
  20. 3 1
      pwm/servlet/web/WEB-INF/jsp/newuser-wait.jsp
  21. 3 4
      pwm/servlet/web/WEB-INF/jsp/peoplesearch.jsp
  22. 1 1
      pwm/servlet/web/private/index.jsp
  23. 10 2
      pwm/servlet/web/public/resources/js/changepassword.js
  24. 63 23
      pwm/servlet/web/public/resources/js/configeditor.js
  25. 1 1
      pwm/servlet/web/public/resources/js/configmanager.js
  26. 14 4
      pwm/servlet/web/public/resources/js/helpdesk.js
  27. 36 10
      pwm/servlet/web/public/resources/js/main.js
  28. 11 3
      pwm/servlet/web/public/resources/js/newuser.js
  29. 47 30
      pwm/servlet/web/public/resources/style.css
  30. 12 0
      pwm/servlet/web/public/resources/themes/pwm/style.css

+ 1 - 1
pwm/servlet/src/password/pwm/PwmApplication.java

@@ -358,7 +358,7 @@ public class PwmApplication {
             final ChaiProvider proxiedProvider = getProxyChaiProvider(userIdentity.getLdapProfileID());
             return ChaiFactory.createChaiUser(userIdentity.getUserDN(), proxiedProvider);
         } catch (ChaiUnavailableException e) {
-            throw new PwmUnrecoverableException(PwmError.forChaiError(e.getErrorCode()));
+            throw PwmUnrecoverableException.fromChaiException(e);
         }
     }
 

+ 6 - 2
pwm/servlet/src/password/pwm/config/PwmSetting.java

@@ -33,6 +33,7 @@ import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.i18n.Config;
 import password.pwm.i18n.LocaleHelper;
 import password.pwm.util.logging.PwmLogger;
+import password.pwm.util.macro.MacroMachine;
 
 import java.util.*;
 import java.util.regex.Pattern;
@@ -1028,10 +1029,10 @@ public enum PwmSetting {
     private final PwmSettingCategory category;
     private final Set<Template> templates;
 
+
     private final Map<Template, StoredValue>    CACHE_DEFAULT_VALUES = new HashMap<>();
     private final Map<Locale,String>            CACHE_LABELS = new HashMap<>();
 
-
 // --------------------------- CONSTRUCTORS ---------------------------
 
     PwmSetting(
@@ -1151,7 +1152,10 @@ public enum PwmSetting {
     public String getDescription(final Locale locale) {
         final Element settingElement = PwmSettingXml.readSettingXml(this);
         final Element descriptionElement = settingElement.getChild("description");
-        return descriptionElement.getText();
+        final String storedText = descriptionElement.getText();
+        final MacroMachine macroMachine = MacroMachine.forStatic();
+        final String value = macroMachine.expandMacros(storedText);
+        return value;
     }
 
     public String getPlaceholder(final Locale locale) {

+ 20 - 8
pwm/servlet/src/password/pwm/config/PwmSetting.xml

@@ -142,7 +142,19 @@
     </setting>
     <setting key="interface.theme" level="1" required="true">
         <label>Interface Theme</label>
-        <description><![CDATA[Change the look and feel by selecting a theme.  The included themes are provided to mainly to inspiration to those wishing to make customizations.  If <b>Embedded</b> is selected, the settings <i>User Interface -> Embedded CSS Stylesheet</i> and <i>User Interface -> Embedded Mobile CSS Stylesheet</i> will be used to manage the custom CSS tags.  If <b>Custom</b> is selected, the settings <i>User Interface -> Custom CSS Location</i> and <i>Custom Mobile CSS Location</i>.]]></description>
+        <description><![CDATA[
+            Change the look and feel by selecting a theme. The included themes are provided primarily as inspiration to those wishing to make customizations.<br/><br/>
+                If <code>Embedded</code> is selected, the follow settings will be used to contain the contents of the default css theme:
+                <ul>
+                    <li><a data-gotoSettingLink="display.css.customStyle">@PwmSettingReference:display.css.customStyle@</a></li>
+                    <li><a data-gotoSettingLink="display.css.customMobileStyle">@PwmSettingReference:display.css.customMobileStyle@</a></li>
+                </ul>
+                If <code>Custom</code> is selected, the contents of the default css theme will be served from the locations referenced in the settings
+                <ul>
+                    <li><a data-gotoSettingLink="display.css.customStyleLocation">@PwmSettingReference:display.css.customStyleLocation@</a></li>
+                    <li><a data-gotoSettingLink="display.css.customMobileStyleLocation">@PwmSettingReference:display.css.customMobileStyleLocation@</a></li>
+                </ul>
+        ]]></description>
         <default>
             <value><![CDATA[pwm]]></value>
         </default>
@@ -310,28 +322,28 @@
     </setting>
     <setting key="display.css.customStyleLocation" level="2">
         <label>Custom CSS Stylesheet Location</label>
-        <description><![CDATA[URL Location (and name) of the custom <i>style.css</i> resource.  The setting <i>User Interface -> Theme</i> must be set to Custom for this setting to be useful.  If this URL is relative, it will be appended to the context path.]]></description>
+        <description><![CDATA[URL of the custom CSS resource.  The setting <a data-gotoSettingLink="interface.theme">@PwmSettingReference:interface.theme@</a> must be set to <code>Custom</code> for this setting to be useful.  If this URL is relative it will be appended to the context path.]]></description>
         <default>
             <value><![CDATA[]]></value>
         </default>
     </setting>
     <setting key="display.css.customMobileStyleLocation" level="2">
         <label>Custom Mobile CSS Stylesheet Location</label>
-        <description><![CDATA[URL Location (and name) of the custom <i>mobileStyle.css</i> resource.  The setting <i>User Interface -> Theme</i> must be set to Custom for this setting to be useful.  If this URL is relative, it will be appended to the context path.]]></description>
+        <description><![CDATA[URL of the custom mobile CSS resource.  The setting <a data-gotoSettingLink="interface.theme">@PwmSettingReference:interface.theme@</a> must be set to <code>Custom</code> for this setting to be useful.  If this URL is relative it will be appended to the context path.]]></description>
         <default>
             <value><![CDATA[]]></value>
         </default>
     </setting>
     <setting key="display.css.customStyle" level="2">
         <label>Embedded CSS Stylesheet</label>
-        <description><![CDATA[Contents of the custom CSS Stylesheet.  The setting <i>User Interface -> Theme</i> must be set to Embed for this setting to be useful.  The contents of this setting will be served from the "virtual" url of <b>/public/resources/themes/embed/style.css</b>.]]></description>
+        <description><![CDATA[Contents of the embedded CSS Stylesheet.   The setting <a data-gotoSettingLink="interface.theme">@PwmSettingReference:interface.theme@</a> must be set to <code>Embedded</code> for this setting to be useful.   The contents of this setting will be served from the virtual url of <code>/public/resources/themes/embed/style.css</code>.]]></description>
         <default>
             <value />
         </default>
     </setting>
     <setting key="display.css.customMobileStyle" level="2">
         <label>Embedded Mobile CSS Stylesheet</label>
-        <description><![CDATA[Contents of the custom mobile CSS Stylesheet.  The setting <i>User Interface -> Theme</i> must be set to Embed for this setting to be useful.  The contents of this setting will be served from the "virtual" url of <b>/public/resources/themes/embed/mobileStyle.css</b>.]]></description>
+        <description><![CDATA[Contents of the embedded mobile CSS Stylesheet.   The setting <a data-gotoSettingLink="interface.theme">@PwmSettingReference:interface.theme@</a> must be set to <code>Embedded</code> for this setting to be useful.  The contents of this setting will be served from the virtual url of <code>/public/resources/themes/embed/mobileStyle.css</code>.]]></description>
         <default>
             <value />
         </default>
@@ -2007,7 +2019,7 @@
         </default>
     </setting>
     <setting key="events.java.stdoutLevel" level="1">
-        <label>Java StdOut Log Level</label>
+        <label>Console (StdOut) Log Level</label>
         <description><![CDATA[Default Log level for stdout.  Most servlet containers will redirect stdout to a log file.  For example, tomcat logs stdout output to the <i>tomcat/logs/catalina.out</i> file by default.]]></description>
         <default>
             <value><![CDATA[INFO]]></value>
@@ -3419,7 +3431,7 @@
         <label>User Detail Display Name</label>
         <description><![CDATA[The display name used to identify the user on the user detail screen.  Macros are resolved to the displayed user.]]></description>
         <default>
-            <value>@User:ID@ - @User:Email@</value>
+            <value>@LDAP:givenName@ @LDAP:sn@ - @User:ID@ - @User:Email@</value>
         </default>
     </setting>
     <setting key="helpdesk.profile.list" level="1" hidden="true">
@@ -4084,7 +4096,7 @@
     </category>
     <category key="SMS">
         <label>SMS</label>
-        <description><![CDATA[Configuration settings for interfacing with SMS service gateways.  The SMS gateway should support REST web service to use with this application.  The service provider will provide you with information that will allow you to complete the settings here..]]></description>
+        <description><![CDATA[Configuration settings for interfacing with SMS service gateways.  The SMS gateway should support REST web service to use with this application.  The service provider will provide you with information that will allow you to complete the settings here.]]></description>
     </category>
     <category key="SMS_GATEWAY">
         <label>SMS Gateway</label>

+ 13 - 0
pwm/servlet/src/password/pwm/error/PwmUnrecoverableException.java

@@ -23,6 +23,9 @@
 package password.pwm.error;
 
 
+import com.novell.ldapchai.exception.ChaiException;
+import com.novell.ldapchai.exception.ChaiUnavailableException;
+
 /**
  * A general exception thrown by PWM.
  */
@@ -39,5 +42,15 @@ public class PwmUnrecoverableException extends PwmException {
     public PwmUnrecoverableException(final PwmError error) {
         super(error);
     }
+
+    public static PwmUnrecoverableException fromChaiException(final ChaiException e) {
+        final ErrorInformation errorInformation;
+        if (e instanceof ChaiUnavailableException) {
+            errorInformation = new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, e.getMessage());
+        } else {
+            errorInformation = new ErrorInformation(PwmError.forChaiError(e.getErrorCode()), e.getMessage());
+        }
+        return new PwmUnrecoverableException(errorInformation);
+    }
 }
 

+ 1 - 1
pwm/servlet/src/password/pwm/http/SessionManager.java

@@ -172,7 +172,7 @@ public class SessionManager implements Serializable {
             final ChaiProvider provider = this.getChaiProvider();
             return ChaiFactory.createChaiUser(userIdentity.getUserDN(), provider);
         } catch (ChaiUnavailableException e) {
-            throw new PwmUnrecoverableException(PwmError.forChaiError(e.getErrorCode()));
+            throw PwmUnrecoverableException.fromChaiException(e);
         }
     }
 

+ 3 - 3
pwm/servlet/src/password/pwm/http/servlet/peoplesearch/PeopleSearchServlet.java

@@ -292,7 +292,7 @@ public class PeopleSearchServlet extends PwmServlet {
             );
         } catch (ChaiException e) {
             LOGGER.error("unexpected error during detail lookup of '" + userIdentity + "', error: " + e.getMessage());
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.forChaiError(e.getErrorCode()),e.getMessage()));
+            throw PwmUnrecoverableException.fromChaiException(e);
         }
     }
 
@@ -333,7 +333,7 @@ public class PeopleSearchServlet extends PwmServlet {
             LOGGER.error(pwmRequest, "error generating user detail object: " + e.getMessage());
             pwmRequest.respondWithError(e.getErrorInformation());
         } catch (ChaiUnavailableException e) {
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.forChaiError(e.getErrorCode()),e.getMessage()));
+            throw PwmUnrecoverableException.fromChaiException(e);
         }
     }
 
@@ -523,7 +523,7 @@ public class PeopleSearchServlet extends PwmServlet {
                 return null;
             }
         } catch (ChaiUnavailableException e) {
-            throw new PwmUnrecoverableException(PwmError.forChaiError(e.getErrorCode()));
+            throw PwmUnrecoverableException.fromChaiException(e);
         }
 
         return "PeopleSearch?processAction=photo&userKey=" + userIdentity.toObfuscatedKey(pwmApplication.getConfig());

+ 1 - 1
pwm/servlet/src/password/pwm/i18n/Config.properties

@@ -109,7 +109,7 @@ Warning_ShowDescription=Help text for settings is available by clicking on setti
 Warning_ShowNotes=Notes exist for this configuration.  Select <em>Configuration Notes</em> from the <em>View</em> menu to show the notes.
 Warning_HeaderVisibility=Drag to pointer to top of screen to re-enable the alert header bar.
 Warning_ConfigMustBeClosed=<p>The configuration must be closed before these settings are available.</p><p>Close the configuration using the <a href="%1%">ConfigManager</a>.</p>
-Warning_MakeSupportZipNoTrace=<p>The configuration setting <b>Settings --> Logging & Auditing --> LocalDB Log Level</b> must be set to level <i>TRACE</i> before this option can be used.</p>
+Warning_MakeSupportZipNoTrace=<p>The configuration setting <code>@PwmSettingReference:events.pwmDB.logLevel@</code> must be set to level <code>TRACE</code> before this option can be used.</p>
 Warning_DownloadSupportZip=<b>Warning:</b> The download file contains sensitive security information, handle with appropriate care.
 Warning_DownloadConfiguration=<b>Warning:</b> The configuration download file contains sensitive security information, including security credentials, handle with appropriate care.
 Warning_DownloadLocal=<b>Warning:</b> The download LocalDB archive may contain sensitive security information, handle with appropriate care.

+ 33 - 0
pwm/servlet/src/password/pwm/util/macro/AbstractMacro.java

@@ -22,7 +22,15 @@
 
 package password.pwm.util.macro;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 public abstract class AbstractMacro implements MacroImplementation {
+
+    static final String PATTERN_OPTIONAL_PARAMETER_MATCH = "(:(?:/@|[^@])*)*"; // match param values inside @ and include @ if preceded by /
+    static final String PATTERN_PARAMETER_SPLIT = "(?<![/]):"; //split on : except if preceded by /
+
     public AbstractMacro() {
     }
 
@@ -30,4 +38,29 @@ public abstract class AbstractMacro implements MacroImplementation {
     public boolean isSensitive() {
         return false;
     }
+    static String stripMacroDelimiters(final String input) {
+        return input.replaceAll("^@|@$",""); // strip leading / trailing @
+    }
+
+    static String unescapeParamValue(final String input) {
+        String result = input;
+        result = result.replace("/:", ":");
+        result = result.replace("/@","@");
+        return result;
+    }
+
+    static List<String> splitMacroParameters(final String input, String... ignoreValues) {
+        final String strippedInput = stripMacroDelimiters(input);
+        final String[] splitInput = strippedInput.split(PATTERN_PARAMETER_SPLIT);
+        final List<String> returnObj = new ArrayList<>();
+        final List<String> ignoreValueList = Arrays.asList(ignoreValues);
+        for (final String value : splitInput) {
+            if (!ignoreValueList.contains(value)) {
+                returnObj.add(unescapeParamValue(value));
+                ignoreValueList.remove(value);
+            }
+        }
+        return returnObj;
+    }
+
 }

+ 24 - 0
pwm/servlet/src/password/pwm/util/macro/InternalMacros.java

@@ -24,6 +24,7 @@ package password.pwm.util.macro;
 
 import password.pwm.PwmConstants;
 import password.pwm.bean.UserInfoBean;
+import password.pwm.config.PwmSetting;
 import password.pwm.util.logging.PwmLogger;
 
 import java.util.ArrayList;
@@ -40,6 +41,7 @@ public abstract class InternalMacros {
         final List<Class<? extends MacroImplementation>> defaultMacros = new ArrayList<>();
         defaultMacros.add(OtpSetupTimeMacro.class);
         defaultMacros.add(ResponseSetupTimeMacro.class);
+        defaultMacros.add(PwmSettingReference.class);
         INTERNAL_MACROS = Collections.unmodifiableList(defaultMacros);
     }
 
@@ -76,4 +78,26 @@ public abstract class InternalMacros {
             return null;
         }
     }
+
+    public static class PwmSettingReference extends AbstractMacro {
+        private static final Pattern PATTERN = Pattern.compile("@PwmSettingReference" + PATTERN_OPTIONAL_PARAMETER_MATCH + "@" );
+
+        public Pattern getRegExPattern() {
+            return PATTERN;
+        }
+
+        public String replaceValue(String matchValue, MacroRequestInfo macroRequestInfo)
+                throws MacroParseException
+        {
+            final String settingKeyStr = matchValue.substring(21, matchValue.length() - 1);
+            if (settingKeyStr.isEmpty()) {
+                throw new MacroParseException("PwmSettingReference macro requires a setting key value");
+            }
+            final PwmSetting setting = PwmSetting.forKey(settingKeyStr);
+            if (setting == null) {
+                throw new MacroParseException("PwmSettingReference macro has unknown key value '" + settingKeyStr + "'");
+            }
+            return setting.toMenuLocationDebug(null, PwmConstants.DEFAULT_LOCALE);
+        }
+    }
 }

+ 12 - 2
pwm/servlet/src/password/pwm/util/macro/MacroMachine.java

@@ -83,7 +83,9 @@ public class MacroMachine {
             }
         }
 
-        final List<String> externalMethods = pwmApplication.getConfig().readSettingAsStringArray(PwmSetting.EXTERNAL_MACROS_REST_URLS);
+        final List<String> externalMethods = pwmApplication == null
+                ? Collections.<String>emptyList()
+                : pwmApplication.getConfig().readSettingAsStringArray(PwmSetting.EXTERNAL_MACROS_REST_URLS);
 
         int iteration = 0;
         for (final String url : externalMethods) {
@@ -177,7 +179,11 @@ public class MacroMachine {
             replaceStr = macroImplementation.replaceValue(matchedStr, macroRequestInfo);
         } catch (MacroParseException e) {
             LOGGER.debug(sessionLabel, "macro parse error replacing macro '" + matchedStr + "', error: " + e.getMessage());
-            replaceStr = "[" + e.getErrorInformation().toUserStr(PwmConstants.DEFAULT_LOCALE,macroRequestInfo.getPwmApplication().getConfig()) + "]";
+            if (pwmApplication != null) {
+                replaceStr = "[" + e.getErrorInformation().toUserStr(PwmConstants.DEFAULT_LOCALE, macroRequestInfo.getPwmApplication().getConfig()) + "]";
+            } else {
+                replaceStr = "[" + e.getErrorInformation().toUserStr(PwmConstants.DEFAULT_LOCALE, null) + "]";
+            }
         }  catch (Exception e) {
             LOGGER.error(sessionLabel, "error while replacing macro '" + matchedStr + "', error: " + e.getMessage());
         }
@@ -201,6 +207,10 @@ public class MacroMachine {
         return new StringBuilder(input).replace(startPos, endPos, replaceStr).toString();
     }
 
+    public static MacroMachine forStatic() {
+        return new MacroMachine(null,null,null,null,null);
+    }
+
     public static interface StringReplacer {
         public String replace(final String matchedMacro, final String newValue);
     }

+ 1 - 29
pwm/servlet/src/password/pwm/util/macro/StandardMacros.java

@@ -46,10 +46,6 @@ import java.util.regex.Pattern;
 public abstract class StandardMacros {
     private static final PwmLogger LOGGER = PwmLogger.forClass(StandardMacros.class);
 
-    static final String PATTERN_OPTIONAL_PARAMETER_MATCH = "(:(?:/@|[^@])*)*"; // match param values inside @ and include @ if preceded by /
-    static final String PATTERN_PARAMETER_SPLIT = "(?<![/]):"; //split on : except if preceded by /
-
-
     public static final List<Class<? extends MacroImplementation>> STANDARD_MACROS;
     static {
         final List<Class<? extends MacroImplementation>> defaultMacros = new ArrayList<>();
@@ -74,30 +70,6 @@ public abstract class StandardMacros {
         STANDARD_MACROS = Collections.unmodifiableList(defaultMacros);
     }
 
-    static String stripMacroDelimiters(final String input) {
-        return input.replaceAll("^@|@$",""); // strip leading / trailing @
-    }
-
-    static String unescapeParamValue(final String input) {
-        String result = input;
-        result = result.replace("/:", ":");
-        result = result.replace("/@","@");
-        return result;
-    }
-
-    static List<String> splitMacroParameters(final String input, String... ignoreValues) {
-        final String strippedInput = stripMacroDelimiters(input);
-        final String[] splitInput = strippedInput.split(PATTERN_PARAMETER_SPLIT);
-        final List<String> returnObj = new ArrayList<>();
-        final List<String> ignoreValueList = Arrays.asList(ignoreValues);
-        for (final String value : splitInput) {
-            if (!ignoreValueList.contains(value)) {
-                returnObj.add(unescapeParamValue(value));
-                ignoreValueList.remove(value);
-            }
-        }
-        return returnObj;
-    }
 
     public static class LdapMacro extends AbstractMacro {
         private static final Pattern PATTERN = Pattern.compile("@LDAP" + PATTERN_OPTIONAL_PARAMETER_MATCH + "@");
@@ -529,7 +501,7 @@ public abstract class StandardMacros {
         private static final Pattern PATTERN = Pattern.compile("@Encode:[^:]+:\\[\\[.*\\]\\]@");
         // @Encode:ENCODE_TYPE:value@
 
-        private static enum ENCODE_TYPE {
+        private enum ENCODE_TYPE {
             urlPath,
             urlParameter,
             base64,

+ 3 - 2
pwm/servlet/src/password/pwm/util/operations/ActionExecutor.java

@@ -51,8 +51,9 @@ public class ActionExecutor {
     private PwmApplication pwmApplication;
     private ActionExecutorSettings settings;
 
-    private ActionExecutor(PwmApplication pwmApplication) {
+    private ActionExecutor(final PwmApplication pwmApplication, final ActionExecutorSettings settings) {
         this.pwmApplication = pwmApplication;
+        this.settings = settings;
     }
 
     public void executeActions(
@@ -298,7 +299,7 @@ public class ActionExecutor {
         }
 
         public ActionExecutor createActionExecutor() {
-            return new ActionExecutor(this.pwmApplication);
+            return new ActionExecutor(this.pwmApplication,this);
         }
     }
 

+ 4 - 4
pwm/servlet/src/password/pwm/util/report/ReportService.java

@@ -239,7 +239,7 @@ public class ReportService implements PwmService {
             final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers());
             reportStatus.setTotal(allUsers.size());
             while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) {
-                final long startUpdateTime = System.currentTimeMillis();
+                final Date startUpdateTime = new Date();
                 final UserIdentity userIdentity = allUsers.poll();
                 try {
                     if (updateCache(userIdentity)) {
@@ -256,9 +256,9 @@ public class ReportService implements PwmService {
                 }
                 reportStatus.setCount(reportStatus.getCount() + 1);
                 reportStatus.getEventRateMeter().markEvents(1);
-                final long totalUpdateTime = System.currentTimeMillis() - startUpdateTime;
+                final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime);
                 if (settings.isAutoCalcRest()) {
-                    avgTracker.addSample(totalUpdateTime);
+                    avgTracker.addSample(totalUpdateTime.getTotalMilliseconds());
                     Helper.pause(avgTracker.avgAsLong());
                 } else {
                     Helper.pause(settings.getRestTime().getTotalMilliseconds());
@@ -593,7 +593,7 @@ public class ReportService implements PwmService {
                         }
                     }
                 }
-                LOGGER.warn(PwmConstants.REPORTING_SESSION_LABEL,"unable to dredge ldap for ");
+                LOGGER.warn(PwmConstants.REPORTING_SESSION_LABEL,"unable to dredge ldap due to error: " + e.getMessage());
             }
         }
     }

+ 1 - 1
pwm/servlet/src/password/pwm/ws/server/rest/RestChallengesServer.java

@@ -375,7 +375,7 @@ public class RestChallengesServer extends AbstractRestServer {
                 StatisticsManager.incrementStat(restRequestBean.getPwmApplication(), Statistic.REST_CHALLENGES);
             }
 
-            final String successMsg = Message.Success_ClearResponse.getLocalizedMessage(request.getLocale(),restRequestBean.getPwmApplication().getConfig());
+            final String successMsg = Message.Success_Unknown.getLocalizedMessage(request.getLocale(),restRequestBean.getPwmApplication().getConfig());
             RestResultBean resultBean = new RestResultBean();
             resultBean.setError(false);
             resultBean.setSuccessMessage(successMsg);

+ 3 - 1
pwm/servlet/web/WEB-INF/jsp/changepassword-wait.jsp

@@ -55,7 +55,9 @@
         <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
         <p><pwm:display key="Display_PleaseWaitPassword"/></p>
         <div class="meteredProgressBar">
-            <div data-dojo-type="dijit/ProgressBar" style="width:100%" data-dojo-id="passwordProgressBar" id="passwordProgressBar" data-dojo-props="maximum:100"></div>
+          <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">
             <%--

+ 3 - 1
pwm/servlet/web/WEB-INF/jsp/fragment/header-body.jsp

@@ -38,9 +38,11 @@
         final boolean showButtons = !pwmRequest.isFlag(PwmRequest.Flag.HIDE_HEADER_BUTTONS) && !pwmRequest.isForcedPageView();
         final boolean loggedIn = pwmRequest.isAuthenticated();
         if (showButtons && loggedIn) {
-            showLogout = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_LOGOUT_BUTTON);
             showHome = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_HOME_BUTTON);
         }
+        if (loggedIn) {
+            showLogout = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_LOGOUT_BUTTON);
+        }
     } catch (PwmUnrecoverableException e) {
         /* application must be unavailable */
     }

+ 15 - 16
pwm/servlet/web/WEB-INF/jsp/fragment/header-warnings.jsp

@@ -60,7 +60,20 @@
     </script>
 </pwm:script>
 <div id="header-warning" style="display: none">
-    <div class="header-warning-buttons">
+    <div class="header-warning-row header-warning-version"><%=PwmConstants.PWM_APP_NAME_VERSION%></div>
+    <div id="header-warning-message" class="header-warning-row header-warning-message">
+    <% if (PwmConstants.TRIAL_MODE) { %>
+    <pwm:display key="Header_TrialMode" bundle="Admin" value1="<%=PwmConstants.PWM_APP_NAME%>"/>
+    <% } else if (configMode) { %>
+    <pwm:display key="Header_ConfigModeActive" bundle="Admin" value1="<%=PwmConstants.PWM_APP_NAME%>"/>
+
+    <pwm:if test="showIcons"><span id="icon-configModeHelp" class="btn-icon fa fa-question-circle"></span></pwm:if>
+        <br/><br/>
+    <% } else if (adminUser) { %>
+    <pwm:display key="Header_AdminUser" bundle="Admin" value1="<%=PwmConstants.PWM_APP_NAME%>"/>
+    <% } %>
+    </div>
+    <div class="header-warning-row header-warning-buttons">
         <a class="header-warning-button" id="header_configManagerButton">
             <pwm:if test="showIcons"><span class="btn-icon fa fa-gears"></span></pwm:if>
             <pwm:display key="MenuItem_ConfigManager" bundle="Admin"/>
@@ -82,26 +95,12 @@
         </a>
         <% } %>
     </div>
-    <span id="header-warning-message" style="padding-right: 15px; font-weight: bold">
-    <% if (PwmConstants.TRIAL_MODE) { %>
-    <pwm:display key="Header_TrialMode" bundle="Admin" value1="<%=PwmConstants.PWM_APP_NAME%>"/>
-    <% } else if (configMode) { %>
-    <pwm:display key="Header_ConfigModeActive" bundle="Admin" value1="<%=PwmConstants.PWM_APP_NAME%>"/>
-
-    <pwm:if test="showIcons"><span id="icon-configModeHelp" class="btn-icon fa fa-question-circle"></span></pwm:if>
-        <br/><br/>
-    <% } else if (adminUser) { %>
-    <pwm:display key="Header_AdminUser" bundle="Admin" value1="<%=PwmConstants.PWM_APP_NAME%>"/>
-    <% } %>
-    </span>
-    <div id="panel-header-healthData" style="cursor: pointer"></div>
+    <div id="panel-header-healthData" class="header-warning-row header-warning-healthData"></div>
     <% if (includeHeader) { %>
     <div id="button-closeHeader">
         <span class="fa fa-chevron-circle-right"></span>
     </div>
     <% } %>
-    <br/>
-    <%=PwmConstants.PWM_APP_NAME_VERSION%>
 </div>
 <% if (includeHeader) { %>
 <div id="button-openHeader">

+ 2 - 6
pwm/servlet/web/WEB-INF/jsp/helpdesk-detail.jsp

@@ -528,11 +528,7 @@
                             <script type="text/javascript">
                                 PWM_GLOBAL['startupFunctions'].push(function(){
                                     PWM_MAIN.addEventHandler('button_refresh','click',function(){
-                                        PWM_MAIN.showWaitDialog({loadFunction:function(){
-                                            setTimeout(function(){
-                                                document.continueForm.submit();
-                                            },1000);
-                                        }});
+                                        PWM_HELPDESK.refreshDetailPage();
                                     });
                                 });
                             </script>
@@ -745,7 +741,7 @@
         }
 
         PWM_GLOBAL['startupFunctions'].push(function(){
-            require(["dojo/parser","dojo/domReady!","dijit/layout/TabContainer","dijit/layout/ContentPane"],function(dojoParser){
+            require(["dojo/parser","dijit/layout/TabContainer","dijit/layout/ContentPane"],function(dojoParser){
                 dojoParser.parse();
                 PWM_VAR['helpdesk_obfuscatedDN'] = '<%=StringUtil.escapeJS(obfuscatedDN)%>';
                 PWM_VAR['helpdesk_username'] = '<%=StringUtil.escapeJS(searchedUserInfo.getUsername())%>';

+ 3 - 4
pwm/servlet/web/WEB-INF/jsp/helpdesk.jsp

@@ -33,10 +33,9 @@
     <jsp:include page="/WEB-INF/jsp/fragment/header-body.jsp">
         <jsp:param name="pwm.PageName" value="Title_Helpdesk"/>
     </jsp:include>
-    <div id="centerbody" class="wide">
+    <div id="centerbody" class="wide tall">
         <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
-        <div id="searchControlPanel" style="position: relative; margin-left: auto; margin-right: auto; width: 100%; text-align: center">
-            <br/>
+        <div id="panel-searchbar" class="searchbar">
             <table class="noborder" style="margin-left: auto; margin-right: auto; width:100px; table-layout: fixed" >
                 <tr>
                     <td style="width:15px">
@@ -62,7 +61,7 @@
             </noscript>
             <br/>
         </div>
-        <div id="helpdesk-searchResultsGrid" class="grid">
+        <div id="helpdesk-searchResultsGrid" class="grid tall">
         </div>
     </div>
     <div class="push"></div>

+ 3 - 1
pwm/servlet/web/WEB-INF/jsp/newuser-wait.jsp

@@ -52,7 +52,9 @@
         <p><pwm:display key="Display_PleaseWaitNewUser"/></p>
         <%@ include file="fragment/message.jsp" %>
         <div class="meteredProgressBar">
-            <div data-dojo-type="dijit/ProgressBar" style="width:100%" data-dojo-id="createProgressBar" id="createProgressBar" data-dojo-props="maximum:100"></div>
+          <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">
             <%--

+ 3 - 4
pwm/servlet/web/WEB-INF/jsp/peoplesearch.jsp

@@ -30,10 +30,9 @@
     <jsp:include page="/WEB-INF/jsp/fragment/header-body.jsp">
         <jsp:param name="pwm.PageName" value="Title_PeopleSearch"/>
     </jsp:include>
-    <div id="centerbody" class="wide" style="height:100%">
+    <div id="centerbody" class="wide tall" style="height:100%">
         <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
-
-        <div id="searchControlPanel" style="position: relative; margin-left: auto; margin-right: auto; width: 100%; text-align: center;">
+        <div id="panel-searchbar" class="searchbar">
             <table class="noborder" style="margin-left: auto; margin-right: auto; width:100px;" >
                 <tr>
                     <td style="width:5%">
@@ -60,7 +59,7 @@
             </noscript>
         </div>
         <br/>
-        <div id="peoplesearch-searchResultsGrid" class="grid">
+        <div id="peoplesearch-searchResultsGrid" class="grid tall">
         </div>
     </div>
     <div class="push"></div>

+ 1 - 1
pwm/servlet/web/private/index.jsp

@@ -35,7 +35,7 @@
 %>
 <html dir="<pwm:LocaleOrientation/>">
 <%@ include file="../WEB-INF/jsp/fragment/header.jsp" %>
-<body>
+<body class="nihilo">
 <div id="wrapper">
     <jsp:include page="../WEB-INF/jsp/fragment/header-body.jsp">
         <jsp:param name="pwm.PageName" value="Title_MainPage"/>

+ 10 - 2
pwm/servlet/web/public/resources/js/changepassword.js

@@ -436,8 +436,16 @@ PWM_CHANGEPW.refreshCreateStatus=function(refreshInterval) {
         var displayStringsUrl = "ChangePassword?processAction=checkProgress";
         var completedUrl = "ChangePassword?processAction=complete&pwmFormID=" + PWM_GLOBAL['pwmFormID'];
         var loadFunction = function(data) {
-            var progressBar = registry.byId('passwordProgressBar');
-            progressBar.set("value",data['data']['percentComplete']);
+            var supportsProgress = (document.createElement('progress').max !== undefined);
+            if (supportsProgress) {
+                console.log('beginning html5 progress refresh');
+                var html5passwordProgressBar = PWM_MAIN.getObject('html5ProgressBar');
+                dojo.setAttr(html5passwordProgressBar, "value", data['data']['percentComplete']);
+            } else {
+                console.log('beginning dojo progress refresh');
+                var progressBar = registry.byId('passwordProgressBar');
+                progressBar.set("value",data['data']['percentComplete']);
+            }
 
             try {
                 var tableBody = '';

+ 63 - 23
pwm/servlet/web/public/resources/js/configeditor.js

@@ -78,7 +78,7 @@ PWM_CFGEDIT.updateLastModifiedInfo = function(keyName, data) {
     if (PWM_MAIN.getObject('panel-' + keyName + '-modifyTime')) {
         if (data['data']['modifyTime']) {
             PWM_MAIN.getObject('panel-' + keyName + '-modifyTime').innerHTML = 'Last Modified '
-            + '<span id="panel-' + keyName + '-modifyTimestamp">' + data['data']['modifyTime'] + '</span>';
+                + '<span id="panel-' + keyName + '-modifyTimestamp">' + data['data']['modifyTime'] + '</span>';
             PWM_MAIN.TimestampHandler.initElement(PWM_MAIN.getObject('panel-' + keyName + '-modifyTimestamp'));
         } else {
             PWM_MAIN.getObject('panel-' + keyName + '-modifyTime').innerHTML = '';
@@ -510,8 +510,27 @@ PWM_CFGEDIT.processSettingSearch = function(destinationDiv) {
 PWM_CFGEDIT.gotoSetting = function(category,settingKey,profile) {
     console.log('going to setting... category=' + category + " settingKey=" + settingKey + " profile=" + profile);
 
-    if (!category || (!(category in PWM_SETTINGS['categories']))) {
-        console.log('can\'t process request to display settings category: ' + category );
+    if (!category) {
+        if (settingKey) {
+            var settingInfo = PWM_SETTINGS['settings'][settingKey];
+            if (settingInfo) {
+                category = settingInfo['category'];
+            }
+        }
+    }
+
+    if (!settingKey && !category) {
+        alert('unable to goto setting: settingKey and category parameter are not specified');
+        return;
+    }
+
+    if (settingKey && !(settingKey in PWM_SETTINGS['settings'])) {
+        alert('unable to goto setting: settingKey parameter "' + settingKey + '" is not valid');
+        return;
+    }
+
+    if (!(category in PWM_SETTINGS['categories'])) {
+        alert('unable to goto setting: category parameter "' + category + '" is not valid');
         return;
     }
 
@@ -722,12 +741,23 @@ PWM_CFGEDIT.selectTemplate = function(newTemplate) {
 PWM_CFGEDIT.loadMainPageBody = function() {
 
     PWM_CFGEDIT.drawNavigationMenu();
+
     var storedPreferences = PWM_MAIN.readLocalStorage();
-    if (storedPreferences['lastSelected']) {
-        PWM_CFGEDIT.dispatchNavigationItem(storedPreferences['lastSelected']);
+    if (storedPreferences['configeditor-lastSelected']) {
+        PWM_CFGEDIT.dispatchNavigationItem(storedPreferences['configeditor-lastSelected']);
     } else {
         PWM_CFGEDIT.drawHomePage();
     }
+
+    require(["dojo/io-query"],function(ioQuery){
+        var uri = window.location.href;
+        var queryString = uri.substring(uri.indexOf("?") + 1, uri.length);
+        var queryParams = ioQuery.queryToObject(queryString);
+        if (queryParams['processAction'] == 'gotoSetting') {
+            PWM_CFGEDIT.gotoSetting(queryParams['category'],queryParams['settingKey'],queryParams['profile']);
+            return;
+        }
+    });
 };
 
 PWM_CFGEDIT.displaySettingsCategory = function(category) {
@@ -744,16 +774,16 @@ PWM_CFGEDIT.displaySettingsCategory = function(category) {
 
     if (category == 'LDAP_PROFILE') {
         htmlSettingBody += '<div style="width: 100%; text-align: center">'
-        + '<button class="btn" id="button-test-LDAP_PROFILE"><span class="btn-icon fa fa-bolt"></span>Test LDAP Profile</button>'
-        + '</div>';
+            + '<button class="btn" id="button-test-LDAP_PROFILE"><span class="btn-icon fa fa-bolt"></span>Test LDAP Profile</button>'
+            + '</div>';
     } else if (category == 'DATABASE') {
         htmlSettingBody += '<div style="width: 100%; text-align: center">'
-        + '<button class="btn" id="button-test-DATABASE"><span class="btn-icon fa fa-bolt"></span>Test Database Settings</button>'
-        + '</div>';
+            + '<button class="btn" id="button-test-DATABASE"><span class="btn-icon fa fa-bolt"></span>Test Database Settings</button>'
+            + '</div>';
     } else if (category == 'SMS_GATEWAY') {
         htmlSettingBody += '<div style="width: 100%; text-align: center">'
-        + '<button class="btn" id="button-test-SMS"><span class="btn-icon fa fa-bolt"></span>Test SMS Settings</button>'
-        + '</div>';
+            + '<button class="btn" id="button-test-SMS"><span class="btn-icon fa fa-bolt"></span>Test SMS Settings</button>'
+            + '</div>';
     }
 
     PWM_VAR['skippedSettingCount'] = 0;
@@ -783,6 +813,7 @@ PWM_CFGEDIT.displaySettingsCategory = function(category) {
     } else if (category == 'SMS_GATEWAY') {
         PWM_MAIN.addEventHandler('button-test-SMS', 'click', function(){PWM_CFGEDIT.smsHealthCheck();});
     }
+    PWM_CFGEDIT.applyGotoSettingHandlers();
 };
 
 PWM_CFGEDIT.drawProfileEditorPage = function(settingKey) {
@@ -809,22 +840,22 @@ PWM_CFGEDIT.drawHtmlOutlineForSetting = function(settingInfo, options) {
     }
 
     htmlBody += '<div style="visibility: hidden" class="fa fa-undo icon_button" title="' + PWM_CONFIG.showString('Tooltip_ResetButton') + '" id="resetButton-' + settingKey + '"></div>'
-    + '</div>' // close title
-    + '<div id="titlePane_' + settingKey + '" class="setting_body">';
+        + '</div>' // close title
+        + '<div id="titlePane_' + settingKey + '" class="setting_body">';
 
     if (settingInfo['description']) {
         var prefs = PWM_MAIN.readLocalStorage();
         var expandHelp = 'helpExpanded' in prefs && settingKey in prefs['helpExpanded'];
         htmlBody += '<div class="pane-help" id="pane-help-' + settingKey + '" style="display:' + (expandHelp ? 'inherit' : 'none') + '">'
-        + settingInfo['description'] + '</div>';
+            + settingInfo['description'] + '</div>';
     }
 
     htmlBody += '<div class="pane-settingValue" id="table_setting_' + settingKey + '" style="border:0 none">'
-    + '</div>' // close setting;
-    + '</div>' // close body
-    + '<div class="footnote" style="width:100%"><span id="panel-' + settingKey + '-modifyTime"></span></div>'
-    + '<div class="footnote" style="width:100%"><span id="panel-' + settingKey + '-modifyUser"></span></div>'
-    + '</div>';  // close outline
+        + '</div>' // close setting;
+        + '</div>' // close body
+        + '<div class="footnote" style="width:100%"><span id="panel-' + settingKey + '-modifyTime"></span></div>'
+        + '<div class="footnote" style="width:100%"><span id="panel-' + settingKey + '-modifyUser"></span></div>'
+        + '</div>';  // close outline
 
     return htmlBody;
 };
@@ -980,7 +1011,7 @@ PWM_CFGEDIT.drawNavigationMenu = function() {
                     id: 'navigationTree',
                     onClick: function(item){
                         var storedPreferences = PWM_MAIN.readLocalStorage();
-                        storedPreferences['lastSelected'] = item;
+                        storedPreferences['configeditor-lastSelected'] = item;
                         PWM_MAIN.writeLocalStorage(storedPreferences);
                         PWM_CFGEDIT.dispatchNavigationItem(item);
                     }
@@ -1051,7 +1082,7 @@ PWM_CFGEDIT.drawDisplayTextPage = function(settingKey, keys) {
     var settingsPanel = PWM_MAIN.getObject('settingsPanel');
     var remainingLoads = keys.length;
     settingsPanel.innerHTML = '<div id="displaytext-loading-panel" style="width:100%; text-align: center">'
-    + PWM_MAIN.showString('Display_PleaseWait') + '&nbsp;<span id="remainingCount"></div>';
+        + PWM_MAIN.showString('Display_PleaseWait') + '&nbsp;<span id="remainingCount"></div>';
     console.log('drawing displaytext-editor for setting-' + settingKey);
     var htmlBody = '<div id="localetext-editor-wrapper" style="display:none">';
     for (var key in keys) {
@@ -1062,7 +1093,7 @@ PWM_CFGEDIT.drawDisplayTextPage = function(settingKey, keys) {
         htmlBody += PWM_CFGEDIT.drawHtmlOutlineForSetting(settingInfo,{showHelp:false});
     }
     settingsPanel.innerHTML = settingsPanel.innerHTML + htmlBody;
-    
+
     var initSetting = function(keyCounter) {
         if (PWM_VAR['outstandingOperations'] > 5) {
             setTimeout(function () { initSetting(keyCounter); }, 50);
@@ -1078,7 +1109,7 @@ PWM_CFGEDIT.drawDisplayTextPage = function(settingKey, keys) {
         remainingLoads--;
         PWM_MAIN.getObject('remainingCount').innerHTML = remainingLoads > 0 ? remainingLoads : '';
     };
-    
+
     var delay = 5;
     for (var key in keys) {
         (function(keyCounter) {
@@ -1255,4 +1286,13 @@ PWM_CFGEDIT.setCurrentProfile = function(profile) {
     } else {
         delete PWM_VAR['currentProfile'];
     }
+};
+
+PWM_CFGEDIT.applyGotoSettingHandlers = function() {
+    PWM_MAIN.doQuery('[data-gotoSettingLink]',function(element){
+        PWM_MAIN.addEventHandler(element,'click',function(){
+            var linkValue = element.getAttribute('data-gotoSettingLink');
+            PWM_CFGEDIT.gotoSetting(null,linkValue,null);
+        })
+    });
 };

+ 1 - 1
pwm/servlet/web/public/resources/js/configmanager.js

@@ -426,7 +426,7 @@ PWM_CONFIG.initConfigHeader = function() {
     PWM_CONFIG.showHeaderHealth();
 
     var prefs = PWM_MAIN.readLocalStorage();
-    if (prefs['headerVisibility'] == 'show') {
+    if (prefs['headerVisibility'] != 'hide') {
         PWM_CONFIG.openHeaderWarningPanel();
     }
 

+ 14 - 4
pwm/servlet/web/public/resources/js/helpdesk.js

@@ -46,19 +46,21 @@ PWM_HELPDESK.executeAction = function(actionName) {
 PWM_HELPDESK.doResponseClear = function() {
     var username = PWM_VAR['helpdesk_obfuscatedDN'];
     PWM_MAIN.showWaitDialog({loadFunction:function() {
-        var inputValues = { 'username': username };
-        var url = PWM_GLOBAL['url-restservice'] + "/challenges";
+        var url = PWM_GLOBAL['url-restservice'] + "/challenges?username=" + username;
         var loadFunction = function(results) {
             if (results['error'] != true) {
                 PWM_MAIN.showDialog({
                     title: PWM_MAIN.showString('Button_ClearResponses'),
-                    text: results['successMessage']
+                    text: results['successMessage'],
+                    okAction:function(){
+                        PWM_HELPDESK.refreshDetailPage();
+                    }
                 });
             } else {
                 PWM_MAIN.showErrorDialog(results);
             }
         };
-        PWM_MAIN.ajaxRequest(url,loadFunction,{content:inputValues,method:'delete'});
+        PWM_MAIN.ajaxRequest(url,loadFunction,{method:'DELETE'});
     }});
 };
 
@@ -451,4 +453,12 @@ PWM_HELPDESK.initPage = function() {
     }
 };
 
+PWM_HELPDESK.refreshDetailPage = function() {
+    PWM_MAIN.showWaitDialog({loadFunction:function(){
+        setTimeout(function(){
+            document.continueForm.submit();
+        },1000);
+    }});
+};
+
 PWM_HELPDESK.initPage();

+ 36 - 10
pwm/servlet/web/public/resources/js/main.js

@@ -1957,27 +1957,53 @@ PWM_MAIN.clearFocus = function() {
     document.activeElement.blur();
 };
 
+PWM_MAIN.prefsValues = {
+    attrTimestamp:"ClientPreferencesTimestamp",
+    attrPrefs:"ClientPreferences",
+    persistanceTime:(24 * 60 * 60 * 1000)
+};
+
 PWM_MAIN.readLocalStorage = function() {
     if(typeof(Storage) !== "undefined") {
-        var storedStr = localStorage.getItem("ConfigEditor_Storage");
-        if (storedStr) {
-            try {
-                return JSON.parse(storedStr);
-            } catch (e) {
-                console.error('Error decoding existing local storage value: ' + e);
+        try {
+            var storedTimeStr = localStorage.getItem(PWM_MAIN.prefsValues.attrTimestamp);
+            if (storedTimeStr) {
+                var lastStoredDate = Date.parse(storedTimeStr);
+                if (lastStoredDate) {
+                    var MAX_AGE = PWM_MAIN.prefsValues.persistanceTime;
+                    if (((new Date) - lastStoredDate) > MAX_AGE) {
+                        localStorage.setItem(PWM_MAIN.prefsValues.attrPrefs, "{}");
+                    }
+                }
             }
+
+            var storedStr = localStorage.getItem(PWM_MAIN.prefsValues.attrPrefs);
+            if (storedStr) {
+                try {
+                    return JSON.parse(storedStr);
+                } catch (e) {
+                    console.log('Error decoding existing local storage value: ' + e);
+                }
+            }
+        } catch (e) {
+            console.log("error reading locale storage preferences: " + e);
         }
-        return {};
     } else {
         console.log("browser doesn't support local storage");
     }
+    return {};
 };
 
 PWM_MAIN.writeLocalStorage = function(dataUpdate) {
-    if(typeof(Storage) !== "undefined") {
-        if (dataUpdate) {
-            localStorage.setItem("ConfigEditor_Storage",JSON.stringify(dataUpdate));
+    try {
+        if (typeof(Storage) !== "undefined") {
+            if (dataUpdate) {
+                    localStorage.setItem(PWM_MAIN.prefsValues.attrTimestamp, new Date().toISOString());
+                    localStorage.setItem(PWM_MAIN.prefsValues.attrPrefs, JSON.stringify(dataUpdate));
+            }
         }
+    } catch (e) {
+        console.log("error storing local storage preferences: " + e);
     }
 };
 

+ 11 - 3
pwm/servlet/web/public/resources/js/newuser.js

@@ -153,8 +153,16 @@ PWM_NEWUSER.refreshCreateStatus=function(refreshInterval) {
             timeout: PWM_GLOBAL['client.ajaxTypingTimeout'],
             headers: { "Accept": "application/json" },
             load: function(data) {
-                var progressBar = registry.byId('createProgressBar');
-                progressBar.set("value",data['data']['percentComplete']);
+                var supportsProgress = (document.createElement('progress').max !== undefined);
+                if (supportsProgress) {
+                    console.log('beginning html5 progress refresh');
+                    var html5passwordProgressBar = PWM_MAIN.getObject('html5ProgressBar');
+                    dojo.setAttr(html5passwordProgressBar, "value", data['data']['percentComplete']);
+                } else {
+                    console.log('beginning dojo progress refresh');
+                    var progressBar = registry.byId('passwordProgressBar');
+                    progressBar.set("value",data['data']['percentComplete']);
+                }
 
                 if (data['data']['complete'] == true) {
                     PWM_MAIN.goto(completedUrl,{delay:1000})
@@ -172,4 +180,4 @@ PWM_NEWUSER.refreshCreateStatus=function(refreshInterval) {
             }
         });
     });
-}
+}

+ 47 - 30
pwm/servlet/web/public/resources/style.css

@@ -235,6 +235,19 @@ input[type=password]::-ms-reveal{display: none;}
     min-width: 600px;
 }
 
+#centerbody.tall {
+    bottom: 80px;
+    height: auto !important;
+    left: 40px;
+    margin: auto;
+    min-width: auto;
+    position: absolute;
+    right: 40px;
+    top: 100px;
+    width: auto;
+}
+
+
 /* all forms use a buttonbar div containing the action buttons */
 .buttonbar {
     margin-top: 30px;
@@ -349,14 +362,23 @@ div.progress-container > div {
     position: absolute;
     right:6px;
     top:6px;
-    width: 190px;
+    width: 200px;
     border: 2px solid #aaaaaa;
     background-color: #DDDDDD;
     z-index: 10;
     padding: 10px;
-    animation: fadein 0.3s;
-    -moz-animation: fadein 0.3s; /* Firefox */
-    -webkit-animation: fadein 0.3s; /* Safari and Chrome */
+}
+
+.header-warning-row {
+    margin-bottom: 15px;
+}
+
+.header-warning-healthData {
+    cursor: pointer;
+}
+
+.header-warning-version {
+    font-weight: bold;
 }
 
 .header-warning-buttons {
@@ -525,9 +547,14 @@ img.qrcodeimage {
     background-color: black;
 }
 
-#helpdesk-searchResultsGrid {
-    min-height: 400px;
-    height: 60vh;
+.grid.tall {
+    bottom: 10px;
+    height: auto;
+    left: 10px;
+    position: absolute;
+    right: 10px;
+    top: 45px;
+    cursor: pointer;
 }
 
 .checkboxWrapper {
@@ -606,6 +633,10 @@ input[type=search] {
     font-weight: bold;
 }
 
+.searchbar {
+    position: relative; margin-left: auto; margin-right: auto; width: 100%; text-align: center;
+}
+
 .formFieldWrapper {
     padding-bottom: 10px;
 }
@@ -615,6 +646,13 @@ progress:not([value]) {
     height: 20px;
 }
 
+progress[value] {
+    height: 20px;
+    width: 100%;
+    color: orange;
+}
+
+
 .blink { animation: blink 1s steps(5, start) infinite; -webkit-animation: blink 1s steps(5, start) infinite; }
 @keyframes blink { to { visibility: hidden; } }
 @-webkit-keyframes blink { to { visibility: hidden; } }
@@ -652,8 +690,7 @@ dialog .closeIcon { float: right; cursor: pointer; margin-right: 3px; }
 
 /* begin peoplesearch section */
 
-.icon-peoplesearch-orgChart { background-image: url("orgChart.png"); position: absolute; top:5px; right:5px; height:30px; width:30px; cursor: pointer;
-}
+.icon-peoplesearch-orgChart { background-image: url("orgChart.png"); position: absolute; top:5px; right:5px; height:30px; width:30px; cursor: pointer; }
 .panel-peoplesearch-userDetailPhoto { display: inline  }
 .img-peoplesearch-userDetailPhoto { width: 80px; height: 80px; border-radius: 2px; border: 1px solid #d8e2e2; }
 .panel-peoplesearch-person { margin-left:5px; background: #eaeaea; position: relative; padding: 6px; width: auto; height: 83px; margin-right: 5px; margin-bottom: 10px; border:  1px solid transparent; }
@@ -662,27 +699,6 @@ dialog .closeIcon { float: right; cursor: pointer; margin-right: 3px; }
 
 #peopleSearch-userDetailWrapper { max-height: 450px; overflow-y: auto; }
 .peoplesearch-input-username { width:400px; }
-#peoplesearch-searchResultsGrid {
-    bottom: 10px;
-    height: auto;
-    left: 10px;
-    position: absolute;
-    right: 10px;
-    top: 45px;
-    cursor: pointer;
-}
-
-.peoplesearch-wrapper #centerbody.wide {
-    bottom: 80px;
-    height: auto !important;
-    left: 40px;
-    margin: auto;
-    min-width: auto;
-    position: absolute;
-    right: 40px;
-    top: 100px;
-    width: auto;
-}
 
 .peopleSearch-userDetails { max-height: 450px; overflow-y: auto; border: 1px solid #d8e2e2; }
 .peopleSearch-userDetails td.key { font-weight: normal; color: #949494; width: auto; padding: 3px 15px 3px 10px; border-bottom: 1px solid #d8e2e2; }
@@ -714,3 +730,4 @@ dialog .closeIcon { float: right; cursor: pointer; margin-right: 3px; }
 .panel-orgChart-footer {clear: both; margin-bottom: 10px; }
 /* end peoplesearch org chart section */
 
+

+ 12 - 0
pwm/servlet/web/public/resources/themes/pwm/style.css

@@ -101,6 +101,18 @@ h3 {
      background:linear-gradient(to bottom, #B2B1B9 5%, #E8E1F6 100% );
  }
 
+#header-warning {
+    box-shadow: 4px 4px 2px #888888;
+    animation: slideInRight 0.3s;
+    -moz-animation: slideInRight 0.3s; /* Firefox */
+    -webkit-animation: slideInRight 0.3s; /* Safari and Chrome */
+}
+
 .btn-icon {
     opacity:0.75;
 }
+
+
+@keyframes slideInRight { 0% { transform: translate3d(100%, 0, 0); visibility: visible; } 100% { transform: translate3d(0, 0, 0); } }
+@-webkit-keyframes slideInRight { 0% { transform: translate3d(100%, 0, 0); visibility: visible; } 100% { transform: translate3d(0, 0, 0); } }
+@-moz-keyframes slideInRight { 0% { transform: translate3d(100%, 0, 0); visibility: visible; } 100% { transform: translate3d(0, 0, 0); } }