From ac946e22066a445b2e3222f8994526ec07bb75c4 Mon Sep 17 00:00:00 2001 From: isopolito Date: Thu, 1 Dec 2022 07:41:49 -0600 Subject: [PATCH 1/6] Handle new nordvpn version when parsing CLI output --- metadata.json | 6 ++++-- modules/CommonFavorite.js | 7 ------- modules/Vpn.js | 19 ++++++++++++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/metadata.json b/metadata.json index fcbf204..537eb8e 100644 --- a/metadata.json +++ b/metadata.json @@ -3,9 +3,11 @@ "description": "A Gnome extension that shows the NordVPN status in the top bar and provides the ability to configure certain aspects of the connection.", "name": "gNordVPN-Local", "shell-version": [ - "43" + "40", + "41", + "42" ], "url": "https://github.com/Isopolito/gNordVPN-Local", "uuid": "gnordvpn-local@isopolito", - "version": 13 + "version": 14 } diff --git a/modules/CommonFavorite.js b/modules/CommonFavorite.js index aa18e70..6efaed6 100644 --- a/modules/CommonFavorite.js +++ b/modules/CommonFavorite.js @@ -25,13 +25,6 @@ var CommonFavorite = class CommonFavorite extends MenuBase { this._signals = new Signals(); } - disable() { - this._isBuilt = false; - this._destroyMap = {}; - this.favList = {}; - this.itemList = {}; - } - updateFavorite() { let newFav = {}; diff --git a/modules/Vpn.js b/modules/Vpn.js index c635ee2..8a294b9 100644 --- a/modules/Vpn.js +++ b/modules/Vpn.js @@ -2,6 +2,9 @@ const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const ExtensionUtils = imports.misc.extensionUtils; + +// Force version 2.x to avoid compatibility issues with certain distros that are using Soup 3.x by default +imports.gi.versions.Soup = "2.4"; const Soup = imports.gi.Soup; const CMD_VPNSTATUS = `nordvpn status`; @@ -131,11 +134,14 @@ var Vpn = class Vpn { const allStatusMessages = this._getString(standardOut).split(`\n`); let connectStatus, updateMessage, country, serverNumber, city, serverIp, currentTech, currentProtocol, transfer, uptime, currentServer; + + // NOTE that some of these message formats change across versions, old message formats are left in for backwards compatibility for (const msg of allStatusMessages) { if (msg.includes("Status:")) connectStatus = (msg.match(/Status: \w+/) || [``])[0]; else if (msg.includes("Country:")) country = msg.replace("Country: ", "").toUpperCase(); else if (msg.includes("City:")) city = msg.replace("City: ", ""); else if (msg.includes("Server IP:")) serverIp = msg.replace("Server IP: ", ""); + else if (msg.includes("IP:")) serverIp = msg.replace("IP: ", ""); else if (msg.includes("Current protocol:")) currentProtocol = msg.replace("Current protocol: ", ""); else if (msg.includes("Current technology:")) currentTech = msg.replace("Current technology: ", ""); else if (msg.includes("Transfer:")) transfer = msg.replace("Transfer: ", ""); @@ -144,6 +150,9 @@ var Vpn = class Vpn { else if (msg.includes("Current server:")) { serverNumber = msg.match(/\d+/); currentServer = msg.replace("Current server: ", "") + } else if (msg.includes("Hostname:")) { + serverNumber = msg.match(/\d+/); + currentServer = msg.replace("Hostname: ", "") } } @@ -203,8 +212,8 @@ var Vpn = class Vpn { getCountries(withId = false) { if (withId) { this.message = Soup.Message.new("GET", "https://api.nordvpn.com/v1/servers/countries"); - this.session.send(this.message, null); - let countrieMap; + this.session.send_message(this.message); + let countrieNames, countrieMap; try { let data = JSON.parse(this.message.response_body_data.get_data()); countrieMap = data.reduce((acc, v) => { @@ -220,7 +229,7 @@ var Vpn = class Vpn { const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_COUNTRIES); const countries = this._processCityCountryOutput(this._getString(standardOut)); - + let processedCountries = {}; for (let country of countries) { processedCountries[country.replace(/_/g, " ")] = country; @@ -242,7 +251,7 @@ var Vpn = class Vpn { for (let i = 0; i < citiesSaved.length; i++) { const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(`${CMD_CITIES} ${citiesSaved[i]}`); const cities = this._processCityCountryOutput(this._getString(standardOut)); - + for (let j = 0; j < cities.length; j++) { if (j > citiesMax) break; let c = (citiesSaved[i] + ", " + cities[j].replace(",", "")).replace(/_/g, " "); @@ -285,7 +294,7 @@ var Vpn = class Vpn { try { for (let i = 0; i < countriesSaved.length; i++) { this.message = Soup.Message.new("GET", url + "&filters[country_id]=" + countriesSaved[i]); - this.session.send(this.message, null); + this.session.send_message(this.message); let data = this.message.response_body_data.get_data(); JSON.parse(this._getString(data)).forEach(e => { servers[e['name']] = e['hostname'].replace('.nordvpn.com', ''); From fa8e288ee28ca99b4391444a3b9bd0b8442d2279 Mon Sep 17 00:00:00 2001 From: isopolito Date: Sat, 3 Dec 2022 12:55:29 -0600 Subject: [PATCH 2/6] Gracefully handle when NordVpn is not running --- extension.js | 8 +++++--- modules/ConnectionMenu.js | 13 +++++++------ modules/StateManager.js | 6 +++--- modules/Vpn.js | 27 ++++++++++++++++----------- modules/common.js | 3 +++ prefs.js | 3 +-- 6 files changed, 35 insertions(+), 25 deletions(-) create mode 100644 modules/common.js diff --git a/extension.js b/extension.js index e65639b..b3579e9 100644 --- a/extension.js +++ b/extension.js @@ -31,7 +31,7 @@ const VpnIndicator = GObject.registerClass({ this.stateManager = new StateManager(); this.settings = ExtensionUtils.getSettings(`org.gnome.shell.extensions.gnordvpn-local`); - this.settings.connect('changed', (settings, key)=> { + this.settings.connect('changed', (settings, key) => { switch(key) { case 'panel-styles': case 'common-panel-style': @@ -87,7 +87,10 @@ const VpnIndicator = GObject.registerClass({ let status = this._vpn.getStatus(); status.loggedin = this.loggedin; - status.currentState = this.stateManager.resolveState(status); + + status.currentState = this._vpn.isNordVpnRunning() + ? this.stateManager.resolveState(status) + : this.stateManager.resolveState(null); // Ensure that menus are populated. Since the menu may be created before the VPN is running and able // to provide available cities, countries, etc @@ -106,7 +109,6 @@ const VpnIndicator = GObject.registerClass({ } _updateMenu(status) { - // Set the status text on the menu this._statusLabel.text = status.connectStatus; this._statusPopup.get_label_actor().set_text(status.connectStatus); diff --git a/modules/ConnectionMenu.js b/modules/ConnectionMenu.js index 58c2605..98b3ad9 100644 --- a/modules/ConnectionMenu.js +++ b/modules/ConnectionMenu.js @@ -9,6 +9,7 @@ const Constants = Me.imports.modules.constants; const Signals = Me.imports.modules.Signals.Signals; const MenuBase = Me.imports.modules.MenuBase.MenuBase; const Favorites = Me.imports.modules.Favorites.Favorites; +const Common = Me.imports.modules.common; var ConnectionMenu = class ConnectionMenu extends MenuBase { constructor(connectionLabel, connectionType, favoritesKey, connectionCallback) { @@ -34,11 +35,11 @@ var ConnectionMenu = class ConnectionMenu extends MenuBase { const connectionFavs = this._favorites.get(this._favoritesKey).favorites; //connectionFavs-favConnectionItems - let toAddToFav = Object.keys(connectionFavs).filter(x => !this._favConnectionItems.includes(x)); + let toAddToFav = Common.safeObjectKeys(connectionFavs).filter(x => !this._favConnectionItems.includes(x)); toAddToFav.forEach(connection => { this._toogleConnectionMenuItem(connection, !true); }) //_favConnectionItems-connectionFavs - let toRemoveFromFav = this._favConnectionItems.filter(x => !Object.keys(connectionFavs).includes(x)) + let toRemoveFromFav = this._favConnectionItems.filter(x => !Common.safeObjectKeys(connectionFavs).includes(x)) toRemoveFromFav.forEach(connection => { this._toogleConnectionMenuItem(connection, !false); }) } @@ -154,7 +155,7 @@ var ConnectionMenu = class ConnectionMenu extends MenuBase { const connectionFavs = this._favorites.get(this._favoritesKey, this._connections); this._connections = {...connectionFavs.favorites, ...connectionFavs.itemsMinusFavorites}; - for (const connection of Object.keys(connectionFavs.favorites).sort()) { + for (const connection of Common.safeObjectKeys(connectionFavs.favorites).sort()) { const menuItem = this._buildConnectionMenuItem(connection, true); this._favConnectionItems.push(connection); this._connectionMenu.menu.addMenuItem(menuItem); @@ -164,13 +165,13 @@ var ConnectionMenu = class ConnectionMenu extends MenuBase { this._connectionMenu.menu.addMenuItem(this._menuSeperator); - for (const connection of Object.keys(connectionFavs.itemsMinusFavorites).sort()) { + for (const connection of Common.safeObjectKeys(connectionFavs.itemsMinusFavorites).sort()) { const menuItem = this._buildConnectionMenuItem(connection, false); this._connectionMenuItems.push(connection); this._connectionMenu.menu.addMenuItem(menuItem); } - if (Object.keys(this._connections).length < 1) { + if (Common.safeObjectKeys(this._connections).length < 1) { this._connectionMenu.hide(); } else { this._connectionMenu.show(); @@ -180,7 +181,7 @@ var ConnectionMenu = class ConnectionMenu extends MenuBase { } showHide(show=true) { - if (Object.keys(this._connections).length < 1 || !show) { + if (Common.safeObjectKeys(this._connections).length < 1 || !show) { this._connectionMenu.hide(); } else { this._connectionMenu.show(); diff --git a/modules/StateManager.js b/modules/StateManager.js index 968aa75..ad516fc 100644 --- a/modules/StateManager.js +++ b/modules/StateManager.js @@ -120,11 +120,11 @@ var StateManager = class StateManager { } resolveState(status) { - let vpnState = this.states[status.connectStatus] || this.states.ERROR; - if (!status.loggedin) vpnState = this.states['LOGGED OUT']; + let vpnState = (status && this.states[status.connectStatus]) || this.states.ERROR; + if (status && !status.loggedin) vpnState = this.states['LOGGED OUT']; // If a state override is active, increment it and override the state if appropriate - if (this.stateOverride) { + if (status && this.stateOverride) { this.stateOverrideCounter += 1; let overrideFromKey = (this.stateOverride.overrideKeys && ( diff --git a/modules/Vpn.js b/modules/Vpn.js index 8a294b9..ae38970 100644 --- a/modules/Vpn.js +++ b/modules/Vpn.js @@ -128,6 +128,11 @@ var Vpn = class Vpn { return this._getString(standardOut).replace(/\s+/g, ` `).includes('You are already logged in.'); } + isNordVpnRunning() { + const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); + return exitStatus === 0; + } + getStatus() { const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); @@ -157,17 +162,17 @@ var Vpn = class Vpn { } return { - connectStatus, - updateMessage, - country, - city, - serverNumber, - currentServer, - serverIp, - currentTech, - currentProtocol, - transfer, - uptime + connectStatus: connectStatus || 'N/A', + updateMessage: updateMessage || 'N/A', + country: country || 'N/A', + city: city || 'N/A', + serverNumber: serverNumber || 'N/A', + currentServer: currentServer || 'N/A', + serverIp: serverIp || 'N/A', + currentTech: currentTech || 'N/A', + currentProtocol: currentProtocol || 'N/A', + transfer: transfer || 'N/A', + uptime: uptime || 'N/A' } } diff --git a/modules/common.js b/modules/common.js new file mode 100644 index 0000000..558a184 --- /dev/null +++ b/modules/common.js @@ -0,0 +1,3 @@ +var safeObjectKeys = function(obj) { + return obj ? Object.keys(obj) : []; +} \ No newline at end of file diff --git a/prefs.js b/prefs.js index b2cd872..f7556df 100644 --- a/prefs.js +++ b/prefs.js @@ -89,7 +89,6 @@ function loadStyle(data, styleItems) { let css = data[item.state].css; item.css.get_buffer().set_text(css, css.length); - }) } @@ -104,7 +103,7 @@ function buildPrefsWidget() { this.countrieMapWithID = this.vpn.getCountries(true); this.countrieNames = Object.keys(this.countrieMap); - const notebook = new Gtk.Notebook() + const notebook = new Gtk.Notebook(); const generalPage = new Gtk.Grid({ margin_start: 18, From 975abe3c6690d60b9bcb47a39ee12ace32a484e1 Mon Sep 17 00:00:00 2001 From: isopolito Date: Sun, 4 Dec 2022 10:17:41 -0600 Subject: [PATCH 3/6] Don't break if nordvpn is not installed --- extension.js | 1 + modules/Vpn.js | 41 ++++++++++++++++++++++++++++------------- prefs.js | 7 ++++--- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/extension.js b/extension.js index b3579e9..e81b4f3 100644 --- a/extension.js +++ b/extension.js @@ -308,6 +308,7 @@ const VpnIndicator = GObject.registerClass({ this._vpn.applySettingsToNord(); this._buildIndicatorMenu(); + this._refresh(); } diff --git a/modules/Vpn.js b/modules/Vpn.js index ae38970..cb5b3fc 100644 --- a/modules/Vpn.js +++ b/modules/Vpn.js @@ -7,6 +7,7 @@ const ExtensionUtils = imports.misc.extensionUtils; imports.gi.versions.Soup = "2.4"; const Soup = imports.gi.Soup; +const CMD_NORDEXISTS = `command -v nordvpn`; const CMD_VPNSTATUS = `nordvpn status`; const CMD_VPNACCOUNT = `nordvpn account`; const CMD_COUNTRIES = `nordvpn countries`; @@ -71,8 +72,23 @@ var Vpn = class Vpn { return null; } - setSettingsFromNord() { + _executeCommand(command) { + if (!this.isNordVpnRunning()) return ""; const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_FETCH_SETTINGS); + return standardOut; + } + + isNordVpnRunning() { + try { + [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); + return exitStatus === 0; + } catch { + return false; + } + } + + setSettingsFromNord() { + const standardOut = this._executeCommand(CMD_FETCH_SETTINGS); const normalizedOut = this._getString(standardOut); for (const line of normalizedOut.split(`\n`)) { @@ -89,7 +105,10 @@ var Vpn = class Vpn { } } + applySettingsToNord() { + if (!this.isNordVpnRunning()) return; + this.executeCommandSync(`${CMD_SETTINGS} firewall ${this.settings.get_boolean(`firewall`)}`); this.executeCommandSync(`${CMD_SETTINGS} autoconnect ${this.settings.get_boolean(`autoconnect`)}`); this.executeCommandSync(`${CMD_SETTINGS} cybersec ${this.settings.get_boolean(`cybersec`)}`); @@ -110,7 +129,7 @@ var Vpn = class Vpn { getAccount() { // Read the VPN status from the command line - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNACCOUNT); + const standardOut = this._executeCommand(CMD_VPNACCOUNT); const allAccountMessages = this._getString(standardOut).split(`\n`); let emailAddress; @@ -124,19 +143,15 @@ var Vpn = class Vpn { } checkLogin() { - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_LOGIN); + const standardOut = this._executeCommand(CMD_LOGIN); return this._getString(standardOut).replace(/\s+/g, ` `).includes('You are already logged in.'); } - isNordVpnRunning() { - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); - return exitStatus === 0; - } getStatus() { - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); - + const standardOut = this._executeCommand(CMD_VPNSTATUS); const allStatusMessages = this._getString(standardOut).split(`\n`); + let connectStatus, updateMessage, country, serverNumber, city, serverIp, currentTech, currentProtocol, transfer, uptime, currentServer; @@ -163,7 +178,7 @@ var Vpn = class Vpn { return { connectStatus: connectStatus || 'N/A', - updateMessage: updateMessage || 'N/A', + updateMessage, country: country || 'N/A', city: city || 'N/A', serverNumber: serverNumber || 'N/A', @@ -189,7 +204,7 @@ var Vpn = class Vpn { } loginVpn() { - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_LOGIN); + const standardOut = this._executeCommand(CMD_LOGIN); const ref = "Continue in the browser: "; let url = this._getString(standardOut).replace(/\s+/g, ` `); @@ -232,7 +247,7 @@ var Vpn = class Vpn { return countrieMap; } - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_COUNTRIES); + const standardOut = this._executeCommand(CMD_COUNTRIES); const countries = this._processCityCountryOutput(this._getString(standardOut)); let processedCountries = {}; @@ -254,7 +269,7 @@ var Vpn = class Vpn { let processedCities = {}; for (let i = 0; i < citiesSaved.length; i++) { - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(`${CMD_CITIES} ${citiesSaved[i]}`); + const standardOut = this._executeCommand(`${CMD_CITIES} ${citiesSaved[i]}`); const cities = this._processCityCountryOutput(this._getString(standardOut)); for (let j = 0; j < cities.length; j++) { diff --git a/prefs.js b/prefs.js index f7556df..a8e460c 100644 --- a/prefs.js +++ b/prefs.js @@ -9,6 +9,7 @@ const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const Vpn = Me.imports.modules.Vpn.Vpn; const Constants = Me.imports.modules.constants; +const Common = Me.imports.modules.common; function init() { } @@ -101,7 +102,7 @@ function buildPrefsWidget() { this.countrieMap = this.vpn.getCountries(); this.countrieMapWithID = this.vpn.getCountries(true); - this.countrieNames = Object.keys(this.countrieMap); + this.countrieNames = Common.safeObjectKeys(this.countrieMap); const notebook = new Gtk.Notebook(); @@ -424,7 +425,7 @@ function buildPrefsWidget() { let row = 5; let styleItems = []; - Object.keys(Constants.states).forEach(state => { + Common.safeObjectKeys(Constants.states).forEach(state => { const label = new Gtk.Label({ label: state, halign: Gtk.Align.START, @@ -954,7 +955,7 @@ function buildPrefsWidget() { let isMono = monoToggle.get_active(); let isAlt = altToggle.get_active(); let style = isAlt ? styleAltCss : styleCss; - Object.keys(style).forEach(key => { + Common.safeObjectKeys(style).forEach(key => { if (isMono) style[key].css = isAlt ? altMonoCss : monoCss; style[key].panelText = panelTexts[key]; }); From 102dbcff67e8c6b77931203f6a535061bd7e3b7a Mon Sep 17 00:00:00 2001 From: isopolito Date: Sun, 4 Dec 2022 11:22:00 -0600 Subject: [PATCH 4/6] Implement disable callback --- modules/CommonFavorite.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/CommonFavorite.js b/modules/CommonFavorite.js index 6efaed6..eadf075 100644 --- a/modules/CommonFavorite.js +++ b/modules/CommonFavorite.js @@ -26,7 +26,6 @@ var CommonFavorite = class CommonFavorite extends MenuBase { } updateFavorite() { - let newFav = {}; Object.keys(Constants.favorites).forEach(key => { @@ -175,4 +174,11 @@ var CommonFavorite = class CommonFavorite extends MenuBase { this._favoriteMenu.show(); } } + + disable() { + this._isBuilt = false; + this._destroyMap = {}; + this.favList = {}; + this.itemList = {}; + } } From d20a6cf50e7bc416c79450dbea6581f1680b2106 Mon Sep 17 00:00:00 2001 From: isopolito Date: Sun, 4 Dec 2022 11:46:35 -0600 Subject: [PATCH 5/6] Clean up VPN logic --- modules/Vpn.js | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/modules/Vpn.js b/modules/Vpn.js index cb5b3fc..f70d9ba 100644 --- a/modules/Vpn.js +++ b/modules/Vpn.js @@ -7,7 +7,6 @@ const ExtensionUtils = imports.misc.extensionUtils; imports.gi.versions.Soup = "2.4"; const Soup = imports.gi.Soup; -const CMD_NORDEXISTS = `command -v nordvpn`; const CMD_VPNSTATUS = `nordvpn status`; const CMD_VPNACCOUNT = `nordvpn account`; const CMD_COUNTRIES = `nordvpn countries`; @@ -74,13 +73,13 @@ var Vpn = class Vpn { _executeCommand(command) { if (!this.isNordVpnRunning()) return ""; - const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_FETCH_SETTINGS); - return standardOut; + const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(command); + return this._getString(standardOut); } isNordVpnRunning() { try { - [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); + const [ok, standardOut, standardError, exitStatus] = this.executeCommandSync(CMD_VPNSTATUS); return exitStatus === 0; } catch { return false; @@ -89,9 +88,7 @@ var Vpn = class Vpn { setSettingsFromNord() { const standardOut = this._executeCommand(CMD_FETCH_SETTINGS); - const normalizedOut = this._getString(standardOut); - - for (const line of normalizedOut.split(`\n`)) { + for (const line of standardOut.split(`\n`)) { let parts = line.split(`:`); const settingName = this._resolveSettingsKey(parts[0]); const settingValue = this._resolveSettingsValue(parts[1]); @@ -130,7 +127,7 @@ var Vpn = class Vpn { getAccount() { // Read the VPN status from the command line const standardOut = this._executeCommand(CMD_VPNACCOUNT); - const allAccountMessages = this._getString(standardOut).split(`\n`); + const allAccountMessages = standardOut.split(`\n`); let emailAddress; let vpnService; @@ -144,13 +141,13 @@ var Vpn = class Vpn { checkLogin() { const standardOut = this._executeCommand(CMD_LOGIN); - return this._getString(standardOut).replace(/\s+/g, ` `).includes('You are already logged in.'); + return standardOut.replace(/\s+/g, ` `).includes('You are already logged in.'); } getStatus() { const standardOut = this._executeCommand(CMD_VPNSTATUS); - const allStatusMessages = this._getString(standardOut).split(`\n`); + const allStatusMessages = standardOut.split(`\n`); let connectStatus, updateMessage, country, serverNumber, city, serverIp, currentTech, currentProtocol, transfer, uptime, currentServer; @@ -207,7 +204,7 @@ var Vpn = class Vpn { const standardOut = this._executeCommand(CMD_LOGIN); const ref = "Continue in the browser: "; - let url = this._getString(standardOut).replace(/\s+/g, ` `); + let url = standardOut.replace(/\s+/g, ` `); url = url.substring(url.indexOf(ref) + ref.length).trim(); Gio.app_info_launch_default_for_uri(url, null); @@ -248,7 +245,7 @@ var Vpn = class Vpn { } const standardOut = this._executeCommand(CMD_COUNTRIES); - const countries = this._processCityCountryOutput(this._getString(standardOut)); + const countries = this._processCityCountryOutput(standardOut); let processedCountries = {}; for (let country of countries) { @@ -270,7 +267,7 @@ var Vpn = class Vpn { for (let i = 0; i < citiesSaved.length; i++) { const standardOut = this._executeCommand(`${CMD_CITIES} ${citiesSaved[i]}`); - const cities = this._processCityCountryOutput(this._getString(standardOut)); + const cities = this._processCityCountryOutput(standardOut); for (let j = 0; j < cities.length; j++) { if (j > citiesMax) break; From fb1bde7754f9c9cec3d55517354eaec774b75a22 Mon Sep 17 00:00:00 2001 From: isopolito Date: Sun, 4 Dec 2022 13:57:21 -0600 Subject: [PATCH 6/6] Check soup version --- metadata.json | 2 +- modules/Vpn.js | 31 ++++++++++++++++++------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/metadata.json b/metadata.json index 537eb8e..0ea0db0 100644 --- a/metadata.json +++ b/metadata.json @@ -9,5 +9,5 @@ ], "url": "https://github.com/Isopolito/gNordVPN-Local", "uuid": "gnordvpn-local@isopolito", - "version": 14 + "version": 15 } diff --git a/modules/Vpn.js b/modules/Vpn.js index f70d9ba..3ac5daf 100644 --- a/modules/Vpn.js +++ b/modules/Vpn.js @@ -2,11 +2,7 @@ const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const ExtensionUtils = imports.misc.extensionUtils; - -// Force version 2.x to avoid compatibility issues with certain distros that are using Soup 3.x by default -imports.gi.versions.Soup = "2.4"; const Soup = imports.gi.Soup; - const CMD_VPNSTATUS = `nordvpn status`; const CMD_VPNACCOUNT = `nordvpn account`; const CMD_COUNTRIES = `nordvpn countries`; @@ -23,10 +19,23 @@ var Vpn = class Vpn { this.executeCommandSync = GLib.spawn_command_line_sync; this.executeCommandAsync = GLib.spawn_command_line_async; this.settings = ExtensionUtils.getSettings(`org.gnome.shell.extensions.gnordvpn-local`); - this.session = Soup.Session.new(); + this.soupVersion = Soup.get_major_version(); } + _httpGet = (url) => { + const msg = Soup.Message.new("GET", url); + switch (this.soupVersion) { + case 2: + this.session.send_message(msg); + break; + default: + this.session.send(msg, null); + break; + } + return JSON.parse(this._getString(msg.response_body_data.get_data())); + } + // Remove the junk that shows up from messages in the nordvpn output _processCityCountryOutput = (input) => { const match = input.match(/(^\w+?,\s(\w+?,\s)+?(\w+?$)|^\s*?\w+?\s*?$)/gm); @@ -228,11 +237,9 @@ var Vpn = class Vpn { getCountries(withId = false) { if (withId) { - this.message = Soup.Message.new("GET", "https://api.nordvpn.com/v1/servers/countries"); - this.session.send_message(this.message); - let countrieNames, countrieMap; + let countrieMap; try { - let data = JSON.parse(this.message.response_body_data.get_data()); + let data = this._httpGet("https://api.nordvpn.com/v1/servers/countries"); countrieMap = data.reduce((acc, v) => { acc[v['name']] = v['id']; return acc; @@ -310,10 +317,8 @@ var Vpn = class Vpn { let servers = {} try { for (let i = 0; i < countriesSaved.length; i++) { - this.message = Soup.Message.new("GET", url + "&filters[country_id]=" + countriesSaved[i]); - this.session.send_message(this.message); - let data = this.message.response_body_data.get_data(); - JSON.parse(this._getString(data)).forEach(e => { + let data = this._httpGet(url + "&filters[country_id]=" + countriesSaved[i]); + data.forEach(e => { servers[e['name']] = e['hostname'].replace('.nordvpn.com', ''); }); }