Some ideas from Claude...
Anti-Spam Strategy for Sessionizer
Context
Spam accounts and sessions are still getting through despite email confirmation gating and a honeypot field. A community member is advocating for better fraud handling workflows (soft-delete instead of hard-delete). This plan covers both prevention (stop spam from getting in) and handling (deal with spam that gets through).
Phase 1: Quick Fixes
1. Server-side guard on session creation
The email confirmation check only exists in the view template (sessions/new.html.erb). A direct POST to /sessions bypasses it entirely.
2. Fix participant-session association
Hard-deleting a participant currently orphans their sessions (broken participant_id FK). Add dependent: :restrict_with_error so Rails prevents destroying a participant who still has sessions.
Phase 2: Soft-Delete / Suspension for Participants
3. Unified soft-delete system for participants
Combine the soft-delete and suspension concepts into one mechanism. Add a discarded_at column to participants, following the same pattern as the existing canceled_at on sessions. When a participant is discarded:
- They cannot log in
- Their sessions are auto-canceled (using the existing
canceled_at mechanism)
- They are filtered from public queries via default scope
- The action is reversible (undiscard restores the participant and their sessions)
Implementation:
- Migration: add
discarded_at (datetime, indexed) to participants
- Model: add
kept, discarded, with_discarded scopes + default_scope { kept } + discarded? method
- Block login for discarded participants via Authlogic session validation
- On discard: auto-cancel all active sessions belonging to that participant
- On undiscard: auto-uncancel those sessions
- Admin: add discard/undiscard member actions and action items, add scope tabs (Active/Discarded/All) - modeled after existing session cancel/uncancel pattern in sessions.rb
- Files: new migration, participant.rb, participants.rb, Authlogic session model
Phase 3: reCAPTCHA v3
4. reCAPTCHA v3 on signup (and optionally session creation)
Invisible, score-based bot detection. Config keys already exist in recaptcha_config.rb but the gem isn't installed.
- Add
recaptcha gem
- Configure with environment variables (replace the hardcoded keys in
recaptcha_config.rb)
- Add invisible reCAPTCHA v3 to registration form
- Validate score in
ParticipantsController#create (reject below threshold, e.g. 0.5)
- Optionally add to session creation form as well
- Files: Gemfile, recaptcha_config.rb, new.html.erb, participants_controller.rb
Phase 4: Future Considerations
5. Disposable email domain blocking
Block registrations from known throwaway email services with a curated YAML blocklist and custom validation.
6. Community spam reporting
Let confirmed users flag suspicious sessions. Auto-hide after N reports pending admin review. Best tackled after prevention measures are in place.
- New
spam_reports table, model, controller, view integration, admin dashboard widget
Verification
- Phase 1: Run existing test suite, manually test POST to
/sessions as unconfirmed user (should be rejected), verify destroying a participant with sessions is blocked
- Phase 2: Test discard/undiscard round-trip in admin, verify discarded participant can't log in, verify their sessions are auto-canceled and restored on undiscard
- Phase 3: Test reCAPTCHA in development mode, verify low-score submissions are rejected, verify fallback when reCAPTCHA service is unavailable
Some ideas from Claude...
Anti-Spam Strategy for Sessionizer
Context
Spam accounts and sessions are still getting through despite email confirmation gating and a honeypot field. A community member is advocating for better fraud handling workflows (soft-delete instead of hard-delete). This plan covers both prevention (stop spam from getting in) and handling (deal with spam that gets through).
Phase 1: Quick Fixes
1. Server-side guard on session creation
The email confirmation check only exists in the view template (
sessions/new.html.erb). A direct POST to/sessionsbypasses it entirely.SessionsController#createbefore theallow_new_sessions?check2. Fix participant-session association
Hard-deleting a participant currently orphans their sessions (broken
participant_idFK). Adddependent: :restrict_with_errorso Rails prevents destroying a participant who still has sessions.Phase 2: Soft-Delete / Suspension for Participants
3. Unified soft-delete system for participants
Combine the soft-delete and suspension concepts into one mechanism. Add a
discarded_atcolumn to participants, following the same pattern as the existingcanceled_aton sessions. When a participant is discarded:canceled_atmechanism)Implementation:
discarded_at(datetime, indexed) to participantskept,discarded,with_discardedscopes +default_scope { kept }+discarded?methodPhase 3: reCAPTCHA v3
4. reCAPTCHA v3 on signup (and optionally session creation)
Invisible, score-based bot detection. Config keys already exist in
recaptcha_config.rbbut the gem isn't installed.recaptchagemrecaptcha_config.rb)ParticipantsController#create(reject below threshold, e.g. 0.5)Phase 4: Future Considerations
5. Disposable email domain blocking
Block registrations from known throwaway email services with a curated YAML blocklist and custom validation.
config/disposable_email_domains.yml6. Community spam reporting
Let confirmed users flag suspicious sessions. Auto-hide after N reports pending admin review. Best tackled after prevention measures are in place.
spam_reportstable, model, controller, view integration, admin dashboard widgetVerification
/sessionsas unconfirmed user (should be rejected), verify destroying a participant with sessions is blocked