From 6dad9432d03eb918db784a7740627ea15a5059a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Sat, 7 Feb 2026 23:14:38 +0100 Subject: [PATCH] Add UpdateFilePath method to update file name and path while preserving ID --- go_cloud/internal/database/db.go | 11 +++++++++++ go_cloud/internal/http/routes.go | 32 ++++++++++++++++---------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/go_cloud/internal/database/db.go b/go_cloud/internal/database/db.go index 7efb9a5..a7bb8b9 100644 --- a/go_cloud/internal/database/db.go +++ b/go_cloud/internal/database/db.go @@ -982,6 +982,17 @@ func (db *DB) UpdateFileSize(ctx context.Context, fileID uuid.UUID, size int64, return err } +// UpdateFilePath updates the path and name of a file while preserving its ID +// This is used when moving/renaming files to ensure WOPI sessions remain valid +func (db *DB) UpdateFilePath(ctx context.Context, fileID uuid.UUID, newName, newPath string) error { + _, err := db.ExecContext(ctx, ` + UPDATE files + SET name = $1, path = $2, last_modified = NOW() + WHERE id = $3 + `, newName, newPath, fileID) + return err +} + // DeleteFileByPath removes a file or folder matching path for a given org or user func (db *DB) DeleteFileByPath(ctx context.Context, orgID *uuid.UUID, userID *uuid.UUID, path string) error { var res sql.Result diff --git a/go_cloud/internal/http/routes.go b/go_cloud/internal/http/routes.go index 68cda69..a6a5939 100644 --- a/go_cloud/internal/http/routes.go +++ b/go_cloud/internal/http/routes.go @@ -2280,6 +2280,9 @@ func moveOrgFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB, newPath = req.TargetPath } + // Determine new filename from the path + newName := path.Base(newPath) + // Get or create user's WebDAV client and move in Nextcloud storageClient, err := getUserWebDAVClient(r.Context(), db, userID, cfg.NextcloudURL, cfg.NextcloudUser, cfg.NextcloudPass) if err != nil { @@ -2294,14 +2297,11 @@ func moveOrgFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB, } } - // Delete old file record - if err := db.DeleteFileByPath(r.Context(), &orgID, nil, req.SourcePath); err != nil { - errors.LogError(r, err, "Failed to delete old file record") - } - - // Create new file record at the new location - if _, err := db.CreateFile(r.Context(), &orgID, nil, sourceFile.Name, newPath, sourceFile.Type, sourceFile.Size); err != nil { - errors.LogError(r, err, "Failed to create new file record at destination") + // Update file record path and name in-place (preserves file ID for WOPI sessions) + if err := db.UpdateFilePath(r.Context(), sourceFile.ID, newName, newPath); err != nil { + errors.LogError(r, err, "Failed to update file path") + errors.WriteError(w, errors.CodeInternal, "Server error", http.StatusInternalServerError) + return } auditLogger.Log(r.Context(), audit.Entry{ @@ -2508,6 +2508,9 @@ func moveUserFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB newPath = req.TargetPath } + // Determine new filename from the path + newName := path.Base(newPath) + // Get or create user's WebDAV client and move in Nextcloud storageClient, err := getUserWebDAVClient(r.Context(), db, userID, cfg.NextcloudURL, cfg.NextcloudUser, cfg.NextcloudPass) if err != nil { @@ -2521,14 +2524,11 @@ func moveUserFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB } } - // Delete old file record - if err := db.DeleteFileByPath(r.Context(), nil, &userID, req.SourcePath); err != nil { - errors.LogError(r, err, "Failed to delete old file record") - } - - // Create new file record at the new location - if _, err := db.CreateFile(r.Context(), nil, &userID, sourceFile.Name, newPath, sourceFile.Type, sourceFile.Size); err != nil { - errors.LogError(r, err, "Failed to create new file record at destination") + // Update file record path and name in-place (preserves file ID for WOPI sessions) + if err := db.UpdateFilePath(r.Context(), sourceFile.ID, newName, newPath); err != nil { + errors.LogError(r, err, "Failed to update file path") + errors.WriteError(w, errors.CodeInternal, "Server error", http.StatusInternalServerError) + return } auditLogger.Log(r.Context(), audit.Entry{