UNPKG

i18next-http-middleware

Version:

i18next-http-middleware is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.

98 lines (88 loc) 3.02 kB
// eslint-disable-next-line no-control-regex const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/ const serializeCookie = (name, val, options) => { const opt = options || {} opt.path = opt.path || '/' const value = encodeURIComponent(val) let str = name + '=' + value if (opt.maxAge > 0) { const maxAge = opt.maxAge - 0 if (isNaN(maxAge)) throw new Error('maxAge should be a Number') str += '; Max-Age=' + Math.floor(maxAge) } if (opt.domain) { if (!fieldContentRegExp.test(opt.domain)) { throw new TypeError('option domain is invalid') } str += '; Domain=' + opt.domain } if (opt.path) { if (!fieldContentRegExp.test(opt.path)) { throw new TypeError('option path is invalid') } str += '; Path=' + opt.path } if (opt.expires) { if (typeof opt.expires.toUTCString !== 'function') { throw new TypeError('option expires is invalid') } str += '; Expires=' + opt.expires.toUTCString() } if (opt.httpOnly) str += '; HttpOnly' if (opt.secure) str += '; Secure' if (opt.sameSite) { const sameSite = typeof opt.sameSite === 'string' ? opt.sameSite.toLowerCase() : opt.sameSite switch (sameSite) { case true: str += '; SameSite=Strict' break case 'lax': str += '; SameSite=Lax' break case 'strict': str += '; SameSite=Strict' break case 'none': str += '; SameSite=None' break default: throw new TypeError('option sameSite is invalid') } } return str } export default { name: 'cookie', lookup (req, res, options) { let found if (options.lookupCookie && typeof req !== 'undefined') { const cookies = options.getCookies(req) if (cookies) found = cookies[options.lookupCookie] } return found }, cacheUserLanguage (req, res, lng, options = {}) { if (options.lookupCookie && req !== 'undefined') { let expirationDate = options.cookieExpirationDate if (!expirationDate) { expirationDate = new Date() expirationDate.setFullYear(expirationDate.getFullYear() + 1) } const cookieOptions = { expires: expirationDate, domain: options.cookieDomain, path: options.cookiePath, httpOnly: false, overwrite: true, sameSite: options.cookieSameSite } if (options.cookieSecure) cookieOptions.secure = options.cookieSecure let existingCookie = options.getHeader(res, 'set-cookie') || options.getHeader(res, 'Set-Cookie') || [] if (typeof existingCookie === 'string') existingCookie = [existingCookie] if (!Array.isArray(existingCookie)) existingCookie = [] existingCookie = existingCookie.filter((c) => c.indexOf(`${options.lookupCookie}=`) !== 0) existingCookie.push(serializeCookie(options.lookupCookie, lng, cookieOptions)) options.setHeader(res, 'Set-Cookie', existingCookie.length === 1 ? existingCookie[0] : existingCookie) } } }