Merge: Remove locales from js bundle

* commit 'd633e45a064e94029d5e659efa07aeb685794a8b':
  + client: add eslint-import-resolver-webpack
  + client: remove locales from js bundle
  + http: allow access to /__locales/ when not authenticated
  * http: allow access to /__locales/ while installing
This commit is contained in:
Ildar Kamalov 2020-02-03 18:34:40 +03:00
commit 8330f40d51
11 changed files with 183 additions and 251 deletions

View File

@ -7,29 +7,29 @@
"da": "Dansk",
"de": "Deutsch",
"nl": "Dutch",
"no": "Norsk",
"en": "English",
"es": "Español",
"fr": "Français",
"hr": "Hrvatski",
"id": "Indonesian",
"it": "Italiano",
"no": "Norsk",
"pl": "Polski",
"pt-br": "Portuguese (BR)",
"pt-pt": "Portuguese (PT)",
"sk": "Slovenčina",
"sl": "Slovenščina",
"sr-cs": "Srpski",
"sv": "Svenska",
"vi": "Tiếng Việt",
"tr": "Türkçe",
"cs": "Český",
"bg": "Български",
"ru": "Русский",
"fa": "فارسی",
"ja": "日本語",
"zh-tw": "正體中文",
"zh-cn": "简体中文",
"sr-cs": "Srpski",
"hr": "Hrvatski",
"fa": "فارسی",
"ko": "한국어"
}
}

5
client/.eslintrc vendored
View File

@ -17,6 +17,11 @@
"react": {
"pragma": "React",
"version": "16.4"
},
"import/resolver": {
"webpack": {
"config": "webpack.common.js"
}
}
},

143
client/package-lock.json generated vendored
View File

@ -925,6 +925,12 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
"array-find": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz",
"integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=",
"dev": true
},
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@ -4548,6 +4554,79 @@
}
}
},
"eslint-import-resolver-webpack": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.1.tgz",
"integrity": "sha512-O/sUAXk6GWrICiN8JUkkjdt9uZpqZHP+FVnTxtEILL6EZMaPSrnP4lGPSFwcKsv7O211maqq4Nz60+dh236hVg==",
"dev": true,
"requires": {
"array-find": "^1.0.0",
"debug": "^2.6.9",
"enhanced-resolve": "^0.9.1",
"find-root": "^1.1.0",
"has": "^1.0.3",
"interpret": "^1.2.0",
"lodash": "^4.17.15",
"node-libs-browser": "^1.0.0 || ^2.0.0",
"resolve": "^1.13.1",
"semver": "^5.7.1"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"enhanced-resolve": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz",
"integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"memory-fs": "^0.2.0",
"tapable": "^0.1.8"
}
},
"interpret": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
"integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
"dev": true
},
"memory-fs": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz",
"integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=",
"dev": true
},
"resolve": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
"integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
},
"tapable": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz",
"integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=",
"dev": true
}
}
},
"eslint-loader": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz",
@ -5458,7 +5537,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -5479,12 +5559,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -5499,17 +5581,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -5626,7 +5711,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -5638,6 +5724,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -5652,6 +5739,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -5659,12 +5747,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -5683,6 +5773,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -5763,7 +5854,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -5775,6 +5867,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -5860,7 +5953,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -5896,6 +5990,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -5915,6 +6010,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -5958,12 +6054,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@ -6778,6 +6876,29 @@
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-2.2.3.tgz",
"integrity": "sha512-sJZ2n9Vgax0vGer23hJMwyO3FRO7P0dq2DXZPXWE329g3snfJUcw+S24Mp3lqJaxL/0McDu4BD75ds6pzIfhhw=="
},
"i18next-xhr-backend": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-3.2.2.tgz",
"integrity": "sha512-OtRf2Vo3IqAxsttQbpjYnmMML12IMB5e0fc5B7qKJFLScitYaXa1OhMX0n0X/3vrfFlpHL9Ro/H+ps4Ej2j7QQ==",
"requires": {
"@babel/runtime": "^7.5.5"
},
"dependencies": {
"@babel/runtime": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz",
"integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==",
"requires": {
"regenerator-runtime": "^0.13.2"
}
},
"regenerator-runtime": {
"version": "0.13.3",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
}
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",

2
client/package.json vendored
View File

@ -15,6 +15,7 @@
"date-fns": "^1.29.0",
"i18next": "^12.0.0",
"i18next-browser-languagedetector": "^2.2.3",
"i18next-xhr-backend": "^3.2.2",
"lodash": "^4.17.15",
"nanoid": "^1.2.3",
"prop-types": "^15.7.2",
@ -54,6 +55,7 @@
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-react-app": "^2.1.0",
"eslint-import-resolver-webpack": "^0.12.1",
"eslint-loader": "1.9.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-jsx-a11y": "5.1.1",

View File

@ -1,7 +1,9 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Trans, withNamespaces } from 'react-i18next';
import { REPOSITORY, LANGUAGES, PRIVACY_POLICY_LINK } from '../../helpers/constants';
import { REPOSITORY, PRIVACY_POLICY_LINK } from '../../helpers/constants';
import { LANGUAGES } from '../../helpers/twosky';
import i18n from '../../i18n';
import Version from './Version';
@ -68,9 +70,9 @@ class Footer extends Component {
value={i18n.language}
onChange={this.changeLanguage}
>
{LANGUAGES.map(language => (
<option key={language.key} value={language.key}>
{language.name}
{Object.keys(LANGUAGES).map(lang => (
<option key={lang} value={lang}>
{LANGUAGES[lang]}
</option>
))}
</select>

View File

@ -31,117 +31,6 @@ export const REPOSITORY = {
export const PRIVACY_POLICY_LINK = 'https://adguard.com/privacy/home.html';
export const LANGUAGES = [
{
key: 'da',
name: 'Dansk',
},
{
key: 'de',
name: 'Deutsch',
},
{
key: 'nl',
name: 'Dutch',
},
{
key: 'en',
name: 'English',
},
{
key: 'es',
name: 'Español',
},
{
key: 'fr',
name: 'Français',
},
{
key: 'id',
name: 'Indonesian',
},
{
key: 'it',
name: 'Italiano',
},
{
key: 'pl',
name: 'Polski',
},
{
key: 'pt-br',
name: 'Portuguese (BR)',
},
{
key: 'pt-pt',
name: 'Portuguese (PT)',
},
{
key: 'sk',
name: 'Slovenčina',
},
{
key: 'sl',
name: 'Slovenščina',
},
{
key: 'sv',
name: 'Svenska',
},
{
key: 'vi',
name: 'Tiếng Việt',
},
{
key: 'tr',
name: 'Türkçe',
},
{
key: 'cs',
name: 'Český',
},
{
key: 'bg',
name: 'Български',
},
{
key: 'ru',
name: 'Русский',
},
{
key: 'ja',
name: '日本語',
},
{
key: 'zh-tw',
name: '正體中文',
},
{
key: 'zh-cn',
name: '简体中文',
},
{
key: 'no',
name: 'Norsk',
},
{
key: 'sr-cs',
name: 'Srpski',
},
{
key: 'hr',
name: 'Hrvatski',
},
{
key: 'fa',
name: 'فارسی',
},
{
key: 'ko',
name: '한국어',
},
];
export const INSTALL_FIRST_STEP = 1;
export const INSTALL_TOTAL_STEPS = 5;

View File

@ -0,0 +1,6 @@
import twosky from 'MainRoot/.twosky.json';
export const {
languages: LANGUAGES,
base_locale: BASE_LOCALE,
} = twosky[0];

View File

@ -1,132 +1,21 @@
import i18n from 'i18next';
import XHR from 'i18next-xhr-backend';
import { reactI18nextModule } from 'react-i18next';
import { initReactI18n } from 'react-i18next/hooks';
import langDetect from 'i18next-browser-languagedetector';
import { DEFAULT_LANGUAGE } from './helpers/constants';
import { LANGUAGES, BASE_LOCALE } from './helpers/twosky';
import vi from './__locales/vi.json';
import en from './__locales/en.json';
import ru from './__locales/ru.json';
import es from './__locales/es.json';
import fr from './__locales/fr.json';
import ja from './__locales/ja.json';
import sv from './__locales/sv.json';
import ptBR from './__locales/pt-br.json';
import zhTW from './__locales/zh-tw.json';
import bg from './__locales/bg.json';
import zhCN from './__locales/zh-cn.json';
import cs from './__locales/cs.json';
import da from './__locales/da.json';
import de from './__locales/de.json';
import id from './__locales/id.json';
import it from './__locales/it.json';
import ko from './__locales/ko.json';
import no from './__locales/no.json';
import nl from './__locales/nl.json';
import pl from './__locales/pl.json';
import ptPT from './__locales/pt-pt.json';
import sk from './__locales/sk.json';
import sl from './__locales/sl.json';
import tr from './__locales/tr.json';
import srCS from './__locales/sr-cs.json';
import hr from './__locales/hr.json';
import fa from './__locales/fa.json';
const resources = {
en: {
translation: en,
},
vi: {
translation: vi,
},
ru: {
translation: ru,
},
es: {
translation: es,
},
fr: {
translation: fr,
},
ja: {
translation: ja,
},
sv: {
translation: sv,
},
'pt-br': {
translation: ptBR,
},
'zh-tw': {
translation: zhTW,
},
bg: {
translation: bg,
},
'zh-cn': {
translation: zhCN,
},
cs: {
translation: cs,
},
da: {
translation: da,
},
de: {
translation: de,
},
id: {
translation: id,
},
it: {
translation: it,
},
ko: {
translation: ko,
},
no: {
translation: no,
},
nl: {
translation: nl,
},
pl: {
translation: pl,
},
'pt-pt': {
translation: ptPT,
},
sk: {
translation: sk,
},
sl: {
translation: sl,
},
tr: {
translation: tr,
},
'sr-cs': {
translation: srCS,
},
hr: {
translation: hr,
},
fa: {
translation: fa,
},
};
const availableLanguages = Object.keys(resources);
const availableLanguages = Object.keys(LANGUAGES);
i18n
.use(langDetect)
.use(XHR)
.use(initReactI18n)
.use(reactI18nextModule)
.init({
resources,
lowerCaseLng: true,
fallbackLng: DEFAULT_LANGUAGE,
fallbackLng: BASE_LOCALE,
keySeparator: false,
nsSeparator: false,
returnEmptyString: false,
@ -136,9 +25,13 @@ i18n
react: {
wait: true,
},
whitelist: availableLanguages,
backend: {
loadPath: '/__locales/{{lng}}.json',
},
}, () => {
if (!availableLanguages.includes(i18n.language)) {
i18n.changeLanguage(DEFAULT_LANGUAGE);
i18n.changeLanguage(BASE_LOCALE);
}
});

View File

@ -15,6 +15,7 @@ const HTML_PATH = path.resolve(RESOURCES_PATH, 'public/index.html');
const HTML_INSTALL_PATH = path.resolve(RESOURCES_PATH, 'public/install.html');
const HTML_LOGIN_PATH = path.resolve(RESOURCES_PATH, 'public/login.html');
const FAVICON_PATH = path.resolve(RESOURCES_PATH, 'public/favicon.png');
const LOCALES_PATH = path.resolve(RESOURCES_PATH, 'src/__locales/*.json');
const PUBLIC_PATH = path.resolve(__dirname, '../build/static');
@ -32,6 +33,10 @@ const config = {
},
resolve: {
modules: ['node_modules'],
alias: {
MainRoot: path.resolve(__dirname, '../'),
ClientRoot: path.resolve(__dirname, './src'),
},
},
module: {
rules: [
@ -101,7 +106,7 @@ const config = {
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
new CleanWebpackPlugin(['*.*'], {
new CleanWebpackPlugin(['**/*.*'], {
root: PUBLIC_PATH,
verbose: false,
dry: false,
@ -132,6 +137,13 @@ const config = {
new CopyPlugin([
{ from: FAVICON_PATH, to: PUBLIC_PATH },
]),
new CopyPlugin([
{
from: LOCALES_PATH,
to: PUBLIC_PATH,
context: 'src/',
},
]),
],
};

View File

@ -379,7 +379,8 @@ func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.Re
}
} else if r.URL.Path == "/favicon.png" ||
strings.HasPrefix(r.URL.Path, "/login.") {
strings.HasPrefix(r.URL.Path, "/login.") ||
strings.HasPrefix(r.URL.Path, "/__locales/") {
// process as usual
} else if config.auth != nil && config.auth.AuthRequired() {

View File

@ -111,8 +111,9 @@ func preInstallHandler(handler http.Handler) http.Handler {
func postInstall(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if config.firstRun &&
!strings.HasPrefix(r.URL.Path, "/install.") &&
r.URL.Path != "/favicon.png" {
!(strings.HasPrefix(r.URL.Path, "/install.") ||
strings.HasPrefix(r.URL.Path, "/__locales/") ||
r.URL.Path == "/favicon.png") {
http.Redirect(w, r, "/install.html", http.StatusSeeOther) // should not be cacheable
return
}