Avoid Sentry exceptions when attackers try to stuff invalid emails. The
browser performs form field validation that should normally prevent this
from occurring, so we just return 422 without validation error messages.
Also:
- extract redirect_to_session_magic_link helper
- some controller refactoring and cleanup
Specifically this will help people understand why their SVG avatar
uploads are being rejected, and will keep the RecordInvalid exception
out of Sentry logs.
* CSP: fix magic link console logging by including nonce in the script tag
* Remove unused back-nav controller
Unused since c0f842427d
Eliminates a potential CSP violation with javascript: URI
External sources:
- challenges.cloudflare.com for Turnstile (script-src, frame-src)
- storage.basecamp.com for Active Storage (connect-src)
User tools: loosen style/img/font/media/worker-src to avoid fighting
accessibility extensions, privacy tools, and custom fonts.
Display "Unverified" with an explanation instead of the email address
for users who haven't confirmed their identity. Hide the card links
and activity timeline since unverified users won't have any activity.
Co-Authored-By: Claude <noreply@anthropic.com>
Adds verified? check to bundling_emails? to prevent notification emails
from being sent to users who have never authenticated. This closes the
spam vector where bad actors could create users for known email
addresses and trigger unwanted notifications by mentioning them.
Co-Authored-By: Claude <noreply@anthropic.com>
Identifies users who have demonstrated authentication by looking for
evidence of real activity: owners, content creators (cards, comments,
boards, events), action takers (assigners, closers, postponers,
reactors, pinners, filter creators), board accessors, export requesters,
push subscribers, setup completers, and users with active sessions.
Run this script after deploying the verified_at column to backfill
existing users before enabling the notification guard.
Co-Authored-By: Claude <noreply@anthropic.com>
User are marked as verified after a join code is redeemed. The user is
redirected to Users::VerificationsController, either:
- after submitting a valid magic link code,
- or immediately after redeeming the join code (if they're already
authenticated with the correct identity)
Account owners are automatically verified when the account is
created (because they have already provided a magic link code at that
point).
This sets up for later commits that will backfill existing users and
require verification before sending notification emails.
Co-Authored-By: Claude <noreply@anthropic.com>
Reworked the magic link stimulus controller, because the system test
was causing double-submission of the form (because the event was
bubbling up). I think that change simplifies the form and will still
work well for iOS devices.
Loosen font-src and add media-src to allow browser extensions like
accessibility fonts (OpenDyslexic) and user style managers to work
without CSP violations.
Add default-src and connect-src directives to close security gaps where
unspecified directives were implicitly allowing all sources.
Default to a very narrow policy since there are no CDNs or third-party
resources to contend with.
Configurable via:
- config.x.content_security_policy.* for fizzy-saas gem overrides
- DISABLE_CSP to skip entirely
- CSP_REPORT_ONLY to enable report-only mode
- CSP_REPORT_URI for violation reporting
- Update the README with detailed information about how to deploy a
Fizzy instance
- Reduce the example deploy config
- Add example SMTP configuration in production.rb