884 lines
29 KiB
JavaScript
Raw Normal View History

2016-09-04 20:16:13 -04:00
/* jshint esversion: 6 */
2016-08-12 12:13:26 -04:00
import {
Meteor
} from 'meteor/meteor';
import {
Mongo
} from 'meteor/mongo';
2016-08-01 19:30:32 +08:00
2017-04-25 03:28:00 -04:00
console.log("Server started!");
2016-08-25 22:35:44 -04:00
// Defines who the admins are - not added
2016-08-29 21:13:35 -04:00
var superadmins = [
2016-08-12 19:10:54 -04:00
"ybq987@gmail.com",
"ksjdragon@gmail.com",
2016-08-31 07:05:23 -04:00
//"aravagarwal3073@gmail.com"
2016-08-12 19:10:54 -04:00
];
2016-08-25 22:35:44 -04:00
2016-08-29 21:13:35 -04:00
var worktype = ["test", "quiz", "project", "normal", "other"];
2016-08-12 21:52:14 -04:00
Meteor.users.allow({
update: function(userId, doc, fields, modifier) {
return Roles.userIsInRole(userId, ['superadmin']);
}
});
2016-08-12 20:11:26 -04:00
Meteor.publish('schools', function() {
return schools.find();
});
2016-11-08 20:19:22 -05:00
Meteor.publish('teachers', function() {
2016-11-18 20:51:04 -05:00
return teachers.find({}, {fields: {name: 1, school: 1}});
});
2016-11-08 20:19:22 -05:00
// Returns the code for classes (for debug)
2016-08-25 22:35:44 -04:00
2016-08-12 20:11:26 -04:00
Meteor.publish('classes', function() {
2016-08-12 20:42:29 -04:00
if (Roles.userIsInRole(this.userId, ['superadmin', 'admin'])) {
2016-08-12 20:11:26 -04:00
return classes.find();
2016-09-03 21:54:39 -04:00
} else if (this.userId !== null) {
// Return user classes and all _public_ classes.
2016-09-01 00:13:17 -04:00
var userprofile = Meteor.users.findOne(this.userId);
if (userprofile !== undefined && userprofile.profile.classes !== undefined) {
2016-08-24 21:09:34 -04:00
return classes.find({
$or: [{
privacy: false
}, {
_id: {
2016-09-01 00:13:17 -04:00
$in: userprofile.profile.classes
2016-08-24 21:09:34 -04:00
}
}]
2016-08-12 20:11:26 -04:00
}, {
2016-08-24 21:09:34 -04:00
// Return non-sensitive fields
fields: {
school: 1,
name: 1,
hour: 1,
teacher: 1,
admin: 1,
status: 1,
privacy: 1,
category: 1,
moderators: 1,
banned: 1,
subscribers: 1
2016-08-12 20:11:26 -04:00
}
2016-08-24 21:09:34 -04:00
});
} else {
2016-09-01 00:13:17 -04:00
Meteor.call('createProfile', this.userId);
2016-09-03 21:34:06 -04:00
return classes.find({
privacy: false,
status: true,
}, {
// Return non-sensitive fields
fields: {
school: 1,
name: 1,
hour: 1,
teacher: 1,
admin: 1,
status: 1,
privacy: 1,
category: 1,
moderators: 1,
banned: 1,
subscribers: 1
}
2016-09-03 21:34:06 -04:00
});
2016-08-24 21:09:34 -04:00
}
2016-08-12 20:11:26 -04:00
}
});
// Gives everything in work if superadmin
2016-08-25 22:35:44 -04:00
2016-08-12 20:11:26 -04:00
Meteor.publish('work', function() {
2016-08-12 20:42:29 -04:00
if (Roles.userIsInRole(this.userId, ['superadmin', 'admin'])) {
2016-08-12 20:11:26 -04:00
return work.find();
2016-09-03 21:54:39 -04:00
} else if (this.userId !== null) {
2016-09-01 00:13:17 -04:00
var userprofile = Meteor.users.findOne(this.userId);
if (userprofile !== undefined && userprofile.profile.classes !== undefined) {
2016-08-26 21:32:17 -04:00
return work.find({
// Only return work of enrolled classes
class: {
2016-09-11 18:47:50 -04:00
$in: userprofile.profile.classes
2016-08-26 21:32:17 -04:00
}
});
} else {
2016-09-01 00:13:17 -04:00
Meteor.call('createProfile', this.userId);
2016-09-03 21:36:33 -04:00
return work.find({
2016-09-03 21:34:06 -04:00
_id: null
});
2016-08-26 21:32:17 -04:00
}
2016-08-24 21:15:16 -04:00
2016-08-12 20:11:26 -04:00
}
});
2016-08-25 22:35:44 -04:00
//Returns issues in sites (not implemented on client)
Meteor.publish('requests', function() {
if (Roles.userIsInRole(this.userId, ['superadmin', 'admin'])) {
return requests.find();
} else {
2016-08-24 21:09:34 -04:00
return requests.find({
requestor: this.userId
});
}
});
Meteor.publish("personalUser", function() {
return Meteor.users.find({_id: this.userId}, {
fields: {
'services': 1,
'profile': 1
}
});
});
2016-08-25 22:35:44 -04:00
//Publishes every-persons email and user-ids
2016-08-15 20:55:21 -04:00
Meteor.publish('users', function() {
if (Roles.userIsInRole(this.userId, ['superadmin', 'admin'])) {
return Meteor.users.find();
} else {
2016-08-18 06:54:22 -04:00
return Meteor.users.find({}, {
2016-08-23 21:35:10 -04:00
// Only return necessary fields
2016-08-18 06:54:22 -04:00
fields: {
'services.google.email': 1,
'services.google.picture': 1,
'profile.grade': 1,
'profile.name': 1,
'profile.school': 1
2016-08-18 06:54:22 -04:00
}
});
2016-08-15 20:55:21 -04:00
}
});
2016-08-23 21:35:10 -04:00
// Allows only superadmins to edit collections from client
Security.permit(['insert', 'update', 'remove']).collections([schools, classes, work]).ifHasRole('superadmin');
2016-11-18 20:57:40 -05:00
Accounts.validateLoginAttempt(function(info) {
var user = info.user;
2017-02-08 00:58:37 -05:00
if(info.user) {
if(user.banned) throw new Meteor.Error(403, 'You are banned');
}
2016-11-18 20:57:40 -05:00
return true;
});
2016-11-18 19:54:39 -05:00
2016-08-23 21:35:10 -04:00
2016-10-25 21:05:56 -04:00
var errors = [
2016-10-28 22:24:09 -04:00
"Success.", // 0
2016-10-25 21:05:56 -04:00
["unauthorized", "You have too many unverified classes right now. Try again later."],
["matching", "The school you have requested does not exist."],
["matching", "This teacher is already teaching a class elsewhere!"],
["unauthorized", "You are not an administrator of this class."],
["matching", "This class does not exist."], // 5
2016-10-25 21:05:56 -04:00
["matching", "This user does not exist"],
["matching", "This user is banned from this class"],
["matching", "This user is not enrolled in the class"],
["trivial", "The past is in the past! Let it go!"],
["trivial", "This name is too long"], // 10
2016-10-25 21:05:56 -04:00
["trivial", "This description is too long"],
["unauthorized", "You are not the creator of this work."],
["trivial", "This comment is too long."],
["unauthorized", "Incorrect code, try again."],
["trivial", "You are already enrolled in this class."], // 15
2016-10-25 21:05:56 -04:00
["trivial", "This request is too long."],
["trivial", "Not a valid work type"],
2016-10-28 22:24:09 -04:00
["unauthorized", "This class has not been approved yet"],
2016-11-08 20:19:22 -05:00
["matching", "This teacher already exists!"],
2016-11-18 20:51:04 -05:00
["trivial", "Please put the full name!"], // 20
2016-10-25 21:05:56 -04:00
2016-11-07 21:34:30 -05:00
["unauthorized", "Sorry, you are not authorized to complete this action."], // n - 2
["other", "Error could not be processed"] // n - 1
2016-10-25 21:05:56 -04:00
];
2016-10-25 22:06:46 -04:00
function securityCheck(checklist, input) {
var error;
2016-10-25 22:06:46 -04:00
var results = [];
for(var i = 0; i < checklist.length - 1; i++) {
var checkpoint = checklist[i];
error = 0;
2016-10-25 22:06:46 -04:00
if (Array.isArray(checkpoint)) {
var arrayresult = securityCheck(checkpoint, input);
results.push(arrayresult);
2016-10-25 22:06:46 -04:00
continue;
}
2016-10-25 21:05:56 -04:00
switch (checkpoint) {
// Superadmin
case -1:
2016-10-28 22:24:09 -04:00
if (!Roles.userIsInRole(Meteor.userId(), ['superadmin'])) error = errors.length - 2;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Any admin
case 1:
2016-11-02 23:03:24 -04:00
if (!Roles.userIsInRole(Meteor.userId(), ['superadmin', 'admin'])) error = errors.length - 2;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Unverified classes
case 2:
2016-10-30 22:34:11 -04:00
if (classes.find({status:false, admin: Meteor.userId()}).fetch().length > 8) error = 1;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// School existence
case 3:
if (!schools.findOne({name: input.school})) error = 2;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Duplicate classes
case 4:
2016-11-08 20:19:22 -05:00
if (classes.findOne({school: input.school, teacher: input.teacher, status: true, privacy: false, hour: input.hour}) || (input.teacher === "" && input.hour === "")) error = 3;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Class admin
case 5:
2016-10-28 22:24:09 -04:00
if (input.admin !== Meteor.userId()) error = 4;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Not banned
case 8:
if (_.contains(input.banned, input.userId)) error = 7;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Subscribed
case 9:
if (!_.contains(input.subscribers, input.userId)) error = 8;
2016-10-25 22:06:46 -04:00
break;
2016-10-25 21:05:56 -04:00
// Date is today or onward
case 10:
var ref = new Date();
ref.setHours(0, 0, 0, 0);
ref = ref.getTime();
if (!(input.dueDate instanceof Date) || ref > input.dueDate.getTime()) error = 9;
2016-10-25 22:06:46 -04:00
break;
// Name too long
2016-10-25 21:05:56 -04:00
case 11:
2016-10-28 22:24:09 -04:00
if (typeof input.name !== "string" || input.name.length > 50) error = 10;
2016-10-25 22:06:46 -04:00
break;
// Description too long
2016-10-25 21:05:56 -04:00
case 12:
if ((typeof input.description !== "string" || input.description.length > 300) && input.description !== undefined) error = 11;
2016-10-25 22:06:46 -04:00
break;
2016-10-28 22:24:09 -04:00
// Moderator of class
2016-10-25 21:05:56 -04:00
case 13:
2016-10-28 22:24:09 -04:00
if (!_.contains(input.moderators, Meteor.userId())) error = 4;
2016-10-25 22:06:46 -04:00
break;
// Creator of work
2016-10-25 21:05:56 -04:00
case 14:
if (Meteor.userId() !== input.creator) error = 12;
2016-10-25 22:06:46 -04:00
break;
// Comment too long
2016-10-25 21:05:56 -04:00
case 15:
2016-10-28 23:47:26 -04:00
if (typeof input.comment !== "string" || input.comment.length > 200) error = 13;
2016-10-25 22:06:46 -04:00
break;
// Private class
2016-10-25 21:05:56 -04:00
case 16:
if (input.class !== Meteor.userId()) error = errors.length - 1;
2016-10-25 22:06:46 -04:00
break;
// Code is wrong
2016-10-25 21:05:56 -04:00
case 17:
2016-10-28 22:24:09 -04:00
if (input.code !== input.pass && input.privacy) error = 14;
2016-10-25 22:06:46 -04:00
break;
// Check if user is already enrolled
2016-10-25 21:05:56 -04:00
case 18:
2016-10-28 22:24:09 -04:00
if (_.contains(input.subscribers, input.userId)) error = 15;
2016-10-25 22:06:46 -04:00
break;
// Request too long
2016-10-25 21:05:56 -04:00
case 19:
if (typeof input.content !== "string" || input.content.length > 500) error = 16;
2016-10-25 22:06:46 -04:00
break;
// Is valid work type
case 20:
if (!_.contains(worktype, input.type)) error = 17;
break;
2016-10-28 22:24:09 -04:00
// Tracking in moderators or banned
case 21:
if (!_.contains(["moderators", "banned"], input.userlist)) error = errors.length - 1;
break;
// Editing list moderators
case 22:
if (input.userlist === "moderators") error = errors.length - 2;
break;
// Toggling possible toggleWork
case 23:
2016-10-28 23:23:07 -04:00
if(!_.contains(["confirmations", "reports", "done"], input.toggle)) error = errors.length - 1;
2016-10-28 22:24:09 -04:00
break;
// Class is approved
case 24:
if (!input.status) error = 18;
break;
// User is logged in
case 25:
if (Meteor.userId() === null) error = errors.length - 1;
2016-10-28 22:24:09 -04:00
break;
2016-11-07 21:34:30 -05:00
// New Teacher doesn't already exist
case 26:
2016-11-18 20:51:04 -05:00
if (teachers.find({name: input.teachername, school: input.school}).fetch().length > 0) error = 19;
2016-11-07 21:34:30 -05:00
break;
2016-11-18 20:51:04 -05:00
// Not banning admin
2016-11-18 19:54:39 -05:00
case 27:
if (Roles.userIsInRole(input.userId, ['superadmin', 'admin'])) error = errors.length - 2;
break;
2016-11-08 20:19:22 -05:00
// Incorrect teacher format
2016-11-18 20:51:04 -05:00
case 28:
2017-04-17 03:48:17 -04:00
if (input.teachername.split(" ").length < 2 && teachername !== "") error = 20;
2016-11-08 20:19:22 -05:00
break;
2016-10-25 21:05:56 -04:00
}
2016-10-25 22:06:46 -04:00
results.push(error);
2016-10-25 21:05:56 -04:00
}
error = results.find(function(result){return result !== 0;});
2017-04-19 01:45:46 -04:00
if (checklist[checklist.length - 1] && error !== undefined) {
return error;
} else if (results.find(function(result){return result === 0;}) === undefined) {
return results[0];
} else {
return 0;
}
2016-10-25 21:05:56 -04:00
}
2016-08-08 20:55:02 -04:00
Meteor.methods({
// Stuff that is accessible in client
2016-08-26 21:32:17 -04:00
// Generates private codes for classes - like google classroom
'genCode': function(privacy) {
if (privacy) {
var currcode = Math.random().toString(36).substr(2, 6);
while (classes.findOne({
2016-08-31 07:05:23 -04:00
code: currcode
})) {
currcode = Math.random().toString(36).substr(2, 6);
}
return currcode;
} else {
return "";
2016-08-18 19:08:58 -04:00
}
2016-08-12 12:13:26 -04:00
},
2016-08-23 21:35:10 -04:00
// School Functions
2016-08-25 22:35:44 -04:00
// Ability to create schools for selections
2016-08-12 12:13:26 -04:00
'createSchool': function(schoolname) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, true]);
if (!security) {
2016-08-12 12:13:26 -04:00
schools.insert({
2016-08-25 21:57:22 -04:00
name: schoolname
2016-08-12 12:13:26 -04:00
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 12:13:26 -04:00
}
},
// Deletes school
2016-08-12 19:10:54 -04:00
'deleteSchool': function(schoolId) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, true]);
if (!security) {
2016-08-12 19:10:54 -04:00
schools.remove({
_id: schoolId
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 19:10:54 -04:00
}
2016-08-12 12:13:26 -04:00
},
2016-08-23 21:35:10 -04:00
// Class Functions
2016-08-12 12:13:26 -04:00
'createClass': function(input) {
classes.schema.validate(input);
2016-10-28 22:24:09 -04:00
var security = securityCheck([2, 3, 4, true],
input);
if (!security) {
input.status = Roles.userIsInRole(Meteor.userId(), ['superadmin', 'admin']);
input.admin = Meteor.userId();
2017-04-17 03:48:17 -04:00
Meteor.call('genCode', input.privacy, function(error, result) {
2016-10-28 22:24:09 -04:00
input.code = result;
2017-04-17 03:48:17 -04:00
if (input.category != "class" && input.category != "club") {
input.category = "other";
}
input.subscribers = [];
input.moderators = [];
input.banned = [];
classes.insert(input, function(err, result) {
Meteor.call('joinClass', [result, input.code]);
});
2016-10-28 22:24:09 -04:00
});
2016-08-12 12:13:26 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-15 22:32:00 -04:00
}
},
2016-10-23 21:42:18 -04:00
'approveClass': function(classId) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, true]);
if (!security) {
var currentclass = classes.findOne({
2016-10-23 21:42:18 -04:00
_id: classId
});
classes.update({
2016-10-23 21:42:18 -04:00
_id: classId
}, {
$set: {
status: !currentclass.status
2016-10-23 21:42:18 -04:00
}
});
2016-10-28 22:24:09 -04:00
} else {
throw new Meteor.Error(errors[security]);
2016-10-23 21:42:18 -04:00
}
},
2016-08-27 09:34:23 -04:00
// For class admins to get code
'getCode': function(classId) {
2016-09-07 01:12:30 -04:00
var foundclass = classes.findOne({
2016-08-27 09:47:59 -04:00
_id: classId
});
2016-10-28 22:24:09 -04:00
var security = securityCheck([5, true], foundclass);
if (!security) {
2016-09-07 18:11:36 -04:00
return (foundclass.code === '') ? "None" : foundclass.code;
2016-08-27 09:34:23 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-27 09:34:23 -04:00
}
},
2016-08-15 22:32:00 -04:00
'changeAdmin': function(input) {
var userId = input[0];
var classId = input[1];
2016-08-18 06:54:22 -04:00
var found = Meteor.users.find({
_id: userId
2016-08-18 06:54:22 -04:00
});
var foundclass = classes.find({
_id: classId
2016-08-18 06:54:22 -04:00
});
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, [5, 8, 9, true], false],
2017-02-09 09:01:18 -05:00
Object.assign({}, foundclass || {}, {userId: found._id}));
2016-10-28 22:24:09 -04:00
if (!security) {
2016-08-18 06:54:22 -04:00
classes.update({
_id: classId
2016-08-18 06:54:22 -04:00
}, {
$set: {
admin: userId
2016-08-18 06:54:22 -04:00
}
});
2016-08-15 22:32:00 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-15 22:32:00 -04:00
}
},
2016-08-25 22:35:44 -04:00
// Allows someone to manage the class
2016-08-15 22:32:00 -04:00
'trackUserInClass': function(input) {
var userId = input[0];
var classId = input[1];
var userlist = input[2];
2016-08-18 06:54:22 -04:00
var foundclass = classes.findOne({
_id: classId
2016-08-18 06:54:22 -04:00
});
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, [[5, [13, 22, true], false], 9, 21, true], false],
2017-02-09 09:01:18 -05:00
Object.assign({}, foundclass, {userlist: userlist}));
2016-10-28 22:24:09 -04:00
if (!security) {
if (_.contains(foundclass[userlist], userId)) {
foundclass[userlist] = _.without(foundclass[userlist], userId);
} else {
foundclass[userlist] = foundclass[userlist].concat(userId);
}
2016-08-18 06:54:22 -04:00
classes.update({
_id: classId
2016-08-18 06:54:22 -04:00
}, {
2016-10-28 22:24:09 -04:00
$set: foundclass
2016-08-18 06:54:22 -04:00
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 12:13:26 -04:00
}
},
2016-10-28 22:24:09 -04:00
2016-08-12 12:13:26 -04:00
'deleteClass': function(classid) {
2016-08-12 21:52:14 -04:00
var found = classes.findOne({
2016-08-12 12:13:26 -04:00
_id: classid
});
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, 5, false],
found);
if (!security) {
for (var i = 0; i < found.subscribers.length; i++) {
2016-08-18 06:54:22 -04:00
var current = Meteor.users.findOne({
_id: found.subscribers[i]
}).profile;
2016-08-17 22:32:33 -04:00
var index = current.classes.indexOf(classid);
current.classes.splice(index, 1);
Meteor.users.update({
_id: found.subscribers[i]
}, {
$set: {
profile: current
}
});
2016-08-15 22:32:00 -04:00
}
2016-08-12 12:13:26 -04:00
classes.remove({
_id: classid
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 12:13:26 -04:00
}
},
2016-08-23 21:35:10 -04:00
// Work Functions
2016-08-12 12:13:26 -04:00
'createWork': function(input) {
2016-08-12 21:52:14 -04:00
input.creator = Meteor.userId();
2017-02-26 19:27:50 -05:00
if(input.description) input.description = input.description.trim();
2016-08-12 12:13:26 -04:00
work.schema.validate(input);
2016-08-13 17:26:07 -04:00
var found = classes.findOne({
2016-08-12 12:13:26 -04:00
_id: input.class
2016-08-09 17:10:08 -04:00
});
var security = securityCheck([[[8, 9, true], 16, false], 10, 20, 11, 12, true],
2017-02-09 09:01:18 -05:00
Object.assign({}, found || {}, input, {userId: Meteor.userId()}));
if (!security) {
2017-04-25 22:27:30 -04:00
input = Object.assign({}, input, {confirmations: [Meteor.userId()], reports: [], done: [], comments: []});
2016-08-12 12:13:26 -04:00
work.insert(input);
2016-08-21 10:02:07 -04:00
} else {
throw new Meteor.Error(errors[security]);
2016-08-12 12:13:26 -04:00
}
2016-08-10 17:42:07 -04:00
2016-08-12 12:13:26 -04:00
},
2016-08-12 21:52:14 -04:00
'editWork': function(change) {
2016-09-03 21:54:39 -04:00
var currentwork = work.findOne({
_id: change._id
});
2016-08-13 13:32:40 -04:00
var currentclass = classes.findOne({
2016-09-03 21:34:06 -04:00
_id: currentwork.class
2016-08-13 13:32:40 -04:00
});
2017-02-26 19:27:50 -05:00
if(change.description) change.description = change.description.trim();
2017-04-25 02:46:06 -04:00
var security = securityCheck([[1, 16, 13, 14, 5, false], 11, 12, 10, 20, true],
2017-02-09 09:01:18 -05:00
Object.assign({}, currentclass || {}, currentwork, {description: change.description, name: change.name, dueDate: change.dueDate, type: change.type}));
2017-04-19 01:45:46 -04:00
2016-10-28 22:24:09 -04:00
if (!security) {
2016-09-03 21:54:39 -04:00
work.update({
_id: change._id
}, {
$set: {
name: change.name,
dueDate: change.dueDate,
description: change.description,
attachments: change.attachments,
type: change.type
}
});
2016-08-12 21:52:14 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 21:52:14 -04:00
}
},
'addComment': function(input) {
2016-08-22 16:52:04 -04:00
var comment = input[0];
2016-08-13 13:32:40 -04:00
var workobject = work.findOne({
_id: input[1]
});
var currentclass = classes.findOne({
_id: workobject.class
});
2016-08-13 16:10:01 -04:00
var user = Meteor.userId();
2016-10-28 22:24:09 -04:00
var security = securityCheck([15, [16, [8, 9, true], false]],
2017-02-09 09:01:18 -05:00
Object.assign({}, workobject, currentclass || {}, {userId: user, comment: comment}));
2016-10-28 22:24:09 -04:00
if (!security) {
2016-08-29 21:13:35 -04:00
var commentInfo = {
2016-10-28 23:23:07 -04:00
"comment": comment,
2016-08-31 07:05:23 -04:00
"user": user,
"date": new Date()
};
2016-10-28 23:23:07 -04:00
var newchain = workobject.comments.concat(commentInfo);
2016-08-13 13:32:40 -04:00
work.update({
_id: input[1]
}, {
$set: {
2016-10-28 23:23:07 -04:00
comments: newchain
2016-08-13 13:32:40 -04:00
}
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 21:52:14 -04:00
}
},
2016-08-26 21:32:17 -04:00
2016-08-12 22:35:28 -04:00
'toggleWork': function(input) {
2016-08-13 13:32:40 -04:00
var workobject = work.findOne({
_id: input[0]
});
var currentclass = classes.findOne({
_id: workobject.class
});
2016-10-28 23:23:07 -04:00
var security = securityCheck([[16, 9, false], 23, true],
2017-02-09 09:01:18 -05:00
Object.assign({}, workobject, currentclass || {}, {userId: Meteor.userId(), toggle: input[1]}));
2016-10-28 22:24:09 -04:00
if (!security) {
2017-05-02 20:51:30 -04:00
var type = input[1];
var index = workobject[type].indexOf(Meteor.userId());
var cIndex = workobject["confirmations"].indexOf(Meteor.userId());
var rIndex = workobject["reports"].indexOf(Meteor.userId());
var dIndex = workobject["done"].indexOf(Meteor.userId());
switch(type) {
case "confirmations":
if(index === -1) { // User hasn't confirmed.
workobject[type] = workobject[type].concat(Meteor.userId());
if(rIndex !== -1) workobject["reports"].splice(rIndex, 1);
} else { // Used has confirmed.
workobject[type].splice(index, 1);
}
break;
case "reports":
if(index === -1) { // User hasn't reported.
workobject[type] = workobject[type].concat(Meteor.userId());
if(cIndex !== -1) workobject["confirmations"].splice(cIndex, 1);
} else { // Used has reported.
workobject[type].splice(index, 1);
}
break;
case "done":
if(index === -1) { // User isn't done.
workobject[type] = workobject[type].concat(Meteor.userId());
if(cIndex === -1) workobject["confirmations"] = workobject["confirmations"].concat(Meteor.userId());
} else { // User is done
workobject[type].splice(index, 1);
}
break;
2016-08-12 22:35:28 -04:00
}
2016-08-13 13:32:40 -04:00
work.update({
2016-08-28 18:41:35 -04:00
_id: input[0]
2016-08-13 13:32:40 -04:00
}, {
$set: workobject
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 21:52:14 -04:00
}
},
2016-08-12 21:00:32 -04:00
'deleteWork': function(workId) {
2016-09-22 00:36:08 -04:00
var currentwork = work.findOne({
2016-09-03 21:54:39 -04:00
_id: workId
});
2016-08-13 13:32:40 -04:00
var currentclass = classes.findOne({
2016-09-03 21:34:06 -04:00
_id: currentwork.class
2016-08-13 13:32:40 -04:00
});
2017-04-25 02:46:06 -04:00
var security = securityCheck([1, 16, 13, 14, 5, false],
2017-02-09 09:01:18 -05:00
Object.assign({}, currentwork, currentclass || {}));
2016-10-28 22:24:09 -04:00
if (!security) {
2016-08-12 21:52:14 -04:00
work.remove({
_id: workId
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 21:00:32 -04:00
}
2016-08-12 12:13:26 -04:00
},
2016-08-23 21:35:10 -04:00
// User Functions
2016-08-12 12:13:26 -04:00
'editProfile': function(change) {
2016-10-11 06:40:01 -04:00
var refyear = new Date().getUTCFullYear();
2016-08-12 21:52:14 -04:00
var current = Meteor.user().profile;
2016-09-06 20:56:31 -04:00
current = {
"__proto__": current.__proto__,
"school": change.school,
"grade": change.grade,
2016-09-10 12:12:15 -04:00
"classes": current.classes,
2016-09-07 18:11:36 -04:00
"preferences": change.preferences,
"name": current.name,
"complete": change.complete
2016-09-06 20:56:31 -04:00
};
2016-10-29 00:00:16 -04:00
if ((current.grade <= refyear || current.grade >= refyear + 4) && current.grade !== 0) {
2016-10-11 06:40:01 -04:00
current.grade = refyear;
}
Meteor.users.update({
_id: Meteor.userId()
}, {
$set: {
profile: current
}
});
2016-08-12 12:13:26 -04:00
},
2016-09-10 12:12:15 -04:00
'reorderClasses': function(newOrder) {
var current = Meteor.user().profile;
2016-09-19 23:13:00 -04:00
if (newOrder.every(elem => _.contains(current.classes, elem)) &&
newOrder.length === current.classes.length) {
2016-09-10 12:12:15 -04:00
current.classes = newOrder;
Meteor.users.update({
_id: Meteor.userId()
}, {
$set: {
profile: current
}
});
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[errors.length - 1]);
2016-09-10 12:12:15 -04:00
}
},
2016-08-24 21:09:34 -04:00
'createProfile': function(userId) {
2016-10-10 22:22:47 -04:00
var currentuser = Meteor.users.findOne({
2016-08-24 21:09:34 -04:00
_id: userId
2016-10-10 22:22:47 -04:00
});
var current = currentuser.profile;
2016-09-11 18:47:50 -04:00
current.classes = [userId];
current.preferences = {
2016-10-18 23:53:20 -04:00
"theme": themeColors.lux,
"mode": "classes",
"timeHide": 1,
2016-09-16 09:10:56 -04:00
"done": true,
"hideReport": true
};
2016-10-10 23:06:57 -04:00
2016-10-23 16:19:08 -04:00
if (_.contains(superadmins, currentuser.services.google.email)) {
2016-10-10 23:06:57 -04:00
Roles.addUsersToRoles(userId, 'superadmin');
Roles.addUsersToRoles(userId, 'admin');
2016-10-22 16:29:21 -04:00
}
2016-08-24 21:09:34 -04:00
Meteor.users.update({
_id: userId
}, {
$set: {
profile: current
}
});
},
2016-08-12 12:13:26 -04:00
'joinClass': function(input) {
2016-08-12 21:52:14 -04:00
var change = input[0];
var pass = input[1];
var found = classes.findOne({
2016-10-10 22:22:47 -04:00
_id: change
2016-08-12 12:13:26 -04:00
});
2016-10-28 22:24:09 -04:00
var security = securityCheck([17, [5, 24, false], 18, true],
2017-02-09 09:01:18 -05:00
Object.assign({}, found, {userId: Meteor.userId(), pass: pass}));
2016-10-28 22:24:09 -04:00
if (!security) {
2016-08-29 21:13:35 -04:00
var foundsubs = found.subscribers;
2016-08-18 06:54:22 -04:00
classes.update({
_id: found._id
}, {
$set: {
2016-08-20 20:56:05 -04:00
subscribers: foundsubs.concat(Meteor.userId())
2016-08-18 06:54:22 -04:00
}
});
2017-04-19 01:45:46 -04:00
var current = Meteor.users.findOne({_id: Meteor.userId()}).profile;
current.classes.push(change);
2016-08-12 12:13:26 -04:00
Meteor.users.update({
_id: Meteor.userId()
}, {
$set: {
profile: current
}
});
2016-08-21 10:02:07 -04:00
return true;
2016-08-09 18:23:02 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-09 18:23:02 -04:00
}
2016-08-12 12:13:26 -04:00
},
2016-08-17 18:45:50 -04:00
'joinPrivateClass': function(input) {
2016-08-18 06:54:22 -04:00
var found = classes.findOne({
status: true,
privacy: true,
code: input
});
var current = Meteor.user().profile;
if (found !== undefined && input !== undefined &&
!_.contains(current.classes, found._id)) {
2016-08-18 06:54:22 -04:00
classes.update({
_id: found._id
}, {
$set: {
subscribers: found.subscribers.concat(Meteor.userId())
}
});
current.classes = current.classes.concat(found._id);
2016-08-18 06:54:22 -04:00
Meteor.users.update({
_id: Meteor.userId()
}, {
$set: {
profile: current
}
});
return true;
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[14]);
2016-08-17 18:45:50 -04:00
}
},
2016-08-12 12:13:26 -04:00
'leaveClass': function(change) {
if (Meteor.user() !== null) {
2016-08-21 22:48:15 -04:00
var current = Meteor.user().profile;
var index = current.classes.indexOf(change);
2016-08-12 12:13:26 -04:00
if (index >= 0) {
if (classes.findOne({
2016-08-31 07:05:23 -04:00
_id: change
}).admin != Meteor.userId()) {
2016-08-21 22:48:15 -04:00
current.classes.splice(index, 1);
2016-08-12 12:13:26 -04:00
Meteor.users.update({
_id: Meteor.userId()
}, {
$set: {
profile: current
}
});
2016-08-18 06:54:22 -04:00
var newstudents = classes.findOne({
_id: change
}).subscribers.splice(Meteor.userId(), 1);
classes.update({
_id: change
}, {
$set: {
subscribers: newstudents
}
});
2016-08-12 12:13:26 -04:00
} else {
2016-08-31 23:21:53 -04:00
throw new Meteor.Error("unauthorized", "You are currently the admin of this class. Transfer ownership in order to leave this class.");
2016-08-12 12:13:26 -04:00
}
}
2016-08-09 18:03:31 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[errors.length - 1]);
2016-08-12 12:13:26 -04:00
}
2016-08-12 19:10:54 -04:00
},
2016-08-23 21:35:10 -04:00
// Admin Functions
2016-08-12 19:10:54 -04:00
'createAdmin': function(userId) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([-1, true]);
if (!security) {
2016-08-12 19:10:54 -04:00
Roles.addUsersToRoles(userId, ['admin']);
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 19:10:54 -04:00
}
},
'deleteAdmin': function(userId) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([-1, true]);
if (!security) {
2016-08-12 19:10:54 -04:00
Roles.removeUsersToRoles(userId, ['admin']);
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
2016-08-12 19:10:54 -04:00
}
},
'createRequest': function(request) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([19, 25, true],
request);
if (!security) {
requests.insert({
requestor: Meteor.userId(),
2016-08-31 20:33:25 -04:00
request: request.content,
info: request.info,
timeRequested: new Date()
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
}
},
'deleteRequest': function(requestId) {
2016-10-28 22:24:09 -04:00
var security = securityCheck([1, true]);
if (!security) {
2016-08-24 21:09:34 -04:00
requests.remove({
_id: requestId
});
2016-08-21 10:02:07 -04:00
} else {
2016-10-28 22:24:09 -04:00
throw new Meteor.Error(errors[security]);
}
2016-11-07 21:34:30 -05:00
},
'createTeacher': function(teacherName, schoolName) {
2016-11-18 20:51:04 -05:00
teachers.schema.validate({name: teacherName, school: schoolName});
var security = securityCheck([26, 28, 3, true], {teachername: teacherName, school: schoolName});
2016-11-07 21:34:30 -05:00
if (!security) {
teachers.insert({
name: teacherName,
2016-11-18 20:51:04 -05:00
school: schoolName,
creator: Meteor.userId()
2016-11-07 21:34:30 -05:00
});
} else {
throw new Meteor.Error(errors[security]);
}
2016-11-18 19:54:39 -05:00
},
'ban': function(studentId) {
var security = securityCheck([1, 27, true], {userId: studentId});
if (!security) {
Meteor.users.update({_id: studentId}, {$set: {banned: true}});
} else {
throw new Meteor.Error(errors[security]);
}
},
'unban': function(studentId) {
var security = securityCheck([1, true], {userId: studentId});
if (!security) {
Meteor.users.update({_id: studentId}, {$set: {banned: false}});
} else {
throw new Meteor.Error(errors[security]);
}
2016-08-09 18:03:31 -04:00
}
});