diff --git a/app/assets/javascripts/admin/addon/components/modal/incoming-email.hbs b/app/assets/javascripts/admin/addon/components/modal/incoming-email.hbs new file mode 100644 index 00000000000..e1beb0f6664 --- /dev/null +++ b/app/assets/javascripts/admin/addon/components/modal/incoming-email.hbs @@ -0,0 +1,54 @@ + + <:body> + + {{i18n "admin.email.incoming_emails.modal.error"}} + + {{@model.error}} + {{#if @model.error_description}} + {{@model.error_description}} + {{/if}} + + + + + + + {{i18n "admin.email.incoming_emails.modal.headers"}} + + + + + + + {{i18n "admin.email.incoming_emails.modal.subject"}} + + {{@model.subject}} + + + + + {{i18n "admin.email.incoming_emails.modal.body"}} + + + + + + {{#if @model.rejection_message}} + + + + {{i18n + "admin.email.incoming_emails.modal.rejection_message" + }} + + + + + {{/if}} + + \ No newline at end of file diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js deleted file mode 100644 index 3724332cee7..00000000000 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-incoming-email.js +++ /dev/null @@ -1,28 +0,0 @@ -import Controller from "@ember/controller"; -import IncomingEmail from "admin/models/incoming-email"; -import ModalFunctionality from "discourse/mixins/modal-functionality"; -import discourseComputed from "discourse-common/utils/decorators"; -import { longDate } from "discourse/lib/formatter"; -import { popupAjaxError } from "discourse/lib/ajax-error"; - -export default class AdminIncomingEmailController extends Controller.extend( - ModalFunctionality -) { - @discourseComputed("model.date") - date(d) { - return longDate(d); - } - - load(id) { - return IncomingEmail.find(id).then((result) => this.set("model", result)); - } - - loadFromBounced(id) { - return IncomingEmail.findByBounced(id) - .then((result) => this.set("model", result)) - .catch((error) => { - this.send("closeModal"); - popupAjaxError(error); - }); - } -} diff --git a/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js b/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js index 74cb0975b9b..5a5d410c176 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js +++ b/app/assets/javascripts/admin/addon/routes/admin-email-bounced.js @@ -1,13 +1,26 @@ import { action } from "@ember/object"; import AdminEmailLogs from "admin/routes/admin-email-logs"; -import showModal from "discourse/lib/show-modal"; +import IncomingEmail from "admin/models/incoming-email"; +import IncomingEmailModal from "../components/modal/incoming-email"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { inject as service } from "@ember/service"; export default class AdminEmailBouncedRoute extends AdminEmailLogs { + @service modal; status = "bounced"; @action - showIncomingEmail(id) { - showModal("admin-incoming-email", { admin: true }); - this.controllerFor("modals/admin-incoming-email").loadFromBounced(id); + async showIncomingEmail(id) { + const model = await this.loadFromBounced(id); + this.modal.show(IncomingEmailModal, { model }); + } + + @action + async loadFromBounced(id) { + try { + return await IncomingEmail.findByBounced(id); + } catch (error) { + popupAjaxError(error); + } } } diff --git a/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js b/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js index d09c81ef4fb..bb8b73f77a5 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js +++ b/app/assets/javascripts/admin/addon/routes/admin-email-rejected.js @@ -1,13 +1,16 @@ import { action } from "@ember/object"; import AdminEmailIncomings from "admin/routes/admin-email-incomings"; -import showModal from "discourse/lib/show-modal"; +import IncomingEmailModal from "../components/modal/incoming-email"; +import IncomingEmail from "admin/models/incoming-email"; +import { inject as service } from "@ember/service"; export default class AdminEmailRejectedRoute extends AdminEmailIncomings { + @service modal; status = "rejected"; @action - showIncomingEmail(id) { - showModal("admin-incoming-email", { admin: true }); - this.controllerFor("modals/admin-incoming-email").load(id); + async showIncomingEmail(id) { + const model = await IncomingEmail.find(id); + this.modal.show(IncomingEmailModal, { model }); } } diff --git a/app/assets/javascripts/admin/addon/templates/modal/admin-incoming-email.hbs b/app/assets/javascripts/admin/addon/templates/modal/admin-incoming-email.hbs deleted file mode 100644 index 28a4294b9d2..00000000000 --- a/app/assets/javascripts/admin/addon/templates/modal/admin-incoming-email.hbs +++ /dev/null @@ -1,50 +0,0 @@ - - - {{i18n "admin.email.incoming_emails.modal.error"}} - - {{this.model.error}} - {{#if this.model.error_description}} - {{this.model.error_description}} - {{/if}} - - - - - - - {{i18n "admin.email.incoming_emails.modal.headers"}} - - - - - - - {{i18n "admin.email.incoming_emails.modal.subject"}} - - {{this.model.subject}} - - - - - {{i18n "admin.email.incoming_emails.modal.body"}} - - - - - - {{#if this.model.rejection_message}} - - - - {{i18n - "admin.email.incoming_emails.modal.rejection_message" - }} - - - - - {{/if}} - \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/services/modal.js b/app/assets/javascripts/discourse/app/services/modal.js index 118b2229ad0..ff6c5ec273d 100644 --- a/app/assets/javascripts/discourse/app/services/modal.js +++ b/app/assets/javascripts/discourse/app/services/modal.js @@ -58,7 +58,6 @@ const KNOWN_LEGACY_MODALS = [ "user-status", "admin-add-upload", "admin-delete-posts-confirmation", - "admin-incoming-email", "admin-merge-users-prompt", "admin-start-backup", "admin-watched-word-test", diff --git a/config/dev_defaults.yml b/config/dev_defaults.yml index dcdb65dfa09..0420be8feb1 100644 --- a/config/dev_defaults.yml +++ b/config/dev_defaults.yml @@ -35,6 +35,8 @@ topic: max: 3 user: count: 30 +email_logs: + count: 2 new_user: username: new_user diff --git a/lib/discourse_dev/email_log.rb b/lib/discourse_dev/email_log.rb new file mode 100644 index 00000000000..b7d94c27090 --- /dev/null +++ b/lib/discourse_dev/email_log.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require "discourse_dev/record" +require "faker" + +module DiscourseDev + class EmailLog < Record + def initialize + super(::EmailLog, DiscourseDev.config.email_logs[:count]) + end + + def create_sent! + ::EmailLog.create!(email_log_data) + end + + def create_bounced! + bounce_key = SecureRandom.hex + email_local_part, email_domain = SiteSetting.notification_email.split("@") + bounced_to_address = "#{email_local_part}+verp-#{bounce_key}@#{email_domain}" + bounce_data = + email_log_data.merge( + to_address: bounced_to_address, + bounced: true, + bounce_key: bounce_key, + bounce_error_code: "5.0.0", + ) + + # Bounced email logs require a matching incoming email record + ::IncomingEmail.create!( + incoming_email_data.merge(to_addresses: bounced_to_address, is_bounce: true), + ) + ::EmailLog.create!(bounce_data) + end + + def create_rejected! + ::IncomingEmail.create!(incoming_email_data) + end + + def email_log_data + { + to_address: User.random.email, + email_type: :digest, + user_id: User.random.id, + raw: Faker::Lorem.paragraph, + } + end + + def incoming_email_data + user = User.random + subject = Faker::Lorem.sentence + email_content = <<-EMAIL + Return-Path: #{user.email} + From: #{user.email} + Date: #{Date.today} + Mime-Version: "1.0" + Content-Type: "text/plain" + Content-Transfer-Encoding: "7bit" + + #{Faker::Lorem.paragraph} + EMAIL + + { + user_id: user.id, + from_address: user.email, + raw: email_content, + error: Faker::Lorem.sentence, + rejection_message: I18n.t("emails.incoming.errors.bounced_email_error"), + } + end + + def populate! + @count.times { create_sent! } + @count.times { create_bounced! } + @count.times { create_rejected! } + end + end +end diff --git a/lib/tasks/populate.rake b/lib/tasks/populate.rake index 15a018db3f5..a1191c427c6 100644 --- a/lib/tasks/populate.rake +++ b/lib/tasks/populate.rake @@ -54,3 +54,8 @@ desc "Add replies to a topic" task "replies:populate", %i[topic_id count] => ["db:load_config"] do |_, args| DiscourseDev::Post.add_replies!(args) end + +desc "Creates sample email logs" +task "email_logs:populate" => ["db:load_config"] do |_, args| + DiscourseDev::EmailLog.populate! +end
{{@model.error}}
{{@model.error_description}}
{{this.model.error}}
{{this.model.error_description}}