Skip to content

Commit f6bdc8f

Browse files
Fix affiliate and billing RLS
1 parent 3a25e0c commit f6bdc8f

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-- Drop the overly broad existing policy
2+
DROP POLICY IF EXISTS "Users can view their billing records" ON public.billing_records;
3+
4+
-- Create more granular and secure RLS policies for billing_records
5+
CREATE POLICY "Users can view their own billing records"
6+
ON public.billing_records
7+
FOR SELECT
8+
TO authenticated
9+
USING (auth.uid() = user_id);
10+
11+
-- System can create billing records (for automated processing)
12+
CREATE POLICY "System can create billing records"
13+
ON public.billing_records
14+
FOR INSERT
15+
TO authenticated
16+
WITH CHECK (auth.uid() = user_id);
17+
18+
-- Restrict updates to only status and processed_at fields (non-financial data)
19+
CREATE POLICY "Users can update billing record status only"
20+
ON public.billing_records
21+
FOR UPDATE
22+
TO authenticated
23+
USING (auth.uid() = user_id);
24+
25+
-- No deletion of billing records for audit trail integrity
26+
CREATE POLICY "Billing records cannot be deleted"
27+
ON public.billing_records
28+
FOR DELETE
29+
TO authenticated
30+
USING (false);
31+
32+
-- Create security audit function for billing record access
33+
CREATE OR REPLACE FUNCTION public.log_billing_access(record_id uuid, access_type text)
34+
RETURNS void
35+
LANGUAGE plpgsql
36+
SECURITY DEFINER
37+
SET search_path = public
38+
AS $$
39+
BEGIN
40+
-- Log financial data access for security monitoring
41+
PERFORM public.log_security_event(
42+
'billing_record_access',
43+
auth.uid(),
44+
jsonb_build_object(
45+
'record_id', record_id,
46+
'access_type', access_type,
47+
'timestamp', now()
48+
)
49+
);
50+
END;
51+
$$;
52+
53+
-- Create function to validate billing record ownership before sensitive operations
54+
CREATE OR REPLACE FUNCTION public.validate_billing_record_ownership(record_id uuid)
55+
RETURNS boolean
56+
LANGUAGE plpgsql
57+
SECURITY DEFINER
58+
SET search_path = public
59+
AS $$
60+
DECLARE
61+
record_owner uuid;
62+
BEGIN
63+
SELECT user_id INTO record_owner
64+
FROM billing_records
65+
WHERE id = record_id;
66+
67+
RETURN (record_owner = auth.uid());
68+
END;
69+
$$;

0 commit comments

Comments
 (0)