35 lines
1.4 KiB
SQL
35 lines
1.4 KiB
SQL
-- Create auth_logs table
|
|
CREATE TABLE IF NOT EXISTS public.auth_logs (
|
|
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL,
|
|
event_type TEXT NOT NULL, -- 'login', '2fa_verify', '2fa_fail', 'logout', 'otp_sent'
|
|
ip_address TEXT,
|
|
user_agent TEXT,
|
|
details JSONB DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now()) NOT NULL
|
|
);
|
|
|
|
-- Associate auth_logs with profiles if needed, but auth.users is safer for raw auth logs.
|
|
-- Enable RLS for auth_logs (Admins can view all, users can view own?)
|
|
ALTER TABLE public.auth_logs ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY "Admins can view all logs" ON public.auth_logs
|
|
FOR SELECT USING (
|
|
EXISTS (
|
|
SELECT 1 FROM public.profiles
|
|
WHERE profiles.id = auth.uid() AND profiles.role = 'admin'
|
|
)
|
|
);
|
|
|
|
-- Create rate_limits table (simplified for IP based blocking)
|
|
CREATE TABLE IF NOT EXISTS public.rate_limits (
|
|
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
ip_address TEXT NOT NULL,
|
|
action TEXT NOT NULL, -- 'login_attempt', 'otp_verify'
|
|
count INTEGER DEFAULT 1,
|
|
last_attempt TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::text, now()) NOT NULL,
|
|
blocked_until TIMESTAMP WITH TIME ZONE
|
|
);
|
|
|
|
CREATE INDEX idx_rate_limits_ip_action ON public.rate_limits(ip_address, action);
|