From 9b1adb15da77047b85a65967ff3fcda8eaf12598 Mon Sep 17 00:00:00 2001 From: Ibnu Maksum Date: Fri, 20 Sep 2024 17:07:18 +0700 Subject: [PATCH] Forgot Password and Forgot Username for Customer, requested by fiberwan --- CHANGELOG.md | 6 + system/autoload/Message.php | 2 +- system/controllers/forgot.php | 252 +++++++++++++++++++++------------- system/lan/english.json | 3 +- ui/ui/user-ui/forgot.tpl | 164 ++++++++++++---------- version.json | 2 +- 6 files changed, 258 insertions(+), 171 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f9e0862..8b873a0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ # CHANGELOG +## 2024.9.20 + +- Forgot Password +- Forgot Username +- Public header template + ## 2024.9.13 - Add Selling Mikrotik VPN By @agstrxyz diff --git a/system/autoload/Message.php b/system/autoload/Message.php index cdc04525..1f880f03 100644 --- a/system/autoload/Message.php +++ b/system/autoload/Message.php @@ -217,7 +217,7 @@ class Message ) { if ($via == 'sms') { Message::sendSMS($phone, $msg); - } else if ($config['user_notification_payment'] == 'email') { + } else if ($via == 'email') { self::sendEmail($cust['email'], '[' . $config['CompanyName'] . '] ' . Lang::T("Balance Notification"), $msg); } else if ($via == 'wa') { Message::sendWhatsapp($phone, $msg); diff --git a/system/controllers/forgot.php b/system/controllers/forgot.php index 4b711dfe..57b7c680 100644 --- a/system/controllers/forgot.php +++ b/system/controllers/forgot.php @@ -4,111 +4,165 @@ * PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/) * by https://t.me/ibnux **/ -$do = ''; -if (isset($routes['1'])) { - $do = $routes['1']; -} - +$step = _req('step', 0); $otpPath = $CACHE_PATH . File::pathFixer('/forgot/'); -switch ($do) { - case 'post': - $otp_code = _post('otp_code'); - $username = alphanumeric(_post('username'), "+_.@-"); - $email = _post('email'); - $fullname = _post('fullname'); - $password = _post('password'); - $cpassword = _post('cpassword'); - $address = _post('address'); - if (!empty($config['sms_url']) && $_c['allow_phone_otp'] == 'yes') { - $phonenumber = Lang::phoneFormat($username); - $username = $phonenumber; - } else if (strlen($username) < 21) { - $phonenumber = $username; - } - $msg = ''; - if (Validator::Length($username, 35, 2) == false) { - $msg .= 'Username should be between 3 to 55 characters' . '
'; - } - if (Validator::Length($fullname, 36, 2) == false) { - $msg .= 'Full Name should be between 3 to 25 characters' . '
'; - } - if (!Validator::Length($password, 35, 2)) { - $msg .= 'Password should be between 3 to 35 characters' . '
'; - } - if (!Validator::Email($email)) { - $msg .= 'Email is not Valid
'; - } - if ($password != $cpassword) { - $msg .= Lang::T('Passwords does not match') . '
'; - } +if ($step == '-1') { + $_COOKIE['forgot_username'] = ''; + setcookie('forgot_username', '', time() - 3600, '/'); + $step = 0; +} - if (!empty($config['sms_url']) && $_c['allow_phone_otp'] == 'yes') { +if (!empty($_COOKIE['forgot_username']) && in_array($step, [0, 1])) { + $step = 1; + $_POST['username'] = $_COOKIE['forgot_username']; +} + +if ($step == 1) { + $username = _post('username'); + if (!empty($username)) { + $ui->assign('username', $username); + if (!file_exists($otpPath)) { + mkdir($otpPath); + } + setcookie('forgot_username', $username, time() + 3600, '/'); + $user = ORM::for_table('tbl_customers')->selects(['phonenumber', 'email'])->where('username', $username)->find_one(); + if ($user) { $otpPath .= sha1($username . $db_pass) . ".txt"; - run_hook('validate_otp'); #HOOK - //expired 10 minutes - if (file_exists($otpPath) && time() - filemtime($otpPath) > 1200) { - unlink($otpPath); - r2(U . 'register', 's', 'Verification code expired'); - } else if (file_exists($otpPath)) { - $code = file_get_contents($otpPath); - if ($code != $otp_code) { - $ui->assign('username', $username); - $ui->assign('fullname', $fullname); - $ui->assign('address', $address); - $ui->assign('email', $email); - $ui->assign('phonenumber', $phonenumber); - $ui->assign('notify', 'Wrong Verification code'); - $ui->assign('notify_t', 'd'); - $ui->display('user-ui/register-otp.tpl'); - exit(); - } else { - unlink($otpPath); + if (file_exists($otpPath) && time() - filemtime($otpPath) < 600) { + $ui->assign('notify_t', 's'); + $ui->assign('notify', Lang::T("If your Username is found, Verification Code has been Sent to Your Phone/Email/Whatsapp")); + } else { + $via = $config['user_notification_reminder']; + if ($via == 'email') { + $via = 'sms'; } - } else { - r2(U . 'register', 's', 'No Verification code'); - } - } - $d = ORM::for_table('tbl_customers')->where('username', $username)->find_one(); - if ($d) { - $msg .= Lang::T('Account already axist') . '
'; - } - if ($msg == '') { - run_hook('register_user'); #HOOK - $d = ORM::for_table('tbl_customers')->create(); - $d->username = alphanumeric($username, "+_.@-"); - $d->password = $password; - $d->fullname = $fullname; - $d->address = $address; - $d->email = $email; - $d->phonenumber = $phonenumber; - if ($d->save()) { - $user = $d->id(); - r2(U . 'login', 's', Lang::T('Register Success! You can login now')); - } else { - $ui->assign('username', $username); - $ui->assign('fullname', $fullname); - $ui->assign('address', $address); - $ui->assign('email', $email); - $ui->assign('phonenumber', $phonenumber); - $ui->assign('notify', 'Failed to register'); - $ui->assign('notify_t', 'd'); - run_hook('view_otp_register'); #HOOK - $ui->display('user-ui/register-rotp.tpl'); + $otp = mt_rand(100000, 999999); + file_put_contents($otpPath, $otp); + if ($via == 'sms') { + Message::sendSMS($user['phonenumber'], $config['CompanyName'] . " C0de: $otp"); + } else { + Message::sendWhatsapp($user['phonenumber'], $config['CompanyName'] . " C0de: $otp"); + } + Message::sendEmail( + $user['email'], + $config['CompanyName'] . Lang::T("Your Verification Code") . ' : ' . $otp, + Lang::T("Your Verification Code") . ' : ' . $otp . '' + ); + $ui->assign('notify_t', 's'); + $ui->assign('notify', Lang::T("If your Username is found, Verification Code has been Sent to Your Phone/Email/Whatsapp")); } } else { - $ui->assign('username', $username); - $ui->assign('fullname', $fullname); - $ui->assign('address', $address); - $ui->assign('email', $email); - $ui->assign('phonenumber', $phonenumber); - $ui->assign('notify', $msg); - $ui->assign('notify_t', 'd'); - $ui->display('user-ui/register.tpl'); + // Username not found + $ui->assign('notify_t', 's'); + $ui->assign('notify', Lang::T("If your Username is found, Verification Code has been Sent to Your Phone/Email/Whatsapp") . "."); } - break; - - default: - $ui->display('user-ui/forgot.tpl'); - break; + } else { + $step = 0; + } +} else if ($step == 2) { + $username = _post('username'); + $otp_code = _post('otp_code'); + if (!empty($username) && !empty($otp_code)) { + $otpPath .= sha1($username . $db_pass) . ".txt"; + if (file_exists($otpPath) && time() - filemtime($otpPath) <= 600) { + $otp = file_get_contents($otpPath); + if ($otp == $otp_code) { + $pass = mt_rand(10000, 99999); + $user = ORM::for_table('tbl_customers')->where('username', $username)->find_one(); + $user->password = $pass; + $user->save(); + $ui->assign('username', $username); + $ui->assign('passsword', $pass); + $ui->assign('notify_t', 's'); + $ui->assign('notify', Lang::T("Verification Code Valid")); + if (file_exists($otpPath)) { + unlink($otpPath); + } + setcookie('forgot_username', '', time() - 3600, '/'); + } else { + r2(U . 'forgot&step=1', 'e', Lang::T('Invalid Username or Verification Code')); + } + } else { + if (file_exists($otpPath)) { + unlink($otpPath); + } + r2(U . 'forgot&step=1', 'e', Lang::T('Invalid Username or Verification Code')); + } + } else { + r2(U . 'forgot&step=1', 'e', Lang::T('Invalid Username or Verification Code')); + } +} else if ($step == 7) { + $find = _post('find'); + $step = 6; + if (!empty($find)) { + $via = $config['user_notification_reminder']; + if ($via == 'email') { + $via = 'sms'; + } + if (!file_exists($otpPath)) { + mkdir($otpPath); + } + $otpPath .= sha1($find . $db_pass) . ".txt"; + $users = ORM::for_table('tbl_customers')->selects(['username', 'phonenumber', 'email'])->where('phonenumber', $find)->find_array(); + if ($users) { + // prevent flooding only can request every 10 minutes + if (!file_exists($otpPath) || (file_exists($otpPath) && time() - filemtime($otpPath) >= 600)) { + $usernames = implode(", ", array_column($users, 'username')); + if ($via == 'sms') { + Message::sendSMS($find, Lang::T("Your username for") . ' ' . $config['CompanyName'] . "\n" . $usernames); + } else { + Message::sendWhatsapp($find, Lang::T("Your username for") . ' ' . $config['CompanyName'] . "\n" . $usernames); + } + file_put_contents($otpPath, time()); + } + $ui->assign('notify_t', 's'); + $ui->assign('notify', Lang::T("Usernames have been sent to your phone/Whatsapp") . " $find"); + $step = 0; + } else { + $users = ORM::for_table('tbl_customers')->selects(['username', 'phonenumber', 'email'])->where('email', $find)->find_array(); + if ($users) { + // prevent flooding only can request every 10 minutes + if (!file_exists($otpPath) || (file_exists($otpPath) && time() - filemtime($otpPath) >= 600)) { + $usernames = implode(", ", array_column($users, 'username')); + $phones = []; + foreach ($users as $user) { + if (!in_array($user['phonenumber'], $phones)) { + if ($via == 'sms') { + Message::sendSMS($user['phonenumber'], Lang::T("Your username for") . ' ' . $config['CompanyName'] . "\n" . $usernames); + } else { + Message::sendWhatsapp($user['phonenumber'], Lang::T("Your username for") . ' ' . $config['CompanyName'] . "\n" . $usernames); + } + $phones[] = $user['phonenumber']; + } + } + Message::sendEmail( + $user['email'], + Lang::T("Your username for") . ' ' . $config['CompanyName'], + Lang::T("Your username for") . ' ' . $config['CompanyName'] . "\n" . $usernames + ); + file_put_contents($otpPath, time()); + } + $ui->assign('notify_t', 's'); + $ui->assign('notify', Lang::T("Usernames have been sent to your phone/Whatsapp/Email")); + $step = 0; + } else { + $ui->assign('notify_t', 'e'); + $ui->assign('notify', Lang::T("No data found")); + } + } + } } + +// delete old files +$pth = $CACHE_PATH . File::pathFixer('/forgot/'); +$fs = scandir($pth); +foreach ($fs as $file) { + if(is_file($pth.$file) && time() - filemtime($pth.$file) > 3600) { + unlink($pth.$file); + } +} + +$ui->assign('step', $step); +$ui->assign('_title', Lang::T('Forgot Password')); +$ui->display('user-ui/forgot.tpl'); diff --git a/system/lan/english.json b/system/lan/english.json index b1e78a05..81315026 100644 --- a/system/lan/english.json +++ b/system/lan/english.json @@ -724,5 +724,6 @@ "Mail_Reply_To": "Mail Reply To", "Customer_will_reply_email_to_this_address__empty_if_you_want_to_use_From_Address": "Customer will reply email to this address, empty if you want to use From Address", "You_will_get_Payment_and_Error_notification": "You will get Payment and Error notification", - "Languge_set_to_english": "Bahasa diatur ke bahasa Inggris" + "Languge_set_to_english": "Bahasa diatur ke bahasa Inggris", + "Forgot_Password": "Forgot Password" } \ No newline at end of file diff --git a/ui/ui/user-ui/forgot.tpl b/ui/ui/user-ui/forgot.tpl index 2289533c..b905a6e9 100644 --- a/ui/ui/user-ui/forgot.tpl +++ b/ui/ui/user-ui/forgot.tpl @@ -1,73 +1,99 @@ {include file="user-ui/header-public.tpl"} -
-
-
-
{Lang::T('Announcement')}
-
- {$Announcement = "{$PAGES_PATH}/Announcement.html"} - {if file_exists($Announcement)} - {include file=$Announcement} - {/if} -
+ + +
+
+
+ {if $step == 1} +
+
{Lang::T('Verification Code')}
+
+
+
+ {if $_c['country_code_phone']!= ''} + + {else} + + {/if} + +
+
+
+
+ + +
+
+
+ +
+ {elseif $step == 2} +
+
{Lang::T('Success')}
+
+
+ +
+ {if $_c['country_code_phone']!= ''} + + {else} + + {/if} + +
+
+ + +

+ {Lang::T('Use the password to login, and change the password from password change page')}

+
+ +
+ {elseif $step == 6} +
+
{Lang::T('Forgot Username')}
+
+ + +
+ +
+ {else} +
+
{Lang::T('Forgot Password')}
+
+
+ +
+ {if $_c['country_code_phone']!= ''} + + {else} + + {/if} + +
+
+
+ +
+ {/if}
-
-
-
{Lang::T('Log in to Member Panel')}
-
- -
- -
- {if $_c['country_code_phone']!= ''} - - {else} - - {/if} - -
- -
-
- -
- - -
-
- - -
- -
- -
-
-
-
- {Lang::T('Forgot Password')} -
- Privacy - • - T & C -
- -
-
-
-
+ {include file="user-ui/footer-public.tpl"} \ No newline at end of file diff --git a/version.json b/version.json index 13f748ef..6efc45b5 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "2024.9.13" + "version": "2024.9.20" } \ No newline at end of file