summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorlkisme <lkisme@me.com>2017-02-24 22:10:38 +0800
committerlkisme <lkisme@me.com>2017-02-24 22:10:38 +0800
commit1dfb6ef477dba4d0faf4bf86026647f43fb2f5f6 (patch)
tree2c97395901ac5789975a65d5efc6eaf0e37c1e5d /models
parent29fdfb9c886f1a906a27398fd546ad6cdb929ff9 (diff)
downloadwekan-1dfb6ef477dba4d0faf4bf86026647f43fb2f5f6.tar.gz
wekan-1dfb6ef477dba4d0faf4bf86026647f43fb2f5f6.tar.bz2
wekan-1dfb6ef477dba4d0faf4bf86026647f43fb2f5f6.zip
Admin panel:
Only invited user can register in strict mode, Set mail server in admin panel, Switch strict mode in admin panel, Invite people to system in admin panel
Diffstat (limited to 'models')
-rw-r--r--models/invitationCodes.js45
-rw-r--r--models/settings.js111
-rw-r--r--models/users.js45
3 files changed, 200 insertions, 1 deletions
diff --git a/models/invitationCodes.js b/models/invitationCodes.js
new file mode 100644
index 00000000..5761977a
--- /dev/null
+++ b/models/invitationCodes.js
@@ -0,0 +1,45 @@
+InvitationCodes = new Mongo.Collection('invitation_codes');
+
+InvitationCodes.attachSchema(new SimpleSchema({
+ code: {
+ type: String,
+ },
+ email: {
+ type: String,
+ unique: true,
+ regEx: SimpleSchema.RegEx.Email,
+ },
+ createdAt: {
+ type: Date,
+ denyUpdate: false,
+ },
+ // always be the admin if only one admin
+ authorId: {
+ type: String,
+ },
+ boardsToBeInvited: {
+ type: [String],
+ optional: true,
+ },
+ valid: {
+ type: Boolean,
+ defaultValue: true,
+ },
+}));
+
+InvitationCodes.helpers({
+ author(){
+ return Users.findOne(this.authorId);
+ },
+});
+
+// InvitationCodes.before.insert((userId, doc) => {
+ // doc.createdAt = new Date();
+ // doc.authorId = userId;
+// });
+
+if (Meteor.isServer) {
+ Boards.deny({
+ fetch: ['members'],
+ });
+}
diff --git a/models/settings.js b/models/settings.js
new file mode 100644
index 00000000..77bf8d24
--- /dev/null
+++ b/models/settings.js
@@ -0,0 +1,111 @@
+Settings = new Mongo.Collection('settings');
+
+Settings.attachSchema(new SimpleSchema({
+ strict: {
+ type: Boolean,
+ },
+ 'mailServer.username': {
+ type: String,
+ },
+ 'mailServer.password': {
+ type: String,
+ },
+ 'mailServer.host': {
+ type: String,
+ },
+ 'mailServer.port': {
+ type: String,
+ },
+ 'mailServer.from': {
+ type: String,
+ defaultValue: 'Kanban',
+ },
+ createdAt: {
+ type: Date,
+ denyUpdate: true,
+ },
+ modifiedAt: {
+ type: Date,
+ },
+}));
+Settings.helpers({
+ mailUrl () {
+ const mailUrl = `smtp://${this.mailServer.username}:${this.mailServer.password}@${this.mailServer.host}:${this.mailServer.port}/`;
+ return mailUrl;
+ },
+});
+Settings.allow({
+ update(userId) {
+ const user = Users.findOne(userId);
+ return user && user.isAdmin;
+ },
+});
+
+Settings.before.update((userId, doc, fieldNames, modifier) => {
+ modifier.$set = modifier.$set || {};
+ modifier.$set.modifiedAt = new Date();
+});
+
+if (Meteor.isServer) {
+ Meteor.startup(() => {
+ const setting = Settings.findOne({});
+ if(!setting){
+ const now = new Date();
+ const defaultSetting = {strict: false, mailServer: {
+ username: '', password:'', host: '', port:'', from: '',
+ }, createdAt: now, modifiedAt: now};
+ Settings.insert(defaultSetting);
+ }
+ const newSetting = Settings.findOne();
+ process.env.MAIL_URL = newSetting.mailUrl();
+ Accounts.emailTemplates.from = newSetting.mailServer.from;
+ });
+
+ function getRandomNum (min, max) {
+ const range = max - min;
+ const rand = Math.random();
+ return (min + Math.round(rand * range));
+ }
+
+ function sendInvitationEmail (_id){
+ const icode = InvitationCodes.findOne(_id);
+ const author = Users.findOne(Meteor.userId());
+ try {
+ const params = {
+ email: icode.email,
+ inviter: Users.findOne(icode.authorId).username,
+ user: icode.email.split('@')[0],
+ icode: icode.code,
+ url: FlowRouter.url('sign-up'),
+ };
+ const lang = author.getLanguage();
+ Email.send({
+ to: icode.email,
+ from: Accounts.emailTemplates.from,
+ subject: TAPi18n.__('email-invite-register-subject', params, lang),
+ text: TAPi18n.__('email-invite-register-text', params, lang),
+ });
+ } catch (e) {
+ throw new Meteor.Error('email-fail', e.message);
+ }
+ }
+
+ Meteor.methods({
+ sendInvitation(emails, boards) {
+ check(emails, [String]);
+ check(boards, [String]);
+ const user = Users.findOne(Meteor.userId());
+ if(!user.isAdmin){
+ throw new Meteor.Error('not-allowed');
+ }
+ emails.forEach((email) => {
+ if (email && SimpleSchema.RegEx.Email.test(email)) {
+ const code = getRandomNum(100000, 999999);
+ InvitationCodes.insert({code, email, boardsToBeInvited: boards, createdAt: new Date(), authorId: Meteor.userId()}, function(err, _id){
+ if(!err && _id) sendInvitationEmail(_id);
+ });
+ }
+ });
+ },
+ });
+}
diff --git a/models/users.js b/models/users.js
index 58513231..c7db8fff 100644
--- a/models/users.js
+++ b/models/users.js
@@ -348,7 +348,7 @@ if (Meteor.isServer) {
if (user._id === inviter._id) throw new Meteor.Error('error-user-notAllowSelf');
} else {
if (posAt <= 0) throw new Meteor.Error('error-user-doesNotExist');
-
+ if (Settings.findOne().strict) throw new Meteor.Error('error-user-notCreated');
const email = username;
username = email.substring(0, posAt);
const newUserId = Accounts.createUser({ username, email });
@@ -389,6 +389,28 @@ if (Meteor.isServer) {
return { username: user.username, email: user.emails[0].address };
},
});
+ Accounts.onCreateUser((options, user) => {
+ const userCount = Users.find().count();
+ if (userCount === 0){
+ user.isAdmin = true;
+ return user;
+ }
+ const strict = Settings.findOne().strict;
+ if (!strict) {
+ return user;
+ }
+
+ const iCode = options.profile.invitationcode | '';
+
+ const invitationCode = InvitationCodes.findOne({code: iCode, valid:true});
+ if (!invitationCode) {
+ throw new Meteor.Error('error-invitation-code-not-exist');
+ }else{
+ user.profile = {icode: options.profile.invitationcode};
+ }
+
+ return user;
+ });
}
if (Meteor.isServer) {
@@ -458,4 +480,25 @@ if (Meteor.isServer) {
});
});
}
+
+ Users.after.insert((userId, doc) => {
+
+ //invite user to corresponding boards
+ const strict = Settings.findOne().strict;
+ if (strict) {
+ const user = Users.findOne(doc._id);
+ const invitationCode = InvitationCodes.findOne({code: user.profile.icode, valid:true});
+ if (!invitationCode) {
+ throw new Meteor.Error('error-user-notCreated');
+ }else{
+ invitationCode.boardsToBeInvited.forEach((boardId) => {
+ const board = Boards.findOne(boardId);
+ board.addMember(doc._id);
+ });
+ user.profile = {invitedBoards: invitationCode.boardsToBeInvited};
+ InvitationCodes.update(invitationCode._id, {$set: {valid:false}});
+ }
+ }
+ });
}
+