veza/veza-backend-api/internal/handlers/privacy_handler.go
2026-03-07 00:54:35 +01:00

49 lines
1.7 KiB
Go

package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"gorm.io/gorm"
apperrors "veza-backend-api/internal/errors"
)
// PrivacyOptOut sets the CCPA "Do Not Sell" preference for the authenticated user.
// v0.803 SEC2-06: CCPA compliance - honors user opt-out request.
//
// @Summary CCPA Do Not Sell opt-out
// @Description Saves the user's Do Not Sell preference (CCPA compliance)
// @Tags Users
// @Security BearerAuth
// @Success 200 {object} map[string]interface{}
// @Failure 401 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /users/me/privacy/opt-out [post]
func PrivacyOptOut(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok || userID == uuid.Nil {
RespondWithAppError(c, apperrors.NewUnauthorizedError("Authentication required"))
return
}
// Upsert user_preferences with do_not_sell in privacy JSONB
// Uses PostgreSQL jsonb_set to merge do_not_sell: true into existing privacy
result := db.Exec(`
INSERT INTO user_preferences (user_id, theme, language, timezone, notifications, privacy, audio, contrast, density, accent_hue, font_size, updated_at)
VALUES ($1, 'light', 'en', 'UTC', '{}', '{"do_not_sell": true}', '{}', 'normal', 'comfortable', 220, 16, NOW())
ON CONFLICT (user_id) DO UPDATE SET
privacy = COALESCE(user_preferences.privacy, '{}')::jsonb || '{"do_not_sell": true}'::jsonb,
updated_at = NOW()
`, userID)
if result.Error != nil {
RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to save privacy preference", result.Error))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"message": "Do Not Sell preference saved"})
}
}