api: add user-resolution middleware and POST /api/setup
resolveUser attaches the session's provisioned geniusrun user (if any) to request context without blocking; requireProvisionedUser (wired fully in Task 13) 403s routes that need one. GET /api/session/me now reports has_profile/display_name so the frontend can show the setup screen.
This commit is contained in:
39
backend/internal/api/setup.go
Normal file
39
backend/internal/api/setup.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"geniusrun/backend/internal/auth"
|
||||
)
|
||||
|
||||
func (s *Server) handleSetup(w http.ResponseWriter, r *http.Request) {
|
||||
claims, ok := auth.ClaimsFromContext(r.Context())
|
||||
if !ok {
|
||||
writeError(w, http.StatusUnauthorized, "not authenticated")
|
||||
return
|
||||
}
|
||||
if _, found := userFromContext(r.Context()); found {
|
||||
writeError(w, http.StatusConflict, "profile already exists for this account")
|
||||
return
|
||||
}
|
||||
|
||||
var body struct {
|
||||
DisplayName string `json:"display_name"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
if body.DisplayName == "" {
|
||||
writeError(w, http.StatusBadRequest, "display_name is required")
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := s.DB.ProvisionUser(r.Context(), claims.Sub, body.DisplayName)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"user_id": userID, "display_name": body.DisplayName})
|
||||
}
|
||||
Reference in New Issue
Block a user