perf+security: polling guards, sensitive data redaction, SAF path sanitization

Go backend:
- Add sensitive data redaction in log buffer (tokens, keys, passwords)
- Validate extension auth URLs (HTTPS only, no private IPs, no embedded creds)
- Block embedded credentials in extension HTTP requests
- Tighten extension storage file permissions (0644 -> 0600)
- Sanitize extension ID in store download path
- Summarize auth URLs in logs to prevent token leakage

Android (Kotlin):
- Add sanitizeRelativeDir to prevent path traversal in SAF operations
- Apply sanitizeFilename to all user-provided file names in SAF

Flutter:
- Add sensitive data redaction in Dart logger (mirrors Go patterns)
- Mask device ID in log exports
- Add in-flight guard to progress polling (download queue + local library)
- Remove redundant _downloadedSpotifyIds Set, use _bySpotifyId map
- Remove redundant _isrcSet, use _byIsrc map
- Expand DownloadQueueLookup with byItemId and itemIds
- Lazy search index building in queue tab
- Bound embedded cover cache in queue tab (max 180)
- Coalesce embedded cover refresh callbacks via postFrameCallback
- Cache album track filtering in downloaded album screen
- Cache thumbnail sizes by extension ID in home tab
- Simplify recent access aggregation (single-pass)
- Remove unused _isTyping state in home tab
- Cap pre-warm track batch size to 80
- Skip setShowingRecentAccess if value unchanged
- Use downloadQueueLookupProvider for granular queue selectors
- Move grouped album filtering before content data computation
This commit is contained in:
zarzet
2026-02-11 02:02:03 +07:00
parent a9150b85b9
commit 84df64fcfe
14 changed files with 785 additions and 330 deletions
+16
View File
@@ -3,6 +3,7 @@ package gobackend
import (
"encoding/json"
"fmt"
"regexp"
"strings"
"sync"
"time"
@@ -30,8 +31,22 @@ const (
var (
globalLogBuffer *LogBuffer
logBufferOnce sync.Once
authorizationBearerPattern = regexp.MustCompile(`(?i)\bAuthorization\b\s*[:=]\s*Bearer\s+[A-Za-z0-9._~+/\-]+=*`)
genericKeyValuePattern = regexp.MustCompile(`(?i)\b(access[_\s-]?token|refresh[_\s-]?token|id[_\s-]?token|client[_\s-]?secret|authorization|password|api[_\s-]?key)\b(\s*[:=]\s*)([^\s,;]+)`)
queryTokenPattern = regexp.MustCompile(`(?i)([?&](?:access_token|refresh_token|id_token|token|client_secret|api_key|apikey|password)=)[^&\s]+`)
bearerTokenPattern = regexp.MustCompile(`(?i)\bBearer\s+[A-Za-z0-9._~+/\-]+=*`)
)
func sanitizeSensitiveLogText(message string) string {
redacted := message
redacted = authorizationBearerPattern.ReplaceAllString(redacted, "Authorization: Bearer [REDACTED]")
redacted = genericKeyValuePattern.ReplaceAllString(redacted, `${1}${2}[REDACTED]`)
redacted = queryTokenPattern.ReplaceAllString(redacted, `${1}[REDACTED]`)
redacted = bearerTokenPattern.ReplaceAllString(redacted, "Bearer [REDACTED]")
return redacted
}
func GetLogBuffer() *LogBuffer {
logBufferOnce.Do(func() {
globalLogBuffer = &LogBuffer{
@@ -71,6 +86,7 @@ func (lb *LogBuffer) Add(level, tag, message string) {
return
}
message = sanitizeSensitiveLogText(message)
message = truncateLogMessage(message)
entry := LogEntry{