fix: resolve file management operations not working (#83)
- Fix rename: context menu was nullifying target reference before rename dialog could use it - Fix delete files/folders: auth extractors were mandatory, causing 401 when auth not configured - Fix view-file: async fetch race condition with context menu cleanup - Fix orphaned ID mappings on file deletion - Fix Authorization: Bearer null headers sent without token - Add OptionalUserId and OptionalAuthUser infallible extractors
This commit is contained in:
+11
-8
@@ -680,12 +680,15 @@ async function loadFiles(options = {}) {
|
||||
}
|
||||
|
||||
const token = localStorage.getItem('oxicloud_token');
|
||||
const headers = {
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
'Pragma': 'no-cache'
|
||||
};
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
const requestOptions = {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
'Pragma': 'no-cache'
|
||||
},
|
||||
headers,
|
||||
cache: 'no-store' // Instruct the browser not to use cache
|
||||
};
|
||||
|
||||
@@ -1727,10 +1730,10 @@ async function findUserHomeFolder(username) {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 3000); // Reduced timeout to 3 seconds
|
||||
|
||||
const folderToken = localStorage.getItem('oxicloud_token');
|
||||
const folderHeaders = folderToken ? { 'Authorization': `Bearer ${folderToken}` } : {};
|
||||
const response = await fetch('/api/folders', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('oxicloud_token')}`
|
||||
},
|
||||
headers: folderHeaders,
|
||||
signal: controller.signal
|
||||
});
|
||||
|
||||
|
||||
+25
-23
@@ -81,11 +81,11 @@ const contextMenus = {
|
||||
// File context menu options
|
||||
document.getElementById('view-file-option').addEventListener('click', () => {
|
||||
if (window.app.contextMenuTargetFile) {
|
||||
// Fetch file details to get the mime type
|
||||
// Capture reference before context menu cleanup nullifies it
|
||||
const file = window.app.contextMenuTargetFile;
|
||||
const token = localStorage.getItem('oxicloud_token');
|
||||
fetch(`/api/files/${window.app.contextMenuTargetFile.id}?metadata=true`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
})
|
||||
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
|
||||
fetch(`/api/files/${file.id}?metadata=true`, { headers })
|
||||
.then(response => response.json())
|
||||
.then(fileDetails => {
|
||||
// Check if viewable file type (images, PDFs, text files)
|
||||
@@ -97,26 +97,17 @@ const contextMenus = {
|
||||
window.fileViewer.open(fileDetails);
|
||||
} else {
|
||||
// If no viewer is available, download directly
|
||||
window.fileOps.downloadFile(
|
||||
window.app.contextMenuTargetFile.id,
|
||||
window.app.contextMenuTargetFile.name
|
||||
);
|
||||
window.fileOps.downloadFile(file.id, file.name);
|
||||
}
|
||||
} else {
|
||||
// For non-viewable files, download
|
||||
window.fileOps.downloadFile(
|
||||
window.app.contextMenuTargetFile.id,
|
||||
window.app.contextMenuTargetFile.name
|
||||
);
|
||||
window.fileOps.downloadFile(file.id, file.name);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching file details:', error);
|
||||
// On error, fallback to download
|
||||
window.fileOps.downloadFile(
|
||||
window.app.contextMenuTargetFile.id,
|
||||
window.app.contextMenuTargetFile.name
|
||||
);
|
||||
window.fileOps.downloadFile(file.id, file.name);
|
||||
});
|
||||
}
|
||||
window.ui.closeFileContextMenu();
|
||||
@@ -242,6 +233,8 @@ const contextMenus = {
|
||||
const renameDialog = document.getElementById('rename-dialog');
|
||||
|
||||
window.app.renameMode = 'folder';
|
||||
// Store the folder reference so it survives context menu cleanup
|
||||
window.app.renameTarget = folder;
|
||||
renameInput.value = folder.name;
|
||||
// Update header text
|
||||
const headerSpan = renameDialog.querySelector('.rename-dialog-header span');
|
||||
@@ -260,6 +253,8 @@ const contextMenus = {
|
||||
const renameDialog = document.getElementById('rename-dialog');
|
||||
|
||||
window.app.renameMode = 'file';
|
||||
// Store the file reference so it survives context menu cleanup
|
||||
window.app.renameTarget = file;
|
||||
renameInput.value = file.name;
|
||||
// Update header text
|
||||
const headerSpan = renameDialog.querySelector('.rename-dialog-header span');
|
||||
@@ -275,6 +270,7 @@ const contextMenus = {
|
||||
closeRenameDialog() {
|
||||
document.getElementById('rename-dialog').style.display = 'none';
|
||||
window.app.contextMenuTargetFolder = null;
|
||||
window.app.renameTarget = null;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -322,14 +318,21 @@ const contextMenus = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.app.renameMode === 'file' && window.app.contextMenuTargetFile) {
|
||||
const success = await window.fileOps.renameFile(window.app.contextMenuTargetFile.id, newName);
|
||||
// Use renameTarget which was saved before the context menu was closed
|
||||
const target = window.app.renameTarget;
|
||||
if (!target) {
|
||||
console.error('No rename target available');
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.app.renameMode === 'file') {
|
||||
const success = await window.fileOps.renameFile(target.id, newName);
|
||||
if (success) {
|
||||
contextMenus.closeRenameDialog();
|
||||
window.loadFiles();
|
||||
}
|
||||
} else if (window.app.contextMenuTargetFolder) {
|
||||
const success = await window.fileOps.renameFolder(window.app.contextMenuTargetFolder.id, newName);
|
||||
} else if (window.app.renameMode === 'folder') {
|
||||
const success = await window.fileOps.renameFolder(target.id, newName);
|
||||
if (success) {
|
||||
contextMenus.closeRenameDialog();
|
||||
window.loadFiles();
|
||||
@@ -350,9 +353,8 @@ const contextMenus = {
|
||||
async loadAllFolders(itemId, mode) {
|
||||
try {
|
||||
const token = localStorage.getItem('oxicloud_token');
|
||||
const response = await fetch('/api/folders', {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
|
||||
const response = await fetch('/api/folders', { headers });
|
||||
if (response.ok) {
|
||||
const folders = await response.json();
|
||||
const folderSelectContainer = document.getElementById('folder-select-container');
|
||||
|
||||
+13
-13
@@ -31,11 +31,11 @@ const favorites = {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 3000); // 3s timeout
|
||||
|
||||
const favToken = localStorage.getItem('oxicloud_token');
|
||||
const favHeaders = favToken ? { 'Authorization': `Bearer ${favToken}` } : {};
|
||||
const response = await fetch('/api/favorites', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('oxicloud_token')}`
|
||||
},
|
||||
headers: favHeaders,
|
||||
signal: controller.signal
|
||||
}).catch(err => {
|
||||
console.warn('Network error checking favorites API:', err);
|
||||
@@ -67,10 +67,10 @@ const favorites = {
|
||||
async syncWithServer() {
|
||||
try {
|
||||
// Get server favorites
|
||||
const syncToken = localStorage.getItem('oxicloud_token');
|
||||
const syncHeaders = syncToken ? { 'Authorization': `Bearer ${syncToken}` } : {};
|
||||
const response = await fetch('/api/favorites', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('oxicloud_token')}`
|
||||
}
|
||||
headers: syncHeaders
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -149,12 +149,12 @@ const favorites = {
|
||||
*/
|
||||
async addToServerFavorites(id, type) {
|
||||
try {
|
||||
const addToken = localStorage.getItem('oxicloud_token');
|
||||
const addHeaders = { 'Content-Type': 'application/json' };
|
||||
if (addToken) addHeaders['Authorization'] = `Bearer ${addToken}`;
|
||||
const response = await fetch(`/api/favorites/${type}/${id}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('oxicloud_token')}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
headers: addHeaders
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -175,11 +175,11 @@ const favorites = {
|
||||
*/
|
||||
async removeFromServerFavorites(id, type) {
|
||||
try {
|
||||
const rmToken = localStorage.getItem('oxicloud_token');
|
||||
const rmHeaders = rmToken ? { 'Authorization': `Bearer ${rmToken}` } : {};
|
||||
const response = await fetch(`/api/favorites/${type}/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('oxicloud_token')}`
|
||||
}
|
||||
headers: rmHeaders
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
Reference in New Issue
Block a user