Implement authentication check and redirect for internal file access in PublicFileViewer
This commit is contained in:
@@ -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", "*")
|
||||
|
||||
Reference in New Issue
Block a user