38980-vm/app-9w9pd00g5j41/supabase/migrations/00053_add_anonymous_trip_token_system.sql
2026-03-04 18:25:09 +00:00

145 lines
4.3 KiB
PL/PgSQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Anonim geziler için token sistemi ekle
-- Bu migration güvenlik açığını kapatır
-- 1. trips tablosuna anonymous_token sütunu ekle
ALTER TABLE trips ADD COLUMN IF NOT EXISTS anonymous_token TEXT;
-- 2. Unique index oluştur (NULL değerler için unique constraint çalışmaz, bu yüzden partial index)
CREATE UNIQUE INDEX IF NOT EXISTS trips_anonymous_token_key
ON trips(anonymous_token)
WHERE anonymous_token IS NOT NULL;
-- 3. Index oluştur (performans için)
CREATE INDEX IF NOT EXISTS trips_anonymous_token_idx
ON trips(anonymous_token)
WHERE anonymous_token IS NOT NULL;
-- 4. Eski güvensiz politikaları kaldır
DROP POLICY IF EXISTS "Herkes public seyahatleri görebilir" ON trips;
DROP POLICY IF EXISTS "Kullanıcılar kendi seyahatlerini güncelleyebilir" ON trips;
DROP POLICY IF EXISTS "Kullanıcılar kendi seyahatlerini silebilir" ON trips;
-- 5. Yeni güvenli politikalar oluştur
-- SELECT: Public geziler, kendi gezileri, veya token ile anonim geziler
CREATE POLICY "Güvenli seyahat görüntüleme"
ON trips FOR SELECT
USING (
is_public = true
OR user_id = auth.uid()
OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
);
-- UPDATE: Sadece kendi gezileri veya token ile anonim geziler
CREATE POLICY "Güvenli seyahat güncelleme"
ON trips FOR UPDATE
USING (
user_id = auth.uid()
OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
);
-- DELETE: Sadece kendi gezileri veya token ile anonim geziler
CREATE POLICY "Güvenli seyahat silme"
ON trips FOR DELETE
USING (
user_id = auth.uid()
OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
);
-- 6. trip_days için güvenli politikalar
DROP POLICY IF EXISTS "Herkes seyahat günlerini yönetebilir" ON trip_days;
CREATE POLICY "Güvenli seyahat günleri yönetimi"
ON trip_days FOR ALL
USING (
EXISTS (
SELECT 1 FROM trips
WHERE trips.id = trip_days.trip_id
AND (
trips.is_public = true
OR trips.user_id = auth.uid()
OR (trips.user_id IS NULL AND trips.anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
)
)
);
-- 7. trip_places için güvenli politikalar
DROP POLICY IF EXISTS "Herkes seyahat yerlerini yönetebilir" ON trip_places;
CREATE POLICY "Güvenli seyahat yerleri yönetimi"
ON trip_places FOR ALL
USING (
EXISTS (
SELECT 1 FROM trip_days
JOIN trips ON trips.id = trip_days.trip_id
WHERE trip_days.id = trip_places.trip_day_id
AND (
trips.is_public = true
OR trips.user_id = auth.uid()
OR (trips.user_id IS NULL AND trips.anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
)
)
);
-- 8. Anonim gezi sahipliğini transfer etme fonksiyonu
CREATE OR REPLACE FUNCTION claim_anonymous_trip(
trip_id_param UUID,
token_param TEXT
)
RETURNS BOOLEAN
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
current_user_id UUID;
BEGIN
-- Mevcut kullanıcıyı al
current_user_id := auth.uid();
-- Kullanıcı giriş yapmamışsa hata
IF current_user_id IS NULL THEN
RAISE EXCEPTION 'Kullanıcı giriş yapmamış';
END IF;
-- Token eşleşiyorsa ve user_id NULL ise ownership transfer et
UPDATE trips
SET
user_id = current_user_id,
anonymous_token = NULL -- Token'ı temizle
WHERE
id = trip_id_param
AND user_id IS NULL
AND anonymous_token = token_param;
-- Güncelleme başarılı mı kontrol et
RETURN FOUND;
END;
$$;
-- 9. Eski anonim gezileri temizleme fonksiyonu
CREATE OR REPLACE FUNCTION cleanup_old_anonymous_trips()
RETURNS INTEGER
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
deleted_count INTEGER;
BEGIN
-- 7 günden eski, user_id NULL olan gezileri sil
WITH deleted AS (
DELETE FROM trips
WHERE
user_id IS NULL
AND created_at < NOW() - INTERVAL '7 days'
RETURNING id
)
SELECT COUNT(*) INTO deleted_count FROM deleted;
RETURN deleted_count;
END;
$$;
-- 10. Fonksiyonlara yorum ekle
COMMENT ON FUNCTION claim_anonymous_trip IS 'Anonim bir geziyi giriş yapmış kullanıcıya transfer eder';
COMMENT ON FUNCTION cleanup_old_anonymous_trips IS '7 günden eski anonim gezileri siler';