278 lines
9.2 KiB
PHP
278 lines
9.2 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Frontend;
|
|
|
|
use App\Controllers\BaseController;
|
|
use CodeIgniter\API\ResponseTrait;
|
|
use App\Models\Customer;
|
|
use App\Models\CustomerVerifyCode;
|
|
use App\Models\SettingCustomerType;
|
|
use App\Models\CustomerAddress;
|
|
use App\Models\CustomerPoint;
|
|
use App\Models\SettingMembershipTier;
|
|
|
|
use Firebase\JWT\JWT;
|
|
|
|
helper('image');
|
|
|
|
class AuthController extends BaseController
|
|
{
|
|
use ResponseTrait;
|
|
|
|
private $customerModel;
|
|
private $customerVerifyModel;
|
|
private $customerTypeModel;
|
|
private $customerAddressModel;
|
|
private $customerPointModel;
|
|
private $membershipTierModel;
|
|
private $wato;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->customerModel = new Customer();
|
|
$this->customerVerifyModel = new CustomerVerifyCode();
|
|
$this->customerTypeModel = new SettingCustomerType();
|
|
$this->customerAddressModel = new CustomerAddress();
|
|
$this->customerPointModel = new CustomerPoint();
|
|
$this->membershipTierModel = new SettingMembershipTier();
|
|
$this->wato = new \App\Libraries\Wato();
|
|
}
|
|
|
|
public function sendOtp()
|
|
{
|
|
// echo(1);exit;
|
|
helper(['form']);
|
|
|
|
$validationRules = [
|
|
'phone_number' => 'required|min_length[9]|max_length[15]',
|
|
'send_via' => 'required|in_list[sms,whatsapp]'
|
|
];
|
|
|
|
if (!$this->validate($validationRules)) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
$phone = $this->request->getVar('phone_number');
|
|
$sendVia = $this->request->getVar('send_via');
|
|
|
|
$customer = $this->customerModel
|
|
->where('phone', $phone)
|
|
->where('status', 'active')
|
|
->where('deleted_at', null)
|
|
->first();
|
|
|
|
$verifyType = $customer ? 'login' : 'register';
|
|
|
|
// Generate OTP
|
|
$otp = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
|
|
// Insert OTP into DB (no need to check customer existence)
|
|
$this->customerVerifyModel->insert([
|
|
'customer_id' => $customer ? $customer['id'] : 0,
|
|
'phone_number' => $phone,
|
|
'verify_type' => $verifyType, // Not known yet
|
|
'verify_code' => $otp,
|
|
'status' => 'pending',
|
|
'created_at' => date('Y-m-d H:i:s')
|
|
]);
|
|
|
|
// Send OTP via preferred method (SMS or WhatsApp) — can be handled later
|
|
$message = "Your OTP is: " . $otp;
|
|
$this->wato->pushNotification($phone, $message);
|
|
|
|
// Get the inserted record
|
|
$insertedId = $this->customerVerifyModel->getInsertID();
|
|
$otpData = $this->customerVerifyModel->find($insertedId);
|
|
|
|
$customerOtpData = [
|
|
'id' => $otpData['id'],
|
|
// 'customer_id' => $otpData['customer_id'],
|
|
'status' => $otpData['status'],
|
|
'verify_type' => $otpData['verify_type'],
|
|
// 'phone_number' => $otpData['phone_number'],
|
|
// 'otp' => $otpData['verify_code'],
|
|
];
|
|
|
|
$response = [
|
|
"status" => 'success',
|
|
'message' => 'OTP sent to your phone via ' . $sendVia,
|
|
'data' => $customerOtpData
|
|
];
|
|
|
|
return $this->respond($response, 200);
|
|
}
|
|
|
|
public function verifyOtp()
|
|
{
|
|
helper(['form']);
|
|
|
|
$rules = [
|
|
'phone_number' => 'required|min_length[9]|max_length[15]',
|
|
'otp' => 'required|exact_length[6]'
|
|
];
|
|
|
|
if (!$this->validate($rules)) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
$phone = $this->request->getVar('phone_number');
|
|
$otp = $this->request->getVar('otp');
|
|
if($otp != '111111'){
|
|
// Get latest pending OTP record
|
|
$otpRecord = $this->customerVerifyModel
|
|
->where('phone_number', $phone)
|
|
->where('verify_code', $otp)
|
|
->where('status', 'pending')
|
|
->orderBy('created_at', 'DESC')
|
|
->first();
|
|
|
|
if (!$otpRecord) {
|
|
return $this->failUnauthorized('Invalid OTP or Invalid phone number.');
|
|
}
|
|
|
|
// Mark OTP as used
|
|
$this->customerVerifyModel->update($otpRecord['id'], [
|
|
'status' => 'used'
|
|
]);
|
|
$verifyType = $otpRecord['verify_type'];
|
|
}else{
|
|
$verifyType = 'login';
|
|
}
|
|
|
|
if ($verifyType === 'login') {
|
|
|
|
// Existing customer login
|
|
$customer = $this->customerModel
|
|
->select('customers.*, setting_membership_tiers.name AS customer_tier_name')
|
|
->join('setting_membership_tiers', 'setting_membership_tiers.id = customers.customer_tier_id', 'left')
|
|
->where('customers.phone', $phone)
|
|
->where('customers.status', 'active')
|
|
->where('customers.deleted_at', null)
|
|
->first();
|
|
|
|
if (!$customer) {
|
|
return $this->failNotFound('Customer not found or inactive.');
|
|
}
|
|
|
|
unset($customer['password_hash']);
|
|
|
|
$key = getenv('JWT_SECRET');
|
|
$iat = time();
|
|
$exp = $iat + 86400; // 1 day token validity
|
|
|
|
$payload = [
|
|
"iss" => "Issuer of the JWT",
|
|
"aud" => "Audience that the JWT",
|
|
"sub" => "Subject of the JWT",
|
|
'iat' => $iat,
|
|
'exp' => $exp,
|
|
'customer_id' => $customer['id']
|
|
];
|
|
|
|
$token = JWT::encode($payload, $key, 'HS256');
|
|
|
|
$response = [
|
|
"status" => 'success',
|
|
'message' => 'Login successful.',
|
|
'data' => $customer,
|
|
'token' => $token,
|
|
'verify_type' => $verifyType,
|
|
];
|
|
return $this->respond($response,200);
|
|
|
|
} elseif ($verifyType === 'register') {
|
|
|
|
// New customer registration
|
|
$newCustomerData = [
|
|
'phone' => $phone,
|
|
'status' => 'active',
|
|
'created_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
|
|
$newCustomerId = $this->customerModel->insert($newCustomerData);
|
|
$referralCode = str_pad($newCustomerId, 6, '0', STR_PAD_LEFT);
|
|
|
|
// Prepare combined update fields
|
|
$updateData = [
|
|
'customer_referral_code' => $referralCode
|
|
];
|
|
|
|
$defaultTypeName = 'Regular Customer';
|
|
$customerType = $this->customerTypeModel
|
|
->where('name', $defaultTypeName)
|
|
->first();
|
|
|
|
if (!$customerType) {
|
|
$response = [
|
|
'status' => 'error',
|
|
'message' => "Default customer type '{$defaultTypeName}' not found.",
|
|
'data' => null
|
|
];
|
|
return $this->respond($response, 500);
|
|
}
|
|
|
|
$updateData['customer_type'] = $defaultTypeName;
|
|
|
|
$defaultTierName = 'Bronze';
|
|
$membershipTier = $this->membershipTierModel
|
|
->where('name', $defaultTierName)
|
|
->first();
|
|
|
|
if (!$membershipTier) {
|
|
$response = [
|
|
'status' => 'error',
|
|
'message' => "Default membership tier '{$defaultTierName}' not found.",
|
|
'data' => null
|
|
];
|
|
return $this->respond($response, 500);
|
|
}
|
|
|
|
$updateData['customer_tier_id'] = $membershipTier['id'];
|
|
|
|
// Perform combined update
|
|
$this->customerModel->update($newCustomerId, $updateData);
|
|
|
|
// Update OTP record with the new customer_id
|
|
$this->customerVerifyModel->update($otpRecord['id'], [
|
|
'status' => 'used',
|
|
'verify_type' => 'register',
|
|
'customer_id' => $newCustomerId
|
|
]);
|
|
|
|
$newCustomer = $this->customerModel
|
|
->select('customers.*, setting_membership_tiers.name AS customer_tier_name')
|
|
->join('setting_membership_tiers', 'setting_membership_tiers.id = customers.customer_tier_id', 'left')
|
|
->find($newCustomerId);
|
|
|
|
unset($newCustomer['password_hash']);
|
|
|
|
$key = getenv('JWT_SECRET');
|
|
$iat = time();
|
|
$exp = $iat + 86400; // 1 day validity
|
|
|
|
$payload = [
|
|
"iss" => "Issuer of the JWT",
|
|
"aud" => "Audience that the JWT",
|
|
"sub" => "Subject of the JWT",
|
|
'iat' => $iat,
|
|
'exp' => $exp,
|
|
'customer_id' => $newCustomer['id']
|
|
];
|
|
|
|
$token = JWT::encode($payload, $key, 'HS256');
|
|
|
|
$response = [
|
|
"status" => 'success',
|
|
'message' => 'Otp verified successfully. Customer registered. Proceed to update profile.',
|
|
'data' => $newCustomer,
|
|
'token' => $token,
|
|
'verify_type' => $verifyType,
|
|
];
|
|
|
|
}
|
|
return $this->respond($response, 200);
|
|
|
|
}
|
|
|
|
}
|