diff options
Diffstat (limited to 'includes/js/dojox/form/PasswordValidator.js')
-rw-r--r-- | includes/js/dojox/form/PasswordValidator.js | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/includes/js/dojox/form/PasswordValidator.js b/includes/js/dojox/form/PasswordValidator.js new file mode 100644 index 0000000..e147ddf --- /dev/null +++ b/includes/js/dojox/form/PasswordValidator.js @@ -0,0 +1,280 @@ +if(!dojo._hasResource["dojox.form.PasswordValidator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.form.PasswordValidator"] = true; +dojo.provide("dojox.form.PasswordValidator"); + +dojo.require("dijit.form._FormWidget"); +dojo.require("dijit.form.ValidationTextBox"); + +dojo.requireLocalization("dojox.form", "PasswordValidator", null, "ROOT"); + +dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, { + // summary: + // A class that is shared between all our children - extends + // ValidationTextBox and provides some shared functionality + // + // containerWidget: widget + // Our parent (the PasswordValidator) + containerWidget: null, + + // type: string + // Don't override this - we are all "password" types + type: "password", + + reset: function(){ + // summary: + // Force-set to empty string (we don't save passwords EVER)...and + // since _OldPWBox overrides setValue to check for empty string, + // call our parent class directly (not this.inherited()) + dijit.form.ValidationTextBox.prototype.setValue.call(this, "", true); + this._hasBeenBlurred = false; + } +}); + + + +dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, { + // summary: + // A class representing our "old password" box. + // + // _isPWValid: boolean + // Whether or not the password is valid + _isPWValid: false, + + setValue: function(/* anything */ newVal, /* boolean? */ priority){ + // summary: + // Updates _isPWValid if this isn't our initial update by calling + // our PasswordValidator's pwCheck function + if(newVal === ""){ + newVal = dojox.form._OldPWBox.superclass.getValue.call(this); + } + if(priority !== null){ + // Priority is passed in as null, explicitly when this is an + // update (not initially set). We want to check our password now. + this._isPWValid = this.containerWidget.pwCheck(newVal); + } + this.inherited("setValue", arguments); + }, + + isValid: function(/* boolean */ isFocused){ + // Take into account the isPWValid setting + return this.inherited("isValid", arguments) && this._isPWValid; + }, + + _update: function(/* event */ e){ + // Only call validate() if we've been blurred or else we get popups + // too early. + if(this._hasBeenBlurred){ this.validate(true); } + this._onMouse(e); + }, + + getValue: function(){ + // summary: + // Only returns a value if our container widget is valid. This + // is to prevent exposure of "oldPW" too early. + if(this.containerWidget.isValid()){ + return this.inherited("getValue", arguments); + }else{ + return ""; + } + } +}); + + +dojo.declare("dojox.form._NewPWBox", dojox.form._ChildTextBox, { + // summary: + // A class representing our new password textbox + + // required: boolean + // Whether or not this widget is required (default: true) + required: true, + + onChange: function(){ + // summary: + // Validates our verify box - to make sure that a change to me is + // reflected there + this.containerWidget._inputWidgets[2].validate(false); + this.inherited(arguments); + } +}); + +dojo.declare("dojox.form._VerifyPWBox", dojox.form._ChildTextBox, { + // summary: + // A class representing our verify textbox + + isValid: function(isFocused){ + // summary: + // Validates that we match the "real" password + return this.inherited("isValid", arguments) && + (this.getValue() == this.containerWidget._inputWidgets[1].getValue()); + } +}); + +dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, { + // summary: + // A password validation widget that simplifies the "old/new/verify" + // style of requesting passwords. You will probably want to override + // this class and implement your own pwCheck function. + // + // required: boolean + // Whether or not it is required for form submission + required: true, + + // inputWidgets: TextBox[] + // An array of text boxes that are our components + _inputWidgets: null, + + // oldName: string? + // The name to send our old password as (when form is posted) + oldName: "", + + templateString:"<div dojoAttachPoint=\"containerNode\">\n\t<input type=\"hidden\" name=\"${name}\" value=\"\" dojoAttachPoint=\"focusNode\" />\n</div>\n", + + _hasBeenBlurred: false, + + isValid: function(/* boolean */ isFocused){ + // summary: we are valid if ALL our children are valid + return dojo.every(this._inputWidgets, function(i){ + if(i && i._setStateClass){ i._setStateClass(); } + return (!i || i.isValid()); + }); + }, + + validate: function(/* boolean */ isFocused){ + // summary: Validating this widget validates all our children + return dojo.every(dojo.map(this._inputWidgets, function(i){ + if(i && i.validate){ + i._hasBeenBlurred = (i._hasBeenBlurred || this._hasBeenBlurred); + return i.validate(); + } + return true; + }, this), "return item;"); + }, + + reset: function(){ + // summary: Resetting this widget resets all our children + this._hasBeenBlurred = false; + dojo.forEach(this._inputWidgets, function(i){ + if(i && i.reset){ i.reset(); } + }, this); + }, + + _createSubWidgets: function(){ + // summary: + // Turns the inputs inside this widget into "real" validation + // widgets - and sets up the needed connections. + var widgets = this._inputWidgets, + msg = dojo.i18n.getLocalization("dojox.form", "PasswordValidator", + this.lang); + dojo.forEach(widgets, function(i, idx){ + if(i){ + var p = {containerWidget: this}, c; + if(idx === 0){ + p.name = this.oldName; + p.invalidMessage = msg.badPasswordMessage; + c = dojox.form._OldPWBox; + }else if(idx === 1){ + p.required = this.required; + c = dojox.form._NewPWBox; + }else if(idx === 2){ + p.invalidMessage = msg.nomatchMessage; + c = dojox.form._VerifyPWBox; + } + widgets[idx] = new c(p, i); + } + }, this); + }, + + pwCheck: function(/* string */ password){ + // summary: + // Overridable function for validation of the old password box. + // + // This function is called and passed the old password. Return + // true if it's OK to continue, and false if it is not. + // + // IMPORTANT SECURITY NOTE: Do NOT EVER EVER EVER check this in + // HTML or JavaScript!!! + // + // You will probably want to override this function to callback + // to a server to verify the password (the callback will need to + // be syncronous) - and it's probably a good idea to validate + // it again on form submission before actually doing + // anything destructive - that's why the "oldName" value + // is available. + // + // And don't just fetch the password from the server + // either :) Send the test password (probably hashed, for + // security) and return from the server a status instead. + // + // Again - DON'T BE INSECURE!!! Security is left as an exercise + // for the reader :) + return false; + }, + + postCreate: function(){ + // summary: + // Sets up the correct widgets. You *MUST* specify one child + // text box (a simple HTML <input> element) with pwType="new" + // *and* one child text box with pwType="verify". You *MAY* + // specify a third child text box with pwType="old" in order to + // prompt the user to enter in their old password before the + // widget returns that it is valid. + + this.inherited(arguments); + + // Turn my inputs into the correct stuff.... + var widgets = this._inputWidgets = []; + dojo.forEach(["old","new","verify"], function(i){ + widgets.push(dojo.query("input[pwType=" + i + "]", + this.containerNode)[0]); + }, this); + if (!widgets[1] || !widgets[2]){ + throw new Error("Need at least pwType=\"new\" and pwType=\"verify\""); + } + if (this.oldName && !widgets[0]){ + throw new Error("Need to specify pwType=\"old\" if using oldName"); + } + this._createSubWidgets(); + }, + + setAttribute: function(/* string */ attr, /* anything */ value){ + this.inherited(arguments); + + // Disabling (or enabling) the container disables (or enables) all + // the subwidgets as well - same for requiring + switch(attr){ + case "disabled": + case "required": + dojo.forEach(this._inputWidgets, function(i){ + if(i && i.setAttribute){ i.setAttribute(attr, value);} + }); + break; + default: + break; + } + }, + + getValue: function(){ + // summary: overridden to return an empty string if we aren't valid. + if (this.isValid()){ + return this._inputWidgets[1].getValue(); + }else{ + return ""; + } + }, + + focus: function(){ + // summary: + // places focus on the first invalid input widget - if all + // input widgets are valid, the first widget is focused. + var f = false; + dojo.forEach(this._inputWidgets, function(i){ + if(i && !i.isValid() && !f){ + i.focus(); + f = true; + } + }); + if(!f){ this._inputWidgets[1].focus(); } + } +}); + +} |