Class: MagicLinksController

Inherits:
ApplicationController
  • Object
show all
Defined in:
app/controllers/magic_links_controller.rb

Overview

Unified create-or-login email magic link (the passwordless email path).

POST /magic_link        — request a link (email [, return_to])
GET  /magic_link/:token — consume it: log in OR create the account

create-or-login: clicking the link IS proof of email ownership, so an email that collides with a Google/wallet-only account that was never email-verified is safely logged in here and stamped email_verified_at (unlike from_omniauth, which refuses that collision precisely because it lacked this proof).

This is the engine’s GENERIC base. Apps that need richer post-consume routing (e.g. turf-monster’s contest landing + picks rehydration + entry-tokens upsell) OVERRIDE this controller in the app and reuse the MagicLink service + the sign_in_existing / sign_up_new building blocks.

Instance Method Summary collapse

Instance Method Details

#consumeObject



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/controllers/magic_links_controller.rb', line 33

def consume
  # Keep the token out of Referer headers on the consume page's subresource
  # loads. Single-use + short TTL is the primary defence; this closes the
  # passive-leak gap. NOTE: aggressive email link-scanners (Outlook SafeLinks,
  # Mimecast) may pre-fetch the link and burn the single-use token before the
  # human clicks — a known magic-link tradeoff; documented for support.
  response.set_header("Referrer-Policy", "no-referrer")
  result = MagicLink.consume(params[:token])
  user = User.find_by(email: result.email)
  user ? (user, result) : (result)
rescue MagicLink::InvalidToken
  redirect_to , alert: "That sign-in link is invalid or has expired. Request a fresh one below."
end

#createObject

Respond uniformly for any well-formed email. Under create-or-login every address is “valid” (it logs in or signs up), so there is nothing to enumerate. A malformed email gets the same response with no mail sent.



21
22
23
24
25
26
27
28
29
30
31
# File 'app/controllers/magic_links_controller.rb', line 21

def create
  email = params[:email].to_s.strip.downcase
  if email.match?(URI::MailTo::EMAIL_REGEXP)
    token = MagicLink.generate(email: email, return_to: safe_path(params[:return_to]))
    UserMailer.magic_link(email, token).deliver_later
  end
  respond_to do |format|
    format.json { render json: { success: true } }
    format.html { redirect_to , notice: "Check your inbox — we just emailed you a sign-in link." }
  end
end