--- a/appview/pages/funcmap.go +++ b/appview/pages/funcmap.go @@ -505,34 +505,26 @@ did = identity.DID.String() } - secret := p.avatar.SharedSecret - h := hmac.New(sha256.New, []byte(secret)) - h.Write([]byte(did)) - signature := hex.EncodeToString(h.Sum(nil)) - - // Get avatar CID for cache busting + // Get avatar CID from profile DB profile, err := db.GetProfile(p.db, did) - version := "" - if err == nil && profile != nil && profile.Avatar != "" { - // Use first 8 chars of avatar CID as version - if len(profile.Avatar) > 8 { - version = profile.Avatar[:8] - } else { - version = profile.Avatar + if err == nil && profile != nil && profile.Avatar != "" && identity != nil { + // Get PDS endpoint from DID document + if svc, ok := identity.Services["atproto_pds"]; ok { + pdsUrl := strings.TrimRight(svc.URL, "/") + return fmt.Sprintf("%s/xrpc/com.atproto.sync.getBlob?did=%s&cid=%s", pdsUrl, did, profile.Avatar) } } - baseUrl := fmt.Sprintf("%s/%s/%s", p.avatar.Host, signature, did) - if size != "" { - if version != "" { - return fmt.Sprintf("%s?size=%s&v=%s", baseUrl, size, version) - } - return fmt.Sprintf("%s?size=%s", baseUrl, size) + // Fallback to avatar proxy if configured + if p.avatar.Host != "" && p.avatar.SharedSecret != "" { + secret := p.avatar.SharedSecret + h := hmac.New(sha256.New, []byte(secret)) + h.Write([]byte(did)) + signature := hex.EncodeToString(h.Sum(nil)) + return fmt.Sprintf("%s/%s/%s", p.avatar.Host, signature, did) } - if version != "" { - return fmt.Sprintf("%s?v=%s", baseUrl, version) - } - return baseUrl + + return "" } func (p *Pages) icon(name string, classes []string) (template.HTML, error) {