A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
81
fork

Configure Feed

Select the types of activity you want to include in your feed.

support did lookups in urls

+33 -8
+16 -4
pkg/appview/handlers/repository.go
··· 31 31 } 32 32 33 33 func (h *RepositoryPageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 34 - handle := chi.URLParam(r, "handle") 34 + identifier := chi.URLParam(r, "handle") 35 35 repository := chi.URLParam(r, "repository") 36 36 37 - // Look up user by handle 38 - owner, err := db.GetUserByHandle(h.DB, handle) 37 + // Resolve identifier (handle or DID) to canonical DID and current handle 38 + did, resolvedHandle, _, err := atproto.ResolveIdentity(r.Context(), identifier) 39 39 if err != nil { 40 - http.Error(w, err.Error(), http.StatusInternalServerError) 40 + http.Error(w, "User not found", http.StatusNotFound) 41 41 return 42 42 } 43 43 44 + // Look up user by DID 45 + owner, err := db.GetUserByDID(h.DB, did) 46 + if err != nil { 47 + http.Error(w, err.Error(), http.StatusInternalServerError) 48 + return 49 + } 44 50 if owner == nil { 45 51 http.Error(w, "User not found", http.StatusNotFound) 46 52 return 53 + } 54 + 55 + // Opportunistically update cached handle if it changed 56 + if owner.Handle != resolvedHandle { 57 + _ = db.UpdateUserHandle(h.DB, did, resolvedHandle) 58 + owner.Handle = resolvedHandle 47 59 } 48 60 49 61 // Fetch tags with platform information
+17 -4
pkg/appview/handlers/user.go
··· 6 6 "net/http" 7 7 8 8 "atcr.io/pkg/appview/db" 9 + "atcr.io/pkg/atproto" 9 10 "github.com/go-chi/chi/v5" 10 11 ) 11 12 ··· 17 18 } 18 19 19 20 func (h *UserPageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 20 - handle := chi.URLParam(r, "handle") 21 + identifier := chi.URLParam(r, "handle") 21 22 22 - // Look up user by handle 23 - viewedUser, err := db.GetUserByHandle(h.DB, handle) 23 + // Resolve identifier (handle or DID) to canonical DID and current handle 24 + did, resolvedHandle, _, err := atproto.ResolveIdentity(r.Context(), identifier) 25 + if err != nil { 26 + http.Error(w, "User not found", http.StatusNotFound) 27 + return 28 + } 29 + 30 + // Look up user by DID 31 + viewedUser, err := db.GetUserByDID(h.DB, did) 24 32 if err != nil { 25 33 http.Error(w, err.Error(), http.StatusInternalServerError) 26 34 return 27 35 } 28 - 29 36 if viewedUser == nil { 30 37 http.Error(w, "User not found", http.StatusNotFound) 31 38 return 39 + } 40 + 41 + // Opportunistically update cached handle if it changed 42 + if viewedUser.Handle != resolvedHandle { 43 + _ = db.UpdateUserHandle(h.DB, did, resolvedHandle) 44 + viewedUser.Handle = resolvedHandle 32 45 } 33 46 34 47 // Fetch repositories for this user