feat: Add delete button for uploaded CSV files in admin panel

- Added delete button (trash icon) next to each uploaded file in the import section
- Implemented DELETE endpoint at /admin/delete-file/{filename} with authentication and validation
- Added JavaScript function to handle file deletion with confirmation dialog
- Includes security checks for directory traversal and file existence
- Logs file deletion actions with username for audit trail
- UI automatically refreshes after successful deletion
This commit is contained in:
HotSwapp
2025-10-08 13:07:04 -05:00
parent fa4e0b9f62
commit dc1c10f44b
2 changed files with 92 additions and 1 deletions

View File

@@ -1803,6 +1803,61 @@ async def admin_sync_data(
})
@app.delete("/admin/delete-file/{filename}")
async def admin_delete_file(
request: Request,
filename: str,
db: Session = Depends(get_db)
):
"""
Delete an uploaded CSV file from the data-import directory.
Requires authentication and validates that the file exists.
"""
# Check authentication
user = get_current_user_from_session(request.session)
if not user:
raise HTTPException(status_code=401, detail="Unauthorized")
# Validate filename to prevent directory traversal
if ".." in filename or "/" in filename or "\\" in filename:
raise HTTPException(status_code=400, detail="Invalid filename")
# Construct file path
import_dir = "data-import"
file_path = os.path.join(import_dir, filename)
# Check if file exists
if not os.path.exists(file_path):
raise HTTPException(status_code=404, detail="File not found")
# Check if it's actually a file (not a directory)
if not os.path.isfile(file_path):
raise HTTPException(status_code=400, detail="Not a file")
try:
# Delete the file
os.remove(file_path)
# Log the deletion
logger.info(
"admin_delete_file",
filename=filename,
username=user.username,
)
return {"success": True, "message": f"File '{filename}' deleted successfully"}
except Exception as e:
logger.error(
"admin_delete_file_error",
filename=filename,
username=user.username,
error=str(e)
)
raise HTTPException(status_code=500, detail=f"Error deleting file: {str(e)}")
@app.get("/admin")
async def admin_panel(request: Request, db: Session = Depends(get_db)):
"""