diff --git a/app/Config/Filters.php b/app/Config/Filters.php index 9f28a05..0042bda 100755 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -19,6 +19,7 @@ use App\Filters\Cors; use App\Filters\GlobalPostFileUploadGuard; use App\Filters\SecurityInputFilter; use App\Filters\AclFilter; +use App\Filters\RateLimitFilter; @@ -47,6 +48,7 @@ class Filters extends BaseConfig 'GlobalPostFileUploadGuard' => GlobalPostFileUploadGuard::class, 'SecurityInputFilter' => SecurityInputFilter::class, 'AclFilter' => AclFilter::class, + 'ratelimit' => RateLimitFilter::class, ]; diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 6b133ac..a0eb3e0 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -442,7 +442,7 @@ $routes->cli('cli/check_env', 'MasterController::checkEnv'); -$routes->group("/api", ["filter" => "authJWT"], function ($routes) { +$routes->group("/api", ["filter" => [ 'ratelimit' , 'authJWT' ] ], function ($routes) { $routes->post("logined", "RestAuthenticationController::logined"); $routes->post("getId", "RestAuthenticationController::getUserIdFromToken"); }); @@ -454,7 +454,7 @@ $routes->group("/api", ["filter" => "authJWT"], function ($routes) { // $routes->post("employeeRest/createOrUpdateEmployeePolicySiAmount", "EmployeeRestController::createOrUpdateEmployeePolicySiAmount"); // $routes->post("employeeRest/calculatePremium", "EmployeeRestController::calculatePremium"); // $routes->post("updateMpin", "RestAuthenticationController::updateMpin"); -$routes->group("employeeRest", ['filter' => ['GlobalPostFileUploadGuard', 'appSignature' , 'authJWT'] ], function ($routes) { +$routes->group("employeeRest", ['filter' => [ 'GlobalPostFileUploadGuard', 'ratelimit' , 'appSignature' , 'authJWT' ] ], function ($routes) { $routes->post('logout', 'RestAuthenticationController::logout'); @@ -503,10 +503,11 @@ $routes->group("employeeRest", ['filter' => ['GlobalPostFileUploadGuard', 'appSi $routes->post("hrFileUpload", "EmployeeRestController::hrFileUpload"); $routes->get("copyActiveEmployeeAndDependentDetails", "EmployeeRestController::copyActiveEmployeeAndDependentDetails"); + $routes->get("getExcelFileErrors/(:any)", "EmployeeController::getExcelFileErrors/$1"); }); -$routes->group("employeeRest", ['filter' => ['appSignature'] ], function ($routes) { +$routes->group("employeeRest", ['filter' => ['ratelimit' , 'appSignature'] ], function ($routes) { //Employee login api's $routes->post("verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); @@ -539,7 +540,7 @@ $routes->group("employeeRest", ['filter' => ['appSignature'] ], function ($route }); -$routes->post("getPreEmployeePolicyCount","EmployeeRestController::getPreEmployeePolicyCount", ['filter' => ['appSignature']]); +$routes->post("getPreEmployeePolicyCount","EmployeeRestController::getPreEmployeePolicyCount", ['filter' => ['ratelimit','appSignature']]); $routes->get("getEmployeeActiveOrInactivePolicy", "EmployeeRestController::getEmployeeActiveOrInactivePolicy"); $routes->get("sendPushNotification", "EmployeeRestController::sendPushNotification"); diff --git a/app/Controllers/EmployeeController.php b/app/Controllers/EmployeeController.php index df12f29..0f40f94 100755 --- a/app/Controllers/EmployeeController.php +++ b/app/Controllers/EmployeeController.php @@ -180,9 +180,13 @@ class EmployeeController extends AdminController //handles employee & dependent bulk upload with events like inception,addition,deletion, correction and SI enhancements public function employeesUplodWithEvents($post_data = []) - { + { if(empty($post_data)){ $post_data = $this->request->getPost(); + $post_data = array_merge($post_data, $this->request->getFiles()); + $is_post_request = true; + }else{ + $is_post_request = false; } // $empDataServiceController = new EmpDataServiceController(); @@ -339,7 +343,7 @@ class EmployeeController extends AdminController $avatar = isset($post_data['emplist']) ? $post_data['emplist'] : $this->request->getFile('emplist'); if (!$avatar) { $this->myLogger->logme("error", 'File not found'); - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => false, 'message' => 'File not found']; } else { return $this->respond(['dataStatus' => false, 'code' => 400, 'message' => 'File not found'], 400); @@ -355,7 +359,7 @@ class EmployeeController extends AdminController $this->myLogger->logme("error", 'File move successful'); } else { $this->myLogger->logme("error", 'File move failed'); - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => false, 'message' => 'File move failed']; } else { return $this->respond(['dataStatus' => false, 'code' => 500, 'message' => 'File move failed'], 500); @@ -363,7 +367,7 @@ class EmployeeController extends AdminController } } else { $this->myLogger->logme("error", 'Upload failed Invalid file'); - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => false, 'message' => 'Invalid file']; } else { return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'Invalid file'], 404); @@ -385,7 +389,7 @@ class EmployeeController extends AdminController $client_id = $post_data['client_id'] ?? null; $policy_id = $post_data['policy_id'] ?? null; $branch_id = $post_data['client_branch_id'] ?? null; - $action = $post_data['file_action'] ?? null; + $action = "enrollment"; $enrollment_open_date = $post_data['enrollment_open_date'] ?? null; $enrollment_close_date = $post_data['enrollment_close_date'] ?? null; $status = 'inprogress'; @@ -405,7 +409,7 @@ class EmployeeController extends AdminController $this->myLogger->logme("error", '{file_id} is less than 1MB, validating on the fly', ['file_id' => $file_id]); //endof validation process if (isset($result['error_summary']) && count($result['error_summary'])) { - if(!empty($post_data)){ + if(!$is_post_request){ return ['status' => false, 'message' => 'file rejected with errors', 'file_id' => $file_id]; }else{ return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'file rejected with errors'], 200); @@ -418,7 +422,7 @@ class EmployeeController extends AdminController $this->myLogger->logme("error", '{file_id} is greather than 1MB, validating with job queue', ['file_id' => $file_id]); } - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => true, 'message' => 'File upload successs, Data validation is in-progress', 'file_id' => $file_id]; } else { return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'file upload success'], 200); @@ -507,7 +511,7 @@ class EmployeeController extends AdminController // dd($data['fileList']);die(); - if ($_SERVER('REQUEST_METHOD') == "GET") { + if ($_SERVER['REQUEST_METHOD'] == "GET") { $this->loadLayout('import_export', $data); } } @@ -517,10 +521,26 @@ class EmployeeController extends AdminController $file_data = $this->fileModel->where('id', $file_id)->first(); $error = json_decode($file_data['reason'] ?? '{}', true); - if(!empty($error) && $retun_type == 'api'){ + if(!empty($error) && $retun_type == 'api' && $file_data['status'] == 'failed'){ $send = isset($error['error_summary'][5]) || isset($error['error_summary'][6]) ? true : false; if($send){ - return $this->respond(['status' => false, 'code' => 404, 'message' => $error['error_data'], 'data' => []], 200); + + $string = $error['error_data'] ?? 'System error'; + + $errorMap = [ + "Column order conflict" => "Invalid file format. Please use the sample file.", + ]; + + $message = $string; // Default to the original error + + foreach ($errorMap as $keyword => $friendlyMessage) { + if (strpos($string, $keyword) !== false) { + $message = $friendlyMessage; + break; // Stop looking once we find a match + } + } + + return $this->respond(['status' => false, 'code' => 404, 'message' => $message, 'data' => []], 200); } } diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index bdb7a23..ad822a1 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -846,14 +846,16 @@ class EmployeeRestController extends AdminController $responce = $employeeController->employeesUplodWithEvents($post_data); // print_r($responce); die; - if(!$responce['status']){ - $file_data = $this->getDataFromFilesTable(['file_id' => $responce['file_id']]); - $responce['data'] = $file_data; - return $this->respond($responce, 200); - }else{ - $responce['data'] = []; - return $this->respond($responce, 200); - } + return $this->respond($responce, 200); + + // if(!$responce['status']){ + // $file_data = $this->getDataFromFilesTable(['file_id' => $responce['file_id']]); + // $responce['data'] = $file_data; + // return $this->respond($responce, 200); + // }else{ + // $responce['data'] = []; + // return $this->respond($responce, 200); + // } @@ -1239,7 +1241,7 @@ class EmployeeRestController extends AdminController files.policy_id, cp.policy_no, files.file_name, - files.action, + files.action as file_action, files.created_at, files.created_by, files.updated_at, @@ -1273,7 +1275,11 @@ class EmployeeRestController extends AdminController } if (isset($search_data['client_id']) && !empty($search_data['client_id'])) { - $builder->where("files.client_id", $search_data['client_id']); + if (is_string($search_data['client_id']) && preg_match('/^[a-f0-9]{32}$/i', $search_data['client_id'])) { + $builder->where("MD5(files.client_id)", $search_data['client_id']); + } else { + $builder->where("files.client_id", $search_data['client_id']); + } } if (isset($search_data['file_id']) && !empty($search_data['file_id'])) { @@ -4239,13 +4245,13 @@ class EmployeeRestController extends AdminController $file_id = $this->request->getGet('id') ?? $id; // Find record - $record = $this->hrFileUploadModel->find($file_id); + $record = $this->fileModel->where('id', $file_id)->first(); if (!$record) { return $this->failNotFound("File record not found"); } - $uploadPath = WRITEPATH . 'uploads/hr_files/'; + $uploadPath = WRITEPATH . 'uploads/excel/'; $filePath = $uploadPath . $record['file_name']; if (!file_exists($filePath)) { @@ -4253,8 +4259,8 @@ class EmployeeRestController extends AdminController } // Force file download - return $this->response->download($filePath, null) - ->setFileName($record['file_name']); + return $this->response->download($filePath, null)->setFileName($record['file_name']); + } catch (\Exception $e) { return $this->failServerError($e->getMessage()); } @@ -4263,6 +4269,28 @@ class EmployeeRestController extends AdminController public function hrFileList() { try { + + $request = service('request'); + $search_data = $request->getGetPost() ?? []; + + // Fetch results + $data = $this->getDataFromFilesTable($search_data); + + return $this->respond([ + 'status' => true, + 'message' => 'File list fetched successfully', + 'data' => $data + ]); + + } catch (\Exception $e) { + return $this->failServerError($e->getMessage()); + } + } + + public function hrFileListOld() + { + try { + $request = service('request'); $builder = $this->hrFileUploadModel; diff --git a/app/Filters/RateLimitFilter.php b/app/Filters/RateLimitFilter.php new file mode 100644 index 0000000..31efe81 --- /dev/null +++ b/app/Filters/RateLimitFilter.php @@ -0,0 +1,34 @@ +getIPAddress()); + + if ($throttler->check($key, 25, MINUTE) === false) { + return service('response') + ->setStatusCode(429) + ->setJSON([ + 'status' => 'error', + 'message' => 'Too many requests. Try again later.' + ]); + } + } + + + public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) + { + // nothing + } +} diff --git a/app/Helpers/JWTToken.php b/app/Helpers/JWTToken.php index d110444..f7b32ba 100755 --- a/app/Helpers/JWTToken.php +++ b/app/Helpers/JWTToken.php @@ -31,16 +31,16 @@ class JWTToken try{ $token = JWT::encode($request_data ,$secret_Key,'HS512'); $id = $request_data['id']; - $data["token_time_out"] = time() + getenv('TOKENTIMEOUT'); + $update["token_time_out"] = time() + getenv('TOKENTIMEOUT'); if(isset($data['emp_code'])){ $model = new EmployeeModel(); - $model->update($id, $data); + $model->update($id, $update); }else{ $models = new LevelContactModel(); $id = $request_data['pre_hr_id']; - $models->update($id, $data); + $models->update($id, $update); }