FEATURE: Implement support for IMAP and SMTP email protocols. (#8301)

FEATURE: Implement support for IMAP and SMTP email protocols. (#8301)

Co-authored-by: Joffrey JAFFEUX j.jaffeux@gmail.com

diff --git a/app/assets/javascripts/discourse/app/components/groups-form-email-fields.js b/app/assets/javascripts/discourse/app/components/groups-form-email-fields.js
new file mode 100644
index 0000000..faebb63
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/groups-form-email-fields.js
@@ -0,0 +1,19 @@
+import Component from "@ember/component";
+import discourseComputed from "discourse-common/utils/decorators";
+
+export default Component.extend({
+  @discourseComputed("model.imap_mailboxes")
+  mailboxes(imapMailboxes) {
+    return imapMailboxes.map(mailbox => ({ name: mailbox, value: mailbox }));
+  },
+
+  @discourseComputed("model.imap_old_emails")
+  oldEmails(oldEmails) {
+    return oldEmails || 0;
+  },
+
+  @discourseComputed("model.imap_old_emails", "model.imap_new_emails")
+  totalEmails(oldEmails, newEmails) {
+    return (oldEmails || 0) + (newEmails || 0);
+  }
+});
diff --git a/app/assets/javascripts/discourse/app/controllers/group-manage.js b/app/assets/javascripts/discourse/app/controllers/group-manage.js
index 7a9e785..cc5bd11 100644
--- a/app/assets/javascripts/discourse/app/controllers/group-manage.js
+++ b/app/assets/javascripts/discourse/app/controllers/group-manage.js
@@ -18,6 +18,11 @@ export default Controller.extend({
     ];
 
     if (!automatic) {
+      defaultTabs.splice(2, 0, {
+        route: "group.manage.email",
+        title: "groups.manage.email.title"
+      });
+
       defaultTabs.splice(1, 0, {
         route: "group.manage.membership",
         title: "groups.manage.membership.title"
diff --git a/app/assets/javascripts/discourse/app/models/group.js b/app/assets/javascripts/discourse/app/models/group.js
index 1423414..af514bd 100644
--- a/app/assets/javascripts/discourse/app/models/group.js
+++ b/app/assets/javascripts/discourse/app/models/group.js
@@ -188,6 +188,15 @@ const Group = RestModel.extend({
       primary_group: !!this.primary_group,
       grant_trust_level: this.grant_trust_level,
       incoming_email: this.incoming_email,
+      smtp_server: this.smtp_server,
+      smtp_port: this.smtp_port,
+      smtp_ssl: this.smtp_ssl,
+      imap_server: this.imap_server,
+      imap_port: this.imap_port,
+      imap_ssl: this.imap_ssl,
+      imap_mailbox_name: this.imap_mailbox_name,
+      email_username: this.email_username,
+      email_password: this.email_password,
       flair_icon: null,
       flair_upload_id: null,
       flair_bg_color: this.flairBackgroundHexColor,
diff --git a/app/assets/javascripts/discourse/app/routes/app-route-map.js b/app/assets/javascripts/discourse/app/routes/app-route-map.js
index 9057ff2..23aa5e2 100644
--- a/app/assets/javascripts/discourse/app/routes/app-route-map.js
+++ b/app/assets/javascripts/discourse/app/routes/app-route-map.js
@@ -92,6 +92,7 @@ export default function() {
       this.route("profile");
       this.route("membership");
       this.route("interaction");
+      this.route("email");
       this.route("members");
       this.route("logs");
     });
diff --git a/app/assets/javascripts/discourse/app/routes/group-manage-email.js b/app/assets/javascripts/discourse/app/routes/group-manage-email.js
new file mode 100644
index 0000000..58ce783
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/routes/group-manage-email.js
@@ -0,0 +1,10 @@
+import DiscourseRoute from "discourse/routes/discourse";
+import I18n from "I18n";
+
+export default DiscourseRoute.extend({
+  showFooter: true,
+
+  titleToken() {
+    return I18n.t("groups.manage.email.title");
+  }
+});
diff --git a/app/assets/javascripts/discourse/app/templates/components/groups-form-email-fields.hbs b/app/assets/javascripts/discourse/app/templates/components/groups-form-email-fields.hbs
new file mode 100644
index 0000000..0a8e08f
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/templates/components/groups-form-email-fields.hbs
@@ -0,0 +1,67 @@
+{{#if currentUser.admin}}
+  <div class="control-group">
+    <label class="control-label">{{i18n "groups.manage.email.credentials.title"}}</label>
+  </div>
+
+  {{#if model.imap_last_error}}
+    <div class="alert alert-error">{{model.imap_last_error}}</div>
+  {{else}}
+    <div class="alert alert-info">
+      {{i18n "groups.manage.email.status" old_emails=oldEmails total_emails=totalEmails}}
+    </div>
+  {{/if}}
+
+  <div class="control-group">
+    <label for="smtp_server">{{i18n "groups.manage.email.credentials.smtp_server"}}</label>
+    {{input type="text" name="smtp_server" value=model.smtp_server}}
+  </div>
+
+  <div class="control-group">
+    <label for="smtp_port">{{i18n "groups.manage.email.credentials.smtp_port"}}</label>
+    {{input type="text" name="smtp_port" value=model.smtp_port}}
+  </div>
+
+  <div class="control-group">
+    {{input type="checkbox" name="smtp_ssl" checked=model.smtp_ssl}}
+    <label class="control-group-inline" for="smtp_ssl">{{i18n "groups.manage.email.credentials.smtp_ssl"}}</label>
+  </div>
+
+  <div class="control-group">
+    <label for="imap_server">{{i18n "groups.manage.email.credentials.imap_server"}}</label>
+    {{input type="text" name="imap_server" value=model.imap_server}}
+  </div>
+
+  <div class="control-group">
+    <label for="imap_port">{{i18n "groups.manage.email.credentials.imap_port"}}</label>
+    {{input type="text" name="imap_port" value=model.imap_port}}
+  </div>
+
+  <div class="control-group">
+    {{input type="checkbox" name="imap_ssl" checked=model.imap_ssl}}
+    <label class="control-group-inline" for="imap_ssl">{{i18n "groups.manage.email.credentials.imap_ssl"}}</label>
+  </div>
+
+  <div class="control-group">
+    <label for="username">{{i18n "groups.manage.email.credentials.username"}}</label>
+    {{input type="text" name="username" value=model.email_username}}
+  </div>
+
+  <div class="control-group">
+    <label for="password">{{i18n "groups.manage.email.credentials.password"}}</label>
+    {{input type="password" name="password" value=model.email_password}}
+  </div>
+
+  <div class="control-group">
+    {{#if mailboxes}}
+      <label for="imap_mailbox_name">{{i18n "groups.manage.email.mailboxes.synchronized"}}</label>
+      {{combo-box name="imap_mailbox_name"
+                  value=model.imap_mailbox_name
+                  valueProperty="value"
+                  content=mailboxes
+                  none="groups.manage.email.mailboxes.disabled"
+                  onChange=(action (mut model.imap_mailbox_name))}}
+    {{else}}
+      {{i18n "groups.manage.email.mailboxes.none_found"}}
+    {{/if}}
+  </div>
+{{/if}}
diff --git a/app/assets/javascripts/discourse/app/templates/group/manage/email.hbs b/app/assets/javascripts/discourse/app/templates/group/manage/email.hbs
new file mode 100644
index 0000000..6ef5aad
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/templates/group/manage/email.hbs
@@ -0,0 +1,4 @@
+<form class="groups-form form-vertical">
+  {{groups-form-email-fields model=model}}
+  {{group-manage-save-button model=model}}
+</form>
diff --git a/app/assets/stylesheets/common/base/groups.scss b/app/assets/stylesheets/common/base/groups.scss
index 0cc6fcd..3419cb5 100644
--- a/app/assets/stylesheets/common/base/groups.scss
+++ b/app/assets/stylesheets/common/base/groups.scss
@@ -141,3 +141,9 @@
     }
   }
 }
+
+.groups-form {
+  .control-group-inline {
+    display: inline;
+  }
+}
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 2e112ed..08205d0 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -547,6 +547,15 @@ class GroupsController < ApplicationController
         if current_user.admin
           default_params.push(*[
             :incoming_email,
+            :smtp_server,
+            :smtp_port,
+            :smtp_ssl,
+            :imap_server,
+            :imap_port,
+            :imap_ssl,
+            :imap_mailbox_name,
+            :email_username,
+            :email_password,

[... diff too long, it was truncated ...]

GitHub sha: c72bc278

This commit appears in #8301 which was approved by eviltrout. It was merged by udan11.