removes withDefaultLocale as it was not necessary

This commit is contained in:
James
2020-04-13 11:38:19 -04:00
parent df6b9b13ac
commit ffb5f97756
31 changed files with 326 additions and 327 deletions

19
src/auth/executePolicy.js Normal file
View File

@@ -0,0 +1,19 @@
const executePolicy = async (user, policy) => {
if (policy) {
const result = await policy(user);
if (!result) {
return false;
}
return true;
}
if (user) {
return true;
}
return false;
};
module.exports = executePolicy;

View File

@@ -6,7 +6,7 @@ const {
const formatName = require('../../graphql/utilities/formatName');
const {
getFind, getFindByID, getDelete, getUpdate,
find, findByID, deleteResolver, update,
} = require('../../collections/graphql/resolvers');
const buildPaginatedListType = require('../../graphql/schema/buildPaginatedListType');
@@ -55,7 +55,7 @@ function registerUser() {
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
},
resolve: getFindByID(this.config, this.User),
resolve: findByID(this.User),
};
this.Query.fields[pluralLabel] = {
@@ -68,7 +68,7 @@ function registerUser() {
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
resolve: getFind(this.config, this.User),
resolve: find(this.User),
};
this.Mutation.fields[`update${singularLabel}`] = {
@@ -77,7 +77,7 @@ function registerUser() {
id: { type: new GraphQLNonNull(GraphQLString) },
data: { type: this.User.graphQL.mutationInputType },
},
resolve: getUpdate(this.config, this.User),
resolve: update(this.User),
};
this.Mutation.fields[`delete${singularLabel}`] = {
@@ -85,7 +85,7 @@ function registerUser() {
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: getDelete(this.User),
resolve: deleteResolver(this.User),
};
}

View File

@@ -6,7 +6,7 @@ const {
const formatName = require('../../graphql/utilities/formatName');
const {
getCreate, getFind, getFindByID, getDelete, getUpdate,
create, find, findByID, deleteResolver, update,
} = require('./resolvers');
const buildPaginatedListType = require('../../graphql/schema/buildPaginatedListType');
@@ -56,7 +56,7 @@ function registerCollections() {
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
},
resolve: getFindByID(this.config, collection),
resolve: findByID(collection),
};
this.Query.fields[pluralLabel] = {
@@ -69,7 +69,7 @@ function registerCollections() {
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
resolve: getFind(this.config, collection),
resolve: find(collection),
};
this.Mutation.fields[`create${singularLabel}`] = {
@@ -77,7 +77,7 @@ function registerCollections() {
args: {
data: { type: collection.graphQL.mutationInputType },
},
resolve: getCreate(this.config, collection),
resolve: create(collection),
};
this.Mutation.fields[`update${singularLabel}`] = {
@@ -86,7 +86,7 @@ function registerCollections() {
id: { type: new GraphQLNonNull(GraphQLString) },
data: { type: collection.graphQL.mutationInputType },
},
resolve: getUpdate(this.config, collection),
resolve: update(collection),
};
this.Mutation.fields[`delete${singularLabel}`] = {
@@ -94,7 +94,7 @@ function registerCollections() {
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: getDelete(collection),
resolve: deleteResolver(collection),
};
});
}

View File

@@ -0,0 +1,21 @@
/* eslint-disable no-param-reassign */
const createQuery = require('../../queries/create');
const create = collection => async (_, args, context) => {
const options = {
...collection,
data: args.data,
user: context.user,
};
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
const result = await createQuery(options);
return result;
};
module.exports = create;

View File

@@ -0,0 +1,16 @@
/* eslint-disable no-param-reassign */
const { deleteQuery } = require('../../queries');
const getDelete = collection => async (_, args, context) => {
const options = {
...collection,
id: args.id,
user: context.user,
};
const result = await deleteQuery(options);
return result;
};
module.exports = getDelete;

View File

@@ -0,0 +1,33 @@
/* eslint-disable no-param-reassign */
const find = require('../../queries/find');
const getFind = collection => async (_, args, context) => {
const options = {
...collection,
depth: 0,
query: {},
paginate: {},
user: context.user,
};
if (args.where) options.query.where = args.where;
if (args.limit) options.paginate.limit = args.limit;
if (args.page) options.paginate.page = args.page;
if (args.sort) options.paginate.sort = args.sort;
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
if (args.fallbackLocale) {
context.fallbackLocale = args.fallbackLocale;
options.fallbackLocale = args.fallbackLocale;
}
const results = await find(options);
return results;
};
module.exports = getFind;

View File

@@ -0,0 +1,27 @@
/* eslint-disable no-param-reassign */
const findByIDQuery = require('../../queries/findByID');
const findByID = collection => async (_, args, context) => {
const options = {
...collection,
depth: 0,
id: args.id,
user: context.user,
};
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
if (args.fallbackLocale) {
context.fallbackLocale = args.fallbackLocale;
options.fallbackLocale = args.fallbackLocale;
}
const result = await findByIDQuery(options);
return result;
};
module.exports = findByID;

View File

@@ -1,29 +0,0 @@
/* eslint-disable no-param-reassign */
const withDefaultLocale = require('../../../graphql/resolvers/withDefaultLocale');
const withPolicy = require('../../../graphql/resolvers/withPolicy');
const createQuery = require('../../queries/create');
const create = (config, collection) => withDefaultLocale(
config.localization,
withPolicy(
collection.config.policies.create,
async (_, args, context) => {
const options = {
model: collection.model,
locale: context.locale,
data: args.data,
};
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
const result = await createQuery(options);
return result;
},
),
);
module.exports = create;

View File

@@ -1,19 +0,0 @@
/* eslint-disable no-param-reassign */
const withPolicy = require('../../../graphql/resolvers/withPolicy');
const { deleteQuery } = require('../../queries');
const getDelete = collection => withPolicy(
collection.config.policies.delete,
async (_, args) => {
const options = {
model: collection.model,
id: args.id,
};
const result = await deleteQuery(options);
return result;
},
);
module.exports = getDelete;

View File

@@ -1,42 +0,0 @@
/* eslint-disable no-param-reassign */
const withDefaultLocale = require('../../../graphql/resolvers/withDefaultLocale');
const withPolicy = require('../../../graphql/resolvers/withPolicy');
const find = require('../../queries/find');
const getFind = (config, collection) => withDefaultLocale(
config.localization,
withPolicy(
collection.config.policies.read,
async (_, args, context) => {
const options = {
depth: 0,
model: collection.model,
query: {},
paginate: {},
locale: context.locale,
fallbackLocale: context.fallbackLocale,
};
if (args.where) options.query.where = args.where;
if (args.limit) options.paginate.limit = args.limit;
if (args.page) options.paginate.page = args.page;
if (args.sort) options.paginate.sort = args.sort;
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
if (args.fallbackLocale) {
context.fallbackLocale = args.fallbackLocale;
options.fallbackLocale = args.fallbackLocale;
}
const results = await find(options);
return results;
},
),
);
module.exports = getFind;

View File

@@ -1,36 +0,0 @@
/* eslint-disable no-param-reassign */
const withDefaultLocale = require('../../../graphql/resolvers/withDefaultLocale');
const withPolicy = require('../../../graphql/resolvers/withPolicy');
const findByIDQuery = require('../../queries/findByID');
const findByID = (config, collection) => withDefaultLocale(
config.localization,
withPolicy(
collection.config.policies.read,
async (_, args, context) => {
const options = {
depth: 0,
model: collection.model,
id: args.id,
locale: context.locale,
fallbackLocale: context.fallbackLocale,
};
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
if (args.fallbackLocale) {
context.fallbackLocale = args.fallbackLocale;
options.fallbackLocale = args.fallbackLocale;
}
const result = await findByIDQuery(options);
return result;
},
),
);
module.exports = findByID;

View File

@@ -1,30 +0,0 @@
/* eslint-disable no-param-reassign */
const withDefaultLocale = require('../../../graphql/resolvers/withDefaultLocale');
const withPolicy = require('../../../graphql/resolvers/withPolicy');
const updateQuery = require('../../queries/update');
const update = (config, collection) => withDefaultLocale(
config.localization,
withPolicy(
collection.config.policies.update,
async (_, args, context) => {
const options = {
model: collection.model,
locale: context.locale,
data: args.data,
id: args.id,
};
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
const result = await updateQuery(options);
return result;
},
),
);
module.exports = update;

View File

@@ -1,13 +1,13 @@
const getFindByID = require('./getFindByID');
const getFind = require('./getFind');
const getCreate = require('./getCreate');
const getUpdate = require('./getUpdate');
const getDelete = require('./getDelete');
const findByID = require('./findByID');
const find = require('./find');
const create = require('./create');
const update = require('./update');
const deleteResolver = require('./delete');
module.exports = {
getFindByID,
getFind,
getCreate,
getUpdate,
getDelete,
findByID,
find,
create,
update,
deleteResolver,
};

View File

@@ -0,0 +1,23 @@
/* eslint-disable no-param-reassign */
const updateQuery = require('../../queries/update');
const update = collection => async (_, args, context) => {
const options = {
...collection,
locale: context.locale,
data: args.data,
id: args.id,
user: context.user,
};
if (args.locale) {
context.locale = args.locale;
options.locale = args.locale;
}
const result = await updateQuery(options);
return result;
};
module.exports = update;

View File

@@ -1,14 +1,31 @@
const { Forbidden } = require('../../errors');
const executePolicy = require('../../auth/executePolicy');
const create = async (options) => {
try {
// Await validation here
const {
model,
data,
config,
user,
} = options;
// Await pre-hook here
const policy = config && config.policies && config.policies.create;
const hasPermission = await executePolicy(user, policy);
const doc = await options.model.create(options.data);
if (hasPermission) {
// Await validation here
// Await post hook here
// Await pre-hook here
return doc.toJSON({ virtuals: true });
const doc = await model.create(data);
// Await post hook here
return doc.toJSON({ virtuals: true });
}
throw new Forbidden();
} catch (err) {
throw err;
}

View File

@@ -1,12 +1,26 @@
const deleteQuery = async ({ id, model }) => {
const { Forbidden } = require('../../errors');
const executePolicy = require('../../auth/executePolicy');
const deleteQuery = async (options) => {
try {
// Await pre-hook here
const {
model,
id,
user,
config,
} = options;
const result = await model.findOneAndDelete({ _id: id });
const policy = config && config.policies && config.policies.delete;
const hasPermission = await executePolicy(user, policy);
// Await post hook here
if (hasPermission) {
// Await pre-hook here
return result;
const result = await model.findOneAndDelete({ _id: id });
return result.toJSON({ virtuals: true });
// Await post hook here
}
throw new Forbidden();
} catch (err) {
throw err;
}

View File

@@ -1,4 +1,5 @@
const { APIError } = require('../../errors');
const { Forbidden } = require('../../errors');
const executePolicy = require('../../auth/executePolicy');
const find = async (options) => {
try {
@@ -9,44 +10,52 @@ const find = async (options) => {
fallbackLocale,
paginate = {},
depth,
config,
user,
} = options;
// await pre find hook here
const policy = config && config.policies && config.policies.read;
const hasPermission = await executePolicy(user, policy);
const mongooseQuery = await model.buildQuery(query, locale);
if (hasPermission) {
// await pre find hook here
const mongooseOptions = {
options: {},
};
const mongooseQuery = await model.buildQuery(query, locale);
if (paginate.page) mongooseOptions.page = paginate.page;
if (paginate.limit) mongooseOptions.limit = paginate.limit;
if (paginate.sort) mongooseOptions.sort = paginate.sort;
if (depth && depth !== '0') {
mongooseOptions.options.autopopulate = {
maxDepth: parseInt(depth, 10),
const mongooseOptions = {
options: {},
};
if (paginate.page) mongooseOptions.page = paginate.page;
if (paginate.limit) mongooseOptions.limit = paginate.limit;
if (paginate.sort) mongooseOptions.sort = paginate.sort;
if (depth && depth !== '0') {
mongooseOptions.options.autopopulate = {
maxDepth: parseInt(depth, 10),
};
} else {
mongooseOptions.options.autopopulate = false;
}
const result = await model.paginate(mongooseQuery, mongooseOptions);
// await post find hook here
return {
...result,
docs: result.docs.map((doc) => {
if (locale && doc.setLocale) {
doc.setLocale(locale, fallbackLocale);
}
return doc.toJSON({ virtuals: true });
}),
};
} else {
mongooseOptions.options.autopopulate = false;
}
const result = await model.paginate(mongooseQuery, mongooseOptions);
// await post find hook here
return {
...result,
docs: result.docs.map((doc) => {
if (locale && doc.setLocale) {
doc.setLocale(locale, fallbackLocale);
}
return doc.toJSON({ virtuals: true });
}),
};
throw new Forbidden();
} catch (err) {
throw new APIError();
throw err;
}
};

View File

@@ -1,36 +1,49 @@
const { NotFound } = require('../../errors');
const { Forbidden, NotFound } = require('../../errors');
const executePolicy = require('../../auth/executePolicy');
const findByID = async (options) => {
const mongooseOptions = {
options: {},
};
const {
depth, locale, fallbackLocale, model, id,
} = options;
if (depth && depth !== '0') {
mongooseOptions.options.autopopulate = {
maxDepth: parseInt(depth, 10),
};
} else {
mongooseOptions.options.autopopulate = false;
}
try {
// Await pre find hook here
const {
depth,
locale,
fallbackLocale,
model,
config,
id,
user,
} = options;
const result = await model.findOne({ _id: id }, {}, mongooseOptions);
const policy = config && config.policies && config.policies.read;
const hasPermission = await executePolicy(user, policy);
if (!result) throw new NotFound();
if (hasPermission) {
const mongooseOptions = {
options: {},
};
if (locale && result.setLocale) {
result.setLocale(locale, fallbackLocale);
if (depth && depth !== '0') {
mongooseOptions.options.autopopulate = {
maxDepth: parseInt(depth, 10),
};
} else {
mongooseOptions.options.autopopulate = false;
}
// Await pre find hook here
const result = await model.findOne({ _id: id }, {}, mongooseOptions);
if (!result) throw new NotFound();
if (locale && result.setLocale) {
result.setLocale(locale, fallbackLocale);
}
// Await post find hook here
return result.toJSON({ virtuals: true });
}
// Await post find hook here
return result.toJSON({ virtuals: true });
throw new Forbidden();
} catch (err) {
throw err;
}

View File

@@ -1,21 +1,33 @@
const { Forbidden } = require('../../errors');
const executePolicy = require('../../auth/executePolicy');
const update = async (options) => {
try {
const {
id,
model,
data,
config,
user,
} = options;
// Await validation here
// Await pre-hook here
const policy = config && config.policies && config.policies.update;
const hasPermission = await executePolicy(user, policy);
const doc = await model.findOne({ _id: id });
Object.assign(doc, data);
await doc.save();
if (hasPermission) {
// Await validation here
// Await post hook here
// Await pre-hook here
return doc.toJSON({ virtuals: true });
const doc = await model.findOne({ _id: id });
Object.assign(doc, data);
await doc.save();
// Await post hook here
return doc.toJSON({ virtuals: true });
}
throw new Forbidden();
} catch (err) {
throw err;
}

View File

@@ -7,6 +7,8 @@ const createHandler = async (req, res) => {
try {
const doc = await create({
model: req.model,
config: req.collection,
user: req.user,
data: req.body,
});

View File

@@ -6,6 +6,8 @@ const deleteHandler = async (req, res) => {
try {
const doc = await deleteQuery({
model: req.model,
config: req.collection,
user: req.user,
id: req.params.id,
});

View File

@@ -5,6 +5,8 @@ const findHandler = async (req, res) => {
try {
const options = {
model: req.model,
config: req.collection,
user: req.user,
query: {},
paginate: {
page: req.query.page,

View File

@@ -5,6 +5,8 @@ const formatErrorResponse = require('../../express/responses/formatError');
const findByIDHandler = async (req, res) => {
const options = {
model: req.model,
config: req.collection,
user: req.user,
id: req.params.id,
locale: req.locale,
fallbackLocale: req.query['fallback-locale'],

View File

@@ -8,6 +8,8 @@ const updateHandler = async (req, res) => {
try {
const doc = await update({
model: req.model,
config: req.collection,
user: req.user,
id: req.params.id,
data: req.body,
});

View File

@@ -1,7 +1,6 @@
const express = require('express');
const requestHandlers = require('./requestHandlers');
const bindModelMiddleware = require('../express/middleware/bindModel');
const loadPolicy = require('../express/middleware/loadPolicy');
const bindCollectionMiddleware = require('./bindCollection');
const {
@@ -16,13 +15,13 @@ const registerRoutes = ({ model, config }) => {
bindCollectionMiddleware(config));
router.route(`/${config.slug}`)
.get(loadPolicy(config.policies.read), find)
.post(loadPolicy(config.policies.create), create);
.get(find)
.post(create);
router.route(`/${config.slug}/:id`)
.get(loadPolicy(config.policies.read), findByID)
.put(loadPolicy(config.policies.update), update)
.delete(loadPolicy(config.policies.delete), deleteHandler);
.get(findByID)
.put(update)
.delete(deleteHandler);
return router;
};

View File

@@ -1,28 +0,0 @@
const httpStatus = require('http-status');
const { Forbidden } = require('../../errors');
const formatErrorResponse = require('../responses/formatError');
const requireAuth = (req, res, next) => {
if (!req.user) {
res.status(httpStatus.UNAUTHORIZED).json(formatErrorResponse(new Forbidden(), 'APIError'));
}
return next();
};
const loadPolicy = (policy) => {
return [
(req, res, next) => {
if (policy) {
if (!policy(req.user)) {
return res.status(httpStatus.FORBIDDEN)
.json(formatErrorResponse(new Forbidden(), 'APIError'));
}
return next();
}
return requireAuth(req, res, next);
}];
};
module.exports = loadPolicy;

View File

@@ -1,7 +1,6 @@
const express = require('express');
const requestHandlers = require('./requestHandlers');
const bindModelMiddleware = require('../express/middleware/bindModel');
const loadPolicy = require('../express/middleware/loadPolicy');
const getMiddleware = require('./middleware');
const { upsert, findOne } = requestHandlers;
@@ -17,9 +16,9 @@ const registerGlobals = (globalConfigs, Globals) => {
router
.route(`/globals/${global.slug}`)
.get(loadPolicy(global.policies.read), findOne)
.post(loadPolicy(global.policies.create), upsert)
.put(loadPolicy(global.policies.update), upsert);
.get(findOne)
.post(upsert)
.put(upsert);
});
return router;

View File

@@ -1,11 +0,0 @@
/* eslint-disable no-param-reassign */
const withDefaultLocale = (localization, resolver) => (_, args, context) => {
const { defaultLocale, fallback } = localization;
context.locale = defaultLocale;
context.fallbackLocale = fallback ? defaultLocale : null;
return resolver(_, args, context);
};
module.exports = withDefaultLocale;

View File

@@ -1,21 +0,0 @@
const { Forbidden } = require('../../errors');
const withPolicy = (policy, resolver) => (_, args, context) => {
const { user } = context;
if (policy) {
if (!policy(user)) {
throw new Forbidden();
}
return resolver(_, args, context);
}
if (user) {
return resolver(_, args, context);
}
throw new Forbidden();
};
module.exports = withPolicy;

View File

@@ -6,7 +6,7 @@ const {
const formatName = require('../../graphql/utilities/formatName');
const {
getCreate, getFind, getFindByID, getDelete, getUpdate,
create, find, findByID, deleteResolver, update,
} = require('../../collections/graphql/resolvers');
const buildPaginatedListType = require('../../graphql/schema/buildPaginatedListType');
@@ -55,7 +55,7 @@ function registerUpload() {
locale: { type: this.types.localeInputType },
fallbackLocale: { type: this.types.fallbackLocaleInputType },
},
resolve: getFindByID(this.config, this.Upload),
resolve: findByID(this.Upload),
};
this.Query.fields[pluralLabel] = {
@@ -68,7 +68,7 @@ function registerUpload() {
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
resolve: getFind(this.config, this.Upload),
resolve: find(this.Upload),
};
this.Mutation.fields[`update${singularLabel}`] = {
@@ -77,7 +77,7 @@ function registerUpload() {
id: { type: new GraphQLNonNull(GraphQLString) },
data: { type: this.Upload.graphQL.mutationInputType },
},
resolve: getUpdate(this.config, this.Upload),
resolve: update(this.Upload),
};
this.Mutation.fields[`delete${singularLabel}`] = {
@@ -85,7 +85,7 @@ function registerUpload() {
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: getDelete(this.Upload),
resolve: deleteResolver(this.Upload),
};
}