diff --git a/package-lock.json b/package-lock.json index 2aa5eb7..42df02c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "qrcode.react": "^3.1.0", "querystring-es3": "^0.2.1", "react": "^17.0.2", + "react-country-flag": "^3.0.2", "react-dom": "^17.0.2", "react-flatpickr": "^3.10.7", "react-loader-spinner": "^5.2.0", @@ -6829,6 +6830,17 @@ "node": ">=0.10.0" } }, + "node_modules/react-country-flag": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.0.2.tgz", + "integrity": "sha512-JPaz+q3QD0/nZtHBKj5x3O7r/SgSG9kxbymdaIU0RqlDAcorJIe4KV0DFhWIdKh69q5cPVkIVERcMYGZdvXgAA==", + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -13837,6 +13849,12 @@ "object-assign": "^4.1.1" } }, + "react-country-flag": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.0.2.tgz", + "integrity": "sha512-JPaz+q3QD0/nZtHBKj5x3O7r/SgSG9kxbymdaIU0RqlDAcorJIe4KV0DFhWIdKh69q5cPVkIVERcMYGZdvXgAA==", + "requires": {} + }, "react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", diff --git a/package.json b/package.json index 064858b..a08b38f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "qrcode.react": "^3.1.0", "querystring-es3": "^0.2.1", "react": "^17.0.2", + "react-country-flag": "^3.0.2", "react-dom": "^17.0.2", "react-flatpickr": "^3.10.7", "react-loader-spinner": "^5.2.0", diff --git a/src/App.jsx b/src/App.jsx index f3a1ef2..b09988b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -32,6 +32,10 @@ const App = observer(() => { document.querySelector('html').style.scrollBehavior = ''; }, [location.pathname]); // triggered on route change + if (!store.nodeInfo.networkIdentifier) { + return ; + } + return ( <> {store.loading && } diff --git a/src/pages/services/VPNServers.jsx b/src/pages/services/VPNServers.jsx index 8a8a4d7..8c341a6 100644 --- a/src/pages/services/VPNServers.jsx +++ b/src/pages/services/VPNServers.jsx @@ -6,33 +6,45 @@ import { QRCodeSVG } from 'qrcode.react'; import VPNServeIcon from '../../images/vpn_server_icon.png'; import { Filters } from '../../components/Filters'; +import { observer } from 'mobx-react-lite'; +import ReactCountryFlag from 'react-country-flag'; const filters = { - 'View All': '', - Active: 'Active', - Offline: 'Offline', + 'View All': 'all', + Active: true, + Offline: false, }; -function VPNServers() { +const VPNServers = observer(() => { const [sidebarOpen, setSidebarOpen] = useState(false); const [selectedServer, setSelectedServer] = useState(0); const [currentFilter, setCurrentFilter] = useState('View All'); + const servers = useMemo(() => { + if (filters[currentFilter] === 'all') return store.vpnServers; + return store.vpnServers.filter((e) => e.state === filters[currentFilter]); + }, [store.vpnServers, currentFilter]); + const qrContent = useMemo( () => ` [Interface] PrivateKey = ${store.vpnPrivateKey} -Address = ${store.vpnServers?.[selectedServer]?.address} -DNS = ${store.vpnServers?.[selectedServer]?.dns} +Address = ${servers?.[selectedServer]?.address} +DNS = ${servers?.[selectedServer]?.dns} [Peer] -PublicKey = ${store.vpnServers?.[selectedServer]?.publicKey} +PublicKey = ${servers?.[selectedServer]?.serverPublickKey} AllowedIPs = 0.0.0.0/0 -Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint} +Endpoint = ${servers?.[selectedServer]?.endpoint} +PersistentKeepalive = 25 `, - [store.vpnServers, store.vpnPrivateKey] + [store.vpnServers, store.vpnPrivateKey, selectedServer] ); + useEffect(() => { + setSelectedServer(0); + }, [currentFilter]); + const downloadTxtFile = () => { const element = document.createElement('a'); const file = new Blob([qrContent], { type: 'text/plain' }); @@ -59,7 +71,7 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
{/* Content */} -
+
{/* Page header */}
{/* Left: Title */} @@ -79,7 +91,7 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint} {/* Credit cards */}
- {store.vpnServers?.map((e, i) => ( + {servers?.map((e, i) => (
@@ -131,96 +150,111 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
{/* Sidebar */} -
-
-
-
-
-
- Physical Metal Card -
- - {/* Credit Card */} -
- -
- - {/* Details */} -
-
- Details + {servers?.length > 0 && ( +
+
+
+
+
+
+ Physical Metal Card
-
    -
  • -
    Server address
    -
    - {store.vpnServers?.[selectedServer]?.endpoint} -
    -
  • -
  • -
    Status
    -
    -
    -
    - Active + + {/* Credit Card */} +
    + +
    + + {/* Details */} +
    +
    + Details +
    +
      +
    • +
      Server address
      +
      + {servers?.[selectedServer]?.endpoint} +
      +
    • +
    • +
      Status
      +
      + {servers?.[selectedServer]?.state ? ( + <> +
      +
      + Active +
      + + ) : ( + <> +
      +
      + Offline +
      + + )} +
      +
    • +
    +
    + + {/* Payment Limits */} +
    +
    + Transfer +
    +
    +
    +
    Spent This Month
    +
    + {servers?.[selectedServer]?.transferSum}{' '} + / 50.00 + GB
    -
  • -
-
- - {/* Payment Limits */} -
-
- Transfer -
-
-
-
Spent This Month
-
- 4673,00 Mb{' '} - / 46730,00 - Mb +
+
-
-
-
- + + + + Download + +
-
+ )}
); -} +}); export default VPNServers; diff --git a/src/store/store.js b/src/store/store.js index cddc394..2fc6c58 100644 --- a/src/store/store.js +++ b/src/store/store.js @@ -3,27 +3,30 @@ import { makeAutoObservable, onBecomeObserved, onBecomeUnobserved, -} from "mobx"; -import { cryptography } from "@liskhq/lisk-client"; -import { passphrase } from "@liskhq/lisk-client"; -import { getNodeInfo } from "../api/node"; -import { fetchWrapper } from "../shared/fetchWrapper"; -import { labelMap } from "../shared/labelMap"; -import { statusMap } from "../shared/statusMap"; -import { generateSvgAvatar } from "../images/GenerateOnboardingSvg/GenerateSvg"; -import { decryptedData } from "../utils/decryptedData"; +} from 'mobx'; +import { cryptography } from '@liskhq/lisk-client'; +import { passphrase } from '@liskhq/lisk-client'; +import { getNodeInfo } from '../api/node'; +import { fetchWrapper } from '../shared/fetchWrapper'; +import { labelMap } from '../shared/labelMap'; +import { statusMap } from '../shared/statusMap'; +import { generateSvgAvatar } from '../images/GenerateOnboardingSvg/GenerateSvg'; +import { decryptedData } from '../utils/decryptedData'; import { + bytesToMbytes, encryptAccountData, encryptSharedData, + formatBytes, generateTransaction, hashAccountData, -} from "../utils/Utils"; -import sodium from "sodium-universal"; +} from '../utils/Utils'; +import sodium from 'sodium-universal'; +import { countryCodes } from '../utils/countryCodes'; class Store { _accountData = []; - _passPhrase = ""; + _passPhrase = ''; _nodeInfo = {}; @@ -63,18 +66,18 @@ class Store { () => this.address, () => this.fetchAccountInfo() ); - onBecomeObserved(this, "decryptedAccountData", () => + onBecomeObserved(this, 'decryptedAccountData', () => this.fetchNewAccountData() ); - onBecomeUnobserved(this, "decryptedAccountData", () => + onBecomeUnobserved(this, 'decryptedAccountData', () => this.unobservedAccountData() ); - onBecomeObserved(this, "sharedData", () => this.fetchKeysArray()); - onBecomeUnobserved(this, "sharedData", () => this.unobservedSharedData()); - onBecomeObserved(this, "transactionsInfo", () => + onBecomeObserved(this, 'sharedData', () => this.fetchKeysArray()); + onBecomeUnobserved(this, 'sharedData', () => this.unobservedSharedData()); + onBecomeObserved(this, 'transactionsInfo', () => this.fetchTransactionsInfo() ); - onBecomeUnobserved(this, "transactionsInfo", () => + onBecomeUnobserved(this, 'transactionsInfo', () => this.unobservedTransactionsInfo() ); @@ -83,7 +86,7 @@ class Store { fetchVPNServers() { fetchWrapper - .getAuth("vpn/servers", { + .getAuth('vpn/servers', { networkIdentifier: this.nodeInfo.networkIdentifier, lastBlockID: this.nodeInfo.lastBlockID, }) @@ -97,17 +100,12 @@ class Store { } fetchNewAccountData() { - getNodeInfo() - .then((info) => { - this.fetchNodeInfoSuccess(info); - fetchWrapper - .getAuth("data/private", { - networkIdentifier: this.nodeInfo.networkIdentifier, - lastBlockID: this.nodeInfo.lastBlockID, - }) - .then((res) => this.accountDataFetchChange(res)) - .catch((err) => this.throwError(err)); + fetchWrapper + .getAuth('data/private', { + networkIdentifier: this.nodeInfo.networkIdentifier, + lastBlockID: this.nodeInfo.lastBlockID, }) + .then((res) => this.accountDataFetchChange(res)) .catch((err) => this.throwError(err)); } @@ -123,7 +121,7 @@ class Store { .then((info) => { this.fetchNodeInfoSuccess(info); fetchWrapper - .getAuth("data/shared/", { + .getAuth('data/shared/', { networkIdentifier: this.nodeInfo.networkIdentifier, lastBlockID: this.nodeInfo.lastBlockID, }) @@ -144,13 +142,13 @@ class Store { fetchTempTransactions() { fetchWrapper - .get("node/transactions") + .get('node/transactions') .then((res) => this.fetchTempTransactionsSuccess(res)) .catch((err) => this.throwError(err)); } fetchPassPhrase() { - this._passPhrase = sessionStorage.getItem("passPhrase") || ""; + this._passPhrase = sessionStorage.getItem('passPhrase') || ''; } fetchSharedData() { @@ -173,7 +171,7 @@ class Store { if (data.length > 0) { fetchWrapper .postAuth( - "data/shared", + 'data/shared', { networkIdentifier: this.nodeInfo.networkIdentifier, lastBlockID: this.nodeInfo.lastBlockID, @@ -190,7 +188,7 @@ class Store { pushAccountData(data = this.accountData) { fetchWrapper .postAuth( - "data/private", + 'data/private', { networkIdentifier: this.nodeInfo.networkIdentifier, lastBlockID: this.nodeInfo.lastBlockID, @@ -221,7 +219,7 @@ class Store { if (changed.length !== 0) signedTx = builder.update(changed); if (signedTx) { fetchWrapper - .post("transactions", {}, signedTx) + .post('transactions', {}, signedTx) .then(() => this.fetchTempTransactions()) .catch((err) => this.throwError(err)); this.accountInfo.sequence.nonce++; @@ -240,7 +238,7 @@ class Store { if (signedTx) { fetchWrapper - .post("transactions", {}, signedTx) + .post('transactions', {}, signedTx) .then(() => this.fetchTempTransactions()) .catch((err) => this.throwError(err)); this.accountInfo.sequence.nonce++; @@ -262,7 +260,7 @@ class Store { if (signedTx) { fetchWrapper - .post("transactions", {}, signedTx) + .post('transactions', {}, signedTx) .then(() => this.fetchTempTransactions()) .catch((err) => this.throwError(err)); this.accountInfo.sequence.nonce++; @@ -271,12 +269,12 @@ class Store { generatePassPhrase() { this._passPhrase = passphrase.Mnemonic.generateMnemonic(); - sessionStorage.setItem("passPhrase", this._passPhrase); + sessionStorage.setItem('passPhrase', this._passPhrase); } savePastPassPhrase(phrase) { this._passPhrase = phrase; - sessionStorage.setItem("passPhrase", this._passPhrase); + sessionStorage.setItem('passPhrase', this._passPhrase); } unobservedTransactionsInfo() { @@ -398,12 +396,12 @@ class Store { } get firstName() { - return this.decryptedAccountData.find((item) => item.key === "firstname") + return this.decryptedAccountData.find((item) => item.key === 'firstname') ?.value; } get lastName() { - return this.decryptedAccountData.find((item) => item.key === "secondname") + return this.decryptedAccountData.find((item) => item.key === 'secondname') ?.value; } @@ -444,27 +442,27 @@ class Store { let x25519_sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES); sodium.crypto_sign_ed25519_sk_to_curve25519( x25519_sk, - Buffer.from(this.privateKey, "hex") + Buffer.from(this.privateKey, 'hex') ); - return x25519_sk.toString("Base64"); + return x25519_sk.toString('Base64'); } get pubKey() { - return this.addressAndPubKey.publicKey.toString("hex"); + return this.addressAndPubKey.publicKey.toString('hex'); } get address() { - return this.addressAndPubKey.address.toString("hex"); + return this.addressAndPubKey.address.toString('hex'); } get tokenKey() { const stringToSign = this.nodeInfo.networkIdentifier + this.nodeInfo.lastBlockID; - if (!stringToSign) return ""; + if (!stringToSign) return ''; const sign = cryptography - .signDataWithPassphrase(Buffer.from(stringToSign, "hex"), this.passPhrase) - .toString("hex"); - return this.pubKey + ":" + sign; + .signDataWithPassphrase(Buffer.from(stringToSign, 'hex'), this.passPhrase) + .toString('hex'); + return this.pubKey + ':' + sign; } get accountIdentity() { @@ -598,7 +596,19 @@ class Store { } get vpnServers() { - return this._vpnServers; + return this._vpnServers?.map((server) => ({ + ...server, + transferSum: formatBytes( + Number(server.transferTx || 0) + Number(server.transferRx || 0) + ), + trafficUsed: Math.floor( + ((Number(server.transferTx || 0) + Number(server.transferRx || 0)) / + (50 * 1024 * 1024 * 1024)) * + 100 + ), + state: server.state === '1', + country: countryCodes[server.country] || 'US', + })); } get canVPN() { @@ -611,13 +621,13 @@ class Store { let amount = this.processedVotes[address]; - if (amount) return "Pending"; + if (amount) return 'Pending'; amount = this.accountSentVotes[address]; - if (amount) return "Unvote"; + if (amount) return 'Unvote'; - return "Vote"; + return 'Vote'; }; return this._delegates.data.map((delegate) => ({ diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 44cf4de..3e35050 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -139,6 +139,18 @@ export const hashValue = (value = '', seed = '') => Buffer.concat([Buffer.from(seed, 'utf8'), cryptography.hash(value, 'utf8')]) ); +export const formatBytes = (bytes, decimals = 2) => { + if (!+bytes) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; +}; + export const generateTransaction = ( nonce = BigInt(0), senderPublicKey = '', diff --git a/src/utils/countryCodes.js b/src/utils/countryCodes.js new file mode 100644 index 0000000..5ed7164 --- /dev/null +++ b/src/utils/countryCodes.js @@ -0,0 +1,252 @@ +export const countryCodes = { + BGD: 'BD', + BEL: 'BE', + BFA: 'BF', + BGR: 'BG', + BIH: 'BA', + BRB: 'BB', + WLF: 'WF', + BLM: 'BL', + BMU: 'BM', + BRN: 'BN', + BOL: 'BO', + BHR: 'BH', + BDI: 'BI', + BEN: 'BJ', + BTN: 'BT', + JAM: 'JM', + BVT: 'BV', + BWA: 'BW', + WSM: 'WS', + BES: 'BQ', + BRA: 'BR', + BHS: 'BS', + JEY: 'JE', + BLR: 'BY', + BLZ: 'BZ', + RUS: 'RU', + RWA: 'RW', + SRB: 'RS', + TLS: 'TL', + REU: 'RE', + TKM: 'TM', + TJK: 'TJ', + ROU: 'RO', + TKL: 'TK', + GNB: 'GW', + GUM: 'GU', + GTM: 'GT', + SGS: 'GS', + GRC: 'GR', + GNQ: 'GQ', + GLP: 'GP', + JPN: 'JP', + GUY: 'GY', + GGY: 'GG', + GUF: 'GF', + GEO: 'GE', + GRD: 'GD', + GBR: 'GB', + GAB: 'GA', + SLV: 'SV', + GIN: 'GN', + GMB: 'GM', + GRL: 'GL', + GIB: 'GI', + GHA: 'GH', + OMN: 'OM', + TUN: 'TN', + JOR: 'JO', + HRV: 'HR', + HTI: 'HT', + HUN: 'HU', + HKG: 'HK', + HND: 'HN', + HMD: 'HM', + VEN: 'VE', + PRI: 'PR', + PSE: 'PS', + PLW: 'PW', + PRT: 'PT', + SJM: 'SJ', + PRY: 'PY', + IRQ: 'IQ', + PAN: 'PA', + PYF: 'PF', + PNG: 'PG', + PER: 'PE', + PAK: 'PK', + PHL: 'PH', + PCN: 'PN', + POL: 'PL', + SPM: 'PM', + ZMB: 'ZM', + ESH: 'EH', + EST: 'EE', + EGY: 'EG', + ZAF: 'ZA', + ECU: 'EC', + ITA: 'IT', + VNM: 'VN', + SLB: 'SB', + ETH: 'ET', + SOM: 'SO', + ZWE: 'ZW', + SAU: 'SA', + ESP: 'ES', + ERI: 'ER', + MNE: 'ME', + MDA: 'MD', + MDG: 'MG', + MAF: 'MF', + MAR: 'MA', + MCO: 'MC', + UZB: 'UZ', + MMR: 'MM', + MLI: 'ML', + MAC: 'MO', + MNG: 'MN', + MHL: 'MH', + MKD: 'MK', + MUS: 'MU', + MLT: 'MT', + MWI: 'MW', + MDV: 'MV', + MTQ: 'MQ', + MNP: 'MP', + MSR: 'MS', + MRT: 'MR', + IMN: 'IM', + UGA: 'UG', + TZA: 'TZ', + MYS: 'MY', + MEX: 'MX', + ISR: 'IL', + FRA: 'FR', + IOT: 'IO', + SHN: 'SH', + FIN: 'FI', + FJI: 'FJ', + FLK: 'FK', + FSM: 'FM', + FRO: 'FO', + NIC: 'NI', + NLD: 'NL', + NOR: 'NO', + NAM: 'NA', + VUT: 'VU', + NCL: 'NC', + NER: 'NE', + NFK: 'NF', + NGA: 'NG', + NZL: 'NZ', + NPL: 'NP', + NRU: 'NR', + NIU: 'NU', + COK: 'CK', + XKX: 'XK', + CIV: 'CI', + CHE: 'CH', + COL: 'CO', + CHN: 'CN', + CMR: 'CM', + CHL: 'CL', + CCK: 'CC', + CAN: 'CA', + COG: 'CG', + CAF: 'CF', + COD: 'CD', + CZE: 'CZ', + CYP: 'CY', + CXR: 'CX', + CRI: 'CR', + CUW: 'CW', + CPV: 'CV', + CUB: 'CU', + SWZ: 'SZ', + SYR: 'SY', + SXM: 'SX', + KGZ: 'KG', + KEN: 'KE', + SSD: 'SS', + SUR: 'SR', + KIR: 'KI', + KHM: 'KH', + KNA: 'KN', + COM: 'KM', + STP: 'ST', + SVK: 'SK', + KOR: 'KR', + SVN: 'SI', + PRK: 'KP', + KWT: 'KW', + SEN: 'SN', + SMR: 'SM', + SLE: 'SL', + SYC: 'SC', + KAZ: 'KZ', + CYM: 'KY', + SGP: 'SG', + SWE: 'SE', + SDN: 'SD', + DOM: 'DO', + DMA: 'DM', + DJI: 'DJ', + DNK: 'DK', + VGB: 'VG', + DEU: 'DE', + YEM: 'YE', + DZA: 'DZ', + USA: 'US', + URY: 'UY', + MYT: 'YT', + UMI: 'UM', + LBN: 'LB', + LCA: 'LC', + LAO: 'LA', + TUV: 'TV', + TWN: 'TW', + TTO: 'TT', + TUR: 'TR', + LKA: 'LK', + LIE: 'LI', + LVA: 'LV', + TON: 'TO', + LTU: 'LT', + LUX: 'LU', + LBR: 'LR', + LSO: 'LS', + THA: 'TH', + ATF: 'TF', + TGO: 'TG', + TCD: 'TD', + TCA: 'TC', + LBY: 'LY', + VAT: 'VA', + VCT: 'VC', + ARE: 'AE', + AND: 'AD', + ATG: 'AG', + AFG: 'AF', + AIA: 'AI', + VIR: 'VI', + ISL: 'IS', + IRN: 'IR', + ARM: 'AM', + ALB: 'AL', + AGO: 'AO', + ATA: 'AQ', + ASM: 'AS', + ARG: 'AR', + AUS: 'AU', + AUT: 'AT', + ABW: 'AW', + IND: 'IN', + ALA: 'AX', + AZE: 'AZ', + IRL: 'IE', + IDN: 'ID', + UKR: 'UA', + QAT: 'QA', + MOZ: 'MZ', +}; diff --git a/webpack.config.js b/webpack.config.js index 8c6221b..3d83bea 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,19 +1,19 @@ -const path = require("path"); -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const webpack = require("webpack"); +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const webpack = require('webpack'); const plugins = [ new HtmlWebpackPlugin({ - favicon: "./public/favicon.ico", - template: "./public/index.html", + favicon: './public/favicon.ico', + template: './public/index.html', }), new webpack.ProvidePlugin({ - Buffer: ["buffer", "Buffer"], + Buffer: ['buffer', 'Buffer'], }), new webpack.ProvidePlugin({ - process: "process/browser", + process: 'process/browser', }), - require("tailwindcss"), + require('tailwindcss'), new webpack.ContextReplacementPlugin(/sodium/, (data) => { delete data.dependencies[0].critical; return data; @@ -21,86 +21,83 @@ const plugins = [ ]; module.exports = (env, argv) => ({ - entry: "./src/main.jsx", - mode: argv.mode || "development", - devtool: argv.mode === "production" ? false : "eval-source-map", + entry: './src/main.jsx', + mode: argv.mode || 'development', + devtool: argv.mode === 'production' ? false : 'eval-source-map', plugins, output: { clean: true, - path: path.resolve(__dirname, "build"), - assetModuleFilename: "assets/[fullhash:12][ext]", - filename: "main.[fullhash:8].js", + path: path.resolve(__dirname, 'build'), + assetModuleFilename: 'assets/[fullhash:12][ext]', + filename: 'main.[fullhash:8].js', }, devServer: { open: true, static: { - directory: path.join(__dirname, "public"), + directory: path.join(__dirname, 'public'), }, compress: true, - port: "auto", + port: 'auto', hot: true, client: { progress: true, }, proxy: { - "/api/**": { - target: "https://tn-alpha.idntty.org:8080/", + '/api/**': { + target: 'https://tn-alpha.idntty.org:8080/', secure: false, changeOrigin: true, }, }, }, - - ignoreWarnings: [() => false], - module: { rules: [ - { test: /\.(html)$/, use: ["html-loader"] }, + { test: /\.(html)$/, use: ['html-loader'] }, { test: /\.m?jsx?$/, exclude: /(node_modules|bower_components)/, use: { - loader: "babel-loader", + loader: 'babel-loader', }, }, { test: /\.scss$/, use: [ { - loader: "style-loader", + loader: 'style-loader', }, { - loader: "css-loader", + loader: 'css-loader', }, { - loader: "postcss-loader", + loader: 'postcss-loader', }, { - loader: "sass-loader", + loader: 'sass-loader', }, ], }, { test: /\.(png|svg|jpg|gif)$/, - loader: "file-loader", + loader: 'file-loader', options: { - outputPath: "assets", + outputPath: 'assets', }, }, ], }, resolve: { - extensions: [".js", ".jsx"], + extensions: ['.js', '.jsx'], fallback: { - path: require.resolve("path-browserify"), - os: require.resolve("os-browserify/browser"), - querystring: require.resolve("querystring-es3"), - crypto: require.resolve("crypto-browserify"), - util: require.resolve("util/"), - stream: require.resolve("stream-browserify"), - url: require.resolve("url/"), - buffer: require.resolve("buffer/"), + path: require.resolve('path-browserify'), + os: require.resolve('os-browserify/browser'), + querystring: require.resolve('querystring-es3'), + crypto: require.resolve('crypto-browserify'), + util: require.resolve('util/'), + stream: require.resolve('stream-browserify'), + url: require.resolve('url/'), + buffer: require.resolve('buffer/'), fs: false, }, },