Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accusé de réception + lien de suppression auto (rendre l'inbox [email protected] plus simple) #1016

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/jobs/send_user_anonymization_link_after_user_requested_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class SendUserAnonymizationLinkAfterUserRequestedJob < ApplicationJob
queue_as :mailers

def perform(user_id)
user = User.find(user_id)

return if user.anonymized_at?
PrivacyMailer.with(user_id: user.id).send_user_anonymization_link_after_user_requested.deliver_now
rescue Postmark::InactiveRecipientError => e
Rails.logger.error(e.message)
user.anonymize!
rescue Postmark::ApiInputError => e
if e.message.start_with?("Invalid 'To' address:")
Rails.logger.error(e.message)
user.anonymize!
else
raise e
end
end
end
6 changes: 6 additions & 0 deletions app/mailboxes/application_mailbox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ApplicationMailbox < ActionMailbox::Base
PRIVACY_REGEX = /[email protected]/i

# route for incoming emails on that email to PrivacyMailbox
routing PRIVACY_REGEX => :privacy
end
16 changes: 16 additions & 0 deletions app/mailboxes/privacy_mailbox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class PrivacyMailbox < ApplicationMailbox
before_processing :find_user

def process
return if !@user || @user.anonymized_at?

Rails.logger.info("[PrivacyMailbox] Auto-sending an email notice to ##{@user.id} with a destroy link")
SendUserAnonymizationLinkAfterUserRequestedJob.perform_later(@user.id)
end

private

def find_user
@user ||= User.find_by(email: mail.from)
end
end
14 changes: 14 additions & 0 deletions app/mailers/privacy_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class PrivacyMailer < ApplicationMailer
default from: "Covidliste <[email protected]>"

def send_user_anonymization_link_after_user_requested
@user = User.find(params[:user_id])

return if @user.email.blank?

mail(
to: @user.email,
subject: "Nous avons bien reçu votre email"
)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<% authentication_token = @user.signed_id(purpose: "users.destroy", expires_in: 7.days) %>
<mj-section padding-bottom="15px" padding-top="15px">
<mj-column>
<mj-text padding-bottom="0px">
<h1>Nous avons bien reçu votre email</h1>
<br/>
Si vous souhaitez supprimer votre compte, vous pouvez le faire directement ici :
</mj-text>
<mj-button href="<%= confirm_destroy_profile_url(authentication_token: authentication_token) %>" padding-bottom="0px">
Supprimer mon compte et mes données personnelles
</mj-button>
<mj-text>
<strong>Si le lien ne fonctionne pas</strong>, copiez et collez l’adresse suivante dans votre navigateur :
<br />
<%= confirm_destroy_profile_url(authentication_token: authentication_token) %>
</mj-text>
<%= render partial: "mailer/social_networks", formats: [:html] %>
</mj-column>
</mj-section>
3 changes: 3 additions & 0 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@
password: ENV["SMTP_PASSWORD"]
}

config.action_mailbox.ingress = :postmark
config.action_mailbox.queues.routing = :low

config.force_ssl = true
config.ssl_options = {hsts: {subdomains: true, preload: true, expires: 1.year}}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
create_table :active_storage_blobs do |t|
t.string :key, null: false
t.string :filename, null: false
t.string :content_type
t.text :metadata
t.string :service_name, null: false
t.bigint :byte_size, null: false
t.string :checksum, null: false
t.datetime :created_at, null: false

t.index [:key], unique: true
end

create_table :active_storage_attachments do |t|
t.string :name, null: false
t.references :record, null: false, polymorphic: true, index: false
t.references :blob, null: false

t.datetime :created_at, null: false

t.index [:record_type, :record_id, :name, :blob_id], name: "index_active_storage_attachments_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end

create_table :active_storage_variant_records do |t|
t.belongs_to :blob, null: false, index: false
t.string :variation_digest, null: false

t.index %i[blob_id variation_digest], name: "index_active_storage_variant_records_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# This migration comes from action_mailbox (originally 20180917164000)
class CreateActionMailboxTables < ActiveRecord::Migration[6.0]
def change
create_table :action_mailbox_inbound_emails do |t|
t.integer :status, default: 0, null: false
t.string :message_id, null: false
t.string :message_checksum, null: false

t.timestamps

t.index [:message_id, :message_checksum], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
end
end
end
41 changes: 40 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require "rails_helper"

describe SendUserAnonymizationLinkAfterUserRequestedJob do
let!(:user) { create(:user) }

subject { SendUserAnonymizationLinkAfterUserRequestedJob.new.perform(user.id) }

context "user is not anonymized" do
before do
user.update(anonymized_at: nil)
end
it "sends the email" do
mail = double(:mail)
allow(PrivacyMailer).to receive_message_chain("with.send_user_anonymization_link_after_user_requested").and_return(mail)
expect(mail).to receive(:deliver_now)
subject
end
end

context "user is already anonymized" do
before do
user.update(anonymized_at: Time.now.utc)
end
it "does not send the email" do
mail = double(:mail)
allow(PrivacyMailer).to receive_message_chain("with.send_user_anonymization_link_after_user_requested").and_return(mail)
expect(mail).not_to receive(:deliver_now)
subject
end
end
end
20 changes: 20 additions & 0 deletions spec/mailers/privacy_mailer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require "rails_helper"

RSpec.describe PrivacyMailer, type: :mailer do
describe "#send_user_anonymization_link_after_user_requested" do
let(:mail) { described_class.with(user_id: user.id).send_user_anonymization_link_after_user_requested }
let(:user) { create(:user) }

it "renders the headers" do
expect(mail.subject).to eq("Nous avons bien reçu votre email")
expect(mail.to).to eq([user.email])
expect(mail.from).to eq(["[email protected]"])
end

it "includes a signed link to the confirm_destroy_profile URL" do
match_data = mail.body.encoded.match(%r{/users/profile/confirm_destroy\?authentication_token=([^"]+)"})
token = CGI.unescape(match_data.captures.first)
expect(User.find_signed(token, purpose: "users.destroy")).to eq(user)
end
end
end
8 changes: 8 additions & 0 deletions test/mailers/previews/privacy_mailer_preview.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class PrivacyMailerPreview < ActionMailer::Preview
def send_user_anonymization_link_after_user_requested
user = FactoryBot.create(:user)
PrivacyMailer.with(user_id: user.id).send_user_anonymization_link_after_user_requested.deliver_now
end
end