summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorLauri Ojansivu <x@xet7.org>2017-03-05 19:58:22 +0200
committerLauri Ojansivu <x@xet7.org>2017-03-05 19:58:22 +0200
commit7c9a30d8fe3ffdf4b56cdc816bfc51f60881d55f (patch)
tree5715424ab1454463a3f8ca458729347bbc014f5b /models
parent7b68f1901e8bd81ec8fbebb60a3f4e057b57d06d (diff)
parent39f2837838ba30ec02bfe9f33c9fa0dfca05d1a6 (diff)
downloadwekan-7c9a30d8fe3ffdf4b56cdc816bfc51f60881d55f.tar.gz
wekan-7c9a30d8fe3ffdf4b56cdc816bfc51f60881d55f.tar.bz2
wekan-7c9a30d8fe3ffdf4b56cdc816bfc51f60881d55f.zip
Fix merge conflict.
Diffstat (limited to 'models')
-rw-r--r--models/invitationCodes.js45
-rw-r--r--models/settings.js116
-rw-r--r--models/users.js45
3 files changed, 205 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..b9ff1b37
--- /dev/null
+++ b/models/settings.js
@@ -0,0 +1,116 @@
+Settings = new Mongo.Collection('settings');
+
+Settings.attachSchema(new SimpleSchema({
+ disableRegistration: {
+ type: Boolean,
+ },
+ 'mailServer.username': {
+ type: String,
+ optional: true,
+ },
+ 'mailServer.password': {
+ type: String,
+ optional: true,
+ },
+ 'mailServer.host': {
+ type: String,
+ optional: true,
+ },
+ 'mailServer.port': {
+ type: String,
+ optional: true,
+ },
+ 'mailServer.from': {
+ type: String,
+ optional: true,
+ defaultValue: 'Wekan',
+ },
+ 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 = {disableRegistration: 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 da2d02ee..06b84fa0 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().disableRegistration) throw new Meteor.Error('error-user-notCreated');
// Set in lowercase email before creating account
const email = username.toLowerCase();
username = email.substring(0, posAt);
@@ -390,6 +390,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 disableRegistration = Settings.findOne().disableRegistration;
+ if (!disableRegistration) {
+ 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) {
@@ -459,4 +481,25 @@ if (Meteor.isServer) {
});
});
}
+
+ Users.after.insert((userId, doc) => {
+
+ //invite user to corresponding boards
+ const disableRegistration = Settings.findOne().disableRegistration;
+ if (disableRegistration) {
+ 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}});
+ }
+ }
+ });
}
+