Multi-format document viewer: add image/text/office file type support
This commit is contained in:
@@ -469,30 +469,33 @@ func viewerHandler(w http.ResponseWriter, r *http.Request, db *database.DB, jwtM
|
||||
}
|
||||
downloadPath := fmt.Sprintf("%s://%s/orgs/%s/files/download?path=%s&token=%s", scheme, host, orgID.String(), url.QueryEscape(file.Path), url.QueryEscape(viewerToken))
|
||||
|
||||
// Determine if it's a PDF based on file extension
|
||||
// Determine file type based on extension
|
||||
isPdf := strings.HasSuffix(strings.ToLower(file.Name), ".pdf")
|
||||
mimeType := getMimeType(file.Name)
|
||||
|
||||
viewerSession := struct {
|
||||
ViewUrl string `json:"viewUrl"`
|
||||
Token string `json:"token"`
|
||||
Capabilities struct {
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
MimeType string `json:"mimeType"`
|
||||
} `json:"capabilities"`
|
||||
ExpiresAt string `json:"expiresAt"`
|
||||
}{
|
||||
ViewUrl: downloadPath,
|
||||
Token: viewerToken, // Long-lived JWT token for authenticating file download
|
||||
Capabilities: struct {
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
}{CanEdit: false, CanAnnotate: isPdf, IsPdf: isPdf},
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
MimeType string `json:"mimeType"`
|
||||
}{CanEdit: false, CanAnnotate: isPdf, IsPdf: isPdf, MimeType: mimeType},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour).UTC().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
fmt.Printf("[VIEWER-SESSION] orgId=%s, fileId=%s, token_included=yes, isPdf=%v\n", orgID.String(), fileId, isPdf)
|
||||
fmt.Printf("[VIEWER-SESSION] orgId=%s, fileId=%s, token_included=yes, isPdf=%v, mimeType=%s\n", orgID.String(), fileId, isPdf, mimeType)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(viewerSession)
|
||||
@@ -552,34 +555,38 @@ func userViewerHandler(w http.ResponseWriter, r *http.Request, db *database.DB,
|
||||
}
|
||||
downloadPath := fmt.Sprintf("%s://%s/user/files/download?path=%s&token=%s", scheme, host, url.QueryEscape(file.Path), url.QueryEscape(viewerToken))
|
||||
|
||||
// Determine if it's a PDF based on file extension
|
||||
// Determine file type based on extension
|
||||
isPdf := strings.HasSuffix(strings.ToLower(file.Name), ".pdf")
|
||||
mimeType := getMimeType(file.Name)
|
||||
|
||||
viewerSession := struct {
|
||||
ViewUrl string `json:"viewUrl"`
|
||||
Token string `json:"token"`
|
||||
Capabilities struct {
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
MimeType string `json:"mimeType"`
|
||||
} `json:"capabilities"`
|
||||
ExpiresAt string `json:"expiresAt"`
|
||||
}{
|
||||
ViewUrl: downloadPath,
|
||||
Token: viewerToken, // Long-lived JWT token for authenticating file download
|
||||
Capabilities: struct {
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanAnnotate bool `json:"canAnnotate"`
|
||||
IsPdf bool `json:"isPdf"`
|
||||
MimeType string `json:"mimeType"`
|
||||
}{
|
||||
CanEdit: false,
|
||||
CanAnnotate: isPdf,
|
||||
IsPdf: isPdf,
|
||||
MimeType: mimeType,
|
||||
},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour).UTC().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
fmt.Printf("[VIEWER-SESSION] userId=%s, fileId=%s, token_included=yes, isPdf=%v\n", userID.String(), fileId, isPdf)
|
||||
fmt.Printf("[VIEWER-SESSION] userId=%s, fileId=%s, token_included=yes, isPdf=%v, mimeType=%s\n", userID.String(), fileId, isPdf, mimeType)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(viewerSession)
|
||||
@@ -1765,3 +1772,38 @@ func downloadUserFileHandler(w http.ResponseWriter, r *http.Request, db *databas
|
||||
io.Copy(w, resp.Body)
|
||||
|
||||
}
|
||||
|
||||
// getMimeType returns the MIME type based on file extension
|
||||
func getMimeType(filename string) string {
|
||||
lower := strings.ToLower(filename)
|
||||
switch {
|
||||
case strings.HasSuffix(lower, ".pdf"):
|
||||
return "application/pdf"
|
||||
case strings.HasSuffix(lower, ".png"):
|
||||
return "image/png"
|
||||
case strings.HasSuffix(lower, ".jpg"), strings.HasSuffix(lower, ".jpeg"):
|
||||
return "image/jpeg"
|
||||
case strings.HasSuffix(lower, ".gif"):
|
||||
return "image/gif"
|
||||
case strings.HasSuffix(lower, ".webp"):
|
||||
return "image/webp"
|
||||
case strings.HasSuffix(lower, ".svg"):
|
||||
return "image/svg+xml"
|
||||
case strings.HasSuffix(lower, ".txt"):
|
||||
return "text/plain"
|
||||
case strings.HasSuffix(lower, ".html"):
|
||||
return "text/html"
|
||||
case strings.HasSuffix(lower, ".json"):
|
||||
return "application/json"
|
||||
case strings.HasSuffix(lower, ".csv"):
|
||||
return "text/csv"
|
||||
case strings.HasSuffix(lower, ".doc"), strings.HasSuffix(lower, ".docx"):
|
||||
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||||
case strings.HasSuffix(lower, ".xls"), strings.HasSuffix(lower, ".xlsx"):
|
||||
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
case strings.HasSuffix(lower, ".ppt"), strings.HasSuffix(lower, ".pptx"):
|
||||
return "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
||||
default:
|
||||
return "application/octet-stream"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user