소스 검색

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());
             final ChaiProvider proxiedProvider = getProxyChaiProvider(userIdentity.getLdapProfileID());
             return ChaiFactory.createChaiUser(userIdentity.getUserDN(), proxiedProvider);
             return ChaiFactory.createChaiUser(userIdentity.getUserDN(), proxiedProvider);
         } catch (ChaiUnavailableException e) {
         } 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.Config;
 import password.pwm.i18n.LocaleHelper;
 import password.pwm.i18n.LocaleHelper;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
+import password.pwm.util.macro.MacroMachine;
 
 
 import java.util.*;
 import java.util.*;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
@@ -1028,10 +1029,10 @@ public enum PwmSetting {
     private final PwmSettingCategory category;
     private final PwmSettingCategory category;
     private final Set<Template> templates;
     private final Set<Template> templates;
 
 
+
     private final Map<Template, StoredValue>    CACHE_DEFAULT_VALUES = new HashMap<>();
     private final Map<Template, StoredValue>    CACHE_DEFAULT_VALUES = new HashMap<>();
     private final Map<Locale,String>            CACHE_LABELS = new HashMap<>();
     private final Map<Locale,String>            CACHE_LABELS = new HashMap<>();
 
 
-
 // --------------------------- CONSTRUCTORS ---------------------------
 // --------------------------- CONSTRUCTORS ---------------------------
 
 
     PwmSetting(
     PwmSetting(
@@ -1151,7 +1152,10 @@ public enum PwmSetting {
     public String getDescription(final Locale locale) {
     public String getDescription(final Locale locale) {
         final Element settingElement = PwmSettingXml.readSettingXml(this);
         final Element settingElement = PwmSettingXml.readSettingXml(this);
         final Element descriptionElement = settingElement.getChild("description");
         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) {
     public String getPlaceholder(final Locale locale) {

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

@@ -142,7 +142,19 @@
     </setting>
     </setting>
     <setting key="interface.theme" level="1" required="true">
     <setting key="interface.theme" level="1" required="true">
         <label>Interface Theme</label>
         <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>
         <default>
             <value><![CDATA[pwm]]></value>
             <value><![CDATA[pwm]]></value>
         </default>
         </default>
@@ -310,28 +322,28 @@
     </setting>
     </setting>
     <setting key="display.css.customStyleLocation" level="2">
     <setting key="display.css.customStyleLocation" level="2">
         <label>Custom CSS Stylesheet Location</label>
         <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>
         <default>
             <value><![CDATA[]]></value>
             <value><![CDATA[]]></value>
         </default>
         </default>
     </setting>
     </setting>
     <setting key="display.css.customMobileStyleLocation" level="2">
     <setting key="display.css.customMobileStyleLocation" level="2">
         <label>Custom Mobile CSS Stylesheet Location</label>
         <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>
         <default>
             <value><![CDATA[]]></value>
             <value><![CDATA[]]></value>
         </default>
         </default>
     </setting>
     </setting>
     <setting key="display.css.customStyle" level="2">
     <setting key="display.css.customStyle" level="2">
         <label>Embedded CSS Stylesheet</label>
         <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>
         <default>
             <value />
             <value />
         </default>
         </default>
     </setting>
     </setting>
     <setting key="display.css.customMobileStyle" level="2">
     <setting key="display.css.customMobileStyle" level="2">
         <label>Embedded Mobile CSS Stylesheet</label>
         <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>
         <default>
             <value />
             <value />
         </default>
         </default>
@@ -2007,7 +2019,7 @@
         </default>
         </default>
     </setting>
     </setting>
     <setting key="events.java.stdoutLevel" level="1">
     <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>
         <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>
         <default>
             <value><![CDATA[INFO]]></value>
             <value><![CDATA[INFO]]></value>
@@ -3419,7 +3431,7 @@
         <label>User Detail Display Name</label>
         <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>
         <description><![CDATA[The display name used to identify the user on the user detail screen.  Macros are resolved to the displayed user.]]></description>
         <default>
         <default>
-            <value>@User:ID@ - @User:Email@</value>
+            <value>@LDAP:givenName@ @LDAP:sn@ - @User:ID@ - @User:Email@</value>
         </default>
         </default>
     </setting>
     </setting>
     <setting key="helpdesk.profile.list" level="1" hidden="true">
     <setting key="helpdesk.profile.list" level="1" hidden="true">
@@ -4084,7 +4096,7 @@
     </category>
     </category>
     <category key="SMS">
     <category key="SMS">
         <label>SMS</label>
         <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>
     <category key="SMS_GATEWAY">
     <category key="SMS_GATEWAY">
         <label>SMS Gateway</label>
         <label>SMS Gateway</label>

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

@@ -23,6 +23,9 @@
 package password.pwm.error;
 package password.pwm.error;
 
 
 
 
+import com.novell.ldapchai.exception.ChaiException;
+import com.novell.ldapchai.exception.ChaiUnavailableException;
+
 /**
 /**
  * A general exception thrown by PWM.
  * A general exception thrown by PWM.
  */
  */
@@ -39,5 +42,15 @@ public class PwmUnrecoverableException extends PwmException {
     public PwmUnrecoverableException(final PwmError error) {
     public PwmUnrecoverableException(final PwmError error) {
         super(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();
             final ChaiProvider provider = this.getChaiProvider();
             return ChaiFactory.createChaiUser(userIdentity.getUserDN(), provider);
             return ChaiFactory.createChaiUser(userIdentity.getUserDN(), provider);
         } catch (ChaiUnavailableException e) {
         } 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) {
         } catch (ChaiException e) {
             LOGGER.error("unexpected error during detail lookup of '" + userIdentity + "', error: " + e.getMessage());
             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());
             LOGGER.error(pwmRequest, "error generating user detail object: " + e.getMessage());
             pwmRequest.respondWithError(e.getErrorInformation());
             pwmRequest.respondWithError(e.getErrorInformation());
         } catch (ChaiUnavailableException e) {
         } 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;
                 return null;
             }
             }
         } catch (ChaiUnavailableException e) {
         } catch (ChaiUnavailableException e) {
-            throw new PwmUnrecoverableException(PwmError.forChaiError(e.getErrorCode()));
+            throw PwmUnrecoverableException.fromChaiException(e);
         }
         }
 
 
         return "PeopleSearch?processAction=photo&userKey=" + userIdentity.toObfuscatedKey(pwmApplication.getConfig());
         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_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_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_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_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_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.
 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;
 package password.pwm.util.macro;
 
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 public abstract class AbstractMacro implements MacroImplementation {
 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() {
     public AbstractMacro() {
     }
     }
 
 
@@ -30,4 +38,29 @@ public abstract class AbstractMacro implements MacroImplementation {
     public boolean isSensitive() {
     public boolean isSensitive() {
         return false;
         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.PwmConstants;
 import password.pwm.bean.UserInfoBean;
 import password.pwm.bean.UserInfoBean;
+import password.pwm.config.PwmSetting;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -40,6 +41,7 @@ public abstract class InternalMacros {
         final List<Class<? extends MacroImplementation>> defaultMacros = new ArrayList<>();
         final List<Class<? extends MacroImplementation>> defaultMacros = new ArrayList<>();
         defaultMacros.add(OtpSetupTimeMacro.class);
         defaultMacros.add(OtpSetupTimeMacro.class);
         defaultMacros.add(ResponseSetupTimeMacro.class);
         defaultMacros.add(ResponseSetupTimeMacro.class);
+        defaultMacros.add(PwmSettingReference.class);
         INTERNAL_MACROS = Collections.unmodifiableList(defaultMacros);
         INTERNAL_MACROS = Collections.unmodifiableList(defaultMacros);
     }
     }
 
 
@@ -76,4 +78,26 @@ public abstract class InternalMacros {
             return null;
             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;
         int iteration = 0;
         for (final String url : externalMethods) {
         for (final String url : externalMethods) {
@@ -177,7 +179,11 @@ public class MacroMachine {
             replaceStr = macroImplementation.replaceValue(matchedStr, macroRequestInfo);
             replaceStr = macroImplementation.replaceValue(matchedStr, macroRequestInfo);
         } catch (MacroParseException e) {
         } catch (MacroParseException e) {
             LOGGER.debug(sessionLabel, "macro parse error replacing macro '" + matchedStr + "', error: " + e.getMessage());
             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) {
         }  catch (Exception e) {
             LOGGER.error(sessionLabel, "error while replacing macro '" + matchedStr + "', error: " + e.getMessage());
             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();
         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 static interface StringReplacer {
         public String replace(final String matchedMacro, final String newValue);
         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 {
 public abstract class StandardMacros {
     private static final PwmLogger LOGGER = PwmLogger.forClass(StandardMacros.class);
     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;
     public static final List<Class<? extends MacroImplementation>> STANDARD_MACROS;
     static {
     static {
         final List<Class<? extends MacroImplementation>> defaultMacros = new ArrayList<>();
         final List<Class<? extends MacroImplementation>> defaultMacros = new ArrayList<>();
@@ -74,30 +70,6 @@ public abstract class StandardMacros {
         STANDARD_MACROS = Collections.unmodifiableList(defaultMacros);
         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 {
     public static class LdapMacro extends AbstractMacro {
         private static final Pattern PATTERN = Pattern.compile("@LDAP" + PATTERN_OPTIONAL_PARAMETER_MATCH + "@");
         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:[^:]+:\\[\\[.*\\]\\]@");
         private static final Pattern PATTERN = Pattern.compile("@Encode:[^:]+:\\[\\[.*\\]\\]@");
         // @Encode:ENCODE_TYPE:value@
         // @Encode:ENCODE_TYPE:value@
 
 
-        private static enum ENCODE_TYPE {
+        private enum ENCODE_TYPE {
             urlPath,
             urlPath,
             urlParameter,
             urlParameter,
             base64,
             base64,

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

@@ -51,8 +51,9 @@ public class ActionExecutor {
     private PwmApplication pwmApplication;
     private PwmApplication pwmApplication;
     private ActionExecutorSettings settings;
     private ActionExecutorSettings settings;
 
 
-    private ActionExecutor(PwmApplication pwmApplication) {
+    private ActionExecutor(final PwmApplication pwmApplication, final ActionExecutorSettings settings) {
         this.pwmApplication = pwmApplication;
         this.pwmApplication = pwmApplication;
+        this.settings = settings;
     }
     }
 
 
     public void executeActions(
     public void executeActions(
@@ -298,7 +299,7 @@ public class ActionExecutor {
         }
         }
 
 
         public ActionExecutor createActionExecutor() {
         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());
             final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers());
             reportStatus.setTotal(allUsers.size());
             reportStatus.setTotal(allUsers.size());
             while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) {
             while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) {
-                final long startUpdateTime = System.currentTimeMillis();
+                final Date startUpdateTime = new Date();
                 final UserIdentity userIdentity = allUsers.poll();
                 final UserIdentity userIdentity = allUsers.poll();
                 try {
                 try {
                     if (updateCache(userIdentity)) {
                     if (updateCache(userIdentity)) {
@@ -256,9 +256,9 @@ public class ReportService implements PwmService {
                 }
                 }
                 reportStatus.setCount(reportStatus.getCount() + 1);
                 reportStatus.setCount(reportStatus.getCount() + 1);
                 reportStatus.getEventRateMeter().markEvents(1);
                 reportStatus.getEventRateMeter().markEvents(1);
-                final long totalUpdateTime = System.currentTimeMillis() - startUpdateTime;
+                final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime);
                 if (settings.isAutoCalcRest()) {
                 if (settings.isAutoCalcRest()) {
-                    avgTracker.addSample(totalUpdateTime);
+                    avgTracker.addSample(totalUpdateTime.getTotalMilliseconds());
                     Helper.pause(avgTracker.avgAsLong());
                     Helper.pause(avgTracker.avgAsLong());
                 } else {
                 } else {
                     Helper.pause(settings.getRestTime().getTotalMilliseconds());
                     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);
                 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();
             RestResultBean resultBean = new RestResultBean();
             resultBean.setError(false);
             resultBean.setError(false);
             resultBean.setSuccessMessage(successMsg);
             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" %>
         <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
         <p><pwm:display key="Display_PleaseWaitPassword"/></p>
         <p><pwm:display key="Display_PleaseWaitPassword"/></p>
         <div class="meteredProgressBar">
         <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>
         <div style="text-align: center; width: 100%; padding-top: 50px">
         <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 showButtons = !pwmRequest.isFlag(PwmRequest.Flag.HIDE_HEADER_BUTTONS) && !pwmRequest.isForcedPageView();
         final boolean loggedIn = pwmRequest.isAuthenticated();
         final boolean loggedIn = pwmRequest.isAuthenticated();
         if (showButtons && loggedIn) {
         if (showButtons && loggedIn) {
-            showLogout = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_LOGOUT_BUTTON);
             showHome = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_HOME_BUTTON);
             showHome = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_HOME_BUTTON);
         }
         }
+        if (loggedIn) {
+            showLogout = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_LOGOUT_BUTTON);
+        }
     } catch (PwmUnrecoverableException e) {
     } catch (PwmUnrecoverableException e) {
         /* application must be unavailable */
         /* application must be unavailable */
     }
     }

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

@@ -60,7 +60,20 @@
     </script>
     </script>
 </pwm:script>
 </pwm:script>
 <div id="header-warning" style="display: none">
 <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">
         <a class="header-warning-button" id="header_configManagerButton">
             <pwm:if test="showIcons"><span class="btn-icon fa fa-gears"></span></pwm:if>
             <pwm:if test="showIcons"><span class="btn-icon fa fa-gears"></span></pwm:if>
             <pwm:display key="MenuItem_ConfigManager" bundle="Admin"/>
             <pwm:display key="MenuItem_ConfigManager" bundle="Admin"/>
@@ -82,26 +95,12 @@
         </a>
         </a>
         <% } %>
         <% } %>
     </div>
     </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) { %>
     <% if (includeHeader) { %>
     <div id="button-closeHeader">
     <div id="button-closeHeader">
         <span class="fa fa-chevron-circle-right"></span>
         <span class="fa fa-chevron-circle-right"></span>
     </div>
     </div>
     <% } %>
     <% } %>
-    <br/>
-    <%=PwmConstants.PWM_APP_NAME_VERSION%>
 </div>
 </div>
 <% if (includeHeader) { %>
 <% if (includeHeader) { %>
 <div id="button-openHeader">
 <div id="button-openHeader">

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

@@ -528,11 +528,7 @@
                             <script type="text/javascript">
                             <script type="text/javascript">
                                 PWM_GLOBAL['startupFunctions'].push(function(){
                                 PWM_GLOBAL['startupFunctions'].push(function(){
                                     PWM_MAIN.addEventHandler('button_refresh','click',function(){
                                     PWM_MAIN.addEventHandler('button_refresh','click',function(){
-                                        PWM_MAIN.showWaitDialog({loadFunction:function(){
-                                            setTimeout(function(){
-                                                document.continueForm.submit();
-                                            },1000);
-                                        }});
+                                        PWM_HELPDESK.refreshDetailPage();
                                     });
                                     });
                                 });
                                 });
                             </script>
                             </script>
@@ -745,7 +741,7 @@
         }
         }
 
 
         PWM_GLOBAL['startupFunctions'].push(function(){
         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();
                 dojoParser.parse();
                 PWM_VAR['helpdesk_obfuscatedDN'] = '<%=StringUtil.escapeJS(obfuscatedDN)%>';
                 PWM_VAR['helpdesk_obfuscatedDN'] = '<%=StringUtil.escapeJS(obfuscatedDN)%>';
                 PWM_VAR['helpdesk_username'] = '<%=StringUtil.escapeJS(searchedUserInfo.getUsername())%>';
                 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:include page="/WEB-INF/jsp/fragment/header-body.jsp">
         <jsp:param name="pwm.PageName" value="Title_Helpdesk"/>
         <jsp:param name="pwm.PageName" value="Title_Helpdesk"/>
     </jsp:include>
     </jsp:include>
-    <div id="centerbody" class="wide">
+    <div id="centerbody" class="wide tall">
         <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
         <%@ 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" >
             <table class="noborder" style="margin-left: auto; margin-right: auto; width:100px; table-layout: fixed" >
                 <tr>
                 <tr>
                     <td style="width:15px">
                     <td style="width:15px">
@@ -62,7 +61,7 @@
             </noscript>
             </noscript>
             <br/>
             <br/>
         </div>
         </div>
-        <div id="helpdesk-searchResultsGrid" class="grid">
+        <div id="helpdesk-searchResultsGrid" class="grid tall">
         </div>
         </div>
     </div>
     </div>
     <div class="push"></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>
         <p><pwm:display key="Display_PleaseWaitNewUser"/></p>
         <%@ include file="fragment/message.jsp" %>
         <%@ include file="fragment/message.jsp" %>
         <div class="meteredProgressBar">
         <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>
         <div style="text-align: center; width: 100%; padding-top: 50px">
         <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:include page="/WEB-INF/jsp/fragment/header-body.jsp">
         <jsp:param name="pwm.PageName" value="Title_PeopleSearch"/>
         <jsp:param name="pwm.PageName" value="Title_PeopleSearch"/>
     </jsp:include>
     </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" %>
         <%@ 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;" >
             <table class="noborder" style="margin-left: auto; margin-right: auto; width:100px;" >
                 <tr>
                 <tr>
                     <td style="width:5%">
                     <td style="width:5%">
@@ -60,7 +59,7 @@
             </noscript>
             </noscript>
         </div>
         </div>
         <br/>
         <br/>
-        <div id="peoplesearch-searchResultsGrid" class="grid">
+        <div id="peoplesearch-searchResultsGrid" class="grid tall">
         </div>
         </div>
     </div>
     </div>
     <div class="push"></div>
     <div class="push"></div>

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

@@ -35,7 +35,7 @@
 %>
 %>
 <html dir="<pwm:LocaleOrientation/>">
 <html dir="<pwm:LocaleOrientation/>">
 <%@ include file="../WEB-INF/jsp/fragment/header.jsp" %>
 <%@ include file="../WEB-INF/jsp/fragment/header.jsp" %>
-<body>
+<body class="nihilo">
 <div id="wrapper">
 <div id="wrapper">
     <jsp:include page="../WEB-INF/jsp/fragment/header-body.jsp">
     <jsp:include page="../WEB-INF/jsp/fragment/header-body.jsp">
         <jsp:param name="pwm.PageName" value="Title_MainPage"/>
         <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 displayStringsUrl = "ChangePassword?processAction=checkProgress";
         var completedUrl = "ChangePassword?processAction=complete&pwmFormID=" + PWM_GLOBAL['pwmFormID'];
         var completedUrl = "ChangePassword?processAction=complete&pwmFormID=" + PWM_GLOBAL['pwmFormID'];
         var loadFunction = function(data) {
         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 {
             try {
                 var tableBody = '';
                 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 (PWM_MAIN.getObject('panel-' + keyName + '-modifyTime')) {
         if (data['data']['modifyTime']) {
         if (data['data']['modifyTime']) {
             PWM_MAIN.getObject('panel-' + keyName + '-modifyTime').innerHTML = 'Last Modified '
             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'));
             PWM_MAIN.TimestampHandler.initElement(PWM_MAIN.getObject('panel-' + keyName + '-modifyTimestamp'));
         } else {
         } else {
             PWM_MAIN.getObject('panel-' + keyName + '-modifyTime').innerHTML = '';
             PWM_MAIN.getObject('panel-' + keyName + '-modifyTime').innerHTML = '';
@@ -510,8 +510,27 @@ PWM_CFGEDIT.processSettingSearch = function(destinationDiv) {
 PWM_CFGEDIT.gotoSetting = function(category,settingKey,profile) {
 PWM_CFGEDIT.gotoSetting = function(category,settingKey,profile) {
     console.log('going to setting... category=' + category + " settingKey=" + settingKey + " profile=" + 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;
         return;
     }
     }
 
 
@@ -722,12 +741,23 @@ PWM_CFGEDIT.selectTemplate = function(newTemplate) {
 PWM_CFGEDIT.loadMainPageBody = function() {
 PWM_CFGEDIT.loadMainPageBody = function() {
 
 
     PWM_CFGEDIT.drawNavigationMenu();
     PWM_CFGEDIT.drawNavigationMenu();
+
     var storedPreferences = PWM_MAIN.readLocalStorage();
     var storedPreferences = PWM_MAIN.readLocalStorage();
-    if (storedPreferences['lastSelected']) {
-        PWM_CFGEDIT.dispatchNavigationItem(storedPreferences['lastSelected']);
+    if (storedPreferences['configeditor-lastSelected']) {
+        PWM_CFGEDIT.dispatchNavigationItem(storedPreferences['configeditor-lastSelected']);
     } else {
     } else {
         PWM_CFGEDIT.drawHomePage();
         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) {
 PWM_CFGEDIT.displaySettingsCategory = function(category) {
@@ -744,16 +774,16 @@ PWM_CFGEDIT.displaySettingsCategory = function(category) {
 
 
     if (category == 'LDAP_PROFILE') {
     if (category == 'LDAP_PROFILE') {
         htmlSettingBody += '<div style="width: 100%; text-align: center">'
         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') {
     } else if (category == 'DATABASE') {
         htmlSettingBody += '<div style="width: 100%; text-align: center">'
         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') {
     } else if (category == 'SMS_GATEWAY') {
         htmlSettingBody += '<div style="width: 100%; text-align: center">'
         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;
     PWM_VAR['skippedSettingCount'] = 0;
@@ -783,6 +813,7 @@ PWM_CFGEDIT.displaySettingsCategory = function(category) {
     } else if (category == 'SMS_GATEWAY') {
     } else if (category == 'SMS_GATEWAY') {
         PWM_MAIN.addEventHandler('button-test-SMS', 'click', function(){PWM_CFGEDIT.smsHealthCheck();});
         PWM_MAIN.addEventHandler('button-test-SMS', 'click', function(){PWM_CFGEDIT.smsHealthCheck();});
     }
     }
+    PWM_CFGEDIT.applyGotoSettingHandlers();
 };
 };
 
 
 PWM_CFGEDIT.drawProfileEditorPage = function(settingKey) {
 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>'
     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']) {
     if (settingInfo['description']) {
         var prefs = PWM_MAIN.readLocalStorage();
         var prefs = PWM_MAIN.readLocalStorage();
         var expandHelp = 'helpExpanded' in prefs && settingKey in prefs['helpExpanded'];
         var expandHelp = 'helpExpanded' in prefs && settingKey in prefs['helpExpanded'];
         htmlBody += '<div class="pane-help" id="pane-help-' + settingKey + '" style="display:' + (expandHelp ? 'inherit' : 'none') + '">'
         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">'
     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;
     return htmlBody;
 };
 };
@@ -980,7 +1011,7 @@ PWM_CFGEDIT.drawNavigationMenu = function() {
                     id: 'navigationTree',
                     id: 'navigationTree',
                     onClick: function(item){
                     onClick: function(item){
                         var storedPreferences = PWM_MAIN.readLocalStorage();
                         var storedPreferences = PWM_MAIN.readLocalStorage();
-                        storedPreferences['lastSelected'] = item;
+                        storedPreferences['configeditor-lastSelected'] = item;
                         PWM_MAIN.writeLocalStorage(storedPreferences);
                         PWM_MAIN.writeLocalStorage(storedPreferences);
                         PWM_CFGEDIT.dispatchNavigationItem(item);
                         PWM_CFGEDIT.dispatchNavigationItem(item);
                     }
                     }
@@ -1051,7 +1082,7 @@ PWM_CFGEDIT.drawDisplayTextPage = function(settingKey, keys) {
     var settingsPanel = PWM_MAIN.getObject('settingsPanel');
     var settingsPanel = PWM_MAIN.getObject('settingsPanel');
     var remainingLoads = keys.length;
     var remainingLoads = keys.length;
     settingsPanel.innerHTML = '<div id="displaytext-loading-panel" style="width:100%; text-align: center">'
     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);
     console.log('drawing displaytext-editor for setting-' + settingKey);
     var htmlBody = '<div id="localetext-editor-wrapper" style="display:none">';
     var htmlBody = '<div id="localetext-editor-wrapper" style="display:none">';
     for (var key in keys) {
     for (var key in keys) {
@@ -1062,7 +1093,7 @@ PWM_CFGEDIT.drawDisplayTextPage = function(settingKey, keys) {
         htmlBody += PWM_CFGEDIT.drawHtmlOutlineForSetting(settingInfo,{showHelp:false});
         htmlBody += PWM_CFGEDIT.drawHtmlOutlineForSetting(settingInfo,{showHelp:false});
     }
     }
     settingsPanel.innerHTML = settingsPanel.innerHTML + htmlBody;
     settingsPanel.innerHTML = settingsPanel.innerHTML + htmlBody;
-    
+
     var initSetting = function(keyCounter) {
     var initSetting = function(keyCounter) {
         if (PWM_VAR['outstandingOperations'] > 5) {
         if (PWM_VAR['outstandingOperations'] > 5) {
             setTimeout(function () { initSetting(keyCounter); }, 50);
             setTimeout(function () { initSetting(keyCounter); }, 50);
@@ -1078,7 +1109,7 @@ PWM_CFGEDIT.drawDisplayTextPage = function(settingKey, keys) {
         remainingLoads--;
         remainingLoads--;
         PWM_MAIN.getObject('remainingCount').innerHTML = remainingLoads > 0 ? remainingLoads : '';
         PWM_MAIN.getObject('remainingCount').innerHTML = remainingLoads > 0 ? remainingLoads : '';
     };
     };
-    
+
     var delay = 5;
     var delay = 5;
     for (var key in keys) {
     for (var key in keys) {
         (function(keyCounter) {
         (function(keyCounter) {
@@ -1255,4 +1286,13 @@ PWM_CFGEDIT.setCurrentProfile = function(profile) {
     } else {
     } else {
         delete PWM_VAR['currentProfile'];
         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();
     PWM_CONFIG.showHeaderHealth();
 
 
     var prefs = PWM_MAIN.readLocalStorage();
     var prefs = PWM_MAIN.readLocalStorage();
-    if (prefs['headerVisibility'] == 'show') {
+    if (prefs['headerVisibility'] != 'hide') {
         PWM_CONFIG.openHeaderWarningPanel();
         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() {
 PWM_HELPDESK.doResponseClear = function() {
     var username = PWM_VAR['helpdesk_obfuscatedDN'];
     var username = PWM_VAR['helpdesk_obfuscatedDN'];
     PWM_MAIN.showWaitDialog({loadFunction:function() {
     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) {
         var loadFunction = function(results) {
             if (results['error'] != true) {
             if (results['error'] != true) {
                 PWM_MAIN.showDialog({
                 PWM_MAIN.showDialog({
                     title: PWM_MAIN.showString('Button_ClearResponses'),
                     title: PWM_MAIN.showString('Button_ClearResponses'),
-                    text: results['successMessage']
+                    text: results['successMessage'],
+                    okAction:function(){
+                        PWM_HELPDESK.refreshDetailPage();
+                    }
                 });
                 });
             } else {
             } else {
                 PWM_MAIN.showErrorDialog(results);
                 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();
 PWM_HELPDESK.initPage();

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

@@ -1957,27 +1957,53 @@ PWM_MAIN.clearFocus = function() {
     document.activeElement.blur();
     document.activeElement.blur();
 };
 };
 
 
+PWM_MAIN.prefsValues = {
+    attrTimestamp:"ClientPreferencesTimestamp",
+    attrPrefs:"ClientPreferences",
+    persistanceTime:(24 * 60 * 60 * 1000)
+};
+
 PWM_MAIN.readLocalStorage = function() {
 PWM_MAIN.readLocalStorage = function() {
     if(typeof(Storage) !== "undefined") {
     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 {
     } else {
         console.log("browser doesn't support local storage");
         console.log("browser doesn't support local storage");
     }
     }
+    return {};
 };
 };
 
 
 PWM_MAIN.writeLocalStorage = function(dataUpdate) {
 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'],
             timeout: PWM_GLOBAL['client.ajaxTypingTimeout'],
             headers: { "Accept": "application/json" },
             headers: { "Accept": "application/json" },
             load: function(data) {
             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) {
                 if (data['data']['complete'] == true) {
                     PWM_MAIN.goto(completedUrl,{delay:1000})
                     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;
     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 */
 /* all forms use a buttonbar div containing the action buttons */
 .buttonbar {
 .buttonbar {
     margin-top: 30px;
     margin-top: 30px;
@@ -349,14 +362,23 @@ div.progress-container > div {
     position: absolute;
     position: absolute;
     right:6px;
     right:6px;
     top:6px;
     top:6px;
-    width: 190px;
+    width: 200px;
     border: 2px solid #aaaaaa;
     border: 2px solid #aaaaaa;
     background-color: #DDDDDD;
     background-color: #DDDDDD;
     z-index: 10;
     z-index: 10;
     padding: 10px;
     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 {
 .header-warning-buttons {
@@ -525,9 +547,14 @@ img.qrcodeimage {
     background-color: black;
     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 {
 .checkboxWrapper {
@@ -606,6 +633,10 @@ input[type=search] {
     font-weight: bold;
     font-weight: bold;
 }
 }
 
 
+.searchbar {
+    position: relative; margin-left: auto; margin-right: auto; width: 100%; text-align: center;
+}
+
 .formFieldWrapper {
 .formFieldWrapper {
     padding-bottom: 10px;
     padding-bottom: 10px;
 }
 }
@@ -615,6 +646,13 @@ progress:not([value]) {
     height: 20px;
     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; }
 .blink { animation: blink 1s steps(5, start) infinite; -webkit-animation: blink 1s steps(5, start) infinite; }
 @keyframes blink { to { visibility: hidden; } }
 @keyframes blink { to { visibility: hidden; } }
 @-webkit-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 */
 /* 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  }
 .panel-peoplesearch-userDetailPhoto { display: inline  }
 .img-peoplesearch-userDetailPhoto { width: 80px; height: 80px; border-radius: 2px; border: 1px solid #d8e2e2; }
 .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; }
 .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-userDetailWrapper { max-height: 450px; overflow-y: auto; }
 .peoplesearch-input-username { width:400px; }
 .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 { 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; }
 .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; }
 .panel-orgChart-footer {clear: both; margin-bottom: 10px; }
 /* end peoplesearch org chart section */
 /* 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% );
      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 {
 .btn-icon {
     opacity:0.75;
     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); } }