summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorivan <ivan>2011-10-30 23:28:16 +0000
committerivan <ivan>2011-10-30 23:28:16 +0000
commit6e8323cf946ef3684a6846aa6afde7fe3692994e (patch)
tree629678e95d0b8dd40f9c790a8caed9a90341b3dc /FS
parent2543cd5e16887a7976649e8f23818b64f397d2a6 (diff)
selfservice password reset, RT#13656
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/ClientAPI/MyAccount.pm98
-rw-r--r--FS/FS/ClientAPI_XMLRPC.pm2
-rw-r--r--FS/FS/Conf.pm9
-rw-r--r--FS/FS/msg_template.pm10
4 files changed, 109 insertions, 10 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index 36d1fe7..784a33f 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -4,12 +4,16 @@ use 5.008; #require 5.8+ for Time::Local 1.05+
use strict;
use vars qw( $cache $DEBUG $me );
use subs qw( _cache _provision );
+use IO::Scalar;
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
use Date::Format;
-use Business::CreditCard;
use Time::Duration;
use Time::Local qw(timelocal_nocheck);
+use Business::CreditCard;
+use HTML::Entities;
+use Text::CSV_XS;
+use Spreadsheet::WriteExcel;
use FS::UI::Web::small_custview qw(small_custview); #less doh
use FS::UI::Web;
use FS::UI::bytecount qw( display_bytecount );
@@ -19,6 +23,7 @@ use FS::Record qw(qsearch qsearchs dbh);
use FS::Msgcat qw(gettext);
use FS::Misc qw(card_types);
use FS::Misc::DateTime qw(parse_datetime);
+use FS::TicketSystem;
use FS::ClientAPI_SessionCache;
use FS::cust_svc;
use FS::svc_acct;
@@ -35,11 +40,7 @@ use FS::cust_main_county;
use FS::cust_pkg;
use FS::payby;
use FS::acct_rt_transaction;
-use HTML::Entities;
-use FS::TicketSystem;
-use Text::CSV_XS;
-use IO::Scalar;
-use Spreadsheet::WriteExcel;
+use FS::msg_template;
$DEBUG = 0;
$me = '[FS::ClientAPI::MyAccount]';
@@ -2396,12 +2397,93 @@ sub reset_passwd {
}
- #we're verified. now what?
-
+ #okay, we're verified, now create a unique session
+
+ my $reset_session = {
+ 'svcnum' => $svc_acct->svcnum,
+ };
+
+ my $timeout = '1 hour'; #?
+
+ my $reset_session_id;
+ do {
+ $reset_session_id = md5_hex(md5_hex(time(). {}. rand(). $$))
+ } until ( ! defined _cache->get("reset_passwd_$reset_session_id") ); #just in case
+
+ _cache->set( "reset_passwd_$reset_session_id", $reset_session, $timeout );
+
+ #email it
+
+ my $msgnum = $conf->config('selfservice-password_reset_msgnum', $cust_main->agentnum);
+ #die "selfservice-password_reset_msgnum unset" unless $msgnum;
+ return { 'error' => "selfservice-password_reset_msgnum unset" } unless $msgnum;
+ my $msg_template = qsearchs('msg_template', { msgnum => $msgnum } );
+ my $error = $msg_template->send( 'cust_main' => $cust_main,
+ 'object' => $svc_acct,
+ 'substitutions' => {
+ 'session_id' => $reset_session_id,
+ }
+ );
+ if ( $error ) {
+ return { 'error' => $error }; #????
+ }
return { 'error' => '' };
}
+sub check_reset_passwd {
+ my $p = shift;
+
+ my $conf = new FS::Conf;
+ my $verification = $conf->config('selfservice-password_reset_verification')
+ or return { 'error' => 'Password resets disabled' };
+
+ my $reset_session = _cache->get('reset_passwd_'. $p->{'session_id'})
+ or return { 'error' => "Can't resume session" }; #better error message
+
+ my $svcnum = $reset_session->{'svcnum'};
+
+ my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } )
+ or return { 'error' => "Service not found" };
+
+ return { 'error' => '',
+ 'username' => $svc_acct->username,
+ };
+
+}
+
+sub process_reset_passwd {
+ my $p = shift;
+
+ my $conf = new FS::Conf;
+ my $verification = $conf->config('selfservice-password_reset_verification')
+ or return { 'error' => 'Password resets disabled' };
+
+ return { 'error' => "New passwords don't match." }
+ if $p->{'new_password'} ne $p->{'new_password2'};
+
+ return { 'error' => 'Enter new password' }
+ unless length($p->{'new_password'});
+
+ my $reset_session = _cache->get('reset_passwd_'. $p->{'session_id'})
+ or return { 'error' => "Can't resume session" }; #better error message
+
+ my $svcnum = $reset_session->{'svcnum'};
+
+ my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } )
+ or return { 'error' => "Service not found" };
+
+ $svc_acct->_password($p->{'new_password'});
+ my $error = $svc_acct->replace();
+
+ my($label, $value) = $svc_acct->cust_svc->label;
+
+ return { 'error' => $error,
+ #'label' => $label,
+ #'value' => $value,
+ };
+
+}
sub create_ticket {
my $p = shift;
diff --git a/FS/FS/ClientAPI_XMLRPC.pm b/FS/FS/ClientAPI_XMLRPC.pm
index 66d0740..5d91962 100644
--- a/FS/FS/ClientAPI_XMLRPC.pm
+++ b/FS/FS/ClientAPI_XMLRPC.pm
@@ -111,6 +111,8 @@ sub ss2clientapi {
'unprovision_svc' => 'MyAccount/unprovision_svc',
'myaccount_passwd' => 'MyAccount/myaccount_passwd',
'reset_passwd' => 'MyAccount/reset_passwd',
+ 'check_reset_passwd' => 'MyAccount/check_reset_passwd',
+ 'process_reset_passwd' => 'MyAccount/process_reset_passwd',
'create_ticket' => 'MyAccount/create_ticket',
'get_ticket' => 'MyAccount/get_ticket',
'adjust_ticket_priority' => 'MyAccount/adjust_ticket_priority',
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 5488806..dd3af2d 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -2476,7 +2476,14 @@ and customer address. Include units.',
'paymask,amount,zip' => 'Verify with credit card (or bank account) last 4 digits, payment amount and zip code',
],
},
-
+
+ {
+ 'key' => 'selfservice-password_reset_msgnum',
+ 'section' => 'self-service',
+ 'description' => 'Template to use for password reset emails.',
+ %msg_template_options,
+ },
+
{
'key' => 'selfservice-recent-did-age',
'section' => 'self-service',
diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm
index d980ab9..50efcdb 100644
--- a/FS/FS/msg_template.pm
+++ b/FS/FS/msg_template.pm
@@ -262,6 +262,10 @@ The I<from_addr> field in the template takes precedence over this.
Destination address. The default is to use the customer's
invoicing_list addresses. Multiple addresses may be comma-separated.
+=item substitutions
+
+A hash reference of additional substitutions
+
=back
=cut
@@ -324,8 +328,12 @@ sub prepare {
}
}
}
- $_ = encode_entities($_ || '') foreach values(%hash);
+ if ( $opt{substitutions} ) {
+ $hash{$_} = $opt{substitutions}->{$_} foreach keys %{$opt{substitutions}};
+ }
+
+ $_ = encode_entities($_ || '') foreach values(%hash);
###
# clean up template