audit: remove duplicate Stripe integration card + tighten input validation
Deep audit of the recent change set (passes 56-60): - Remove the generic Integrations-tab Stripe card. saveIntegration overwrites integrations.config wholesale, so configuring Stripe there clobbered the dues config (mode/prices/grace_days) that the Dues tab manages, and couldn't actually set up dues. Stripe is now configured in one place (the Dues tab). PayPal/Zeffy/Venmo sync cards unchanged. - deleteDuesPaymentMethod validates platform against DUES_LINK_PLATFORMS instead of passing a raw client string into the enum column. - markNotificationsRead uses a strict uuid regex for the id filter. PGRST201 class characterized + confirmed contained: PostgREST treats a 2-FK table as an ambiguous junction only when its PK covers both FKs; the only such table now is space_member_custom_roles (a legitimate M2M). Guarded by integration/auth-embed.test.ts.
This commit is contained in:
@@ -5,7 +5,7 @@ import { createClient } from '@/lib/supabase/server'
|
||||
import { requireMember, requireMemberWithRole, parseInput } from '@/lib/auth-helpers'
|
||||
import { ADMIN_ROLES } from '@/lib/permissions'
|
||||
import { duesPaymentMethodSchema } from '@/lib/validations'
|
||||
import { isSafeDuesUrl } from '@/lib/dues-payments-logic'
|
||||
import { isSafeDuesUrl, isDuesLinkPlatform } from '@/lib/dues-payments-logic'
|
||||
|
||||
export type DuesPaymentMethod = {
|
||||
platform: string
|
||||
@@ -100,6 +100,10 @@ export async function deleteDuesPaymentMethod(input: {
|
||||
if (!auth.ok) return { error: auth.error }
|
||||
const { member } = auth
|
||||
|
||||
// Validate at the boundary (same as the upsert path) instead of passing a
|
||||
// raw client string into the enum column.
|
||||
if (!isDuesLinkPlatform(input.platform)) return { error: 'Invalid platform' }
|
||||
|
||||
const { error } = await supabase
|
||||
.from('dues_payment_methods')
|
||||
.delete()
|
||||
|
||||
@@ -77,7 +77,9 @@ export async function markNotificationsRead(
|
||||
if (input.ids && input.ids.length > 0) {
|
||||
// Defend the uuid column against a malformed client id (a non-uuid would
|
||||
// error the cast). Only well-formed ids pass; an empty result is a no-op.
|
||||
const ids = input.ids.filter(id => /^[0-9a-f-]{36}$/i.test(id))
|
||||
const ids = input.ids.filter(id =>
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id),
|
||||
)
|
||||
if (ids.length === 0) return { ok: true }
|
||||
q = q.in('id', ids)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user