return '' unless $self->get($self->primary_key); # for validating new passwords pre-insert
+ #check against customer fields
+ my $cust_main = $self->cust_main;
+ if ($cust_main) {
+ my @words;
+ # words from cust_main
+ foreach my $field ( qw( last first daytime night fax mobile ) ) {
+ push @words, split(/\W/,$cust_main->get($field));
+ }
+ # words from cust_location
+ foreach my $loc ($cust_main->cust_location) {
+ foreach my $field ( qw(address1 address2 city county state zip) ) {
+ push @words, split(/\W/,$loc->get($field));
+ }
+ }
+ # words from cust_contact & contact_phone
+ foreach my $contact (map { $_->contact } $cust_main->cust_contact) {
+ foreach my $field ( qw(last first) ) {
+ push @words, split(/\W/,$contact->get($field));
+ }
+ # not hugely useful right now, hyphenless stored values longer than password max,
+ # but max will probably be increased eventually...
+ foreach my $phone ( qsearch('contact_phone', {'contactnum' => $contact->contactnum}) ) {
+ push @words, split(/\W/,$phone->get('phonenum'));
+ }
+ }
+ # do the actual checking
+ foreach my $word (@words) {
+ next unless length($word) > 2;
+ if ($password =~ /$word/i) {
+ return qq(Password contains account information '$word');
+ }
+ }
+ }
+
my $no_reuse = 3;
# allow override here if we really must
my ($self, $password) = @_;
foreach my $field ( qw(username finger) ) {
foreach my $word (split(/\W+/,$self->get($field))) {
+ next unless length($word) > 2;
if ($password =~ /$word/i) {
return qq(Password contains account information '$word');
}
+++ /dev/null
-<SCRIPT>
-function add_password_validation (fieldid) {
- var inputfield = document.getElementById(fieldid);
- inputfield.onchange = function () {
- var fieldid = this.id+'_result';
- var resultfield = document.getElementById(fieldid);
- var svcnum = '';
- var svcfield = document.getElementById(this.id+'_svcnum');
- if (svcfield) {
- svcnum = svcfield.options[svcfield.selectedIndex].value;
- }
- if (this.value) {
- resultfield.innerHTML = '<SPAN STYLE="color: blue;">Validating password...</SPAN>';
- send_xmlhttp('selfservice.cgi',
- ['action','validate_password','fieldid',fieldid,'svcnum',svcnum,'check_password',this.value],
- function (result) {
- result = JSON.parse(result);
- var resultfield = document.getElementById(result.fieldid);
- if (resultfield) {
- if (result.valid) {
- resultfield.innerHTML = '<SPAN STYLE="color: green;">Password valid!</SPAN>';
- } else if (result.error) {
- resultfield.innerHTML = '<SPAN STYLE="color: red;">'+result.error+'</SPAN>';
- } else {
- result.syserror = result.syserror || 'Server error';
- resultfield.innerHTML = '<SPAN STYLE="color: red;">'+result.syserror+'</SPAN>';
- }
- }
- }
- );
- } else {
- resultfield.innerHTML = '';
- }
- };
-}
-</SCRIPT>
--- /dev/null
+function add_password_validation (fieldid,nologin) {
+ var inputfield = document.getElementById(fieldid);
+ inputfield.onchange = function () {
+ var fieldid = this.id+'_result';
+ var resultfield = document.getElementById(fieldid);
+ var svcnum = '';
+ var svcfield = document.getElementById(this.id+'_svcnum');
+ if (svcfield) {
+ svcnum = svcfield.options[svcfield.selectedIndex].value;
+ }
+ if (this.value) {
+ resultfield.innerHTML = '<SPAN STYLE="color: blue;">Validating password...</SPAN>';
+ var action = nologin ? 'validate_password_nologin' : 'validate_password';
+ send_xmlhttp('selfservice.cgi',
+ ['action',action,'fieldid',fieldid,'svcnum',svcnum,'check_password',this.value],
+ function (result) {
+ result = JSON.parse(result);
+ var resultfield = document.getElementById(result.fieldid);
+ if (resultfield) {
+ var errorimg = '<IMG SRC="images/error.png" style="width: 1em; display: inline-block; padding-right: .5em">';
+ var validimg = '<IMG SRC="images/tick.png" style="width: 1em; display: inline-block; padding-right: .5em">';
+ if (result.valid) {
+ resultfield.innerHTML = validimg+'<SPAN STYLE="color: green;">Password valid!</SPAN>';
+ } else if (result.error) {
+ resultfield.innerHTML = errorimg+'<SPAN STYLE="color: red;">'+result.error+'</SPAN>';
+ } else {
+ result.syserror = result.syserror || 'Server error';
+ resultfield.innerHTML = errorimg+'<SPAN STYLE="color: red;">'+result.syserror+'</SPAN>';
+ }
+ }
+ }
+ );
+ } else {
+ resultfield.innerHTML = '';
+ }
+ };
+}
+
<TD>
<INPUT ID="new_password" TYPE="password" NAME="new_password" SIZE="18">
<DIV ID="new_password_result"></DIV>
-<%= include('send_xmlhttp') %>
-<%= include('add_password_validation') %>
-<SCRIPT>
-add_password_validation('new_password');
-</SCRIPT>
+ <SCRIPT SRC="send_xmlhttp.js"></SCRIPT>
+ <SCRIPT SRC="add_password_validation.js"></SCRIPT>
+ <SCRIPT>
+ add_password_validation('new_password');
+ </SCRIPT>
</TD>
</TR>
<INPUT TYPE="hidden" NAME="session_id" VALUE="<%= $session_id %>">
<INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
+<DIV STYLE="background: <%= $box_bgcolor || '#c0c0c0' %>">
<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=2 CELLPADDING=0>
<%= if (!$error) {
<TR>
<TH ALIGN="right">New password: </TH>
- <TD><INPUT TYPE="password" NAME="new_password" SIZE="18"></TD>
+ <TD>
+ <INPUT ID="new_password" TYPE="password" NAME="new_password" SIZE="18">
+ </TD>
+ <TD>
+ <SPAN ID="new_password_result"></SPAN>
+ <SCRIPT SRC="send_xmlhttp.js"></SCRIPT>
+ <SCRIPT SRC="add_password_validation.js"></SCRIPT>
+ <SCRIPT>
+ add_password_validation('new_password',true);
+ </SCRIPT>
+ </TD>
</TR>
<TR>
<TH ALIGN="right">Re-enter new password: </TH>
<TD><INPUT TYPE="password" NAME="new_password2" SIZE="18"></TD>
+ <TD></TD>
</TR>
-
<TR>
- <TD COLSPAN=2 ALIGN="center"><INPUT TYPE="submit" VALUE="Change password"></TD>
+ <TD COLSPAN="2" ALIGN="center"><INPUT TYPE="submit" VALUE="Change password"></TD>
+ <TD></TD>
</TR>
END
%>
</TABLE>
+</DIV>
</FORM>
<%= $body_footer %>
process_forgot_password
do_process_forgot_password
process_forgot_password_session
+ validate_password_nologin
));
push @actions, @nologin_actions;
my %nologin_actions = map { $_=>1 } @nologin_actions;
)
}
+sub validate_password_nologin {
+ $action = 'validate_password'; #use same landing page
+ validate_passwd(
+ map { $_ => scalar($cgi->param($_)) }
+ qw( fieldid check_password )
+ )
+}
+
#--
sub do_template {
+++ /dev/null
-<SCRIPT>
-function rs_init_object () {
- var A;
- try {
- A=new ActiveXObject("Msxml2.XMLHTTP");
- } catch (e) {
- try {
- A=new ActiveXObject("Microsoft.XMLHTTP");
- } catch (oc) {
- A=null;
- }
- }
- if(!A && typeof XMLHttpRequest != "undefined")
- A = new XMLHttpRequest();
- if (!A)
- alert("Can't create XMLHttpRequest object");
- return A;
-}
-
-function send_xmlhttp (url,args,callback) {
- args = args || [];
- callback = callback || function (data) { return data };
- var content = '';
- for (var i = 0; i < args.length; i = i + 2) {
- content = content + "&" + args[i] + "=" + escape(args[i+1]);
- }
- content = content.replace( /[+]/g, '%2B'); // fix unescaped plus signs
-
- var xmlhttp = rs_init_object();
- xmlhttp.open("POST", url, true);
-
- xmlhttp.onreadystatechange = function() {
- if (xmlhttp.readyState != 4)
- return;
- if (xmlhttp.status == 200) {
- var data = xmlhttp.responseText;
- callback(data);
- }
- };
-
- xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- xmlhttp.send(content);
-}
-</SCRIPT>
-
--- /dev/null
+function rs_init_object () {
+ var A;
+ try {
+ A=new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ A=new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (oc) {
+ A=null;
+ }
+ }
+ if(!A && typeof XMLHttpRequest != "undefined")
+ A = new XMLHttpRequest();
+ if (!A)
+ alert("Can't create XMLHttpRequest object");
+ return A;
+}
+
+function send_xmlhttp (url,args,callback) {
+ args = args || [];
+ callback = callback || function (data) { return data };
+ var content = '';
+ for (var i = 0; i < args.length; i = i + 2) {
+ content = content + "&" + args[i] + "=" + escape(args[i+1]);
+ }
+ content = content.replace( /[+]/g, '%2B'); // fix unescaped plus signs
+
+ var xmlhttp = rs_init_object();
+ xmlhttp.open("POST", url, true);
+
+ xmlhttp.onreadystatechange = function() {
+ if (xmlhttp.readyState != 4)
+ return;
+ if (xmlhttp.status == 200) {
+ var data = xmlhttp.responseText;
+ callback(data);
+ }
+ };
+
+ xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xmlhttp.send(content);
+}
+
didselector
);
-sub add_password_validation {
- my $fieldid = shift;
- my $out = '';
- if ((-e './send_xmlhttp.html') && (-e './add_password_validation.html')) {
- my $template = new Text::Template( TYPE => 'FILE',
- SOURCE => "./send_xmlhttp.html",
- DELIMITERS => [ '<%=', '%>' ],
- UNTAINT => 1,
- )
- or die $Text::Template::ERROR;
- $out .= $template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi' );
- $template = new Text::Template( TYPE => 'FILE',
- SOURCE => "./add_password_validation.html",
- DELIMITERS => [ '<%=', '%>' ],
- UNTAINT => 1,
- )
- or die $Text::Template::ERROR;
- $out .= $template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi' );
- $out .= <<ENDOUT;
-<SCRIPT>
-add_password_validation('$fieldid');
-</SCRIPT>
-ENDOUT
- }
- return $out;
-}
-
-
<TD ALIGN="right">Password</TD>
<TD>
<INPUT ID="new_password" TYPE="password" NAME="_password" VALUE="$_password">
- <DIV ID="new_password_result"></DIV>
-ENDOUT
-
- $OUT .= add_password_validation('new_password');
-
- $OUT .= <<ENDOUT;
+ <SPAN ID="new_password_result"></SPAN>
+ <SCRIPT SRC="send_xmlhttp.js"></SCRIPT>
+ <SCRIPT SRC="add_password_validation.js"></SCRIPT>
+ <SCRIPT>
+ add_password_validation('new_password',true);
+ </SCRIPT>
</TD>
</TR>
<TR>
result = JSON.parse(result);
var resultfield = document.getElementById(result.fieldid);
if (resultfield) {
+ var errorimg = '<IMG SRC="<% $p %>images/error.png" style="width: 1em; display: inline-block; padding-right: .5em">';
+ var validimg = '<IMG SRC="<% $p %>images/tick.png" style="width: 1em; display: inline-block; padding-right: .5em">';
if (result.valid) {
- resultfield.innerHTML = '<SPAN STYLE="color: green;">Password valid!</SPAN>';
+ resultfield.innerHTML = validimg+'<SPAN STYLE="color: green;">Password valid!</SPAN>';
} else if (result.error) {
- resultfield.innerHTML = '<SPAN STYLE="color: red;">'+result.error+'</SPAN>';
+ resultfield.innerHTML = errorimg+'<SPAN STYLE="color: red;">'+result.error+'</SPAN>';
} else {
result.syserror = result.syserror || 'Server error';
- resultfield.innerHTML = '<SPAN STYLE="color: red;">'+result.syserror+'</SPAN>';
+ resultfield.innerHTML = errorimg+'<SPAN STYLE="color: red;">'+result.syserror+'</SPAN>';
}
}
}