MERGE_TEST_BUG_FIXES
This commit is contained in:
commit
9f1adfe8cc
@ -22,6 +22,9 @@ class Acl
|
||||
'#^/getSSORedirectUrl#' => ['public' => true],
|
||||
'#^/getEmployeePolicy#' => ['public' => true],
|
||||
'#^/downloadFileTableFile#' => ['public' => true],
|
||||
'#^/storage/file-download#' => ['public' => true],
|
||||
'#^/fileDownload#' => ['public' => true],
|
||||
'#^/downloadClaimFile#' => ['public' => true],
|
||||
'#^/swagger#' => ['roles' => [ADMIN_ROLE_ID]],
|
||||
'#^/getEmployeeActiveOrInactivePolicy#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID]],
|
||||
'#^/test/chartbrewDashboardDemo#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID]],
|
||||
|
||||
@ -38,6 +38,9 @@ $routes->group('/storage/files', ['filter' => 'authMVC'], function ($routes) {
|
||||
$routes->get('list', 'StorageFilesController::listFiles');
|
||||
$routes->get('folders', 'StorageFilesController::folders');
|
||||
});
|
||||
// Force download (attachment) — public so TPA can fetch claim docs
|
||||
$routes->get('storage/file-download/claim/(:segment)', 'StorageFilesController::forceDownloadClaim/$1');
|
||||
$routes->get('storage/file-download', 'StorageFilesController::forceDownloadByFolderFile');
|
||||
$routes->get('/visitOffBoardCheck', 'EmployeeController::visitOffBoardCheck');
|
||||
$routes->get('/metaDashboardDemo', 'TestingController::metaDashboardDemo');
|
||||
$routes->get('/apacheSuperSetDemo', 'TestingController::apacheSuperSetDemo');
|
||||
|
||||
@ -2,8 +2,11 @@
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Models\ClaimFilesModel;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
|
||||
/**
|
||||
* Browse S3 upload-bucket objects folder-wise with paginated search UI.
|
||||
* Browse S3 upload-bucket objects + file-download (attachment) APIs.
|
||||
*/
|
||||
class StorageFilesController extends AdminController
|
||||
{
|
||||
@ -158,6 +161,94 @@ class StorageFilesController extends AdminController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /storage/file-download/claim/{md5(id)}
|
||||
* Streams claim_files row by MD5(id) as attachment (never inline).
|
||||
*/
|
||||
public function forceDownloadClaim($md5Id = null)
|
||||
{
|
||||
helper('utility');
|
||||
|
||||
$md5Id = strtolower(trim((string) $md5Id));
|
||||
if ($md5Id === '' || ! preg_match('/^[a-f0-9]{32}$/', $md5Id)) {
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
$claimFiles = new ClaimFilesModel();
|
||||
$record = $claimFiles
|
||||
->where('MD5(CAST(id AS CHAR))', $md5Id)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
if (empty($record)) {
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
$diskName = ! empty($record['url'])
|
||||
? basename((string) $record['url'])
|
||||
: basename((string) ($record['file_name'] ?? ''));
|
||||
|
||||
if ($diskName === '') {
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
$downloadAs = storage_upload_display_name($diskName);
|
||||
|
||||
return $this->streamAttachment(WRITEPATH . 'uploads/claim_files', $diskName, $downloadAs);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /storage/file-download?folder=claim_files&file=xxx.pdf
|
||||
* Streams any storage module object as attachment (never inline).
|
||||
*/
|
||||
public function forceDownloadByFolderFile()
|
||||
{
|
||||
helper('utility');
|
||||
|
||||
$folder = basename(str_replace('\\', '/', trim((string) $this->request->getGet('folder'))));
|
||||
$file = basename(str_replace('\\', '/', trim((string) $this->request->getGet('file'))));
|
||||
|
||||
if (
|
||||
$folder === '' || $folder === '.' || $folder === '..'
|
||||
|| $file === '' || $file === '.' || $file === '..'
|
||||
|| preg_match('/[^a-zA-Z0-9_\-]/', $folder)
|
||||
|| preg_match('/[\\\\\\/]/', $file)
|
||||
) {
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
$uploadPath = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . $folder;
|
||||
$downloadAs = storage_upload_display_name($file);
|
||||
|
||||
return $this->streamAttachment($uploadPath, $file, $downloadAs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream file bytes with attachment disposition (never inline / never S3 redirect).
|
||||
*/
|
||||
private function streamAttachment(string $uploadPath, string $diskName, string $downloadAs)
|
||||
{
|
||||
$storage = \Config\Services::getFileStorageService();
|
||||
$result = $storage->download($uploadPath, $diskName);
|
||||
|
||||
if (! ($result['success'] ?? false)) {
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
if (! empty($result['path']) && is_file($result['path'])) {
|
||||
return $this->response
|
||||
->download($result['path'], null)
|
||||
->setFileName($downloadAs);
|
||||
}
|
||||
|
||||
if (! empty($result['content'])) {
|
||||
return $this->response
|
||||
->download($downloadAs, $result['content'])
|
||||
->setFileName($downloadAs);
|
||||
}
|
||||
|
||||
throw PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
private function localUploadFolders(): array
|
||||
{
|
||||
|
||||
@ -579,7 +579,8 @@ if (! function_exists('storage_claim_file_Upload')) {
|
||||
|
||||
/**
|
||||
* Build a TPA-facing download URL for a claim file.
|
||||
* Prefers an S3 presigned URL; falls back to app downloadClaimFile/{id} for local mode.
|
||||
* Prefers Nhance file-download API (attachment stream from local/S3).
|
||||
* Falls back to folder+file URL when file id is missing.
|
||||
*/
|
||||
if (! function_exists('storage_claim_file_download_url')) {
|
||||
function storage_claim_file_download_url(string $diskName, $fileId = null, int $expirationMinutes = 360): string
|
||||
@ -592,22 +593,31 @@ if (! function_exists('storage_claim_file_download_url')) {
|
||||
$uploadPath = WRITEPATH . 'uploads/claim_files';
|
||||
$storage = \Config\Services::getFileStorageService();
|
||||
|
||||
// Prefer app file-download URL when claim_files id is known (TPA-safe, attachment).
|
||||
if ($fileId !== null && $fileId !== '') {
|
||||
if ($storage->usesS3()) {
|
||||
if (! $storage->exists($uploadPath, $diskName)) {
|
||||
log_message('error', 'storage_claim_file_download_url | missing on S3 | ' . $diskName);
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$localPath = $storage->resolveLocalPath($uploadPath, $diskName);
|
||||
if (! is_file($localPath)) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return base_url('storage/file-download/claim/' . md5((string) (int) $fileId));
|
||||
}
|
||||
|
||||
if ($storage->usesS3()) {
|
||||
if (! $storage->exists($uploadPath, $diskName)) {
|
||||
log_message('error', 'storage_claim_file_download_url | missing on S3 | ' . $diskName);
|
||||
return '';
|
||||
}
|
||||
|
||||
$result = $storage->getPresignedUrl($uploadPath, $diskName, max(1, $expirationMinutes));
|
||||
if (($result['success'] ?? false) && ! empty($result['url'])) {
|
||||
return (string) $result['url'];
|
||||
}
|
||||
|
||||
log_message('error', 'storage_claim_file_download_url | presign failed | ' . json_encode([
|
||||
'disk_name' => $diskName,
|
||||
'message' => $result['message'] ?? null,
|
||||
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
|
||||
return '';
|
||||
// No file id: folder+file download endpoint
|
||||
return base_url('storage/file-download') . '?folder=claim_files&file=' . rawurlencode($diskName);
|
||||
}
|
||||
|
||||
$localPath = $storage->resolveLocalPath($uploadPath, $diskName);
|
||||
@ -615,11 +625,7 @@ if (! function_exists('storage_claim_file_download_url')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($fileId !== null && $fileId !== '') {
|
||||
return base_url('downloadClaimFile/' . $fileId);
|
||||
}
|
||||
|
||||
return '';
|
||||
return base_url('storage/file-download') . '?folder=claim_files&file=' . rawurlencode($diskName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user