Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f39b3a41e | ||
|
|
40cecc10ad | ||
|
|
aee78c9750 |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,5 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## Changes 5/27/2025 v1.3.9
|
||||
|
||||
- Support for mounting CIFS (SMB) network shares via Docker volumes
|
||||
- New `scripts/scan_uploads.php` script to generate metadata for imported files and folders
|
||||
- `SCAN_ON_START` environment variable to trigger automatic scanning on container startup
|
||||
- Documentation for configuring CIFS share mounting and scanning
|
||||
|
||||
- Clipboard Paste Upload Support (single image):
|
||||
- Users can now paste images directly into the FileRise web interface.
|
||||
- Pasted images are renamed to `image<TIMESTAMP>.png` and added to the upload queue using the existing drag-and-drop logic.
|
||||
- Implemented using a `.isClipboard` flag and a delayed UI cleanup inside `xhr.addEventListener("load", ...)`.
|
||||
|
||||
---
|
||||
|
||||
## Changes 5/26/2025
|
||||
|
||||
- Updated `REGEX_FOLDER_NAME` in `config.php` to forbids < > : " | ? * characters in folder names.
|
||||
- Ensures the whole name can’t end in a space or period.
|
||||
- Blocks Windows device names.
|
||||
|
||||
- Updated `FolderController.php` when `createFolder` issues invalid folder name to return `http_response_code(400);`
|
||||
|
||||
---
|
||||
|
||||
## Changes 5/23/2025 v1.3.8
|
||||
|
||||
- **Folder-strip context menu**
|
||||
|
||||
@@ -28,7 +28,7 @@ define('TRASH_DIR', UPLOAD_DIR . 'trash/');
|
||||
define('TIMEZONE', 'America/New_York');
|
||||
define('DATE_TIME_FORMAT','m/d/y h:iA');
|
||||
define('TOTAL_UPLOAD_SIZE','5G');
|
||||
define('REGEX_FOLDER_NAME', '/^[\p{L}\p{N}_\-\s\/\\\\]+$/u');
|
||||
define('REGEX_FOLDER_NAME','/^(?!^(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$)(?!.*[. ]$)(?:[^<>:"\/\\\\|?*\x00-\x1F]{1,255})(?:[\/\\\\][^<>:"\/\\\\|?*\x00-\x1F]{1,255})*$/xu');
|
||||
define('PATTERN_FOLDER_NAME','[\p{L}\p{N}_\-\s\/\\\\]+');
|
||||
define('REGEX_FILE_NAME', '/^[^\x00-\x1F\/\\\\]{1,255}$/u');
|
||||
define('REGEX_USER', '/^[\p{L}\p{N}_\- ]+$/u');
|
||||
|
||||
@@ -3,7 +3,7 @@ import { loadAdminConfigFunc } from './auth.js';
|
||||
import { showToast, toggleVisibility, attachEnterKeyListener } from './domUtils.js';
|
||||
import { sendRequest } from './networkUtils.js';
|
||||
|
||||
const version = "v1.3.8";
|
||||
const version = "v1.3.9";
|
||||
const adminTitle = `${t("admin_panel")} <small style="font-size:12px;color:gray;">${version}</small>`;
|
||||
|
||||
// ————— Inject updated styles —————
|
||||
|
||||
@@ -669,6 +669,18 @@ function submitFiles(allFiles) {
|
||||
}
|
||||
allSucceeded = false;
|
||||
}
|
||||
if (file.isClipboard) {
|
||||
setTimeout(() => {
|
||||
window.selectedFiles = [];
|
||||
updateFileInfoCount();
|
||||
const progressContainer = document.getElementById("uploadProgressContainer");
|
||||
if (progressContainer) progressContainer.innerHTML = "";
|
||||
const fileInfoContainer = document.getElementById("fileInfoContainer");
|
||||
if (fileInfoContainer) {
|
||||
fileInfoContainer.innerHTML = `<span id="fileInfoDefault">No files selected</span>`;
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// ─── Only now count this chunk as finished ───────────────────
|
||||
finishedCount++;
|
||||
@@ -847,4 +859,39 @@ function initUpload() {
|
||||
}
|
||||
}
|
||||
|
||||
export { initUpload };
|
||||
export { initUpload };
|
||||
|
||||
// -------------------------
|
||||
// Clipboard Paste Handler (Mimics Drag-and-Drop)
|
||||
// -------------------------
|
||||
document.addEventListener('paste', function handlePasteUpload(e) {
|
||||
const items = e.clipboardData?.items;
|
||||
if (!items) return;
|
||||
|
||||
const files = [];
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
if (item.kind === 'file') {
|
||||
const file = item.getAsFile();
|
||||
if (file) {
|
||||
const ext = file.name.split('.').pop() || 'png';
|
||||
const renamedFile = new File([file], `image${Date.now()}.${ext}`, { type: file.type });
|
||||
renamedFile.isClipboard = true;
|
||||
|
||||
Object.defineProperty(renamedFile, 'customRelativePath', {
|
||||
value: renamedFile.name,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
files.push(renamedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
processFiles(files);
|
||||
showToast('Pasted file added to upload list.', 'success');
|
||||
}
|
||||
});
|
||||
63
scripts/scan_uploads.php
Normal file
63
scripts/scan_uploads.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* scan_uploads.php
|
||||
* Scans the uploads directory and creates metadata entries for new files/folders using config settings.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../config/config.php';
|
||||
|
||||
if (!isset($config['upload_dir']) || !isset($config['metadata_dir'])) {
|
||||
die("Missing configuration for upload_dir or metadata_dir\n");
|
||||
}
|
||||
|
||||
$uploadDir = $config['upload_dir'];
|
||||
$metadataDir = $config['metadata_dir'];
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
function scanDirectory($dir) {
|
||||
$items = array_diff(scandir($dir), ['.', '..']);
|
||||
$results = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$path = $dir . DIRECTORY_SEPARATOR . $item;
|
||||
$results[] = $path;
|
||||
|
||||
if (is_dir($path)) {
|
||||
$results = array_merge($results, scanDirectory($path));
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function metadataPath($filePath, $uploadDir, $metadataDir) {
|
||||
$relativePath = ltrim(str_replace($uploadDir, '', $filePath), '/');
|
||||
return $metadataDir . '/' . $relativePath . '.json';
|
||||
}
|
||||
|
||||
$allItems = scanDirectory($uploadDir);
|
||||
|
||||
foreach ($allItems as $item) {
|
||||
$metaPath = metadataPath($item, $uploadDir, $metadataDir);
|
||||
|
||||
if (!file_exists($metaPath)) {
|
||||
$type = is_dir($item) ? 'folder' : 'file';
|
||||
$size = is_file($item) ? filesize($item) : 0;
|
||||
|
||||
$metadata = [
|
||||
'path' => str_replace($uploadDir, '', $item),
|
||||
'type' => $type,
|
||||
'size' => $size,
|
||||
'user' => 'Imported',
|
||||
'uploadDate' => date('c')
|
||||
];
|
||||
|
||||
if (!is_dir(dirname($metaPath))) {
|
||||
mkdir(dirname($metaPath), 0775, true);
|
||||
}
|
||||
|
||||
file_put_contents($metaPath, json_encode($metadata, JSON_PRETTY_PRINT));
|
||||
echo "Created metadata for: {$item}\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -96,12 +96,14 @@ class FolderController
|
||||
|
||||
// Basic sanitation for folderName.
|
||||
if (!preg_match(REGEX_FOLDER_NAME, $folderName)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Invalid folder name.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Optionally sanitize the parent.
|
||||
if ($parent && !preg_match(REGEX_FOLDER_NAME, $parent)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Invalid parent folder name.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
7
start.sh
7
start.sh
@@ -109,4 +109,9 @@ if [ ! -f /var/www/metadata/createdTags.json ]; then
|
||||
fi
|
||||
|
||||
echo "🔥 Starting Apache..."
|
||||
exec apachectl -D FOREGROUND
|
||||
exec apachectl -D FOREGROUND
|
||||
|
||||
if [ "$SCAN_ON_START" = "true" ]; then
|
||||
echo "Scanning uploads directory to generate metadata..."
|
||||
php /var/www/scripts/scan_uploads.php
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user