Class: Studio::LinksController

Inherits:
ApplicationController
  • Object
show all
Includes:
LinkConsumption
Defined in:
app/controllers/studio/links_controller.rb

Overview

The unified short-token link entry point — GET/POST /l/<token>. Dispatches by Studio::Link#kind:

magic_link → scanner-safe confirm interstitial (GET, inert) that auto-POSTs
             to #consume, the ONLY place the single-use token is burned +
             the recipient is signed in / signed up.
referral   → idempotent: capture attribution into a cookie + redirect to
             the link's target (or root). Reusable + safe to prefetch, so
             GET does the work (no POST step).

Namespaced (not top-level Links) because mcritchie-studio already owns a public /links linktree (top-level LinksController). Apps needing richer post-consume routing (contest landing, picks rehydration, age-gate) define their own Studio::LinksController and reuse Studio::Link + the Studio::LinkConsumption building blocks.

Instance Method Summary collapse

Instance Method Details

#consumeObject

POST /l/:token — authoritative magic-link consume. Only magic_link kinds are consumable here; referral links are reusable and handled entirely on GET.



42
43
44
45
46
47
48
49
50
51
52
# File 'app/controllers/studio/links_controller.rb', line 42

def consume
  response.set_header("Referrer-Policy", "strict-origin")
  link = Studio::Link.find_by(token: params[:token])
  raise Studio::Link::InvalidToken, "not a magic link" unless link&.kind == "magic_link"

  link.consume! # burns the single-use token; raises if already used / expired
  user = User.find_by(email: link.email)
  user ? (user, link) : (link)
rescue Studio::Link::InvalidToken
  redirect_to , alert: "That sign-in link is invalid or has expired. Request a fresh one below."
end

#showObject

GET /l/:token



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'app/controllers/studio/links_controller.rb', line 24

def show
  response.set_header("Referrer-Policy", "strict-origin")
  @link = Studio::Link.find_by(token: params[:token])

  case @link&.kind
  when "magic_link"
    @token = params[:token]
    render :confirm
  when "referral"
    capture_referral(@link)
    redirect_to(@link.target || root_path)
  else
    redirect_to , alert: "That link is invalid or has expired. Request a fresh one below."
  end
end