diff --git a/.gitignore b/.gitignore index bd86e6906..e8dfd14e7 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ plugins/* !plugins/coral-plugin-respect !plugins/coral-plugin-offtopic +**/node_modules/* diff --git a/Dockerfile b/Dockerfile index 5bc38013a..90c08057f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:7 +FROM node:7.9 # Create app directory RUN mkdir -p /usr/src/app diff --git a/INSTALL.md b/INSTALL.md index 33b634de8..18244f635 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,37 +1,204 @@ +## Contents + +- [Installation](#installation) - install the application on a machine + - [Via Docker](#installation-from-docker) + - [Via Source](#installation-from-source) +- [Setup](#setup) - setup the application for first use +- [Usage](#usage) - connect the application to a website + # Installation ## Requirements -### System - - Any flavour of Linux, OSX or Windows - 1GB memory (minimum) - 5GB storage (minimum) +- [MongoDB](https://www.mongodb.com/) v3.4 or later +- [Redis](https://redis.io/) v3.2 or later +- SSL Certificate + - This application assumes that you will be serving this application in a + production environment, and therefore requires that you serve it behind a + webserver with a valid SSL certificate. This is chosen in order to secure + user's sessions. + +## Installation From Docker + +We currently support packaging the Talk application via Docker, which automates +the dependency install and asset build process. This is the recommended way to +deploy the application when used in production. + +Available as [coralproject/talk](https://hub.docker.com/r/coralproject/talk/) on Docker Hub. + +Images are tagged using the following notation: + +- `x` (where `x` is the major version number): any minor or patch updates will be included in this. If you're ok getting + new features occasionally and all the bug fixes, this is the tag for you. +- `x.y` (where `y` is the minor version number): any patch updates will be + included with this tag. If you like getting fixes and having features change + only when you want, this is the tag for you. **(recommended)** +- `x.y.z` (where `z` is the patch version): this tag never gets updated, and + essentially freezes your version, this should only be used when you are either + extending Talk or are sure of a specific version you want to freeze. + +We provide tags with `*-onbuild` that can be used for easy plugin integration and +acts as a customization endpoint. Instructions are provided in the `PLUGINS.md` +document as to how to use it. + +### Requirements + +There are some runtime requirements for running Talk for Docker: + +- [Docker](https://www.docker.com/) v1.13.0 or later +- [Docker Compose](https://docs.docker.com/compose/) v1.10.0 or later + +_Please be sure to check the versions of these requirements. Incorrect versions +of these may lead to unexpected errors!_ + +### Installing + +An example docker-compose.yml: + +```yaml +version: '2' +services: + talk: + image: coralproject/talk:1.5 + restart: always + ports: + - "5000:5000" + depends_on: + - mongo + - redis + environment: + - TALK_MONGO_URL=mongodb://mongo/talk + - TALK_REDIS_URL=redis://redis + mongo: + image: mongo:3.2 + restart: always + volumes: + - mongo:/data/db + redis: + image: redis:3.2 + restart: always + volumes: + - redis:/data +volumes: + mongo: + external: false + redis: + external: false +``` + +At this stage, you should refer to the `README.md` for configuration variables +that are specific to your installation. Some pre-defined fields have been filled +in the above example which are consistent with Docker Compose naming conventions +for [Docker Links](https://docs.docker.com/compose/networking/#links). + +### Scaling + +If you are interested in splitting apart services, you can simply adjust the +command being executed in the container to optimize for your use case. An +example would be if you wanted to run the API server and the job processor +on different machines. You can achieve this easily with docker compose: + +```yaml +version: '2' +services: + talk-api: + image: coralproject/talk:1.5 + command: cli serve + restart: always + ports: + - "5000:5000" + depends_on: + - mongo + - redis + environment: + - TALK_MONGO_URL=mongodb://mongo/talk + - TALK_REDIS_URL=redis://redis + talk-jobs: + image: coralproject/talk:1.5 + command: cli jobs process + restart: always + ports: + - "5001:5000" + depends_on: + - mongo + - redis + environment: + - TALK_MONGO_URL=mongodb://mongo/talk + - TALK_REDIS_URL=redis://redis + mongo: + image: mongo:3.2 + restart: always + volumes: + - mongo:/data/db + redis: + image: redis:3.2 + restart: always + volumes: + - redis:/data +volumes: + mongo: + external: false + redis: + external: false +``` + +Note that the only difference is in the `command` key. From this, you are able +to discretely control which modules are running in order to have the maximum +flexibility when managing your application. + +### Running + +If you're using docker compose: + +```bash +# Start the services using compose +docker-compose up -d +``` + +If you're using plain docker: + +```bash +docker run -d -P coralproject/talk:latest +``` ## Installation From Source +This provides information on how to setup the application from source. Note that +this is not recommended for production deploys, but will work for development +and testing purposes. + ### Requirements There are some runtime requirements for running Talk from source: -- [Node](https://nodejs.org/) v7 or later -- [MongoDB](https://www.mongodb.com/) v3.4 or later -- [Redis](https://redis.io/) v3.2 or later -- [Yarn](https://yarnpkg.com/) v0.19.1 or later +- [Node](https://nodejs.org/) v7.9 or later +- [Yarn](https://yarnpkg.com/) v0.22.0 or later -_Please be sure to check the versions of these requirements. Insufficient versions of these may lead to unexpected errors!_ +_Please be sure to check the versions of these requirements. Incorrect versions +of these may lead to unexpected errors!_ ### Installing +#### Download + +It is highly recommended that you download a released version as the code +available in `master` may not be stable. You can download the latest release +from the [releases page](https://github.com/coralproject/talk/releases). + +You can also clone the git repository via: + ```bash -# Download the tarball containing the repository -curl -L https://github.com/coralproject/talk/tarball/master -o coralproject-talk.tar.gz +git clone https://github.com/coralproject/talk.git +``` -# Untar that file and change to that directory -tar xpf coralproject-talk.tar.gz -mv coralproject-talk-* coralproject-talk -cd coralproject-talk +#### Building +We now have to install the dependencies and build the static assets. + +```bash # Install package dependancies yarn @@ -39,6 +206,17 @@ yarn yarn build ``` +After you create/modify the `plugins.json` (refer to `PLUGINS.md` for plugin +docs) file, you can re-run the following to install their dependencies: + +```bash +# Reconcile plugins +./bin/cli plugins reconcile + +# Build static files +yarn build +``` + ### Running Refer to the `README.md` file for required configuration variables to add to the @@ -50,45 +228,48 @@ You can start the server after configuring the server using the command: yarn start ``` +This will setup the server to serve everything on a single node.js process and +is designed to be used in production. + You can see other scripts we've made available by consulting the `package.json` file under the `scripts` key including: - `yarn test` run unit tests - `yarn e2e` run end to end tests - `yarn build-watch` watch for changes to client files and build static assets -- `yarn dev-start` watch for changes to server files and reload the server +- `yarn dev-start` watch for changes to server files and reload the server while + also sourcing a `.env` file in your local directory for configuration -## Installation From Docker Hub +# Setup -### Requirements +Once you've installed Talk (either via Docker or source), you still need to +setup the application. If you are unfamiliar with any terminoligy used in the +setup process, refer to the `TERMINOLOGY.md` document. -There are some runtime requirements for running Talk for Docker: +## Via Web -- [MongoDB](https://www.mongodb.com/) v3.2 or later -- [Redis](https://redis.io/) v3.2 or later -- [Docker](https://www.docker.com/) v1.13.0 or later -- [Docker Compose](https://docs.docker.com/compose/) v1.10.0 or later +If you want to perform your setup via the web, you can navigate to your +installation of Talk at the path `/admin/install`. There you will be asked a +series of questions for your installation. -_Please be sure to check the versions of these requirements. Insufficient versions of these may lead to unexpected errors!_ +## Via CLI -### Installing +If you want to perform your setup through the terminal, you can simply run: ```bash -# Create a directory for talk -mkdir coralproject-talk -cd coralproject-talk - -# Download the docker-compose.yml file from the repository -curl -LO https://raw.githubusercontent.com/coralproject/talk/master/docker-compose.yml +cli setup ``` -At this stage, you should refer to the `README.md` file for required -configuration variables to add to the environment key for the `talk` service -listed in the `docker-compose.yml` file. +And follow the instructions to perform initial setup and create your first user +account. -### Running -```bash -# Start the services using compose -docker-compose up -d -``` +# Usage + +After setup is complete, you can then refer to the `/admin/configure` path to +get the embed code that you can copy/paste onto your blog or website in order to +start using Talk. + +_In order for the embed to work correctly, you will need to whitelist the domain +that is allowed to embed your site on the `/admin/configure` page, failure to do +so will result in the comment stream not loading._ diff --git a/PLUGINS.md b/PLUGINS.md index 8bf00229d..068a0886f 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -46,27 +46,73 @@ External plugins can be resolved by running: ./bin/cli plugins reconcile ``` -This will also traverse into local plugin folders and install their -dependancies. _Note that if the plugin is already installed and available in the -node_modules folder, it will not be fetched again unless there is a version -mismatch._ +This achieves two things: + +1. It will traverse into local plugin folders and install their dependencies. + _Note that if the plugin is already installed and available in the node_modules folder, it will not be + fetched again unless there is a version mismatch._ This will result in the + project `package.json` and `yarn.lock` files to be modified, this is normal as + this ensures that repeated deployments (with the same config) will have the + same config, these changes should not be committed to source control. +2. It will seek out dependencies that are listed in the object notation and try + to install them from npm. ## Plugin Dependencies -From your plugins you may import any component of server code relative to the -project root. An example could be: - -```js -const cache = require('services/cache'); -``` - -You may also include additional external depenancies in your local packages by +You may also include additional external dependencies in your local packages by specifying a `package.json` at your plugin root which will result in a `node_modules` folder being generated at the plugin root with your specific dependencies. +## Deployment Solutions + +Plugins can be deployed with a production instance of Talk. + +### Source + +Source deployments can just modify the `plugins.json` file and include any +local plugins into the `plugins/` directory. After including the config, you +need to reconcile the plugins and build the static assets: + +```bash +# get plugin dependancies and remote plugins +./bin/cli plugins reconcile + +# build staic assets (including enabled client side plugins) +yarn build +``` + +Then the application can be started as is. + +### Docker + +If you deploy using Docker, you can extend from the `*-onbuild` image, an +example `Dockerfile` for your project could be: + +```Dockerfile +FROM coralproject/talk:latest-onbuild +``` + +Where the directory for your instance would contain a `plugins.json` file +describing the plugin requirements and a `plugins` directory containing any +other local plugins that should be included. + +Onbuild triggers will execute when the image is building with your custom +configuration and will ensure that the image is ready to use by building all +assets inside the image as well. + ## Server Plugins +### API + +You can access any API available inside the talk directory in a plugin by simply +importing the file relative to the talk project root. An example would be if you +wanted to import the `MetadataService`, you would simply write: + +```javascript +const MetadataService = require('services/metadata'); +``` + ### Specification Each plugin should export a single object with all hooks available on it. diff --git a/bin/cli-plugins b/bin/cli-plugins index 94ce74904..b1dee381b 100755 --- a/bin/cli-plugins +++ b/bin/cli-plugins @@ -67,7 +67,7 @@ function reconcilePackages({quiet = false, upgradeRemote = false}) { console.log(' +missing (m) packages are not found'); console.log(); } - + for (let i in plugins) { let section = itteratePlugins(plugins[i]); @@ -118,7 +118,7 @@ function reconcilePackages({quiet = false, upgradeRemote = false}) { if (!quiet) { console.log(` e ${name}`); } - + if (upgradeRemote) { upgradable.push({name, version}); } @@ -141,12 +141,13 @@ async function reconcileRemotePlugins({skipLocal, dryRun, upgradeRemote}) { if (fetchable.length > 0) { - console.log(`$ yarn add ${fetchable.map(({name, version}) => `${name}@${version}`.cyan)}`); + console.log(`$ yarn add --ignore-scripts ${fetchable.map(({name, version}) => `${name}@${version}`.cyan)}`); if (!dryRun) { let args = [ 'add', + '--ignore-scripts', ...fetchable.map(({name, version}) => `${name}@${version}`) ]; diff --git a/circle.yml b/circle.yml index 013ef28b8..e7427094b 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: node: - version: 7 + version: 7.9 services: - docker - redis diff --git a/client/coral-admin/src/containers/Dashboard/FlagWidget.js b/client/coral-admin/src/containers/Dashboard/FlagWidget.js index 17be2acbd..92de6c4d2 100644 --- a/client/coral-admin/src/containers/Dashboard/FlagWidget.js +++ b/client/coral-admin/src/containers/Dashboard/FlagWidget.js @@ -10,7 +10,7 @@ const FlagWidget = ({assets}) => { return (
{lang.t('streams.article')}
{lang.t('dashboard.flags')}
diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json index 1021978f1..911411523 100644 --- a/client/coral-admin/src/translations.json +++ b/client/coral-admin/src/translations.json @@ -69,6 +69,10 @@ }, "configure": { "closed-stream-settings": "Closed Stream Message", + "open-stream-configuration": "This comment stream is currently open. By closing this comment stream, no new comments may be submitted and all previous comments will still be displayed.", + "close-stream-configuration": "This comment stream is currently closed. By opening this comment stream, new comments may be submitted and displayed", + "close-stream": "Close Stream", + "open-stream": "Open Stream", "stream-settings": "Stream Settings", "moderation-settings": "Moderation Settings", "tech-settings": "Tech Settings", @@ -139,7 +143,8 @@ "no_likes": "There have been no likes in the last 5 minutes. All quiet.", "flags": "Flags", "no_activity": "There haven't been any comments anywhere in the last five minutes.", - "comment_count": "comments" + "comment_count": "comments", + "most_flags": "Articles with the most flags" }, "streams": { "empty_result": "No assets match this search. Maybe try widening your search?", @@ -231,6 +236,10 @@ }, "configure": { "closed-stream-settings": "Mensaje a enviar cuando los comentarios están cerrados en el artículo", + "open-stream-configuration": "Este hilo de comentarios esta abierto. Al cerrarlo, ningún nuevo comentario será publicado y todos los comentarios anteriores serán mostrados.", + "close-stream-configuration": "Este hilo de comentario está en este momento cerrado. Al abrirlo, nuevos comentarios serán publicaods y mostrados.", + "close-stream": "Cerrar Comentarios", + "open-stream": "Abrir Comentarios", "stream-settings": "Configuración de Comentarios", "moderation-settings": "Configuración de Moderación", "tech-settings": "Configuración Técnica", @@ -283,14 +292,15 @@ "cancel": "Cancelar", "yes_ban_user": "Si, Suspendan el usuario" }, - "dashbord": { + "dashboard": { "next-update": "{0} minutos hasta la siguiente actualización.", "auto-update": "Los datos se actualizan automaticamente cada 5 minutos o cuando recargas.", "no_flags": "¡Nadie ha marcado nada en los últimos 5 minutos! ¡Bravo!", "no_likes": "A nadie le ha gustado algún comentario en los últimos 5 minutos. Todo tranquilo.", "flags": "Marcados", "no_activity": "No hubo comentarios en los ultimos 5 minutos", - "comment_count": "comentarios" + "comment_count": "comentarios", + "most_flags": "Articulos con más reportes" }, "streams": { "empty_result": "No se encuentro articulo con esta busqueda. ¿Tal vez puedas extender la busqueda?", diff --git a/client/coral-configure/components/CloseCommentsInfo.js b/client/coral-configure/components/CloseCommentsInfo.js index 627328f9b..fae7bc5e5 100644 --- a/client/coral-configure/components/CloseCommentsInfo.js +++ b/client/coral-configure/components/CloseCommentsInfo.js @@ -1,23 +1,25 @@ import React from 'react'; import {Button} from 'coral-ui'; +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from 'coral-admin/src/translations'; + +const lang = new I18n(translations); + export default ({status, onClick}) => ( status === 'open' ? (- This comment stream is currently open. By closing this comment stream, - no new comments may be submitted and all previous comments will still - be displayed. + {lang.t('configure.open-stream-configuration')}
- +- This comment stream is currently closed. By opening this comment stream, - new comments may be submitted and displayed + {lang.t('configure.close-stream-configuration')}
- +The comment stream will close in {this.getClosedIn()}.
: ''} +The comment stream will close in {this.getClosedIn()}.
: ''}When you ignore a user, all comments they wrote on the site will be hidden from you. You can undo this later from the Profile tab.
+Are you sure you want to ignore { user.name }?
++ {lang.t('commentIsIgnored')} +
+Because you ignored these, you do not see their comments.
+ : null + } +{ emailAddress }
+ : null + } - // Hiding bio until moderation can get figured out - /*{lang.t('userNoComment')}
- - // Hiding user bio pending effective moderation system. - /*