diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2021-10-01 13:24:33 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2021-10-01 13:24:33 +0200 |
| commit | 2cc8932c76a2546574f138bf95b88a9978fb0eb8 (patch) | |
| tree | a6b86a49a635184244827854be9b783209629083 | |
| parent | 26ca38a9520b39ac45102dd7473a965af6220bd6 (diff) | |
| parent | c32d5d1a3a437318e11c5b5f448a02b042bde69a (diff) | |
| download | mullvadvpn-2cc8932c76a2546574f138bf95b88a9978fb0eb8.tar.xz mullvadvpn-2cc8932c76a2546574f138bf95b88a9978fb0eb8.zip | |
Merge branch 'update-to-electron-15'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | README.md | 4 | ||||
| -rwxr-xr-x | dist-assets/linux/mullvad-gui-launcher.sh | 4 | ||||
| -rw-r--r-- | gui/package-lock.json | 331 | ||||
| -rw-r--r-- | gui/package.json | 8 | ||||
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 2 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 23 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 29 | ||||
| -rw-r--r-- | gui/src/renderer/components/SvgMap.tsx | 4 | ||||
| -rw-r--r-- | gui/src/renderer/components/Switch.tsx | 15 | ||||
| -rw-r--r-- | gui/src/renderer/components/TransitionContainer.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/WireguardKeys.tsx | 2 |
12 files changed, 153 insertions, 272 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b1c29f52..57634b5690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Line wrap the file at 100 chars. Th - Update Electron from 11.2.3 to 11.4.9. - Move OpenVPN and WireGuard settings in the advanced settings view into separate settings views. - Return to main view in desktop app after being hidden/closed for two minutes. +- Update Electron from 11.4.9 to 15.0.0. #### Linux - Always send DNS requests inside the tunnel for excluded processes when using public custom DNS. @@ -265,7 +265,7 @@ storePassword = keystore-password 1. *This can be skipped for Android builds*. - Get the latest version 14 release of Node.js and the latest version of npm. After installing + Get the latest version 16 release of Node.js and the latest version of npm. After installing Node.js the latest version of npm can be installed by running: ``` npm install -g npm @@ -276,7 +276,7 @@ storePassword = keystore-password ``` #### Linux - Just download and unpack the `node-v14.xxxx.tar.xz` tarball and add its `bin` directory to your + Just download and unpack the `node-v16.xxxx.tar.xz` tarball and add its `bin` directory to your `PATH`. #### Windows diff --git a/dist-assets/linux/mullvad-gui-launcher.sh b/dist-assets/linux/mullvad-gui-launcher.sh index 67aae93a7b..32be5868ca 100755 --- a/dist-assets/linux/mullvad-gui-launcher.sh +++ b/dist-assets/linux/mullvad-gui-launcher.sh @@ -4,10 +4,6 @@ set -eu UNPRIVILEGED_USERNS_PATH="/proc/sys/kernel/unprivileged_userns_clone" if [ -e $UNPRIVILEGED_USERNS_PATH ] && grep -q 0 $UNPRIVILEGED_USERNS_PATH; then SANDBOX_FLAG="--no-sandbox" -elif command -v lsb_release > /dev/null && \ - [[ "$(lsb_release -i | awk -F : '{print $2}' | xargs echo)" == "Ubuntu" ]] && \ - [[ "$(lsb_release -r | awk -F : '{print $2}' | xargs echo)" == "21.10" ]]; then - SANDBOX_FLAG="--no-sandbox" else SANDBOX_FLAG="" fi diff --git a/gui/package-lock.json b/gui/package-lock.json index 911e66cbbd..01bdfccf26 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -24,8 +24,7 @@ "react-simple-maps": "^2.1.2", "redux": "^4.0.5", "sprintf-js": "^1.1.2", - "styled-components": "^5.1.1", - "uuid": "^3.0.1" + "styled-components": "^5.1.1" }, "devDependencies": { "@types/chai": "^4.1.7", @@ -36,7 +35,7 @@ "@types/google-protobuf": "^3.7.2", "@types/history": "^4.7.8", "@types/mocha": "^5.2.6", - "@types/node": "^10.12.3", + "@types/node": "^16.10.1", "@types/node-gettext": "^3.0.1", "@types/rbush": "^2.0.2", "@types/react": "^16.9.56", @@ -48,7 +47,6 @@ "@types/sprintf-js": "^1.1.2", "@types/styled-components": "^5.1.4", "@types/topojson-specification": "^1.0.1", - "@types/uuid": "^3.4.4", "@typescript-eslint/eslint-plugin": "^4.31.0", "@typescript-eslint/parser": "^4.31.0", "browserify": "^17.0.0", @@ -56,7 +54,7 @@ "chai-as-promised": "^7.1.1", "chai-spies": "^1.0.0", "cross-env": "^5.1.3", - "electron": "^11.4.10", + "electron": "^15.0.0", "electron-builder": "^22.11.7", "electron-devtools-installer": "^3.2.0", "electron-mocha": "^9.3.3", @@ -281,14 +279,13 @@ } }, "node_modules/@electron/get": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.3.tgz", - "integrity": "sha512-NFwSnVZQK7dhOYF1NQCt+HGqgL1aNdj0LUSx75uCqnZJqyiWCVdAMFV4b4/kC8HjUJAnsvdSEmjEt4G2qNQ9+Q==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz", + "integrity": "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ==", "dev": true, "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", - "filenamify": "^4.1.0", "fs-extra": "^8.1.0", "got": "^9.6.0", "progress": "^2.0.3", @@ -304,15 +301,20 @@ } }, "node_modules/@electron/get/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/@electron/get/node_modules/fs-extra": { @@ -334,7 +336,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, - "dependencies": { + "optionalDependencies": { "graceful-fs": "^4.1.6" } }, @@ -529,11 +531,6 @@ "node": "^8.13.0 || >=10.10.0" } }, - "node_modules/@grpc/grpc-js/node_modules/@types/node": { - "version": "16.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz", - "integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA==" - }, "node_modules/@gulp-sourcemaps/identity-map": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", @@ -988,10 +985,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "10.12.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.3.tgz", - "integrity": "sha512-sfGmOtSMSbQ/AKG8V9xD1gmjquC9awIIZ/Kj309pHb2n3bcRAcGMQv5nJ6gCXZVsneGE4+ve8DXKRCsrg3TFzg==", - "dev": true + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz", + "integrity": "sha512-4/Z9DMPKFexZj/Gn3LylFgamNKHm4K3QDi0gz9B26Uk0c8izYf97B5fxfpspMNkWlFupblKM/nV8+NA9Ffvr+w==" }, "node_modules/@types/node-gettext": { "version": "3.0.1", @@ -1122,15 +1118,6 @@ "@types/geojson": "*" } }, - "node_modules/@types/uuid": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz", - "integrity": "sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/verror": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.4.tgz", @@ -2316,9 +2303,9 @@ "dev": true }, "node_modules/boolean": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.2.tgz", - "integrity": "sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz", + "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==", "dev": true, "optional": true }, @@ -3458,9 +3445,9 @@ } }, "node_modules/config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, "optional": true, "dependencies": { @@ -3540,12 +3527,16 @@ } }, "node_modules/core-js": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", - "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.18.1.tgz", + "integrity": "sha512-vJlUi/7YdlCZeL6fXvWNaLUPh/id12WXj3MbkMw5uOyF0PfWPBNOCNbs53YqgrvtujLNlt9JQpruyIKkUZ+PKA==", "dev": true, "hasInstallScript": true, - "optional": true + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, "node_modules/core-util-is": { "version": "1.0.2", @@ -4094,9 +4085,9 @@ } }, "node_modules/detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true, "optional": true }, @@ -4409,14 +4400,14 @@ } }, "node_modules/electron": { - "version": "11.4.10", - "resolved": "https://registry.npmjs.org/electron/-/electron-11.4.10.tgz", - "integrity": "sha512-aQTRgRdHwCW68gxz9qvGCfOUvR4NBbdecLB/mEWX8fMncDFvPMmm+dq2D6zSWWVEKywmsj3+wMMVn3UV2Cl2CQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-15.0.0.tgz", + "integrity": "sha512-LlBjN5nCJoC7EDrgfDQwEGSGSAo/o08nSP5uJxN2m+ZtNA69SxpnWv4yPgo1K08X/iQPoGhoZu6C8LYYlk1Dtg==", "dev": true, "hasInstallScript": true, "dependencies": { - "@electron/get": "^1.0.1", - "@types/node": "^12.0.12", + "@electron/get": "^1.13.0", + "@types/node": "^14.6.2", "extract-zip": "^1.0.3" }, "bin": { @@ -4945,9 +4936,9 @@ } }, "node_modules/electron/node_modules/@types/node": { - "version": "12.19.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.15.tgz", - "integrity": "sha512-lowukE3GUI+VSYSu6VcBXl14d61Rp5hA1D+61r16qnwC0lYNSqdxcvRh0pswejorHfS+HgwBasM8jLXz0/aOsw==", + "version": "14.17.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.19.tgz", + "integrity": "sha512-jjYI6NkyfXykucU6ELEoT64QyKOdvaA6enOqKtP4xUsGY0X0ZUZz29fUmrTRo+7v7c6TgDu82q3GHHaCEkqZwA==", "dev": true }, "node_modules/elliptic": { @@ -5043,9 +5034,9 @@ } }, "node_modules/env-paths": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", - "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, "engines": { "node": ">=6" @@ -6085,29 +6076,6 @@ "minimatch": "^3.0.4" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.2.0.tgz", - "integrity": "sha512-pkgE+4p7N1n7QieOopmn3TqJaefjdWXwEkj2XLZJLKfOgcQKkn11ahvGNgTD8mLggexLiDFQxeTs14xVU22XPA==", - "dev": true, - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -6589,9 +6557,9 @@ } }, "node_modules/global-agent": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", - "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz", + "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==", "dev": true, "optional": true, "dependencies": { @@ -6693,9 +6661,9 @@ } }, "node_modules/globalthis": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz", - "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", "dev": true, "optional": true, "dependencies": { @@ -6703,6 +6671,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/globby": { @@ -8622,6 +8593,9 @@ "optional": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/md5.js": { @@ -11266,6 +11240,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/serialize-error/node_modules/type-fest": { @@ -11276,6 +11253,9 @@ "optional": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/serialize-javascript": { @@ -12013,18 +11993,6 @@ "node": ">=0.10.0" } }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/styled-components": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.1.1.tgz", @@ -12064,15 +12032,20 @@ } }, "node_modules/sumchecker/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/sumchecker/node_modules/ms": { @@ -12472,18 +12445,6 @@ "topoquantize": "bin/topoquantize" } }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -13164,14 +13125,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-compile-cache": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", @@ -13954,14 +13907,13 @@ } }, "@electron/get": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.3.tgz", - "integrity": "sha512-NFwSnVZQK7dhOYF1NQCt+HGqgL1aNdj0LUSx75uCqnZJqyiWCVdAMFV4b4/kC8HjUJAnsvdSEmjEt4G2qNQ9+Q==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz", + "integrity": "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ==", "dev": true, "requires": { "debug": "^4.1.1", "env-paths": "^2.2.0", - "filenamify": "^4.1.0", "fs-extra": "^8.1.0", "global-agent": "^2.0.2", "global-tunnel-ng": "^2.7.1", @@ -13972,9 +13924,9 @@ }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -14146,13 +14098,6 @@ "integrity": "sha512-CKQVuwuSPh40tgOkR7c0ZisxYRiN05PcKPW72mQL5y++qd7CwBRoaJZvU5xfXnCJDFBmS3qZGQ71Frx6Ofo2XA==", "requires": { "@types/node": ">=12.12.47" - }, - "dependencies": { - "@types/node": { - "version": "16.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz", - "integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA==" - } } }, "@gulp-sourcemaps/identity-map": { @@ -14533,10 +14478,9 @@ "dev": true }, "@types/node": { - "version": "10.12.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.3.tgz", - "integrity": "sha512-sfGmOtSMSbQ/AKG8V9xD1gmjquC9awIIZ/Kj309pHb2n3bcRAcGMQv5nJ6gCXZVsneGE4+ve8DXKRCsrg3TFzg==", - "dev": true + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz", + "integrity": "sha512-4/Z9DMPKFexZj/Gn3LylFgamNKHm4K3QDi0gz9B26Uk0c8izYf97B5fxfpspMNkWlFupblKM/nV8+NA9Ffvr+w==" }, "@types/node-gettext": { "version": "3.0.1", @@ -14667,15 +14611,6 @@ "@types/geojson": "*" } }, - "@types/uuid": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.4.tgz", - "integrity": "sha512-tPIgT0GUmdJQNSHxp0X2jnpQfBSTfGxUMc/2CXBU2mnyTFVYVa2ojpoQ74w0U2yn2vw3jnC640+77lkFFpdVDw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/verror": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.4.tgz", @@ -15609,9 +15544,9 @@ "dev": true }, "boolean": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.2.tgz", - "integrity": "sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz", + "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==", "dev": true, "optional": true }, @@ -16564,9 +16499,9 @@ } }, "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, "optional": true, "requires": { @@ -16637,9 +16572,9 @@ } }, "core-js": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", - "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==", + "version": "3.18.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.18.1.tgz", + "integrity": "sha512-vJlUi/7YdlCZeL6fXvWNaLUPh/id12WXj3MbkMw5uOyF0PfWPBNOCNbs53YqgrvtujLNlt9JQpruyIKkUZ+PKA==", "dev": true, "optional": true }, @@ -17120,9 +17055,9 @@ "dev": true }, "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true, "optional": true }, @@ -17375,20 +17310,20 @@ } }, "electron": { - "version": "11.4.10", - "resolved": "https://registry.npmjs.org/electron/-/electron-11.4.10.tgz", - "integrity": "sha512-aQTRgRdHwCW68gxz9qvGCfOUvR4NBbdecLB/mEWX8fMncDFvPMmm+dq2D6zSWWVEKywmsj3+wMMVn3UV2Cl2CQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-15.0.0.tgz", + "integrity": "sha512-LlBjN5nCJoC7EDrgfDQwEGSGSAo/o08nSP5uJxN2m+ZtNA69SxpnWv4yPgo1K08X/iQPoGhoZu6C8LYYlk1Dtg==", "dev": true, "requires": { - "@electron/get": "^1.0.1", - "@types/node": "^12.0.12", + "@electron/get": "^1.13.0", + "@types/node": "^14.6.2", "extract-zip": "^1.0.3" }, "dependencies": { "@types/node": { - "version": "12.19.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.15.tgz", - "integrity": "sha512-lowukE3GUI+VSYSu6VcBXl14d61Rp5hA1D+61r16qnwC0lYNSqdxcvRh0pswejorHfS+HgwBasM8jLXz0/aOsw==", + "version": "14.17.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.19.tgz", + "integrity": "sha512-jjYI6NkyfXykucU6ELEoT64QyKOdvaA6enOqKtP4xUsGY0X0ZUZz29fUmrTRo+7v7c6TgDu82q3GHHaCEkqZwA==", "dev": true } } @@ -17890,9 +17825,9 @@ } }, "env-paths": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", - "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, "error-ex": { @@ -18728,23 +18663,6 @@ "minimatch": "^3.0.4" } }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true - }, - "filenamify": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.2.0.tgz", - "integrity": "sha512-pkgE+4p7N1n7QieOopmn3TqJaefjdWXwEkj2XLZJLKfOgcQKkn11ahvGNgTD8mLggexLiDFQxeTs14xVU22XPA==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - } - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -19132,9 +19050,9 @@ } }, "global-agent": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", - "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz", + "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==", "dev": true, "optional": true, "requires": { @@ -19211,9 +19129,9 @@ } }, "globalthis": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz", - "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", "dev": true, "optional": true, "requires": { @@ -23497,15 +23415,6 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "devOptional": true }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, "styled-components": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.1.1.tgz", @@ -23542,9 +23451,9 @@ }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -23871,15 +23780,6 @@ "commander": "2" } }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, "truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -24398,11 +24298,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, "v8-compile-cache": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", diff --git a/gui/package.json b/gui/package.json index afb3b8ae95..2eb1b8f35b 100644 --- a/gui/package.json +++ b/gui/package.json @@ -26,8 +26,7 @@ "react-simple-maps": "^2.1.2", "redux": "^4.0.5", "sprintf-js": "^1.1.2", - "styled-components": "^5.1.1", - "uuid": "^3.0.1" + "styled-components": "^5.1.1" }, "optionalDependencies": { "grpc-tools": "^1.10.0", @@ -42,7 +41,7 @@ "@types/google-protobuf": "^3.7.2", "@types/history": "^4.7.8", "@types/mocha": "^5.2.6", - "@types/node": "^10.12.3", + "@types/node": "^16.10.1", "@types/node-gettext": "^3.0.1", "@types/rbush": "^2.0.2", "@types/react": "^16.9.56", @@ -54,7 +53,6 @@ "@types/sprintf-js": "^1.1.2", "@types/styled-components": "^5.1.4", "@types/topojson-specification": "^1.0.1", - "@types/uuid": "^3.4.4", "@typescript-eslint/eslint-plugin": "^4.31.0", "@typescript-eslint/parser": "^4.31.0", "browserify": "^17.0.0", @@ -62,7 +60,7 @@ "chai-as-promised": "^7.1.1", "chai-spies": "^1.0.0", "cross-env": "^5.1.3", - "electron": "^11.4.10", + "electron": "^15.0.0", "electron-builder": "^22.11.7", "electron-devtools-installer": "^3.2.0", "electron-mocha": "^9.3.3", diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index 89360fbc15..9df81f119e 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -125,7 +125,7 @@ export class DaemonRpc { private connectionObservers: ConnectionObserver[] = []; private nextSubscriptionId = 0; private subscriptions: Map<number, grpc.ClientReadableStream<grpcTypes.DaemonEvent>> = new Map(); - private reconnectionTimeout?: number; + private reconnectionTimeout?: NodeJS.Timer; constructor(connectionParams: string) { this.client = (new ManagementServiceClient( diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index 3421e72894..b211d9fe12 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -1,4 +1,5 @@ import { exec, execFile } from 'child_process'; +import { randomUUID } from 'crypto'; import { app, BrowserWindow, @@ -15,7 +16,6 @@ import os from 'os'; import * as path from 'path'; import { sprintf } from 'sprintf-js'; import util from 'util'; -import * as uuid from 'uuid'; import config from '../config.json'; import { closeToExpiry, hasExpired } from '../shared/account-expiry'; import { IApplication } from '../shared/application-types'; @@ -95,6 +95,8 @@ const UPDATE_NOTIFICATION_DISABLED = process.env.MULLVAD_DISABLE_UPDATE_NOTIFICA const SANDBOX_DISABLED = app.commandLine.hasSwitch('no-sandbox'); +const ALLOWED_PERMISSIONS = ['clipboard-sanitized-write']; + enum AppQuitStage { unready, initiated, @@ -438,8 +440,8 @@ class ApplicationMain { this.blockPermissionRequests(); // Blocks any http(s) and file requests that aren't supposed to happen. this.blockRequests(); - // Blocks navigation since it's not needed. - this.blockNavigation(); + // Blocks navigation and window.open since it's not needed. + this.blockNavigationAndWindowOpen(); this.updateCurrentLocale(); @@ -1289,7 +1291,7 @@ class ApplicationMain { }); IpcMainEventChannel.problemReport.handleCollectLogs((toRedact) => { - const id = uuid.v4(); + const id = randomUUID(); const reportPath = this.getProblemReportPath(id); const executable = resolveBin('mullvad-problem-report'); const args = ['collect', '--output', reportPath]; @@ -1597,7 +1599,9 @@ class ApplicationMain { session.defaultSession.setPermissionRequestHandler((_webContents, _permission, callback) => { callback(false); }); - session.defaultSession.setPermissionCheckHandler(() => false); + session.defaultSession.setPermissionCheckHandler((_webContents, permission) => + ALLOWED_PERMISSIONS.includes(permission), + ); } // Since the app frontend never performs any network requests, all requests originating from the @@ -1648,11 +1652,11 @@ class ApplicationMain { ); } - private blockNavigation() { + // Blocks navigation and window.open since it's not needed. + private blockNavigationAndWindowOpen() { app.on('web-contents-created', (_event, contents) => { - contents.on('will-navigate', (event) => { - event.preventDefault(); - }); + contents.on('will-navigate', (event) => event.preventDefault()); + contents.setWindowOpenHandler(() => ({ action: 'deny' })); }); } @@ -1721,7 +1725,6 @@ class ApplicationMain { nodeIntegration: false, nodeIntegrationInWorker: false, nodeIntegrationInSubFrames: false, - enableRemoteModule: false, sandbox: !SANDBOX_DISABLED, contextIsolation: true, spellcheck: false, diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index c8950f88c8..c37f52bd4f 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -47,34 +47,7 @@ import { LogLevel } from '../shared/logging-types'; import IpcOutput from './lib/logging'; import { RoutePath } from './lib/routes'; -// This function wraps all IPC calls to catch errors and then rethrow them without the -// "Uncaught Error:" prefix that's added by Electron. -// This is a temporary workaround which won't be required after this Electron PR has been merged and -// released: https://github.com/electron/electron/pull/28346 -function handleReponse(ipc: typeof window.ipc): typeof window.ipc { - const wrappedIpc: Record<string, Record<string, unknown>> = {}; - - Object.entries(ipc).forEach(([groupName, group]) => { - wrappedIpc[groupName] = {} as typeof group; - - Object.entries(group).forEach(([fnName, fn]) => { - wrappedIpc[groupName][fnName] = (...args: Parameters<typeof fn>) => { - const response = fn(...args); - if (response instanceof Promise) { - return response.catch((error: Error) => { - throw new Error(error.message?.replace(/^Uncaught Error: /, '')); - }); - } else { - return response; - } - }; - }); - }); - - return wrappedIpc as typeof window.ipc; -} - -const IpcRendererEventChannel = handleReponse(window.ipc); +const IpcRendererEventChannel = window.ipc; interface IPreferredLocaleDescriptor { name: string; diff --git a/gui/src/renderer/components/SvgMap.tsx b/gui/src/renderer/components/SvgMap.tsx index cae3c68ed6..b72ea36bbd 100644 --- a/gui/src/renderer/components/SvgMap.tsx +++ b/gui/src/renderer/components/SvgMap.tsx @@ -31,8 +31,10 @@ const mapStyle = { height: '100%', backgroundColor: '#192e45', }; -const zoomableGroupStyle = { +const zoomableGroupStyle: React.CSSProperties = { transition: `transform ${MOVE_SPEED}ms ease-out`, + // Workaround to prevent map blurryness in Electron 13+ + zoom: '100.01%', }; function getMarkerImageStyle(zoom: number) { diff --git a/gui/src/renderer/components/Switch.tsx b/gui/src/renderer/components/Switch.tsx index 0f90a4e7e1..e3b722c721 100644 --- a/gui/src/renderer/components/Switch.tsx +++ b/gui/src/renderer/components/Switch.tsx @@ -17,6 +17,9 @@ interface IProps { interface IState { isOn: boolean; isPressed: boolean; + // gRPC calls cause the transition to glitch for some reason. Waiting with the onchange event + // until after the transition prevents the visual glitch from happening. + notifyOnTransitionEnd: boolean; } const PAN_DISTANCE = 10; @@ -56,6 +59,7 @@ export default class Switch extends React.PureComponent<IProps, IState> { public state: IState = { isOn: this.props.isOn, isPressed: false, + notifyOnTransitionEnd: false, }; private containerRef = React.createRef<HTMLDivElement>(); @@ -93,6 +97,7 @@ export default class Switch extends React.PureComponent<IProps, IState> { isOn={this.state.isOn} isPressed={this.state.isPressed} onMouseDown={this.handleMouseDown} + onTransitionEnd={this.onTransitionEnd} /> </SwitchContainer> ); @@ -103,13 +108,19 @@ export default class Switch extends React.PureComponent<IProps, IState> { assignToRef(element, this.props.forwardedRef); }; + private onTransitionEnd = (event: React.TransitionEvent) => { + if (this.state.notifyOnTransitionEnd && event.propertyName === 'left') { + this.notify(); + } + }; + private handleClick = () => { if (this.props.disabled) { return; } if (!this.changedDuringPan) { - this.setState((state) => ({ isOn: !state.isOn }), this.notify); + this.setState((state) => ({ isOn: !state.isOn, notifyOnTransitionEnd: true })); } // Needs to be reset to allow clicks on container after panning. @@ -161,7 +172,7 @@ export default class Switch extends React.PureComponent<IProps, IState> { if (this.state.isOn !== nextOn) { this.startPos = event.clientX; this.changedDuringPan = true; - this.setState({ isOn: nextOn }); + this.setState({ isOn: nextOn, notifyOnTransitionEnd: false }); } } }; diff --git a/gui/src/renderer/components/TransitionContainer.tsx b/gui/src/renderer/components/TransitionContainer.tsx index 1d177319c2..92aec7828e 100644 --- a/gui/src/renderer/components/TransitionContainer.tsx +++ b/gui/src/renderer/components/TransitionContainer.tsx @@ -67,6 +67,8 @@ export const StyledTransitionView = styled.div({ display: 'flex', flex: 1, flexDirection: 'column', + height: '100%', + width: '100%', }); export class TransitionView extends React.Component<ITransitioningViewProps> { diff --git a/gui/src/renderer/components/WireguardKeys.tsx b/gui/src/renderer/components/WireguardKeys.tsx index e76820b006..4a45d58d36 100644 --- a/gui/src/renderer/components/WireguardKeys.tsx +++ b/gui/src/renderer/components/WireguardKeys.tsx @@ -68,7 +68,7 @@ export default class WireguardKeys extends React.Component<IProps, IState> { public componentDidMount() { this.verifyKey(); - this.keyAgeUpdateInterval = setInterval(this.setAgeOfKeyStringState, 60 * 1000); + this.keyAgeUpdateInterval = window.setInterval(this.setAgeOfKeyStringState, 60 * 1000); } public componentWillUnmount() { |
