Skip to content

Commit 297fd73

Browse files
committed
harden chat thread ownership
1 parent fbdca9e commit 297fd73

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
-- Remove duplicate slug indexes covered by unique constraints, and ensure
2+
-- client-created chat threads point at the real visible listing owner.
3+
4+
drop index if exists public.public_listings_slug_idx;
5+
drop index if exists public.listing_contact_cards_slug_idx;
6+
7+
create or replace function private.enforce_chat_thread_insert()
8+
returns trigger
9+
language plpgsql
10+
security definer
11+
set search_path = ''
12+
as $$
13+
declare
14+
jwt_role text;
15+
begin
16+
jwt_role := nullif(current_setting('request.jwt.claim.role', true), '');
17+
18+
if jwt_role = 'service_role'
19+
or ((select auth.uid()) is null and jwt_role is null)
20+
then
21+
return new;
22+
end if;
23+
24+
if (select auth.uid()) is null or new.initiator_id is distinct from (select auth.uid()) then
25+
raise exception 'Users can only start chat threads as themselves.'
26+
using errcode = '42501';
27+
end if;
28+
29+
if not exists (
30+
select 1
31+
from public.listings
32+
where listings.id = new.listing_id
33+
and listings.owner_id = new.owner_id
34+
and listings.visibility = true
35+
) then
36+
raise exception 'Users can only start chat threads for visible listings with the correct owner.'
37+
using errcode = '42501';
38+
end if;
39+
40+
if (
41+
select count(*)
42+
from public.chat_messages
43+
where sender_id = new.initiator_id
44+
and created_at >= now() - interval '1 hour'
45+
) >= 10 then
46+
raise exception 'Too many messages sent recently to start a new chat thread.'
47+
using errcode = '42501';
48+
end if;
49+
50+
if (
51+
select count(*)
52+
from public.chat_threads
53+
where initiator_id = new.initiator_id
54+
and created_at >= now() - interval '1 hour'
55+
) >= 6 then
56+
raise exception 'Too many chat threads started recently.'
57+
using errcode = '42501';
58+
end if;
59+
60+
return new;
61+
end;
62+
$$;
63+
64+
alter function private.enforce_chat_thread_insert() owner to postgres;
65+
66+
revoke all privileges on function private.enforce_chat_thread_insert()
67+
from anon, authenticated, public;

0 commit comments

Comments
 (0)