소스 검색

captcha refactoring and improvements

jrivard@gmail.com 6 년 전
부모
커밋
2c6db444af

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/LoginServlet.java

@@ -210,7 +210,7 @@ public class LoginServlet extends ControlledPwmServlet
                 : null;
                 : null;
         final String context = valueMap.get( PwmConstants.PARAM_CONTEXT );
         final String context = valueMap.get( PwmConstants.PARAM_CONTEXT );
         final String ldapProfile = valueMap.get( PwmConstants.PARAM_LDAP_PROFILE );
         final String ldapProfile = valueMap.get( PwmConstants.PARAM_LDAP_PROFILE );
-        final String recaptchaResponse = valueMap.get( "g-recaptcha-response" );
+        final String recaptchaResponse = valueMap.get( CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME );
 
 
 
 
         if ( !passwordOnly && ( username == null || username.isEmpty() ) )
         if ( !passwordOnly && ( username == null || username.isEmpty() ) )

+ 11 - 8
server/src/main/java/password/pwm/util/CaptchaUtility.java

@@ -67,6 +67,8 @@ public class CaptchaUtility
 
 
     private static final String COOKIE_SKIP_INSTANCE_VALUE = "INSTANCEID";
     private static final String COOKIE_SKIP_INSTANCE_VALUE = "INSTANCEID";
 
 
+    public static final String PARAM_RECAPTCHA_FORM_NAME = "g-recaptcha-response";
+
     public enum CaptchaMode
     public enum CaptchaMode
     {
     {
         V3,
         V3,
@@ -91,7 +93,7 @@ public class CaptchaUtility
     )
     )
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException
     {
     {
-        final String recaptchaResponse = pwmRequest.readParameterAsString( "g-recaptcha-response" );
+        final String recaptchaResponse = pwmRequest.readParameterAsString( PARAM_RECAPTCHA_FORM_NAME );
         return verifyReCaptcha( pwmRequest, recaptchaResponse );
         return verifyReCaptcha( pwmRequest, recaptchaResponse );
     }
     }
 
 
@@ -116,19 +118,18 @@ public class CaptchaUtility
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PasswordData privateKey = pwmApplication.getConfig().readSettingAsPassword( PwmSetting.RECAPTCHA_KEY_PRIVATE );
         final PasswordData privateKey = pwmApplication.getConfig().readSettingAsPassword( PwmSetting.RECAPTCHA_KEY_PRIVATE );
 
 
-        final StringBuilder bodyText = new StringBuilder();
-        bodyText.append( "secret=" ).append( privateKey.getStringValue() );
-        bodyText.append( "&" );
-        bodyText.append( "remoteip=" ).append( pwmRequest.getSessionLabel().getSrcAddress() );
-        bodyText.append( "&" );
-        bodyText.append( "response=" ).append( recaptchaResponse );
+        final String bodyText = "secret=" + StringUtil.urlEncode( privateKey.getStringValue() )
+                        + "&"
+                        + "remoteip=" + StringUtil.urlEncode( pwmRequest.getSessionLabel().getSrcAddress() )
+                        + "&"
+                        + "response=" + StringUtil.urlEncode( recaptchaResponse );
 
 
         try
         try
         {
         {
             final PwmHttpClientRequest clientRequest = new PwmHttpClientRequest(
             final PwmHttpClientRequest clientRequest = new PwmHttpClientRequest(
                     HttpMethod.POST,
                     HttpMethod.POST,
                     pwmApplication.getConfig().readAppProperty( AppProperty.RECAPTCHA_VALIDATE_URL ),
                     pwmApplication.getConfig().readAppProperty( AppProperty.RECAPTCHA_VALIDATE_URL ),
-                    bodyText.toString(),
+                    bodyText,
                     Collections.singletonMap( "Content-Type", HttpContentType.form.getHeaderValue() )
                     Collections.singletonMap( "Content-Type", HttpContentType.form.getHeaderValue() )
             );
             );
             LOGGER.debug( pwmRequest, "sending reCaptcha verification request" );
             LOGGER.debug( pwmRequest, "sending reCaptcha verification request" );
@@ -151,6 +152,7 @@ public class CaptchaUtility
                 if ( success )
                 if ( success )
                 {
                 {
                     writeCaptchaSkipCookie( pwmRequest );
                     writeCaptchaSkipCookie( pwmRequest );
+                    LOGGER.trace( pwmRequest, "captcha verification passed" );
                     return true;
                     return true;
                 }
                 }
 
 
@@ -176,6 +178,7 @@ public class CaptchaUtility
             throw pwmE;
             throw pwmE;
         }
         }
 
 
+        LOGGER.trace( pwmRequest, "captcha verification failed" );
         return false;
         return false;
     }
     }
 
 

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

@@ -43,7 +43,7 @@
             <%@ include file="/WEB-INF/jsp/fragment/captcha-embed.jsp"%>
             <%@ include file="/WEB-INF/jsp/fragment/captcha-embed.jsp"%>
 
 
             <div class="buttonbar">
             <div class="buttonbar">
-                <button type="submit" name="button" class="btn" id="submitBtn">
+                <button type="submit" name="button" class="btn pwm-btn-submit" id="submitBtn">
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-forward"></span></pwm:if>
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-forward"></span></pwm:if>
                     <pwm:display key="Button_Activate"/>
                     <pwm:display key="Button_Activate"/>
                 </button>
                 </button>

+ 1 - 1
webapp/src/main/webapp/WEB-INF/jsp/forgottenpassword-search.jsp

@@ -47,7 +47,7 @@
 
 
             <div class="buttonbar">
             <div class="buttonbar">
                 <input type="hidden" name="processAction" value="<%=ForgottenPasswordServlet.ForgottenPasswordAction.search%>"/>
                 <input type="hidden" name="processAction" value="<%=ForgottenPasswordServlet.ForgottenPasswordAction.search%>"/>
-                <button type="submit" class="btn" name="search" id="submitBtn">
+                <button type="submit" class="btn pwm-btn-submit" name="search" id="submitBtn">
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-search"></span></pwm:if>
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-search"></span></pwm:if>
                     <pwm:display key="Button_Search"/>
                     <pwm:display key="Button_Search"/>
                 </button>
                 </button>

+ 1 - 1
webapp/src/main/webapp/WEB-INF/jsp/forgottenusername-search.jsp

@@ -45,7 +45,7 @@
 
 
             <div class="buttonbar">
             <div class="buttonbar">
                 <input type="hidden" name="processAction" value="search"/>
                 <input type="hidden" name="processAction" value="search"/>
-                <button type="submit" class="btn" name="search" id="submitBtn">
+                <button type="submit" class="btn pwm-btn-submit" name="search" id="submitBtn">
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-search"></span></pwm:if>
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-search"></span></pwm:if>
                     <pwm:display key="Button_Search"/>
                     <pwm:display key="Button_Search"/>
                 </button>
                 </button>

+ 18 - 8
webapp/src/main/webapp/WEB-INF/jsp/fragment/captcha-embed.jsp

@@ -40,8 +40,14 @@
 <pwm:script>
 <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
         function onloadCallback() {
         function onloadCallback() {
+            PWM_MAIN.doQuery('.pwm-btn-submit',function(submitButton) {
+                submitButton.disabled = true;
+            });
             var recaptchaCallback = function() {
             var recaptchaCallback = function() {
                 console.log('captcha completed, passed');
                 console.log('captcha completed, passed');
+                PWM_MAIN.doQuery('.pwm-btn-submit',function(submitButton) {
+                    submitButton.disabled = false;
+                });
             };
             };
 
 
             console.log('reached google recaptcha onload callback');
             console.log('reached google recaptcha onload callback');
@@ -53,30 +59,34 @@
 <% } %>
 <% } %>
 <% if ( captchaMode == CaptchaUtility.CaptchaMode.V3_INVISIBLE ) { %>
 <% if ( captchaMode == CaptchaUtility.CaptchaMode.V3_INVISIBLE ) { %>
 <!-- captcha v3-invisible 1.0 -->
 <!-- captcha v3-invisible 1.0 -->
-<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response"/>
+<input type="hidden" name="<%=CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME%>" id="<%=CaptchaUtility.PARAM_RECAPTCHA_FORM_NAME%>"/>
 <pwm:script>
 <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
         PWM_GLOBAL['startupFunctions'].push(function() {
         PWM_GLOBAL['startupFunctions'].push(function() {
             PWM_MAIN.doQuery('.pwm-form-captcha',function(formElement) {
             PWM_MAIN.doQuery('.pwm-form-captcha',function(formElement) {
                 PWM_MAIN.addEventHandler(formElement, "submit", function(event){
                 PWM_MAIN.addEventHandler(formElement, "submit", function(event){
-                    console.log('entering handleCaptchaFormSubmit');
-
+                    PWM_MAIN.log('entering handleCaptchaFormSubmit');
                     PWM_VAR['captcha-form-element'] = formElement;
                     PWM_VAR['captcha-form-element'] = formElement;
                     PWM_MAIN.cancelEvent(event);
                     PWM_MAIN.cancelEvent(event);
 
 
-                    grecaptcha.execute();
+                    PWM_MAIN.showWaitDialog({loadFunction: function () {
+                            try {
+                                grecaptcha.execute();
+                            } catch (e) {
+                                PWM_MAIN.log('error executing invisible recaptcha: ' + e);
+                                PWM_FORM.handleFormSubmit(formElement);
+                            }
+                    }});
                 });
                 });
             });
             });
-
-
         });
         });
 
 
         var onloadCaptcha = function() {
         var onloadCaptcha = function() {
-            console.log('entering onloadCaptcha');
+            PWM_MAIN.log('entering onloadCaptcha');
         };
         };
 
 
         var postCaptchaFormSubmit = function(response) {
         var postCaptchaFormSubmit = function(response) {
-            console.log('entering postCaptchaFormSubmit, response=' + response);
+            PWM_MAIN.log('entering postCaptchaFormSubmit, response=' + response);
             var form = PWM_VAR['captcha-form-element'];
             var form = PWM_VAR['captcha-form-element'];
             PWM_MAIN.getObject('g-recaptcha-response').value = response;
             PWM_MAIN.getObject('g-recaptcha-response').value = response;
             PWM_MAIN.handleFormSubmit(form);
             PWM_MAIN.handleFormSubmit(form);

+ 14 - 2
webapp/src/main/webapp/WEB-INF/jsp/login.jsp

@@ -62,7 +62,7 @@
                 </div>
                 </div>
                 <%@ include file="/WEB-INF/jsp/fragment/captcha-embed.jsp"%>
                 <%@ include file="/WEB-INF/jsp/fragment/captcha-embed.jsp"%>
                 <div class="buttonbar">
                 <div class="buttonbar">
-                    <button type="submit" class="btn" <pwm:autofocus/> name="button" id="submitBtn">
+                    <button type="submit" class="btn pwm-btn-submit" <pwm:autofocus/> name="button" id="submitBtn">
                         <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-sign-in"></span></pwm:if>
                         <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-sign-in"></span></pwm:if>
                         <pwm:display key="Button_Login"/>
                         <pwm:display key="Button_Login"/>
                     </button>
                     </button>
@@ -168,7 +168,19 @@
 <pwm:if test="<%=PwmIfTest.forwardUrlDefined%>">
 <pwm:if test="<%=PwmIfTest.forwardUrlDefined%>">
     <%@ include file="/WEB-INF/jsp/fragment/cancel-form.jsp" %>
     <%@ include file="/WEB-INF/jsp/fragment/cancel-form.jsp" %>
 </pwm:if>
 </pwm:if>
-<% if (!CaptchaUtility.captchaEnabledForRequest(JspUtility.getPwmRequest(pageContext))) { %>
+<% if (CaptchaUtility.captchaEnabledForRequest(JspUtility.getPwmRequest(pageContext))) { %>
+<% if (CaptchaUtility.readCaptchaMode( JspUtility.getPwmRequest( pageContext ) ) == CaptchaUtility.CaptchaMode.V3 ) { %>
+<pwm:script>
+    <script type="text/javascript">
+        PWM_GLOBAL['startupFunctions'].push(function(){
+            PWM_MAIN.addEventHandler('login','submit',function(event){
+                PWM_MAIN.handleFormSubmit(PWM_MAIN.getObject('login'),event);
+            });
+        });
+    </script>
+</pwm:script>
+<% } %>
+<% } else { %>
 <pwm:script>
 <pwm:script>
     <script type="text/javascript">
     <script type="text/javascript">
         PWM_GLOBAL['startupFunctions'].push(function(){
         PWM_GLOBAL['startupFunctions'].push(function(){

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

@@ -49,7 +49,7 @@
 
 
             <div class="buttonbar">
             <div class="buttonbar">
                 <input type="hidden" name="processAction" value="processForm"/>
                 <input type="hidden" name="processAction" value="processForm"/>
-                <button type="submit" name="Create" class="btn" id="submitBtn">
+                <button type="submit" name="Create" class="btn pwm-btn-submit" id="submitBtn">
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-forward"></span></pwm:if>
                     <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-forward"></span></pwm:if>
                     <pwm:display key="Button_Continue"/>
                     <pwm:display key="Button_Continue"/>
                 </button>
                 </button>

+ 0 - 1
webapp/src/main/webapp/public/resources/js/configmanager.js

@@ -203,7 +203,6 @@ PWM_CONFIG.showHeaderHealth = function() {
         var loadFunction = function(data) {
         var loadFunction = function(data) {
             if (data['data'] && data['data']['overall']) {
             if (data['data'] && data['data']['overall']) {
                 var hasWarnTopics = data['data']['overall'] === 'WARN';
                 var hasWarnTopics = data['data']['overall'] === 'WARN';
-                console.log('has health errors: ' + hasWarnTopics);
                 if (hasWarnTopics) {
                 if (hasWarnTopics) {
                     PWM_MAIN.removeCssClass('header-menu-alert','display-none');
                     PWM_MAIN.removeCssClass('header-menu-alert','display-none');
                     PWM_MAIN.removeCssClass('panel-header-healthData','display-none');
                     PWM_MAIN.removeCssClass('panel-header-healthData','display-none');

+ 49 - 45
webapp/src/main/webapp/public/resources/js/main.js

@@ -87,12 +87,12 @@ PWM_MAIN.loadClientData=function(completeFunction) {
         for (var globalProp in data['data']['PWM_GLOBAL']) {
         for (var globalProp in data['data']['PWM_GLOBAL']) {
             PWM_GLOBAL[globalProp] = data['data']['PWM_GLOBAL'][globalProp];
             PWM_GLOBAL[globalProp] = data['data']['PWM_GLOBAL'][globalProp];
         }
         }
-        console.log('loaded client data');
+        PWM_MAIN.log('loaded client data');
         if (completeFunction) completeFunction();
         if (completeFunction) completeFunction();
     };
     };
     var errorFunction = function(error) {
     var errorFunction = function(error) {
         var errorMsg = 'unable to read app-data: ' + error;;
         var errorMsg = 'unable to read app-data: ' + error;;
-        console.log(errorMsg);
+        PWM_MAIN.log(errorMsg);
         if (!PWM_VAR['initError']) PWM_VAR['initError'] = errorMsg;
         if (!PWM_VAR['initError']) PWM_VAR['initError'] = errorMsg;
         if (completeFunction) completeFunction();
         if (completeFunction) completeFunction();
     };
     };
@@ -112,12 +112,12 @@ PWM_MAIN.loadLocaleBundle = function(bundleName, completeFunction) {
                 PWM_GLOBAL['localeStrings'][bundleName][settingKey] = data['data'][settingKey];
                 PWM_GLOBAL['localeStrings'][bundleName][settingKey] = data['data'][settingKey];
             }
             }
         }
         }
-        console.log('loaded locale bundle data for ' + bundleName);
+        PWM_MAIN.log('loaded locale bundle data for ' + bundleName);
         if (completeFunction) completeFunction();
         if (completeFunction) completeFunction();
     };
     };
     var errorFunction = function(){
     var errorFunction = function(){
         var errorMsg = 'unable to load locale bundle from , please reload page (' + error + ')';
         var errorMsg = 'unable to load locale bundle from , please reload page (' + error + ')';
-        console.log(errorMsg);
+        PWM_MAIN.log(errorMsg);
         if (!PWM_VAR['initError']) PWM_VAR['initError'] = errorMsg;
         if (!PWM_VAR['initError']) PWM_VAR['initError'] = errorMsg;
         if (completeFunction) completeFunction();
         if (completeFunction) completeFunction();
     };
     };
@@ -217,7 +217,7 @@ PWM_MAIN.initPage = function() {
 
 
     ShowHidePasswordHandler.initAllForms();
     ShowHidePasswordHandler.initAllForms();
 
 
-    console.log('initPage completed');
+    PWM_MAIN.log('initPage completed');
 };
 };
 
 
 PWM_MAIN.initDisplayTabPreferences = function() {
 PWM_MAIN.initDisplayTabPreferences = function() {
@@ -284,7 +284,7 @@ PWM_MAIN.applyFormAttributes = function() {
     require(["dojo"], function (dojo) {
     require(["dojo"], function (dojo) {
         if(dojo.isIE){
         if(dojo.isIE){
             PWM_MAIN.doQuery("button[type=submit][form]",function(element){
             PWM_MAIN.doQuery("button[type=submit][form]",function(element){
-                console.log('added event handler for submit button with form attribute ' + element.id);
+                PWM_MAIN.log('added event handler for submit button with form attribute ' + element.id);
                 PWM_MAIN.addEventHandler(element,'click',function(e){
                 PWM_MAIN.addEventHandler(element,'click',function(e){
                     PWM_MAIN.stopEvent(e);
                     PWM_MAIN.stopEvent(e);
                     PWM_VAR['dirtyPageLeaveFlag'] = false;
                     PWM_VAR['dirtyPageLeaveFlag'] = false;
@@ -354,11 +354,11 @@ PWM_MAIN.gotoUrl = function(url, options) {
     var executeGoto = function() {
     var executeGoto = function() {
         if (options['delay']) {
         if (options['delay']) {
             setTimeout(function () {
             setTimeout(function () {
-                console.log('redirecting to new url: ' + url);
+                PWM_MAIN.log('redirecting to new url: ' + url);
                 window.location = url;
                 window.location = url;
             }, options['delay']);
             }, options['delay']);
         } else {
         } else {
-            console.log('redirecting to new url: ' + url);
+            PWM_MAIN.log('redirecting to new url: ' + url);
             window.location = url;
             window.location = url;
         }
         }
     };
     };
@@ -375,7 +375,7 @@ PWM_MAIN.gotoUrl = function(url, options) {
 
 
 
 
 PWM_MAIN.handleLoginFormSubmit = function(form, event) {
 PWM_MAIN.handleLoginFormSubmit = function(form, event) {
-    console.log('entering handleLoginFormSubmit');
+    PWM_MAIN.log('entering handleLoginFormSubmit');
     PWM_MAIN.cancelEvent(event);
     PWM_MAIN.cancelEvent(event);
 
 
     require(["dojo","dojo/dom-form"], function(dojo, domForm) {
     require(["dojo","dojo/dom-form"], function(dojo, domForm) {
@@ -397,7 +397,7 @@ PWM_MAIN.handleLoginFormSubmit = function(form, event) {
                         });
                         });
                         return;
                         return;
                     }
                     }
-                    console.log('authentication success');
+                    PWM_MAIN.log('authentication success');
                     var nextURL = data['data']['nextURL'];
                     var nextURL = data['data']['nextURL'];
                     if (nextURL) {
                     if (nextURL) {
                         PWM_MAIN.gotoUrl(nextURL, {noContext: true});
                         PWM_MAIN.gotoUrl(nextURL, {noContext: true});
@@ -408,16 +408,20 @@ PWM_MAIN.handleLoginFormSubmit = function(form, event) {
                     try {
                     try {
                         grecaptcha.reset(); // reset the
                         grecaptcha.reset(); // reset the
                     } catch (e) {
                     } catch (e) {
-                        console.log("error resetting the captcha: " + e)
+                        PWM_MAIN.log("error resetting the captcha: " + e)
                     }
                     }
                 }
                 }
             }});
             }});
     });
     });
 };
 };
 
 
+PWM_MAIN.log = function(text) {
+    console.log(text);
+};
+
 
 
 PWM_MAIN.handleFormSubmit = function(form, event) {
 PWM_MAIN.handleFormSubmit = function(form, event) {
-    console.log('entering handleFormSubmit');
+    PWM_MAIN.log('entering handleFormSubmit');
     PWM_MAIN.cancelEvent(event);
     PWM_MAIN.cancelEvent(event);
 
 
     PWM_GLOBAL['idle_suspendTimeout'] = true;
     PWM_GLOBAL['idle_suspendTimeout'] = true;
@@ -596,13 +600,13 @@ PWM_MAIN.clearDijitWidget = function (widgetName) {
             try {
             try {
                 oldDijitNode.destroyRecursive();
                 oldDijitNode.destroyRecursive();
             } catch (error) {
             } catch (error) {
-                console.log('error destroying old widget: ' + error);
+                PWM_MAIN.log('error destroying old widget: ' + error);
             }
             }
 
 
             try {
             try {
                 oldDijitNode.destroy();
                 oldDijitNode.destroy();
             } catch (error) {
             } catch (error) {
-                console.log('error destroying old widget: ' + error);
+                PWM_MAIN.log('error destroying old widget: ' + error);
             }
             }
         }
         }
     });
     });
@@ -704,7 +708,7 @@ PWM_MAIN.showErrorDialog = function(error, options) {
         logMsg += 'due to error code type, reloading page.';
         logMsg += 'due to error code type, reloading page.';
     }
     }
 
 
-    console.log('displaying error message: ' + logMsg);
+    PWM_MAIN.log('displaying error message: ' + logMsg);
     options['title'] = titleMsg;
     options['title'] = titleMsg;
     options['text'] = body;
     options['text'] = body;
     var previousOkAction = 'okAction' in options ? options['okAction'] : function() {};
     var previousOkAction = 'okAction' in options ? options['okAction'] : function() {};
@@ -788,15 +792,15 @@ PWM_MAIN.showDialog = function(options) {
         if ('okAction' in options) {
         if ('okAction' in options) {
             options['okAction']();
             options['okAction']();
         } else {
         } else {
-            console.log('dialog okAction is empty')
+            PWM_MAIN.log('dialog okAction is empty')
         }
         }
     };
     };
     var cancelAction = 'cancelAction' in options ? options['cancelAction'] : function(){
     var cancelAction = 'cancelAction' in options ? options['cancelAction'] : function(){
         PWM_MAIN.closeWaitDialog(idName);
         PWM_MAIN.closeWaitDialog(idName);
-        console.log('no-dialog-cancelaction')
+        PWM_MAIN.log('no-dialog-cancelaction')
     };
     };
     var loadFunction = 'loadFunction' in options ? options['loadFunction'] : function(){
     var loadFunction = 'loadFunction' in options ? options['loadFunction'] : function(){
-        console.log('no-dialog-loadfunction')
+        PWM_MAIN.log('no-dialog-loadfunction')
     };
     };
 
 
     PWM_VAR['dialog_loadFunction'] = loadFunction;
     PWM_VAR['dialog_loadFunction'] = loadFunction;
@@ -1088,7 +1092,7 @@ PWM_MAIN.createCSSClass = function(selector, style) {
                     return;
                     return;
                 }
                 }
             } catch (e) {
             } catch (e) {
-                console.log('error while checking existing rules during cssCreate:' + e);
+                PWM_MAIN.log('error while checking existing rules during cssCreate:' + e);
             }
             }
         }
         }
         // or add a new rule
         // or add a new rule
@@ -1112,10 +1116,10 @@ PWM_MAIN.createCSSClass = function(selector, style) {
 
 
 PWM_MAIN.flashDomElement = function(flashColor,elementName,durationMS) {
 PWM_MAIN.flashDomElement = function(flashColor,elementName,durationMS) {
     if (!PWM_MAIN.getObject(elementName)) {
     if (!PWM_MAIN.getObject(elementName)) {
-        console.log('cant flash non-existing element id ' + elementName);
+        PWM_MAIN.log('cant flash non-existing element id ' + elementName);
         return;
         return;
     }
     }
-    console.log('will flash element id ' + elementName);
+    PWM_MAIN.log('will flash element id ' + elementName);
     require(["dojo","dojo/window","dojo/domReady!"],function(dojo) {
     require(["dojo","dojo/window","dojo/domReady!"],function(dojo) {
         var originalBGColor = PWM_MAIN.getRenderedStyle(elementName,'background-color');
         var originalBGColor = PWM_MAIN.getRenderedStyle(elementName,'background-color');
         PWM_MAIN.getObject(elementName).style.backgroundColor = flashColor;
         PWM_MAIN.getObject(elementName).style.backgroundColor = flashColor;
@@ -1209,7 +1213,7 @@ PWM_MAIN.pwmFormValidator = function(validationProps, reentrant) {
     var completeFunction = 'completeFunction' in validationProps ? validationProps['completeFunction'] : function(){};
     var completeFunction = 'completeFunction' in validationProps ? validationProps['completeFunction'] : function(){};
 
 
 
 
-    if (CONSOLE_DEBUG) console.log("pwmFormValidator: beginning...");
+    if (CONSOLE_DEBUG) PWM_MAIN.log("pwmFormValidator: beginning...");
 
 
     //init vars;
     //init vars;
     if (!PWM_VAR['validationCache']) {
     if (!PWM_VAR['validationCache']) {
@@ -1225,7 +1229,7 @@ PWM_MAIN.pwmFormValidator = function(validationProps, reentrant) {
         var cachedResult = PWM_VAR['validationCache'][formKey];
         var cachedResult = PWM_VAR['validationCache'][formKey];
         if (cachedResult) {
         if (cachedResult) {
             processResultsFunction(cachedResult);
             processResultsFunction(cachedResult);
-            if (CONSOLE_DEBUG) console.log('pwmFormValidator: processed cached data, exiting');
+            if (CONSOLE_DEBUG) PWM_MAIN.log('pwmFormValidator: processed cached data, exiting');
             completeFunction(cachedResult);
             completeFunction(cachedResult);
             return;
             return;
         }
         }
@@ -1241,15 +1245,15 @@ PWM_MAIN.pwmFormValidator = function(validationProps, reentrant) {
             PWM_MAIN.showInfo(PWM_MAIN.showString('Display_TypingWait'));
             PWM_MAIN.showInfo(PWM_MAIN.showString('Display_TypingWait'));
         }
         }
         setTimeout(function(){PWM_MAIN.pwmFormValidator(validationProps, true)}, typeWaitTimeMs + 1);
         setTimeout(function(){PWM_MAIN.pwmFormValidator(validationProps, true)}, typeWaitTimeMs + 1);
-        if (CONSOLE_DEBUG) console.log('pwmFormValidator: sleeping while waiting for typing to finish, will retry...');
+        if (CONSOLE_DEBUG) PWM_MAIN.log('pwmFormValidator: sleeping while waiting for typing to finish, will retry...');
         return;
         return;
     }
     }
-    if (CONSOLE_DEBUG) console.log('pwmFormValidator: user no longer typing, continuing..');
+    if (CONSOLE_DEBUG) PWM_MAIN.log('pwmFormValidator: user no longer typing, continuing..');
 
 
     //check to see if a validation is already in progress, if it is then ignore keypress.
     //check to see if a validation is already in progress, if it is then ignore keypress.
     if (PWM_VAR['validationInProgress'] === true) {
     if (PWM_VAR['validationInProgress'] === true) {
         setTimeout(function(){PWM_MAIN.pwmFormValidator(validationProps, true)}, typeWaitTimeMs + 1);
         setTimeout(function(){PWM_MAIN.pwmFormValidator(validationProps, true)}, typeWaitTimeMs + 1);
-        if (CONSOLE_DEBUG) console.log('pwmFormValidator: waiting for a previous validation to complete, exiting...');
+        if (CONSOLE_DEBUG) PWM_MAIN.log('pwmFormValidator: waiting for a previous validation to complete, exiting...');
         return;
         return;
     }
     }
     PWM_VAR['validationInProgress'] = true;
     PWM_VAR['validationInProgress'] = true;
@@ -1265,12 +1269,12 @@ PWM_MAIN.pwmFormValidator = function(validationProps, reentrant) {
 
 
     var formDataString = JSON.stringify(formData) ;
     var formDataString = JSON.stringify(formData) ;
 
 
-    if (CONSOLE_DEBUG) console.log('FormValidator: sending form data to server... ' + formDataString);
+    if (CONSOLE_DEBUG) PWM_MAIN.log('FormValidator: sending form data to server... ' + formDataString);
     var loadFunction = function(data) {
     var loadFunction = function(data) {
         PWM_VAR['validationInProgress'] = false;
         PWM_VAR['validationInProgress'] = false;
         delete PWM_VAR['validationLastType'];
         delete PWM_VAR['validationLastType'];
         PWM_VAR['validationCache'][formKey] = data;
         PWM_VAR['validationCache'][formKey] = data;
-        if (CONSOLE_DEBUG) console.log('pwmFormValidator: successful read, data added to cache');
+        if (CONSOLE_DEBUG) PWM_MAIN.log('pwmFormValidator: successful read, data added to cache');
         PWM_MAIN.pwmFormValidator(validationProps, true);
         PWM_MAIN.pwmFormValidator(validationProps, true);
     };
     };
     var options = {};
     var options = {};
@@ -1281,7 +1285,7 @@ PWM_MAIN.pwmFormValidator = function(validationProps, reentrant) {
         if (showMessage) {
         if (showMessage) {
             PWM_MAIN.showInfo(PWM_MAIN.showString('Display_CommunicationError'));
             PWM_MAIN.showInfo(PWM_MAIN.showString('Display_CommunicationError'));
         }
         }
-        if (CONSOLE_DEBUG) console.log('pwmFormValidator: error connecting to service: ' + error);
+        if (CONSOLE_DEBUG) PWM_MAIN.log('pwmFormValidator: error connecting to service: ' + error);
         processResultsFunction(null);
         processResultsFunction(null);
         completeFunction(null);
         completeFunction(null);
     };
     };
@@ -1411,7 +1415,7 @@ ShowHidePasswordHandler.initAllForms = function() {
 
 
     PWM_MAIN.doQuery('.passwordfield',function(field){
     PWM_MAIN.doQuery('.passwordfield',function(field){
         if (field.id) {
         if (field.id) {
-            if (ShowHidePasswordHandler.debugOutput) console.log('adding show/hide option on fieldID=' + field.id);
+            if (ShowHidePasswordHandler.debugOutput) PWM_MAIN.log('adding show/hide option on fieldID=' + field.id);
             ShowHidePasswordHandler.init(field.id);
             ShowHidePasswordHandler.init(field.id);
         }
         }
     });
     });
@@ -1453,7 +1457,7 @@ ShowHidePasswordHandler.init = function(nodeName) {
 };
 };
 
 
 ShowHidePasswordHandler.renderIcon = function(nodeName) {
 ShowHidePasswordHandler.renderIcon = function(nodeName) {
-    if (ShowHidePasswordHandler.debugOutput) console.log("calling renderIcon on node " + nodeName);
+    if (ShowHidePasswordHandler.debugOutput) PWM_MAIN.log("calling renderIcon on node " + nodeName);
     var node = PWM_MAIN.getObject(nodeName);
     var node = PWM_MAIN.getObject(nodeName);
     var eyeId = nodeName + ShowHidePasswordHandler.idSuffix;
     var eyeId = nodeName + ShowHidePasswordHandler.idSuffix;
     var eyeNode = PWM_MAIN.getObject(eyeId);
     var eyeNode = PWM_MAIN.getObject(eyeId);
@@ -1504,7 +1508,7 @@ ShowHidePasswordHandler.show = function(nodeName) {
 
 
 ShowHidePasswordHandler.addInputEvents = function(nodeName) {
 ShowHidePasswordHandler.addInputEvents = function(nodeName) {
     PWM_MAIN.addEventHandler(nodeName, "keyup, input", function(){
     PWM_MAIN.addEventHandler(nodeName, "keyup, input", function(){
-        if (ShowHidePasswordHandler.debugOutput) console.log("keypress event on node " + nodeName);
+        if (ShowHidePasswordHandler.debugOutput) PWM_MAIN.log("keypress event on node " + nodeName);
         ShowHidePasswordHandler.renderIcon(nodeName);
         ShowHidePasswordHandler.renderIcon(nodeName);
         ShowHidePasswordHandler.setupTooltip(nodeName);
         ShowHidePasswordHandler.setupTooltip(nodeName);
     });
     });
@@ -1537,7 +1541,7 @@ ShowHidePasswordHandler.changeInputTypeField = function(object, type) {
 };
 };
 
 
 ShowHidePasswordHandler.setupTooltip = function(nodeName) {
 ShowHidePasswordHandler.setupTooltip = function(nodeName) {
-    if (ShowHidePasswordHandler.debugOutput) console.log('begin setupTooltip');
+    if (ShowHidePasswordHandler.debugOutput) PWM_MAIN.log('begin setupTooltip');
     var state = ShowHidePasswordHandler.state[nodeName];
     var state = ShowHidePasswordHandler.state[nodeName];
     var eyeNodeId = nodeName + ShowHidePasswordHandler.idSuffix;
     var eyeNodeId = nodeName + ShowHidePasswordHandler.idSuffix;
 
 
@@ -1545,12 +1549,12 @@ ShowHidePasswordHandler.setupTooltip = function(nodeName) {
         PWM_MAIN.showTooltip({id:eyeNodeId,text:PWM_MAIN.showString('Button_Show')});
         PWM_MAIN.showTooltip({id:eyeNodeId,text:PWM_MAIN.showString('Button_Show')});
         PWM_MAIN.removeCssClass(eyeNodeId,"pwm-icon-eye-slash");
         PWM_MAIN.removeCssClass(eyeNodeId,"pwm-icon-eye-slash");
         PWM_MAIN.addCssClass(eyeNodeId,"pwm-icon-eye");
         PWM_MAIN.addCssClass(eyeNodeId,"pwm-icon-eye");
-        if (ShowHidePasswordHandler.debugOutput) console.log('set class to pwm-icon-eye');
+        if (ShowHidePasswordHandler.debugOutput) PWM_MAIN.log('set class to pwm-icon-eye');
     } else {
     } else {
         PWM_MAIN.showTooltip({id:eyeNodeId,text:PWM_MAIN.showString('Button_Hide')});
         PWM_MAIN.showTooltip({id:eyeNodeId,text:PWM_MAIN.showString('Button_Hide')});
         PWM_MAIN.removeCssClass(eyeNodeId,"pwm-icon-eye");
         PWM_MAIN.removeCssClass(eyeNodeId,"pwm-icon-eye");
         PWM_MAIN.addCssClass(eyeNodeId,"pwm-icon-eye-slash");
         PWM_MAIN.addCssClass(eyeNodeId,"pwm-icon-eye-slash");
-        if (ShowHidePasswordHandler.debugOutput) console.log('set class to pwm-icon-slash');
+        if (ShowHidePasswordHandler.debugOutput) PWM_MAIN.log('set class to pwm-icon-slash');
     }
     }
 };
 };
 
 
@@ -1790,7 +1794,7 @@ PWM_MAIN.ajaxRequest = function(url,loadFunction,options) {
         var status = error['response']['status'];
         var status = error['response']['status'];
         if (status === 0 || status < 200 || status >= 300) {
         if (status === 0 || status < 200 || status >= 300) {
             var msg = PWM_MAIN.showString("Display_ClientDisconnect") + "  (" + status + ")";
             var msg = PWM_MAIN.showString("Display_ClientDisconnect") + "  (" + status + ")";
-            console.log(msg);
+            PWM_MAIN.log(msg);
             PWM_MAIN.showErrorDialog(msg);
             PWM_MAIN.showErrorDialog(msg);
         } else {
         } else {
             PWM_MAIN.showErrorDialog(error);
             PWM_MAIN.showErrorDialog(error);
@@ -2051,10 +2055,10 @@ PWM_MAIN.Preferences.readLocalStorage = function(key,valueIfMissing) {
                 }
                 }
             }
             }
         } catch (e) {
         } catch (e) {
-            console.log("error reading locale storage preferences: " + e);
+            PWM_MAIN.log("error reading locale storage preferences: " + e);
         }
         }
     } else {
     } else {
-        console.log("browser doesn't support local storage");
+        PWM_MAIN.log("browser doesn't support local storage");
     }
     }
     return valueIfMissing;
     return valueIfMissing;
 };
 };
@@ -2071,10 +2075,10 @@ PWM_MAIN.Preferences.writeLocalStorage = function(key, value, lifetimeSeconds) {
             baseJson[key] = wrapperValue;
             baseJson[key] = wrapperValue;
             localStorage.setItem(PWM_MAIN.Preferences.StorageKeyName,JSON.stringify(baseJson));
             localStorage.setItem(PWM_MAIN.Preferences.StorageKeyName,JSON.stringify(baseJson));
         } catch (e) {
         } catch (e) {
-            console.log("error writing locale storage preferences: " + e);
+            PWM_MAIN.log("error writing locale storage preferences: " + e);
         }
         }
     } else {
     } else {
-        console.log("browser doesn't support local storage");
+        PWM_MAIN.log("browser doesn't support local storage");
     }
     }
 };
 };
 
 
@@ -2087,10 +2091,10 @@ PWM_MAIN.Preferences.readSessionStorage = function(key,valueIfMissing) {
                 return key in baseJson ? baseJson[key] : valueIfMissing;
                 return key in baseJson ? baseJson[key] : valueIfMissing;
             }
             }
         } catch (e) {
         } catch (e) {
-            console.log("error reading session storage preferences: " + e);
+            PWM_MAIN.log("error reading session storage preferences: " + e);
         }
         }
     } else {
     } else {
-        console.log("browser doesn't support session storage");
+        PWM_MAIN.log("browser doesn't support session storage");
     }
     }
     return valueIfMissing;
     return valueIfMissing;
 };
 };
@@ -2103,10 +2107,10 @@ PWM_MAIN.Preferences.writeSessionStorage = function(key, value) {
             baseJson[key] = value;
             baseJson[key] = value;
             sessionStorage.setItem(PWM_MAIN.Preferences.StorageKeyName,JSON.stringify(baseJson));
             sessionStorage.setItem(PWM_MAIN.Preferences.StorageKeyName,JSON.stringify(baseJson));
         } catch (e) {
         } catch (e) {
-            console.log("error writing session storage preferences: " + e);
+            PWM_MAIN.log("error writing session storage preferences: " + e);
         }
         }
     } else {
     } else {
-        console.log("browser doesn't support session storage");
+        PWM_MAIN.log("browser doesn't support session storage");
     }
     }
 };
 };
 
 
@@ -2118,7 +2122,7 @@ PWM_MAIN.numberFormat = function (number) {
     try {
     try {
         return new Number(number).toLocaleString();
         return new Number(number).toLocaleString();
     } catch (t) {
     } catch (t) {
-        console.log('error localizing number value "' + number + '", error: ' + t);
+        PWM_MAIN.log('error localizing number value "' + number + '", error: ' + t);
     }
     }
 
 
     return number;
     return number;