hata düzeltme
This commit is contained in:
@@ -139,7 +139,7 @@ export async function updateEmployee(id: string, formData: FormData) {
|
|||||||
military_status: formData.get('military_status'),
|
military_status: formData.get('military_status'),
|
||||||
start_date: formData.get('start_date') || null,
|
start_date: formData.get('start_date') || null,
|
||||||
leave_date: formData.get('leave_date') || null,
|
leave_date: formData.get('leave_date') || null,
|
||||||
status: formData.get('leave_date') ? 'inactive' : formData.get('status')
|
status: formData.get('leave_date') ? 'inactive' : (formData.get('status') || 'active')
|
||||||
})
|
})
|
||||||
.eq('id', id)
|
.eq('id', id)
|
||||||
|
|
||||||
|
|||||||
@@ -255,6 +255,14 @@ export default function EmployeeModal({
|
|||||||
<label className={labelClass}>İŞTEN AYRILIŞ TARİHİ</label>
|
<label className={labelClass}>İŞTEN AYRILIŞ TARİHİ</label>
|
||||||
<input type="date" name="leave_date" defaultValue={editingEmployee?.leave_date} className={inputClass} />
|
<input type="date" name="leave_date" defaultValue={editingEmployee?.leave_date} className={inputClass} />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className={labelClass}>SİSTEM DURUMU</label>
|
||||||
|
<select name="status" defaultValue={editingEmployee?.status || 'active'} className={inputClass}>
|
||||||
|
<option value="active">Aktif</option>
|
||||||
|
<option value="inactive">Pasif</option>
|
||||||
|
<option value="terminated">İlişiği Kesildi</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import { createClient } from '@supabase/supabase-js'
|
import { createClient } from '@supabase/supabase-js'
|
||||||
|
|
||||||
export function createAdminClient() {
|
export function createAdminClient() {
|
||||||
|
const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
||||||
|
const key = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
||||||
|
|
||||||
|
console.log('Admin Client Init - URL:', url);
|
||||||
|
console.log('Admin Client Init - Key Length:', key?.length);
|
||||||
|
|
||||||
return createClient(
|
return createClient(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
url!,
|
||||||
process.env.SUPABASE_SERVICE_ROLE_KEY!,
|
key!,
|
||||||
{
|
{
|
||||||
auth: {
|
auth: {
|
||||||
autoRefreshToken: false,
|
autoRefreshToken: false,
|
||||||
persistSession: false
|
persistSession: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
-- Fix RLS Policies for Employees Table (V5 - Architectural Fix)
|
||||||
|
-- This version moves user context to the 'users' table to break recursion.
|
||||||
|
|
||||||
|
-- 1. Extend public.users table (Idempotent)
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='users' AND column_name='role_name') THEN
|
||||||
|
ALTER TABLE public.users ADD COLUMN role_name TEXT;
|
||||||
|
END IF;
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='users' AND column_name='company_id') THEN
|
||||||
|
ALTER TABLE public.users ADD COLUMN company_id UUID;
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- 2. Create Sync Function
|
||||||
|
CREATE OR REPLACE FUNCTION public.sync_user_security_context()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Update the users table when an employee is linked to a user_id
|
||||||
|
IF NEW.user_id IS NOT NULL THEN
|
||||||
|
UPDATE public.users
|
||||||
|
SET
|
||||||
|
role_name = (SELECT name FROM public.roles WHERE id = NEW.role_id),
|
||||||
|
company_id = NEW.company_id
|
||||||
|
WHERE id = NEW.user_id;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||||
|
|
||||||
|
-- 3. Create Sync Trigger
|
||||||
|
DROP TRIGGER IF EXISTS on_employee_security_change ON public.employees;
|
||||||
|
CREATE TRIGGER on_employee_security_change
|
||||||
|
AFTER INSERT OR UPDATE OF role_id, company_id, user_id ON public.employees
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION public.sync_user_security_context();
|
||||||
|
|
||||||
|
-- 4. Initial Sync (Seed existing users)
|
||||||
|
UPDATE public.users u
|
||||||
|
SET
|
||||||
|
role_name = r.name,
|
||||||
|
company_id = e.company_id
|
||||||
|
FROM public.employees e
|
||||||
|
JOIN public.roles r ON e.role_id = r.id
|
||||||
|
WHERE e.user_id = u.id;
|
||||||
|
|
||||||
|
-- 5. Helper Function (Bypass RLS)
|
||||||
|
-- This one is now super safe because it only checks 'users' table
|
||||||
|
CREATE OR REPLACE FUNCTION public.is_authorized_to_manage(target_company_id UUID)
|
||||||
|
RETURNS BOOLEAN AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Allow if table is empty (initial setup)
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM public.employees) THEN
|
||||||
|
RETURN TRUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Check users table for cached role info
|
||||||
|
-- Since we are querying 'users' from an 'employees' policy, there is NO RECURSION.
|
||||||
|
RETURN EXISTS (
|
||||||
|
SELECT 1 FROM public.users
|
||||||
|
WHERE id = auth.uid()
|
||||||
|
AND (role_name = 'admin' OR (role_name = 'manager' AND company_id = target_company_id))
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||||
|
|
||||||
|
-- 6. Redefine Employees Policies
|
||||||
|
DROP POLICY IF EXISTS "Employees unified select" ON public.employees;
|
||||||
|
DROP POLICY IF EXISTS "Employees unified insert" ON public.employees;
|
||||||
|
DROP POLICY IF EXISTS "Employees unified update" ON public.employees;
|
||||||
|
DROP POLICY IF EXISTS "Employees unified delete" ON public.employees;
|
||||||
|
DROP POLICY IF EXISTS "View employees policy" ON public.employees;
|
||||||
|
DROP POLICY IF EXISTS "Manage employees policy" ON public.employees;
|
||||||
|
DROP POLICY IF EXISTS "Initial setup allowance" ON public.employees;
|
||||||
|
|
||||||
|
-- SELECT: Colleagues can see each other, Admins see all
|
||||||
|
CREATE POLICY "Employees select policy"
|
||||||
|
ON public.employees
|
||||||
|
FOR SELECT TO authenticated
|
||||||
|
USING (
|
||||||
|
user_id = auth.uid() -- Can see self
|
||||||
|
OR EXISTS (
|
||||||
|
SELECT 1 FROM public.users u
|
||||||
|
WHERE u.id = auth.uid()
|
||||||
|
AND (u.role_name = 'admin' OR u.company_id = employees.company_id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- INSERT/UPDATE/DELETE
|
||||||
|
CREATE POLICY "Employees management policy"
|
||||||
|
ON public.employees
|
||||||
|
FOR ALL TO authenticated
|
||||||
|
USING ( public.is_authorized_to_manage(company_id) )
|
||||||
|
WITH CHECK ( public.is_authorized_to_manage(company_id) );
|
||||||
Reference in New Issue
Block a user