Files

80 lines
3.0 KiB
TypeScript
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.
import 'server-only';
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.SUPABASE_URL;
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!supabaseUrl || !serviceRoleKey) {
throw new Error('SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY tanımlı değil (.env dosyasına bakın).');
}
// service_role ile — RLS bypass edilir, admin panelinin ihtiyacı budur (licenses,
// crash_reports, access_logs gibi tablolarda bilerek hiç RLS policy yok, sadece
// service_role erişebiliyor). SADECE server component / route handler içinde
// import edilmeli — 'server-only' paketi bunu build-time'da garanti ediyor.
export const supabaseAdmin = createClient(supabaseUrl, serviceRoleKey, {
auth: { autoRefreshToken: false, persistSession: false },
});
export interface AuthUser {
id: string;
email?: string;
created_at: string;
last_sign_in_at?: string | null;
}
// profiles tablosunda e-posta yok (auth.users'a referans veriyor) — e-postayı
// Supabase Auth Admin API'den çekmemiz gerekiyor.
export async function listAuthUsers(): Promise<Map<string, AuthUser>> {
const res = await fetch(`${supabaseUrl}/auth/v1/admin/users?per_page=1000`, {
headers: { apikey: serviceRoleKey!, Authorization: `Bearer ${serviceRoleKey}` },
cache: 'no-store',
});
if (!res.ok) return new Map();
const data = await res.json();
const users: AuthUser[] = data.users || [];
return new Map(users.map((u) => [u.id, u]));
}
// Kullanıcı silme: Supabase Auth Admin API üzerinden. profiles satırını silmek
// admin'in sorumluluğunda ayrıca çağrılmalı — auth.users -> profiles cascade'i
// bu self-hosted kurulumda garanti değil.
export async function deleteAuthUser(id: string): Promise<{ error?: string }> {
const res = await fetch(`${supabaseUrl}/auth/v1/admin/users/${id}`, {
method: 'DELETE',
headers: { apikey: serviceRoleKey!, Authorization: `Bearer ${serviceRoleKey}` },
});
if (!res.ok) {
const text = await res.text().catch(() => '');
return { error: `Auth kullanıcı silinemedi (${res.status}): ${text}` };
}
return {};
}
export interface CustomerOption {
id: string;
name: string | null;
email: string;
}
// Lisans düzenleme/oluşturma formlarındaki "Müşteri" seçimi Kullanıcılar sayfasıyla
// AYNI kaynaktan (profiles + Supabase Auth e-postası) besleniyor — serbest metin
// yerine, gerçekten var olan bir kullanıcı seçtirmek için.
export async function listCustomerOptions(): Promise<CustomerOption[]> {
const [{ data: profiles }, authUsers] = await Promise.all([
supabaseAdmin.from('profiles').select('id, full_name'),
listAuthUsers(),
]);
const options: CustomerOption[] = (profiles || [])
.map((p: { id: string; full_name: string | null }) => ({
id: p.id,
name: p.full_name,
email: authUsers.get(p.id)?.email || '',
}))
.filter((c) => c.email);
options.sort((a, b) => (a.name || a.email).localeCompare(b.name || b.email, 'tr'));
return options;
}