Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2d678ee19 | ||
|
|
da62e70c02 | ||
|
|
f19d30f58a | ||
|
|
a8202adbec | ||
|
|
5dc58ffa42 | ||
|
|
f4f700ecda | ||
|
|
94178775d5 | ||
|
|
1d3f731483 | ||
|
|
6926d5b065 | ||
|
|
46e9761cae | ||
|
|
fa828f5dea |
@@ -1,5 +1,10 @@
|
|||||||
# FileRise - Elevate your File Management
|
# FileRise - Elevate your File Management
|
||||||
|
|
||||||
|
**Demo link:** https://demo.filerise.net
|
||||||
|
**UserName:** demo
|
||||||
|
**Password:** demo
|
||||||
|
Read only permissions but can view the interface.
|
||||||
|
|
||||||
**4/3/2025 Video demo:**
|
**4/3/2025 Video demo:**
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/221f6a53-85f5-48d4-9abe-89445e0af90e
|
https://github.com/user-attachments/assets/221f6a53-85f5-48d4-9abe-89445e0af90e
|
||||||
|
|||||||
7
auth.js
7
auth.js
@@ -400,6 +400,13 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
disableBasicAuth: localStorage.getItem("disableBasicAuth") === "true",
|
disableBasicAuth: localStorage.getItem("disableBasicAuth") === "true",
|
||||||
disableOIDCLogin: localStorage.getItem("disableOIDCLogin") === "true"
|
disableOIDCLogin: localStorage.getItem("disableOIDCLogin") === "true"
|
||||||
});
|
});
|
||||||
|
const oidcLoginBtn = document.getElementById("oidcLoginBtn");
|
||||||
|
if (oidcLoginBtn) {
|
||||||
|
oidcLoginBtn.addEventListener("click", () => {
|
||||||
|
// Redirect to the OIDC auth endpoint. The endpoint can be adjusted if needed.
|
||||||
|
window.location.href = "auth.php?oidc=initiate";
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export { initAuth, checkAuthentication };
|
export { initAuth, checkAuthentication };
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { showToast, toggleVisibility } from './domUtils.js';
|
import { showToast, toggleVisibility } from './domUtils.js';
|
||||||
import { sendRequest } from './networkUtils.js';
|
import { sendRequest } from './networkUtils.js';
|
||||||
|
|
||||||
const version = "v1.0.6";
|
const version = "v1.0.7";
|
||||||
const adminTitle = `Admin Panel <small style="font-size: 12px; color: gray;">${version}</small>`;
|
const adminTitle = `Admin Panel <small style="font-size: 12px; color: gray;">${version}</small>`;
|
||||||
let lastLoginData = null;
|
let lastLoginData = null;
|
||||||
|
|
||||||
|
|||||||
17
config.php
17
config.php
@@ -55,7 +55,7 @@ if (!$encryptionKey) {
|
|||||||
|
|
||||||
function loadUserPermissions($username)
|
function loadUserPermissions($username)
|
||||||
{
|
{
|
||||||
global $encryptionKey; // Ensure $encryptionKey is available
|
global $encryptionKey;
|
||||||
$permissionsFile = USERS_DIR . 'userPermissions.json';
|
$permissionsFile = USERS_DIR . 'userPermissions.json';
|
||||||
|
|
||||||
if (file_exists($permissionsFile)) {
|
if (file_exists($permissionsFile)) {
|
||||||
@@ -69,21 +69,12 @@ function loadUserPermissions($username)
|
|||||||
$permissions = json_decode($content, true);
|
$permissions = json_decode($content, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($permissions)) {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($permissions) && array_key_exists($username, $permissions)) {
|
if (is_array($permissions) && array_key_exists($username, $permissions)) {
|
||||||
$result = $permissions[$username];
|
$result = $permissions[$username];
|
||||||
if (empty($result)) {
|
return !empty($result) ? $result : false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
error_log("loadUserPermissions: Permissions file not found: $permissionsFile");
|
|
||||||
}
|
}
|
||||||
|
// Removed error_log() to prevent flooding logs when file is not found.
|
||||||
return false; // Return false if no permissions found.
|
return false; // Return false if no permissions found.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +123,7 @@ if (!isset($_SESSION["authenticated"]) && isset($_COOKIE['remember_me_token']))
|
|||||||
$_SESSION["authenticated"] = true;
|
$_SESSION["authenticated"] = true;
|
||||||
$_SESSION["username"] = $tokenData["username"];
|
$_SESSION["username"] = $tokenData["username"];
|
||||||
// IMPORTANT: Set the folderOnly flag here for auto-login.
|
// IMPORTANT: Set the folderOnly flag here for auto-login.
|
||||||
$_SESSION["folderOnly"] = loadFolderPermission($tokenData["username"]);
|
$_SESSION["folderOnly"] = loadUserPermissions($tokenData["username"]);
|
||||||
} else {
|
} else {
|
||||||
unset($persistentTokens[$_COOKIE['remember_me_token']]);
|
unset($persistentTokens[$_COOKIE['remember_me_token']]);
|
||||||
$newEncryptedContent = encryptData(json_encode($persistentTokens, JSON_PRETTY_PRINT), $encryptionKey);
|
$newEncryptedContent = encryptData(json_encode($persistentTokens, JSON_PRETTY_PRINT), $encryptionKey);
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ if ($receivedToken !== $_SESSION['csrf_token']) {
|
|||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ if ($receivedToken !== $_SESSION['csrf_token']) {
|
|||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
60
download.php
60
download.php
@@ -1,8 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once 'config.php';
|
require_once 'config.php';
|
||||||
|
|
||||||
// For GET requests (which download.php will use), we assume session authentication is enough.
|
|
||||||
|
|
||||||
// Check if the user is authenticated.
|
// Check if the user is authenticated.
|
||||||
if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
||||||
http_response_code(401);
|
http_response_code(401);
|
||||||
@@ -22,38 +20,70 @@ if (!preg_match('/^[A-Za-z0-9_\-\.\(\) ]+$/', $file)) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the directory.
|
// Get the realpath of the upload directory.
|
||||||
if ($folder !== 'root') {
|
$uploadDirReal = realpath(UPLOAD_DIR);
|
||||||
$directory = rtrim(UPLOAD_DIR, '/\\') . DIRECTORY_SEPARATOR . $folder . DIRECTORY_SEPARATOR;
|
if ($uploadDirReal === false) {
|
||||||
} else {
|
http_response_code(500);
|
||||||
$directory = UPLOAD_DIR;
|
echo json_encode(["error" => "Server misconfiguration."]);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filePath = $directory . $file;
|
// Determine the directory.
|
||||||
|
if ($folder === 'root') {
|
||||||
|
$directory = $uploadDirReal;
|
||||||
|
} else {
|
||||||
|
// Prevent path traversal in folder parameter.
|
||||||
|
if (strpos($folder, '..') !== false) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(["error" => "Invalid folder name."]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (!file_exists($filePath)) {
|
$directoryPath = rtrim(UPLOAD_DIR, '/\\') . DIRECTORY_SEPARATOR . $folder;
|
||||||
|
$directory = realpath($directoryPath);
|
||||||
|
|
||||||
|
// Ensure that the resolved directory exists and is within the allowed UPLOAD_DIR.
|
||||||
|
if ($directory === false || strpos($directory, $uploadDirReal) !== 0) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(["error" => "Invalid folder path."]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the file path.
|
||||||
|
$filePath = $directory . DIRECTORY_SEPARATOR . $file;
|
||||||
|
$realFilePath = realpath($filePath);
|
||||||
|
|
||||||
|
// Validate that the real file path exists and is within the allowed directory.
|
||||||
|
if ($realFilePath === false || strpos($realFilePath, $uploadDirReal) !== 0) {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode(["error" => "Access forbidden."]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($realFilePath)) {
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
echo json_encode(["error" => "File not found."]);
|
echo json_encode(["error" => "File not found."]);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve the file.
|
// Serve the file.
|
||||||
$mimeType = mime_content_type($filePath);
|
$mimeType = mime_content_type($realFilePath);
|
||||||
header("Content-Type: " . $mimeType);
|
header("Content-Type: " . $mimeType);
|
||||||
|
|
||||||
// For images, serve inline; for other types, force download.
|
// For images, serve inline; for other types, force download.
|
||||||
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
|
$ext = strtolower(pathinfo($realFilePath, PATHINFO_EXTENSION));
|
||||||
if (in_array($ext, ['jpg','jpeg','png','gif','bmp','webp','svg','ico'])) {
|
if (in_array($ext, ['jpg','jpeg','png','gif','bmp','webp','svg','ico'])) {
|
||||||
header('Content-Disposition: inline; filename="' . basename($filePath) . '"');
|
header('Content-Disposition: inline; filename="' . basename($realFilePath) . '"');
|
||||||
} else {
|
} else {
|
||||||
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
|
header('Content-Disposition: attachment; filename="' . basename($realFilePath) . '"');
|
||||||
}
|
}
|
||||||
header('Content-Length: ' . filesize($filePath));
|
header('Content-Length: ' . filesize($realFilePath));
|
||||||
|
|
||||||
// Disable caching.
|
// Disable caching.
|
||||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||||
header('Pragma: no-cache');
|
header('Pragma: no-cache');
|
||||||
|
|
||||||
readfile($filePath);
|
readfile($realFilePath);
|
||||||
exit;
|
exit;
|
||||||
?>
|
?>
|
||||||
@@ -17,9 +17,9 @@ if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
|||||||
echo json_encode(["error" => "Unauthorized"]);
|
echo json_encode(["error" => "Unauthorized"]);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
199
main.js
199
main.js
@@ -17,12 +17,17 @@ import { loadFolderTree } from './folderManager.js';
|
|||||||
import { initUpload } from './upload.js';
|
import { initUpload } from './upload.js';
|
||||||
import { initAuth, checkAuthentication } from './auth.js';
|
import { initAuth, checkAuthentication } from './auth.js';
|
||||||
import { setupTrashRestoreDelete } from './trashRestoreDelete.js';
|
import { setupTrashRestoreDelete } from './trashRestoreDelete.js';
|
||||||
import { initDragAndDrop, loadSidebarOrder, loadHeaderOrder } from './dragAndDrop.js'
|
import { initDragAndDrop, loadSidebarOrder, loadHeaderOrder } from './dragAndDrop.js';
|
||||||
import { initTagSearch, openTagModal, filterFilesByTag } from './fileTags.js';
|
import { initTagSearch, openTagModal, filterFilesByTag } from './fileTags.js';
|
||||||
|
|
||||||
function loadCsrfToken() {
|
function loadCsrfTokenWithRetry(retries = 3, delay = 1000) {
|
||||||
fetch('token.php', { credentials: 'include' })
|
return fetch('token.php', { credentials: 'include' })
|
||||||
.then(response => response.json())
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Token fetch failed with status: " + response.status);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
// Set global variables.
|
// Set global variables.
|
||||||
window.csrfToken = data.csrf_token;
|
window.csrfToken = data.csrf_token;
|
||||||
@@ -45,11 +50,19 @@ function loadCsrfToken() {
|
|||||||
document.head.appendChild(metaShare);
|
document.head.appendChild(metaShare);
|
||||||
}
|
}
|
||||||
metaShare.setAttribute('content', data.share_url);
|
metaShare.setAttribute('content', data.share_url);
|
||||||
})
|
|
||||||
.catch(error => console.error("Error loading CSRF token and share URL:", error));
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", loadCsrfToken);
|
return data;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (retries > 0) {
|
||||||
|
console.warn(`CSRF token load failed. Retrying in ${delay}ms... (${retries} retries left)`, error);
|
||||||
|
return new Promise(resolve => setTimeout(resolve, delay))
|
||||||
|
.then(() => loadCsrfTokenWithRetry(retries - 1, delay * 2));
|
||||||
|
}
|
||||||
|
console.error("Failed to load CSRF token after retries.", error);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Expose functions for inline handlers.
|
// Expose functions for inline handlers.
|
||||||
window.sendRequest = sendRequest;
|
window.sendRequest = sendRequest;
|
||||||
@@ -63,96 +76,104 @@ window.renameFile = renameFile;
|
|||||||
window.currentFolder = "root";
|
window.currentFolder = "root";
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
// Call initAuth synchronously.
|
// First, load the CSRF token (with retry).
|
||||||
initAuth();
|
loadCsrfTokenWithRetry().then(() => {
|
||||||
|
// Once CSRF token is loaded, initialize authentication.
|
||||||
|
initAuth();
|
||||||
|
|
||||||
const newPasswordInput = document.getElementById("newPassword");
|
// Continue with initializations that rely on a valid CSRF token:
|
||||||
if (newPasswordInput) {
|
checkAuthentication().then(authenticated => {
|
||||||
newPasswordInput.addEventListener("input", function() {
|
if (authenticated) {
|
||||||
console.log("newPassword input event:", this.value);
|
window.currentFolder = "root";
|
||||||
});
|
initTagSearch();
|
||||||
} else {
|
loadFileList(window.currentFolder);
|
||||||
console.error("newPassword input not found!");
|
initDragAndDrop();
|
||||||
}
|
loadSidebarOrder();
|
||||||
// --- Dark Mode Persistence ---
|
loadHeaderOrder();
|
||||||
const darkModeToggle = document.getElementById("darkModeToggle");
|
initFileActions();
|
||||||
const storedDarkMode = localStorage.getItem("darkMode");
|
initUpload();
|
||||||
|
loadFolderTree();
|
||||||
|
setupTrashRestoreDelete();
|
||||||
|
|
||||||
if (storedDarkMode === "true") {
|
const helpBtn = document.getElementById("folderHelpBtn");
|
||||||
document.body.classList.add("dark-mode");
|
const helpTooltip = document.getElementById("folderHelpTooltip");
|
||||||
} else if (storedDarkMode === "false") {
|
helpBtn.addEventListener("click", function () {
|
||||||
document.body.classList.remove("dark-mode");
|
// Toggle display of the tooltip.
|
||||||
} else {
|
if (helpTooltip.style.display === "none" || helpTooltip.style.display === "") {
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
helpTooltip.style.display = "block";
|
||||||
document.body.classList.add("dark-mode");
|
} else {
|
||||||
} else {
|
helpTooltip.style.display = "none";
|
||||||
document.body.classList.remove("dark-mode");
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (darkModeToggle) {
|
|
||||||
darkModeToggle.textContent = document.body.classList.contains("dark-mode")
|
|
||||||
? "Light Mode"
|
|
||||||
: "Dark Mode";
|
|
||||||
|
|
||||||
darkModeToggle.addEventListener("click", function () {
|
|
||||||
if (document.body.classList.contains("dark-mode")) {
|
|
||||||
document.body.classList.remove("dark-mode");
|
|
||||||
localStorage.setItem("darkMode", "false");
|
|
||||||
darkModeToggle.textContent = "Dark Mode";
|
|
||||||
} else {
|
} else {
|
||||||
document.body.classList.add("dark-mode");
|
console.warn("User not authenticated. Data loading deferred.");
|
||||||
localStorage.setItem("darkMode", "true");
|
|
||||||
darkModeToggle.textContent = "Light Mode";
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (localStorage.getItem("darkMode") === null && window.matchMedia) {
|
// Other DOM initialization that can happen after CSRF is ready.
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (event) => {
|
const newPasswordInput = document.getElementById("newPassword");
|
||||||
if (event.matches) {
|
if (newPasswordInput) {
|
||||||
document.body.classList.add("dark-mode");
|
newPasswordInput.addEventListener("input", function() {
|
||||||
if (darkModeToggle) darkModeToggle.textContent = "Light Mode";
|
console.log("newPassword input event:", this.value);
|
||||||
} else {
|
|
||||||
document.body.classList.remove("dark-mode");
|
|
||||||
if (darkModeToggle) darkModeToggle.textContent = "Dark Mode";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// --- End Dark Mode Persistence ---
|
|
||||||
|
|
||||||
const message = sessionStorage.getItem("welcomeMessage");
|
|
||||||
if (message) {
|
|
||||||
showToast(message);
|
|
||||||
sessionStorage.removeItem("welcomeMessage");
|
|
||||||
}
|
|
||||||
|
|
||||||
checkAuthentication().then(authenticated => {
|
|
||||||
if (authenticated) {
|
|
||||||
window.currentFolder = "root";
|
|
||||||
initTagSearch();
|
|
||||||
loadFileList(window.currentFolder);
|
|
||||||
initDragAndDrop();
|
|
||||||
loadSidebarOrder();
|
|
||||||
loadHeaderOrder();
|
|
||||||
initFileActions();
|
|
||||||
initUpload();
|
|
||||||
loadFolderTree();
|
|
||||||
setupTrashRestoreDelete();
|
|
||||||
|
|
||||||
const helpBtn = document.getElementById("folderHelpBtn");
|
|
||||||
const helpTooltip = document.getElementById("folderHelpTooltip");
|
|
||||||
helpBtn.addEventListener("click", function () {
|
|
||||||
// Toggle display of the tooltip.
|
|
||||||
if (helpTooltip.style.display === "none" || helpTooltip.style.display === "") {
|
|
||||||
helpTooltip.style.display = "block";
|
|
||||||
} else {
|
|
||||||
helpTooltip.style.display = "none";
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn("User not authenticated. Data loading deferred.");
|
console.error("newPassword input not found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Dark Mode Persistence ---
|
||||||
|
const darkModeToggle = document.getElementById("darkModeToggle");
|
||||||
|
const storedDarkMode = localStorage.getItem("darkMode");
|
||||||
|
|
||||||
|
if (storedDarkMode === "true") {
|
||||||
|
document.body.classList.add("dark-mode");
|
||||||
|
} else if (storedDarkMode === "false") {
|
||||||
|
document.body.classList.remove("dark-mode");
|
||||||
|
} else {
|
||||||
|
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
|
document.body.classList.add("dark-mode");
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove("dark-mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (darkModeToggle) {
|
||||||
|
darkModeToggle.textContent = document.body.classList.contains("dark-mode")
|
||||||
|
? "Light Mode"
|
||||||
|
: "Dark Mode";
|
||||||
|
|
||||||
|
darkModeToggle.addEventListener("click", function () {
|
||||||
|
if (document.body.classList.contains("dark-mode")) {
|
||||||
|
document.body.classList.remove("dark-mode");
|
||||||
|
localStorage.setItem("darkMode", "false");
|
||||||
|
darkModeToggle.textContent = "Dark Mode";
|
||||||
|
} else {
|
||||||
|
document.body.classList.add("dark-mode");
|
||||||
|
localStorage.setItem("darkMode", "true");
|
||||||
|
darkModeToggle.textContent = "Light Mode";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localStorage.getItem("darkMode") === null && window.matchMedia) {
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (event) => {
|
||||||
|
if (event.matches) {
|
||||||
|
document.body.classList.add("dark-mode");
|
||||||
|
if (darkModeToggle) darkModeToggle.textContent = "Light Mode";
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove("dark-mode");
|
||||||
|
if (darkModeToggle) darkModeToggle.textContent = "Dark Mode";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// --- End Dark Mode Persistence ---
|
||||||
|
|
||||||
|
const message = sessionStorage.getItem("welcomeMessage");
|
||||||
|
if (message) {
|
||||||
|
showToast(message);
|
||||||
|
sessionStorage.removeItem("welcomeMessage");
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error("Initialization halted due to CSRF token load failure.", error);
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- Auto-scroll During Drag ---
|
// --- Auto-scroll During Drag ---
|
||||||
|
|||||||
@@ -20,9 +20,8 @@ if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
|||||||
http_response_code(401);
|
http_response_code(401);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
|||||||
http_response_code(401);
|
http_response_code(401);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
@@ -27,9 +27,8 @@ if ($receivedToken !== $_SESSION['csrf_token']) {
|
|||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 459 KiB After Width: | Height: | Size: 499 KiB |
@@ -18,9 +18,8 @@ if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
|||||||
http_response_code(401);
|
http_response_code(401);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
// Check if the user is read-only. (Assuming that if readOnly is true, deletion is disallowed.)
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
if (isset($userPermissions['readOnly']) && $userPermissions['readOnly'] === true) {
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ if (!isset($_SESSION['authenticated']) || $_SESSION['authenticated'] !== true) {
|
|||||||
http_response_code(401);
|
http_response_code(401);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$userPermissions = loadUserPermissions($username);
|
|
||||||
$username = $_SESSION['username'] ?? '';
|
$username = $_SESSION['username'] ?? '';
|
||||||
|
$userPermissions = loadUserPermissions($username);
|
||||||
if ($username) {
|
if ($username) {
|
||||||
$userPermissions = loadUserPermissions($username);
|
$userPermissions = loadUserPermissions($username);
|
||||||
if (isset($userPermissions['disableUpload']) && $userPermissions['disableUpload'] === true) {
|
if (isset($userPermissions['disableUpload']) && $userPermissions['disableUpload'] === true) {
|
||||||
|
|||||||
Reference in New Issue
Block a user