0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-05 13:59:03 +08:00
discourse/app/services/user_activator.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

82 lines
1.6 KiB
Ruby
Vendored

# frozen_string_literal: true
class UserActivator
attr_reader :user, :request, :session, :cookies, :message
def initialize(user, request, session, cookies)
@user = user
@session = session
@cookies = cookies
@request = request
@message = nil
end
def start
end
def finish
@message = activator.activate
end
def success_message
activator.success_message
end
private
def activator
factory.new(user, request, session, cookies)
end
def factory
invite = Invite.find_by(email: Email.downcase(user.email))
if !user.active?
EmailActivator
elsif SiteSetting.must_approve_users? && !(invite.present? && invite.redeemable?)
ApprovalActivator
else
LoginActivator
end
end
end
class ApprovalActivator < UserActivator
def activate
success_message
end
def success_message
I18n.t("login.wait_approval")
end
end
class EmailActivator < UserActivator
def activate
email_token = user.email_tokens.create!(email: user.email, scope: EmailToken.scopes[:signup])
EmailToken.enqueue_signup_email(email_token)
success_message
end
def success_message
I18n.t("login.activate_email", email: Rack::Utils.escape_html(user.email))
end
end
class LoginActivator < UserActivator
include CurrentUser
def activate
log_on_user(
user,
{ authenticated_with_oauth: session[:authenticated_with_oauth] },
replay_anonymous_action: true,
)
user.enqueue_welcome_message("welcome_user")
success_message
end
def success_message
I18n.t("login.active")
end
end