fix(roles): pin assignCustomRole to the caller's space (D4)
assignCustomRole inserted {member_id, custom_role_id} with no space
check on either; the RLS WITH CHECK only validated member_id's space,
so an admin of space A could attach space B's custom role to an A
member. Now both the custom role and the target member are verified
in the caller's space before insert. (Blast radius was bounded by
downstream space re-filtering; this closes the scoping defect.)
This commit is contained in:
@@ -137,6 +137,26 @@ export async function assignCustomRole(memberId: string, customRoleId: string) {
|
|||||||
const supabase = await createClient()
|
const supabase = await createClient()
|
||||||
const auth = await requireMemberWithRole(supabase, ROLE_ADMIN_ROLES, 'Admin or board access required')
|
const auth = await requireMemberWithRole(supabase, ROLE_ADMIN_ROLES, 'Admin or board access required')
|
||||||
if (!auth.ok) return { error: auth.error }
|
if (!auth.ok) return { error: auth.error }
|
||||||
|
const { member } = auth
|
||||||
|
|
||||||
|
// Pin BOTH the target member and the custom role to the caller's space.
|
||||||
|
// The RLS insert WITH CHECK only validated member_id's space, not the
|
||||||
|
// custom_role_id's — an admin of space A could otherwise attach space B's
|
||||||
|
// custom role to a member of A.
|
||||||
|
const { data: cr } = await supabase
|
||||||
|
.from('space_custom_roles')
|
||||||
|
.select('id')
|
||||||
|
.eq('id', b.data)
|
||||||
|
.eq('space_id', member.space_id)
|
||||||
|
.maybeSingle()
|
||||||
|
if (!cr) return { error: 'Custom role not found in this space.' }
|
||||||
|
const { data: tm } = await supabase
|
||||||
|
.from('space_members')
|
||||||
|
.select('id')
|
||||||
|
.eq('id', a.data)
|
||||||
|
.eq('space_id', member.space_id)
|
||||||
|
.maybeSingle()
|
||||||
|
if (!tm) return { error: 'Member not found in this space.' }
|
||||||
|
|
||||||
const { error } = await supabase
|
const { error } = await supabase
|
||||||
.from('space_member_custom_roles')
|
.from('space_member_custom_roles')
|
||||||
|
|||||||
Reference in New Issue
Block a user