diff --git a/src/components/CrewForm.tsx b/src/components/CrewForm.tsx index 7a6813d..0b46600 100644 --- a/src/components/CrewForm.tsx +++ b/src/components/CrewForm.tsx @@ -26,6 +26,7 @@ import { SKATE_CREW_KIND, SKATE_SPOT_KIND, SKATE_SHOP_KIND, parseAddrCoord, ZAP_ import { CREW_VIBE_KEYS, CREW_FOCUS_KEYS, CREW_FOCUS_DESC_KEYS, CREW_LOOKING_FOR_KEYS, CREW_ROLE_KEYS } from '@/lib/labelKeys'; import { useCrewGoal } from '@/hooks/useCrewGoal'; import { useCoordinator, useCoordinatorHealth } from '@/hooks/useCoordinator'; +import { normalizeUrlInput, sanitizeUrl } from '@/lib/sanitizeUrl'; import { Nip05HandlesEditor } from '@/components/Nip05HandlesEditor'; import { coordinatorAddUrl, crewCoordinatorInputValue, parseCrewCoordinatorInput, shortNpub } from '@/lib/coordinator'; import { useRelays } from '@/lib/relays'; @@ -394,10 +395,14 @@ export function CrewForm({ existing }: CrewFormProps) { }; const addSocial = () => { - const val = socialInput.trim(); + const raw = socialInput.trim(); setSocialInput(''); - if (!val || socials.includes(val)) return; - setSocials((prev) => [...prev, val]); + if (!raw) return; + // Coerce a bare domain to https:// so it renders as a link; keep a non-URL + // (e.g. a @handle) as typed so nothing is silently dropped. + const safe = sanitizeUrl(normalizeUrlInput(raw)) ?? raw; + if (socials.includes(safe)) return; + setSocials((prev) => [...prev, safe]); }; // Crew NIP-05 handles — up to 5, each verified against the founder's key. @@ -550,11 +555,15 @@ export function CrewForm({ existing }: CrewFormProps) { } } if (image) tags.push(['image', image]); - if (website.trim()) tags.push(['website', website.trim()]); + { + const safe = website.trim() ? sanitizeUrl(normalizeUrlInput(website)) : null; + if (website.trim()) tags.push(['website', safe ?? website.trim()]); + } if (instagram.trim()) tags.push(['instagram', instagram.trim()]); if (bandName.trim()) tags.push(['band', bandName.trim()]); - if (bandUrl.trim() && /^https?:\/\//i.test(bandUrl.trim())) { - tags.push(['band-url', bandUrl.trim()]); + { + const safe = bandUrl.trim() ? sanitizeUrl(normalizeUrlInput(bandUrl)) : null; + if (bandUrl.trim()) tags.push(['band-url', safe ?? bandUrl.trim()]); } for (const s of socials) { if (s.trim()) tags.push(['social', s.trim()]); @@ -1275,6 +1284,9 @@ export function CrewForm({ existing }: CrewFormProps) {
{t('socialUi.form.invalidUrl')}
+ )}{t('socialUi.form.invalidUrl')}
+ )}