2016-08-08 11:18:21 +09:00
|
|
|
import Telescope from 'meteor/nova:lib';
|
2016-06-23 15:00:58 +09:00
|
|
|
import Users from './collection.js';
|
|
|
|
|
|
|
|
const adminGroup = {
|
|
|
|
name: "admin",
|
|
|
|
order: 10
|
|
|
|
};
|
|
|
|
|
2016-07-21 09:53:58 +09:00
|
|
|
// check if user can create a new user
|
|
|
|
const canInsert = user => Users.canDo(user, "users.new");
|
|
|
|
|
|
|
|
// check if user can edit a user
|
|
|
|
const canEdit = Users.canEdit;
|
|
|
|
|
|
|
|
// check if user can edit *all* users
|
|
|
|
const canEditAll = user => Users.canDo(user, "users.edit.all");
|
|
|
|
|
2016-10-30 18:25:51 +01:00
|
|
|
const alwaysPublic = user => true;
|
|
|
|
|
2016-11-10 16:00:17 +01:00
|
|
|
/**
|
|
|
|
* @summary User Data schema
|
|
|
|
* @type {SimpleSchema}
|
|
|
|
*/
|
|
|
|
Telescope.schemas.userData = new SimpleSchema({
|
|
|
|
/**
|
|
|
|
Bio (Markdown version)
|
|
|
|
*/
|
|
|
|
bio: {
|
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
control: "textarea",
|
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit,
|
|
|
|
// form: {
|
|
|
|
// rows: 5
|
|
|
|
// }
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
Total comment count
|
|
|
|
*/
|
|
|
|
commentCount: {
|
|
|
|
type: Number,
|
|
|
|
publish: true,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
The name displayed throughout the app. Can contain spaces and special characters, doesn't need to be unique
|
|
|
|
*/
|
|
|
|
displayName: {
|
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
control: "text",
|
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
An array containing comment downvotes
|
|
|
|
*/
|
|
|
|
downvotedComments: {
|
|
|
|
type: [Telescope.schemas.votes],
|
|
|
|
publish: false,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
An array containing posts downvotes
|
|
|
|
*/
|
|
|
|
downvotedPosts: {
|
|
|
|
type: [Telescope.schemas.votes],
|
|
|
|
publish: false,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's email. Modifiable.
|
|
|
|
*/
|
|
|
|
email: {
|
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
regEx: SimpleSchema.RegEx.Email,
|
|
|
|
required: true,
|
|
|
|
control: "text",
|
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit
|
|
|
|
// unique: true // note: find a way to fix duplicate accounts before enabling this
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
A hash of the email, used for Gravatar // TODO: change this when email changes
|
|
|
|
*/
|
|
|
|
emailHash: {
|
|
|
|
type: String,
|
|
|
|
publish: true,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
The HTML version of the bio field
|
|
|
|
*/
|
|
|
|
htmlBio: {
|
|
|
|
type: String,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
optional: true,
|
|
|
|
// form: {
|
|
|
|
// omit: true
|
|
|
|
// },
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's karma
|
|
|
|
*/
|
|
|
|
karma: {
|
|
|
|
type: Number,
|
|
|
|
decimal: true,
|
|
|
|
publish: true,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
Total post count
|
|
|
|
*/
|
|
|
|
postCount: {
|
|
|
|
type: Number,
|
|
|
|
publish: true,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
A blackbox modifiable object to store the user's settings
|
|
|
|
*/
|
|
|
|
// settings: {
|
|
|
|
// type: Object,
|
|
|
|
// optional: true,
|
|
|
|
// editableIf: canEdit,
|
|
|
|
// blackbox: true,
|
|
|
|
// form: {
|
|
|
|
// omit: true
|
|
|
|
// }
|
|
|
|
// },
|
|
|
|
/**
|
|
|
|
The user's profile URL slug // TODO: change this when displayName changes
|
|
|
|
*/
|
|
|
|
slug: {
|
|
|
|
type: String,
|
|
|
|
publish: true,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's Twitter username
|
|
|
|
*/
|
|
|
|
twitterUsername: {
|
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
control: "text",
|
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit,
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
An array containing comments upvotes
|
|
|
|
*/
|
|
|
|
upvotedComments: {
|
|
|
|
type: [Telescope.schemas.votes],
|
|
|
|
publish: false,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
An array containing posts upvotes
|
|
|
|
*/
|
|
|
|
upvotedPosts: {
|
|
|
|
type: [Telescope.schemas.votes],
|
|
|
|
publish: false,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
A link to the user's homepage
|
|
|
|
*/
|
|
|
|
website: {
|
|
|
|
type: String,
|
|
|
|
regEx: SimpleSchema.RegEx.Url,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
optional: true,
|
|
|
|
control: "text",
|
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
Groups
|
|
|
|
*/
|
|
|
|
groups: {
|
|
|
|
type: [String],
|
|
|
|
optional: true,
|
|
|
|
control: "checkboxgroup",
|
|
|
|
insertableIf: canEditAll,
|
|
|
|
editableIf: canEditAll,
|
|
|
|
form: {
|
|
|
|
options: function () {
|
|
|
|
const groups = _.without(_.keys(Users.groups), "anonymous", "default", "admins");
|
|
|
|
return groups.map(group => {return {value: group, label: group};});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2016-06-23 15:00:58 +09:00
|
|
|
/**
|
2016-11-08 18:22:17 +01:00
|
|
|
* @summary Users schema
|
2016-06-23 15:00:58 +09:00
|
|
|
* @type {SimpleSchema}
|
|
|
|
*/
|
2016-11-08 18:22:17 +01:00
|
|
|
Users.schema = new SimpleSchema({
|
|
|
|
_id: {
|
|
|
|
type: String,
|
|
|
|
publish: true,
|
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
2016-11-08 18:22:17 +01:00
|
|
|
username: {
|
|
|
|
type: String,
|
|
|
|
// regEx: /^[a-z0-9A-Z_]{3,15}$/,
|
|
|
|
publish: true,
|
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
|
|
|
},
|
|
|
|
emails: {
|
|
|
|
type: [Object],
|
2016-06-23 15:00:58 +09:00
|
|
|
optional: true
|
|
|
|
},
|
2016-11-08 18:22:17 +01:00
|
|
|
"emails.$.address": {
|
|
|
|
type: String,
|
|
|
|
regEx: SimpleSchema.RegEx.Email,
|
2016-06-23 15:00:58 +09:00
|
|
|
optional: true
|
2016-11-08 18:22:17 +01:00
|
|
|
},
|
|
|
|
"emails.$.verified": {
|
|
|
|
type: Boolean,
|
|
|
|
optional: true
|
|
|
|
},
|
|
|
|
createdAt: {
|
|
|
|
type: Date,
|
|
|
|
publish: true,
|
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
|
|
|
},
|
|
|
|
isAdmin: {
|
|
|
|
type: Boolean,
|
|
|
|
label: "Admin",
|
|
|
|
control: "checkbox",
|
|
|
|
optional: true,
|
|
|
|
insertableIf: canEditAll,
|
|
|
|
editableIf: canEditAll,
|
|
|
|
viewableIf: alwaysPublic,
|
|
|
|
group: adminGroup
|
|
|
|
},
|
|
|
|
profile: {
|
|
|
|
type: Object,
|
|
|
|
optional: true,
|
|
|
|
blackbox: true
|
|
|
|
},
|
2016-11-10 16:00:17 +01:00
|
|
|
// telescope-specific data, kept for backward compatibility and migration purposes
|
|
|
|
telescope: {
|
|
|
|
type: Telescope.schemas.userData,
|
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
|
|
|
},
|
2016-11-08 18:22:17 +01:00
|
|
|
services: {
|
|
|
|
type: Object,
|
|
|
|
optional: true,
|
|
|
|
blackbox: true
|
|
|
|
},
|
2016-06-23 15:00:58 +09:00
|
|
|
/**
|
|
|
|
Bio (Markdown version)
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__bio: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
control: "textarea",
|
2016-07-21 09:53:58 +09:00
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit,
|
2016-10-30 18:25:51 +01:00
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
The name displayed throughout the app. Can contain spaces and special characters, doesn't need to be unique
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__displayName: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
control: "text",
|
2016-07-21 09:53:58 +09:00
|
|
|
insertableIf: canInsert,
|
2016-10-30 18:25:51 +01:00
|
|
|
editableIf: canEdit,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's email. Modifiable.
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__email: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
regEx: SimpleSchema.RegEx.Email,
|
|
|
|
required: true,
|
|
|
|
control: "text",
|
2016-07-21 09:53:58 +09:00
|
|
|
insertableIf: canInsert,
|
2016-10-30 18:25:51 +01:00
|
|
|
editableIf: canEdit,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
// unique: true // note: find a way to fix duplicate accounts before enabling this
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
A hash of the email, used for Gravatar // TODO: change this when email changes
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__emailHash: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
publish: true,
|
2016-10-30 18:25:51 +01:00
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
The HTML version of the bio field
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__htmlBio: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
optional: true,
|
2016-10-30 18:25:51 +01:00
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's karma
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__karma: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: Number,
|
|
|
|
decimal: true,
|
|
|
|
publish: true,
|
2016-10-30 18:25:51 +01:00
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's profile URL slug // TODO: change this when displayName changes
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__slug: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
publish: true,
|
2016-10-30 18:25:51 +01:00
|
|
|
optional: true,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
The user's Twitter username
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__twitterUsername: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
optional: true,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
control: "text",
|
2016-07-21 09:53:58 +09:00
|
|
|
insertableIf: canInsert,
|
|
|
|
editableIf: canEdit,
|
2016-10-30 18:25:51 +01:00
|
|
|
viewableIf: alwaysPublic,
|
2016-06-23 15:00:58 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
A link to the user's homepage
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__website: {
|
2016-06-23 15:00:58 +09:00
|
|
|
type: String,
|
|
|
|
regEx: SimpleSchema.RegEx.Url,
|
|
|
|
publish: true,
|
|
|
|
profile: true,
|
|
|
|
optional: true,
|
|
|
|
control: "text",
|
2016-07-21 09:53:58 +09:00
|
|
|
insertableIf: canInsert,
|
2016-10-30 18:25:51 +01:00
|
|
|
editableIf: canEdit,
|
|
|
|
viewableIf: alwaysPublic,
|
2016-07-19 17:30:59 +09:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
Groups
|
|
|
|
*/
|
2016-11-10 14:22:47 +01:00
|
|
|
__groups: {
|
2016-07-19 17:30:59 +09:00
|
|
|
type: [String],
|
|
|
|
optional: true,
|
|
|
|
control: "checkboxgroup",
|
2016-07-21 09:53:58 +09:00
|
|
|
insertableIf: canEditAll,
|
|
|
|
editableIf: canEditAll,
|
2016-10-30 18:25:51 +01:00
|
|
|
viewableIf: alwaysPublic,
|
2016-10-05 08:43:13 +02:00
|
|
|
form: {
|
2016-07-19 17:30:59 +09:00
|
|
|
options: function () {
|
|
|
|
const groups = _.without(_.keys(Users.groups), "anonymous", "default", "admins");
|
|
|
|
return groups.map(group => {return {value: group, label: group};});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2016-06-23 15:00:58 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
// Meteor.startup(function(){
|
|
|
|
// Users.internationalize();
|
|
|
|
// });
|
|
|
|
|
|
|
|
/**
|
2016-10-05 08:37:48 +02:00
|
|
|
* @summary Attach schema to Users (Meteor.users at the moment) collection
|
2016-06-23 15:00:58 +09:00
|
|
|
*/
|
|
|
|
Users.attachSchema(Users.schema);
|
2016-10-29 16:37:33 +09:00
|
|
|
|
2016-11-08 18:22:17 +01:00
|
|
|
Telescope.graphQL.addCollection(Users);
|
2016-10-29 16:37:33 +09:00
|
|
|
|
2016-11-03 21:39:09 +09:00
|
|
|
Telescope.graphQL.addToContext({ Users });
|