using smart publications and smart methods

This commit is contained in:
Sacha Greif 2016-02-28 13:12:36 +09:00
parent 3f8c5a81af
commit 14b5af4b41
30 changed files with 200 additions and 170 deletions

View file

@ -112,11 +112,6 @@ oauth2@1.1.6-beta.11
observe-sequence@1.0.8-beta.11
ongoworks:speakingurl@9.0.0
ordered-dict@1.0.4
peerlibrary:assert@0.2.5
peerlibrary:fiber-utils@0.6.0
peerlibrary:reactive-mongo@0.1.1
peerlibrary:reactive-publish@0.2.0
peerlibrary:server-autorun@0.5.2
percolatestudio:synced-cron@1.1.0
promise@0.5.2-beta.11
raix:eventemitter@0.1.3
@ -150,7 +145,7 @@ underscore@1.0.5-beta.11
url@1.0.6-beta.11
utilities:react-list-container@0.1.0
utilities:smart-methods@0.0.2
utilities:smart-publications@0.1.0
utilities:smart-publications@0.1.1
webapp@1.2.5-beta.11
webapp-hashing@1.0.6-beta.11
zimme:active-route@2.3.2

View file

@ -4,7 +4,8 @@ Posts.addField([
fieldSchema: {
type: String,
optional: true,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
type: 'bootstrap-postthumbnail',
order: 40

View file

@ -48,9 +48,10 @@ Users.addField([
fieldName: "telescope.isInvited",
fieldSchema: {
type: Boolean,
public: true,
publish: true,
optional: true,
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
autoform: {
omit: true
}

View file

@ -4,12 +4,14 @@ Feeds.schema = new SimpleSchema({
url: {
type: String,
regEx: SimpleSchema.RegEx.Url,
editableBy: ["admin"]
insertableIf: Users.is.admin,
editableIf: Users.is.admin
},
userId: {
type: String,
label: 'feedUser',
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
autoform: {
instructions: 'Posts will be assigned to this user.',
options: function () {
@ -27,7 +29,8 @@ Feeds.schema = new SimpleSchema({
type: [String],
label: 'categories',
optional: true,
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
autoform: {
instructions: 'Posts will be assigned to this category.',
noselect: true,

View file

@ -50,7 +50,7 @@ Posts.addField([
type: Number,
decimal: true,
optional: true,
public: true,
publish: true,
}
},
/**
@ -62,7 +62,7 @@ Posts.addField([
type: Number,
decimal: true,
optional: true,
public: true,
publish: true,
}
},
]);
@ -81,7 +81,7 @@ Comments.addField([
fieldSchema: {
type: Number,
optional: true,
public: true,
publish: true,
}
},
/**
@ -92,7 +92,7 @@ Comments.addField([
fieldSchema: {
type: [String],
optional: true,
public: true,
publish: true,
}
},
/**
@ -103,7 +103,7 @@ Comments.addField([
fieldSchema: {
type: Number,
optional: true,
public: true,
publish: true,
}
},
/**
@ -114,7 +114,7 @@ Comments.addField([
fieldSchema: {
type: [String],
optional: true,
public: true,
publish: true,
}
},
/**
@ -126,7 +126,7 @@ Comments.addField([
type: Number,
decimal: true,
optional: true,
public: true,
publish: true,
}
},
/**
@ -138,7 +138,7 @@ Comments.addField([
type: Number,
decimal: true,
optional: true,
public: true,
publish: true,
}
},
]);

View file

@ -46,7 +46,7 @@ const UsersEdit = React.createClass({
({CanEditUser} = Telescope.components);
const fields = Meteor.users.simpleSchema().getEditableFields(this.props.currentUser);
const fields = Users.getInsertableFields(this.props.currentUser);
return (
<CanEditUser user={this.props.currentUser} userToEdit={user}>

View file

@ -4,14 +4,16 @@ Categories = new Mongo.Collection("categories");
Categories.schema = new SimpleSchema({
name: {
type: String,
editableBy: ["admin"],
public: true
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true
},
description: {
type: String,
optional: true,
editableBy: ["admin"],
public: true,
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true,
autoform: {
rows: 3
}
@ -19,26 +21,30 @@ Categories.schema = new SimpleSchema({
order: {
type: Number,
optional: true,
editableBy: ["admin"],
public: true
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true
},
slug: {
type: String,
optional: true,
editableBy: ["admin"],
public: true
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true
},
image: {
type: String,
optional: true,
editableBy: ["admin"],
public: true
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true
},
parentId: {
type: String,
optional: true,
editableBy: ["admin"],
public: true,
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true,
autoform: {
options: function () {
var categories = Categories.find().map(function (category) {

View file

@ -7,7 +7,8 @@ Posts.addField(
type: [String],
control: "checkboxgroup",
optional: true,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
noselect: true,
type: "bootstrap-category",

View file

@ -11,7 +11,8 @@ Package.onUse(function (api) {
api.use([
'nova:core@0.25.7',
'nova:posts@0.25.7'
'nova:posts@0.25.7',
'nova:users@0.25.7'
]);
api.addFiles([

View file

@ -1,6 +1,6 @@
Template.comment_edit.helpers({
commentFields: function () {
return Comments.simpleSchema().getEditableFields(Meteor.user());
return Comments.getInsertableFields(Meteor.user());
}
});

View file

@ -1,6 +1,6 @@
Template.comment_submit.helpers({
commentFields: function () {
return Comments.simpleSchema().getEditableFields(Meteor.user());
return Comments.getInsertableFields(Meteor.user());
},
isLoggedIn: function () {
return !!Meteor.user();

View file

@ -15,7 +15,7 @@ Comments.schema = new SimpleSchema({
_id: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
The `_id` of the parent comment, if there is one
@ -24,9 +24,10 @@ Comments.schema = new SimpleSchema({
type: String,
// regEx: SimpleSchema.RegEx.Id,
max: 500,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
optional: true,
public: true,
publish: true,
autoform: {
omit: true // never show this
}
@ -38,9 +39,10 @@ Comments.schema = new SimpleSchema({
type: String,
// regEx: SimpleSchema.RegEx.Id,
max: 500,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
optional: true,
public: true,
publish: true,
autoform: {
omit: true // never show this
}
@ -51,7 +53,7 @@ Comments.schema = new SimpleSchema({
createdAt: {
type: Date,
optional: true,
public: false,
publish: false
},
/**
The timestamp of the comment being posted. For now, comments are always created and posted at the same time
@ -59,7 +61,7 @@ Comments.schema = new SimpleSchema({
postedAt: {
type: Date,
optional: true,
public: true,
publish: true,
},
/**
The comment body (Markdown)
@ -67,8 +69,9 @@ Comments.schema = new SimpleSchema({
body: {
type: String,
max: 3000,
editableBy: ["member", "admin"],
public: true,
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
publish: true,
autoform: {
rows: 5,
afFormGroup: {
@ -82,7 +85,7 @@ Comments.schema = new SimpleSchema({
htmlBody: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
The comment author's name
@ -90,7 +93,7 @@ Comments.schema = new SimpleSchema({
author: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
Whether the comment is inactive. Inactive comments' scores gets recalculated less often
@ -98,7 +101,7 @@ Comments.schema = new SimpleSchema({
inactive: {
type: Boolean,
optional: true,
public: true,
publish: true,
},
/**
The post's `_id`
@ -106,10 +109,10 @@ Comments.schema = new SimpleSchema({
postId: {
type: String,
optional: true,
public: true,
publish: true,
// regEx: SimpleSchema.RegEx.Id,
max: 500,
// editableBy: ["member", "admin"], // TODO: should users be able to set postId, but not modify it?
// editableIf: Users.is.ownerOrAdmin, // TODO: should users be able to set postId, but not modify it?
autoform: {
omit: true // never show this
}
@ -120,7 +123,7 @@ Comments.schema = new SimpleSchema({
userId: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
Whether the comment is deleted. Delete comments' content doesn't appear on the site.
@ -128,7 +131,7 @@ Comments.schema = new SimpleSchema({
isDeleted: {
type: Boolean,
optional: true,
public: true,
publish: true,
}
});

View file

@ -9,7 +9,7 @@ Posts.addField([
fieldSchema: {
type: Number,
optional: true,
public: true
publish: true
}
},
/**
@ -20,7 +20,7 @@ Posts.addField([
fieldSchema: {
type: [String],
optional: true,
public: true,
publish: true,
join: {
joinAs: "commentersArray",
collection: () => Users,

View file

@ -46,7 +46,7 @@ const EditDocContainer = React.createClass({
const document = this.props.document;
const collection = this.props.collection;
const fields = collection.simpleSchema().getEditableFields(this.data.currentUser);
const fields = collection.getInsertableFields(this.data.currentUser);
return (
<div className="document-edit">

View file

@ -42,7 +42,7 @@ const NewDocContainer = React.createClass({
render() {
const collection = this.props.collection;
const fields = collection.simpleSchema().getEditableFields(this.data.currentUser);
const fields = collection.getInsertableFields(this.data.currentUser);
return (
<div className="new-document">

View file

@ -17,17 +17,16 @@ FlowRouter.route('/demo', {
Movies = new Mongo.Collection("movies");
const hasUserId = userId => !!userId;
const isOwner = (userId, document) => userId === document.userId;
const isLoggedIn = user => !!user;
const isOwner = (user, document) => {user._id === document.userId};
const schema = new SimpleSchema({
name: {
type: String,
publish: true,
control: "text",
createIf: hasUserId,
editIf: isOwner,
editableBy: ["member", "admin"]
insertableIf: isLoggedIn,
editableIf: isOwner
},
createdAt: {
type: Date,
@ -38,21 +37,19 @@ const schema = new SimpleSchema({
publish: true,
optional: true,
control: "text",
createIf: hasUserId,
editIf: isOwner,
editableBy: ["member", "admin"]
insertableIf: isLoggedIn,
editableIf: isOwner
},
review: {
type: String,
publish: true,
control: "textarea",
createIf: hasUserId,
editIf: isOwner,
editableBy: ["member", "admin"]
insertableIf: isLoggedIn,
editableIf: isOwner
},
userId: {
type: String,
publish: true,
publish: user => Users.is.admin(user),
join: {
collection: () => Meteor.users,
joinAs: "user",
@ -67,15 +64,15 @@ Movies.attachSchema(schema);
// Methods //
//////////////////////////////////////////////////////
Movies.initMethods({
deleteIf: isOwner,
Movies.smartMethods({
createCallback: function (document) {
document = _.extend(document, {
createdAt: new Date(),
userId: Meteor.userId()
});
return document;
}
},
deleteCallback: isOwner
});
//////////////////////////////////////////////////////

View file

@ -48,7 +48,7 @@ Telescope.allowCheck = function (collection, userId, document, fieldNames, modif
var schema = collection.simpleSchema();
var user = Meteor.users.findOne(userId);
var allowedFields = schema.getEditableFields(user);
var allowedFields = collection.getInsertableFields(user);
var fields = [];
// fieldNames only contains top-level fields, so loop over modifier to get real list of fields
@ -75,23 +75,6 @@ Meteor.Collection.prototype.allowCheck = function (userId, document, fieldNames,
*/
Telescope.schemas = {};
/**
* @method SimpleSchema.getEditableFields
* Get a list of all fields editable by a specific user for a given schema
* @param {Object} user the user for which to check field permissions
*/
SimpleSchema.prototype.getEditableFields = function (user) {
var schema = this._schema;
var fields = _.sortBy(_.filter(_.keys(schema), function (fieldName) {
var field = schema[fieldName];
return Users.can.editField(user, field);
}), function (fieldName) {
var field = schema[fieldName];
return field.autoform && field.autoform.order;
});
return fields;
};
SimpleSchema.prototype.getProfileFields = function () {
var schema = this._schema;
var fields = _.filter(_.keys(schema), function (fieldName) {

View file

@ -21,15 +21,11 @@ SimpleSchema.extendOptions({
private: Match.Optional(Boolean),
editable: Match.Optional(Boolean), // editable: true means the field can be edited by the document's owner
hidden: Match.Optional(Boolean), // hidden: true means the field is never shown in a form no matter what
editableBy: Match.Optional([String]),
publishedTo: Match.Optional([String]),
required: Match.Optional(Boolean), // required: true means the field is required to have a complete profile
public: Match.Optional(Boolean), // public: true means the field is published freely
profile: Match.Optional(Boolean), // profile: true means the field is shown on user profiles
template: Match.Optional(String), // template used to display the field
autoform: Match.Optional(Object), // autoform placeholder
control: Match.Optional(String), // autoform placeholder
join: Match.Optional(Object) // autoform placeholder
// editableBy: Match.Optional(String)
});

View file

@ -72,6 +72,7 @@ Package.onUse(function (api) {
// 'peerlibrary:reactive-publish@0.2.0',
'utilities:smart-publications',
'utilities:smart-methods',
'ecmascript',
'react',

View file

@ -17,7 +17,8 @@ Users.addField([
label: 'Show banner',
type: Boolean,
optional: true,
editableBy: ['admin', 'member'],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
omit: true
}
@ -29,7 +30,8 @@ Users.addField([
label: 'Subscribe to newsletter',
type: Boolean,
optional: true,
editableBy: ['admin', 'member'],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
omit: true
}

View file

@ -28,7 +28,7 @@ Template.post_edit.helpers({
return Posts.findOne(FlowRouter.getParam("_id"));
},
postFields: function () {
return Posts.simpleSchema().getEditableFields(Meteor.user());
return Posts.getInsertableFields(Meteor.user());
}
});

View file

@ -4,7 +4,7 @@ Template.post_submit.onCreated(function () {
Template.post_submit.helpers({
postFields: function () {
return Posts.simpleSchema().getEditableFields(Meteor.user());
return Posts.getInsertableFields(Meteor.user());
}
});

View file

@ -9,7 +9,7 @@ Posts.schema = new SimpleSchema({
_id: {
type: String,
optional: true,
public: true
publish: true
},
/**
Timetstamp of post creation
@ -17,7 +17,7 @@ Posts.schema = new SimpleSchema({
createdAt: {
type: Date,
optional: true,
public: false
publish: false
},
/**
Timestamp of post first appearing on the site (i.e. being approved)
@ -25,8 +25,9 @@ Posts.schema = new SimpleSchema({
postedAt: {
type: Date,
optional: true,
editableBy: ["admin"],
public: true,
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
publish: true,
control: "datepicker",
autoform: {
group: 'admin',
@ -40,9 +41,10 @@ Posts.schema = new SimpleSchema({
type: String,
optional: true,
max: 500,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
control: "text",
public: true,
publish: true,
autoform: {
type: "bootstrap-url",
order: 10
@ -55,9 +57,10 @@ Posts.schema = new SimpleSchema({
type: String,
optional: false,
max: 500,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
control: "text",
public: true,
publish: true,
autoform: {
order: 20
}
@ -68,7 +71,7 @@ Posts.schema = new SimpleSchema({
slug: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
Post body (markdown)
@ -77,9 +80,10 @@ Posts.schema = new SimpleSchema({
type: String,
optional: true,
max: 3000,
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
control: "textarea",
public: true,
publish: true,
autoform: {
rows: 5,
order: 30
@ -91,7 +95,7 @@ Posts.schema = new SimpleSchema({
htmlBody: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
Count of how many times the post's page was viewed
@ -99,7 +103,7 @@ Posts.schema = new SimpleSchema({
viewCount: {
type: Number,
optional: true,
public: true,
publish: true,
},
/**
Timestamp of the last comment
@ -107,7 +111,7 @@ Posts.schema = new SimpleSchema({
lastCommentedAt: {
type: Date,
optional: true,
public: true,
publish: true,
},
/**
Count of how many times the post's link was clicked
@ -115,7 +119,7 @@ Posts.schema = new SimpleSchema({
clickCount: {
type: Number,
optional: true,
public: true,
publish: true,
},
/**
The post's status. One of pending (`1`), approved (`2`), or deleted (`3`)
@ -123,9 +127,10 @@ Posts.schema = new SimpleSchema({
status: {
type: Number,
optional: true,
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
control: "select",
public: true,
publish: true,
autoValue: function () {
// only provide a default value
// 1) this is an insert operation
@ -147,9 +152,10 @@ Posts.schema = new SimpleSchema({
type: Boolean,
optional: true,
defaultValue: false,
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
control: "checkbox",
public: true,
publish: true,
autoform: {
group: 'admin',
leftLabel: "Sticky"
@ -161,7 +167,7 @@ Posts.schema = new SimpleSchema({
inactive: {
type: Boolean,
optional: true,
public: false,
publish: false
},
/**
Save info for later spam checking on a post. We will use this for the akismet package
@ -169,17 +175,17 @@ Posts.schema = new SimpleSchema({
userIP: {
type: String,
optional: true,
public: false,
publish: false
},
userAgent: {
type: String,
optional: true,
public: false,
publish: false
},
referrer: {
type: String,
optional: true,
public: false,
publish: false
},
/**
The post author's name
@ -187,7 +193,7 @@ Posts.schema = new SimpleSchema({
author: {
type: String,
optional: true,
public: true,
publish: true,
},
/**
The post author's `_id`.
@ -196,9 +202,10 @@ Posts.schema = new SimpleSchema({
type: String,
optional: true,
// regEx: SimpleSchema.RegEx.Id,
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
control: "select",
public: true,
publish: true,
autoform: {
group: 'admin',
options: function () {

View file

@ -17,7 +17,7 @@ Package.onUse(function (api) {
'nova:core@0.25.7',
// 'nova:i18n@0.25.7',
// 'nova:settings@0.25.7',
// 'nova:users@0.25.7',
'nova:users@0.25.7',
// 'nova:comments@0.25.7'
]);

View file

@ -3,7 +3,7 @@ Template.user_account.helpers({
return this;
},
userFields: function () {
var fields = Meteor.users.simpleSchema().getEditableFields(Meteor.user());
var fields = Meteor.users.getInsertableFields(Meteor.user());
return fields;
},
isUsingPassword: function () {

View file

@ -1,8 +1,3 @@
/**
* Telescope Users namespace
* @namespace Users
*/
Users = Meteor.users;
/**
* Vote schema
@ -34,7 +29,8 @@ Telescope.schemas.userData = new SimpleSchema({
type: String,
optional: true,
control: "textarea",
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
// autoform: {
// rows: 5
// }
@ -44,7 +40,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
commentCount: {
type: Number,
public: true,
publish: true,
optional: true
},
/**
@ -53,17 +49,18 @@ Telescope.schemas.userData = new SimpleSchema({
displayName: {
type: String,
optional: true,
public: true,
publish: true,
profile: true,
control: "text",
editableBy: ["member", "admin"]
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin
},
/**
An array containing comment downvotes
*/
downvotedComments: {
type: [Telescope.schemas.votes],
public: true,
publish: true,
optional: true
},
/**
@ -71,7 +68,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
downvotedPosts: {
type: [Telescope.schemas.votes],
public: true,
publish: true,
optional: true
},
/**
@ -83,7 +80,8 @@ Telescope.schemas.userData = new SimpleSchema({
regEx: SimpleSchema.RegEx.Email,
required: true,
control: "text",
editableBy: ["member", "admin"]
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin
// unique: true // note: find a way to fix duplicate accounts before enabling this
},
/**
@ -91,7 +89,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
emailHash: {
type: String,
public: true,
publish: true,
optional: true
},
/**
@ -99,7 +97,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
htmlBio: {
type: String,
public: true,
publish: true,
profile: true,
optional: true,
// autoform: {
@ -113,7 +111,7 @@ Telescope.schemas.userData = new SimpleSchema({
karma: {
type: Number,
decimal: true,
public: true,
publish: true,
optional: true
},
/**
@ -121,7 +119,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
postCount: {
type: Number,
public: true,
publish: true,
optional: true
},
/**
@ -130,7 +128,7 @@ Telescope.schemas.userData = new SimpleSchema({
// settings: {
// type: Object,
// optional: true,
// editableBy: ["member", "admin"],
// editableIf: Users.is.ownerOrAdmin,
// blackbox: true,
// autoform: {
// omit: true
@ -141,7 +139,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
slug: {
type: String,
public: true,
publish: true,
optional: true
},
/**
@ -150,10 +148,11 @@ Telescope.schemas.userData = new SimpleSchema({
twitterUsername: {
type: String,
optional: true,
public: true,
publish: true,
profile: true,
control: "text",
editableBy: ["member", "admin"],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
template: "user_profile_twitter"
},
/**
@ -161,7 +160,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
upvotedComments: {
type: [Telescope.schemas.votes],
public: true,
publish: true,
optional: true
},
/**
@ -169,7 +168,7 @@ Telescope.schemas.userData = new SimpleSchema({
*/
upvotedPosts: {
type: [Telescope.schemas.votes],
public: true,
publish: true,
optional: true
},
/**
@ -178,11 +177,12 @@ Telescope.schemas.userData = new SimpleSchema({
website: {
type: String,
regEx: SimpleSchema.RegEx.Url,
public: true,
publish: true,
profile: true,
optional: true,
control: "text",
editableBy: ["member", "admin"]
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin
}
});
@ -193,13 +193,13 @@ Telescope.schemas.userData = new SimpleSchema({
Users.schema = new SimpleSchema({
_id: {
type: String,
public: true,
publish: true,
optional: true
},
username: {
type: String,
// regEx: /^[a-z0-9A-Z_]{3,15}$/,
public: true,
publish: true,
optional: true
},
emails: {
@ -217,14 +217,15 @@ Users.schema = new SimpleSchema({
},
createdAt: {
type: Date,
public: true,
publish: true,
optional: true
},
isAdmin: {
type: Boolean,
control: "checkbox",
optional: true,
editableBy: ["admin"],
insertableIf: Users.is.admin,
editableIf: Users.is.admin,
// autoform: {
// omit: true
// }
@ -268,7 +269,8 @@ if (typeof Herald !== "undefined") {
optional: true,
defaultValue: false,
control: "checkbox",
editableBy: ['admin'],
insertableIf: Users.is.admin,
editableBy: Users.is.admin,
autoform: {
group: 'Email Notifications'
}
@ -282,7 +284,8 @@ if (typeof Herald !== "undefined") {
optional: true,
defaultValue: false,
control: "checkbox",
editableBy: ['admin', 'member'],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
group: 'Email Notifications'
}
@ -296,7 +299,8 @@ if (typeof Herald !== "undefined") {
optional: true,
defaultValue: true,
control: "checkbox",
editableBy: ['admin', 'member'],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
group: 'Email Notifications'
}
@ -310,7 +314,8 @@ if (typeof Herald !== "undefined") {
optional: true,
defaultValue: true,
control: "checkbox",
editableBy: ['admin', 'member'],
insertableIf: Users.is.memberOrAdmin,
editableIf: Users.is.ownerOrAdmin,
autoform: {
group: 'Email Notifications'
}

View file

@ -0,0 +1,5 @@
/**
* Telescope Users namespace
* @namespace Users
*/
Users = Meteor.users;

View file

@ -144,16 +144,7 @@ Users.helpers({canEditById: function (document) {return Users.can.editById(this,
* @param {Object} field - The field being edited or inserted
*/
Users.can.submitField = function (user, field) {
if (!field.editableBy || !user) {
return false;
}
var adminCheck = _.contains(field.editableBy, "admin") && Users.is.admin(user); // is the field editable by admins?
var memberCheck = _.contains(field.editableBy, "member"); // is the field editable by regular users?
return adminCheck || memberCheck;
return user && field.insertableIf && field.insertableIf(user);
};
Users.helpers({canSubmitField: function (field) {return Users.can.submitField(this, field);}});
@ -162,7 +153,9 @@ Users.helpers({canSubmitField: function (field) {return Users.can.submitField(th
* @param {Object} user - The user performing the action
* @param {Object} field - The field being edited or inserted
*/
Users.can.editField = Users.can.submitField;
Users.can.editField = function (user, field, document) {
return user && field.editableIf && field.editableIf(user, document);
};
Users.can.invite = function (user) {
return Users.is.invited(user) || Users.is.admin(user);

View file

@ -42,6 +42,35 @@ Users.is.owner = function (userOrUserId, document) {
Users.is.ownerById = Users.is.owner;
Users.helpers({isOwner: function () {return Users.is.owner(this, document);}});
/**
* Check if a user is a member or an admin
* @param {Object} user - The user
* @param {Object} document - The document to check (post, comment, user object, etc.)
*/
Users.is.memberOrAdmin = function (user) {
if (typeof user === "undefined") {
return false;
} else {
return !!user || Users.is.admin(user);
}
};
/**
* Check if a user owns a document or is an admin
* @param {Object} user - The user
* @param {Object} document - The document to check (post, comment, user object, etc.)
*/
Users.is.ownerOrAdmin = function (user, document) {
if (typeof user === "undefined") {
return false;
} else if (typeof document === "undefined") {
return true;
} else {
return Users.is.owner(user, document) || Users.is.admin(user);
}
};
Users.is.invited = function (userOrUserId) {
try {
var user = Users.getUser(userOrUserId);

View file

@ -19,10 +19,11 @@ Package.onUse(function (api) {
api.addFiles([
// 'package-tap.i18n',
'lib/collection.js',
'lib/namespace.js',
'lib/roles.js',
'lib/config.js',
'lib/permissions.js',
'lib/collection.js',
'lib/callbacks.js',
'lib/helpers.js',
'lib/published_fields.js',