Merge branch 'master' into organization-contact

This commit is contained in:
Wyatt Johnson
2018-04-12 13:11:35 -06:00
committed by GitHub
59 changed files with 1559 additions and 548 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
const { forEachField } = require('./utils');
const { maskErrors } = require('graphql-errors');
const errors = require('../errors');
const { TalkError } = require('../errors');
const { Error: { ValidationError } } = require('mongoose');
// If an APIError happens in a mutation, then respond with `{errors: Array}`
@@ -11,7 +11,7 @@ const decorateWithMutationErrorHandler = field => {
try {
return await fieldResolver(obj, args, ctx, info);
} catch (err) {
if (err instanceof errors.APIError) {
if (err instanceof TalkError) {
return {
errors: [err],
};
+3 -3
View File
@@ -57,7 +57,7 @@ const findOrCreateAssetByURL = async (ctx, url) => {
try {
new URL(url);
} catch (err) {
throw ErrInvalidAssetURL;
throw new ErrInvalidAssetURL(url);
}
// Try the easy lookup first.
@@ -76,7 +76,7 @@ const findOrCreateAssetByURL = async (ctx, url) => {
// If the domain wasn't whitelisted, then we shouldn't create this asset!
if (!whitelisted) {
throw ErrInvalidAssetURL;
throw new ErrInvalidAssetURL(url);
}
// Construct the update operator that we'll use to create the asset.
@@ -135,7 +135,7 @@ const findByUrl = async (
try {
new URL(asset_url);
} catch (err) {
throw errors.ErrInvalidAssetURL;
throw new errors.ErrInvalidAssetURL(asset_url);
}
return Assets.findByUrl(asset_url);
+5 -5
View File
@@ -1,4 +1,4 @@
const errors = require('../../errors');
const { ErrNotFound, ErrNotAuthorized } = require('../../errors');
const { CREATE_ACTION, DELETE_ACTION } = require('../../perms/constants');
const { IGNORE_FLAGS_AGAINST_STAFF } = require('../../config');
@@ -40,7 +40,7 @@ const createAction = async (
// Gets the item referenced by the action.
const item = await getActionItem(ctx, { item_id, item_type });
if (!item || item === null) {
throw errors.ErrNotFound;
throw new ErrNotFound();
}
// If we are ignoring flags against staff, ensure that the target isn't a
@@ -59,7 +59,7 @@ const createAction = async (
// The item is a user, and this is a flag. Check to see if they are staff,
// if they are, don't permit the flag.
if (item.isStaff()) {
throw errors.ErrNotAuthorized;
throw new ErrNotAuthorized();
}
}
@@ -108,8 +108,8 @@ const deleteAction = (ctx, { id }) => {
module.exports = ctx => {
let mutators = {
Action: {
create: () => Promise.reject(errors.ErrNotAuthorized),
delete: () => Promise.reject(errors.ErrNotAuthorized),
create: () => Promise.reject(new ErrNotAuthorized()),
delete: () => Promise.reject(new ErrNotAuthorized()),
},
};
+5 -5
View File
@@ -1,4 +1,4 @@
const errors = require('../../errors');
const { ErrNotAuthorized } = require('../../errors');
const {
UPDATE_ASSET_SETTINGS,
UPDATE_ASSET_STATUS,
@@ -71,10 +71,10 @@ const scrapeAsset = async (ctx, id) => {
module.exports = ctx => {
let mutators = {
Asset: {
updateSettings: () => Promise.reject(errors.ErrNotAuthorized),
updateStatus: () => Promise.reject(errors.ErrNotAuthorized),
closeNow: () => Promise.reject(errors.ErrNotAuthorized),
scrape: () => Promise.reject(errors.ErrNotAuthorized),
updateSettings: () => Promise.reject(new ErrNotAuthorized()),
updateStatus: () => Promise.reject(new ErrNotAuthorized()),
closeNow: () => Promise.reject(new ErrNotAuthorized()),
scrape: () => Promise.reject(new ErrNotAuthorized()),
},
};
+4 -4
View File
@@ -1,4 +1,4 @@
const errors = require('../../errors');
const { ErrNotAuthorized } = require('../../errors');
const ActionModel = require('../../models/action');
const ActionsService = require('../../services/actions');
const TagsService = require('../../services/tags');
@@ -312,9 +312,9 @@ const editComment = async (
module.exports = ctx => {
let mutators = {
Comment: {
create: () => Promise.reject(errors.ErrNotAuthorized),
setStatus: () => Promise.reject(errors.ErrNotAuthorized),
edit: () => Promise.reject(errors.ErrNotAuthorized),
create: () => Promise.reject(new ErrNotAuthorized()),
setStatus: () => Promise.reject(new ErrNotAuthorized()),
edit: () => Promise.reject(new ErrNotAuthorized()),
},
};
+2 -2
View File
@@ -1,4 +1,4 @@
const errors = require('../../errors');
const { ErrNotAuthorized } = require('../../errors');
const { UPDATE_SETTINGS } = require('../../perms/constants');
@@ -9,7 +9,7 @@ const update = async (ctx, settings) => SettingsService.update(settings);
module.exports = ctx => {
let mutators = {
Settings: {
update: () => Promise.reject(errors.ErrNotAuthorized),
update: () => Promise.reject(new ErrNotAuthorized()),
},
};
+3 -3
View File
@@ -1,5 +1,5 @@
const TagsService = require('../../services/tags');
const errors = require('../../errors');
const { ErrNotAuthorized } = require('../../errors');
const {
ADD_COMMENT_TAG,
REMOVE_COMMENT_TAG,
@@ -31,8 +31,8 @@ const modify = async (
module.exports = context => {
let mutators = {
Tag: {
add: () => Promise.reject(errors.ErrNotAuthorized),
remove: () => Promise.reject(errors.ErrNotAuthorized),
add: () => Promise.reject(new ErrNotAuthorized()),
remove: () => Promise.reject(new ErrNotAuthorized()),
},
};
+3 -3
View File
@@ -1,4 +1,4 @@
const errors = require('../../errors');
const { ErrNotAuthorized } = require('../../errors');
const TokensService = require('../../services/tokens');
const { CREATE_TOKEN, REVOKE_TOKEN } = require('../../perms/constants');
@@ -21,8 +21,8 @@ const revokeToken = async ({ user }, { id }) => {
module.exports = context => {
let mutators = {
Token: {
create: () => Promise.reject(errors.ErrNotAuthorized),
revoke: () => Promise.reject(errors.ErrNotAuthorized),
create: () => Promise.reject(new ErrNotAuthorized()),
revoke: () => Promise.reject(new ErrNotAuthorized()),
},
};
+11 -11
View File
@@ -1,4 +1,4 @@
const errors = require('../../errors');
const { ErrNotFound, ErrNotAuthorized } = require('../../errors');
const UsersService = require('../../services/users');
const migrationHelpers = require('../../services/migration/helpers');
const {
@@ -92,7 +92,7 @@ const delUser = async (ctx, id) => {
// Find the user we're removing.
const user = await User.findOne({ id });
if (!user) {
throw errors.ErrNotFound;
throw new ErrNotFound();
}
// Get the query transformer we'll use to help batch process the user
@@ -156,15 +156,15 @@ const delUser = async (ctx, id) => {
module.exports = ctx => {
let mutators = {
User: {
changeUsername: () => Promise.reject(errors.ErrNotAuthorized),
ignoreUser: () => Promise.reject(errors.ErrNotAuthorized),
setRole: () => Promise.reject(errors.ErrNotAuthorized),
setUserBanStatus: () => Promise.reject(errors.ErrNotAuthorized),
setUserSuspensionStatus: () => Promise.reject(errors.ErrNotAuthorized),
setUserUsernameStatus: () => Promise.reject(errors.ErrNotAuthorized),
setUsername: () => Promise.reject(errors.ErrNotAuthorized),
stopIgnoringUser: () => Promise.reject(errors.ErrNotAuthorized),
del: () => Promise.reject(errors.ErrNotAuthorized),
changeUsername: () => Promise.reject(new ErrNotAuthorized()),
ignoreUser: () => Promise.reject(new ErrNotAuthorized()),
setRole: () => Promise.reject(new ErrNotAuthorized()),
setUserBanStatus: () => Promise.reject(new ErrNotAuthorized()),
setUserSuspensionStatus: () => Promise.reject(new ErrNotAuthorized()),
setUserUsernameStatus: () => Promise.reject(new ErrNotAuthorized()),
setUsername: () => Promise.reject(new ErrNotAuthorized()),
stopIgnoringUser: () => Promise.reject(new ErrNotAuthorized()),
del: () => Promise.reject(new ErrNotAuthorized()),
},
};
+21 -3
View File
@@ -1,6 +1,14 @@
const { property } = require('lodash');
const { SEARCH_ACTIONS } = require('../../perms/constants');
const { decorateWithTags, decorateWithPermissionCheck } = require('./util');
const {
SEARCH_ACTIONS,
SEARCH_COMMENT_STATUS_HISTORY,
VIEW_BODY_HISTORY,
} = require('../../perms/constants');
const {
decorateWithTags,
decorateWithPermissionCheck,
checkSelfField,
} = require('./util');
const Comment = {
hasParent({ parent_id }) {
@@ -60,9 +68,19 @@ const Comment = {
// Decorate the Comment type resolver with a tags field.
decorateWithTags(Comment);
// Protect direct action access.
// Protect direct action and status history access.
decorateWithPermissionCheck(Comment, {
actions: [SEARCH_ACTIONS],
status_history: [SEARCH_COMMENT_STATUS_HISTORY],
});
// Protect privileged fields.
decorateWithPermissionCheck(
Comment,
{
body_history: [VIEW_BODY_HISTORY],
},
checkSelfField('author_id')
);
module.exports = Comment;
+2 -2
View File
@@ -29,9 +29,9 @@ const User = {
return Comments.getByQuery(query);
},
ignoredUsers({ ignoresUsers }, args, { user, loaders: { Users } }) {
ignoredUsers({ ignoresUsers }, args, { loaders: { Users } }) {
// Return nothing if there is nothing to query for.
if (!user.ignoresUsers || user.ignoresUsers.length <= 0) {
if (!ignoresUsers || ignoresUsers.length <= 0) {
return [];
}
+3 -2
View File
@@ -505,8 +505,9 @@ type Comment {
# The actual comment data.
body: String!
# The body history of the comment.
body_history: [CommentBodyHistory!]!
# The body history of the comment. Requires the `ADMIN` or `MODERATOR` role or
# the author.
body_history: [CommentBodyHistory!]
# The tags on the comment
tags: [TagLink!]