From 1b3270aae0a711f9d7cf7622dce56d8a0c4fe5d1 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Mon, 10 Nov 2025 14:14:17 +0530 Subject: [PATCH] FEAT_PASSWORD_LOGIN_API --- app/Config/Routes.php | 7 +- .../RestAuthenticationController.php | 383 +++++++++--------- app/Models/EmployeeModel.php | 1 + 3 files changed, 203 insertions(+), 188 deletions(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index bbddfdec..af9b67e1 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -506,6 +506,7 @@ $routes->post("/employeeRest/getVerifiedUserData", "RestAuthenticationController $routes->post("/employeeRest/verifyEmployeeEmailId", "RestAuthenticationController::verifyEmployeeWithEmailId"); $routes->post("/employeeRest/updateEmpOTP", "RestAuthenticationController::updateEmpOTP"); +// MPIN api's $routes->post("employeeRest/saveMpin", "RestAuthenticationController::saveMpin"); $routes->post("employeeRest/updateMpin", "RestAuthenticationController::updateMpin"); $routes->post("/employeeRest/verifyMpin", "RestAuthenticationController::verifyMpin"); @@ -513,8 +514,12 @@ $routes->post("/employeeRest/checkMpin", "RestAuthenticationController::checkMpi $routes->post("/employeeRest/updateEmpMPIN", "RestAuthenticationController::updateEmpMPIN"); $routes->post("employeeRest/forgotMPIN", "RestAuthenticationController::forgotMPIN"); $routes->post("employeeRest/updateMobileNumber", "RestAuthenticationController::updateMobileNumber"); -// $routes->post("/employeeRest/saveMpin", "RestAuthenticationController::saveMpin"); +// PASSWORD api's +$routes->post("employeeRest/savePassword", "RestAuthenticationController::savePassword"); +$routes->post("employeeRest/changePassword", "RestAuthenticationController::changePassword"); +$routes->post("employeeRest/verifyPassword", "RestAuthenticationController::verifyPassword"); +$routes->post("employeeRest/verifyOtp", "RestAuthenticationController::verifyOtp"); //HR login api's $routes->post("/employeeRest/verifyHrWithMobileNumber", "RestAuthenticationController::verifyHrWithMobileNumber"); diff --git a/app/Controllers/RestAuthenticationController.php b/app/Controllers/RestAuthenticationController.php index 11b1a8fc..c5630624 100755 --- a/app/Controllers/RestAuthenticationController.php +++ b/app/Controllers/RestAuthenticationController.php @@ -1515,9 +1515,116 @@ class RestAuthenticationController extends AdminController $email_id = $payload->email_id ?? null; $client_id = $payload->client_id ?? null; $plain_password = $payload->password ?? null; + $confirm_password = $payload->confirm_password ?? null; - if (empty($plain_password)) { - return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Password cannot be empty'], 400); + if (empty($plain_password) || empty($confirm_password)) { + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Both password cannot be empty'], 400); + } + + if($plain_password !== $confirm_password){ + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Password and confirm password not matched'], 400); + } + + // Build employee query + if ($mobile_number) { + + $builder = $this->employeeModel + ->select('employees.*') + ->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->where('employees.mobile', $mobile_number) + ->where('employees.relationship', 'Self') + ->where('employee_polices.is_active', 1) + ->whereIn('employee_polices.status', ['active', 'expired']) + ->where('employees.is_active', 1) + ->whereIn('employees.emp_status', ['active', 'expired']); + if (!empty($client_id)) $builder->where('employees.client_id', $client_id); + $employeeData = $builder->orderBy('employees.id', 'desc')->first(); + + } else { + + $builder = $this->employeeModel + ->select('employees.*') + ->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->where('employees.email_corporate', $email_id) + ->where('employees.relationship', 'Self') + ->where('employee_polices.is_active', 1) + ->whereIn('employee_polices.status', ['active', 'expired']) + ->where('employees.is_active', 1) + ->whereIn('employees.emp_status', ['active', 'expired']); + if (!empty($client_id)) $builder->where('employees.client_id', $client_id); + $employeeData = $builder->orderBy('employees.id', 'desc')->first(); + + } + + $lastQuery = $this->employeeModel->db->getLastQuery(); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Last Executed Query: " . $lastQuery); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: employeeData: " . json_encode($employeeData ?? [])); + + + if ($employeeData) { + $id = $employeeData['id']; + $hashedPassword = password_hash($plain_password, PASSWORD_DEFAULT); + + $updateData = [ + 'password' => $hashedPassword, + ]; + + $updated = $this->employeeModel->where('id', $id)->set($updateData)->update(); + + if ($updated) { + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Password saved successfully"); + $result = ['user_verification' => true, 'message' => "Password saved successfully"]; + return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200); + } else { + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Password save failed"); + $result = ['user_verification' => true, 'message' => "Password not saved"]; + return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $result], 200); + } + } else { + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Employee not found"); + $result = ['user_verification' => false, 'message' => "User not found"]; + return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200); + } + } catch (\Throwable $th) { + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine() . " --- Trace: " . $th->getTraceAsString()); + $errorData = [ + 'message' => $th->getMessage(), + 'file' => $th->getFile(), + 'line' => $th->getLine(), + 'code' => $th->getCode(), + 'trace' => $th->getTraceAsString(), + 'trace_array' => $th->getTrace(), // full array version (optional) + 'function' => $th->getTrace()[0]['function'] ?? null, + 'class' => $th->getTrace()[0]['class'] ?? null, + ]; + return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $th->getMessage(), 'errorData' => $errorData], 500); + } + } + + public function changePassword() + { + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Received payload = " . json_encode($this->request->getJSON() ?? [])); + + try { + + $payload = $this->request->getJSON(true); + $mobile_number = $payload['mobile_number'] ?? null; + $email_id = $payload['email_id'] ?? null; + $client_id = $payload['client_id'] ?? null; + $old_password = $payload['old_password'] ?? null; + $new_password = $payload['new_password'] ?? null; + $confirm_password = $payload['confirm_password'] ?? null; + + if (!$mobile_number && !$email_id) { + return $this->respond(['status' => 'failed','code' => 400,'message' => 'Mobile number or Email ID is required'], 400); + } + + if (empty($new_password) || empty($confirm_password) || empty($old_password)) { + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'old_password , New password and Confirm password are required' ], 400); + } + + if($new_password !== $confirm_password){ + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'New password and confirm password not matched'], 400); } // Build employee query @@ -1555,161 +1662,57 @@ class RestAuthenticationController extends AdminController $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Last Executed Query: " . $lastQuery); $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: employeeData: " . json_encode($employeeData ?? [])); - if ($employeeData) { - $id = $employeeData['id']; - $hashedPassword = password_hash($plain_password, PASSWORD_DEFAULT); + if ($employeeData && password_verify($old_password, $employeeData['password'])) { - $updateData = [ - 'password' => $hashedPassword, - ]; + // Hash new password + // $newHashedPassword = password_hash($new_password, PASSWORD_DEFAULT); + $newHashedPassword = $new_password; - $updated = $this->employeeModel->where('id', $id)->set($updateData)->update(); + // Update password and clear OTP + $updated = $this->employeeModel->update($employeeData['id'], [ + 'password' => $newHashedPassword, + ]); if ($updated) { - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Password saved successfully"); - $result = ['user_verification' => true, 'message' => "Password saved successfully"]; - return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Password updated successfully"); + return $this->respond(['status' => 'success','code' => 200,'message' => 'Password changed successfully'], 200); } else { - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Password save failed"); - $result = ['user_verification' => true, 'message' => "Password not saved"]; - return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $result], 200); + return $this->respond(['status' => 'failed','code' => 500,'message' => 'Failed to update password' ], 500); } - } else { - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Employee not found"); - $result = ['user_verification' => false, 'message' => "User not found"]; - return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200); - } - } catch (\Throwable $th) { - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine() . " --- Trace: " . $th->getTraceAsString()); - return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $th->getMessage()], 500); - } - } - public function changePassword() - { - log_message('error', ' '); - log_message('error', ' ************************************* CHANGE PASSWORD START **************************************** '); - log_message('error', ' '); - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Function called"); - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Received payload = " . json_encode($this->request->getJSON() ?? [])); - - try { - $payload = $this->request->getJSON(true); - - $mobile_number = $payload['mobile_number'] ?? null; - $email_id = $payload['email_id'] ?? null; - $client_id = $payload['client_id'] ?? null; - $otp = $payload['otp'] ?? null; - $new_password = $payload['new_password'] ?? null; - - if (empty($otp) || empty($new_password)) { - return $this->respond([ - 'status' => 'failed', - 'code' => 400, - 'message' => 'OTP and new password are required' - ], 400); - } - - // Fetch employee details - $builder = $this->employeeModel - ->select('employees.*') - ->join('employee_polices', 'employees.id = employee_polices.employee_id') - ->where('employees.relationship', 'Self') - ->where('employees.is_active', 1) - ->whereIn('employees.emp_status', ['active']) - ->where('employee_polices.is_active', 1) - ->whereIn('employee_polices.status', ['active']); - - if (!empty($client_id)) $builder->where('employees.client_id', $client_id); - - if ($mobile_number) { - $builder->where('employees.mobile', $mobile_number); - } elseif ($email_id) { - $builder->where('employees.email_corporate', $email_id); - } else { - return $this->respond([ - 'status' => 'failed', - 'code' => 400, - 'message' => 'Mobile number or Email ID is required' - ], 400); - } - - $employeeData = $builder->orderBy('employees.id', 'desc')->first(); - - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: employeeData: " . json_encode($employeeData ?? [])); - - if (!$employeeData) { + }else{ return $this->respond(['status' => 'failed', 'code' => 404, 'message' => 'User not found'], 404); } - // Check OTP validity (assuming fields: otp, otp_expiry exist) - if (empty($employeeData['otp']) || $employeeData['otp'] != $otp) { - return $this->respond(['status' => 'failed', 'code' => 401, 'message' => 'Invalid OTP'], 200); - } - - if (!empty($employeeData['otp_expiry']) && strtotime($employeeData['otp_expiry']) < time()) { - return $this->respond(['status' => 'failed', 'code' => 401, 'message' => 'OTP expired'], 200); - } - - // Hash new password - $newHashedPassword = password_hash($new_password, PASSWORD_DEFAULT); - - // Update password and clear OTP - $updated = $this->employeeModel->update($employeeData['id'], [ - 'password' => $newHashedPassword, - 'otp' => null, - ]); - - if ($updated) { - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Password updated successfully"); - log_message('error', ' '); - log_message('error', ' ************************************* CHANGE PASSWORD END **************************************** '); - log_message('error', ' '); - - return $this->respond([ - 'status' => 'success', - 'code' => 200, - 'message' => 'Password changed successfully' - ], 200); - } else { - return $this->respond([ - 'status' => 'failed', - 'code' => 500, - 'message' => 'Failed to update password' - ], 500); - } - } catch (\Throwable $th) { $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Exception: " . $th->getMessage()); - log_message('error', ' '); - log_message('error', ' ************************************* CHANGE PASSWORD END **************************************** '); - log_message('error', ' '); return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $th->getMessage()], 500); } } public function verifyPassword() { - log_message('error', ' '); - log_message('error', ' ************************************* POST START **************************************** '); - log_message('error', ' '); - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - Verify Password: Function called"); $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Received payload = " . json_encode($this->request->getJSON() ?? [])); try { - $requestData = $this->request->getJSON(true); + $requestData = $this->request->getJSON(true); $mobile_number = $requestData['mobile_number'] ?? null; $email_id = $requestData['email_id'] ?? null; $password = $requestData['password'] ?? null; $client_id = $requestData['client_id'] ?? null; + if(!$mobile_number && !$email_id){ + return $this->respond(['status' => 'failed', 'code' => 400, 'data' => "", 'message' => 'Mobile number or Email ID is required'], 400); + } + if (!$password) { return $this->respond(['status' => 'failed', 'code' => 400, 'data' => "", 'message' => 'Password is required'], 400); } // 🔹 Fetch employee data if ($mobile_number) { + $builder = $this->employeeModel ->select('employees.*') ->join('employee_polices', 'employees.id = employee_polices.employee_id') @@ -1725,7 +1728,9 @@ class RestAuthenticationController extends AdminController } $employeeData = $builder->orderBy('employees.id', 'desc')->first(); + } elseif ($email_id) { + $builder = $this->employeeModel ->select('employees.*') ->join('employee_polices', 'employees.id = employee_polices.employee_id') @@ -1741,9 +1746,8 @@ class RestAuthenticationController extends AdminController } $employeeData = $builder->orderBy('employees.id', 'desc')->first(); - } else { - return $this->respond(['status' => 'failed', 'code' => 400, 'data' => "", 'message' => 'Mobile number or Email ID is required'], 400); - } + + } $lastQuery = $this->employeeModel->db->getLastQuery(); $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Last Executed Query: " . $lastQuery); @@ -1770,11 +1774,8 @@ class RestAuthenticationController extends AdminController $employeeData['token_type'] = "post"; $token = JWTToken::encode($employeeData); - log_message('error', ' '); - log_message('error', ' ************************************* POST END **************************************** '); - log_message('error', ' '); - return $this->respond(['status' => 'success', 'code' => 200, 'data' => $token], 200); + } else { $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Invalid password or employee not found"); log_message('error', ' '); @@ -1783,6 +1784,7 @@ class RestAuthenticationController extends AdminController return $this->respond(['status' => 'failed', 'code' => 404, 'data' => "", 'message' => 'Invalid password'], 200); } + } catch (\Exception $e) { $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Exception: " . $e->getMessage() . " --- Line: " . $e->getLine()); log_message('error', ' '); @@ -1792,75 +1794,82 @@ class RestAuthenticationController extends AdminController } } - public function sendChangePasswordOTP() + public function verifyOtp() { - log_message('error', ' '); - log_message('error', ' ************************************* SEND OTP START **************************************** '); - log_message('error', ' '); - - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - sendChangePasswordOTP: Function called"); - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - sendChangePasswordOTP: Received payload = " . json_encode($this->request->getJSON() ?? [])); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Received payload = " . json_encode($this->request->getJSON() ?? [])); try { - $requestData = $this->request->getJSON(true); + $requestData = $this->request->getJSON(true); + $mobile_number = $requestData['mobile_number'] ?? null; $email_id = $requestData['email_id'] ?? null; $client_id = $requestData['client_id'] ?? null; + $otp = $requestData['otp'] ?? null; - if (!$email_id) { - return $this->respond(['status' => 'failed', 'code' => 400, 'data' => "", 'message' => 'Email ID is required'], 400); + if(!$mobile_number && !$email_id){ + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Mobile number or Email ID is required'], 400); } - // Get employee details - $builder = $this->employeeModel - ->select('employees.id, employees.mobile, employees.email_corporate, employees.client_id') - ->join('employee_polices', 'employees.id = employee_polices.employee_id') - ->where('employees.is_active', 1) - ->whereIn('employees.emp_status', ['active']) - ->where('employee_polices.is_active', 1) - ->whereIn('employee_polices.status', ['active']) - ->where('employees.relationship', 'Self'); - - if (!empty($client_id)) { - $builder->where('employees.client_id', $client_id); + if (!$otp) { + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'OTP is required'], 400); } - if ($email_id) { - $builder->where('employees.email_corporate', $email_id); + // 🔹 Fetch employee data + if ($mobile_number) { + + $builder = $this->employeeModel + ->select('employees.*') + ->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->where('employees.mobile', $mobile_number) + ->where('employees.relationship', 'Self') + ->where('employee_polices.is_active', 1) + ->whereIn('employee_polices.status', ['active']) + ->where('employees.is_active', 1) + ->whereIn('employees.emp_status', ['active']); + + if (!empty($client_id)) { + $builder->where('employees.client_id', $client_id); + } + + $employeeData = $builder->orderBy('employees.id', 'desc')->first(); + + } else { + + $builder = $this->employeeModel + ->select('employees.*') + ->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->where('employees.email_corporate', $email_id) + ->where('employees.relationship', 'Self') + ->where('employee_polices.is_active', 1) + ->whereIn('employee_polices.status', ['active']) + ->where('employees.is_active', 1) + ->whereIn('employees.emp_status', ['active']); + + if (!empty($client_id)) { + $builder->where('employees.client_id', $client_id); + } + + $employeeData = $builder->orderBy('employees.id', 'desc')->first(); + + } + + $lastQuery = $this->employeeModel->db->getLastQuery(); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Last Executed Query: " . $lastQuery); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: employeeData: " . json_encode($employeeData ?? [])); + + // 🔹 Verify otp + if ($employeeData && $employeeData['otp'] == $otp) { + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: OTP Verified employee found"); + $this->employeeModel->where('id', $employeeData['id'])->where('otp', $otp)->where('relationship', 'self')->set(['otp'=>null])->update(); + return $this->respond(['status' => 'success', 'code' => 200, 'message' => "OTP verified succesfully"], 200); + } else { + + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: OTP verification failed, OTP not found in the post db"); + return $this->respond(['status' => 'failed', 'code' => 400, 'message' => "OTP verification failed"], 200); } - - $employeeData = $builder->orderBy('employees.id', 'desc')->first(); - - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - sendChangePasswordOTP: Employee Data: " . json_encode($employeeData ?? [])); - - if (!$employeeData) { - return $this->respond(['status' => 'failed', 'code' => 404, 'data' => "", 'message' => 'Employee not found'], 404); - } - - // Generate 6-digit OTP - $otp = rand(100000, 999999); - - // Save OTP to DB (assuming 'otp' and 'otp_expiry' columns exist) - $this->employeeModel->update($employeeData['id'], [ - 'otp' => $otp, - ]); - - // Send OTP via SMS or Email (you can replace with your actual helper) - if ($email_id) { - // Example: MailHelper::sendMail($email_id, 'Password Change OTP', "Your OTP is {$otp}"); - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - sendChangePasswordOTP: OTP {$otp} sent to email {$email_id}"); - } - - log_message('error', ' '); - log_message('error', ' ************************************* SEND OTP END **************************************** '); - log_message('error', ' '); - - return $this->respond(['status' => 'success', 'code' => 200, 'data' => ['otp_sent_to' => $email_id], 'message' => 'OTP sent successfully'], 200); + } catch (\Exception $e) { - $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - sendChangePasswordOTP: Exception: " . $e->getMessage() . " --- Line: " . $e->getLine()); - log_message('error', ' '); - log_message('error', ' ************************************* SEND OTP END **************************************** '); - log_message('error', ' '); + $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Exception: " . $e->getMessage() . " --- Line: " . $e->getLine()); return $this->respond(['status' => 'failed', 'code' => 500, 'data' => "", 'message' => $e->getMessage()], 500); } } diff --git a/app/Models/EmployeeModel.php b/app/Models/EmployeeModel.php index 1416c082..7f210ca7 100755 --- a/app/Models/EmployeeModel.php +++ b/app/Models/EmployeeModel.php @@ -45,6 +45,7 @@ class EmployeeModel extends Model "mpin", "is_mpin_skipped", "is_biometric_enabled", + "password", ]; // Callbacks