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

This commit is contained in:
Emile NDAGIJIMANA 2021-10-29 18:34:03 +02:00
parent 344094ec18
commit b51152fca4
8 changed files with 145 additions and 5 deletions

View file

@ -184,6 +184,10 @@ template(name='layoutSettings')
.title {{_ 'oidc-button-text'}} .title {{_ 'oidc-button-text'}}
.form-group .form-group
input.wekan-form-control#oidcBtnTextvalue(type="text", placeholder="" value="{{currentSetting.oidcBtnText}}") 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 li.layout-form
.title {{_ 'display-authentication-method'}} .title {{_ 'display-authentication-method'}}
.form-group.flex .form-group.flex

View file

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

View file

@ -49,6 +49,11 @@ template(name="memberMenuPopup")
i.fa.fa-lock i.fa.fa-lock
| {{_ 'admin-panel'}} | {{_ 'admin-panel'}}
hr hr
if isSameDomainNameSettingValue
li
a.js-invite-people
i.fa.fa-envelope
| {{_ 'invite-people'}}
if isNotOAuth2AuthenticationMethod if isNotOAuth2AuthenticationMethod
li li
a.js-edit-profile a.js-edit-profile
@ -80,6 +85,30 @@ template(name="memberMenuPopup")
i.fa.fa-sign-out i.fa.fa-sign-out
| {{_ 'log-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") template(name="editProfilePopup")
form form
label label

View file

@ -3,6 +3,12 @@ Template.headerUserBar.events({
'click .js-change-avatar': Popup.open('changeAvatar'), 'click .js-change-avatar': Popup.open('changeAvatar'),
}); });
BlazeComponent.extendComponent({
onCreated() {
Meteor.subscribe('setting');
},
}).register('memberMenuPopup');
Template.memberMenuPopup.helpers({ Template.memberMenuPopup.helpers({
templatesBoardId() { templatesBoardId() {
currentUser = Meteor.user(); currentUser = Meteor.user();
@ -22,6 +28,26 @@ Template.memberMenuPopup.helpers({
return false; 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(){ isNotOAuth2AuthenticationMethod(){
currentUser = Meteor.user(); currentUser = Meteor.user();
if (currentUser) { if (currentUser) {
@ -42,6 +68,7 @@ Template.memberMenuPopup.events({
'click .js-open-archived-board'() { 'click .js-open-archived-board'() {
Modal.open('archivedBoards'); Modal.open('archivedBoards');
}, },
'click .js-invite-people': Popup.open('invitePeople'),
'click .js-edit-profile': Popup.open('editProfile'), 'click .js-edit-profile': Popup.open('editProfile'),
'click .js-change-settings': Popup.open('changeSettings'), 'click .js-change-settings': Popup.open('changeSettings'),
'click .js-change-avatar': Popup.open('changeAvatar'), '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({ Template.editProfilePopup.helpers({
allowEmailChange() { allowEmailChange() {
Meteor.call('AccountSettings.allowEmailChange', (_, result) => { Meteor.call('AccountSettings.allowEmailChange', (_, result) => {

View file

@ -1095,5 +1095,7 @@
"remove-team-from-table": "Are you sure you want to remove this team from the board ?", "remove-team-from-table": "Are you sure you want to remove this team from the board ?",
"confirm-btn": "Confirm", "confirm-btn": "Confirm",
"remove-btn": "Remove", "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"
} }

View file

@ -1091,8 +1091,10 @@
"cardDetailsPopup-title": "Détails de la carte", "cardDetailsPopup-title": "Détails de la carte",
"add-teams": "Ajouter des équipes", "add-teams": "Ajouter des équipes",
"add-teams-label": "Les équipes ajoutées sont affichées ci-dessous :", "add-teams-label": "Les équipes ajoutées sont affichées ci-dessous :",
"remove-team-from-table": "Voulez-vous vraiment supprimer cette équipe du tableau ?", "remove-team-from-table": "Are you sure you want to remove this team from the board ?",
"confirm-btn": "Confirmer", "confirm-btn": "Confirm",
"remove-btn": "Supprimer", "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"
} }

View file

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

View file

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