Skip to content

Add slug-based URLs for event registrations#1268

Merged
maebeale merged 2 commits intomainfrom
maebeale/event-reg-slugs
Mar 1, 2026
Merged

Add slug-based URLs for event registrations#1268
maebeale merged 2 commits intomainfrom
maebeale/event-reg-slugs

Conversation

@maebeale
Copy link
Collaborator

@maebeale maebeale commented Mar 1, 2026

What is the goal of this PR and why is this important?

  • Replace ID-based user-facing URLs (/event_registrations/123) with secure, unguessable slug tokens (/registration/abc123...) for event registrations
  • Slugs prevent enumeration attacks — users can only access registrations if they have the slug (from email or direct link)
  • Enables guest access to registration tickets without requiring login, improving UX for confirmation emails

How did you approach the change?

  • Added slug column with unique index to event_registrations, generated via SecureRandom.urlsafe_base64(16) (128-bit entropy) on create
  • Added /registration/:slug routes for show, resend confirmation, cancel, and reactivate actions
  • Slug itself serves as authorization — no login required to view ticket, resend email, cancel, or reactivate
  • Secured public registration form show with ?reg=slug param instead of guessable person_id
  • Event show page detects ?reg=slug param to display "View your registration" link and calendar links for guests
  • Replaced De-register button on event show with cancel/reactivate flow on the registration ticket page
  • Extracted shared _ticket.html.erb partial for both admin and public registration views
  • Updated all mailer templates and profile page links to use slug-based URLs
  • Locked down existing /event_registrations/:id show to admin-only
  • Includes backfill rake task: bundle exec rake event_registrations:backfill_slugs

UI Testing Checklist

  • Visit /registration/:slug as guest — should show ticket
  • Click "Back to Event" from ticket — event page should show "View your registration" link
  • Click "Cancel registration" — should show "Registration cancelled" badge and "Register again" button
  • Click "Register again" — should reactivate and show active registration
  • Click "Resend confirmation email" — should send email with slug-based links
  • Confirmation email links go to slug-based URLs (not ID-based)
  • Profile page registration links use slug-based URLs
  • /event_registrations/:id redirects non-admins (admin-only)
  • Public registration form show requires valid ?reg=slug param

Anything else to add?

  • Migration must be run before deploy: ai/db-migrate
  • Backfill existing registrations after deploy: bundle exec rake event_registrations:backfill_slugs

🤖 Generated with Claude Code

maebeale and others added 2 commits February 28, 2026 20:37
Replace ID-based user-facing URLs with secure, unguessable slug tokens
for event registrations. Slugs use SecureRandom.urlsafe_base64(16) for
128-bit entropy and are generated on create.

- Add slug column with unique index and backfill rake task
- Add /registration/:slug routes for show, resend, cancel, reactivate
- Secure public registration form show with slug param instead of person_id
- Pass slug as URL param on event show for guest "View your registration"
- Replace De-register with cancel/reactivate flow on registration ticket
- Extract shared _ticket partial, update mailers and profile links
- Lock down /event_registrations/:id show to admin-only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update page_bg_class alignment spec: remove deleted
  event_registrations/show.html.erb, change public_registrations/show
  to "public", add events/registrations/show as "public"
- Fix request specs to check HTTP 404 status instead of raise_error
  (Rails request specs catch RecordNotFound and return 404)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@maebeale maebeale merged commit e8b220c into main Mar 1, 2026
3 checks passed
@maebeale maebeale deleted the maebeale/event-reg-slugs branch March 1, 2026 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant