updated debugging and scoped path (#1198)

This commit is contained in:
Graham Steffaniak authored and GitHub committed 2025-09-09 12:21:16 -05:00
1 parent 7baf2653e0
commit 2d2a3d7707
3 files changed
+76 -40

No files matched your search

+38 -35
View File
@@ -7,6 +7,7 @@ import (
"io"
"net/http"
"net/url"
"path/filepath"
"strconv"
"strings"
@@ -49,7 +50,21 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
return http.StatusBadRequest, errors.New("missing required parameters: path + source/hash are required")
}
themeMode := utils.Ternary(d.user.DarkMode, "dark", "light")
var sourceInfo settings.Source
var ok bool
if d.fileInfo.Hash != "" {
sourceInfo, ok = settings.Config.Server.SourceMap[source]
if !ok {
logger.Error("OnlyOffice: source not found")
return http.StatusInternalServerError, fmt.Errorf("source not found")
}
} else {
sourceInfo, ok = settings.Config.Server.NameToSource[source]
if !ok {
logger.Error("OnlyOffice: source not found")
return http.StatusInternalServerError, fmt.Errorf("source not found")
}
}
if d.fileInfo.Hash == "" {
// Build file info based on whether this is a share or regular request
// Regular user request - need to resolve scope
@@ -58,27 +73,20 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
logger.Errorf("OnlyOffice: source %s not available for user %s: %v", source, d.user.Username, scopeErr)
return http.StatusForbidden, fmt.Errorf("source %s is not available", source)
}
resolvedPath := utils.JoinPathAsUnix(userScope, path)
logger.Debugf("OnlyOffice user request: resolved path=%s", resolvedPath)
indexPath := utils.JoinPathAsUnix(userScope, path)
logger.Debugf("OnlyOffice user request: resolved path=%s", indexPath)
fileInfo, err := files.FileInfoFaster(iteminfo.FileOptions{
Path: resolvedPath,
Path: indexPath,
Modify: d.user.Permissions.Modify,
Source: source,
Expand: false,
})
if err != nil {
logger.Errorf("OnlyOffice: failed to get file info for source=%s, path=%s: %v", source, resolvedPath, err)
logger.Errorf("OnlyOffice: failed to get file info for source=%s, path=%s: %v", source, indexPath, err)
return errToStatus(err), err
}
d.fileInfo = *fileInfo
} else {
// is a share, use the file info from the share middleware
sourceInfo, ok := settings.Config.Server.SourceMap[d.share.Source]
if !ok {
logger.Error("OnlyOffice: source from share not found")
return http.StatusInternalServerError, fmt.Errorf("source not found for share")
}
source = sourceInfo.Name
// path is index path, so we build from share path
path = utils.JoinPathAsUnix(d.share.Path, path)
@@ -92,7 +100,7 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
}
// Determine file type and editing permissions
fileType := getFileExtension(d.fileInfo.Name)
fileType := strings.TrimPrefix(filepath.Ext(d.fileInfo.Name), ".")
canEdit := iteminfo.CanEditOnlyOffice(d.user.Permissions.Modify, fileType)
canEditMode := utils.Ternary(canEdit, "edit", "view")
if d.fileInfo.Hash != "" {
@@ -111,7 +119,7 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
}
// Generate document ID for OnlyOffice
documentId, err := getOnlyOfficeId(source, path)
documentId, err := getOnlyOfficeId(d.fileInfo.RealPath)
if err != nil {
logger.Errorf("OnlyOffice: failed to generate document ID for source=%s, path=%s: %v", source, path, err)
return http.StatusNotFound, fmt.Errorf("failed to generate document ID: %v", err)
@@ -166,15 +174,6 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
return renderJSON(w, r, clientConfig)
}
// getFileExtension extracts file extension from filename
func getFileExtension(filename string) string {
parts := strings.Split(filename, ".")
if len(parts) < 2 {
return ""
}
return parts[len(parts)-1]
}
// buildOnlyOfficeDownloadURL constructs the download URL that OnlyOffice server will use to fetch the file
func buildOnlyOfficeDownloadURL(source, path, hash, token string) string {
// Determine base URL (internal URL takes priority for OnlyOffice server communication)
@@ -254,6 +253,21 @@ func onlyofficeCallbackHandler(w http.ResponseWriter, r *http.Request, d *reques
logger.Errorf("OnlyOffice callback missing required parameters: source=%s, path=%s", source, path)
return http.StatusBadRequest, errors.New("missing required parameters: path + source/hash are required")
}
var sourceInfo settings.Source
var ok bool
if d.fileInfo.Hash != "" {
sourceInfo, ok = settings.Config.Server.SourceMap[source]
if !ok {
logger.Error("OnlyOffice: source not found")
return http.StatusInternalServerError, fmt.Errorf("source not found")
}
} else {
sourceInfo, ok = settings.Config.Server.NameToSource[source]
if !ok {
logger.Error("OnlyOffice: source not found")
return http.StatusInternalServerError, fmt.Errorf("source not found")
}
}
if d.fileInfo.Hash == "" {
// Regular user request - need to resolve scope
@@ -264,12 +278,6 @@ func onlyofficeCallbackHandler(w http.ResponseWriter, r *http.Request, d *reques
}
path = utils.JoinPathAsUnix(userScope, path)
} else {
// is a share, use the file info from the share middleware
sourceInfo, ok := settings.Config.Server.SourceMap[d.share.Source]
if !ok {
logger.Error("OnlyOffice: source from share not found")
return http.StatusInternalServerError, fmt.Errorf("source not found for share")
}
source = sourceInfo.Name
// path is index path, so we build from share path
path = utils.JoinPathAsUnix(d.share.Path, path)
@@ -339,12 +347,7 @@ func onlyofficeCallbackHandler(w http.ResponseWriter, r *http.Request, d *reques
return renderJSON(w, r, resp)
}
func getOnlyOfficeId(source, path string) (string, error) {
idx := indexing.GetIndex(source)
if idx == nil {
return "", fmt.Errorf("source not found")
}
realpath, _, _ := idx.GetRealPath(path)
func getOnlyOfficeId(realpath string) (string, error) {
// error is intentionally ignored in order treat errors
// the same as a cache-miss
cachedDocumentKey, ok := utils.OnlyOfficeCache.Get(realpath).(string)
+37 -4
View File
@@ -104,6 +104,36 @@ export default {
}
},
methods: {
getInternalUrlInfo() {
if (this.clientConfig && this.clientConfig.document && this.clientConfig.document.url) {
try {
const docUrlOrigin = new URL(this.clientConfig.document.url).origin;
const windowOrigin = window.location.origin;
if (docUrlOrigin !== windowOrigin) {
return {
isSet: true,
message: `${docUrlOrigin}`
};
} else {
return {
isSet: false,
message: "Not set, using window.location"
};
}
} catch (e) {
return {
isSet: false,
message: "⚠️ Error parsing document URL"
};
}
}
return {
isSet: false,
message: "Analyzing..."
};
},
close() {
const current = window.location.pathname;
const newpath = removeLastDir(current);
@@ -137,7 +167,7 @@ export default {
<div style="margin-bottom: 15px; padding: 10px; background: #f5f5f5; border-radius: 4px;">
<strong>Configuration:</strong><br/>
OnlyOffice URL: ${this.onlyOfficeUrl}<br/>
Internal URL: Check server logs<br/>
Internal URL: ${this.getInternalUrlInfo().message}<br/>
Base URL: ${baseURL}<br/>
Source: ${this.source}<br/>
Path: ${this.path}<br/>
@@ -175,6 +205,7 @@ export default {
const filename = this.path.split('/').pop() || "";
const isShare = getters.isShare();
const internalUrlInfo = this.getInternalUrlInfo();
// Build config details if available
let configDetailsHtml = "";
@@ -196,9 +227,8 @@ export default {
Callback URL: ${editor && editor.callbackUrl ? editor.callbackUrl.substring(0, 80) + '...' : 'N/A'}<br/>
<br/>
<strong>Network Flow:</strong><br/>
Browser ↔ OnlyOffice: ${this.onlyOfficeUrl}<br/>
Browser (${window.location.origin}) ↔ OnlyOffice: ${this.onlyOfficeUrl}<br/>
OnlyOffice → FileBrowser: ${downloadDomain}<br/>
OnlyOffice → FileBrowser: ${callbackDomain}<br/>
</div>
`;
}
@@ -234,7 +264,7 @@ export default {
<div style="margin-bottom: 15px; padding: 10px; background: #f5f5f5; border-radius: 4px;">
<strong>Basic Configuration:</strong><br/>
OnlyOffice URL: ${this.onlyOfficeUrl}<br/>
Internal URL: Check server logs<br/>
Internal URL: ${internalUrlInfo.message}<br/>
Base URL: ${baseURL}<br/>
Source: ${this.source}<br/>
Path: ${this.path}<br/>
@@ -372,6 +402,9 @@ export default {
errorMsg += "<strong>Error Code -4:</strong> Document download failed<br/>";
errorMsg += "• Authentication may have expired<br/>";
errorMsg += "• Check download URL accessibility<br/>";
if (!this.getInternalUrlInfo().isSet) {
errorMsg += "• <strong>Suggestion:</strong> consider adding `server.internalUrl` if your OnlyOffice service is on the same network as FileBrowser<br/>";
}
} else {
errorMsg += `<strong>Error Code:</strong> ${errorInfo || 'Unknown error'}<br/>`;
errorMsg += "• Check browser console for detailed error messages<br/>";
+1 -1
View File
@@ -19,7 +19,7 @@ async function globalSetup() {
await page.locator('button[aria-label="File-Actions"]').click();
await page.locator('button[aria-label="Share"]').click();
await page.locator('button[aria-label="Share-Confirm"]').click();
await page.waitForResponse(response => response.url().includes('/api/share') && response.status() === 200);
await page.waitForResponse(response => response.status() === 200);
await expect(page.locator("div[aria-label='share-prompt'] .card-content table tbody tr:not(:has(th))")).toHaveCount(1);
const shareHash = await page.locator("div[aria-label='share-prompt'] .card-content table tbody tr:not(:has(th)) td").first().textContent();
if (!shareHash) {