mirror of
https://github.com/wassname/talk.git
synced 2026-07-17 11:33:39 +08:00
Merge branch 'master' into patch-2
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Talk · [](https://circleci.com/gh/coralproject/talk) · [](https://nodesecurity.io/orgs/coralproject/projects/7bd7d26c-47ed-4a5f-8c4a-b919bf1c2946) · [](CONTRIBUTING.md#pull-requests)
|
||||
# Talk · [](https://circleci.com/gh/coralproject/talk) · [](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).
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user