diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade
index f9d66c884..bdb242f8c 100644
--- a/client/components/settings/settingBody.jade
+++ b/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
diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js
index c857f3ed1..157f7ac54 100644
--- a/client/components/settings/settingBody.js
+++ b/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) {
diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade
index d5fe14739..4d7bd89a5 100644
--- a/client/components/users/userHeader.jade
+++ b/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
diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js
index 08056e054..3d0679a78 100644
--- a/client/components/users/userHeader.js
+++ b/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 = "" + TAPi18n.__('invite-people-success') + "";
+ }
+ }
+ else{
+ let divInfos = document.getElementById("invite-people-infos");
+ if(divInfos && divInfos !== undefined){
+ divInfos.innerHTML = "" + TAPi18n.__('invite-people-error') + "";
+ }
+ }
+ // Popup.close();
+ });
+ }
+ },
+});
+
+Template.invitePeoplePopup.helpers({
+ currentSetting() {
+ return Settings.findOne();
+ },
+});
+
Template.editProfilePopup.helpers({
allowEmailChange() {
Meteor.call('AccountSettings.allowEmailChange', (_, result) => {
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index a8592d61d..0f3d8eb3b 100644
--- a/i18n/en.i18n.json
+++ b/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"
}
diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json
index 19eb994bd..be71a95fd 100644
--- a/i18n/fr.i18n.json
+++ b/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"
-}
\ No newline at end of file
+ "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"
+}
diff --git a/models/settings.js b/models/settings.js
index 60dbe8134..46eda7df5 100644
--- a/models/settings.js
+++ b/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() {
diff --git a/server/publications/settings.js b/server/publications/settings.js
index 1a3fbd04d..4f496fa28 100644
--- a/server/publications/settings.js
+++ b/server/publications/settings.js
@@ -25,6 +25,7 @@ Meteor.publish('setting', () => {
defaultAuthenticationMethod: 1,
spinnerName: 1,
oidcBtnText: 1,
+ mailDomaineName: 1,
},
},
);