mirror of
https://github.com/wassname/talk.git
synced 2026-07-28 11:27:05 +08:00
Merge branch 'master' into cannot-ignore-staff
This commit is contained in:
@@ -20,7 +20,7 @@ Check out our Docs: https://coralproject.github.io/talk/
|
||||
|
||||
## End-to-End Testing
|
||||
|
||||
Talk uses [Nightwatch](http://nightwatchjs.org/) to write e2e tests. The Testing infrastructure is provided with love by our friends at Browserstack that allows us to run our tests in real browsers.
|
||||
Talk uses [Nightwatch](http://nightwatchjs.org/) to write e2e tests. The testing infrastructure that allows us to run our tests in real browsers is provided with love by our friends at Browserstack.
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -5,6 +5,7 @@ import Table from '../containers/Table';
|
||||
import {Pager, Icon} from 'coral-ui';
|
||||
import EmptyCard from '../../../components/EmptyCard';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const tableHeaders = [
|
||||
{
|
||||
@@ -62,4 +63,12 @@ const People = ({commenters, searchValue, onSearchChange, ...props}) => {
|
||||
);
|
||||
};
|
||||
|
||||
People.propTypes = {
|
||||
commenters: PropTypes.array,
|
||||
searchValue: PropTypes.string,
|
||||
onSearchChange: PropTypes.func,
|
||||
totalPages: PropTypes.number,
|
||||
onNewPageHandler: PropTypes.func,
|
||||
};
|
||||
|
||||
export default People;
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.username, .email {
|
||||
max-width: 215px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.email {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@ import React from 'react';
|
||||
import {SelectField, Option} from 'react-mdl-selectfield';
|
||||
import styles from '../components/Table.css';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
|
||||
export default ({headers, commenters, onHeaderClickHandler, onRoleChange, onCommenterStatusChange, viewUserDetail}) => (
|
||||
const Table = ({headers, commenters, onHeaderClickHandler, onRoleChange, onCommenterStatusChange, viewUserDetail}) => (
|
||||
<table className={`mdl-data-table ${styles.dataTable}`}>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -21,7 +23,7 @@ export default ({headers, commenters, onHeaderClickHandler, onRoleChange, onComm
|
||||
{commenters.map((row, i)=> (
|
||||
<tr key={i}>
|
||||
<td className="mdl-data-table__cell--non-numeric">
|
||||
<button onClick={() => {viewUserDetail(row.id);}} className={styles.button}>{row.username}</button>
|
||||
<button onClick={() => {viewUserDetail(row.id);}} className={cn(styles.username, styles.button)}>{row.username}</button>
|
||||
<span className={styles.email}>{row.profiles.map(({id}) => id)}</span>
|
||||
</td>
|
||||
<td className="mdl-data-table__cell--non-numeric">
|
||||
@@ -54,3 +56,14 @@ export default ({headers, commenters, onHeaderClickHandler, onRoleChange, onComm
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
|
||||
Table.propTypes = {
|
||||
headers: PropTypes.array,
|
||||
commenters: PropTypes.array,
|
||||
onHeaderClickHandler: PropTypes.func,
|
||||
onRoleChange: PropTypes.func,
|
||||
onCommenterStatusChange: PropTypes.func,
|
||||
viewUserDetail: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Table;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {compose} from 'react-apollo';
|
||||
import {setRole, setCommenterStatus} from '../../../actions/community';
|
||||
import Table from '../components/Table';
|
||||
import {viewUserDetail} from '../../../actions/userDetail';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class TableContainer extends Component {
|
||||
|
||||
@@ -22,6 +22,12 @@ class TableContainer extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
TableContainer.propTypes = {
|
||||
setRole: PropTypes.func,
|
||||
setCommenterStatus: PropTypes.func,
|
||||
commenters: PropTypes.array,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
commenters: state.community.accounts,
|
||||
});
|
||||
@@ -33,7 +39,5 @@ const mapDispatchToProps = (dispatch) =>
|
||||
viewUserDetail,
|
||||
}, dispatch);
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
)(TableContainer);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(TableContainer);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
.mainContent {
|
||||
width: calc(100% - 300px);
|
||||
padding: 10px 14px;
|
||||
padding: 10px 14px 80px 14px;
|
||||
box-sizing: border-box;
|
||||
max-width: 718px;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
align-items: flex-start;
|
||||
min-height: 100px;
|
||||
max-width: 600px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.header {
|
||||
|
||||
@@ -85,9 +85,14 @@ export class CommentForm extends React.Component {
|
||||
render() {
|
||||
const {maxCharCount, submitEnabled, cancelButtonClassName, submitButtonClassName, charCountEnable, body, loadingState} = this.props;
|
||||
|
||||
const length = body.trim().length;
|
||||
const isRespectingMaxCount = (length) => charCountEnable && maxCharCount && length > maxCharCount;
|
||||
const disableSubmitButton = !length || isRespectingMaxCount(length) || !submitEnabled({body}) || loadingState === 'loading';
|
||||
const length = body.length;
|
||||
const isRespectingMaxCount = (length) => charCountEnable && maxCharCount && length > maxCharCount;
|
||||
const disableSubmitButton =
|
||||
!length ||
|
||||
body.trim().length === 0 ||
|
||||
isRespectingMaxCount(length) ||
|
||||
!submitEnabled({body}) ||
|
||||
loadingState === 'loading';
|
||||
const disableCancelButton = loadingState === 'loading';
|
||||
const disableTextArea = loadingState === 'loading';
|
||||
|
||||
|
||||
@@ -4,11 +4,8 @@ GEM
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
colorator (1.1.0)
|
||||
cssminify2 (2.0.1)
|
||||
execjs (2.7.0)
|
||||
ffi (1.9.18)
|
||||
forwardable-extended (2.6.0)
|
||||
htmlcompressor (0.3.1)
|
||||
jekyll (3.5.2)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
@@ -20,11 +17,6 @@ GEM
|
||||
pathutil (~> 0.9)
|
||||
rouge (~> 1.7)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-minifier (0.1.4)
|
||||
cssminify2 (~> 2.0)
|
||||
htmlcompressor (~> 0.3)
|
||||
jekyll (~> 3.5)
|
||||
uglifier (~> 3.2)
|
||||
jekyll-sass-converter (1.5.0)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.3.0)
|
||||
@@ -50,15 +42,12 @@ GEM
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
uglifier (3.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
jekyll (= 3.5.2)
|
||||
jekyll-minifier (~> 0.1.4)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
tzinfo-data
|
||||
|
||||
|
||||
+15
-1
@@ -13,7 +13,21 @@ items:
|
||||
url: /configuration/
|
||||
- title: Advanced Configuration
|
||||
url: /advanced-configuration/
|
||||
- title: Product Guide
|
||||
children:
|
||||
- title: How Talk Works
|
||||
url: /how-talk-works/
|
||||
- title: Trust
|
||||
url: /trust/
|
||||
- title: Toxic Comments
|
||||
url: /toxic-comments/
|
||||
- title: Plugins
|
||||
children:
|
||||
- title: Plugins Overview
|
||||
url: /plugins/
|
||||
url: /plugins/
|
||||
- title: Default Plugins
|
||||
url: /default-plugins/
|
||||
- title: Additional Plugins
|
||||
url: /additional-plugins/
|
||||
- title: Plugin Recipes
|
||||
url: /plugin-recipes/
|
||||
|
||||
+7
-7
@@ -19,7 +19,7 @@ If you've already configured your application with the required configuration,
|
||||
you can further customize it's behavior by applying
|
||||
[Advanced Configuration]({{ "/advanced-configuration/" | relative_url }}).
|
||||
|
||||
## TALK_MONGO_URL
|
||||
### TALK_MONGO_URL
|
||||
|
||||
The database connection string for the MongoDB database. This usually takes the
|
||||
form of:
|
||||
@@ -31,7 +31,7 @@ TALK_MONGO_URL=mongodb://<DATABASE USER>:<DATABASE PASSWORD>@<DATABASE HOST>:<DA
|
||||
Refer to [connection string uri format](https://docs.mongodb.com/manual/reference/connection-string/){:target="_blank"}
|
||||
for the detailed url scheme of the MongoDB url.
|
||||
|
||||
## TALK_REDIS_URL
|
||||
### TALK_REDIS_URL
|
||||
|
||||
The database connection string for the Redis database. This usually takes the
|
||||
form of:
|
||||
@@ -50,7 +50,7 @@ TALK_REDIS_URL=redis://127.0.0.1:6379/2
|
||||
Refer to [uri scheme](http://www.iana.org/assignments/uri-schemes/prov/redis){:target="_blank"}
|
||||
for the detailed url scheme of the Redis url.
|
||||
|
||||
## TALK_ROOT_URL
|
||||
### TALK_ROOT_URL
|
||||
|
||||
The root url of the installed application externally available in the format:
|
||||
|
||||
@@ -70,7 +70,7 @@ TALK_ROOT_URL=https://talk.coralproject.net/
|
||||
_Note that we omitted the `PORT`, as it was implied by setting the `SCHEME` to
|
||||
`https`._
|
||||
|
||||
## TALK_JWT_SECRET
|
||||
### TALK_JWT_SECRET
|
||||
|
||||
Used to specify the application signing secret. You can specify this using a
|
||||
simple string, we recommend using a password generator and pasting it's output.
|
||||
@@ -85,7 +85,7 @@ Be default, we sign our tokens with HMAC using a SHA-256 hash algorithm. If you
|
||||
want to change the signing algorithm, or use multiple signing/verifying keys,
|
||||
refer to our [Advanced Configuration]({{ "/advanced-configuration/" | relative_url }}) documentation.
|
||||
|
||||
## TALK_FACEBOOK_APP_ID
|
||||
### TALK_FACEBOOK_APP_ID
|
||||
|
||||
The Facebook App ID for your Facebook Login enabled app. You can learn more
|
||||
about getting a Facebook App ID at the
|
||||
@@ -95,7 +95,7 @@ or by visiting the
|
||||
guide. This is only required while the `talk-plugin-facebook-auth` plugin is
|
||||
enabled.
|
||||
|
||||
## TALK_FACEBOOK_APP_SECRET
|
||||
### TALK_FACEBOOK_APP_SECRET
|
||||
|
||||
The Facebook App Secret for your Facebook Login enabled app. You can learn more
|
||||
about getting a Facebook App Secret at the
|
||||
@@ -103,4 +103,4 @@ about getting a Facebook App Secret at the
|
||||
or by visiting the
|
||||
[Creating an App ID](https://developers.facebook.com/docs/apps/register){:target="_blank"}
|
||||
guide. This is only required while the `talk-plugin-facebook-auth` plugin is
|
||||
enabled.
|
||||
enabled.
|
||||
+41
-41
@@ -19,37 +19,37 @@ If this is your first time configuring Talk, ensure you've also added the
|
||||
[Required Configuration]({{ "/configuration/" | relative_url }}) as well,
|
||||
otherwise the application will fail to start.
|
||||
|
||||
## TALK_CACHE_EXPIRY_COMMENT_COUNT
|
||||
### TALK_CACHE_EXPIRY_COMMENT_COUNT
|
||||
|
||||
Configure the duration for which comment counts are cached for, parsed by
|
||||
[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `1hr`)
|
||||
|
||||
## TALK_DEFAULT_LANG
|
||||
### TALK_DEFAULT_LANG
|
||||
|
||||
Specify the default translation language. (Default `en`)
|
||||
|
||||
## TALK_DEFAULT_STREAM_TAB
|
||||
### TALK_DEFAULT_STREAM_TAB
|
||||
|
||||
Specify the default stream tab in the admin. (Default `all`)
|
||||
|
||||
## TALK_DISABLE_AUTOFLAG_SUSPECT_WORDS
|
||||
### TALK_DISABLE_AUTOFLAG_SUSPECT_WORDS
|
||||
|
||||
When `TRUE`, disables flagging of comments that match the suspect word filter. (Default `FALSE`)
|
||||
|
||||
## TALK_DISABLE_EMBED_POLYFILL
|
||||
### TALK_DISABLE_EMBED_POLYFILL
|
||||
|
||||
When set to `TRUE`, the build process will not include the
|
||||
[babel-polyfill](https://babeljs.io/docs/usage/polyfill/){:target="_blank"}
|
||||
in the embed.js target that is loaded on the page that loads the embed. (Default
|
||||
`FALSE`)
|
||||
|
||||
## TALK_DISABLE_STATIC_SERVER
|
||||
### TALK_DISABLE_STATIC_SERVER
|
||||
|
||||
When `TRUE`, it will not mount the static asset serving routes on the router.
|
||||
This is used primarily in conjunction with [TALK_STATIC_URI](#talk_static_uri){: .param}
|
||||
when the static assets are being hosted on an external domain. (Default `FALSE`)
|
||||
|
||||
## TALK_HELMET_CONFIGURATION
|
||||
### TALK_HELMET_CONFIGURATION
|
||||
|
||||
A JSON string representing the configuration passed to the
|
||||
[helmet](https://github.com/helmetjs/helmet){:target="_blank"} middleware. It
|
||||
@@ -68,20 +68,20 @@ TALK_HELMET_CONFIGURATION={"hsts": false}
|
||||
|
||||
To disable these headers from being sent.
|
||||
|
||||
## TALK_INSTALL_LOCK
|
||||
### TALK_INSTALL_LOCK
|
||||
|
||||
When `TRUE`, disables the dynamic setup endpoint `/admin/install` from even
|
||||
loading. This prevents hits to the database with enabled. This should always be
|
||||
set to `TRUE` after you've deployed Talk. (Default `FALSE`)
|
||||
|
||||
## TALK_JWT_ALG
|
||||
### TALK_JWT_ALG
|
||||
|
||||
The algorithm used to sign/verify JWT’s used for session management. Read up
|
||||
about alternative algorithms on the
|
||||
[jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken#algorithms-supported){:target="_blank"}
|
||||
package. (Default `HS256`)
|
||||
|
||||
### Shared Secret
|
||||
#### Shared Secret
|
||||
{:.no_toc}
|
||||
|
||||
You would use a shared secret when you have no need to share the tokens with
|
||||
@@ -102,7 +102,7 @@ These must be provided in the form:
|
||||
```
|
||||
{: .no-copy}
|
||||
|
||||
### Asymmetric Secret
|
||||
#### Asymmetric Secret
|
||||
{:.no_toc}
|
||||
|
||||
You would use a asymmetric secret when you want to share the token in your
|
||||
@@ -138,23 +138,23 @@ certificates that match our required format: [coralcert](https://github.com/cora
|
||||
This tool can generate RSA and ECDSA certificates, check it's [README](https://github.com/coralproject/coralcert){:target="_blank"}
|
||||
for more details.
|
||||
|
||||
## TALK_JWT_AUDIENCE
|
||||
### TALK_JWT_AUDIENCE
|
||||
|
||||
The audience [aud](https://tools.ietf.org/html/rfc7519#section-4.1.3){:target="_blank"}
|
||||
claim for login JWT tokens. (Default `talk`)
|
||||
|
||||
## TALK_JWT_CLEAR_COOKIE_LOGOUT
|
||||
### TALK_JWT_CLEAR_COOKIE_LOGOUT
|
||||
|
||||
When `FALSE`, Talk will not clear the cookie with name
|
||||
[TALK_JWT_SIGNING_COOKIE_NAME](#talk_jwt_signing_cookie_name){: .param} when logging out
|
||||
but will still blacklist the token. (Default `TRUE`)
|
||||
|
||||
## TALK_JWT_COOKIE_NAME
|
||||
### TALK_JWT_COOKIE_NAME
|
||||
|
||||
The default cookie name to check for a valid JWT token to use for verifying a
|
||||
user. (Default `authorization`)
|
||||
|
||||
## TALK_JWT_COOKIE_NAMES
|
||||
### TALK_JWT_COOKIE_NAMES
|
||||
|
||||
The different cookie names to check for a JWT token in, separated by a `,`. By
|
||||
default, we always use the value of [TALK_JWT_COOKIE_NAME](#talk_jwt_cookie_name){: .param}
|
||||
@@ -176,19 +176,19 @@ Would mean we would check the following cookies (in order) for a valid token:
|
||||
2. `coralproject.talk`
|
||||
3. `coralproject.auth`
|
||||
|
||||
## TALK_JWT_DISABLE_AUDIENCE
|
||||
### TALK_JWT_DISABLE_AUDIENCE
|
||||
|
||||
When `TRUE`, Talk will not verify or sign JWT’s with an audience
|
||||
[aud](https://tools.ietf.org/html/rfc7519#section-4.1.3){:target="_blank"}
|
||||
claim, even if [TALK_JWT_AUDIENCE](#talk_jwt_audience){: .param} is set. (Default `FALSE`)
|
||||
|
||||
## TALK_JWT_DISABLE_ISSUER
|
||||
### TALK_JWT_DISABLE_ISSUER
|
||||
|
||||
When `TRUE`, Talk will not verify or sign JWT’s with an issuer
|
||||
[iss](https://tools.ietf.org/html/rfc7519#section-4.1.1){:target="_blank"}
|
||||
claim, even if [TALK_JWT_ISSUER](#talk_jwt_issuer){: .param} is set. (Default `FALSE`)
|
||||
|
||||
## TALK_JWT_EXPIRY
|
||||
### TALK_JWT_EXPIRY
|
||||
|
||||
The expiry duration [exp](https://tools.ietf.org/html/rfc7519#section-4.1.4){:target="_blank"}
|
||||
for the tokens issued for logged in sessions, parsed by
|
||||
@@ -199,12 +199,12 @@ If the user logs out, then an entry is created in the token blacklist of it's
|
||||
set to be automatically removed at it's expiry time. It is important for this
|
||||
reason to create reasonable expiry lengths as to minimize the storage overhead.
|
||||
|
||||
## TALK_JWT_ISSUER
|
||||
### TALK_JWT_ISSUER
|
||||
|
||||
The issuer [iss](https://tools.ietf.org/html/rfc7519#section-4.1.1){:target="_blank"}
|
||||
claim for login JWT tokens. (Defaults to value of [TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param})
|
||||
|
||||
## TALK_JWT_SECRET
|
||||
### TALK_JWT_SECRET
|
||||
|
||||
Used to specify the application signing secret. You can specify this using a
|
||||
simple string, we recommend using a password generator and pasting it's output.
|
||||
@@ -225,7 +225,7 @@ Refer to the documentation for [TALK_JWT_ALG](#talk_jwt_alg){: .param} for other
|
||||
methods and other forms of the `TALK_JWT_SECRET`. If you are interested in using
|
||||
multiple keys, then refer to [TALK_JWT_SECRETS](#talk_jwt_secrets){: .param}.
|
||||
|
||||
## TALK_JWT_SECRETS
|
||||
### TALK_JWT_SECRETS
|
||||
|
||||
Used when specifying multiple secrets used for key rotations. This is a JSON
|
||||
encoded array, where each element matches the JWT Secret pattern. When this is
|
||||
@@ -261,12 +261,12 @@ Refer to the documentation on the [TALK_JWT_ALG](#talk_jwt_alg){: .param} for mo
|
||||
information on what to store in these parameters.
|
||||
{: .code-aside}
|
||||
|
||||
## TALK_JWT_SIGNING_COOKIE_NAME
|
||||
### TALK_JWT_SIGNING_COOKIE_NAME
|
||||
|
||||
The default cookie name that is use to set a cookie containing a JWT that was
|
||||
issued by Talk. (Defaults to value of [TALK_JWT_COOKIE_NAME](#talk_jwt_cookie_name){: .param})
|
||||
|
||||
## TALK_JWT_USER_ID_CLAIM
|
||||
### TALK_JWT_USER_ID_CLAIM
|
||||
|
||||
Specify the claim using dot notation for where the user id should be stored/read
|
||||
to/from. (Default `sub`)
|
||||
@@ -287,13 +287,13 @@ Then we would set `TALK_JWT_USER_ID_CLAIM` to:
|
||||
TALK_JWT_USER_ID_CLAIM=user.id
|
||||
```
|
||||
|
||||
## TALK_KEEP_ALIVE
|
||||
### TALK_KEEP_ALIVE
|
||||
|
||||
The keepalive timeout that should be used to send keep alive messages through
|
||||
the websocket to keep the socket alive, parsed by
|
||||
[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `30s`)
|
||||
|
||||
## TALK_RECAPTCHA_PUBLIC
|
||||
### TALK_RECAPTCHA_PUBLIC
|
||||
|
||||
Client secret used for enabling reCAPTCHA powered logins. If
|
||||
[TALK_RECAPTCHA_SECRET](#talk_recaptcha_secret){: .param} and
|
||||
@@ -302,7 +302,7 @@ default to providing only a time based lockout. Refer to
|
||||
[reCAPTCHA](https://www.google.com/recaptcha/intro/index.html) for information
|
||||
on getting an account setup.
|
||||
|
||||
## TALK_RECAPTCHA_SECRET
|
||||
### TALK_RECAPTCHA_SECRET
|
||||
|
||||
Server secret used for enabling reCAPTCHA powered logins. If
|
||||
[TALK_RECAPTCHA_SECRET](#talk_recaptcha_secret){: .param} and
|
||||
@@ -311,7 +311,7 @@ default to providing only a time based lockout. Refer to
|
||||
[reCAPTCHA](https://www.google.com/recaptcha/intro/index.html) for information
|
||||
on getting an account setup.
|
||||
|
||||
## TALK_REDIS_CLIENT_CONFIG
|
||||
### TALK_REDIS_CLIENT_CONFIG
|
||||
|
||||
Configuration overrides for the redis client configuration in a JSON encoded
|
||||
string. Configuration is overridden as the second parameter to the redis client
|
||||
@@ -319,30 +319,30 @@ constructor, and is merged with default configuration. Refer to the
|
||||
[ioredis](https://github.com/luin/ioredis){:target="_blank"} docs on the
|
||||
available options. (Default `{}`)
|
||||
|
||||
## TALK_REDIS_CLUSTER_CONFIGURATION
|
||||
### TALK_REDIS_CLUSTER_CONFIGURATION
|
||||
|
||||
The JSON encoded form of the cluster nodes. Only required when
|
||||
[TALK_REDIS_CLUSTER_MODE](#talk_redis_cluster_mode){: .param} is `CLUSTER`. See
|
||||
[https://github.com/luin/ioredis#cluster](https://github.com/luin/ioredis#cluster){:target="_blank"}
|
||||
for configuration details. (Default `[]`)
|
||||
|
||||
## TALK_REDIS_CLUSTER_MODE
|
||||
### TALK_REDIS_CLUSTER_MODE
|
||||
|
||||
The cluster mode of the redis client. Can be either `NONE` or `CLUSTER`.
|
||||
(Default `NONE`)
|
||||
|
||||
## TALK_REDIS_RECONNECTION_BACKOFF_FACTOR
|
||||
### TALK_REDIS_RECONNECTION_BACKOFF_FACTOR
|
||||
|
||||
The time factor that will be multiplied against the current attempt count
|
||||
between attempts to connect to redis, parsed by
|
||||
[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `500 ms`)
|
||||
|
||||
## TALK_REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME
|
||||
### TALK_REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME
|
||||
|
||||
The minimum time used to delay before attempting to reconnect to redis, parsed
|
||||
by [ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `1 sec`)
|
||||
|
||||
## TALK_ROOT_URL_MOUNT_PATH
|
||||
### TALK_ROOT_URL_MOUNT_PATH
|
||||
|
||||
When set to `TRUE`, the routes will be mounted onto the `<PATHNAME>` component
|
||||
of the [TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param}.
|
||||
@@ -361,7 +361,7 @@ Then all the routes for the API will be expecting to be hit on `/talk/`, such as
|
||||
can perform the path stripping when serving an upstream proxy, but some CDN's
|
||||
cannot. You would use this option in the latter situation.
|
||||
|
||||
## TALK_SMTP_EMAIL
|
||||
### TALK_SMTP_EMAIL
|
||||
|
||||
The email address to send emails from using the SMTP provider in the format:
|
||||
|
||||
@@ -371,23 +371,23 @@ TALK_SMTP_EMAIL="The Coral Project" <support@coralproject.net>
|
||||
|
||||
Including the name and email address.
|
||||
|
||||
## TALK_SMTP_HOST
|
||||
### TALK_SMTP_HOST
|
||||
|
||||
The domain for the SMTP provider that you are using.
|
||||
|
||||
## TALK_SMTP_PASSWORD
|
||||
### TALK_SMTP_PASSWORD
|
||||
|
||||
The password for the SMTP provider you are using.
|
||||
|
||||
## TALK_SMTP_PORT
|
||||
### TALK_SMTP_PORT
|
||||
|
||||
The port for the SMTP provider that you are using.
|
||||
|
||||
## TALK_SMTP_USERNAME
|
||||
### TALK_SMTP_USERNAME
|
||||
|
||||
The username of the SMTP provider you are using.
|
||||
|
||||
## TALK_STATIC_URI
|
||||
### TALK_STATIC_URI
|
||||
|
||||
Used to set the uri where the static assets should be served from. This is used
|
||||
when you want to upload the static assets through your build process to a
|
||||
@@ -395,14 +395,14 @@ service like Google Cloud Storage or Amazon S3 and you would then specify the
|
||||
CDN/Storage url. (Defaults to value of
|
||||
[TALK_ROOT_URL]({{ "/configuration/#talk_root_url" | relative_url }}){: .param})
|
||||
|
||||
## TALK_THREADING_LEVEL
|
||||
### TALK_THREADING_LEVEL
|
||||
|
||||
Specify the maximum depth of the comment thread. (Default `3`)
|
||||
|
||||
**Note that a high value for `TALK_THREADING_LEVEL` will result in large
|
||||
performance impacts.**
|
||||
|
||||
## TALK_WEBSOCKET_LIVE_URI
|
||||
### TALK_WEBSOCKET_LIVE_URI
|
||||
|
||||
Used to override the location to connect to the websocket endpoint to
|
||||
potentially another host. This should be used when you need to route websocket
|
||||
@@ -419,7 +419,7 @@ is `FALSE`, or the path component of
|
||||
**Warning: if used without managing the auth state manually, auth
|
||||
cannot be persisted due to browser restrictions.**
|
||||
|
||||
## TRUST_THRESHOLDS
|
||||
### TRUST_THRESHOLDS
|
||||
|
||||
Configure the reliability thresholds for flagging and commenting. (Default
|
||||
`comment:2,-1;flag:2,-1`)
|
||||
@@ -116,4 +116,4 @@ assets inside the image as well.
|
||||
|
||||
For more information on the onbuild image, refer to the
|
||||
[Installation from Docker]({{ "/installation-from-docker/" | relative_url }})
|
||||
documentation.
|
||||
documentation.
|
||||
@@ -0,0 +1,152 @@
|
||||
---
|
||||
title: Default Plugins
|
||||
permalink: /default-plugins/
|
||||
class: configuration
|
||||
---
|
||||
|
||||
The default Talk plugins can be found in the `plugins.default.json` file
|
||||
[here](https://github.com/coralproject/talk/blob/master/plugins.default.json).
|
||||
|
||||
Talk ships out of the box with these plugins enabled:
|
||||
|
||||
{% include toc.html %}
|
||||
|
||||
We ship [Additional Plugins]({{ "/additional-plugins/" | relative_url }}) with
|
||||
Talk that are not enabled by default. You can enable these or disable these
|
||||
default plugins by consulting the [Plugins Overview]({{ "/plugins/" | relative_url }})
|
||||
page.
|
||||
|
||||
### talk-plugin-auth
|
||||
|
||||
Source: [plugins/talk-plugin-auth](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-auth){:target="_blank"}
|
||||
|
||||
Enables generic registration via an email address, a username, a password, and a
|
||||
password confirmation. To sync Talk auth with your own auth systems, you can use
|
||||
this plugin as a template.
|
||||
|
||||
### talk-plugin-facebook-auth
|
||||
|
||||
Source: [plugins/talk-plugin-auth](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-auth){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-facebook-auth](#talk-plugin-facebook-auth){:.param}
|
||||
|
||||
Enables sign-in via Facebook via the server side passport middleware.
|
||||
|
||||
Configuration:
|
||||
|
||||
{:.no_toc}
|
||||
|
||||
- [TALK_FACEBOOK_APP_ID]({{ "/configuration/#talk_facebook_app_id" | relative_url }}){:.param} (**required**) - See the existing documentation for the [TALK_FACEBOOK_APP_ID]({{ "/configuration/#talk_facebook_app_id" | relative_url }}){:.param}.
|
||||
- [TALK_FACEBOOK_APP_SECRET]({{ "/configuration/#talk_facebook_app_secret" | relative_url }}){:.param} (**required**) - See the existing documentation for the [TALK_FACEBOOK_APP_SECRET]({{ "/configuration/#talk_facebook_app_secret" | relative_url }}){:.param}.
|
||||
|
||||
### talk-plugin-featured-comments
|
||||
|
||||
Source: [plugins/talk-plugin-featured-comments](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-featured-comments){:target="_blank"}
|
||||
|
||||
Enables the ability for Moderators to feature and un-feature comments via the
|
||||
Stream and the Admin. Featured comments show in a first-place tab on the Stream
|
||||
if there are any featured comments on that story.
|
||||
|
||||
### talk-plugin-respect
|
||||
|
||||
Source: [plugins/talk-plugin-respect](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-respect){:target="_blank"}
|
||||
|
||||
Enables a `respect` reaction button. Why a "respect" button, you ask?
|
||||
[Read more here](https://mediaengagement.org/research/engagement-buttons/).
|
||||
|
||||
### talk-plugin-comment-content
|
||||
|
||||
Source: [plugins/talk-plugin-comment-content](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-comment-content){:target="_blank"}
|
||||
|
||||
Pluginizes the text of a comment to support custom treatment of this text. This
|
||||
plugin currently parses the given text to see if it contains a link, and makes
|
||||
them clickable.
|
||||
|
||||
### talk-plugin-ignore-user
|
||||
|
||||
Source: [plugins/talk-plugin-ignore-user](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-ignore-user){:target="_blank"}
|
||||
|
||||
Enables ability for users to ignore (or "mute") other users. If a user is
|
||||
ignored, you will not see any of their comments. You can un-ignore a user via
|
||||
the My Profile tab.
|
||||
|
||||
### talk-plugin-permalink
|
||||
|
||||
Source: [plugins/talk-plugin-permalink](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-permalink){:target="_blank"}
|
||||
|
||||
Enables a `Link` button that will provide a permalink to the comment that can be
|
||||
shared with others.
|
||||
|
||||
### talk-plugin-viewing-options
|
||||
|
||||
Source: [plugins/talk-plugin-viewing-options](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-viewing-options){:target="_blank"}
|
||||
|
||||
Pluginizes the sorting/viewing options for a comment stream.
|
||||
|
||||
### talk-plugin-sort-newest
|
||||
|
||||
Source: [plugins/talk-plugin-sort-newest](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-sort-newest){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options](#talk-plugin-viewing-options){:.param}
|
||||
|
||||
Provides a sort for the newest comments first. This isn't necessarily required
|
||||
as the default sort without options/plugins is newest first.
|
||||
|
||||
### talk-plugin-sort-oldest
|
||||
|
||||
Source: [plugins/talk-plugin-sort-oldest](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-sort-oldest){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options](#talk-plugin-viewing-options){:.param}
|
||||
|
||||
Provides a sort for the newest comments first.
|
||||
|
||||
### talk-plugin-most-respected
|
||||
|
||||
Source: [plugins/talk-plugin-most-respected](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-most-respected){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options](#talk-plugin-viewing-options){:.param}, [talk-plugin-respect](#talk-plugin-respect){:.param}
|
||||
|
||||
Provides a sort for the comments with the most `respect` reactions first.
|
||||
|
||||
### talk-plugin-most-replied
|
||||
|
||||
Source: [plugins/talk-plugin-most-replied](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-most-replied){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options](#talk-plugin-viewing-options){:.param}
|
||||
|
||||
Provides a sort for the comments with the most replies first.
|
||||
|
||||
### talk-plugin-offtopic
|
||||
|
||||
Source: [plugins/talk-plugin-offtopic](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-offtopic){:target="_blank"}
|
||||
|
||||
Allows the comment authors to tag their comment as `Off-Topic` which will add a
|
||||
visible badge on the frontend to other users that their comment is off-topic.
|
||||
|
||||
### talk-plugin-author-menu
|
||||
|
||||
Source: [plugins/talk-plugin-author-menu](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-author-menu){:target="_blank"}
|
||||
|
||||
Pluginizes the author's name on hover.
|
||||
|
||||
### talk-plugin-member-since
|
||||
|
||||
Source: [plugins/talk-plugin-member-since](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-member-since){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-author-menu](#talk-plugin-author-menu){:.param}
|
||||
|
||||
Displays the date that the user was created as a `Member Since ${created_at}`.
|
||||
|
||||
### talk-plugin-moderation-actions
|
||||
|
||||
Source: [plugins/talk-plugin-moderation-actions](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-moderation-actions){:target="_blank"}
|
||||
|
||||
Enables in-stream moderation so that Moderators can reject, approve comments,
|
||||
as well as ban users, directly from the comment stream. When [talk-plugin-featured-comments](#talk-plugin-featured-comments){:.param} is enabled
|
||||
|
||||
### talk-plugin-flag-details
|
||||
|
||||
Source: [plugins/talk-plugin-flag-details](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-flag-details){:target="_blank"}
|
||||
|
||||
Pluginizes the Flag Details area of comments in the Moderation Queues to display
|
||||
data. Some basic details are already included on flags by default.
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Additional Plugins
|
||||
permalink: /additional-plugins/
|
||||
class: configuration
|
||||
---
|
||||
|
||||
Talk ships with several plugins that aren't enabled by default:
|
||||
|
||||
{% include toc.html %}
|
||||
|
||||
These plugins can be enabled by consulting the
|
||||
[Plugins Overview]({{ "/plugins/" | relative_url }}) page.
|
||||
|
||||
### talk-plugin-like
|
||||
|
||||
Source: [plugins/talk-plugin-like](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-like){:target="_blank"}
|
||||
|
||||
Enables a `like` reaction button.
|
||||
|
||||
### talk-plugin-sort-most-liked
|
||||
|
||||
Source: [plugins/talk-plugin-sort-most-liked](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-sort-most-liked){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options]({{ "/default-plugins/#talk-plugin-viewing-options" | relative_url }}){:.param}, [talk-plugin-like](#talk-plugin-like){:.param}
|
||||
|
||||
Provides a sort for the comments with the most `like` reactions first.
|
||||
|
||||
### talk-plugin-love
|
||||
|
||||
Source: [plugins/talk-plugin-love](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-love){:target="_blank"}
|
||||
|
||||
Enables a `love` reaction button.
|
||||
|
||||
### talk-plugin-sort-most-loved
|
||||
|
||||
Source: [plugins/talk-plugin-sort-most-loved](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-sort-most-loved){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options]({{ "/default-plugins/#talk-plugin-viewing-options" | relative_url }}){:.param}, [talk-plugin-love](#talk-plugin-love){:.param}
|
||||
|
||||
Provides a sort for the comments with the most `love` reactions first.
|
||||
|
||||
### talk-plugin-remember-sort
|
||||
|
||||
Source: [plugins/talk-plugin-remember-sort](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-remember-sort){:target="_blank"}
|
||||
|
||||
Requires: [talk-plugin-viewing-options]({{ "/default-plugins/#talk-plugin-viewing-options" | relative_url }}){:.param}
|
||||
|
||||
Enables saving a user’s last sort selection as they browse other articles.
|
||||
|
||||
### talk-plugin-deep-reply-count
|
||||
|
||||
Source: [plugins/talk-plugin-deep-reply-count](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-deep-reply-count){:target="_blank"}
|
||||
|
||||
Enables counting of comments to include replies via a new graph edge. Not
|
||||
recommended for large installations as it will unreasonably reduce the query
|
||||
efficiency to compute this number.
|
||||
|
||||
### talk-plugin-slack-notifications
|
||||
|
||||
Source: [plugins/talk-plugin-slack-notifications](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-slack-notifications){:target="_blank"}
|
||||
|
||||
Enables all new comments that are written to be posted to a Slack channel as
|
||||
well. Configure an
|
||||
[Incoming Webhook](https://api.slack.com/incoming-webhooks){:target="_blank"}
|
||||
app and provide that url in the form of the `SLACK_WEBHOOK_URL`
|
||||
detailed below.
|
||||
|
||||
*Warning: On high volume sites, this means every single comment will flow into
|
||||
Slack, if this isn't what you want, be sure to use the provided plugin as a
|
||||
recipe to further customize the behavior*.
|
||||
|
||||
Configuration:
|
||||
{:.no_toc}
|
||||
|
||||
- `SLACK_WEBHOOK_URL` (**required**) - The webhook url that will be
|
||||
used to post new comments to.
|
||||
|
||||
### talk-plugin-toxic-comments
|
||||
|
||||
Source: [plugins/talk-plugin-toxic-comments](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-toxic-comments){:target="_blank"}
|
||||
|
||||
Using the [Perspective API](http://perspectiveapi.com/){:target="_blank"}, this
|
||||
plugin will warn users and reject comments that exceed the predefined toxicity
|
||||
threshold. For more information on what Toxic Comments are, check out the
|
||||
[Toxic Comments]({{ "/toxic-comments/" | relative_url }}) documentation.
|
||||
|
||||
Configuration:
|
||||
{:.no_toc}
|
||||
|
||||
- `TALK_PERSPECTIVE_API_KEY` (**required**) - The API Key for Perspective. You
|
||||
can register and get your own key at [http://perspectiveapi.com/](http://perspectiveapi.com/){:target="_blank"}.
|
||||
- `TALK_TOXICITY_THRESHOLD` - If the comments toxicity exceeds this threshold,
|
||||
the comment will be rejected. (Default `0.8`)
|
||||
- `TALK_PERSPECTIVE_API_ENDPOINT` - API Endpoint for hitting the
|
||||
perspective API. (Default `https://commentanalyzer.googleapis.com/v1alpha1`)
|
||||
- `TALK_PERSPECTIVE_TIMEOUT` - The timeout for sending a comment to
|
||||
be processed before it will skip the toxicity analysis, parsed by
|
||||
[ms](https://www.npmjs.com/package/ms){:target="_blank"}. (Default `300ms`)
|
||||
|
||||
### talk-plugin-subscriber
|
||||
|
||||
Source: [plugins/talk-plugin-subscriber](https://github.com/coralproject/talk/tree/master/plugins/talk-plugin-subscriber){:target="_blank"}
|
||||
|
||||
Enables a `Subscriber` badge to be added to comments where the author has the
|
||||
`SUBSCRIBER` tag. This must match with a custom auth integration that adds the
|
||||
tag to the users that are subscribed to the service.
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: Plugin Recipes
|
||||
permalink: /plugin-recipes/
|
||||
class: configuration
|
||||
---
|
||||
|
||||
Plugin Recipes are plugin templates used to help bootstrap the development of a
|
||||
plugin. Recipes are available at the
|
||||
[coralproject/talk-recipes](https://github.com/coralproject/talk-recipes) repo.
|
||||
When first developing a plugin with a recipe, you can simply visit the
|
||||
aforementioned repository to find the desired recipe, and using the file
|
||||
listings on the page, determine which files need to be modified to suit your
|
||||
needs.
|
||||
|
||||
The following are the available recipes for use:
|
||||
|
||||
{% include toc.html %}
|
||||
|
||||
### recipe-avatar
|
||||
|
||||
Source: [talk-recipes/tree/master/plugins/avatar](https://github.com/coralproject/talk-recipes/tree/master/plugins/avatar){:target="_blank"}
|
||||
|
||||
Provides support for avatars hosted via third party, extends the User Model and
|
||||
provides UI on the client-side too.
|
||||
|
||||
|
||||
### recipe-translations
|
||||
|
||||
Source: [talk-recipes/tree/master/plugins/translations](https://github.com/coralproject/talk-recipes/tree/master/plugins/translations){:target="_blank"}
|
||||
|
||||
Provides an example for overriding application text through the translation
|
||||
system.
|
||||
|
||||
|
||||
### recipe-subscriber
|
||||
|
||||
Source: [talk-recipes/tree/master/plugins/subscriber](https://github.com/coralproject/talk-recipes/tree/master/plugins/subscriber){:target="_blank"}
|
||||
|
||||
Provides an example for adding `SUBSCRIBER` badges for users with the
|
||||
`SUBSCRIBER` tag added to their user model through a direct server plugin with
|
||||
the auth system.
|
||||
|
||||
|
||||
### recipe-author-name
|
||||
|
||||
Source: [talk-recipes/tree/master/plugins/author-name](https://github.com/coralproject/talk-recipes/tree/master/plugins/author-name){:target="_blank"}
|
||||
|
||||
Enables the ability to hover over a commenter’s name and add plugin
|
||||
functionality there. The Member Since plugin that is provided in this recipe is
|
||||
an example of this.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: How Talk Works
|
||||
permalink: /how-talk-works/
|
||||
---
|
||||
|
||||
Talk is an open-source commenting platform. It has two pieces. One is the
|
||||
embedded script, which allows newsrooms to have a unique comments section on
|
||||
each story/post/page they have on their site, and allows their readers to
|
||||
comment and discuss articles. The other is the Admin, which is where newsrooms
|
||||
moderate their comments and manage and configure Talk.
|
||||
|
||||
## Talk Core
|
||||
|
||||
As we’re building Talk, our vision was always to have it be very modular, so
|
||||
there are features we have built and are opinionated about, but we allow
|
||||
newsrooms and their developers to customize Talk easily so that it fits their
|
||||
use cases and needs.
|
||||
|
||||
Talk Core is the core application of Talk - this contains all of the standard
|
||||
commenting features that are necessary for a comment section, and ones that we
|
||||
believe are important to be universal. If you would like to contribute to Talk,
|
||||
be sure to check out our
|
||||
[Contributor's Guide](https://github.com/coralproject/talk/blob/master/CONTRIBUTING.md){:target="_blank"}.
|
||||
|
||||
## Plugins
|
||||
|
||||
Plugins are additional functionality which are optional to use with Talk. You
|
||||
can turn these on or off, depending on your specific needs. Plugins are either
|
||||
part of our core plugins, which ship with Talk, or they are developed by 3rd
|
||||
parties and either used privately and internally, or are open sourced for use
|
||||
across the greater community. You can explore the plugins we offer by visiting our [Default Plugins]({{ "/default-plugins/" | relative_url}})
|
||||
and [Additional Plugins]({{ "/additional-plugins/" | relative_url }}) pages.
|
||||
|
||||
## Recipes
|
||||
|
||||
Recipes are plugin templates that are created by the Talk team and 3rd party
|
||||
developers, in order to help contributors and newsrooms build plugins easily.
|
||||
You can explore the recipes we offer by visiting our [Plugin Recipes]({{ "/plugin-recipes/" | relative_url}})
|
||||
page.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: Trust
|
||||
permalink: /trust/
|
||||
---
|
||||
|
||||
Trust is a set of components within Talk that incorporate automated moderation
|
||||
features based on a user's previous behavior.
|
||||
|
||||
### User Karma Score
|
||||
|
||||
Using Trust’s calculations, Talk will automatically pre-moderate comments of
|
||||
users who have a negative karma score. All users start out with a `0` neutral
|
||||
karma score. If they have a comment approved by a moderator, their score
|
||||
increases by `1`; if they have a comment rejected by a moderator, it decreases
|
||||
by `1`. When a commenter is labeled as Unreliable, their comments must be
|
||||
moderated before they are posted.
|
||||
|
||||
When a commenter has one comment rejected, their next comment must be moderated
|
||||
once in order to post freely again. If they instead get rejected again, then
|
||||
they must have two of their comments approved in order to get added back to the
|
||||
queue.
|
||||
|
||||
Here are the default thresholds:
|
||||
|
||||
```text
|
||||
-2 and lower: Unreliable
|
||||
-1 to +2: Neutral
|
||||
+3 and higher: Reliable
|
||||
```
|
||||
|
||||
You can configure your own Trust thresholds by using [TRUST_THRESHOLD]({{"/advanced-configuration/#trust_thresholds" | relative_url }}{:.param}) in your
|
||||
configuration.
|
||||
|
||||
|
||||
### Reliable and Unreliable Flaggers
|
||||
|
||||
Trust also calculates how reliable users are in terms of the comments they
|
||||
report. This information is displayed to moderators in the User History drawer,
|
||||
which is accessed by clicking on a user’s name in the Admin.
|
||||
|
||||
If a user's reports mostly match what moderators reject, their Report status
|
||||
will display to moderators as Reliable in the user information drawer. If a
|
||||
user's reports mostly differ from what moderators reject, their Report status
|
||||
will show as Unreliable.
|
||||
|
||||
If we don't have enough reports to make a call, or the reports even out, their
|
||||
status is Neutral.
|
||||
|
||||
Note: Report Karma doesn't include reports of "I don't agree with this comment".
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: Toxic Comments
|
||||
permalink: /toxic-comments/
|
||||
---
|
||||
|
||||
Leveraging Google's Perspective API, you can now set a Toxicity Threshold for
|
||||
Talk (0.8 or 80% is the default), which works like this:
|
||||
|
||||
- If a comment exceeds the threshold, the commenter is warned that their comment
|
||||
may be toxic, and are given the chance to modify their comment before posting
|
||||
- If the revised comment is below the Toxicity Threshold, it is posted and
|
||||
displayed normally
|
||||
- If the revised comment still exceeds the Toxicity Threshold, it is not
|
||||
displayed on the stream and instead is sent to the Reported queue for
|
||||
moderation
|
||||
- If the moderator accepts the comment, it's displayed on the stream; if it's
|
||||
rejected, it will not be displayed
|
||||
- Moderators see a Toxic Probability Score on toxic comments in the Moderation
|
||||
queues
|
||||
|
||||
Read more about Coral’s take on toxicity
|
||||
[on our blog](https://blog.coralproject.net/toxic-avenging/){:target="_blank"}.
|
||||
|
||||
### What is the Perspective API?
|
||||
|
||||
The likely toxicity of a comment is evaluated using scores generated from
|
||||
[Perspective API](http://perspectiveapi.com/){:target="_blank"}. This is part of
|
||||
the [Conversation AI](https://conversationai.github.io/){:target="_blank"}
|
||||
research effort run by Jigsaw (a section of Google that works on global problems
|
||||
around speech and access to information).
|
||||
|
||||
Perspective API uses machine learning, based on existing databases of
|
||||
accepted/rejected comments, to guess the probability that a comment is abusive
|
||||
and/or toxic. It is currently English only, but the system is designed to work
|
||||
with multiple languages.
|
||||
|
||||
In order to activate our plugin, each news organization applies for an API key
|
||||
from Jigsaw (click “Request API access” on this site.) Sites can also work with
|
||||
Jigsaw to create an individualized data set specifically trained on their own
|
||||
comment history.
|
||||
|
||||
Perspective API was released earlier this year, and is currently in alpha
|
||||
(meaning that it is being continually refined and improved.) Jigsaw should
|
||||
certainly be praised for devoting serious resources to this issue, and making
|
||||
their work available for others, including us, to use.
|
||||
|
||||
We’ve talked with their team on several occasions, and have been impressed by
|
||||
their dedication and commitment to this issue. These are smart people who are
|
||||
trying to improve a broken part of the internet.
|
||||
|
||||
### How do I add the Toxic Comments plugin?
|
||||
To enable this behavior, visit the
|
||||
[talk-plugin-toxic-comments]({{ "/additional-plugins/#talk-plugin-toxic-comments" | relative_url }})
|
||||
plugin documentation.
|
||||
|
||||
|
||||
### Request an API Key
|
||||
|
||||
You can read more about Google's Perspective API and/or request an API key here: [http://perspectiveapi.com/](http://perspectiveapi.com/).
|
||||
@@ -2,7 +2,7 @@
|
||||
layout: default
|
||||
---
|
||||
<article{% if page.class %} class="{{ page.class }}"{% endif %}>
|
||||
<a class="btn btn-sm btn-light float-right suggest-edits" href="https://github.com/coralproject/talk/edit/master/docs/{{ page.path }}" title="Suggest edits to this page">Suggest Edits</a>
|
||||
<a class="btn btn-sm btn-light float-right suggest-edits plain-link" href="https://github.com/coralproject/talk/edit/master/docs/{{ page.path }}" title="Suggest edits to this page">Suggest Edits</a>
|
||||
<h1>{{ page.title }}</h1>
|
||||
<hr/>
|
||||
|
||||
|
||||
+10
-4
@@ -36,13 +36,17 @@ h2, h3, h4 {
|
||||
}
|
||||
}
|
||||
|
||||
.param {
|
||||
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
article.configuration {
|
||||
h2 {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
h2, .toc, .param {
|
||||
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
h2, .toc {
|
||||
@extend .param;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,10 +231,9 @@ pre {
|
||||
}
|
||||
|
||||
.coral-link {
|
||||
border-bottom: 2px dotted $coral_button_border_color;
|
||||
border-bottom: 1px solid $coral_button_border_color;
|
||||
color: $coral_button_color;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: $coral_button_hover_color;
|
||||
@@ -260,6 +263,9 @@ pre {
|
||||
p a:not(.plain-link) {
|
||||
@extend .coral-link;
|
||||
}
|
||||
ul:not(.toc__menu) li a {
|
||||
@extend .coral-link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -57,13 +57,13 @@ en:
|
||||
banned_user: "Banned User"
|
||||
cancel: Cancel
|
||||
dont_like_username: "Dislike username"
|
||||
flaggedaccounts: "Flagged Usernames"
|
||||
flaggedaccounts: "Reported Usernames"
|
||||
flags: Flags
|
||||
impersonating: "Impersonation"
|
||||
loading: "Loading results"
|
||||
moderator: Moderator
|
||||
newsroom_role: "Newsroom Role"
|
||||
no_flagged_accounts: "The Flagged Usernames queue is currently empty."
|
||||
no_flagged_accounts: "The Reported Usernames queue is currently empty."
|
||||
no_results: "No users found with that user name or email address. They're hiding!"
|
||||
offensive: "Offensive"
|
||||
other: Other
|
||||
|
||||
+14
-14
@@ -1,27 +1,27 @@
|
||||
{
|
||||
"server": [
|
||||
"talk-plugin-auth",
|
||||
"talk-plugin-respect",
|
||||
"talk-plugin-offtopic",
|
||||
"talk-plugin-facebook-auth",
|
||||
"talk-plugin-featured-comments"
|
||||
"talk-plugin-featured-comments",
|
||||
"talk-plugin-offtopic",
|
||||
"talk-plugin-respect"
|
||||
],
|
||||
"client": [
|
||||
"talk-plugin-respect",
|
||||
"talk-plugin-auth",
|
||||
"talk-plugin-offtopic",
|
||||
"talk-plugin-viewing-options",
|
||||
"talk-plugin-author-menu",
|
||||
"talk-plugin-comment-content",
|
||||
"talk-plugin-permalink",
|
||||
"talk-plugin-featured-comments",
|
||||
"talk-plugin-flag-details",
|
||||
"talk-plugin-ignore-user",
|
||||
"talk-plugin-member-since",
|
||||
"talk-plugin-moderation-actions",
|
||||
"talk-plugin-offtopic",
|
||||
"talk-plugin-permalink",
|
||||
"talk-plugin-respect",
|
||||
"talk-plugin-sort-most-replied",
|
||||
"talk-plugin-sort-most-respected",
|
||||
"talk-plugin-sort-newest",
|
||||
"talk-plugin-sort-oldest",
|
||||
"talk-plugin-sort-most-respected",
|
||||
"talk-plugin-sort-most-replied",
|
||||
"talk-plugin-author-menu",
|
||||
"talk-plugin-member-since",
|
||||
"talk-plugin-ignore-user",
|
||||
"talk-plugin-moderation-actions",
|
||||
"talk-plugin-flag-details"
|
||||
"talk-plugin-viewing-options"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
"description": "Provides support for measuring the toxicity of user comments using the Perspectives API",
|
||||
"main": "index.js",
|
||||
"author": "The Coral Project Team <coral@mozillafoundation.org>",
|
||||
"license": "Apache-2.0"
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"ms": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
const ms = require('ms');
|
||||
|
||||
const config = {
|
||||
API_ENDPOINT: process.env.TALK_PERSPECTIVE_API_ENDPOINT || 'https://commentanalyzer.googleapis.com/v1alpha1',
|
||||
API_KEY: process.env.TALK_PERSPECTIVE_API_KEY,
|
||||
THRESHOLD: process.env.TALK_TOXICITY_THRESHOLD || 0.8,
|
||||
API_TIMEOUT: process.env.TALK_PERSPECTIVE_TIMEOUT || 300,
|
||||
API_TIMEOUT: ms(process.env.TALK_PERSPECTIVE_TIMEOUT || '300ms'),
|
||||
};
|
||||
|
||||
if (process.env.NODE_ENV !== 'test' && !config.API_KEY) {
|
||||
|
||||
@@ -2,3 +2,6 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
ms@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ module.exports = class AssetsService {
|
||||
static search({value, limit, open, sortOrder, cursor} = {}) {
|
||||
let assets = AssetModel.find({});
|
||||
|
||||
if (value) {
|
||||
if (value && value.length > 0) {
|
||||
assets.merge({
|
||||
$text: {
|
||||
$search: value
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Escape string for special regular expression characters.
|
||||
*/
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
escapeRegExp,
|
||||
};
|
||||
+10
-4
@@ -25,6 +25,7 @@ const ActionsService = require('./actions');
|
||||
const MailerService = require('./mailer');
|
||||
const Wordlist = require('./wordlist');
|
||||
const Domainlist = require('./domainlist');
|
||||
const {escapeRegExp} = require('./regex');
|
||||
|
||||
const EMAIL_CONFIRM_JWT_SUBJECT = 'email_confirm';
|
||||
const PASSWORD_RESET_JWT_SUBJECT = 'password_reset';
|
||||
@@ -631,14 +632,19 @@ module.exports = class UsersService {
|
||||
* @return {Promise}
|
||||
*/
|
||||
static search(value) {
|
||||
if (!value || typeof value !== 'string' || value.length === 0) {
|
||||
return UserModel.find({});
|
||||
}
|
||||
|
||||
value = escapeRegExp(value);
|
||||
|
||||
return UserModel.find({
|
||||
$or: [
|
||||
|
||||
// Search by a prefix match on the username.
|
||||
{
|
||||
'username': {
|
||||
$regex: new RegExp(`^${value}`),
|
||||
$options: 'i'
|
||||
'lowercaseUsername': {
|
||||
$regex: new RegExp(value.toLowerCase())
|
||||
}
|
||||
},
|
||||
|
||||
@@ -647,7 +653,7 @@ module.exports = class UsersService {
|
||||
'profiles': {
|
||||
$elemMatch: {
|
||||
id: {
|
||||
$regex: new RegExp(`^${value}`),
|
||||
$regex: new RegExp(value),
|
||||
$options: 'i'
|
||||
},
|
||||
provider: 'local'
|
||||
|
||||
@@ -3,13 +3,7 @@ const _ = require('lodash');
|
||||
const SettingsService = require('./settings');
|
||||
const Errors = require('../errors');
|
||||
const memoize = require('lodash/memoize');
|
||||
|
||||
/**
|
||||
* Escape string for special regular expression characters.
|
||||
*/
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
}
|
||||
const {escapeRegExp} = require('./regex');
|
||||
|
||||
/**
|
||||
* Generate a regulare expression that catches the `phrases`.
|
||||
|
||||
@@ -221,6 +221,50 @@ describe('services.UsersService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#search', () => {
|
||||
it('should return all the results without a value', async () => {
|
||||
expect(await UsersService.search()).to.have.length(3);
|
||||
});
|
||||
|
||||
it('should match the search terms', async () => {
|
||||
const tests = [
|
||||
{
|
||||
search: 'monster',
|
||||
results: 1,
|
||||
id: mockUsers[1].id,
|
||||
},
|
||||
{
|
||||
search: 'Stamp',
|
||||
results: 1,
|
||||
id: mockUsers[0].id,
|
||||
},
|
||||
{
|
||||
search: 'sockmonster@gmail.com',
|
||||
results: 1,
|
||||
id: mockUsers[1].id,
|
||||
},
|
||||
{
|
||||
search: 'marvel',
|
||||
results: 1,
|
||||
id: mockUsers[2].id,
|
||||
},
|
||||
{
|
||||
search: 'gmail.com',
|
||||
results: 3
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of tests) {
|
||||
const users = await UsersService.search(test.search);
|
||||
|
||||
expect(users).to.have.length(test.results);
|
||||
if (test.results === 1) {
|
||||
expect(users[0]).to.have.property('id', test.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#editName', () => {
|
||||
it('should let the user edit their username if the proper toggle is set', () => {
|
||||
return UsersService
|
||||
|
||||
Reference in New Issue
Block a user