A bounded adversarial re-verification of the new fund-custody auth found two real bypasses that the fix rounds missed; both fixed here, plus executable proof. - BYPASS #1 (CRITICAL, external): p2p_fiat_trades/p2p_fiat_offers kept USING(true) anon UPDATE, and confirm-payment / admin_resolve_dispute read the fund DESTINATION (buyer_id), amount and token straight from those rows. An anon attacker could `UPDATE p2p_fiat_trades SET buyer_id=<attacker>` so the honest seller's correctly- signed release paid the attacker. Fix: BEFORE UPDATE triggers freeze the fund-routing columns (offer_id, seller_id, buyer_id, crypto_amount, fiat_amount, price_per_unit, escrow_locked_amount on trades; seller_id, token, amount_crypto on offers) for any non-service-role writer — trigger-level, independent of RLS/grants; status/proof/chat stay open. (Corrects the earlier triage that dismissed these tables as non-custodial.) - BYPASS #2 (double-release TOCTOU): confirm-payment checked status then released non-atomically, so two concurrent differently-nonced valid requests could both release and drain other buyers' escrow. Fix: atomic compare-and-swap of payment_sent->completed BEFORE the escrow move (loser gets 409; revert on release failure). - Hardening: REVOKE EXECUTE on the dead legacy resolve_p2p_dispute mover from PUBLIC/anon/authenticated. - Proof: 34 executable tests (Deno) — identity-auth unit tests (sr25519 sign/verify, challenge money-param binding, citizen/visa ownership, nonce single-use+concurrency, freshness) + per-handler authorization-flow tests (bad-sig/cross-id/wrong-state/replay, CAS double-release). All pass.
Supabase Setup Guide
Overview
Bu klasör Supabase database setup için gerekli migration dosyalarını içerir.
Quick Start
1. Supabase Dashboard'a Giriş
- https://supabase.com/dashboard adresine gidin
- PezkuwiChain projesini açın: https://supabase.com/dashboard/project/vsyrpfiwhjvahofxwytr
2. SQL Editor'ı Açın
- Sol menüden SQL Editor sekmesine tıklayın
- New Query butonuna tıklayın
3. Migration Script'ini Çalıştırın
supabase/migrations/001_initial_schema.sqldosyasını açın- Tüm içeriği kopyalayın
- Supabase SQL Editor'a yapıştırın
- Sağ alttaki Run butonuna tıklayın
4. Sonuçları Kontrol Edin
Migration başarılıysa şu mesajı göreceksiniz:
Database schema created successfully!
Oluşturulan Tablolar
1. profiles Tablosu
Kullanıcı profil bilgilerini ve referral verilerini saklar:
id- User ID (auth.users'a reference)username- Benzersiz kullanıcı adıemail- Email adresifull_name- Tam adavatar_url- Avatar resmi URL'sireferred_by- Referans kodu (kim davet etti)referral_code- Kendi referans kodu (otomatik oluşturulur)referral_count- Kaç kişi davet ettitotal_referral_rewards- Toplam kazanılan ödüller
2. admin_roles Tablosu
Admin ve moderator rol atamalarını saklar:
id- Benzersiz IDuser_id- User IDrole- Rol: 'admin', 'super_admin', 'moderator'granted_by- Rolü kim verdigranted_at- Ne zaman verildi
3. wallets Tablosu
Kullanıcı wallet adreslerini saklar:
id- Benzersiz IDuser_id- User IDaddress- Wallet adresinetwork- Network adı (pezkuwichain, polkadot, etc.)is_primary- Primary wallet mı?nickname- Wallet nickname'i
4. referral_history Tablosu
Referral ödüllerini ve geçmişini takip eder:
id- Benzersiz IDreferrer_id- Davet eden user IDreferred_user_id- Davet edilen user IDreferral_code- Kullanılan referral codereward_amount- Ödül miktarıreward_token- Ödül token'ı (PEZ, HEZ, etc.)reward_claimed- Ödül talep edildi mi?
Automatic Features
1. Referral Code Auto-Generation
Her kullanıcı kaydolduğunda otomatik olarak benzersiz 8 karakterli bir referral code oluşturulur.
2. Row Level Security (RLS)
Tüm tablolarda RLS etkin:
- Kullanıcılar sadece kendi verilerini görebilir/düzenleyebilir
- Admin'ler admin_roles tablosuna erişebilir
- Public profiller herkes tarafından görülebilir
3. Timestamp Updates
Profile güncellendiğinde updated_at otomatik olarak güncellenir.
Test Etme
1. Sign Up Testi
- Web uygulamasını başlatın:
npm run dev /loginsayfasına gidin- Sign Up sekmesine tıklayın
- Yeni kullanıcı bilgilerini girin:
- Full Name: Test User
- Email: test@example.com
- Password: Test1234!
- Referral Code: (opsiyonel)
- Create Account butonuna tıklayın
2. Database'i Kontrol Edin
- Supabase Dashboard → Table Editor sekmesine gidin
profilestablosunu seçin- Yeni kaydın oluştuğunu doğrulayın
referral_codealanının otomatik doldurulduğunu kontrol edin
3. Login Testi
- Oluşturduğunuz email ve password ile login olun
- Başarılı giriş yapabildiğinizi doğrulayın
Admin Rolü Ekleme
Bir kullanıcıya admin rolü vermek için:
- Supabase Dashboard → SQL Editor
- Şu SQL'i çalıştırın:
-- Get user ID first
SELECT id, email FROM auth.users WHERE email = 'info@pezkuwichain.io';
-- Then add admin role (replace USER_ID with actual ID)
INSERT INTO public.admin_roles (user_id, role, granted_by)
VALUES ('USER_ID', 'super_admin', 'USER_ID')
ON CONFLICT (user_id) DO UPDATE SET role = 'super_admin';
Troubleshooting
Problem: "relation 'profiles' already exists"
Çözüm: Tablolar zaten oluşturulmuş. Sorun yok, devam edebilirsiniz.
Problem: "duplicate key value violates unique constraint"
Çözüm: Bu kayıt zaten var. Normal bir durum.
Problem: Sign up başarılı ama profile oluşmadı
Çözüm:
- AuthContext.tsx'deki
signUpfonksiyonunu kontrol edin (line 148-186) - Browser console'da hata mesajlarını kontrol edin
- Supabase Dashboard → Logs → Postgres Logs'u inceleyin
Problem: "Invalid JWT token"
Çözüm: .env dosyasındaki VITE_SUPABASE_ANON_KEY değerini kontrol edin.
Security Notes
🔒 Row Level Security (RLS)
Tüm tablolar RLS ile korunuyor:
- Kullanıcılar sadece kendi verilerine erişebilir
- Public veriler (profil bilgileri) herkes tarafından görülebilir
- Admin rolleri sadece admin'ler tarafından görülebilir
🔑 API Keys
- anon key: Frontend'de kullanılır, RLS kurallarına tabidir
- service_role key: ASLA frontend'de kullanmayın! Server-side only.
📝 Best Practices
-
Production'da:
VITE_ENABLE_DEMO_MODE=falseyapın- Demo credentials'ları kaldırın
- Service role key'i asla commit etmeyin
-
Development'ta:
- Test verileri ile çalışın
- Real user data kullanmayın
Additional Resources
Last Updated: 2025-01-28 Version: 1.0.0