diff --git a/.eslintrc.json b/.eslintrc.json index 237650932..8ca153cbc 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,9 @@ "es6": true, "node": true }, - "extends": "eslint:recommended", + "extends": [ + "eslint:recommended" + ], "parserOptions": { "ecmaVersion": 2017 }, @@ -12,9 +14,7 @@ "json" ], "rules": { - "indent": ["error", - 2 - ], + "indent": ["error", 2], "no-console": "off", "linebreak-style": ["error", "unix"], "quotes": ["error", "single"], @@ -29,7 +29,7 @@ "no-global-assign": "error", "no-implied-eval": "error", "lines-around-comment": ["warn", {"beforeLineComment": true}], - "spaced-comment": ["warn", "always", { "line": { "exceptions": ["-", "="] } }], + "spaced-comment": ["warn", "always", {"line": {"exceptions": ["-", "="]}}], "no-script-url": "error", "no-throw-literal": "error", "yoda": "warn", @@ -41,32 +41,20 @@ "object-curly-spacing": "warn", "space-infix-ops": ["error"], "space-in-parens": ["error", "never"], - "space-unary-ops": ["error", { - "words": true, - "nonwords": false - }], + "space-unary-ops": ["error", {"words": true, "nonwords": false}], "no-const-assign": "error", "no-duplicate-imports": "error", "prefer-template": "warn", - "comma-spacing": ["error", { - "after": true - }], + "comma-spacing": ["error", {"after": true}], "no-var": "error", "no-lonely-if": "error", "curly": "error", - "no-unused-vars": ["error", { - "argsIgnorePattern": "^_|next", - "varsIgnorePattern": "^_" - }], - "no-multiple-empty-lines": ["error", { - "max": 1 - }], - "newline-per-chained-call": ["error", { - "ignoreChainWithDepth": 2 - }], + "no-unused-vars": ["error", {"argsIgnorePattern": "^_|next", "varsIgnorePattern": "^_"}], + "no-multiple-empty-lines": ["error", {"max": 1}], + "newline-per-chained-call": ["error", {"ignoreChainWithDepth": 2}], "promise/no-return-wrap": "error", "promise/param-names": "error", - "promise/catch-or-return": "error", + "promise/catch-or-return": "warn", "promise/no-native": "off", "promise/no-nesting": "warn", "promise/no-promise-in-callback": "warn", diff --git a/client/coral-admin/src/actions/install.js b/client/coral-admin/src/actions/install.js index d6b27115a..02d562d65 100644 --- a/client/coral-admin/src/actions/install.js +++ b/client/coral-admin/src/actions/install.js @@ -128,18 +128,18 @@ const checkInstallRequest = () => ({type: actions.CHECK_INSTALL_REQUEST}); const checkInstallSuccess = (installed) => ({type: actions.CHECK_INSTALL_SUCCESS, installed}); const checkInstallFailure = (error) => ({type: actions.CHECK_INSTALL_FAILURE, error}); -export const checkInstall = (next) => (dispatch, _, {rest}) => { +export const checkInstall = (next) => async (dispatch, _, {rest}) => { dispatch(checkInstallRequest()); - rest('/setup') - .then(({installed}) => { - dispatch(checkInstallSuccess(installed)); - if (installed) { - next(); - } - }) - .catch((error) => { - console.error(error); - const errorMessage = error.translation_key ? t(`error.${error.translation_key}`) : error.toString(); - dispatch(checkInstallFailure(errorMessage)); - }); + + try { + const {installed} = await rest('/setup'); + dispatch(checkInstallSuccess(installed)); + if (installed) { + next(); + } + } catch (error) { + console.error(error); + const errorMessage = error.translation_key ? t(`error.${error.translation_key}`) : error.toString(); + dispatch(checkInstallFailure(errorMessage)); + } }; diff --git a/client/coral-admin/src/components/UserDetail.js b/client/coral-admin/src/components/UserDetail.js index a7eadbac3..fd44d5f17 100644 --- a/client/coral-admin/src/components/UserDetail.js +++ b/client/coral-admin/src/components/UserDetail.js @@ -28,16 +28,26 @@ export default class UserDetail extends React.Component { bulkReject: PropTypes.func.isRequired, } - rejectThenReload = (info) => { - this.props.rejectComment(info).then(() => { + rejectThenReload = async (info) => { + try { + await this.props.rejectComment(info); this.props.data.refetch(); - }); + } catch (err) { + + // TODO: handle error. + console.error(err); + } } - acceptThenReload = (info) => { - this.props.acceptComment(info).then(() => { + acceptThenReload = async (info) => { + try { + await this.props.acceptComment(info); this.props.data.refetch(); - }); + } catch (err) { + + // TODO: handle error. + console.error(err); + } } showAll = () => { @@ -133,7 +143,7 @@ export default class UserDetail extends React.Component {
diff --git a/client/coral-admin/src/containers/UserDetail.js b/client/coral-admin/src/containers/UserDetail.js index 0eb81a9a1..5effb2b84 100644 --- a/client/coral-admin/src/containers/UserDetail.js +++ b/client/coral-admin/src/containers/UserDetail.js @@ -36,14 +36,19 @@ class UserDetailContainer extends React.Component { isLoadingMore = false; // status can be 'ACCEPTED' or 'REJECTED' - bulkSetCommentStatus = (status) => { + bulkSetCommentStatus = async (status) => { const changes = this.props.selectedCommentIds.map((commentId) => { return this.props.setCommentStatus({commentId, status}); }); - Promise.all(changes).then(() => { + try { + await Promise.all(changes); this.props.clearUserDetailSelections(); // un-select everything - }); + } catch (err) { + + // TODO: handle error. + console.error(err); + } } bulkReject = () => { diff --git a/client/coral-admin/src/routes/Community/components/FlaggedUser.js b/client/coral-admin/src/routes/Community/components/FlaggedUser.js index 5b2238592..81d7790fe 100644 --- a/client/coral-admin/src/routes/Community/components/FlaggedUser.js +++ b/client/coral-admin/src/routes/Community/components/FlaggedUser.js @@ -85,7 +85,7 @@ class User extends React.Component { {t('community.flags')}({ user.actions.length }) : - { user.action_summaries.map( + { user.action_summaries.map( (action, i) => { return {shortReasons[action.reason]} ({action.count}) diff --git a/client/coral-admin/src/routes/Community/components/RejectUsernameDialog.js b/client/coral-admin/src/routes/Community/components/RejectUsernameDialog.js index 128946b61..4932021bd 100644 --- a/client/coral-admin/src/routes/Community/components/RejectUsernameDialog.js +++ b/client/coral-admin/src/routes/Community/components/RejectUsernameDialog.js @@ -48,11 +48,15 @@ class RejectUsernameDialog extends Component { const cancel = this.props.handleClose; const next = () => this.setState({stage: stage + 1}); - const suspend = () => { - rejectUsername({id: user.user.id, message: this.state.email}) - .then(() => { - this.props.handleClose(); - }); + const suspend = async () => { + try { + await rejectUsername({id: user.user.id, message: this.state.email}); + this.props.handleClose(); + } catch (err) { + + // TODO: handle error. + console.error(err); + } }; const suspendModalActions = [ diff --git a/client/coral-admin/src/routes/Stories/components/Stories.js b/client/coral-admin/src/routes/Stories/components/Stories.js index 5b931e6fc..d57b8f779 100644 --- a/client/coral-admin/src/routes/Stories/components/Stories.js +++ b/client/coral-admin/src/routes/Stories/components/Stories.js @@ -50,17 +50,22 @@ export default class Stories extends Component { return `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`; } - onStatusClick = (closeStream, id, statusMenuOpen) => () => { + onStatusClick = (closeStream, id, statusMenuOpen) => async () => { if (statusMenuOpen) { this.setState((prev) => { prev.statusMenus[id] = false; return prev; }); - this.props.updateAssetState(id, closeStream ? Date.now() : null) - .then(() => { - const {search, sort, filter, page} = this.state; - this.props.fetchAssets(page, limit, search, sort, filter); - }); + + try { + await this.props.updateAssetState(id, closeStream ? Date.now() : null); + const {search, sort, filter, page} = this.state; + this.props.fetchAssets(page, limit, search, sort, filter); + } catch (err) { + + // TODO: handle error. + console.error(err); + } } else { this.setState((prev) => { prev.statusMenus[id] = true; diff --git a/client/coral-embed-stream/src/components/StreamTabPanel.js b/client/coral-embed-stream/src/components/StreamTabPanel.js index a511ac555..50f54c2a0 100644 --- a/client/coral-embed-stream/src/components/StreamTabPanel.js +++ b/client/coral-embed-stream/src/components/StreamTabPanel.js @@ -15,8 +15,8 @@ class StreamTabPanel extends React.Component { {loading ?
: - {tabPanes} - + {tabPanes} + } ); diff --git a/graph/loaders/users.js b/graph/loaders/users.js index ac3493479..b943c60ed 100644 --- a/graph/loaders/users.js +++ b/graph/loaders/users.js @@ -3,6 +3,10 @@ const DataLoader = require('dataloader'); const util = require('./util'); const union = require('lodash/union'); +const { + SEARCH_OTHER_USERS, +} = require('../../perms/constants'); + const UsersService = require('../../services/users'); const UserModel = require('../../models/user'); @@ -28,12 +32,23 @@ const genUserByIDs = async (context, ids) => { * @param {Object} query query terms to apply to the users query */ const getUsersByQuery = async ({user, loaders: {Actions}}, {ids, limit, cursor, statuses, action_type, sortOrder}) => { - let query = UserModel.find(); - if (action_type) { - const userIds = await Actions.getByTypes({action_type, item_type: 'USERS'}); - ids = ids ? union(ids, userIds) : userIds; + if (action_type || statuses) { + if (!user || !user.can(SEARCH_OTHER_USERS)) { + return null; + } + + if (statuses) { + query = query.where({ + status: { + $in: statuses + } + }); + } else { + const userIds = await Actions.getByTypes({action_type, item_type: 'USERS'}); + ids = ids ? union(ids, userIds) : userIds; + } } if (ids) { @@ -44,14 +59,6 @@ const getUsersByQuery = async ({user, loaders: {Actions}}, {ids, limit, cursor, }); } - if (statuses) { - query = query.where({ - status: { - $in: statuses - } - }); - } - if (cursor) { if (sortOrder === 'DESC') { query = query.where({ diff --git a/package.json b/package.json index 3d054e0d6..21a127a11 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ "build": "WEBPACK=TRUE NODE_ENV=production webpack -p --config webpack.config.js --bail", "prebuild-watch": "yarn generate-introspection", "build-watch": "WEBPACK=TRUE NODE_ENV=development webpack --progress --config webpack.config.js --watch", - "lint": "eslint --ext .json bin/* .", - "lint-fix": "eslint bin/* . --fix", + "lint": "eslint --ext=.js --ext=.json bin/* .", + "lint-fix": "yarn lint --fix", "test": "TEST_MODE=unit NODE_ENV=test mocha -R ${MOCHA_REPORTER:-spec}", "test-cover": "TEST_MODE=unit NODE_ENV=test istanbul cover _mocha --report text --check-coverage -- -R spec", "heroku-postbuild": "./bin/cli plugins reconcile && yarn build",