From 90eafb557c57c3937fcf4733f533a656c19396ec Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Tue, 21 Aug 2018 19:52:02 +0200 Subject: [PATCH 1/5] fix language detection in IE11 and Edge (#1810) --- client/coral-framework/services/i18n.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/coral-framework/services/i18n.js b/client/coral-framework/services/i18n.js index 42a0b2030..f7553c05a 100644 --- a/client/coral-framework/services/i18n.js +++ b/client/coral-framework/services/i18n.js @@ -75,10 +75,15 @@ let TIMEAGO_INSTANCE; // detectLanguage will try to get the locale from storage if available, // otherwise will try to get it from the navigator, otherwise, it will fallback // to the default language. -const detectLanguage = () => - first( +const detectLanguage = () => { + var browserLanguages = navigator.languages; + //IE11 and MS-EDGE do not provide navigator.languages + if (!browserLanguages) { + browserLanguages = [navigator.language]; + } + return first( negotiateLanguages( - navigator.languages, + browserLanguages, whitelistedLanguages || supportedLocales, { defaultLocale, @@ -86,6 +91,7 @@ const detectLanguage = () => } ) ); +}; export function setupTranslations() { // locale From 0904453e41cc7c17acbb5949b1f8a06998a1416f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Suriyaa=20=E2=9C=8C=EF=B8=8F=EF=B8=8F?= Date: Wed, 22 Aug 2018 18:04:58 +0200 Subject: [PATCH 2/5] Remove Node Security Platform Badge (#1813) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 404ef994c..3c6a2f54e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Talk · [![CircleCI](https://circleci.com/gh/coralproject/talk.svg?style=svg)](https://circleci.com/gh/coralproject/talk) · [![NSP Status](https://nodesecurity.io/orgs/coralproject/projects/7bd7d26c-47ed-4a5f-8c4a-b919bf1c2946/badge)](https://nodesecurity.io/orgs/coralproject/projects/7bd7d26c-47ed-4a5f-8c4a-b919bf1c2946) · [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md#pull-requests) +# Talk · [![CircleCI](https://circleci.com/gh/coralproject/talk.svg?style=svg)](https://circleci.com/gh/coralproject/talk) · [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md#pull-requests) Online comments are broken. Our open-source commenting platform, Talk, rethinks how moderation, comment display, and conversation function, creating the opportunity for safer, smarter discussions around your work. [Read more about Talk here](https://coralproject.net/talk). From dff3d795698450c27cd799c0e99504b6bb77ec51 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 24 Aug 2018 16:14:18 +0000 Subject: [PATCH 3/5] Subscription Optimizations (#1817) * fix: optimized user extraction during subscription operations * fix: fixed query * feat: added user refeshing batching --- graph/subscriptions/index.js | 99 +++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 12 deletions(-) diff --git a/graph/subscriptions/index.js b/graph/subscriptions/index.js index 5ade76feb..e4ccfef04 100644 --- a/graph/subscriptions/index.js +++ b/graph/subscriptions/index.js @@ -1,11 +1,14 @@ const { SubscriptionManager } = require('graphql-subscriptions'); const { SubscriptionServer } = require('subscriptions-transport-ws'); const debug = require('debug')('talk:graph:subscriptions'); +const DataLoader = require('dataloader'); const { getPubsub } = require('./pubsub'); const schema = require('../schema'); const Context = require('../context'); const plugins = require('../../services/plugins'); +const User = require('../../models/user'); +const { singleJoinBy } = require('../loaders/util'); const { deserializeUser } = require('../../services/subscriptions'); const setupFunctions = require('./setupFunctions'); @@ -59,31 +62,103 @@ const onConnect = async (connectionParams, connection) => { }`; } + try { + // Pull the user off of the upgrade request. + const hydratedRequest = await deserializeUser(connection.upgradeReq); + + // Update the connections upgrade request, as we'll use that to verify that + // the user is allowed each operation. + connection.upgradeReq = hydratedRequest; + } catch (err) { + console.error(err); + } + // Call all the hooks. await Promise.all( hooks.onConnect.map(hook => hook(connectionParams, connection)) ); }; -const onOperation = (parsedMessage, baseParams, connection) => { - // Cache the upgrade request. - let upgradeReq = connection.upgradeReq; +/** + * batchedUserRefresher will get users based on ID for websocket user refresh + * operations to reduce load related to user refreshing. + */ +const batchedUserRefresher = new DataLoader( + userIDs => { + console.log(`OPERATION: refreshing ${userIDs.length} users.`); + return User.find({ id: { $in: userIDs } }).then( + singleJoinBy(userIDs, 'id') + ); + }, + { + // Disable the cache, as this dataloader is long lived, and the point of + // using this dataloader is to batch refetch operations rather than caching + // then as we normally would. + cache: false, + } +); - // Attach the context per request. - baseParams.context = async () => { - let req; +const contextGenerator = req => { + // Pull the user(?) off the request. + const { user, jwt } = req; - try { - req = await deserializeUser(upgradeReq); - debug(`user ${req.user ? 'was' : 'was not'} on websocket request`); - } catch (e) { - console.error(e); + if (!user || !jwt) { + // There is no valid user on the request, let it continue as is then. + return async () => new Context(req); + } - return new Context({}); + // Provide a flag that can be used to short circuit invalid requests. + let expiredLogin = false; + + async function refreshUser() { + // Check to see if this request has been short circuited. + if (expiredLogin) { + // It has, let's exit here. + return null; } + // Validate that the JWT for this user has not expired. + const { exp = false } = jwt; + if (exp && exp < Date.now() / 1000) { + // Mark that this token has expired, don't bother performing this syscall + // again to check the time. + expiredLogin = true; + return null; + } + + try { + // Let's refresh the user from the database, as they may have changed. + const refreshedUser = await batchedUserRefresher.load(user.id); + if (!refreshedUser) { + return null; + } + + return refreshedUser; + } catch (err) { + return null; + } + } + + // Return the context builder function that'll use the passed context to + // generate future contexts. + return async () => { + // Refresh the user (potentially null). + const refreshedUser = await refreshUser(); + + // Attach the refreshedUser to the request. + req.user = refreshedUser; + + // Return the new context. return new Context(req); }; +}; + +const onOperation = async (parsedMessage, baseParams, connection) => { + // Pull the upgrade request off of the connection. + const upgradeReq = connection.upgradeReq; + + // Attach the context handler to the request. + baseParams.context = contextGenerator(upgradeReq); return baseParams; }; From 620273769f6c0bf7dc1d1b291467b9e0d6756768 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 24 Aug 2018 12:22:23 -0600 Subject: [PATCH 4/5] Update package.json (#1818) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ae55b0e5..f35544cf0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "talk", - "version": "4.6.1", + "version": "4.6.2", "description": "A better commenting experience from Mozilla, The New York Times, and the Washington Post. https://coralproject.net", "main": "app.js", "private": true, From 5427f295f6d43d605281e64fb9829dc412046ab0 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Tue, 28 Aug 2018 15:48:50 +0200 Subject: [PATCH 5/5] add german translation for sort-upvoted --- plugins/talk-plugin-sort-most-upvoted/client/translations.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/talk-plugin-sort-most-upvoted/client/translations.yml b/plugins/talk-plugin-sort-most-upvoted/client/translations.yml index 6a673a767..95f7d3689 100644 --- a/plugins/talk-plugin-sort-most-upvoted/client/translations.yml +++ b/plugins/talk-plugin-sort-most-upvoted/client/translations.yml @@ -1,6 +1,9 @@ en: talk-plugin-sort-most-upvoted: label: Most upvoted first +de: + talk-plugin-sort-most-upvoted: + label: Am besten bewertet es: talk-plugin-sort-oldest: label: Más votadas primero