Browse Source

Add a possibility for non admin users who have email on a given domain name (in Admin panel settings) to send an invitation for inscription

Emile NDAGIJIMANA 3 năm trước cách đây
mục cha
commit
b51152fca4

+ 4 - 0
client/components/settings/settingBody.jade

@@ -184,6 +184,10 @@ template(name='layoutSettings')
       .title {{_ 'oidc-button-text'}}
       .form-group
         input.wekan-form-control#oidcBtnTextvalue(type="text", placeholder="" value="{{currentSetting.oidcBtnText}}")
+    li.layout-form
+      .title {{_ 'can-invite-if-same-mailDomainName'}}
+      .form-group
+        input.wekan-form-control#mailDomaineNamevalue(type="text", placeholder="" value="{{currentSetting.mailDomaineName}}")
     li.layout-form
       .title {{_ 'display-authentication-method'}}
       .form-group.flex

+ 6 - 0
client/components/settings/settingBody.js

@@ -205,6 +205,11 @@ BlazeComponent.extendComponent({
     )
       .val()
       .trim();
+    const mailDomaineName = $(
+      '#mailDomaineNamevalue',
+    )
+      .val()
+      .trim();
     const hideLogoChange = $('input[name=hideLogo]:checked').val() === 'true';
     const displayAuthenticationMethod =
       $('input[name=displayAuthenticationMethod]:checked').val() === 'true';
@@ -228,6 +233,7 @@ BlazeComponent.extendComponent({
           automaticLinkedUrlSchemes,
           spinnerName,
           oidcBtnText,
+          mailDomaineName,
         },
       });
     } catch (e) {

+ 29 - 0
client/components/users/userHeader.jade

@@ -49,6 +49,11 @@ template(name="memberMenuPopup")
             i.fa.fa-lock
             | {{_ 'admin-panel'}}
       hr
+      if isSameDomainNameSettingValue
+        li
+          a.js-invite-people
+            i.fa.fa-envelope
+            | {{_ 'invite-people'}}
       if isNotOAuth2AuthenticationMethod
         li
           a.js-edit-profile
@@ -80,6 +85,30 @@ template(name="memberMenuPopup")
           i.fa.fa-sign-out
           | {{_ 'log-out'}}
 
+template(name="invitePeoplePopup")
+  ul#registration-setting.setting-detail
+    li
+      #invite-people-infos
+    li
+      br
+    li
+      .invite-people(class="{{#if currentSetting.disableRegistration}}{{else}}hide{{/if}}")
+        ul
+          li
+            .title {{_ 'invite-people'}}
+            textarea#email-to-invite.wekan-form-control(rows='5', placeholder="{{_ 'email-addresses'}}")
+          li
+            .title {{_ 'to-boards'}}
+            .bg-white
+              each boards
+                a.option.flex.js-toggle-board-choose(id= _id)
+                  .materialCheckBox(data-id= _id)
+
+                  span= title
+
+          li
+            button.js-email-invite.primary {{_ 'invite'}}
+
 template(name="editProfilePopup")
   form
     label

+ 87 - 0
client/components/users/userHeader.js

@@ -3,6 +3,12 @@ Template.headerUserBar.events({
   'click .js-change-avatar': Popup.open('changeAvatar'),
 });
 
+BlazeComponent.extendComponent({
+  onCreated() {
+    Meteor.subscribe('setting');
+  },
+}).register('memberMenuPopup');
+
 Template.memberMenuPopup.helpers({
   templatesBoardId() {
     currentUser = Meteor.user();
@@ -22,6 +28,26 @@ Template.memberMenuPopup.helpers({
       return false;
     }
   },
+  isSameDomainNameSettingValue(){
+    const currSett = Settings.findOne();
+    if(currSett && currSett != undefined && currSett.disableRegistration && currSett.mailDomaineName !== undefined && currSett.mailDomaineName != ""){
+      currentUser = Meteor.user();
+      if (currentUser) {
+        let found = false;
+        for(let i = 0; i < currentUser.emails.length; i++) {
+          if(currentUser.emails[i].address.endsWith(currSett.mailDomaineName)){
+            found = true;
+            break;
+          }
+        }
+        return found;
+      } else {
+        return true;
+      }
+    }
+    else
+      return false;
+  },
   isNotOAuth2AuthenticationMethod(){
     currentUser = Meteor.user();
     if (currentUser) {
@@ -42,6 +68,7 @@ Template.memberMenuPopup.events({
   'click .js-open-archived-board'() {
     Modal.open('archivedBoards');
   },
+  'click .js-invite-people': Popup.open('invitePeople'),
   'click .js-edit-profile': Popup.open('editProfile'),
   'click .js-change-settings': Popup.open('changeSettings'),
   'click .js-change-avatar': Popup.open('changeAvatar'),
@@ -57,6 +84,66 @@ Template.memberMenuPopup.events({
   },
 });
 
+BlazeComponent.extendComponent({
+  onCreated() {
+    Meteor.subscribe('setting');
+  },
+}).register('editProfilePopup');
+
+Template.invitePeoplePopup.events({
+  'click a.js-toggle-board-choose'(event){
+    let target = $(event.target);
+    if (!target.hasClass('js-toggle-board-choose')) {
+      target = target.parent();
+    }
+    const checkboxId = target.attr('id');
+    $(`#${checkboxId} .materialCheckBox`).toggleClass('is-checked');
+    $(`#${checkboxId}`).toggleClass('is-checked');
+  },
+  'click button.js-email-invite'(event){
+    const emails = $('#email-to-invite')
+      .val()
+      .toLowerCase()
+      .trim()
+      .split('\n')
+      .join(',')
+      .split(',');
+    const boardsToInvite = [];
+    $('.js-toggle-board-choose .materialCheckBox.is-checked').each(function() {
+      boardsToInvite.push($(this).data('id'));
+    });
+    const validEmails = [];
+    emails.forEach(email => {
+      if (email && SimpleSchema.RegEx.Email.test(email.trim())) {
+        validEmails.push(email.trim());
+      }
+    });
+    if (validEmails.length) {
+      Meteor.call('sendInvitation', validEmails, boardsToInvite, (_, rc) => {
+        if (rc == 0) {
+          let divInfos = document.getElementById("invite-people-infos");
+          if(divInfos && divInfos !== undefined){
+            divInfos.innerHTML = "<span style='color: green'>" + TAPi18n.__('invite-people-success') + "</span>";
+          }
+        }
+        else{
+          let divInfos = document.getElementById("invite-people-infos");
+          if(divInfos && divInfos !== undefined){
+            divInfos.innerHTML = "<span style='color: red'>" + TAPi18n.__('invite-people-error') + "</span>";
+          }
+        }
+        // Popup.close();
+      });
+    }
+  },
+});
+
+Template.invitePeoplePopup.helpers({
+  currentSetting() {
+    return Settings.findOne();
+  },
+});
+
 Template.editProfilePopup.helpers({
   allowEmailChange() {
     Meteor.call('AccountSettings.allowEmailChange', (_, result) => {

+ 3 - 1
i18n/en.i18n.json

@@ -1095,5 +1095,7 @@
   "remove-team-from-table": "Are you sure you want to remove this team from the board ?",
   "confirm-btn": "Confirm",
   "remove-btn": "Remove",
-  "filter-card-title-label": "Filter by card title"
+  "invite-people-success": "Invitation for inscription sent wiht success",
+  "invite-people-error": "Error while sending inscription invitation",
+  "can-invite-if-same-mailDomainName": "E-mail domain name"
 }

+ 6 - 4
i18n/fr.i18n.json

@@ -1091,8 +1091,10 @@
     "cardDetailsPopup-title": "Détails de la carte",
     "add-teams": "Ajouter des équipes",
     "add-teams-label": "Les équipes ajoutées sont affichées ci-dessous :",
-    "remove-team-from-table": "Voulez-vous vraiment supprimer cette équipe du tableau ?",
-    "confirm-btn": "Confirmer",
+    "remove-team-from-table": "Are you sure you want to remove this team from the board ?",
+    "confirm-btn": "Confirm",
     "remove-btn": "Supprimer",
-    "filter-card-title-label": "Filtrer par titre de carte"
-}
+    "invite-people-success": "L'invitation à l'inscription a été envoyé avec succèss",
+    "invite-people-error": "Erreur lors de l'envoie d'une invitation à l'inscription",
+    "can-invite-if-same-mailDomainName": "Nom de domaine"
+}

+ 9 - 0
models/settings.js

@@ -88,6 +88,10 @@ Settings.attachSchema(
       type: String,
       optional: true,
     },
+    mailDomaineName: {
+      type: String,
+      optional: true,
+    },
     createdAt: {
       type: Date,
       denyUpdate: true,
@@ -290,11 +294,13 @@ if (Meteor.isServer) {
 
   Meteor.methods({
     sendInvitation(emails, boards) {
+      let rc = 0;
       check(emails, [String]);
       check(boards, [String]);
 
       const user = Users.findOne(Meteor.userId());
       if (!user.isAdmin) {
+        rc = -1;
         throw new Meteor.Error('not-allowed');
       }
       emails.forEach(email => {
@@ -302,6 +308,7 @@ if (Meteor.isServer) {
           // Checks if the email is already link to an account.
           const userExist = Users.findOne({ email });
           if (userExist) {
+            rc = -1;
             throw new Meteor.Error(
               'user-exist',
               `The user with the email ${email} has already an account.`,
@@ -328,6 +335,7 @@ if (Meteor.isServer) {
                 if (!err && _id) {
                   sendInvitationEmail(_id);
                 } else {
+                  rc = -1;
                   throw new Meteor.Error(
                     'invitation-generated-fail',
                     err.message,
@@ -338,6 +346,7 @@ if (Meteor.isServer) {
           }
         }
       });
+      return rc;
     },
 
     sendSMTPTestEmail() {

+ 1 - 0
server/publications/settings.js

@@ -25,6 +25,7 @@ Meteor.publish('setting', () => {
         defaultAuthenticationMethod: 1,
         spinnerName: 1,
         oidcBtnText: 1,
+        mailDomaineName: 1,
       },
     },
   );