Implement authentication check and redirect for internal file access in PublicFileViewer

This commit is contained in:
Leon Bösche
2026-01-25 17:11:58 +01:00
parent 565b9fed6f
commit 9aa1667e9c
5 changed files with 70 additions and 24 deletions

View File

@@ -2956,43 +2956,72 @@ func publicFileShareHandler(w http.ResponseWriter, r *http.Request, db *database
downloadPath := fmt.Sprintf("%s://%s/public/share/%s/download?token=%s", scheme, host, token, url.QueryEscape(viewerToken))
viewPath := fmt.Sprintf("%s://%s/public/share/%s/view?token=%s", scheme, host, token, url.QueryEscape(viewerToken))
// Check if user is authenticated and has access to the file
var internalOrgId *string
var internalFileId *string
authHeader := r.Header.Get("Authorization")
if authHeader != "" && strings.HasPrefix(authHeader, "Bearer ") {
jwtToken := strings.TrimPrefix(authHeader, "Bearer ")
claims, err := jwtManager.Validate(jwtToken)
if err == nil {
userID, err := uuid.Parse(claims.Subject)
if err == nil {
// Check if user has access
if file.UserID != nil && *file.UserID == userID {
// Personal file, user is owner
fileIDStr := file.ID.String()
internalOrgId = nil // personal
internalFileId = &fileIDStr
} else if link.OrgID != nil {
// Org file, check if user is in org
for _, orgIDStr := range claims.OrgIDs {
orgID, err := uuid.Parse(orgIDStr)
if err == nil && orgID == *link.OrgID {
fileIDStr := file.ID.String()
internalOrgId = &orgIDStr
internalFileId = &fileIDStr
break
}
}
}
}
}
}
// Determine file type
isPdf := strings.HasSuffix(strings.ToLower(file.Name), ".pdf")
mimeType := getMimeType(file.Name)
viewerSession := struct {
FileName string `json:"fileName"`
FileSize int64 `json:"fileSize"`
DownloadUrl string `json:"downloadUrl"`
ViewUrl string `json:"viewUrl,omitempty"`
Token string `json:"token"`
Capabilities struct {
CanEdit bool `json:"canEdit"`
CanAnnotate bool `json:"canAnnotate"`
IsPdf bool `json:"isPdf"`
MimeType string `json:"mimeType"`
} `json:"capabilities"`
}{
FileName: file.Name,
FileSize: file.Size,
DownloadUrl: downloadPath,
Token: viewerToken,
viewerSession := map[string]interface{}{
"fileName": file.Name,
"fileSize": file.Size,
"downloadUrl": downloadPath,
"token": viewerToken,
"capabilities": map[string]interface{}{
"canEdit": false,
"canAnnotate": false,
"isPdf": isPdf,
"mimeType": mimeType,
},
}
// Set view URL for PDFs, videos, audio, and documents (for inline viewing)
if isPdf || strings.HasPrefix(mimeType, "video/") || strings.HasPrefix(mimeType, "audio/") {
viewerSession.ViewUrl = viewPath
viewerSession["viewUrl"] = viewPath
} else if strings.Contains(mimeType, "document") || strings.Contains(mimeType, "word") || strings.Contains(mimeType, "spreadsheet") || strings.Contains(mimeType, "presentation") {
// Use Collabora for document viewing
wopiSrc := fmt.Sprintf("%s://%s/public/wopi/share/%s", scheme, host, token)
collaboraUrl := fmt.Sprintf("https://of.b0esche.cloud/lool/dist/mobile/cool.html?WOPISrc=%s", url.QueryEscape(wopiSrc))
viewerSession.ViewUrl = collaboraUrl
viewerSession["viewUrl"] = collaboraUrl
}
viewerSession.Capabilities.CanEdit = false
viewerSession.Capabilities.CanAnnotate = false
viewerSession.Capabilities.IsPdf = isPdf
viewerSession.Capabilities.MimeType = mimeType
// Add internal access info if user has access
if internalFileId != nil {
viewerSession["fileId"] = *internalFileId
if internalOrgId != nil {
viewerSession["orgId"] = *internalOrgId
}
}
// Add CORS headers for public access
w.Header().Set("Access-Control-Allow-Origin", "*")