* * Add file to email attachment session */ if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', '1'); } if (!defined('NOREQUIREMENU')) { define('NOREQUIREMENU', '1'); } if (!defined('NOREQUIREAJAX')) { define('NOREQUIREAJAX', '1'); } // Load Dolibarr environment $res = 0; // Path from /custom/filearchiv/ajax/ to main.inc.php if (!$res && file_exists("../../../main.inc.php")) { $res = @include "../../../main.inc.php"; } // Fallback for different directory structures if (!$res && file_exists("../../../../main.inc.php")) { $res = @include "../../../../main.inc.php"; } if (!$res && file_exists("../../main.inc.php")) { $res = @include "../../main.inc.php"; } if (!$res) { die("Include of main fails"); } require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; header('Content-Type: application/json; charset=UTF-8'); // Debug logging $debugFile = '/tmp/filearchiv_addfile_debug.log'; @file_put_contents($debugFile, date('Y-m-d H:i:s') . " === addfile.php called ===\n", FILE_APPEND); @file_put_contents($debugFile, "Session ID: " . session_id() . "\n", FILE_APPEND); @file_put_contents($debugFile, "User ID: " . (isset($user) ? $user->id : 'not set') . "\n", FILE_APPEND); @file_put_contents($debugFile, "POST: " . print_r($_POST, true) . "\n", FILE_APPEND); // Security check if (!isModEnabled('filearchiv')) { http_response_code(403); echo json_encode(array('success' => false, 'error' => 'Module not enabled')); exit; } $filepath = GETPOST('filepath', 'alphanohtml'); $filename = GETPOST('filename', 'alphanohtml'); $trackid = GETPOST('trackid', 'aZ09'); if (empty($filepath) || empty($filename)) { echo json_encode(array('success' => false, 'error' => 'Missing parameters')); exit; } // Security: Check that file exists and is readable if (!file_exists($filepath) || !is_readable($filepath)) { echo json_encode(array('success' => false, 'error' => 'File not found or not readable')); exit; } // Security: Check that file is within allowed directories $allowed = false; $allowedPaths = array( $conf->societe->multidir_output[$conf->entity], $conf->propal->multidir_output[$conf->entity], $conf->commande->multidir_output[$conf->entity], $conf->facture->multidir_output[$conf->entity], $conf->expedition->dir_output, $conf->product->multidir_output[$conf->entity], ); if (!empty($conf->fournisseur->commande->multidir_output[$conf->entity])) { $allowedPaths[] = $conf->fournisseur->commande->multidir_output[$conf->entity]; } if (!empty($conf->fournisseur->facture->multidir_output[$conf->entity])) { $allowedPaths[] = $conf->fournisseur->facture->multidir_output[$conf->entity]; } foreach ($allowedPaths as $path) { if (!empty($path) && strpos(realpath($filepath), realpath($path)) === 0) { $allowed = true; break; } } if (!$allowed) { echo json_encode(array('success' => false, 'error' => 'Access denied to file path')); exit; } // Get temporary directory for attachments $upload_dir = $conf->user->dir_temp . '/' . $user->id . '/email_attachments'; if (!empty($trackid)) { $upload_dir .= '/' . $trackid; } if (!is_dir($upload_dir)) { dol_mkdir($upload_dir); } // Copy file to temp directory $destfile = $upload_dir . '/' . $filename; // Make filename unique if already exists $counter = 1; $pathinfo = pathinfo($filename); $basename = $pathinfo['filename']; $ext = isset($pathinfo['extension']) ? '.' . $pathinfo['extension'] : ''; while (file_exists($destfile)) { $destfile = $upload_dir . '/' . $basename . '_' . $counter . $ext; $counter++; } $result = dol_copy($filepath, $destfile); if ($result < 0) { echo json_encode(array('success' => false, 'error' => 'Failed to copy file')); exit; } // Add to session for FormMail // FormMail uses trackid as suffix: listofpaths-TRACKID $keytoavoidconflict = empty($trackid) ? '' : '-'.$trackid; $listofpaths = isset($_SESSION["listofpaths".$keytoavoidconflict]) ? $_SESSION["listofpaths".$keytoavoidconflict] : ''; $listofnames = isset($_SESSION["listofnames".$keytoavoidconflict]) ? $_SESSION["listofnames".$keytoavoidconflict] : ''; $listofmimes = isset($_SESSION["listofmimes".$keytoavoidconflict]) ? $_SESSION["listofmimes".$keytoavoidconflict] : ''; // Get mime type include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $mime = dol_mimetype($destfile); // Append to session $listofpaths = $listofpaths . ($listofpaths ? ';' : '') . $destfile; $listofnames = $listofnames . ($listofnames ? ';' : '') . basename($destfile); $listofmimes = $listofmimes . ($listofmimes ? ';' : '') . $mime; $_SESSION["listofpaths".$keytoavoidconflict] = $listofpaths; $_SESSION["listofnames".$keytoavoidconflict] = $listofnames; $_SESSION["listofmimes".$keytoavoidconflict] = $listofmimes; // Debug logging @file_put_contents($debugFile, "Key: listofpaths$keytoavoidconflict\n", FILE_APPEND); @file_put_contents($debugFile, "Set listofpaths: $listofpaths\n", FILE_APPEND); @file_put_contents($debugFile, "Set listofnames: $listofnames\n", FILE_APPEND); @file_put_contents($debugFile, "Destfile: $destfile\n", FILE_APPEND); @file_put_contents($debugFile, "File copied: " . (file_exists($destfile) ? "YES" : "NO") . "\n", FILE_APPEND); echo json_encode(array( 'success' => true, 'message' => 'File added successfully', 'filename' => basename($destfile) ));