viewableBy -> canRead

This commit is contained in:
SachaG 2018-06-22 20:55:22 +09:00
parent 725320fab1
commit 50fba6b0a3
14 changed files with 96 additions and 80 deletions

View file

@ -10,7 +10,7 @@ export const addCustomFields = collection => {
fieldSchema: { fieldSchema: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
} }
}, },
{ {
@ -18,7 +18,7 @@ export const addCustomFields = collection => {
fieldSchema: { fieldSchema: {
type: Array, type: Array,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
} }
}, },
{ {
@ -36,7 +36,7 @@ export const addCustomFields = collection => {
fieldSchema: { fieldSchema: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
arguments: 'format: String', arguments: 'format: String',

View file

@ -3,66 +3,66 @@ import { Callbacks } from 'meteor/vulcan:lib';
const schema = { const schema = {
name: { name: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
}, },
iterator: { iterator: {
type: Object, type: Object,
viewableBy: ['admins'], canRead: ['admins'],
}, },
properties: { properties: {
type: Array, type: Array,
viewableBy: ['admins'], canRead: ['admins'],
}, },
'properties.$': { 'properties.$': {
type: Object, type: Object,
viewableBy: ['admins'], canRead: ['admins'],
}, },
// iterator: { // iterator: {
// label: 'Iterator', // label: 'Iterator',
// type: String, // type: String,
// viewableBy: ['admins'], // canRead: ['admins'],
// }, // },
// options: { // options: {
// label: 'Options', // label: 'Options',
// type: Array, // type: Array,
// viewableBy: ['admins'], // canRead: ['admins'],
// }, // },
// 'options.$': { // 'options.$': {
// type: Object, // type: Object,
// viewableBy: ['admins'], // canRead: ['admins'],
// }, // },
runs: { runs: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
}, },
newSyntax: { newSyntax: {
label: 'New Syntax', label: 'New Syntax',
type: Boolean, type: Boolean,
viewableBy: ['admins'], canRead: ['admins'],
}, },
returns: { returns: {
label: 'Should Return', label: 'Should Return',
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
}, },
description: { description: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
}, },
hooks: { hooks: {
type: Array, type: Array,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
type: '[String]', type: '[String]',
resolver: callback => { resolver: callback => {

View file

@ -3,31 +3,31 @@ const schema = {
name: { name: {
label: 'Name', label: 'Name',
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
}, },
value: { value: {
label: 'Value', label: 'Value',
type: Object, type: Object,
viewableBy: ['admins'], canRead: ['admins'],
}, },
defaultValue: { defaultValue: {
label: 'Default Value', label: 'Default Value',
type: Object, type: Object,
viewableBy: ['admins'], canRead: ['admins'],
}, },
isPublic: { isPublic: {
label: 'Public', label: 'Public',
type: Boolean, type: Boolean,
viewableBy: ['admins'], canRead: ['admins'],
}, },
description: { description: {
label: 'Description', label: 'Description',
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
}, },
}; };

View file

@ -1,7 +1,7 @@
const schema = { const schema = {
createdAt: { createdAt: {
type: Date, type: Date,
viewableBy: ['guests'], canRead: ['guests'],
optional: true, optional: true,
onInsert: () => { onInsert: () => {
return new Date() return new Date()
@ -9,7 +9,7 @@ const schema = {
}, },
name: { name: {
type: String, type: String,
viewableBy: ['guests'], canRead: ['guests'],
insertableBy: ['guests'], insertableBy: ['guests'],
}, },
userId: { userId: {
@ -33,7 +33,7 @@ const schema = {
type: Object, type: Object,
optional: true, optional: true,
blackbox: true, blackbox: true,
viewableBy: ['guests'], canRead: ['guests'],
insertableBy: ['guests'], insertableBy: ['guests'],
}, },
}; };

View file

@ -87,7 +87,7 @@ Posts.addField({
control: getComponent('Upload'), control: getComponent('Upload'),
insertableBy: ['members'], insertableBy: ['members'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ['guests'], canRead: ['guests'],
form: { form: {
options: { options: {
preset: getSetting('cloudinaryPresets').posts // this setting refers to the transformation you want to apply to the image preset: getSetting('cloudinaryPresets').posts // this setting refers to the transformation you want to apply to the image
@ -113,7 +113,7 @@ Users.addField({
control: getComponent('Upload'), control: getComponent('Upload'),
insertableBy: ['members'], insertableBy: ['members'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ['guests'], canRead: ['guests'],
preload: true, // ⚠️ will preload the field for the current user! preload: true, // ⚠️ will preload the field for the current user!
form: { form: {
options: { options: {

View file

@ -68,6 +68,21 @@ class FormWrapper extends PureComponent {
return this.props.documentId || this.props.slug ? "edit" : "new"; return this.props.documentId || this.props.slug ? "edit" : "new";
} }
getReadableFields() {
// OpenCRUD backwards compatibility
return Object.keys(this.getSchema()).filter(fieldName => schema[fieldName].canRead || schema[fieldName].viewableBy);
}
getCreateableFields() {
// OpenCRUD backwards compatibility
return Object.keys(this.getSchema()).filter(fieldName => schema[fieldName].canCreate || schema[fieldName].insertableBy);
}
getUpdatetableFields() {
// OpenCRUD backwards compatibility
return Object.keys(this.getSchema()).filter(fieldName => schema[fieldName].canUpdate || schema[fieldName].editableBy);
}
// get fragment used to decide what data to load from the server to populate the form, // get fragment used to decide what data to load from the server to populate the form,
// as well as what data to ask for as return value for the mutation // as well as what data to ask for as return value for the mutation
getFragments() { getFragments() {
@ -75,16 +90,15 @@ class FormWrapper extends PureComponent {
const prefix = `${this.getCollection()._name}${Utils.capitalize(this.getFormType())}` const prefix = `${this.getCollection()._name}${Utils.capitalize(this.getFormType())}`
const fragmentName = `${prefix}FormFragment`; const fragmentName = `${prefix}FormFragment`;
const schema = this.getSchema();
const fields = this.props.fields; const fields = this.props.fields;
const viewableFields = _.filter(_.keys(schema), fieldName => !!schema[fieldName].viewableBy); const readableFields = this.getReadableFields();
const insertableFields = _.filter(_.keys(schema), fieldName => !!schema[fieldName].insertableBy); const createableFields = this.getCreateableFields();
const editableFields = _.filter(_.keys(schema), fieldName => !!schema[fieldName].editableBy); const updatetableFields = this.getUpdatetableFields();
// get all editable/insertable fields (depending on current form type) // get all editable/insertable fields (depending on current form type)
let queryFields = this.getFormType() === 'new' ? insertableFields : editableFields; let queryFields = this.getFormType() === 'new' ? createableFields : updatetableFields;
// for the mutations's return value, also get non-editable but viewable fields (such as createdAt, userId, etc.) // for the mutations's return value, also get non-editable but viewable fields (such as createdAt, userId, etc.)
let mutationFields = this.getFormType() === 'new' ? _.unique(insertableFields.concat(viewableFields)) : _.unique(insertableFields.concat(editableFields)); let mutationFields = this.getFormType() === 'new' ? _.unique(createableFields.concat(readableFields)) : _.unique(createableFields.concat(updatetableFields));
// if "fields" prop is specified, restrict list of fields to it // if "fields" prop is specified, restrict list of fields to it
if (typeof fields !== "undefined" && fields.length > 0) { if (typeof fields !== "undefined" && fields.length > 0) {

View file

@ -84,7 +84,8 @@ export const getDefaultFragmentText = (collection, options = { onlyViewable: tru
*/ */
const field = schema[fieldName]; const field = schema[fieldName];
return (field.resolveAs && !field.resolveAs.addOriginalField) || fieldName.indexOf('$') !== -1 || options.onlyViewable && !field.viewableBy // OpenCRUD backwards compatibility
return (field.resolveAs && !field.resolveAs.addOriginalField) || fieldName.indexOf('$') !== -1 || options.onlyViewable && !(field.canRead || field.viewableBy);
}); });
if (fieldNames.length) { if (fieldNames.length) {

View file

@ -140,7 +140,8 @@ export const GraphQLSchema = {
// only include fields that are viewable/insertable/editable and don't contain "$" in their name // only include fields that are viewable/insertable/editable and don't contain "$" in their name
// note: insertable/editable fields must be included in main schema in case they're returned by a mutation // note: insertable/editable fields must be included in main schema in case they're returned by a mutation
if ((field.viewableBy || field.insertableBy || field.editableBy) && fieldName.indexOf('$') === -1) { // OpenCRUD backwards compatibility
if ((field.canRead || field.canCreate || field.canUpdate || field.viewableBy || field.insertableBy || field.editableBy) && fieldName.indexOf('$') === -1) {
const fieldDescription = field.description; const fieldDescription = field.description;
const fieldDirective = isIntlField(field) ? `@intl` : ''; const fieldDirective = isIntlField(field) ? `@intl` : '';

View file

@ -10,7 +10,7 @@ Users.addField([
defaultValue: false, defaultValue: false,
insertableBy: ['members'], insertableBy: ['members'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ['guests'], canRead: ['guests'],
control: 'NewsletterSubscribe', control: 'NewsletterSubscribe',
group: { group: {
name: "newsletter", name: "newsletter",

View file

@ -7,12 +7,12 @@ const schema = {
_id: { _id: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
}, },
createdAt: { createdAt: {
type: Date, type: Date,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
onInsert: (document, currentUser) => { onInsert: (document, currentUser) => {
return new Date(); return new Date();
}, },
@ -20,7 +20,7 @@ const schema = {
userId: { userId: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
fieldName: 'user', fieldName: 'user',
type: 'User', type: 'User',
@ -34,20 +34,20 @@ const schema = {
type: { type: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
}, },
// custom properties // custom properties
associatedCollection: { associatedCollection: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
optional: true, optional: true,
}, },
associatedId: { associatedId: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
optional: true, optional: true,
}, },
@ -58,37 +58,37 @@ const schema = {
productKey: { productKey: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
optional: true, optional: true,
}, },
source: { source: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
optional: false, optional: false,
}, },
test: { test: {
type: Boolean, type: Boolean,
viewableBy: ['admins'], canRead: ['admins'],
optional: true, optional: true,
}, },
data: { data: {
type: Object, type: Object,
viewableBy: ['admins'], canRead: ['admins'],
blackbox: true, blackbox: true,
}, },
properties: { properties: {
type: Object, type: Object,
viewableBy: ['admins'], canRead: ['admins'],
blackbox: true, blackbox: true,
}, },
ip: { ip: {
type: String, type: String,
viewableBy: ['admins'], canRead: ['admins'],
optional: true, optional: true,
}, },
@ -97,7 +97,7 @@ const schema = {
amount: { amount: {
type: Number, type: Number,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
type: 'Int', type: 'Int',
resolver: charge => charge.data.amount, resolver: charge => charge.data.amount,
@ -107,7 +107,7 @@ const schema = {
createdAtFormatted: { createdAtFormatted: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
resolver: (charge, args, context) => { resolver: (charge, args, context) => {
@ -119,7 +119,7 @@ const schema = {
createdAtFormattedShort: { createdAtFormattedShort: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
resolver: (charge, args, context) => { resolver: (charge, args, context) => {
@ -131,7 +131,7 @@ const schema = {
stripeId: { stripeId: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
resolver: (charge, args, context) => { resolver: (charge, args, context) => {
@ -143,7 +143,7 @@ const schema = {
stripeChargeUrl: { stripeChargeUrl: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
resolver: (charge, args, context) => { resolver: (charge, args, context) => {
@ -156,7 +156,7 @@ const schema = {
// associatedDocument: { // associatedDocument: {
// type: Object, // type: Object,
// viewableBy: ['admins'], // canRead: ['admins'],
// optional: true, // optional: true,
// resolveAs: { // resolveAs: {
// type: 'Chargeable', // type: 'Chargeable',

View file

@ -34,12 +34,12 @@ const schema = {
_id: { _id: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
}, },
username: { username: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
insertableBy: ['guests'], insertableBy: ['guests'],
onInsert: user => { onInsert: user => {
if (user.services && user.services.twitter && user.services.twitter.screenName) { if (user.services && user.services.twitter && user.services.twitter.screenName) {
@ -68,7 +68,7 @@ const schema = {
createdAt: { createdAt: {
type: Date, type: Date,
optional: true, optional: true,
viewableBy: ['admins'], canRead: ['admins'],
onInsert: () => { onInsert: () => {
return new Date(); return new Date();
} }
@ -80,7 +80,7 @@ const schema = {
optional: true, optional: true,
insertableBy: ['admins'], insertableBy: ['admins'],
editableBy: ['admins'], editableBy: ['admins'],
viewableBy: ['guests'], canRead: ['guests'],
group: adminGroup, group: adminGroup,
}, },
locale: { locale: {
@ -90,7 +90,7 @@ const schema = {
control: 'select', control: 'select',
insertableBy: ['members'], insertableBy: ['members'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ['guests'], canRead: ['guests'],
options: () => Locales.map(({ id, label }) => ({ value: id, label })), options: () => Locales.map(({ id, label }) => ({ value: id, label })),
}, },
profile: { profile: {
@ -109,7 +109,7 @@ const schema = {
type: Object, type: Object,
optional: true, optional: true,
blackbox: true, blackbox: true,
viewableBy: ownsOrIsAdmin, canRead: ownsOrIsAdmin,
}, },
/** /**
The name displayed throughout the app. Can contain spaces and special characters, doesn't need to be unique The name displayed throughout the app. Can contain spaces and special characters, doesn't need to be unique
@ -120,7 +120,7 @@ const schema = {
control: "text", control: "text",
insertableBy: ['members'], insertableBy: ['members'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ['guests'], canRead: ['guests'],
order: 10, order: 10,
onInsert: (user, options) => { onInsert: (user, options) => {
const profileName = Utils.getNestedProperty(user, 'profile.name'); const profileName = Utils.getNestedProperty(user, 'profile.name');
@ -145,7 +145,7 @@ const schema = {
control: "text", control: "text",
insertableBy: ['guests'], insertableBy: ['guests'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ownsOrIsAdmin, canRead: ownsOrIsAdmin,
order: 20, order: 20,
onInsert: (user) => { onInsert: (user) => {
// look in a few places for the user email // look in a few places for the user email
@ -171,7 +171,7 @@ const schema = {
emailHash: { emailHash: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
onInsert: user => { onInsert: user => {
if (user.email) { if (user.email) {
return getCollection('Users').avatar.hash(user.email); return getCollection('Users').avatar.hash(user.email);
@ -181,7 +181,7 @@ const schema = {
avatarUrl: { avatarUrl: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
onInsert: user => { onInsert: user => {
const twitterAvatar = Utils.getNestedProperty(user, 'services.twitter.profile_image_url_https'); const twitterAvatar = Utils.getNestedProperty(user, 'services.twitter.profile_image_url_https');
@ -217,7 +217,7 @@ const schema = {
slug: { slug: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
order: 40, order: 40,
onInsert: user => { onInsert: user => {
// create a basic slug from display name and then modify it if this slugs already exists; // create a basic slug from display name and then modify it if this slugs already exists;
@ -234,7 +234,7 @@ const schema = {
control: "text", control: "text",
insertableBy: ['members'], insertableBy: ['members'],
editableBy: ['members'], editableBy: ['members'],
viewableBy: ['guests'], canRead: ['guests'],
order: 60, order: 60,
resolveAs: { resolveAs: {
type: 'String', type: 'String',
@ -257,7 +257,7 @@ const schema = {
control: "checkboxgroup", control: "checkboxgroup",
insertableBy: ['admins'], insertableBy: ['admins'],
editableBy: ['admins'], editableBy: ['admins'],
viewableBy: ['guests'], canRead: ['guests'],
group: adminGroup, group: adminGroup,
form: { form: {
options: function () { options: function () {
@ -276,7 +276,7 @@ const schema = {
pageUrl: { pageUrl: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
resolver: (user, args, { Users }) => { resolver: (user, args, { Users }) => {
@ -288,7 +288,7 @@ const schema = {
editUrl: { editUrl: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
resolveAs: { resolveAs: {
type: 'String', type: 'String',
resolver: (user, args, { Users }) => { resolver: (user, args, { Users }) => {

View file

@ -11,7 +11,7 @@ Users.addField([
fieldSchema: { fieldSchema: {
type: Array, type: Array,
optional: true, optional: true,
viewableBy: Users.owns, canRead: Users.owns,
resolveAs: { resolveAs: {
type: '[Vote]', type: '[Vote]',
arguments: 'collectionName: String', arguments: 'collectionName: String',

View file

@ -15,7 +15,7 @@ export const makeVoteable = collection => {
fieldSchema: { fieldSchema: {
type: Array, type: Array,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
resolveAs: { resolveAs: {
type: '[Vote]', type: '[Vote]',
resolver: async (document, args, { Users, Votes, currentUser }) => { resolver: async (document, args, { Users, Votes, currentUser }) => {
@ -44,7 +44,7 @@ export const makeVoteable = collection => {
fieldSchema: { fieldSchema: {
type: Array, type: Array,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
resolveAs: { resolveAs: {
type: '[Vote]', type: '[Vote]',
resolver: async (document, args, { Users, Votes, currentUser }) => { resolver: async (document, args, { Users, Votes, currentUser }) => {
@ -72,7 +72,7 @@ export const makeVoteable = collection => {
fieldSchema: { fieldSchema: {
type: Array, type: Array,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
resolveAs: { resolveAs: {
type: '[User]', type: '[User]',
resolver: async (document, args, { currentUser, Users }) => { resolver: async (document, args, { currentUser, Users }) => {
@ -105,7 +105,7 @@ export const makeVoteable = collection => {
type: Number, type: Number,
optional: true, optional: true,
defaultValue: 0, defaultValue: 0,
viewableBy: ['guests'], canRead: ['guests'],
onInsert: document => { onInsert: document => {
// default to 0 if empty // default to 0 if empty
return document.baseScore || 0; return document.baseScore || 0;
@ -121,7 +121,7 @@ export const makeVoteable = collection => {
type: Number, type: Number,
optional: true, optional: true,
defaultValue: 0, defaultValue: 0,
viewableBy: ['guests'], canRead: ['guests'],
onInsert: document => { onInsert: document => {
// default to 0 if empty // default to 0 if empty
return document.score || 0; return document.score || 0;

View file

@ -2,7 +2,7 @@ const schema = {
_id: { _id: {
type: String, type: String,
viewableBy: ['guests'], canRead: ['guests'],
}, },
/** /**
@ -10,7 +10,7 @@ const schema = {
*/ */
documentId: { documentId: {
type: String, type: String,
viewableBy: ['guests'], canRead: ['guests'],
}, },
/** /**
@ -18,7 +18,7 @@ const schema = {
*/ */
collectionName: { collectionName: {
type: String, type: String,
viewableBy: ['guests'], canRead: ['guests'],
}, },
/** /**
@ -26,7 +26,7 @@ const schema = {
*/ */
userId: { userId: {
type: String, type: String,
viewableBy: ['guests'], canRead: ['guests'],
}, },
/** /**
@ -35,7 +35,7 @@ const schema = {
voteType: { voteType: {
type: String, type: String,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
}, },
/** /**
@ -44,7 +44,7 @@ const schema = {
power: { power: {
type: Number, type: Number,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
}, },
/** /**
@ -53,7 +53,7 @@ const schema = {
votedAt: { votedAt: {
type: Date, type: Date,
optional: true, optional: true,
viewableBy: ['guests'], canRead: ['guests'],
} }
}; };