Module: Studio::LinkToken
- Defined in:
- lib/studio/link_token.rb
Overview
Pure-Ruby helpers behind the Studio::Link model — token minting, the kind rules, and the input sanitizers. Kept free of ActiveRecord so it loads (and unit-tests) without a database, mirroring the other lib/studio/*.rb pure classes. The AR model (app/models/studio/link.rb) delegates to this.
Constant Summary collapse
- KINDS =
The kinds of link that share the studio_links table + the /l/<token> entry point.
magic_link — single-use, short-lived passwordless sign-in / sign-up referral — reusable, non-expiring share link owned by a User %w[magic_link referral].freeze
- SINGLE_USE_KINDS =
Kinds burned on first successful consume. Referral links are reusable, so they are deliberately NOT single-use.
%w[magic_link].freeze
- TOKEN_BYTES =
96 bits of entropy → ~16 URL-safe chars (e.g. “PP-PDbEj5V3-aNh4”). Short enough to keep the URL clean, far too large to brute-force — especially for single-use, expiring magic links. Matches turf-monster’s proven format.
12
Class Method Summary collapse
-
.generate ⇒ Object
A fresh URL-safe token.
- .kind?(kind) ⇒ Boolean
- .normalize_email(email) ⇒ Object
-
.sanitize_path(path) ⇒ Object
Only same-origin absolute paths survive; protocol-relative (“//evil”), absolute URLs, and blanks collapse to nil so callers fall back to a safe default redirect.
- .single_use?(kind) ⇒ Boolean
Class Method Details
.generate ⇒ Object
A fresh URL-safe token. urlsafe_base64 emits only [A-Za-z0-9_-], so the token satisfies the %r[^/]+ route constraint and survives URL generation without extra encoding.
31 32 33 |
# File 'lib/studio/link_token.rb', line 31 def generate SecureRandom.urlsafe_base64(TOKEN_BYTES) end |
.kind?(kind) ⇒ Boolean
35 36 37 |
# File 'lib/studio/link_token.rb', line 35 def kind?(kind) KINDS.include?(kind.to_s) end |
.normalize_email(email) ⇒ Object
43 44 45 |
# File 'lib/studio/link_token.rb', line 43 def normalize_email(email) email.to_s.strip.downcase end |
.sanitize_path(path) ⇒ Object
Only same-origin absolute paths survive; protocol-relative (“//evil”), absolute URLs, and blanks collapse to nil so callers fall back to a safe default redirect. Mirrors the MagicLink service’s sanitizer.
50 51 52 53 |
# File 'lib/studio/link_token.rb', line 50 def sanitize_path(path) p = path.to_s p.start_with?("/") && !p.start_with?("//") ? p : nil end |
.single_use?(kind) ⇒ Boolean
39 40 41 |
# File 'lib/studio/link_token.rb', line 39 def single_use?(kind) SINGLE_USE_KINDS.include?(kind.to_s) end |