Files
lagos-back/src/middleware/auth.ts
T

89 lines
3.0 KiB
TypeScript
Raw 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.
import { Request, Response, NextFunction } from 'express';
import { supabase } from '../lib/supabase';
export interface AuthenticatedRequest extends Request {
user?: any;
}
export const requireAuth = async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
try {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized: Missing or invalid token' });
}
const token = authHeader.split(' ')[1];
const { data: { user }, error } = await supabase.auth.getUser(token);
if (error || !user) {
return res.status(401).json({ error: 'Unauthorized: Invalid token' });
}
// P0-2: Lisans Kontrolü
let { data: profile } = await supabase
.from('profiles')
.select('license_status, trial_end_date')
.eq('id', user.id)
.maybeSingle();
if (!profile) {
// 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()) {
await supabase
.from('profiles')
.update({ license_status: 'expired' })
.eq('id', user.id);
return res.status(403).json({
error: 'Trial süresi dolmuştur. Lisansınızı aktive etmek için aktivasyon kodunuzu girin.',
code: 'TRIAL_EXPIRED',
});
}
}
if (profile.license_status !== 'active' && profile.license_status !== 'trial') {
return res.status(403).json({ error: 'Forbidden: License is not active or in trial', code: 'LICENSE_INACTIVE' });
}
req.user = user;
// P0-3: Kaynak Sahipliği Doğrulama (Eğer istekte caseId veya case_id varsa)
const caseId = req.params.caseId || req.body?.case_id;
if (caseId && caseId !== 'general') {
const { data: caseRecord } = await supabase
.from('cases')
.select('id, user_id')
.eq('id', caseId)
.maybeSingle();
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' });
}
}
}
next();
} catch (error) {
console.error('Auth middleware error:', error);
res.status(500).json({ error: 'Internal server error during authentication' });
}
};