···
+
"Coves/internal/api/middleware"
+
"Coves/internal/core/communities"
+
// BlockHandler handles community blocking operations
+
type BlockHandler struct {
+
service communities.Service
+
// NewBlockHandler creates a new block handler
+
func NewBlockHandler(service communities.Service) *BlockHandler {
+
// HandleBlock blocks a community
+
// POST /xrpc/social.coves.community.block
+
// Body: { "community": "did:plc:xxx" or "!gaming@coves.social" }
+
func (h *BlockHandler) HandleBlock(w http.ResponseWriter, r *http.Request) {
+
if r.Method != http.MethodPost {
+
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+
Community string `json:"community"` // DID or handle
+
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+
writeError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request body")
+
if req.Community == "" {
+
writeError(w, http.StatusBadRequest, "InvalidRequest", "community is required")
+
// Validate format (DID or handle)
+
if !strings.HasPrefix(req.Community, "did:") && !strings.HasPrefix(req.Community, "!") {
+
writeError(w, http.StatusBadRequest, "InvalidRequest",
+
"community must be a DID (did:plc:...) or handle (!name@instance.com)")
+
// Extract authenticated user DID and access token from request context (injected by auth middleware)
+
userDID := middleware.GetUserDID(r)
+
writeError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required")
+
userAccessToken := middleware.GetUserAccessToken(r)
+
if userAccessToken == "" {
+
writeError(w, http.StatusUnauthorized, "AuthRequired", "Missing access token")
+
// Block via service (write-forward to PDS)
+
block, err := h.service.BlockCommunity(r.Context(), userDID, userAccessToken, req.Community)
+
handleServiceError(w, err)
+
// Return success response (following atProto conventions for block responses)
+
response := map[string]interface{}{
+
"block": map[string]interface{}{
+
"recordUri": block.RecordURI,
+
"recordCid": block.RecordCID,
+
w.Header().Set("Content-Type", "application/json")
+
w.WriteHeader(http.StatusOK)
+
if err := json.NewEncoder(w).Encode(response); err != nil {
+
log.Printf("Failed to encode response: %v", err)
+
// HandleUnblock unblocks a community
+
// POST /xrpc/social.coves.community.unblock
+
// Body: { "community": "did:plc:xxx" or "!gaming@coves.social" }
+
func (h *BlockHandler) HandleUnblock(w http.ResponseWriter, r *http.Request) {
+
if r.Method != http.MethodPost {
+
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+
Community string `json:"community"`
+
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+
writeError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request body")
+
if req.Community == "" {
+
writeError(w, http.StatusBadRequest, "InvalidRequest", "community is required")
+
// Validate format (DID or handle)
+
if !strings.HasPrefix(req.Community, "did:") && !strings.HasPrefix(req.Community, "!") {
+
writeError(w, http.StatusBadRequest, "InvalidRequest",
+
"community must be a DID (did:plc:...) or handle (!name@instance.com)")
+
// Extract authenticated user DID and access token from request context (injected by auth middleware)
+
userDID := middleware.GetUserDID(r)
+
writeError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required")
+
userAccessToken := middleware.GetUserAccessToken(r)
+
if userAccessToken == "" {
+
writeError(w, http.StatusUnauthorized, "AuthRequired", "Missing access token")
+
// Unblock via service (delete record on PDS)
+
err := h.service.UnblockCommunity(r.Context(), userDID, userAccessToken, req.Community)
+
handleServiceError(w, err)
+
// Return success response
+
w.Header().Set("Content-Type", "application/json")
+
w.WriteHeader(http.StatusOK)
+
if err := json.NewEncoder(w).Encode(map[string]interface{}{
+
log.Printf("Failed to encode response: %v", err)