fix: remove hashed_ip from bugreport service, store email in mail.eml (#442)
## Summary - **Remove hashed_ip entirely**: dropped `HashedIP` field, `hashIP` function, and all IP extraction logic from the server. No IP address is collected or stored in any form. - **Move contact email out of report.json**: if the user opts to include their email for follow-up, it is now written to `mail.eml` in the report directory instead of being embedded in `report.json`. This keeps PII separate from the structured report data. - Remove now-unused imports (`crypto/sha256`, `encoding/hex`, `strings`). - Flutter client (`bug_report_screen.dart`) was already not sending a `hashed_ip` field — no client changes needed. ## Test plan - [x] `go build ./...` in `server/bugreport/` passes with no errors - [x] `go vet ./...` passes with no warnings - Reports without a contact email produce only `report.json` (no `mail.eml`) - Reports with a contact email produce `report.json` (no `email` key) and `mail.eml` containing the address Closes #441 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Thomas SharedInbox <sharedinbox@thomas-guettler.de> Reviewed-on: https://codeberg.org/guettli/sharedinbox/pulls/442
This commit was merged in pull request #442.
This commit is contained in:
committed by
guettli
co-authored by
guettli
Thomas SharedInbox
parent
913e5493f5
commit
71dac3cbb2
+11
-27
@@ -2,8 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -13,7 +11,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -21,12 +18,10 @@ import (
|
|||||||
// BugReport represents the data stored in report.json
|
// BugReport represents the data stored in report.json
|
||||||
type BugReport struct {
|
type BugReport struct {
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Email string `json:"email"`
|
|
||||||
AboutInfo string `json:"about_info"`
|
AboutInfo string `json:"about_info"`
|
||||||
EmailData string `json:"email_data,omitempty"`
|
EmailData string `json:"email_data,omitempty"`
|
||||||
SyncLog string `json:"sync_log,omitempty"`
|
SyncLog string `json:"sync_log,omitempty"`
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
HashedIP string `json:"hashed_ip"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -75,12 +70,6 @@ func generateUUID() (string, error) {
|
|||||||
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]), nil
|
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashIP(ip string) string {
|
|
||||||
h := sha256.New()
|
|
||||||
h.Write([]byte(ip))
|
|
||||||
return hex.EncodeToString(h.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func bugReportHandler(storageDir string) http.HandlerFunc {
|
func bugReportHandler(storageDir string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Enable CORS so the web app (if applicable) can upload
|
// Enable CORS so the web app (if applicable) can upload
|
||||||
@@ -143,20 +132,6 @@ func bugReportHandler(storageDir string) http.HandlerFunc {
|
|||||||
emailData := r.FormValue("email_data")
|
emailData := r.FormValue("email_data")
|
||||||
syncLog := r.FormValue("sync_log")
|
syncLog := r.FormValue("sync_log")
|
||||||
|
|
||||||
// Get IP address
|
|
||||||
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
|
||||||
if err != nil {
|
|
||||||
ip = r.RemoteAddr
|
|
||||||
}
|
|
||||||
// Check X-Forwarded-For if behind a proxy
|
|
||||||
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
|
|
||||||
parts := strings.Split(xff, ",")
|
|
||||||
if len(parts) > 0 {
|
|
||||||
ip = strings.TrimSpace(parts[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hashedIP := hashIP(ip)
|
|
||||||
|
|
||||||
uuidVal, err := generateUUID()
|
uuidVal, err := generateUUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to generate UUID: %v", err)
|
log.Printf("Failed to generate UUID: %v", err)
|
||||||
@@ -179,12 +154,10 @@ func bugReportHandler(storageDir string) http.HandlerFunc {
|
|||||||
// Write report.json
|
// Write report.json
|
||||||
report := BugReport{
|
report := BugReport{
|
||||||
Description: description,
|
Description: description,
|
||||||
Email: email,
|
|
||||||
AboutInfo: aboutInfo,
|
AboutInfo: aboutInfo,
|
||||||
EmailData: emailData,
|
EmailData: emailData,
|
||||||
SyncLog: syncLog,
|
SyncLog: syncLog,
|
||||||
Timestamp: now,
|
Timestamp: now,
|
||||||
HashedIP: hashedIP,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reportJSONPath := filepath.Join(reportDir, "report.json")
|
reportJSONPath := filepath.Join(reportDir, "report.json")
|
||||||
@@ -205,6 +178,17 @@ func bugReportHandler(storageDir string) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write contact email to mail.eml (kept separate from report.json to isolate PII)
|
||||||
|
if email != "" {
|
||||||
|
mailEmlPath := filepath.Join(reportDir, "mail.eml")
|
||||||
|
err = os.WriteFile(mailEmlPath, []byte(email), 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed to write mail.eml: %v", err)
|
||||||
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save attachments
|
// Save attachments
|
||||||
form := r.MultipartForm
|
form := r.MultipartForm
|
||||||
files := form.File["attachments[]"]
|
files := form.File["attachments[]"]
|
||||||
|
|||||||
Reference in New Issue
Block a user