From 48875294c8852c6e75e2462cc7649dc399d24511 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 5 Sep 2017 13:57:35 -0600 Subject: [PATCH] initial support for changing the uri --- client/coral-framework/constants/config.js | 3 ++ client/coral-framework/services/bootstrap.js | 3 +- config.js | 3 ++ docs/_data/navigation.yml | 2 + docs/_docs/00-01-faq.md | 2 +- docs/_docs/02-01-configuration.md | 10 +++++ docs/_docs/02-05-persistence.md | 45 ++++++++++++++++++++ routes/admin/index.js | 6 ++- routes/embed/index.js | 27 ++++++------ 9 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 client/coral-framework/constants/config.js create mode 100644 docs/_docs/02-05-persistence.md diff --git a/client/coral-framework/constants/config.js b/client/coral-framework/constants/config.js new file mode 100644 index 000000000..81eab50e2 --- /dev/null +++ b/client/coral-framework/constants/config.js @@ -0,0 +1,3 @@ +const configElement = document.querySelector('#data'); + +export const CONFIG = JSON.parse(configElement ? configElement.textContent : '{}'); diff --git a/client/coral-framework/services/bootstrap.js b/client/coral-framework/services/bootstrap.js index ac94d8b29..eed8313d4 100644 --- a/client/coral-framework/services/bootstrap.js +++ b/client/coral-framework/services/bootstrap.js @@ -8,6 +8,7 @@ import thunk from 'redux-thunk'; import {loadTranslations} from './i18n'; import bowser from 'bowser'; import {BASE_PATH} from 'coral-framework/constants/url'; +import {CONFIG} from 'coral-framework/constants/config'; import {createPluginsService} from './plugins'; import {createNotificationService} from './notification'; import {createGraphQLRegistry} from './graphqlRegistry'; @@ -69,7 +70,7 @@ export function createContext({reducers = {}, pluginsConfig = [], graphqlExtensi }); const client = createClient({ uri: `${BASE_PATH}api/v1/graph/ql`, - liveUri: `${protocol}://${location.host}${BASE_PATH}api/v1/live`, + liveUri: CONFIG.LIVE_URI || `${protocol}://${location.host}${BASE_PATH}api/v1/live`, token, }); const plugins = createPluginsService(pluginsConfig); diff --git a/config.js b/config.js index f48159444..d7e247ec3 100644 --- a/config.js +++ b/config.js @@ -135,6 +135,9 @@ const CONFIG = { RECAPTCHA_PUBLIC: process.env.TALK_RECAPTCHA_PUBLIC, RECAPTCHA_SECRET: process.env.TALK_RECAPTCHA_SECRET, + // WEBSOCKET_LIVE_URI is the absolute url to the live endpoint. + WEBSOCKET_LIVE_URI: process.env.TALK_WEBSOCKET_LIVE_URI || null, + //------------------------------------------------------------------------------ // SMTP Server configuration //------------------------------------------------------------------------------ diff --git a/docs/_data/navigation.yml b/docs/_data/navigation.yml index 7226f6003..9fe39d103 100755 --- a/docs/_data/navigation.yml +++ b/docs/_data/navigation.yml @@ -38,6 +38,8 @@ docs: url: /docs/running/plugins/ - title: "Database Migrations" url: /docs/running/migrations/ + - title: "Persistence" + url: /docs/running/persistence/ - title: "Architecture" url: /docs/architecture/ children: diff --git a/docs/_docs/00-01-faq.md b/docs/_docs/00-01-faq.md index 01172f84a..e114fce72 100644 --- a/docs/_docs/00-01-faq.md +++ b/docs/_docs/00-01-faq.md @@ -91,7 +91,7 @@ source process), then: ``` cd docs -docker run --rm --volume=$PWD:/srv/jekyll -p 127.0.0.1:4000:4000 -it jekyll/jekyll:pages jekyll serve +docker run --rm --volume=$PWD:/srv/jekyll -p 127.0.0.1:4000:4000 -it jekyll/jekyll:pages bash -c "bundle install && jekyll serve" ``` You can edit the files in docs with any editor and view the live updates in a diff --git a/docs/_docs/02-01-configuration.md b/docs/_docs/02-01-configuration.md index df790b24b..6ffb9afc0 100644 --- a/docs/_docs/02-01-configuration.md +++ b/docs/_docs/02-01-configuration.md @@ -53,6 +53,7 @@ These are only used during the webpack build. - `TALK_REDIS_URL` (*required*) - the database connection string for the Redis database. #### Advanced +{:.no_toc} - `TALK_REDIS_RECONNECTION_MAX_ATTEMPTS` (_optional_) - the amount of attempts that a redis connection will attempt to reconnect before aborting with an @@ -76,11 +77,19 @@ These are only used during the webpack build. - `TALK_INSTALL_LOCK` (_optional for dynamic setup_) - When `TRUE`, disables the dynamic setup endpoint. (Default `FALSE`) #### Advanced +{:.no_toc} - `TALK_ROOT_URL_MOUNT_PATH` (_optional_) - when set to `TRUE`, the routes will be mounted onto the `` component of the `TALK_ROOT_URL`. You would use this when your upstream proxy cannot strip the prefix from the url. (Default `FALSE`) +- `TALK_WEBSOCKET_LIVE_URI` (_optional_) - 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 requests out of your CDN in order to + serve traffic more efficiently for websockets. **Warning: if used without + managing the auth state manually, auth cannot be persisted, for further + information refer to the [Persistence Documentation]({{ "/docs/running/persistence/" | absolute_url }})** + (Default `${ssl ? 'ws' : 'wss'}://${location.host}${TALK_ROOT_URL_MOUNT_PATH}api/v1/live`) ### Word Filter @@ -105,6 +114,7 @@ variable. Refer to the [Secrets Documentation]({{ "/docs/running/secrets/" | abs on the contents of those variables.** #### Advanced +{:.no_toc} These are advanced settings for fine tuning the auth integration, and is not needed in most situations. diff --git a/docs/_docs/02-05-persistence.md b/docs/_docs/02-05-persistence.md new file mode 100644 index 000000000..fc67a9970 --- /dev/null +++ b/docs/_docs/02-05-persistence.md @@ -0,0 +1,45 @@ +--- +title: User Persistence +permalink: /docs/running/persistence/ +--- + +One of the biggest problems on the internet today is the proliferation of +sophisticated tracking systems and the outcome of invading user's privacy. This +has had quite a big impact on our design of Talk, as we've had to work around +the safeguards that are there to keep your data safe while still allowing our +application to run smoothly on the page it's embedded on. + +--- + +**Problem**: Safari has inconsistent behavior around localStorage when used +within an iFrame. + +**Solution**: We set a cookie instead when Safari is detected to store the auth +state. + +--- + +**Problem**: Safari's default privacy settings block cookies from domains that +do not match the current domain. + +**Solution**: When using Talk's built in auth, we will open a pop-out when +setting the cookie, so that the domain of the setting domain matches the issuer. + +--- + +**Problem**: When using a different domain for websockets, and using the built +in auth solution, cookies are not set on that domain for use with Safari. + +**No Solution Exists**: It is our expectation that for users that must deploy +Talk in environments that must run the websockets out of a separate domain will +use and integrate their own auth solution. During the login process in Talk, +users submit their user credentials to an auth endpoint, and receive a token +back, or for Safari, a cookie. Aggressive defaults in Safari make it not +possible to have one domain set cookies for another domain during this process. +This results in a situation where we have no way to persist the auth credentials +for this specific situation for the time being. + +--- + +It's important to understand that these problems are in fact there to improve +privacy for end users. \ No newline at end of file diff --git a/routes/admin/index.js b/routes/admin/index.js index 30bb69f5e..ab6189e85 100644 --- a/routes/admin/index.js +++ b/routes/admin/index.js @@ -1,7 +1,8 @@ const express = require('express'); const router = express.Router(); const { - RECAPTCHA_PUBLIC + RECAPTCHA_PUBLIC, + WEBSOCKET_LIVE_URI, } = require('../../config'); // Get /email-confirmation expects a signed JWT in the hash @@ -20,7 +21,8 @@ router.get('/password-reset', (req, res) => { router.get('*', (req, res) => { const data = { - TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC + TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC, + LIVE_URI: WEBSOCKET_LIVE_URI, }; res.render('admin', {data}); diff --git a/routes/embed/index.js b/routes/embed/index.js index 0aaa9ff9c..256d03b30 100644 --- a/routes/embed/index.js +++ b/routes/embed/index.js @@ -2,25 +2,24 @@ const express = require('express'); const router = express.Router(); const SettingsService = require('../../services/settings'); const { - RECAPTCHA_PUBLIC + RECAPTCHA_PUBLIC, + WEBSOCKET_LIVE_URI, } = require('../../config'); -router.use('/:embed', (req, res, next) => { +router.use('/:embed', async (req, res, next) => { switch (req.params.embed) { - case 'stream': - return SettingsService.retrieve() - .then(({customCssUrl}) => { - const data = { - TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC - }; + case 'stream': { + const {customCssUrl} = await SettingsService.retrieve(); + const data = { + TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC, + LIVE_URI: WEBSOCKET_LIVE_URI, + }; - return res.render('embed/stream', {customCssUrl, data}); - }); - default: - - // will return a 404. - return next(); + return res.render('embed/stream', {customCssUrl, data}); } + } + + return next(); }); module.exports = router;