157 lines
4.7 KiB
Go
157 lines
4.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gorilla/mux"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
|
|
"github.com/noteapp/backend/internal/application/dto"
|
|
"github.com/noteapp/backend/internal/application/services"
|
|
)
|
|
|
|
// PublicHandler handles unauthenticated public read-only requests
|
|
type PublicHandler struct {
|
|
spaceService *services.SpaceService
|
|
noteService *services.NoteService
|
|
}
|
|
|
|
// NewPublicHandler creates a new PublicHandler
|
|
func NewPublicHandler(spaceService *services.SpaceService, noteService *services.NoteService) *PublicHandler {
|
|
return &PublicHandler{spaceService: spaceService, noteService: noteService}
|
|
}
|
|
|
|
// GetPublicSpace handles GET /public/spaces/{spaceId}
|
|
func (h *PublicHandler) GetPublicSpace(w http.ResponseWriter, r *http.Request) {
|
|
spaceID, err := bson.ObjectIDFromHex(mux.Vars(r)["spaceId"])
|
|
if err != nil {
|
|
http.Error(w, "invalid space id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
space, err := h.spaceService.GetPublicSpace(r.Context(), spaceID)
|
|
if err != nil {
|
|
if err.Error() == "space is not public" {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(space)
|
|
}
|
|
|
|
// ListPublicSpaces handles GET /public/spaces
|
|
func (h *PublicHandler) ListPublicSpaces(w http.ResponseWriter, r *http.Request) {
|
|
spaces, err := h.spaceService.GetPublicSpaces(r.Context())
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"spaces": spaces})
|
|
}
|
|
|
|
// GetPublicNotes handles GET /public/spaces/{spaceId}/notes
|
|
func (h *PublicHandler) GetPublicNotes(w http.ResponseWriter, r *http.Request) {
|
|
spaceID, err := bson.ObjectIDFromHex(mux.Vars(r)["spaceId"])
|
|
if err != nil {
|
|
http.Error(w, "invalid space id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
skip := 0
|
|
limit := 50
|
|
if v := r.URL.Query().Get("skip"); v != "" {
|
|
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
|
|
skip = n
|
|
}
|
|
}
|
|
if v := r.URL.Query().Get("limit"); v != "" {
|
|
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 100 {
|
|
limit = n
|
|
}
|
|
}
|
|
|
|
notes, err := h.noteService.GetPublicNotesBySpace(r.Context(), spaceID, skip, limit)
|
|
if err != nil {
|
|
if err.Error() == "space is not public" {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"notes": notes})
|
|
}
|
|
|
|
// GetPublicNote handles GET /public/spaces/{spaceId}/notes/{noteId}
|
|
func (h *PublicHandler) GetPublicNote(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
|
if err != nil {
|
|
http.Error(w, "invalid space id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
noteID, err := bson.ObjectIDFromHex(vars["noteId"])
|
|
if err != nil {
|
|
http.Error(w, "invalid note id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
note, err := h.noteService.GetPublicNoteBySpaceAndID(r.Context(), spaceID, noteID)
|
|
if err != nil {
|
|
if err.Error() == "space is not public" || err.Error() == "note is not public" || err.Error() == "space not found" || err.Error() == "note not found" {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(note)
|
|
}
|
|
|
|
// UnlockPublicNote verifies a public note password and returns full note content
|
|
func (h *PublicHandler) UnlockPublicNote(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
|
if err != nil {
|
|
http.Error(w, "invalid space id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
noteID, err := bson.ObjectIDFromHex(vars["noteId"])
|
|
if err != nil {
|
|
http.Error(w, "invalid note id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var req dto.UnlockNoteRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, "invalid request body", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
note, err := h.noteService.UnlockPublicNote(r.Context(), spaceID, noteID, req.Password)
|
|
if err != nil {
|
|
if err.Error() == "invalid note password" {
|
|
http.Error(w, err.Error(), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
if err.Error() == "space is not public" || err.Error() == "space not found" || err.Error() == "note not found" {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(note)
|
|
}
|