mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Update req.i18n.translate
to contains better filtering security and inject appName
variable by default to all translation keys (#11312)
Also remove the unused translate wrapper function since the content has been imported directly in the `req.i18n.translate` GitOrigin-RevId: ed9cee76783e4d41819845a82f66afaed47e2ebd
This commit is contained in:
parent
9719b0439c
commit
811b224d81
3 changed files with 38 additions and 38 deletions
|
@ -1,34 +0,0 @@
|
|||
const Settings = require('@overleaf/settings')
|
||||
const pug = require('pug-runtime')
|
||||
const logger = require('@overleaf/logger')
|
||||
const SafeHTMLSubstitute = require('./SafeHTMLSubstitution')
|
||||
const I18N_HTML_INJECTIONS = new Set()
|
||||
|
||||
function translate(key, req, vars, components) {
|
||||
vars = vars || {}
|
||||
|
||||
if (Settings.i18n.checkForHTMLInVars) {
|
||||
Object.entries(vars).forEach(([field, value]) => {
|
||||
if (pug.escape(value) !== value) {
|
||||
const violationsKey = key + field
|
||||
// do not flood the logs, log one sample per pod + key + field
|
||||
if (!I18N_HTML_INJECTIONS.has(violationsKey)) {
|
||||
logger.warn(
|
||||
{ key, field, value },
|
||||
'html content in translations context vars'
|
||||
)
|
||||
I18N_HTML_INJECTIONS.add(violationsKey)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
vars.appName = Settings.appName
|
||||
const locale = req.i18n.translate(key, vars)
|
||||
if (components) {
|
||||
return SafeHTMLSubstitute.render(locale, components)
|
||||
} else {
|
||||
return locale
|
||||
}
|
||||
}
|
||||
module.exports = { translate }
|
|
@ -18,7 +18,6 @@ const {
|
|||
const {
|
||||
addOptionalCleanupHandlerAfterDrainingConnections,
|
||||
} = require('./GracefulShutdown')
|
||||
const { translate } = require('../Features/Helpers/Translate')
|
||||
|
||||
const IEEE_BRAND_ID = Settings.ieeeBrandId
|
||||
|
||||
|
@ -227,8 +226,8 @@ module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
|
|||
})
|
||||
|
||||
webRouter.use(function (req, res, next) {
|
||||
res.locals.translate = (key, vars, components) =>
|
||||
translate(key, req, vars, components)
|
||||
res.locals.translate = req.i18n.translate
|
||||
|
||||
// Don't include the query string parameters, otherwise Google
|
||||
// treats ?nocdn=true as the canonical version
|
||||
const parsedOriginalUrl = new URL(req.originalUrl, Settings.siteUrl)
|
||||
|
|
|
@ -4,11 +4,16 @@ const middleware = require('i18next-http-middleware')
|
|||
const path = require('path')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const { URL } = require('url')
|
||||
const pug = require('pug-runtime')
|
||||
const logger = require('@overleaf/logger')
|
||||
const SafeHTMLSubstitution = require('../Features/Helpers/SafeHTMLSubstitution')
|
||||
|
||||
const fallbackLanguageCode = Settings.i18n.defaultLng || 'en'
|
||||
const availableLanguageCodes = []
|
||||
const availableHosts = new Map()
|
||||
const subdomainConfigs = new Map()
|
||||
const I18N_HTML_INJECTIONS = new Set()
|
||||
|
||||
Object.values(Settings.i18n.subdomainLang || {}).forEach(function (spec) {
|
||||
availableLanguageCodes.push(spec.lngCode)
|
||||
// prebuild a host->lngCode mapping for the usage at runtime in the
|
||||
|
@ -50,6 +55,10 @@ i18n
|
|||
// Disable nesting in interpolated values, preventing user input
|
||||
// injection via another nested value
|
||||
skipOnVariables: true,
|
||||
|
||||
defaultVariables: {
|
||||
appName: Settings.appName,
|
||||
},
|
||||
},
|
||||
|
||||
preload: availableLanguageCodes,
|
||||
|
@ -83,7 +92,33 @@ function setLangBasedOnDomainMiddleware(req, res, next) {
|
|||
|
||||
// Decorate req.i18n with translate function alias for backwards
|
||||
// compatibility usage in requests
|
||||
req.i18n.translate = req.i18n.t
|
||||
req.i18n.translate = (key, vars, components) => {
|
||||
vars = vars || {}
|
||||
|
||||
if (Settings.i18n.checkForHTMLInVars) {
|
||||
Object.entries(vars).forEach(([field, value]) => {
|
||||
if (pug.escape(value) !== value) {
|
||||
const violationsKey = key + field
|
||||
// do not flood the logs, log one sample per pod + key + field
|
||||
if (!I18N_HTML_INJECTIONS.has(violationsKey)) {
|
||||
logger.warn(
|
||||
{ key, field, value },
|
||||
'html content in translations context vars'
|
||||
)
|
||||
I18N_HTML_INJECTIONS.add(violationsKey)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const locale = req.i18n.t(key, vars)
|
||||
if (components) {
|
||||
return SafeHTMLSubstitution.render(locale, components)
|
||||
} else {
|
||||
return locale
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue