From 33be00a5404cded4b4b5b8b9d1f0ba37533a96f8 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 10 May 2018 16:44:19 -0600 Subject: [PATCH 01/19] Added support for external signins on Admin --- .../coral-admin/src/components/External.css | 16 ++++ client/coral-admin/src/components/External.js | 24 +++++ client/coral-admin/src/components/SignIn.js | 90 ++++++++++--------- client/coral-admin/src/containers/SignIn.js | 4 +- .../coral-framework/services/postMessage.js | 6 +- client/coral-framework/utils/index.js | 20 +++++ plugin-api/beta/client/utils/index.js | 1 + .../client/actions.js | 4 +- .../talk-plugin-google-auth/client/actions.js | 4 +- 9 files changed, 121 insertions(+), 48 deletions(-) create mode 100644 client/coral-admin/src/components/External.css create mode 100644 client/coral-admin/src/components/External.js diff --git a/client/coral-admin/src/components/External.css b/client/coral-admin/src/components/External.css new file mode 100644 index 000000000..ff23c53cc --- /dev/null +++ b/client/coral-admin/src/components/External.css @@ -0,0 +1,16 @@ +.external { + margin-bottom: 20px; +} + +.separator h5 { + text-align: center; + font-size: 1.2em; +} + +.slot > * { +margin-bottom: 8px; + +&:last-child { + margin-bottom: 0px; +} +} diff --git a/client/coral-admin/src/components/External.js b/client/coral-admin/src/components/External.js new file mode 100644 index 000000000..0f133d3b9 --- /dev/null +++ b/client/coral-admin/src/components/External.js @@ -0,0 +1,24 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import styles from './External.css'; +import Slot from 'coral-framework/components/Slot'; +import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty'; + +const External = ({ slot }) => ( + +
+
+ +
+
+
Or
+
+
+
+); + +External.propTypes = { + slot: PropTypes.string.isRequired, +}; + +export default External; diff --git a/client/coral-admin/src/components/SignIn.js b/client/coral-admin/src/components/SignIn.js index 5e1de2033..ddd69d3ac 100644 --- a/client/coral-admin/src/components/SignIn.js +++ b/client/coral-admin/src/components/SignIn.js @@ -4,6 +4,7 @@ import styles from './SignIn.css'; import { Button, TextField, Alert } from 'coral-ui'; import cn from 'classnames'; import Recaptcha from 'coral-framework/components/Recaptcha'; +import External from './External'; class SignIn extends React.Component { recaptcha = null; @@ -33,48 +34,55 @@ class SignIn extends React.Component { render() { const { email, password, errorMessage, requireRecaptcha } = this.props; return ( -
- {errorMessage && {errorMessage}} - - - {requireRecaptcha && ( -
- -
- )} - -

- Forgot your password?{' '} - + + + {errorMessage && {errorMessage}} + + + {requireRecaptcha && ( +

+ +
+ )} + +

+ {/* TODO: translate */} + Forgot your password?{' '} + + Request a new one. + +

+ + ); } } diff --git a/client/coral-admin/src/containers/SignIn.js b/client/coral-admin/src/containers/SignIn.js index 523d81091..1af857294 100644 --- a/client/coral-admin/src/containers/SignIn.js +++ b/client/coral-admin/src/containers/SignIn.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { withSignIn } from 'coral-framework/hocs'; +import { withSignIn, withPopupAuthHandler } from 'coral-framework/hocs'; import { compose } from 'recompose'; import SignIn from '../components/SignIn'; @@ -55,4 +55,4 @@ SignInContainer.propTypes = { requireRecaptcha: PropTypes.bool.isRequired, }; -export default compose(withSignIn)(SignInContainer); +export default compose(withSignIn, withPopupAuthHandler)(SignInContainer); diff --git a/client/coral-framework/services/postMessage.js b/client/coral-framework/services/postMessage.js index ef9311e64..6bc18eccf 100644 --- a/client/coral-framework/services/postMessage.js +++ b/client/coral-framework/services/postMessage.js @@ -56,10 +56,10 @@ export function createPostMessage(origin, scope = 'client') { // Send the message. target.postMessage(msg, origin); }, - subscribe: (handler, target = window) => { + subscribe(handler, target = window) { // If this handler is already attached to the target, detach it. if (has(listeners, [target, handler])) { - this.unsubscribeFromMessages(handler, target); + this.unsubscribe(handler, target); } // Wrap the listener with a origin check. @@ -71,7 +71,7 @@ export function createPostMessage(origin, scope = 'client') { // Attach the listener to the target. target.addEventListener('message', listener); }, - unsubscribe: (handler, target = window) => { + unsubscribe(handler, target = window) { if (!has(listeners, [target, handler])) { return; } diff --git a/client/coral-framework/utils/index.js b/client/coral-framework/utils/index.js index e30c12e06..6351c4484 100644 --- a/client/coral-framework/utils/index.js +++ b/client/coral-framework/utils/index.js @@ -273,3 +273,23 @@ export function translateError(error) { } return error.toString(); } + +/** + * handlePopupAuth will optionally open a popup with the requested uri if the + * window is not already a popup. + * + * @param {String} uri the url to open the window? to + * @param {String} title the title of the new window? to open + * @param {String} features the features to use when opening a window? + */ +export function handlePopupAuth( + uri, + title = 'Login', // TODO: translate + features = 'menubar=0,resizable=0,width=500,height=550,top=200,left=500' +) { + if (window.opener) { + window.location = uri; + } else { + window.open(uri, title, features); + } +} diff --git a/plugin-api/beta/client/utils/index.js b/plugin-api/beta/client/utils/index.js index aeb9841f9..0d1893066 100644 --- a/plugin-api/beta/client/utils/index.js +++ b/plugin-api/beta/client/utils/index.js @@ -9,4 +9,5 @@ export { getDefinitionName, getShallowChanges, createDefaultResponseFragments, + handlePopupAuth, } from 'coral-framework/utils'; diff --git a/plugins/talk-plugin-facebook-auth/client/actions.js b/plugins/talk-plugin-facebook-auth/client/actions.js index 79f2d2a6a..2f92ecfb6 100644 --- a/plugins/talk-plugin-facebook-auth/client/actions.js +++ b/plugins/talk-plugin-facebook-auth/client/actions.js @@ -1,3 +1,5 @@ +import { handlePopupAuth } from 'plugin-api/beta/client/utils'; + export const loginWithFacebook = () => (dispatch, _, { rest }) => { - window.location = `${rest.uri}/auth/facebook`; + handlePopupAuth(`${rest.uri}/auth/facebook`); }; diff --git a/plugins/talk-plugin-google-auth/client/actions.js b/plugins/talk-plugin-google-auth/client/actions.js index 8b49bf39e..1856ddb54 100644 --- a/plugins/talk-plugin-google-auth/client/actions.js +++ b/plugins/talk-plugin-google-auth/client/actions.js @@ -1,3 +1,5 @@ +import { handlePopupAuth } from 'plugin-api/beta/client/utils'; + export const loginWithGoogle = () => (dispatch, _, { rest }) => { - window.location = `${rest.uri}/auth/google`; + handlePopupAuth(`${rest.uri}/auth/google`); }; From b73620bcb0de6ef33f10b8491e486fe9be6cfe73 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 20 Apr 2018 10:00:52 +0200 Subject: [PATCH 02/19] WIP --- .gitignore | 1 + .../plugin/talk-plugin-global-switchoff.md | 25 ++++++++ .../client/.eslintrc.json | 23 ++++++++ .../client/components/GlobalSwitchoff.js | 59 +++++++++++++++++++ .../client/components/styles.css | 0 .../client/index.js | 9 +++ .../client/translations.yml | 8 +++ plugins/talk-plugin-global-switchoff/index.js | 11 ++++ .../server/index.js | 1 + .../server/resolvers.js | 10 ++++ .../server/typeDefs.graphql | 10 ++++ 11 files changed, 157 insertions(+) create mode 100644 docs/source/plugin/talk-plugin-global-switchoff.md create mode 100644 plugins/talk-plugin-global-switchoff/client/.eslintrc.json create mode 100644 plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js create mode 100644 plugins/talk-plugin-global-switchoff/client/components/styles.css create mode 100644 plugins/talk-plugin-global-switchoff/client/index.js create mode 100644 plugins/talk-plugin-global-switchoff/client/translations.yml create mode 100644 plugins/talk-plugin-global-switchoff/index.js create mode 100644 plugins/talk-plugin-global-switchoff/server/index.js create mode 100644 plugins/talk-plugin-global-switchoff/server/resolvers.js create mode 100644 plugins/talk-plugin-global-switchoff/server/typeDefs.graphql diff --git a/.gitignore b/.gitignore index 24022b9d7..ce5146929 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ plugins/* !plugins/talk-plugin-facebook-auth !plugins/talk-plugin-featured-comments !plugins/talk-plugin-flag-details +!plugins/talk-plugin-global-switchoff !plugins/talk-plugin-google-auth !plugins/talk-plugin-ignore-user !plugins/talk-plugin-like diff --git a/docs/source/plugin/talk-plugin-global-switchoff.md b/docs/source/plugin/talk-plugin-global-switchoff.md new file mode 100644 index 000000000..317fb4b3b --- /dev/null +++ b/docs/source/plugin/talk-plugin-global-switchoff.md @@ -0,0 +1,25 @@ +--- +title: talk-plugin-global-switchoff +permalink: /plugin/talk-plugin-global-switchoff/ +layout: plugin +plugin: + name: talk-plugin-global-switchoff + provides: + - Client + - Server +--- + +Add a switch to the settings page that disables commenting globally. + +## Installation + +TBD + +Add `"talk-plugin-global-switchoff"` to the `plugins.json` in your Talk installation. +This plugin provides a server and a client side implementation. + +## Server implementation + +### How does this work? + +TODO diff --git a/plugins/talk-plugin-global-switchoff/client/.eslintrc.json b/plugins/talk-plugin-global-switchoff/client/.eslintrc.json new file mode 100644 index 000000000..9fe56bd14 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/client/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "env": { + "browser": true, + "es6": true, + "mocha": true + }, + "parserOptions": { + "sourceType": "module", + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + } + }, + "parser": "babel-eslint", + "plugins": [ + "react" + ], + "rules": { + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", + "no-console": ["warn", { "allow": ["warn", "error"] }] + } +} diff --git a/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js b/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js new file mode 100644 index 000000000..a5150ed10 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js @@ -0,0 +1,59 @@ +import React from 'react'; +import { gql } from 'react-apollo'; +import ConfigureCard from 'coral-framework/components/ConfigureCard'; +import MarkdownEditor from 'coral-framework/components/MarkdownEditor'; +import t from 'coral-framework/services/i18n'; +import { withFragments } from 'plugin-api/beta/client/hocs'; +import cn from 'classnames'; +import styles from './styles.css'; + +const plugin = 'talk-plugin-global-switchoff'; + +class GlobalSwitchoff extends React.Component { + updateGlobalSwitchoffEnable = () => { + const updater = { + globalSwitchoffEnable: { + $set: !this.props.settings.globalSwitchoffEnable, + }, + }; + this.props.updatePending({ updater }); + }; + + updateGlobalSwitchoffMessage = () => {}; + + render() { + const { settings } = this.props; + return ( + +

{t(plugin + '.setting_desc')}

+
+ +
+
+ ); + } +} + +// export default GlobalSwitchoff; + +export default withFragments({ + settings: gql` + fragment TalkPlugin_GlobalSwitchoff_settings on Settings { + globalSwitchoffEnable + globalSwitchoffMessage + } + `, +})(GlobalSwitchoff); diff --git a/plugins/talk-plugin-global-switchoff/client/components/styles.css b/plugins/talk-plugin-global-switchoff/client/components/styles.css new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/talk-plugin-global-switchoff/client/index.js b/plugins/talk-plugin-global-switchoff/client/index.js new file mode 100644 index 000000000..de8b516e7 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/client/index.js @@ -0,0 +1,9 @@ +import GlobalSwitchoff from './components/GlobalSwitchoff'; +import translations from './translations.yml'; + +export default { + translations, + slots: { + adminStreamSettings: [GlobalSwitchoff], + }, +}; diff --git a/plugins/talk-plugin-global-switchoff/client/translations.yml b/plugins/talk-plugin-global-switchoff/client/translations.yml new file mode 100644 index 000000000..c135337f4 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/client/translations.yml @@ -0,0 +1,8 @@ +en: + talk-plugin-global-switchoff: + setting_title: 'Deactivate commenting globally' + setting_desc: 'Write a message that will be displayed while commenting is deactivated.' +de: + talk-plugin-global-switchoff: + setting_title: 'Kommentieren global deaktivieren' + setting_desc: 'Verfassen Sie eine Nachricht, die angezeigt wird, solange das Kommentieren deaktiviert ist.' diff --git a/plugins/talk-plugin-global-switchoff/index.js b/plugins/talk-plugin-global-switchoff/index.js new file mode 100644 index 000000000..dfd1f0d04 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/index.js @@ -0,0 +1,11 @@ +const { readFileSync } = require('fs'); +const path = require('path'); +const resolvers = require('./server/resolvers'); + +module.exports = { + typeDefs: readFileSync( + path.join(__dirname, 'server/typeDefs.graphql'), + 'utf8' + ), + resolvers, +}; diff --git a/plugins/talk-plugin-global-switchoff/server/index.js b/plugins/talk-plugin-global-switchoff/server/index.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/server/index.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/plugins/talk-plugin-global-switchoff/server/resolvers.js b/plugins/talk-plugin-global-switchoff/server/resolvers.js new file mode 100644 index 000000000..4e249ff3a --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/server/resolvers.js @@ -0,0 +1,10 @@ +const { get } = require('lodash'); + +module.exports = { + Settings: { + globalSwitchoffEnable: settings => + get(settings, 'globalSwitchoffEnable', false), + globalSwitchoffMessage: settings => + get(settings, 'globalSwitchoffMessage', ''), + }, +}; diff --git a/plugins/talk-plugin-global-switchoff/server/typeDefs.graphql b/plugins/talk-plugin-global-switchoff/server/typeDefs.graphql new file mode 100644 index 000000000..efb4b80f6 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/server/typeDefs.graphql @@ -0,0 +1,10 @@ + +type Settings { + globalSwitchoffEnable: Boolean + globalSwitchoffMessage: String +} + +input UpdateSettingsInput { + globalSwitchoffEnable: Boolean + globalSwitchoffMessage: String +} From bbd3050b95d24228a6bf50898b126b99a7a49e11 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Mon, 23 Apr 2018 12:04:53 +0200 Subject: [PATCH 03/19] Small refactoring --- .../client/components/GlobalSwitchoff.js | 13 +------------ .../client/containers/GlobalSwitchoff.js | 12 ++++++++++++ .../talk-plugin-global-switchoff/client/index.js | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js diff --git a/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js b/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js index a5150ed10..d676e7531 100644 --- a/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js +++ b/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js @@ -1,9 +1,7 @@ import React from 'react'; -import { gql } from 'react-apollo'; import ConfigureCard from 'coral-framework/components/ConfigureCard'; import MarkdownEditor from 'coral-framework/components/MarkdownEditor'; import t from 'coral-framework/services/i18n'; -import { withFragments } from 'plugin-api/beta/client/hocs'; import cn from 'classnames'; import styles from './styles.css'; @@ -47,13 +45,4 @@ class GlobalSwitchoff extends React.Component { } } -// export default GlobalSwitchoff; - -export default withFragments({ - settings: gql` - fragment TalkPlugin_GlobalSwitchoff_settings on Settings { - globalSwitchoffEnable - globalSwitchoffMessage - } - `, -})(GlobalSwitchoff); +export default GlobalSwitchoff; diff --git a/plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js b/plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js new file mode 100644 index 000000000..b935bcb5a --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js @@ -0,0 +1,12 @@ +import { gql } from 'react-apollo'; +import GlobalSwitchoff from '../components/GlobalSwitchoff'; +import { withFragments } from 'plugin-api/beta/client/hocs'; + +export default withFragments({ + settings: gql` + fragment TalkPlugin_GlobalSwitchoff_settings on Settings { + globalSwitchoffEnable + globalSwitchoffMessage + } + `, +})(GlobalSwitchoff); diff --git a/plugins/talk-plugin-global-switchoff/client/index.js b/plugins/talk-plugin-global-switchoff/client/index.js index de8b516e7..c9994ce5e 100644 --- a/plugins/talk-plugin-global-switchoff/client/index.js +++ b/plugins/talk-plugin-global-switchoff/client/index.js @@ -1,4 +1,4 @@ -import GlobalSwitchoff from './components/GlobalSwitchoff'; +import GlobalSwitchoff from './containers/GlobalSwitchoff'; import translations from './translations.yml'; export default { From 499030028c152969430e76039e297d01899f2eb5 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Mon, 23 Apr 2018 15:35:02 +0200 Subject: [PATCH 04/19] Add hooks to RootMutation to save our setting in the database. --- .../{client => }/.eslintrc.json | 0 plugins/talk-plugin-global-switchoff/index.js | 2 ++ .../talk-plugin-global-switchoff/server/hooks.js | 13 +++++++++++++ 3 files changed, 15 insertions(+) rename plugins/talk-plugin-global-switchoff/{client => }/.eslintrc.json (100%) create mode 100644 plugins/talk-plugin-global-switchoff/server/hooks.js diff --git a/plugins/talk-plugin-global-switchoff/client/.eslintrc.json b/plugins/talk-plugin-global-switchoff/.eslintrc.json similarity index 100% rename from plugins/talk-plugin-global-switchoff/client/.eslintrc.json rename to plugins/talk-plugin-global-switchoff/.eslintrc.json diff --git a/plugins/talk-plugin-global-switchoff/index.js b/plugins/talk-plugin-global-switchoff/index.js index dfd1f0d04..a318f8a11 100644 --- a/plugins/talk-plugin-global-switchoff/index.js +++ b/plugins/talk-plugin-global-switchoff/index.js @@ -1,5 +1,6 @@ const { readFileSync } = require('fs'); const path = require('path'); +const hooks = require('./server/hooks'); const resolvers = require('./server/resolvers'); module.exports = { @@ -7,5 +8,6 @@ module.exports = { path.join(__dirname, 'server/typeDefs.graphql'), 'utf8' ), + hooks, resolvers, }; diff --git a/plugins/talk-plugin-global-switchoff/server/hooks.js b/plugins/talk-plugin-global-switchoff/server/hooks.js new file mode 100644 index 000000000..be0498fb6 --- /dev/null +++ b/plugins/talk-plugin-global-switchoff/server/hooks.js @@ -0,0 +1,13 @@ +module.exports = { + RootMutation: { + updateSettings: { + async pre(_, { input }) { + input.metadata = { + ...input.metadata, + globalSwitchoffEnable: input.globalSwitchoffEnable, + }; + delete input.globalSwitchoffEnable; + }, + }, + }, +}; From fab15daacd008c2d3275e26040683b66b2a76be8 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Mon, 23 Apr 2018 17:06:46 +0200 Subject: [PATCH 05/19] Fix: use the correct keys to get the settings --- plugins/talk-plugin-global-switchoff/server/resolvers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/talk-plugin-global-switchoff/server/resolvers.js b/plugins/talk-plugin-global-switchoff/server/resolvers.js index 4e249ff3a..f28e765fc 100644 --- a/plugins/talk-plugin-global-switchoff/server/resolvers.js +++ b/plugins/talk-plugin-global-switchoff/server/resolvers.js @@ -3,8 +3,8 @@ const { get } = require('lodash'); module.exports = { Settings: { globalSwitchoffEnable: settings => - get(settings, 'globalSwitchoffEnable', false), + get(settings, 'metadata.globalSwitchoffEnable', false), globalSwitchoffMessage: settings => - get(settings, 'globalSwitchoffMessage', ''), + get(settings, 'metadata.globalSwitchoffMessage', ''), }, }; From 48fc3ab5db24e2a05d6faf06ef09edbdbb3baf48 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Thu, 26 Apr 2018 13:12:27 +0200 Subject: [PATCH 06/19] Move "global switchoff" code from plugin to core --- .gitignore | 1 - .../Configure/components/StreamSettings.js | 33 +++++++++++++ .../Configure/containers/StreamSettings.js | 2 + .../src/tabs/stream/components/Stream.js | 11 ++++- .../src/tabs/stream/containers/Stream.js | 2 + errors.js | 19 ++++++++ graph/typeDefs.graphql | 14 ++++++ locales/de.yml | 3 ++ locales/en.yml | 3 ++ models/schema/setting.js | 8 ++++ .../.eslintrc.json | 23 --------- .../client/components/GlobalSwitchoff.js | 48 ------------------- .../client/components/styles.css | 0 .../client/containers/GlobalSwitchoff.js | 12 ----- .../client/index.js | 9 ---- .../client/translations.yml | 8 ---- plugins/talk-plugin-global-switchoff/index.js | 13 ----- .../server/hooks.js | 13 ----- .../server/index.js | 1 - .../server/resolvers.js | 10 ---- .../server/typeDefs.graphql | 10 ---- services/moderation/index.js | 2 + .../moderation/phases/commentingDisabled.js | 9 ++++ services/moderation/phases/index.js | 1 + 24 files changed, 105 insertions(+), 150 deletions(-) delete mode 100644 plugins/talk-plugin-global-switchoff/.eslintrc.json delete mode 100644 plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js delete mode 100644 plugins/talk-plugin-global-switchoff/client/components/styles.css delete mode 100644 plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js delete mode 100644 plugins/talk-plugin-global-switchoff/client/index.js delete mode 100644 plugins/talk-plugin-global-switchoff/client/translations.yml delete mode 100644 plugins/talk-plugin-global-switchoff/index.js delete mode 100644 plugins/talk-plugin-global-switchoff/server/hooks.js delete mode 100644 plugins/talk-plugin-global-switchoff/server/index.js delete mode 100644 plugins/talk-plugin-global-switchoff/server/resolvers.js delete mode 100644 plugins/talk-plugin-global-switchoff/server/typeDefs.graphql create mode 100644 services/moderation/phases/commentingDisabled.js diff --git a/.gitignore b/.gitignore index ce5146929..24022b9d7 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,6 @@ plugins/* !plugins/talk-plugin-facebook-auth !plugins/talk-plugin-featured-comments !plugins/talk-plugin-flag-details -!plugins/talk-plugin-global-switchoff !plugins/talk-plugin-google-auth !plugins/talk-plugin-ignore-user !plugins/talk-plugin-like diff --git a/client/coral-admin/src/routes/Configure/components/StreamSettings.js b/client/coral-admin/src/routes/Configure/components/StreamSettings.js index e6424848f..ce69da129 100644 --- a/client/coral-admin/src/routes/Configure/components/StreamSettings.js +++ b/client/coral-admin/src/routes/Configure/components/StreamSettings.js @@ -82,6 +82,20 @@ class StreamSettings extends React.Component { this.props.updatePending({ updater }); }; + updateGlobalSwitchoffEnable = () => { + const updater = { + globalSwitchoffEnable: { + $set: !this.props.settings.globalSwitchoffEnable, + }, + }; + this.props.updatePending({ updater }); + }; + + updateGlobalSwitchoffMessage = value => { + const updater = { globalSwitchoffMessage: { $set: value } }; + this.props.updatePending({ updater }); + }; + updateAutoClose = () => { const updater = { autoCloseStream: { $set: !this.props.settings.autoCloseStream }, @@ -192,6 +206,25 @@ class StreamSettings extends React.Component {   {t('configure.edit_comment_timeframe_text_post')} + +

{t('configure.global_switchoff_desc')}

+
+ +
+
) : ( -

{asset.settings.closedMessage}

+
+ {asset.isClosed ? ( +

{asset.settings.closedMessage}

+ ) : ( + + )} +
)} diff --git a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js index f1a973f03..99878a9b9 100644 --- a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js +++ b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js @@ -434,6 +434,8 @@ const fragments = { questionBoxIcon closedTimeout closedMessage + globalSwitchoffEnable + globalSwitchoffMessage charCountEnable charCount requireEmailConfirmation diff --git a/errors.js b/errors.js index da1287dd3..39cb6b8ff 100644 --- a/errors.js +++ b/errors.js @@ -161,6 +161,24 @@ class ErrAssetCommentingClosed extends TalkError { } } +// ErrCommentingDisabled is returned when a comment or action is attempted while +// commenting has been disabled site-wide. +class ErrCommentingDisabled extends TalkError { + constructor(message = null) { + super( + 'asset commenting is closed', + { + status: 400, + translation_key: 'COMMENTING_DISABLED', + }, + { + // Include the closedMessage in the metadata piece of the error. + message, + } + ); + } +} + /** * ErrAuthentication is returned when there is an error authenticating and the * message is provided. @@ -387,6 +405,7 @@ module.exports = { ErrAuthentication, ErrCannotIgnoreStaff, ErrCommentTooShort, + ErrCommentingDisabled, ErrContainsProfanity, ErrEditWindowHasEnded, ErrEmailAlreadyVerified, diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index 03c97ce58..dda86291f 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -837,6 +837,13 @@ type Settings { # closed. closedMessage: String + # globalSwitchoffEnable will disable commenting site-wide. + globalSwitchoffEnable: Boolean + + # globalSwitchoffMessage will be shown above the comment stream while + # commenting is disabled site-wide. + globalSwitchoffMessage: String + # editCommentWindowLength is the length of time (in milliseconds) after a # comment is posted that it can still be edited by the author. editCommentWindowLength: Int @@ -1300,6 +1307,13 @@ input UpdateSettingsInput { # closed. closedMessage: String + # globalSwitchoffEnable will disable commenting site-wide. + globalSwitchoffEnable: Boolean + + # globalSwitchoffMessage will be shown above the comment stream while + # commenting is disabled site-wide. + globalSwitchoffMessage: String + # charCountEnable is true when the character count restriction is enabled. charCountEnable: Boolean diff --git a/locales/de.yml b/locales/de.yml index d2b247fbc..00cbb007c 100644 --- a/locales/de.yml +++ b/locales/de.yml @@ -136,6 +136,8 @@ de: enable_premod_links_description: "Moderatoren müssen jeden Kommentar, der einen Link enthält, freigeben, bevor er veröffentlicht wird." enable_questionbox: "Stellen Sie den Lesern eine Frage" enable_questionbox_description: "Diese Frage erscheint am Anfang des Kommentarbereichs. Regen Sie eine Diskussion an." + global_switchoff_title: "Kommentieren global deaktivieren" + global_switchoff_desc: "Verfassen Sie eine Nachricht, die angezeigt wird, solange das Kommentieren deaktiviert ist." hours: Stunden include_comment_stream: "Einleitung zum Kommentarbereich" include_comment_stream_desc: "Verfassen Sie eine Einleitung, die über jedem Kommentarbereich erscheint. Nützlich z.B. für Community-Richtlinien." @@ -223,6 +225,7 @@ de: LOGIN_MAXIMUM_EXCEEDED: "Sie haben zu häufig erfolglos versucht, sich anzumelden. Bitte warten Sie." PASSWORD_REQUIRED: "Passwort ist erforderlich" COMMENTING_CLOSED: "Kommentarbereich ist bereits geschlossen" + COMMENTING_DISABLED: "Die Kommentarfunktion ist derzeit abgeschaltet" NOT_FOUND: "Ressource nicht gefunden" ALREADY_EXISTS: "Ressource existiert bereits" INVALID_ASSET_URL: "Asset-URL ist ungültig" diff --git a/locales/en.yml b/locales/en.yml index e293fb40b..eae0e43c9 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -140,6 +140,8 @@ en: enable_premod_links_description: "Moderators must approve any comment containing a link before it is published." enable_questionbox: "Ask Readers a Question" enable_questionbox_description: "This question will appear at the top of this comment stream. Ask readers about a certain issue in the article or pose discussion questions etc." + global_switchoff_title: "Deactivate commenting site-wide" + global_switchoff_desc: "Write a message that will be displayed while commenting is deactivated." hours: Hours include_comment_stream: "Include Comment Stream Description for Readers" include_comment_stream_desc: "Write a message to be added to the top of your comment stream. Pose a topic include community guidelines etc." @@ -247,6 +249,7 @@ en: LOGIN_MAXIMUM_EXCEEDED: "You have made too many unsuccessful password attempts. Please wait." PASSWORD_REQUIRED: "Must input a password" COMMENTING_CLOSED: "Commenting is already closed" + COMMENTING_DISABLED: "Commenting is currently disabled on this site" NOT_FOUND: "Resource not found" ALREADY_EXISTS: "Resource already exists" INVALID_ASSET_URL: "Assert URL is invalid" diff --git a/models/schema/setting.js b/models/schema/setting.js index eb9dc76d1..a896c797e 100644 --- a/models/schema/setting.js +++ b/models/schema/setting.js @@ -66,6 +66,14 @@ const Setting = new Schema( type: String, default: 'Expired', }, + globalSwitchoffEnable: { + type: Boolean, + default: false, + }, + globalSwitchoffMessage: { + type: String, + default: '', + }, wordlist: { banned: { type: Array, diff --git a/plugins/talk-plugin-global-switchoff/.eslintrc.json b/plugins/talk-plugin-global-switchoff/.eslintrc.json deleted file mode 100644 index 9fe56bd14..000000000 --- a/plugins/talk-plugin-global-switchoff/.eslintrc.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "env": { - "browser": true, - "es6": true, - "mocha": true - }, - "parserOptions": { - "sourceType": "module", - "ecmaFeatures": { - "experimentalObjectRestSpread": true, - "jsx": true - } - }, - "parser": "babel-eslint", - "plugins": [ - "react" - ], - "rules": { - "react/jsx-uses-react": "error", - "react/jsx-uses-vars": "error", - "no-console": ["warn", { "allow": ["warn", "error"] }] - } -} diff --git a/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js b/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js deleted file mode 100644 index d676e7531..000000000 --- a/plugins/talk-plugin-global-switchoff/client/components/GlobalSwitchoff.js +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import ConfigureCard from 'coral-framework/components/ConfigureCard'; -import MarkdownEditor from 'coral-framework/components/MarkdownEditor'; -import t from 'coral-framework/services/i18n'; -import cn from 'classnames'; -import styles from './styles.css'; - -const plugin = 'talk-plugin-global-switchoff'; - -class GlobalSwitchoff extends React.Component { - updateGlobalSwitchoffEnable = () => { - const updater = { - globalSwitchoffEnable: { - $set: !this.props.settings.globalSwitchoffEnable, - }, - }; - this.props.updatePending({ updater }); - }; - - updateGlobalSwitchoffMessage = () => {}; - - render() { - const { settings } = this.props; - return ( - -

{t(plugin + '.setting_desc')}

-
- -
-
- ); - } -} - -export default GlobalSwitchoff; diff --git a/plugins/talk-plugin-global-switchoff/client/components/styles.css b/plugins/talk-plugin-global-switchoff/client/components/styles.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js b/plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js deleted file mode 100644 index b935bcb5a..000000000 --- a/plugins/talk-plugin-global-switchoff/client/containers/GlobalSwitchoff.js +++ /dev/null @@ -1,12 +0,0 @@ -import { gql } from 'react-apollo'; -import GlobalSwitchoff from '../components/GlobalSwitchoff'; -import { withFragments } from 'plugin-api/beta/client/hocs'; - -export default withFragments({ - settings: gql` - fragment TalkPlugin_GlobalSwitchoff_settings on Settings { - globalSwitchoffEnable - globalSwitchoffMessage - } - `, -})(GlobalSwitchoff); diff --git a/plugins/talk-plugin-global-switchoff/client/index.js b/plugins/talk-plugin-global-switchoff/client/index.js deleted file mode 100644 index c9994ce5e..000000000 --- a/plugins/talk-plugin-global-switchoff/client/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import GlobalSwitchoff from './containers/GlobalSwitchoff'; -import translations from './translations.yml'; - -export default { - translations, - slots: { - adminStreamSettings: [GlobalSwitchoff], - }, -}; diff --git a/plugins/talk-plugin-global-switchoff/client/translations.yml b/plugins/talk-plugin-global-switchoff/client/translations.yml deleted file mode 100644 index c135337f4..000000000 --- a/plugins/talk-plugin-global-switchoff/client/translations.yml +++ /dev/null @@ -1,8 +0,0 @@ -en: - talk-plugin-global-switchoff: - setting_title: 'Deactivate commenting globally' - setting_desc: 'Write a message that will be displayed while commenting is deactivated.' -de: - talk-plugin-global-switchoff: - setting_title: 'Kommentieren global deaktivieren' - setting_desc: 'Verfassen Sie eine Nachricht, die angezeigt wird, solange das Kommentieren deaktiviert ist.' diff --git a/plugins/talk-plugin-global-switchoff/index.js b/plugins/talk-plugin-global-switchoff/index.js deleted file mode 100644 index a318f8a11..000000000 --- a/plugins/talk-plugin-global-switchoff/index.js +++ /dev/null @@ -1,13 +0,0 @@ -const { readFileSync } = require('fs'); -const path = require('path'); -const hooks = require('./server/hooks'); -const resolvers = require('./server/resolvers'); - -module.exports = { - typeDefs: readFileSync( - path.join(__dirname, 'server/typeDefs.graphql'), - 'utf8' - ), - hooks, - resolvers, -}; diff --git a/plugins/talk-plugin-global-switchoff/server/hooks.js b/plugins/talk-plugin-global-switchoff/server/hooks.js deleted file mode 100644 index be0498fb6..000000000 --- a/plugins/talk-plugin-global-switchoff/server/hooks.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - RootMutation: { - updateSettings: { - async pre(_, { input }) { - input.metadata = { - ...input.metadata, - globalSwitchoffEnable: input.globalSwitchoffEnable, - }; - delete input.globalSwitchoffEnable; - }, - }, - }, -}; diff --git a/plugins/talk-plugin-global-switchoff/server/index.js b/plugins/talk-plugin-global-switchoff/server/index.js deleted file mode 100644 index f053ebf79..000000000 --- a/plugins/talk-plugin-global-switchoff/server/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {}; diff --git a/plugins/talk-plugin-global-switchoff/server/resolvers.js b/plugins/talk-plugin-global-switchoff/server/resolvers.js deleted file mode 100644 index f28e765fc..000000000 --- a/plugins/talk-plugin-global-switchoff/server/resolvers.js +++ /dev/null @@ -1,10 +0,0 @@ -const { get } = require('lodash'); - -module.exports = { - Settings: { - globalSwitchoffEnable: settings => - get(settings, 'metadata.globalSwitchoffEnable', false), - globalSwitchoffMessage: settings => - get(settings, 'metadata.globalSwitchoffMessage', ''), - }, -}; diff --git a/plugins/talk-plugin-global-switchoff/server/typeDefs.graphql b/plugins/talk-plugin-global-switchoff/server/typeDefs.graphql deleted file mode 100644 index efb4b80f6..000000000 --- a/plugins/talk-plugin-global-switchoff/server/typeDefs.graphql +++ /dev/null @@ -1,10 +0,0 @@ - -type Settings { - globalSwitchoffEnable: Boolean - globalSwitchoffMessage: String -} - -input UpdateSettingsInput { - globalSwitchoffEnable: Boolean - globalSwitchoffMessage: String -} diff --git a/services/moderation/index.js b/services/moderation/index.js index 27346e620..cc3a74a73 100644 --- a/services/moderation/index.js +++ b/services/moderation/index.js @@ -6,6 +6,7 @@ const { wordlist, commentLength, assetClosed, + commentingDisabled, karma, staff, links, @@ -36,6 +37,7 @@ const applyStatus = status => () => ({ status }); const phases = [ commentLength, assetClosed, + commentingDisabled, wordlist, staff, links, diff --git a/services/moderation/phases/commentingDisabled.js b/services/moderation/phases/commentingDisabled.js new file mode 100644 index 000000000..8c62d5d98 --- /dev/null +++ b/services/moderation/phases/commentingDisabled.js @@ -0,0 +1,9 @@ +const { ErrCommentingDisabled } = require('../../../errors'); + +// This phase checks to see if commenting is site-wide disabled. +module.exports = (ctx, comment, { asset }) => { + // Check to see if the asset has closed commenting... + if (asset.settings.globalSwitchoffEnable) { + throw new ErrCommentingDisabled(asset.settings.globalSwitchoffMessage); + } +}; diff --git a/services/moderation/phases/index.js b/services/moderation/phases/index.js index a1c2e7bf5..425c57197 100644 --- a/services/moderation/phases/index.js +++ b/services/moderation/phases/index.js @@ -1,6 +1,7 @@ module.exports.wordlist = require('./wordlist'); module.exports.commentLength = require('./commentLength'); module.exports.assetClosed = require('./assetClosed'); +module.exports.commentingDisabled = require('./commentingDisabled'); module.exports.karma = require('./karma'); module.exports.staff = require('./staff'); module.exports.links = require('./links'); From f28a3f2f4e99012171b969d9ad3cfe5ec90fdfef Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Thu, 26 Apr 2018 13:49:38 +0200 Subject: [PATCH 07/19] Add test case: err if trying to comment while it's disabled --- test/server/graph/mutations/createComment.js | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/server/graph/mutations/createComment.js b/test/server/graph/mutations/createComment.js index fbbbf4d38..373045efc 100644 --- a/test/server/graph/mutations/createComment.js +++ b/test/server/graph/mutations/createComment.js @@ -179,6 +179,54 @@ describe('graph.mutations.createComment', () => { }); }); + describe('assets while commenting is disabled', () => { + [ + { + disabled: false, + error: null, + }, + { + disabled: true, + error: 'COMMENTING_DISABLED', + }, + ].forEach(({ disabled, error }) => { + describe(`commentingDisabled=${disabled}`, () => { + beforeEach(() => + AssetModel.create({ + id: '123', + settings: { globalSwitchoffEnable: disabled }, + }) + ); + + it( + error ? 'does not create the comment' : 'creates the comment', + () => { + const context = new Context({ user: new UserModel({}) }); + + return graphql(schema, query, {}, context).then( + ({ data, errors }) => { + expect(errors).to.be.undefined; + if (error) { + expect(data.createComment).to.have.property('comment').null; + expect(data.createComment).to.have.property('errors').not + .null; + expect(data.createComment.errors[0]).to.have.property( + 'translation_key', + error + ); + } else { + expect(data.createComment).to.have.property('comment').not + .null; + expect(data.createComment).to.have.property('errors').null; + } + } + ); + } + ); + }); + }); + }); + describe('comments made with different asset moderation settings', () => { [ { moderation: 'PRE', status: 'PREMOD' }, From d7313570019385e2922ddfdbfcac74ad9cf54447 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 11 May 2018 12:20:26 +0200 Subject: [PATCH 08/19] Remove plugin docs for global-switchoff. Not a plugin anymore. --- .../plugin/talk-plugin-global-switchoff.md | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 docs/source/plugin/talk-plugin-global-switchoff.md diff --git a/docs/source/plugin/talk-plugin-global-switchoff.md b/docs/source/plugin/talk-plugin-global-switchoff.md deleted file mode 100644 index 317fb4b3b..000000000 --- a/docs/source/plugin/talk-plugin-global-switchoff.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: talk-plugin-global-switchoff -permalink: /plugin/talk-plugin-global-switchoff/ -layout: plugin -plugin: - name: talk-plugin-global-switchoff - provides: - - Client - - Server ---- - -Add a switch to the settings page that disables commenting globally. - -## Installation - -TBD - -Add `"talk-plugin-global-switchoff"` to the `plugins.json` in your Talk installation. -This plugin provides a server and a client side implementation. - -## Server implementation - -### How does this work? - -TODO From bae20c38ec9fcc27d3d90144d06081ceea9049d9 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 11 May 2018 12:21:13 +0200 Subject: [PATCH 09/19] Rename globalSwitchoff to disableCommenting. --- .../Configure/components/StreamSettings.js | 26 +++++++++---------- .../Configure/containers/StreamSettings.js | 4 +-- .../src/tabs/stream/components/Stream.js | 4 +-- .../src/tabs/stream/containers/Stream.js | 4 +-- graph/typeDefs.graphql | 16 ++++++------ locales/de.yml | 4 +-- locales/en.yml | 4 +-- models/schema/setting.js | 4 +-- .../moderation/phases/commentingDisabled.js | 4 +-- test/server/graph/mutations/createComment.js | 2 +- 10 files changed, 36 insertions(+), 36 deletions(-) diff --git a/client/coral-admin/src/routes/Configure/components/StreamSettings.js b/client/coral-admin/src/routes/Configure/components/StreamSettings.js index ce69da129..1f661fd72 100644 --- a/client/coral-admin/src/routes/Configure/components/StreamSettings.js +++ b/client/coral-admin/src/routes/Configure/components/StreamSettings.js @@ -82,17 +82,17 @@ class StreamSettings extends React.Component { this.props.updatePending({ updater }); }; - updateGlobalSwitchoffEnable = () => { + updateDisableCommenting = () => { const updater = { - globalSwitchoffEnable: { - $set: !this.props.settings.globalSwitchoffEnable, + disableCommenting: { + $set: !this.props.settings.disableCommenting, }, }; this.props.updatePending({ updater }); }; - updateGlobalSwitchoffMessage = value => { - const updater = { globalSwitchoffMessage: { $set: value } }; + updateDisableCommentingMessage = value => { + const updater = { disableCommentingMessage: { $set: value } }; this.props.updatePending({ updater }); }; @@ -207,21 +207,21 @@ class StreamSettings extends React.Component { {t('configure.edit_comment_timeframe_text_post')}
-

{t('configure.global_switchoff_desc')}

+

{t('configure.disable_commenting_desc')}

diff --git a/client/coral-admin/src/routes/Configure/containers/StreamSettings.js b/client/coral-admin/src/routes/Configure/containers/StreamSettings.js index 6eaff0d9a..faffb1aec 100644 --- a/client/coral-admin/src/routes/Configure/containers/StreamSettings.js +++ b/client/coral-admin/src/routes/Configure/containers/StreamSettings.js @@ -39,8 +39,8 @@ export default compose( autoCloseStream closedTimeout closedMessage - globalSwitchoffEnable - globalSwitchoffMessage + disableCommenting + disableCommentingMessage ${getSlotFragmentSpreads(slots, 'settings')} } `, diff --git a/client/coral-embed-stream/src/tabs/stream/components/Stream.js b/client/coral-embed-stream/src/tabs/stream/components/Stream.js index fbe49a069..2b7396720 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/Stream.js +++ b/client/coral-embed-stream/src/tabs/stream/components/Stream.js @@ -216,7 +216,7 @@ class Stream extends React.Component { currentUser, } = this.props; const { keepCommentBox } = this.state; - const open = !(asset.isClosed || asset.settings.globalSwitchoffEnable); + const open = !(asset.isClosed || asset.settings.disableCommenting); const banned = get(currentUser, 'status.banned.status'); const suspensionUntil = get(currentUser, 'status.suspension.until'); @@ -298,7 +298,7 @@ class Stream extends React.Component { {asset.isClosed ? (

{asset.settings.closedMessage}

) : ( - + )} )} diff --git a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js index 99878a9b9..d6ca27558 100644 --- a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js +++ b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js @@ -434,8 +434,8 @@ const fragments = { questionBoxIcon closedTimeout closedMessage - globalSwitchoffEnable - globalSwitchoffMessage + disableCommenting + disableCommentingMessage charCountEnable charCount requireEmailConfirmation diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index dda86291f..07947af6e 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -837,12 +837,12 @@ type Settings { # closed. closedMessage: String - # globalSwitchoffEnable will disable commenting site-wide. - globalSwitchoffEnable: Boolean + # disableCommenting will disable commenting site-wide. + disableCommenting: Boolean - # globalSwitchoffMessage will be shown above the comment stream while + # disableCommentingMessage will be shown above the comment stream while # commenting is disabled site-wide. - globalSwitchoffMessage: String + disableCommentingMessage: String # editCommentWindowLength is the length of time (in milliseconds) after a # comment is posted that it can still be edited by the author. @@ -1307,12 +1307,12 @@ input UpdateSettingsInput { # closed. closedMessage: String - # globalSwitchoffEnable will disable commenting site-wide. - globalSwitchoffEnable: Boolean + # disableCommenting will disable commenting site-wide. + disableCommenting: Boolean - # globalSwitchoffMessage will be shown above the comment stream while + # disableCommentingMessage will be shown above the comment stream while # commenting is disabled site-wide. - globalSwitchoffMessage: String + disableCommentingMessage: String # charCountEnable is true when the character count restriction is enabled. charCountEnable: Boolean diff --git a/locales/de.yml b/locales/de.yml index 00cbb007c..15404856c 100644 --- a/locales/de.yml +++ b/locales/de.yml @@ -121,6 +121,8 @@ de: custom_css_url_desc: "URL eines CSS-Stylesheets zum Überschreiben des Standard-Designs" days: Tage description: "Als Administrator können Sie die Einstellungen für den Kommentarbereich dieses Artikels anpassen:" + disable_commenting_title: "Kommentieren global deaktivieren" + disable_commenting_desc: "Verfassen Sie eine Nachricht, die angezeigt wird, solange das Kommentieren deaktiviert ist." domain_list_text: "Geben Sie Domains an, für die diese Talk-Instanz freigegeben werden soll, z.B. für lokale Test- oder Produktionsumgebungen (Bsp.: localhost:3000 staging.domain.com domain.com)." domain_list_title: "Zugelassene Domains" edit_comment_timeframe_heading: "Zeitlimit zur Bearbeitung von Kommentaren" @@ -136,8 +138,6 @@ de: enable_premod_links_description: "Moderatoren müssen jeden Kommentar, der einen Link enthält, freigeben, bevor er veröffentlicht wird." enable_questionbox: "Stellen Sie den Lesern eine Frage" enable_questionbox_description: "Diese Frage erscheint am Anfang des Kommentarbereichs. Regen Sie eine Diskussion an." - global_switchoff_title: "Kommentieren global deaktivieren" - global_switchoff_desc: "Verfassen Sie eine Nachricht, die angezeigt wird, solange das Kommentieren deaktiviert ist." hours: Stunden include_comment_stream: "Einleitung zum Kommentarbereich" include_comment_stream_desc: "Verfassen Sie eine Einleitung, die über jedem Kommentarbereich erscheint. Nützlich z.B. für Community-Richtlinien." diff --git a/locales/en.yml b/locales/en.yml index eae0e43c9..283ec4301 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -124,6 +124,8 @@ en: custom_css_url_desc: "URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external." days: Days description: "Change the comment settings on this story." + disable_commenting_title: "Deactivate commenting site-wide" + disable_commenting_desc: "Write a message that will be displayed while commenting is deactivated." domain_list_text: "Enter the domains you would like to permit for Talk e.g. your local staging and production environments (ex. localhost:3000 staging.domain.com domain.com)." domain_list_title: "Permitted Domains" edit_info: "Edit Info" @@ -140,8 +142,6 @@ en: enable_premod_links_description: "Moderators must approve any comment containing a link before it is published." enable_questionbox: "Ask Readers a Question" enable_questionbox_description: "This question will appear at the top of this comment stream. Ask readers about a certain issue in the article or pose discussion questions etc." - global_switchoff_title: "Deactivate commenting site-wide" - global_switchoff_desc: "Write a message that will be displayed while commenting is deactivated." hours: Hours include_comment_stream: "Include Comment Stream Description for Readers" include_comment_stream_desc: "Write a message to be added to the top of your comment stream. Pose a topic include community guidelines etc." diff --git a/models/schema/setting.js b/models/schema/setting.js index a896c797e..d75bed29e 100644 --- a/models/schema/setting.js +++ b/models/schema/setting.js @@ -66,11 +66,11 @@ const Setting = new Schema( type: String, default: 'Expired', }, - globalSwitchoffEnable: { + disableCommenting: { type: Boolean, default: false, }, - globalSwitchoffMessage: { + disableCommentingMessage: { type: String, default: '', }, diff --git a/services/moderation/phases/commentingDisabled.js b/services/moderation/phases/commentingDisabled.js index 8c62d5d98..060da473c 100644 --- a/services/moderation/phases/commentingDisabled.js +++ b/services/moderation/phases/commentingDisabled.js @@ -3,7 +3,7 @@ const { ErrCommentingDisabled } = require('../../../errors'); // This phase checks to see if commenting is site-wide disabled. module.exports = (ctx, comment, { asset }) => { // Check to see if the asset has closed commenting... - if (asset.settings.globalSwitchoffEnable) { - throw new ErrCommentingDisabled(asset.settings.globalSwitchoffMessage); + if (asset.settings.disableCommenting) { + throw new ErrCommentingDisabled(asset.settings.disableCommentingMessage); } }; diff --git a/test/server/graph/mutations/createComment.js b/test/server/graph/mutations/createComment.js index 373045efc..662404bf2 100644 --- a/test/server/graph/mutations/createComment.js +++ b/test/server/graph/mutations/createComment.js @@ -194,7 +194,7 @@ describe('graph.mutations.createComment', () => { beforeEach(() => AssetModel.create({ id: '123', - settings: { globalSwitchoffEnable: disabled }, + settings: { disableCommenting: disabled }, }) ); From 1236e7a5048385f1c9dc7e8ddd42713fb53fc9ed Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Fri, 11 May 2018 12:52:44 +0200 Subject: [PATCH 10/19] Disable/hide the reply buttons when commenting is disabled. --- .../coral-embed-stream/src/tabs/stream/components/Stream.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/tabs/stream/components/Stream.js b/client/coral-embed-stream/src/tabs/stream/components/Stream.js index 2b7396720..a07f8ff8b 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/Stream.js +++ b/client/coral-embed-stream/src/tabs/stream/components/Stream.js @@ -182,7 +182,9 @@ class Stream extends React.Component { setActiveReplyBox={setActiveReplyBox} activeReplyBox={activeReplyBox} notify={notify} - disableReply={asset.isClosed} + disableReply={ + asset.isClosed || asset.settings.disableCommenting + } postComment={postComment} currentUser={currentUser} postFlag={postFlag} From bde1dff33b4868de902891e07c45c54635574f39 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 11 May 2018 14:45:03 -0600 Subject: [PATCH 11/19] changed to seperate slot --- client/coral-admin/src/components/SignIn.js | 2 +- plugins/talk-plugin-facebook-auth/client/index.js | 1 + plugins/talk-plugin-google-auth/client/index.js | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/client/coral-admin/src/components/SignIn.js b/client/coral-admin/src/components/SignIn.js index ddd69d3ac..a067ace1d 100644 --- a/client/coral-admin/src/components/SignIn.js +++ b/client/coral-admin/src/components/SignIn.js @@ -35,7 +35,7 @@ class SignIn extends React.Component { const { email, password, errorMessage, requireRecaptcha } = this.props; return (
- +
{errorMessage && {errorMessage}} Date: Mon, 14 May 2018 13:57:46 +0200 Subject: [PATCH 12/19] Add new slot 'commentTombstone'. With this slot plugins can override the default tombstone for deleted comments. --- .../src/tabs/stream/components/Comment.js | 14 +++++++++++++- .../src/tabs/stream/components/CommentTombstone.js | 1 + .../src/tabs/stream/containers/Comment.js | 1 + docs/source/api/slots.md | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/tabs/stream/components/Comment.js b/client/coral-embed-stream/src/tabs/stream/components/Comment.js index 32778f7ea..3c840734e 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/Comment.js +++ b/client/coral-embed-stream/src/tabs/stream/components/Comment.js @@ -745,10 +745,22 @@ export default class Comment extends React.Component { const id = `c_${comment.id}`; + // props that are passed down the slots. + const slotPassthrough = { + action: 'deleted', + comment, + }; + return (
{isCommentDeleted(comment) ? ( - + ) : (
{this.renderComment()} diff --git a/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js b/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js index 95184dffd..e08f45d95 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js +++ b/client/coral-embed-stream/src/tabs/stream/components/CommentTombstone.js @@ -39,6 +39,7 @@ class CommentTombstone extends React.Component { CommentTombstone.propTypes = { action: PropTypes.string, + comment: PropTypes.object, onUndo: PropTypes.func, }; diff --git a/client/coral-embed-stream/src/tabs/stream/containers/Comment.js b/client/coral-embed-stream/src/tabs/stream/containers/Comment.js index dca7fadaa..028d6a478 100644 --- a/client/coral-embed-stream/src/tabs/stream/containers/Comment.js +++ b/client/coral-embed-stream/src/tabs/stream/containers/Comment.js @@ -24,6 +24,7 @@ const slots = [ 'commentAuthorName', 'commentAuthorTags', 'commentTimestamp', + 'commentTombstone', 'commentContent', ]; diff --git a/docs/source/api/slots.md b/docs/source/api/slots.md index a2e7cc04d..662a025e0 100644 --- a/docs/source/api/slots.md +++ b/docs/source/api/slots.md @@ -99,6 +99,7 @@ You won't have to use this to build plugins, but it's helpful to find where to e * `commentReactions` * `commentActions` * `commentInputArea` +* `commentTombstone` * `draftArea` * `streamSettings` From 8e392ef32d454c4aadafb9598010a69da3253235 Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Mon, 14 May 2018 15:01:51 +0200 Subject: [PATCH 13/19] Remove superfluous className --- client/coral-embed-stream/src/tabs/stream/components/Comment.js | 1 - 1 file changed, 1 deletion(-) diff --git a/client/coral-embed-stream/src/tabs/stream/components/Comment.js b/client/coral-embed-stream/src/tabs/stream/components/Comment.js index 3c840734e..63740764f 100644 --- a/client/coral-embed-stream/src/tabs/stream/components/Comment.js +++ b/client/coral-embed-stream/src/tabs/stream/components/Comment.js @@ -756,7 +756,6 @@ export default class Comment extends React.Component { {isCommentDeleted(comment) ? ( Date: Wed, 16 May 2018 18:18:36 -0400 Subject: [PATCH 14/19] Update lint-staged to fix dependency issue --- package.json | 4 +- yarn.lock | 134 +++++++++++++++++++++++---------------------------- 2 files changed, 61 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index 97f4e373d..c387d6145 100644 --- a/package.json +++ b/package.json @@ -149,7 +149,7 @@ "metascraper-title": "^3.9.2", "minimist": "^1.2.0", "moment": "^2.18.1", - "mongoose": "^4.12.3", + "mongoose": "^5.1.1", "ms": "^2.0.0", "murmurhash-js": "^1.0.0", "name-all-modules-plugin": "^1.0.1", @@ -231,7 +231,7 @@ "husky": "^0.14.3", "identity-obj-proxy": "^3.0.0", "jest-junit": "^3.6.0", - "lint-staged": "^7.0.0", + "lint-staged": "^7.1.0", "mocha": "^3.1.2", "mocha-junit-reporter": "^1.12.1", "nightwatch": "^0.9.16", diff --git a/yarn.lock b/yarn.lock index f0da6d006..13da4b2f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1644,6 +1644,10 @@ bson@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.4.tgz#93c10d39eaa5b58415cbc4052f3e53e562b0b72c" +bson@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.6.tgz#444db59ddd4c24f0cb063aabdc5c8c7b0ceca912" + buffer-crc32@^0.2.1, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -1652,10 +1656,6 @@ buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" -buffer-shims@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -3353,10 +3353,6 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-promise@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4" - es6-promise@^4.0.5: version "4.1.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a" @@ -4890,10 +4886,6 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -hooks-fixed@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hooks-fixed/-/hooks-fixed-2.0.2.tgz#20076daa07e77d8a6106883ce3f1722e051140b0" - hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -6399,9 +6391,9 @@ jxLoader@*: promised-io "*" walker "1.x" -kareem@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/kareem/-/kareem-1.5.0.tgz#e3e4101d9dcfde299769daf4b4db64d895d17448" +kareem@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.0.7.tgz#8d260366a4df4236ceccec318fcf10c17c5beb22" keymaster@^1.6.2: version "1.6.2" @@ -6528,9 +6520,9 @@ linkifyjs@^2.1.5: react ">=0.14.0" react-dom ">=0.14.0" -lint-staged@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.0.tgz#57926c63201e7bd38ca0576d74391efa699b4a9d" +lint-staged@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.1.0.tgz#1514a5b71b8d9492ca0c3d2a44769cbcbc8bcc79" dependencies: app-root-path "^2.0.1" chalk "^2.3.1" @@ -6541,6 +6533,7 @@ lint-staged@^7.0.0: execa "^0.9.0" find-parent-dir "^0.3.0" is-glob "^4.0.0" + is-windows "^1.0.2" jest-validate "^22.4.0" listr "^0.13.0" lodash "^4.17.5" @@ -6550,8 +6543,9 @@ lint-staged@^7.0.0: p-map "^1.1.1" path-is-inside "^1.0.2" pify "^3.0.0" - please-upgrade-node "^3.0.1" - staged-git-files "1.1.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.1" + string-argv "^0.0.2" stringify-object "^3.2.2" listr-silent-renderer@^1.1.1: @@ -7451,36 +7445,36 @@ moment@^2.15.2: version "2.22.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad" -mongodb-core@2.1.17: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.17.tgz#a418b337a14a14990fb510b923dee6a813173df8" +mongodb-core@3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-3.0.8.tgz#8d401f4eab6056c0d874a3d5844a4844f761d4d7" dependencies: bson "~1.0.4" - require_optional "~1.0.0" + require_optional "^1.0.1" -mongodb@2.2.33: - version "2.2.33" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.33.tgz#b537c471d34a6651b48f36fdbf29750340e08b50" +mongodb@3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.0.8.tgz#2c1daecac9a0ec2de2f2aea4dc97d76ae70f8951" dependencies: - es6-promise "3.2.1" - mongodb-core "2.1.17" - readable-stream "2.2.7" + mongodb-core "3.0.8" -mongoose@^4.12.3: - version "4.13.7" - resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.13.7.tgz#f760c770e6c8cdf34a6fe8b7443882b5fced1032" +mongoose-legacy-pluralize@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4" + +mongoose@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.1.1.tgz#a7e925607e76032e5ef20b3035a357bc8581b45e" dependencies: async "2.1.4" - bson "~1.0.4" - hooks-fixed "2.0.2" - kareem "1.5.0" + bson "~1.0.5" + kareem "2.0.7" lodash.get "4.4.2" - mongodb "2.2.33" - mpath "0.3.0" - mpromise "0.5.5" - mquery "2.3.3" + mongodb "3.0.8" + mongoose-legacy-pluralize "1.0.2" + mpath "0.4.1" + mquery "3.0.0" ms "2.0.0" - muri "1.3.0" regexp-clone "0.0.1" sliced "1.0.1" @@ -7509,17 +7503,13 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" -mpath@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.3.0.tgz#7a58f789e9b5fd3c94520634157960f26bd5ef44" +mpath@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.4.1.tgz#ed10388430380bf7bbb5be1391e5d6969cb08e89" -mpromise@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mpromise/-/mpromise-0.5.5.tgz#f5b24259d763acc2257b0a0c8c6d866fd51732e6" - -mquery@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/mquery/-/mquery-2.3.3.tgz#221412e5d4e7290ca5582dd16ea8f190a506b518" +mquery@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.0.0.tgz#e5f387dbabc0b9b69859e550e810faabe0ceabb0" dependencies: bluebird "3.5.0" debug "2.6.9" @@ -7538,10 +7528,6 @@ ms@^2.0.0, ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" -muri@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/muri/-/muri-1.3.0.tgz#aeccf3db64c56aa7c5b34e00f95b7878527a4721" - murmurhash-js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" @@ -8556,9 +8542,11 @@ platform@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd" -please-upgrade-node@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.1.tgz#0a681f2c18915e5433a5ca2cd94e0b8206a782db" +please-upgrade-node@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.2.tgz#7b9eaeca35aa4a43d6ebdfd10616c042f9a83acc" + dependencies: + semver-compare "^1.0.0" pluralize@^1.2.1: version "1.2.1" @@ -9717,18 +9705,6 @@ readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stre string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@2.2.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1" - dependencies: - buffer-shims "~1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~1.0.0" - util-deprecate "~1.0.1" - readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -10034,7 +10010,7 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" -require_optional@~1.0.0: +require_optional@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" dependencies: @@ -10285,6 +10261,10 @@ selenium-standalone@^6.11.0: which "^1.2.12" yauzl "^2.5.0" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -10762,9 +10742,9 @@ stack-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" -staged-git-files@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.0.tgz#1a9bb131c1885601023c7aaddd3d54c22142c526" +staged-git-files@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b" static-extend@^0.1.1: version "0.1.2" @@ -10841,6 +10821,10 @@ strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + string-hash@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" @@ -10875,7 +10859,7 @@ string.prototype.padend@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" -string_decoder@^1.0.0, string_decoder@~1.0.0, string_decoder@~1.0.3: +string_decoder@^1.0.0, string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: From 5241206b038a51ee3172dc43754cf64e7666e730 Mon Sep 17 00:00:00 2001 From: Kim Gardner Date: Wed, 16 May 2018 18:24:34 -0400 Subject: [PATCH 15/19] Remove deprecated useMongoClient --- services/mongoose.js | 1 - 1 file changed, 1 deletion(-) diff --git a/services/mongoose.js b/services/mongoose.js index 167b0d45b..f6615ad39 100644 --- a/services/mongoose.js +++ b/services/mongoose.js @@ -45,7 +45,6 @@ if (WEBPACK) { // Connect to the Mongo instance. mongoose .connect(MONGO_URL, { - useMongoClient: true, config: { autoIndex: CREATE_MONGO_INDEXES, }, From 0339e97b377aa83a35b3662670213d8078e5cc1f Mon Sep 17 00:00:00 2001 From: Leandro Date: Thu, 17 May 2018 16:39:04 +0200 Subject: [PATCH 16/19] fix optimisticResponse typo --- client/coral-framework/graphql/mutations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index 995ca1720..722d8ea98 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -116,7 +116,7 @@ export const withRemoveTag = withMutation( asset_id: assetId, item_type: itemType, }, - o3timisticResponse: { + optimisticResponse: { removeTag: { __typename: 'ModifyTagResponse', errors: null, From 086c43a0034a039e58ae95dada8c03c822188ec3 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 17 May 2018 13:18:57 -0600 Subject: [PATCH 17/19] Update .nsprc --- .nsprc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.nsprc b/.nsprc index 530a17a9f..8962db719 100644 --- a/.nsprc +++ b/.nsprc @@ -7,6 +7,7 @@ "https://nodesecurity.io/advisories/594", "https://nodesecurity.io/advisories/603", "https://nodesecurity.io/advisories/611", - "https://nodesecurity.io/advisories/612" + "https://nodesecurity.io/advisories/612", + "https://nodesecurity.io/advisories/654" ] } From 417befd52a6172094fa00815e4096fdd99220f85 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Thu, 17 May 2018 21:34:37 +0200 Subject: [PATCH 18/19] Don't close popup when there is an error --- client/coral-auth-callback/src/index.js | 50 +++++++++++++------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/client/coral-auth-callback/src/index.js b/client/coral-auth-callback/src/index.js index 41a83dcd2..7bf75e825 100644 --- a/client/coral-auth-callback/src/index.js +++ b/client/coral-auth-callback/src/index.js @@ -3,32 +3,36 @@ import { getStaticConfiguration } from 'coral-framework/services/staticConfigura import { createPostMessage } from 'coral-framework/services/postMessage'; document.addEventListener('DOMContentLoaded', () => { - try { - const staticConfig = getStaticConfiguration(); - const { STATIC_ORIGIN: origin } = staticConfig; - const postMessage = createPostMessage(origin); + const staticConfig = getStaticConfiguration(); + const { STATIC_ORIGIN: origin } = staticConfig; + const postMessage = createPostMessage(origin); - // Get the auth element and parse it as JSON by decoding it. - const auth = document.getElementById('auth'); - const doc = document.implementation.createHTMLDocument(''); - doc.body.innerHTML = auth.innerText; + // Get the auth element and parse it as JSON by decoding it. + const auth = document.getElementById('auth'); + const doc = document.implementation.createHTMLDocument(''); + doc.body.innerHTML = auth.innerText; - // Auth state is contained within the node. - const { err, data } = JSON.parse(doc.body.textContent); - if (err) { - // TODO: send back the error message. - console.error(err); + // Auth state is contained within the node. + const { err, data } = JSON.parse(doc.body.textContent); + if (err) { + const errDiv = document.createElement('div'); + if (err.message) { + errDiv.innerText = `${err.name}: ${err.message}`; } else { - // The data will contain a user and a token. - const { user, token } = data; - - // Send the state back. - postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token }); + errDiv.innerText = JSON.stringify(err); } - } finally { - // Always close the window. - setTimeout(() => { - window.close(); - }, 50); + document.body.appendChild(errDiv); + throw err; } + + // The data will contain a user and a token. + const { user, token } = data; + + // Send the state back. + postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token }); + + // Close the window when all went well. + setTimeout(() => { + window.close(); + }, 50); }); From ebcff4d95e378f46fc0b1b693e9bb8250a86a490 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 17 May 2018 18:58:01 -0600 Subject: [PATCH 19/19] patched migration bugs --- models/schema/user.js | 10 +++++++++ services/actions.js | 49 +++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/models/schema/user.js b/models/schema/user.js index a4ccfd185..a27b8dc39 100644 --- a/models/schema/user.js +++ b/models/schema/user.js @@ -339,6 +339,11 @@ User.virtual('banned') }) .set(function(status) { this.status.banned.status = status; + + if (!this.status.banned.history) { + this.status.banned.history = []; + } + this.status.banned.history.push({ status, created_at: new Date(), @@ -357,6 +362,11 @@ User.virtual('suspended') }) .set(function(until) { this.status.suspension.until = until; + + if (!this.status.suspension.history) { + this.status.suspension.history = []; + } + this.status.suspension.history.push({ until, created_at: new Date(), diff --git a/services/actions.js b/services/actions.js index 1c95e5128..790adc6a0 100644 --- a/services/actions.js +++ b/services/actions.js @@ -2,7 +2,7 @@ const ActionModel = require('../models/action'); const CommentModel = require('../models/comment'); const UserModel = require('../models/user'); const _ = require('lodash'); -const errors = require('../errors'); +const { ErrAlreadyExists } = require('../errors'); const incrActionCounts = async (action, value) => { const ACTION_TYPE = action.action_type.toLowerCase(); @@ -41,35 +41,30 @@ const incrActionCounts = async (action, value) => { * @param {object} update the update operation for the mongo findOneAndUpdate op * @param {object} options the options operation for the mongo findOneAndUpdate op */ -const findOnlyOneAndUpdate = async (query, update, options = {}) => - new Promise((resolve, reject) => { - ActionModel.findOneAndUpdate( - query, - update, - Object.assign({}, options, { - // Use raw result to get `updatedExisting`. - passRawResult: true, +const findOnlyOneAndUpdate = async (query, update, options = {}) => { + const raw = await ActionModel.findOneAndUpdate( + query, + update, + Object.assign({}, options, { + // Use raw result to get `updatedExisting`. + rawResult: true, - // Ensure that if it's new, we return the new object created. - new: true, + // Ensure that if it's new, we return the new object created. + new: true, - // Perform an upsert in the event that this doesn't exist. - upsert: true, + // Perform an upsert in the event that this doesn't exist. + upsert: true, - // Set the default values if not provided based on the mongoose models. - setDefaultsOnInsert: true, - }), - (err, doc, raw) => { - if (err) { - return reject(err); - } - if (raw.lastErrorObject.updatedExisting) { - return reject(new errors.ErrAlreadyExists(raw.value)); - } - return resolve(raw.value); - } - ); - }); + // Set the default values if not provided based on the mongoose models. + setDefaultsOnInsert: true, + }) + ); + if (raw.lastErrorObject.updatedExisting) { + throw new ErrAlreadyExists(raw.value); + } + + return raw.value; +}; module.exports = class ActionsService { /**