From 60bc0a53bad1810259fd8c1ef8d660339e14adee Mon Sep 17 00:00:00 2001 From: Max Wofford Date: Wed, 12 Mar 2025 16:03:54 -0400 Subject: [PATCH] Turn on transactional emails with loops --- .env.example | 5 +++- app/controllers/sessions_controller.rb | 26 +++++++------------ app/mailers/loops_mailer.rb | 22 ++++++++++++++++ app/models/user.rb | 1 - app/views/auth_mailer/sign_in_email.html.erb | 2 +- app/views/loops_mailer/sign_in_email.text.erb | 7 +++++ 6 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 app/mailers/loops_mailer.rb create mode 100644 app/views/loops_mailer/sign_in_email.text.erb diff --git a/.env.example b/.env.example index deeb5c2..1a3237c 100644 --- a/.env.example +++ b/.env.example @@ -28,4 +28,7 @@ ENCRYPTION_KEY_DERIVATION_SALT=generate_a_salt_and_put_it_here SMTP_USER_NAME=replace_with_your_smtp_username SMTP_PASSWORD=replace_with_your_smtp_password SMTP_ADDRESS=replace_with_your_smtp_address -SMTP_PORT=replace_with_your_smtp_port \ No newline at end of file +SMTP_PORT=replace_with_your_smtp_port + +# some emails are sent via loops.so– again, not needed for local development +LOOPS_API_KEY=your_loops_api_key_here \ No newline at end of file diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index fd7fcc0..acc7fbf 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -35,25 +35,17 @@ class SessionsController < ApplicationController def email email = params[:email].downcase - email_address = EmailAddress.find_by(email: email) - if email_address - # Existing user - send sign in link - token = email_address.user.create_email_signin_token - AuthMailer.sign_in_email(email_address, token).deliver_later - redirect_to root_path(sign_in_email: true), notice: "Check your email for a sign-in link!" - else - # New user - create account and send sign in link - user = User.create!( - username: email.split("@").first, - ) - - email_address = user.email_addresses.create!(email: email) - token = user.create_email_signin_token - AuthMailer.sign_in_email(email_address, token).deliver_later - - redirect_to root_path(sign_in_email: true), notice: "Welcome! Check your email for a sign-in link!" + # Use a transaction to ensure both user and email are created atomically + email_address = ActiveRecord::Base.transaction do + EmailAddress.find_by(email: email) || begin + user = User.create! + user.email_addresses.create!(email: email) + end end + + LoopsMailer.sign_in_email(email_address).deliver_later + redirect_to root_path(sign_in_email: true) end def token diff --git a/app/mailers/loops_mailer.rb b/app/mailers/loops_mailer.rb new file mode 100644 index 0000000..688f194 --- /dev/null +++ b/app/mailers/loops_mailer.rb @@ -0,0 +1,22 @@ +class LoopsMailer < ApplicationMailer + # Override the default mailer settings to use Loops.so SMTP + self.delivery_method = :smtp + self.smtp_settings = { + address: "smtp.loops.so", + port: 587, + user_name: "loops", + password: ENV["LOOPS_API_KEY"], + authentication: "plain", + enable_starttls: true + } + + def sign_in_email(email_address) + @email = email_address.email + @token = email_address.user.create_email_signin_token.token + @sign_in_url = auth_token_url(@token) + + mail( + to: @email, + ) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index b8d51b2..bec57e1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,7 +3,6 @@ class User < ApplicationRecord encrypts :slack_access_token validates :slack_uid, uniqueness: true, allow_nil: true - validates :username, presence: true has_many :heartbeats has_many :email_addresses diff --git a/app/views/auth_mailer/sign_in_email.html.erb b/app/views/auth_mailer/sign_in_email.html.erb index a0dd3ce..2865aed 100644 --- a/app/views/auth_mailer/sign_in_email.html.erb +++ b/app/views/auth_mailer/sign_in_email.html.erb @@ -18,4 +18,4 @@ If you didn't request this email, you can safely ignore it.

- \ No newline at end of file + \ No newline at end of file diff --git a/app/views/loops_mailer/sign_in_email.text.erb b/app/views/loops_mailer/sign_in_email.text.erb new file mode 100644 index 0000000..981f974 --- /dev/null +++ b/app/views/loops_mailer/sign_in_email.text.erb @@ -0,0 +1,7 @@ +{ + "transactionalId": "cm86bg9vd00xuddjuh5u5mfuu", + "email": "<%= @email %>", + "dataVariables": { + "auth_link": "<%= @sign_in_url %>" + } +} \ No newline at end of file