diff --git a/README.md b/README.md index 1a2da7d96..dd0c5a611 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ opportunity for safer, smarter discussions around your work. Built with <3 by The Coral Project, a part of [Vox Media](https://product.voxmedia.com/). +Preview Talk easily by running Talk via a Heroku App: + +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/coralproject/talk/tree/next) + ## Table of Contents diff --git a/app.json b/app.json new file mode 100644 index 000000000..6ba40488a --- /dev/null +++ b/app.json @@ -0,0 +1,40 @@ +{ + "name": "Talk", + "description": "A better commenting experience from Vox Media.", + "env": { + "REWRITE_ENV": { + "description": "Used to rewrite the environment variables set by Heroku.", + "value": "REDIS_URI:REDIS_URL,MONGODB_URI:MONGO_URI" + }, + "SIGNING_SECRET": { + "description": + "The shared secret to use to sign JSON Web Tokens (JWT) with the selected signing algorithm.", + "generator": "secret" + }, + "CONCURRENCY": { + "description": "The number of worker nodes to spawn to handle traffic.", + "value": "1" + }, + "LOCALE": { + "description": + "Specify the default locale to use for all requests without a locale specified", + "value": "en-US" + }, + "ENABLE_GRAPHIQL": { + "description": "When true, this will enable the GraphiQL routes", + "value": "false" + } + }, + "addons": [ + { + "plan": "mongolab:sandbox", + "as": "MONGO" + }, + { + "plan": "rediscloud:30", + "as": "REDIS" + } + ], + "success_url": "/install", + "website": "https://github.com/coralproject/talk" +} diff --git a/package-lock.json b/package-lock.json index 187615763..cfc280039 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2011,7 +2011,7 @@ }, "@types/accepts": { "version": "1.3.5", - "resolved": "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", "requires": { "@types/node": "*" @@ -2039,9 +2039,9 @@ } }, "@types/bson": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-1.0.11.tgz", - "integrity": "sha512-j+UcCWI+FsbI5/FQP/Kj2CXyplWAz39ktHFkXk84h7dNblKRSoNJs95PZFRd96NQGqsPEPgeclqnznWZr14ZDA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.0.tgz", + "integrity": "sha512-pq/rqJwJWkbS10crsG5bgnrisL8pML79KlMKQMoQwLUjlPAkrUHMvHJ3oGwE7WHR61Lv/nadMwXVAD2b+fpD8Q==", "dev": true, "requires": { "@types/node": "*" @@ -2403,9 +2403,9 @@ } }, "@types/mongodb": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.1.14.tgz", - "integrity": "sha512-Hc9nhu9Z33Gq8SP2CZluNlhwbXBCEGAzLMQPEceZG0wUt/ZTzIGaeo8RXu7FWNXfUd6JHh6KHl0YjQlu6TgncQ==", + "version": "3.1.22", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.1.22.tgz", + "integrity": "sha512-hvNR0txBlJJAy1eZOeIDshW4dnQaC694COou4eHHaMdIcteCfoCQATD7sYNlXxNxfTc1iIbHUi7A8CAhQe08uA==", "dev": true, "requires": { "@types/bson": "*", @@ -6191,9 +6191,9 @@ } }, "bson": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", - "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" }, "buffer": { "version": "4.9.1", @@ -10281,6 +10281,11 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, + "env-rewrite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/env-rewrite/-/env-rewrite-1.0.2.tgz", + "integrity": "sha1-PjRKla8b2qs0pVlHm4vjq9CAQYM=" + }, "env-variable": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.4.tgz", @@ -11360,7 +11365,7 @@ "integrity": "sha1-ETOUSrJHeINHOZVZaIPg05z4hc8=", "dev": true, "requires": { - "intl-pluralrules": "github:projectfluent/IntlPluralRules#module" + "intl-pluralrules": "github:projectfluent/IntlPluralRules#94cb0fa1c23ad943bc5aafef43cea132fa51d68b" } }, "fluent-langneg": { @@ -11670,8 +11675,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "optional": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { "version": "1.2.0", @@ -11692,14 +11696,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "optional": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -11714,20 +11716,17 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "optional": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "optional": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", @@ -11844,8 +11843,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "optional": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -11857,7 +11855,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -11872,7 +11869,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -11880,14 +11876,12 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "optional": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -11906,7 +11900,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "optional": true, "requires": { "minimist": "0.0.8" } @@ -11987,8 +11980,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "optional": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { "version": "4.1.1", @@ -12000,7 +11992,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "optional": true, "requires": { "wrappy": "1" } @@ -12086,8 +12077,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "optional": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "safer-buffer": { "version": "2.1.2", @@ -12123,7 +12113,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -12143,7 +12132,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -12187,14 +12175,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "optional": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "yallist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "optional": true + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" } } }, @@ -16874,7 +16860,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -17738,6 +17724,12 @@ "readable-stream": "^2.0.1" } }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -18049,21 +18041,37 @@ } }, "mongodb": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.1.tgz", - "integrity": "sha512-GU9oWK4pi8PC7NyGiwjFMwZyMqwGWoMEMvM0LZh7UKW/FFAqgmZKjjriD+5MEOCDUJE2dtHX93/K5UtDxO0otg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.1.tgz", + "integrity": "sha512-Vboj2WjyQYGMe8RQ7tmxdvtcdthyEu2f+gDdua7zbKu5JjDPZFDbgjjJEgnfcluog8Po+VguqXoPs9Zh+PAuKw==", "requires": { - "mongodb-core": "3.1.0" + "mongodb-core": "3.2.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "mongodb-core": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.0.tgz", - "integrity": "sha512-qRjG62Fu//CZhkgn0jA/k8jh5MhACIq8cOJUryH6sck87pgt+C222MSD02tsCq5zNo/B6ZFHtNodZ2qpf8E86g==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.1.tgz", + "integrity": "sha512-vvnl5F6QhvFhi28umNx+Ymyb8wVQOhvEjU30JF3TjBBomS2tamJFK4eA0uwOa6FxLi9qCQWejbF66B0rb/UUiw==", "requires": { - "bson": "~1.0.4", + "bson": "^1.1.1", "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "moo": { @@ -19465,7 +19473,7 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true } @@ -24720,10 +24728,13 @@ } }, "saslprep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.0.tgz", - "integrity": "sha512-5lvKUEQ7lAN5/vPl5d3k8FQeDbEamu9kizfATfLLWV5h6Mkh1xcieR1FSsJkcSRUk49lF2tAW8gzXWVwtwZVhw==", - "optional": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", + "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } }, "sax": { "version": "1.2.4", @@ -25287,6 +25298,15 @@ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", "dev": true }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", diff --git a/package.json b/package.json index 6c4853e8f..7d90c70c1 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "dompurify": "^1.0.8", "dotenv": "^6.0.0", "dotenv-expand": "^4.2.0", + "env-rewrite": "^1.0.2", "express": "^4.16.3", "express-static-gzip": "^0.3.2", "farce": "^0.2.6", @@ -92,7 +93,7 @@ "metascraper-description": "^3.11.8", "metascraper-image": "^3.11.8", "metascraper-title": "^3.11.8", - "mongodb": "^3.1.1", + "mongodb": "^3.2.1", "ms": "^2.1.1", "node-fetch": "^2.2.0", "nodemailer": "^4.6.7", @@ -158,7 +159,7 @@ "@types/luxon": "^0.5.3", "@types/marked": "^0.6.0", "@types/mini-css-extract-plugin": "^0.2.0", - "@types/mongodb": "^3.1.14", + "@types/mongodb": "^3.1.22", "@types/ms": "^0.7.30", "@types/node": "^10.5.2", "@types/node-fetch": "^2.1.2", diff --git a/src/core/server/config.ts b/src/core/server/config.ts index 0fca60a6d..019da0cea 100644 --- a/src/core/server/config.ts +++ b/src/core/server/config.ts @@ -59,7 +59,7 @@ const config = convict({ env: "LOCALE", }, enable_graphiql: { - doc: "When true, this will enable the GraphiQL routes", + doc: "When true, this will enable the GraphiQL interface at /graphiql", format: Boolean, default: false, env: "ENABLE_GRAPHIQL", @@ -103,7 +103,8 @@ const config = convict({ sensitive: true, }, signing_secret: { - doc: "", + doc: + "The shared secret to use to sign JSON Web Tokens (JWT) with the selected signing algorithm.", format: "*", default: "keyboard cat", // TODO: (wyattjoh) evaluate best solution env: "SIGNING_SECRET", diff --git a/src/index.ts b/src/index.ts index 54c79212d..5665b6acc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import dotenv from "dotenv"; +import { rewrite } from "env-rewrite"; import sourceMapSupport from "source-map-support"; // Configure the source map support so stack traces will reference the source @@ -7,6 +8,15 @@ sourceMapSupport.install({ environment: "node", }); +// Ensure that we always process the rewrites silently, otherwise it may fail in +// environments like Heroku. +process.env.REWRITE_ENV_SILENT = "TRUE"; + +// Perform rewrites to the runtime environment variables based on the contents +// of the process.env.REWRITE_ENV if it exists. This is done here as it is the +// entrypoint for the entire applications configuration. +rewrite(); + // Apply all the configuration provided in the .env file if it isn't already in // the environment. dotenv.config(); diff --git a/src/types/env-rewrite.d.ts b/src/types/env-rewrite.d.ts new file mode 100644 index 000000000..69ddc89b5 --- /dev/null +++ b/src/types/env-rewrite.d.ts @@ -0,0 +1,3 @@ +declare module "env-rewrite" { + export function rewrite(): void; +}