discourse/app/controllers/anonymous_actions_controller.rb
Régis Hanol fba56920b5
FEATURE: Prompt anonymous users to sign up after engagement clicks (#40256)
Previously, anonymous users clicking event RSVP buttons hit a dead-end
with no signup prompt, and other engagement actions (Like, React, Vote)
opened the login modal but lost the click on the way to authentication.

This change captures the intent in a short-lived signed cookie via `POST
/anonymous-action` and replays it through each action's existing service
when `CurrentUser#log_on_user` completes, so anonymous engagement
converts to signups with the original action carried through.

Ref - t/184288

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:30:38 +02:00

26 lines
836 B
Ruby
Vendored

# frozen_string_literal: true
class AnonymousActionsController < ApplicationController
MAX_PARAMS_BYTES = 512
def create
raise Discourse::InvalidAccess if current_user
RateLimiter.new(nil, "anonymous-action-min-#{request.remote_ip}", 10, 1.minute).performed!
RateLimiter.new(nil, "anonymous-action-hr-#{request.remote_ip}", 60, 1.hour).performed!
type = params.require(:type)
raise Discourse::InvalidParameters.new(:type) if !AnonymousAction.registered?(type)
raw_params = params[:params]
action_params = raw_params.is_a?(ActionController::Parameters) ? raw_params.permit!.to_h : {}
if action_params.to_json.bytesize > MAX_PARAMS_BYTES
raise Discourse::InvalidParameters.new(:params)
end
AnonymousAction.set(cookies, type:, params: action_params)
head :no_content
end
end