Add passwordless email auth with pre-checkout signup
Flow: enter email → magic link → verified → Stripe checkout → dashboard - SessionsController: new/create (send magic link), sent, verify, destroy - Customer model: generate_magic_token!, magic_token_valid?, verify_email! - Migration: magic_token, magic_token_expires_at, email_verified_at + unique indexes - CustomerMailer + mailer layout with magic link email (html + text) - CheckoutController: GET /checkout/start requires auth, passes customer_id as Stripe metadata; webhook finds customer by metadata and updates record - DashboardController: requires auth, uses current_customer from session - ApplicationController: current_customer, require_auth, redirect_after_auth (stores return_to so verify sends user back to where they were headed) - Resend gem + initializer; production uses :resend delivery method - Dev logs magic link URL to Rails logger instead of sending email - Pricing page: simple link to /checkout/start (no more JS fetch) - Layout: Sign in / Dashboard / Sign out nav links Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fd2d498141
commit
a1175ab00d
22 changed files with 284 additions and 51 deletions
|
|
@ -1,2 +1,30 @@
|
|||
class Customer < ApplicationRecord
|
||||
TOKEN_TTL = 15.minutes
|
||||
|
||||
def generate_magic_token!
|
||||
self.magic_token = SecureRandom.urlsafe_base64(32)
|
||||
self.magic_token_expires_at = TOKEN_TTL.from_now
|
||||
save!
|
||||
magic_token
|
||||
end
|
||||
|
||||
def magic_token_valid?
|
||||
magic_token.present? && magic_token_expires_at&.future?
|
||||
end
|
||||
|
||||
def verify_email!
|
||||
update!(
|
||||
email_verified_at: Time.current,
|
||||
magic_token: nil,
|
||||
magic_token_expires_at: nil
|
||||
)
|
||||
end
|
||||
|
||||
def email_verified?
|
||||
email_verified_at.present?
|
||||
end
|
||||
|
||||
def subscribed?
|
||||
stripe_customer_id.present?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue