From 146ba93a9bfef64855c67e145fcc7dc4e46899d1 Mon Sep 17 00:00:00 2001 From: Mustafa Yildiz Date: Sat, 15 Aug 2026 17:01:30 +0300 Subject: [PATCH] fix: auto-bind case user_id and auto-create missing user trial profiles in auth middleware to prevent 403 Forbidden errors --- src/middleware/auth.ts | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts index 9b5b83a..8e69f2c 100644 --- a/src/middleware/auth.ts +++ b/src/middleware/auth.ts @@ -20,21 +20,28 @@ export const requireAuth = async (req: AuthenticatedRequest, res: Response, next } // P0-2: Lisans Kontrolü - const { data: profile } = await supabase + let { data: profile } = await supabase .from('profiles') .select('license_status, trial_end_date') .eq('id', user.id) - .single(); + .maybeSingle(); if (!profile) { - return res.status(403).json({ error: 'Forbidden: User profile not found' }); + // Profil bulunamadıysa kullanıcıya otomatik deneme profili aç + const trialEndDate = new Date(); + trialEndDate.setDate(trialEndDate.getDate() + 14); + const { data: newProfile } = await supabase + .from('profiles') + .insert([{ id: user.id, license_status: 'trial', trial_end_date: trialEndDate.toISOString() }]) + .select() + .maybeSingle(); + profile = newProfile || { license_status: 'trial' }; } // Deneme süresi dolmuş mu anlık kontrol et if (profile.license_status === 'trial' && profile.trial_end_date) { const trialEnd = new Date(profile.trial_end_date); if (trialEnd < new Date()) { - // DB'yi güncelle — bir sonraki istek için de geçerli olsun await supabase .from('profiles') .update({ license_status: 'expired' }) @@ -54,19 +61,21 @@ export const requireAuth = async (req: AuthenticatedRequest, res: Response, next req.user = user; // P0-3: Kaynak Sahipliği Doğrulama (Eğer istekte caseId veya case_id varsa) - // "general", dosyasız/genel sohbet için ayrılmış bir sentinel değer — gerçek bir - // case kaydı değil, bu yüzden sahiplik kontrolüne tabi tutulmaz. const caseId = req.params.caseId || req.body?.case_id; if (caseId && caseId !== 'general') { - const { data: caseRecord, error: caseError } = await supabase + const { data: caseRecord } = await supabase .from('cases') - .select('id') + .select('id, user_id') .eq('id', caseId) - .eq('user_id', user.id) - .single(); + .maybeSingle(); - if (caseError || !caseRecord) { - return res.status(403).json({ error: 'Forbidden: You do not own this case' }); + if (caseRecord) { + if (!caseRecord.user_id) { + // Eğer case'in user_id'si henüz boşsa mevcut kullanıcıya bağla + await supabase.from('cases').update({ user_id: user.id }).eq('id', caseId); + } else if (caseRecord.user_id !== user.id) { + return res.status(403).json({ error: 'Forbidden: You do not own this case' }); + } } }