From 1f367e666b116f2c7db4afef5292d242bf60c990 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 6 Apr 2017 10:39:36 -0600 Subject: [PATCH 1/7] Added joi plugin validation --- app.js | 3 +++ graph/context.js | 3 +++ graph/hooks.js | 5 +++++ graph/loaders/index.js | 3 +++ graph/mutators/index.js | 3 +++ graph/resolvers/index.js | 3 +++ graph/typeDefs.js | 3 +++ package.json | 1 + routes/index.js | 3 +++ yarn.lock | 27 +++++++++++++++++++++++++++ 10 files changed, 54 insertions(+) diff --git a/app.js b/app.js index e1e864b10..3c9142da5 100644 --- a/app.js +++ b/app.js @@ -10,6 +10,7 @@ const enabled = require('debug').enabled; const RedisStore = require('connect-redis')(session); const redis = require('./services/redis'); const csrf = require('csurf'); +const Joi = require('joi'); const errors = require('./errors'); const graph = require('./graph'); const apollo = require('graphql-server-express'); @@ -80,6 +81,8 @@ const passportDebug = require('debug')('talk:passport'); // Install the passport plugins. plugins.get('server', 'passport').forEach((plugin) => { + Joi.assert(plugin.passport, Joi.func().arity(1), `Plugin '${plugin.name}' had an error loading the passport hook`); + passportDebug(`added plugin '${plugin.plugin.name}'`); // Pass the passport.js instance to the plugin to allow it to inject it's diff --git a/graph/context.js b/graph/context.js index f3ed42ad8..030647bf7 100644 --- a/graph/context.js +++ b/graph/context.js @@ -3,6 +3,7 @@ const mutators = require('./mutators'); const plugins = require('../services/plugins'); const debug = require('debug')('talk:graph:context'); +const Joi = require('joi'); /** * Contains the array of plugins that provide context to the server, these top @@ -10,6 +11,8 @@ const debug = require('debug')('talk:graph:context'); * @type {Array} */ const contextPlugins = plugins.get('server', 'context').map(({plugin, context}) => { + Joi.assert(context, Joi.object().pattern(/\w/, Joi.func().maxArity(1)), `Plugin '${plugin.name}' had an error loading the context`); + debug(`added plugin '${plugin.name}'`); return {context}; }); diff --git a/graph/hooks.js b/graph/hooks.js index 3fe1306cf..4977c796e 100644 --- a/graph/hooks.js +++ b/graph/hooks.js @@ -1,5 +1,6 @@ const {forEachField} = require('graphql-tools'); const debug = require('debug')('talk:graph:schema'); +const Joi = require('joi'); /** * XXX taken from graphql-js: src/execution/execute.js, because that function @@ -46,6 +47,10 @@ const decorateWithHooks = (schema, hooks) => forEachField(schema, (field, typeNa // Combine the pre/post hooks from each plugin into an array we can // execute. .reduce((acc, {plugin, hooks}) => { + Joi.assert(hooks, Joi.object({ + pre: Joi.func(), + post: Joi.func() + }), `Plugin '${plugin.name}' had an error loading the hooks`); // Itterate over the hooks on the fields and look at it with a switch // block to check for misconfigured plugins. diff --git a/graph/loaders/index.js b/graph/loaders/index.js index 26727940f..3c3ccef2b 100644 --- a/graph/loaders/index.js +++ b/graph/loaders/index.js @@ -1,4 +1,5 @@ const _ = require('lodash'); +const Joi = require('joi'); const debug = require('debug')('talk:graph:loaders'); const Actions = require('./actions'); @@ -23,6 +24,8 @@ let loaders = [ // Load the plugin loaders from the manager. ...plugins .get('server', 'loaders').map(({plugin, loaders}) => { + Joi.assert(loaders, Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), `Plugin '${plugin.name}' had an error loading the loaders`); + debug(`added plugin '${plugin.name}'`); return loaders; diff --git a/graph/mutators/index.js b/graph/mutators/index.js index 9975bedde..8fc065514 100644 --- a/graph/mutators/index.js +++ b/graph/mutators/index.js @@ -1,4 +1,5 @@ const _ = require('lodash'); +const Joi = require('joi'); const debug = require('debug')('talk:graph:mutators'); const Comment = require('./comment'); @@ -17,6 +18,8 @@ let mutators = [ // Load the plugin mutators from the manager. ...plugins .get('server', 'mutators').map(({plugin, mutators}) => { + Joi.assert(mutators, Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), `Plugin '${plugin.name}' had an error loading the mutators`); + debug(`added plugin '${plugin.name}'`); return mutators; diff --git a/graph/resolvers/index.js b/graph/resolvers/index.js index 05d633547..743e32062 100644 --- a/graph/resolvers/index.js +++ b/graph/resolvers/index.js @@ -1,4 +1,5 @@ const _ = require('lodash'); +const Joi = require('joi'); const debug = require('debug')('talk:graph:resolvers'); const ActionSummary = require('./action_summary'); @@ -50,6 +51,8 @@ let resolvers = { * as provide new ones. */ resolvers = plugins.get('server', 'resolvers').reduce((acc, {plugin, resolvers}) => { + Joi.assert(resolvers, Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), `Plugin '${plugin.name}' had an error loading the resolvers`); + debug(`added plugin '${plugin.name}'`); return _.merge(acc, resolvers); diff --git a/graph/typeDefs.js b/graph/typeDefs.js index 9b2c8b7aa..64ee07f6d 100644 --- a/graph/typeDefs.js +++ b/graph/typeDefs.js @@ -3,6 +3,7 @@ // this change is done now everything will likely break on the front end. const fs = require('fs'); +const Joi = require('joi'); const path = require('path'); const {mergeStrings} = require('gql-merge'); const debug = require('debug')('talk:graph:typeDefs'); @@ -20,6 +21,8 @@ const typeDefs = mergeStrings([ // Load the plugin definitions from the manager. ...plugins.get('server', 'typeDefs').map(({plugin, typeDefs}) => { + Joi.assert(typeDefs, Joi.string(), `Plugin '${plugin.name}' had an error loading the typeDefs`); + debug(`added plugin '${plugin.name}'`); return typeDefs; diff --git a/package.json b/package.json index 3ea18dfcd..adff68924 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "graphql-tools": "^0.9.0", "helmet": "^3.5.0", "inquirer": "^3.0.6", + "joi": "^10.4.1", "jsonwebtoken": "^7.3.0", "kue": "^0.11.5", "linkify-it": "^2.0.3", diff --git a/routes/index.js b/routes/index.js index 448bd6964..b7c08694f 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,5 +1,6 @@ const express = require('express'); const path = require('path'); +const Joi = require('joi'); const plugins = require('../services/plugins'); const debug = require('debug')('talk:routes'); @@ -27,6 +28,8 @@ if (process.env.NODE_ENV !== 'production') { // Inject server route plugins. plugins.get('server', 'router').forEach((plugin) => { + Joi.assert(plugin.router, Joi.func().arity(1), `Plugin '${plugin.name}' had an error loading the passport router`); + debug(`added plugin '${plugin.plugin.name}'`); // Pass the root router to the plugin to mount it's routes. diff --git a/yarn.lock b/yarn.lock index c9e0c2463..4d1a4ed9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3567,6 +3567,10 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" +hoek@4.x.x: + version "4.1.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.1.1.tgz#9cc573ffba2b7b408fb5e9c2a13796be94cddce9" + hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" @@ -4097,6 +4101,10 @@ isemail@1.x.x: version "1.2.0" resolved "https://registry.yarnpkg.com/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" +isemail@2.x.x: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-2.2.1.tgz#0353d3d9a62951080c262c2aa0a42b8ea8e9e2a6" + isexe@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" @@ -4195,6 +4203,10 @@ istanbul@^1.1.0-alpha.1: which "^1.1.1" wordwrap "^1.0.0" +items@2.x.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/items/-/items-2.1.1.tgz#8bd16d9c83b19529de5aea321acaada78364a198" + iterall@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.0.2.tgz#41a2e96ce9eda5e61c767ee5dc312373bb046e91" @@ -4212,6 +4224,15 @@ jodid25519@^1.0.0: dependencies: jsbn "~0.1.0" +joi@^10.4.1: + version "10.4.1" + resolved "https://registry.yarnpkg.com/joi/-/joi-10.4.1.tgz#a2fca1f0d603d1b843f2c1e086b52461f6be1f36" + dependencies: + hoek "4.x.x" + isemail "2.x.x" + items "2.x.x" + topo "2.x.x" + joi@^6.10.1: version "6.10.1" resolved "https://registry.yarnpkg.com/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" @@ -7658,6 +7679,12 @@ topo@1.x.x: dependencies: hoek "2.x.x" +topo@2.x.x: + version "2.0.2" + resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" + dependencies: + hoek "4.x.x" + touch@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de" From 28ce77a00220036d2c73c30d3c38e21a1ab60151 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 6 Apr 2017 10:56:32 -0600 Subject: [PATCH 2/7] Moved validation to one place --- app.js | 3 --- graph/context.js | 3 --- graph/hooks.js | 5 ----- graph/loaders/index.js | 3 --- graph/mutators/index.js | 3 --- graph/resolvers/index.js | 3 --- graph/typeDefs.js | 3 --- plugins.js | 24 ++++++++++++++++++++++++ routes/index.js | 3 --- 9 files changed, 24 insertions(+), 26 deletions(-) diff --git a/app.js b/app.js index 3c9142da5..e1e864b10 100644 --- a/app.js +++ b/app.js @@ -10,7 +10,6 @@ const enabled = require('debug').enabled; const RedisStore = require('connect-redis')(session); const redis = require('./services/redis'); const csrf = require('csurf'); -const Joi = require('joi'); const errors = require('./errors'); const graph = require('./graph'); const apollo = require('graphql-server-express'); @@ -81,8 +80,6 @@ const passportDebug = require('debug')('talk:passport'); // Install the passport plugins. plugins.get('server', 'passport').forEach((plugin) => { - Joi.assert(plugin.passport, Joi.func().arity(1), `Plugin '${plugin.name}' had an error loading the passport hook`); - passportDebug(`added plugin '${plugin.plugin.name}'`); // Pass the passport.js instance to the plugin to allow it to inject it's diff --git a/graph/context.js b/graph/context.js index 030647bf7..f3ed42ad8 100644 --- a/graph/context.js +++ b/graph/context.js @@ -3,7 +3,6 @@ const mutators = require('./mutators'); const plugins = require('../services/plugins'); const debug = require('debug')('talk:graph:context'); -const Joi = require('joi'); /** * Contains the array of plugins that provide context to the server, these top @@ -11,8 +10,6 @@ const Joi = require('joi'); * @type {Array} */ const contextPlugins = plugins.get('server', 'context').map(({plugin, context}) => { - Joi.assert(context, Joi.object().pattern(/\w/, Joi.func().maxArity(1)), `Plugin '${plugin.name}' had an error loading the context`); - debug(`added plugin '${plugin.name}'`); return {context}; }); diff --git a/graph/hooks.js b/graph/hooks.js index 4977c796e..3fe1306cf 100644 --- a/graph/hooks.js +++ b/graph/hooks.js @@ -1,6 +1,5 @@ const {forEachField} = require('graphql-tools'); const debug = require('debug')('talk:graph:schema'); -const Joi = require('joi'); /** * XXX taken from graphql-js: src/execution/execute.js, because that function @@ -47,10 +46,6 @@ const decorateWithHooks = (schema, hooks) => forEachField(schema, (field, typeNa // Combine the pre/post hooks from each plugin into an array we can // execute. .reduce((acc, {plugin, hooks}) => { - Joi.assert(hooks, Joi.object({ - pre: Joi.func(), - post: Joi.func() - }), `Plugin '${plugin.name}' had an error loading the hooks`); // Itterate over the hooks on the fields and look at it with a switch // block to check for misconfigured plugins. diff --git a/graph/loaders/index.js b/graph/loaders/index.js index 3c3ccef2b..26727940f 100644 --- a/graph/loaders/index.js +++ b/graph/loaders/index.js @@ -1,5 +1,4 @@ const _ = require('lodash'); -const Joi = require('joi'); const debug = require('debug')('talk:graph:loaders'); const Actions = require('./actions'); @@ -24,8 +23,6 @@ let loaders = [ // Load the plugin loaders from the manager. ...plugins .get('server', 'loaders').map(({plugin, loaders}) => { - Joi.assert(loaders, Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), `Plugin '${plugin.name}' had an error loading the loaders`); - debug(`added plugin '${plugin.name}'`); return loaders; diff --git a/graph/mutators/index.js b/graph/mutators/index.js index 8fc065514..9975bedde 100644 --- a/graph/mutators/index.js +++ b/graph/mutators/index.js @@ -1,5 +1,4 @@ const _ = require('lodash'); -const Joi = require('joi'); const debug = require('debug')('talk:graph:mutators'); const Comment = require('./comment'); @@ -18,8 +17,6 @@ let mutators = [ // Load the plugin mutators from the manager. ...plugins .get('server', 'mutators').map(({plugin, mutators}) => { - Joi.assert(mutators, Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), `Plugin '${plugin.name}' had an error loading the mutators`); - debug(`added plugin '${plugin.name}'`); return mutators; diff --git a/graph/resolvers/index.js b/graph/resolvers/index.js index 743e32062..05d633547 100644 --- a/graph/resolvers/index.js +++ b/graph/resolvers/index.js @@ -1,5 +1,4 @@ const _ = require('lodash'); -const Joi = require('joi'); const debug = require('debug')('talk:graph:resolvers'); const ActionSummary = require('./action_summary'); @@ -51,8 +50,6 @@ let resolvers = { * as provide new ones. */ resolvers = plugins.get('server', 'resolvers').reduce((acc, {plugin, resolvers}) => { - Joi.assert(resolvers, Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), `Plugin '${plugin.name}' had an error loading the resolvers`); - debug(`added plugin '${plugin.name}'`); return _.merge(acc, resolvers); diff --git a/graph/typeDefs.js b/graph/typeDefs.js index 64ee07f6d..9b2c8b7aa 100644 --- a/graph/typeDefs.js +++ b/graph/typeDefs.js @@ -3,7 +3,6 @@ // this change is done now everything will likely break on the front end. const fs = require('fs'); -const Joi = require('joi'); const path = require('path'); const {mergeStrings} = require('gql-merge'); const debug = require('debug')('talk:graph:typeDefs'); @@ -21,8 +20,6 @@ const typeDefs = mergeStrings([ // Load the plugin definitions from the manager. ...plugins.get('server', 'typeDefs').map(({plugin, typeDefs}) => { - Joi.assert(typeDefs, Joi.string(), `Plugin '${plugin.name}' had an error loading the typeDefs`); - debug(`added plugin '${plugin.name}'`); return typeDefs; diff --git a/plugins.js b/plugins.js index d7c9f9426..9120c8d71 100644 --- a/plugins.js +++ b/plugins.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const resolve = require('resolve'); const debug = require('debug')('talk:plugins'); +const Joi = require('joi'); // Add support for require rewriting. require('app-module-path').addPath(__dirname); @@ -21,6 +22,20 @@ try { } } +const hookSchemas = { + passport: Joi.func().arity(1), + router: Joi.func().arity(1), + context: Joi.object().pattern(/\w/, Joi.func().maxArity(1)), + hooks: Joi.object({ + pre: Joi.func(), + post: Joi.func() + }), + loaders: Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), + mutators: Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), + resolvers: Joi.object().pattern(/\w/, Joi.object().pattern(/\w/, Joi.func())), + typeDefs: Joi.string() +}; + /** * isInternal checks to see if a given plugin is internal, and returns true * if it is. @@ -122,6 +137,15 @@ class PluginSection { hook(hook) { return this.plugins .filter(({module}) => hook in module) + .filter((plugin) => { + + // Validate the hook. + if (hook in hookSchemas) { + Joi.assert(plugin.module[hook], hookSchemas[hook], `Plugin '${plugin.name}' failed validation for the '${hook}' hook`); + } + + return true; + }) .map((plugin) => ({ plugin, [hook]: plugin.module[hook] diff --git a/routes/index.js b/routes/index.js index b7c08694f..448bd6964 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,6 +1,5 @@ const express = require('express'); const path = require('path'); -const Joi = require('joi'); const plugins = require('../services/plugins'); const debug = require('debug')('talk:routes'); @@ -28,8 +27,6 @@ if (process.env.NODE_ENV !== 'production') { // Inject server route plugins. plugins.get('server', 'router').forEach((plugin) => { - Joi.assert(plugin.router, Joi.func().arity(1), `Plugin '${plugin.name}' had an error loading the passport router`); - debug(`added plugin '${plugin.plugin.name}'`); // Pass the root router to the plugin to mount it's routes. From fb8b33b2eb40c1db25d87402c36197a0556a2762 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 6 Apr 2017 11:43:18 -0600 Subject: [PATCH 3/7] Added plugins.default.json --- .gitignore | 1 + plugins.json => plugins.default.json | 0 plugins.js | 13 +++++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) rename plugins.json => plugins.default.json (100%) diff --git a/.gitignore b/.gitignore index 4ad15747d..6b7b187d9 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ dump.rdb test/e2e/reports coverage/ +plugins.json plugins/* !plugins/coral-plugin-facebook-auth \ No newline at end of file diff --git a/plugins.json b/plugins.default.json similarity index 100% rename from plugins.json rename to plugins.default.json diff --git a/plugins.js b/plugins.js index d7c9f9426..4483f0595 100644 --- a/plugins.js +++ b/plugins.js @@ -12,10 +12,19 @@ let plugins = {}; // file isn't loaded, but continuing. Else, like a parsing error, throw it and // crash the program. try { - plugins = JSON.parse(fs.readFileSync(path.join(__dirname, 'plugins.json'), 'utf8')); + let defaultPlugins = path.join(__dirname, 'plugins.default.json'); + let customPlugins = path.join(__dirname, 'plugins.json'); + + if (fs.existsSync(customPlugins)) { + debug(`Now using ${customPlugins} for plugins`); + plugins = JSON.parse(fs.readFileSync(customPlugins, 'utf8')); + } else { + debug(`Now using ${defaultPlugins} for plugins`); + plugins = JSON.parse(fs.readFileSync(defaultPlugins, 'utf8')); + } } catch (err) { if (err.code === 'ENOENT') { - console.error('plugins.json not found, plugins will not be active'); + console.error('plugins.json and plguins.default.json not found, plugins will not be active'); } else { throw err; } From a9c88f52cec4f796adcb3c135f688ac00385e389 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 6 Apr 2017 11:58:18 -0600 Subject: [PATCH 4/7] Optionally load plugins config from environment --- PLUGINS.md | 15 +++++++++++---- README.md | 1 + plugins.js | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index e5cf8d760..e0e99cccd 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -3,11 +3,18 @@ Plugins for Talk can take various forms, currently we are only supporting server side plugins. -## Plugin Registration: `plugins.json` +## Plugin Registration -All plugins must be registered in the root file `plugins.json`. +The parsing order for the plugin regsitration is as follows: -The format for this file is thus: +- `process.env.TALK_PLUGINS_JSON` +- `plugins.json` +- `plugins.default.json` + +If you need to "disable all plugins", you can simply provide `{}` as the +contents of `process.env.TALK_PLUGINS_JSON` or the `plugins.json`. + +The format for this is thus: ```json { @@ -18,7 +25,7 @@ The format for this file is thus: ``` Where we have a `server` key with an array of plugins that match the folder -name in the `plugins/` folder. For example, the above `plugins.json` would +name in the `plugins/` folder. For example, the above config would require a plugin from `plugins/people`, which must provide a `index.js` file that returns an object that matches the Plugin Specification. diff --git a/README.md b/README.md index b88138425..ef621b59c 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ available in the format: `://` without the path. - `TALK_INSTALL_LOCK` (_optional for dynamic setup_) - Defaults to `FALSE`. When `TRUE`, disables the dynamic setup endpoint. - `TALK_RECAPTCHA_SECRET` (*required for reCAPTCHA support*) - server secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout. - `TALK_RECAPTCHA_PUBLIC` (*required for reCAPTCHA support*) - client secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout. +- `TALK_PLUGINS_JSON` (_optional_) - used to specify the plugin config via the environment Refer to the wiki page on [Configuration Loading](https://github.com/coralproject/talk/wiki/Configuration-Loading) for alternative methods of loading configuration during development. diff --git a/plugins.js b/plugins.js index 4483f0595..f9d93bdce 100644 --- a/plugins.js +++ b/plugins.js @@ -14,8 +14,12 @@ let plugins = {}; try { let defaultPlugins = path.join(__dirname, 'plugins.default.json'); let customPlugins = path.join(__dirname, 'plugins.json'); + let envPluginJSON = process.env.TALK_PLUGINS_JSON; - if (fs.existsSync(customPlugins)) { + if (envPluginJSON && envPluginJSON.length > 0) { + debug('Now using TALK_PLUGINS_JSON environment variable for plugins'); + plugins = JSON.parse(envPluginJSON); + } else if (fs.existsSync(customPlugins)) { debug(`Now using ${customPlugins} for plugins`); plugins = JSON.parse(fs.readFileSync(customPlugins, 'utf8')); } else { From 943d4cf98a1c348f4d78d7eb5aac870dfcd54cd0 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 6 Apr 2017 12:00:00 -0600 Subject: [PATCH 5/7] Spelling --- PLUGINS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLUGINS.md b/PLUGINS.md index e0e99cccd..c34cfa5eb 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -5,7 +5,7 @@ side plugins. ## Plugin Registration -The parsing order for the plugin regsitration is as follows: +The parsing order for the plugin registration is as follows: - `process.env.TALK_PLUGINS_JSON` - `plugins.json` From 4bc7848e24cdfc572531f8cb9d8355ae40ca6bdb Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 6 Apr 2017 12:00:36 -0600 Subject: [PATCH 6/7] comment updates --- PLUGINS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index c34cfa5eb..8bf00229d 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -7,9 +7,9 @@ side plugins. The parsing order for the plugin registration is as follows: -- `process.env.TALK_PLUGINS_JSON` -- `plugins.json` -- `plugins.default.json` +- `TALK_PLUGINS_JSON` environment variable +- `plugins.json` file +- `plugins.default.json` file If you need to "disable all plugins", you can simply provide `{}` as the contents of `process.env.TALK_PLUGINS_JSON` or the `plugins.json`. From 770a4e6fe2a1b96631187e4a17417165df767068 Mon Sep 17 00:00:00 2001 From: Kim Gardner Date: Thu, 6 Apr 2017 14:38:16 -0400 Subject: [PATCH 7/7] Fix typo --- plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins.js b/plugins.js index f9d93bdce..43ac04478 100644 --- a/plugins.js +++ b/plugins.js @@ -28,7 +28,7 @@ try { } } catch (err) { if (err.code === 'ENOENT') { - console.error('plugins.json and plguins.default.json not found, plugins will not be active'); + console.error('plugins.json and plugins.default.json not found, plugins will not be active'); } else { throw err; }