Исправлен доступ к желаниям на досках
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m3s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m3s
This commit is contained in:
@@ -9976,6 +9976,45 @@ func (a *App) createWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(createdItem)
|
||||
}
|
||||
|
||||
// checkWishlistAccess проверяет доступ пользователя к желанию
|
||||
// Возвращает (hasAccess, itemUserID, boardID, error)
|
||||
func (a *App) checkWishlistAccess(itemID int, userID int) (bool, int, sql.NullInt64, error) {
|
||||
var itemUserID int
|
||||
var boardID sql.NullInt64
|
||||
err := a.DB.QueryRow(`
|
||||
SELECT user_id, board_id
|
||||
FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&itemUserID, &boardID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return false, 0, sql.NullInt64{}, err
|
||||
}
|
||||
if err != nil {
|
||||
return false, 0, sql.NullInt64{}, err
|
||||
}
|
||||
|
||||
// Проверяем доступ: владелец ИЛИ участник доски
|
||||
hasAccess := itemUserID == userID
|
||||
if !hasAccess && boardID.Valid {
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`SELECT owner_id FROM wishlist_boards WHERE id = $1 AND deleted = FALSE`, boardID.Int64).Scan(&ownerID)
|
||||
if err == nil {
|
||||
hasAccess = ownerID == userID
|
||||
if !hasAccess {
|
||||
var isMember bool
|
||||
err = a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM wishlist_board_members WHERE board_id = $1 AND user_id = $2)`,
|
||||
int(boardID.Int64), userID).Scan(&isMember)
|
||||
if err == nil {
|
||||
hasAccess = isMember
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasAccess, itemUserID, boardID, nil
|
||||
}
|
||||
|
||||
// getWishlistItemHandler возвращает одно желание
|
||||
func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "OPTIONS" {
|
||||
@@ -9999,44 +10038,27 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Проверяем доступ к желанию
|
||||
var itemUserID int
|
||||
var boardID sql.NullInt64
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id, board_id
|
||||
FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&itemUserID, &boardID)
|
||||
|
||||
hasAccess, itemUserID, boardID, err := a.checkWishlistAccess(itemID, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Printf("Wishlist item not found: id=%d, userID=%d", itemID, userID)
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Error getting wishlist item: %v", err)
|
||||
log.Printf("Error getting wishlist item (id=%d, userID=%d): %v", itemID, userID, err)
|
||||
sendErrorWithCORS(w, "Error getting wishlist item", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем доступ: владелец ИЛИ участник доски
|
||||
hasAccess := itemUserID == userID
|
||||
if !hasAccess && boardID.Valid {
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`SELECT owner_id FROM wishlist_boards WHERE id = $1 AND deleted = FALSE`, boardID.Int64).Scan(&ownerID)
|
||||
if err == nil {
|
||||
hasAccess = ownerID == userID
|
||||
if !hasAccess {
|
||||
var isMember bool
|
||||
a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM wishlist_board_members WHERE board_id = $1 AND user_id = $2)`,
|
||||
int(boardID.Int64), userID).Scan(&isMember)
|
||||
hasAccess = isMember
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Wishlist item found: id=%d, itemUserID=%d, boardID=%v, currentUserID=%d", itemID, itemUserID, boardID, userID)
|
||||
|
||||
if !hasAccess {
|
||||
log.Printf("Access denied for wishlist item: id=%d, itemUserID=%d, boardID=%v, currentUserID=%d", itemID, itemUserID, boardID, userID)
|
||||
sendErrorWithCORS(w, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Access granted for wishlist item: id=%d, itemUserID=%d, boardID=%v, currentUserID=%d", itemID, itemUserID, boardID, userID)
|
||||
|
||||
// Сохраняем itemUserID для использования в качестве fallback, если conditionUserID NULL
|
||||
itemOwnerID := itemUserID
|
||||
@@ -10262,8 +10284,11 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
setCORSHeaders(w)
|
||||
|
||||
log.Printf("updateWishlistHandler called: method=%s, path=%s", r.Method, r.URL.Path)
|
||||
|
||||
userID, ok := getUserIDFromContext(r)
|
||||
if !ok {
|
||||
log.Printf("updateWishlistHandler: Unauthorized")
|
||||
sendErrorWithCORS(w, "Unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
@@ -10271,26 +10296,34 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
itemID, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
log.Printf("updateWishlistHandler: Invalid wishlist ID: %v", err)
|
||||
sendErrorWithCORS(w, "Invalid wishlist ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("updateWishlistHandler: itemID=%d, userID=%d", itemID, userID)
|
||||
|
||||
// Проверяем владельца
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&ownerID)
|
||||
if err == sql.ErrNoRows || ownerID != userID {
|
||||
// Проверяем доступ к желанию
|
||||
hasAccess, _, _, err := a.checkWishlistAccess(itemID, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Printf("updateWishlistHandler: Wishlist item not found: id=%d, userID=%d", itemID, userID)
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Error checking wishlist ownership: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist ownership: %v", err), http.StatusInternalServerError)
|
||||
log.Printf("updateWishlistHandler: Error getting wishlist item (id=%d, userID=%d): %v", itemID, userID, err)
|
||||
sendErrorWithCORS(w, "Error getting wishlist item", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if !hasAccess {
|
||||
log.Printf("updateWishlistHandler: Access denied: id=%d, userID=%d", itemID, userID)
|
||||
sendErrorWithCORS(w, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("updateWishlistHandler: Access granted: id=%d, userID=%d", itemID, userID)
|
||||
|
||||
var req WishlistRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
log.Printf("Error decoding wishlist request: %v", err)
|
||||
@@ -10311,11 +10344,12 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// Обновляем желание (не проверяем user_id в WHERE, так как доступ уже проверен выше)
|
||||
_, err = tx.Exec(`
|
||||
UPDATE wishlist_items
|
||||
SET name = $1, price = $2, link = $3, updated_at = NOW()
|
||||
WHERE id = $4 AND user_id = $5
|
||||
`, strings.TrimSpace(req.Name), req.Price, req.Link, itemID, userID)
|
||||
WHERE id = $4
|
||||
`, strings.TrimSpace(req.Name), req.Price, req.Link, itemID)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error updating wishlist item: %v", err)
|
||||
@@ -10337,27 +10371,189 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем обновлённое желание
|
||||
items, err := a.getWishlistItemsWithConditions(userID, true)
|
||||
// Получаем обновлённое желание через getWishlistItemHandler логику
|
||||
// Используем тот же запрос, что и в getWishlistItemHandler
|
||||
query := `
|
||||
SELECT
|
||||
wi.id,
|
||||
wi.name,
|
||||
wi.price,
|
||||
wi.image_path,
|
||||
wi.link,
|
||||
wi.completed,
|
||||
wc.id AS condition_id,
|
||||
wc.display_order,
|
||||
wc.task_condition_id,
|
||||
wc.score_condition_id,
|
||||
wc.user_id AS condition_user_id,
|
||||
tc.task_id,
|
||||
t.name AS task_name,
|
||||
sc.project_id,
|
||||
p.name AS project_name,
|
||||
sc.required_points,
|
||||
sc.start_date
|
||||
FROM wishlist_items wi
|
||||
LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id
|
||||
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
|
||||
LEFT JOIN tasks t ON tc.task_id = t.id
|
||||
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
|
||||
LEFT JOIN projects p ON sc.project_id = p.id
|
||||
WHERE wi.id = $1
|
||||
AND wi.deleted = FALSE
|
||||
ORDER BY wc.display_order, wc.id
|
||||
`
|
||||
|
||||
rows, err := a.DB.Query(query, itemID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting updated wishlist item: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error getting updated wishlist item: %v", err), http.StatusInternalServerError)
|
||||
log.Printf("Error querying updated wishlist item: %v", err)
|
||||
sendErrorWithCORS(w, "Error getting updated wishlist item", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
itemsMap := make(map[int]*WishlistItem)
|
||||
var itemOwnerID int
|
||||
for rows.Next() {
|
||||
var itemID int
|
||||
var name string
|
||||
var price sql.NullFloat64
|
||||
var imagePath sql.NullString
|
||||
var link sql.NullString
|
||||
var completed bool
|
||||
var conditionID sql.NullInt64
|
||||
var displayOrder sql.NullInt64
|
||||
var taskConditionID sql.NullInt64
|
||||
var scoreConditionID sql.NullInt64
|
||||
var conditionUserID sql.NullInt64
|
||||
var taskID sql.NullInt64
|
||||
var taskName sql.NullString
|
||||
var projectID sql.NullInt64
|
||||
var projectName sql.NullString
|
||||
var requiredPoints sql.NullFloat64
|
||||
var startDate sql.NullTime
|
||||
|
||||
err := rows.Scan(
|
||||
&itemID, &name, &price, &imagePath, &link, &completed,
|
||||
&conditionID, &displayOrder, &taskConditionID, &scoreConditionID, &conditionUserID,
|
||||
&taskID, &taskName, &projectID, &projectName, &requiredPoints, &startDate,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning updated wishlist item: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
item, exists := itemsMap[itemID]
|
||||
if !exists {
|
||||
// Получаем user_id для этого желания
|
||||
err = a.DB.QueryRow(`SELECT user_id FROM wishlist_items WHERE id = $1`, itemID).Scan(&itemOwnerID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting item owner: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
item = &WishlistItem{
|
||||
ID: itemID,
|
||||
Name: name,
|
||||
Completed: completed,
|
||||
UnlockConditions: []UnlockConditionDisplay{},
|
||||
}
|
||||
if price.Valid {
|
||||
item.Price = &price.Float64
|
||||
}
|
||||
if imagePath.Valid && imagePath.String != "" {
|
||||
url := imagePath.String
|
||||
if !strings.HasPrefix(url, "http") {
|
||||
url = url + "?t=" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||
}
|
||||
item.ImageURL = &url
|
||||
}
|
||||
if link.Valid {
|
||||
item.Link = &link.String
|
||||
}
|
||||
itemsMap[itemID] = item
|
||||
}
|
||||
|
||||
if conditionID.Valid {
|
||||
condition := UnlockConditionDisplay{
|
||||
ID: int(conditionID.Int64),
|
||||
DisplayOrder: int(displayOrder.Int64),
|
||||
}
|
||||
|
||||
conditionOwnerID := itemOwnerID
|
||||
if conditionUserID.Valid {
|
||||
conditionOwnerID = int(conditionUserID.Int64)
|
||||
}
|
||||
|
||||
if taskConditionID.Valid {
|
||||
condition.Type = "task_completion"
|
||||
if taskName.Valid {
|
||||
condition.TaskName = &taskName.String
|
||||
}
|
||||
if taskID.Valid {
|
||||
var taskCompleted int
|
||||
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
|
||||
isCompleted := taskCompleted > 0
|
||||
condition.TaskCompleted = &isCompleted
|
||||
}
|
||||
} else if scoreConditionID.Valid {
|
||||
condition.Type = "project_points"
|
||||
if projectName.Valid {
|
||||
condition.ProjectName = &projectName.String
|
||||
}
|
||||
if requiredPoints.Valid {
|
||||
condition.RequiredPoints = &requiredPoints.Float64
|
||||
}
|
||||
if startDate.Valid {
|
||||
dateStr := startDate.Time.Format("2006-01-02")
|
||||
condition.StartDate = &dateStr
|
||||
}
|
||||
if projectID.Valid {
|
||||
points, _ := a.calculateProjectPointsFromDate(int(projectID.Int64), startDate, conditionOwnerID)
|
||||
condition.CurrentPoints = &points
|
||||
}
|
||||
}
|
||||
|
||||
item.UnlockConditions = append(item.UnlockConditions, condition)
|
||||
}
|
||||
}
|
||||
|
||||
var updatedItem *WishlistItem
|
||||
for i := range items {
|
||||
if items[i].ID == itemID {
|
||||
updatedItem = &items[i]
|
||||
for _, it := range itemsMap {
|
||||
if it.ID == itemID {
|
||||
updatedItem = it
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if updatedItem == nil {
|
||||
log.Printf("Updated item not found: id=%d", itemID)
|
||||
sendErrorWithCORS(w, "Updated item not found", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем разблокировку
|
||||
updatedItem.Unlocked = true
|
||||
if len(updatedItem.UnlockConditions) > 0 {
|
||||
for _, cond := range updatedItem.UnlockConditions {
|
||||
if cond.Type == "task_completion" {
|
||||
if cond.TaskCompleted == nil || !*cond.TaskCompleted {
|
||||
updatedItem.Unlocked = false
|
||||
break
|
||||
}
|
||||
} else if cond.Type == "project_points" {
|
||||
if cond.CurrentPoints == nil || cond.RequiredPoints == nil || *cond.CurrentPoints < *cond.RequiredPoints {
|
||||
updatedItem.Unlocked = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlocked, err := a.checkWishlistUnlock(itemID, userID)
|
||||
if err == nil {
|
||||
updatedItem.Unlocked = unlocked
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(updatedItem)
|
||||
}
|
||||
@@ -10384,27 +10580,27 @@ func (a *App) deleteWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем владельца
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&ownerID)
|
||||
if err == sql.ErrNoRows || ownerID != userID {
|
||||
// Проверяем доступ к желанию
|
||||
hasAccess, _, _, err := a.checkWishlistAccess(itemID, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Error checking wishlist ownership: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist ownership: %v", err), http.StatusInternalServerError)
|
||||
log.Printf("Error checking wishlist access: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist access: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !hasAccess {
|
||||
sendErrorWithCORS(w, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = a.DB.Exec(`
|
||||
UPDATE wishlist_items
|
||||
SET deleted = TRUE, updated_at = NOW()
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`, itemID, userID)
|
||||
WHERE id = $1
|
||||
`, itemID)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error deleting wishlist item: %v", err)
|
||||
@@ -10441,19 +10637,19 @@ func (a *App) uploadWishlistImageHandler(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем владельца
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, wishlistID).Scan(&ownerID)
|
||||
if err == sql.ErrNoRows || ownerID != userID {
|
||||
// Проверяем доступ к желанию
|
||||
hasAccess, _, _, err := a.checkWishlistAccess(wishlistID, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Error checking wishlist ownership: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist ownership: %v", err), http.StatusInternalServerError)
|
||||
log.Printf("Error checking wishlist access: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist access: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !hasAccess {
|
||||
sendErrorWithCORS(w, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -10519,8 +10715,8 @@ func (a *App) uploadWishlistImageHandler(w http.ResponseWriter, r *http.Request)
|
||||
_, err = a.DB.Exec(`
|
||||
UPDATE wishlist_items
|
||||
SET image_path = $1, updated_at = NOW()
|
||||
WHERE id = $2 AND user_id = $3
|
||||
`, imagePath, wishlistID, userID)
|
||||
WHERE id = $2
|
||||
`, imagePath, wishlistID)
|
||||
if err != nil {
|
||||
log.Printf("Error updating database: %v", err)
|
||||
sendErrorWithCORS(w, "Error updating database", http.StatusInternalServerError)
|
||||
@@ -10555,27 +10751,27 @@ func (a *App) completeWishlistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем владельца
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&ownerID)
|
||||
if err == sql.ErrNoRows || ownerID != userID {
|
||||
// Проверяем доступ к желанию
|
||||
hasAccess, _, _, err := a.checkWishlistAccess(itemID, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Error checking wishlist ownership: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist ownership: %v", err), http.StatusInternalServerError)
|
||||
log.Printf("Error checking wishlist access: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist access: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !hasAccess {
|
||||
sendErrorWithCORS(w, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = a.DB.Exec(`
|
||||
UPDATE wishlist_items
|
||||
SET completed = TRUE, updated_at = NOW()
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`, itemID, userID)
|
||||
WHERE id = $1
|
||||
`, itemID)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error completing wishlist item: %v", err)
|
||||
@@ -10685,27 +10881,27 @@ func (a *App) uncompleteWishlistHandler(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем владельца
|
||||
var ownerID int
|
||||
err = a.DB.QueryRow(`
|
||||
SELECT user_id FROM wishlist_items
|
||||
WHERE id = $1 AND deleted = FALSE
|
||||
`, itemID).Scan(&ownerID)
|
||||
if err == sql.ErrNoRows || ownerID != userID {
|
||||
// Проверяем доступ к желанию
|
||||
hasAccess, _, _, err := a.checkWishlistAccess(itemID, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
sendErrorWithCORS(w, "Wishlist item not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Error checking wishlist ownership: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist ownership: %v", err), http.StatusInternalServerError)
|
||||
log.Printf("Error checking wishlist access: %v", err)
|
||||
sendErrorWithCORS(w, fmt.Sprintf("Error checking wishlist access: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !hasAccess {
|
||||
sendErrorWithCORS(w, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = a.DB.Exec(`
|
||||
UPDATE wishlist_items
|
||||
SET completed = FALSE, updated_at = NOW()
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`, itemID, userID)
|
||||
WHERE id = $1
|
||||
`, itemID)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error uncompleting wishlist item: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user