From 14fe263e07b9b102327617b3bf67a7e4afeadddb Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Fri, 16 Sep 2022 11:28:01 +0200 Subject: [PATCH 1/8] feat: Support Wifi with hidden SSID on Windows Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 113 +++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index 11e80c1..8c1dddd 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -23,58 +23,64 @@ function execCommand(cmd, params) { } function connectToWifi(config, ap, callback) { - scan(config)() - .then(networks => { - const selectedAp = networks.find(network => { + let selectedAp = null; + let profile; + if (ap.hiddenWifi) { + selectedAp = { + ssid: ap.ssid, + security: ['WPA2'], + }; + + profile = Promise.resolve(selectedAp); + } else { + profile = scan(config)().then(networks => { + selectedAp = networks.find(network => { return network.ssid === ap.ssid; }); + }); + } - if (selectedAp === undefined) { - throw 'SSID not found'; - } + if (selectedAp === undefined) { + throw 'SSID not found'; + } + fs.writeFileSync( + profileFilename, + win32WirelessProfileBuilder(selectedAp, ap.password, ap.hiddenWifi), + ); - fs.writeFileSync( - profileFilename, - win32WirelessProfileBuilder(selectedAp, ap.password) - ); - }) - .then(() => { - return execCommand('netsh', [ - 'wlan', - 'add', - 'profile', - `filename=${profileFilename}` - ]); - }) - .then(() => { - const cmd = 'netsh'; - const params = [ - 'wlan', - 'connect', - `ssid="${ap.ssid}"`, - `name="${ap.ssid}"` - ]; - if (config.iface) { - params.push(`interface="${config.iface}"`); - } - return execCommand(cmd, params); - }) - .then(() => { - return execCommand(`del ${profileFilename}`); - }) - .then(() => { - callback && callback(); - }) - .catch(err => { - execFile( + profile.then(() => { + return execCommand('netsh', [ + 'wlan', + 'add', + 'profile', + `filename=${profileFilename}`, + ]); + }).then(() => { + const cmd = 'netsh'; + const params = [ + 'wlan', + 'connect', + `ssid="${ap.ssid}"`, + `name="${ap.ssid}"`, + ]; + if (config.iface) { + params.push(`interface="${config.iface}"`); + } + return execCommand(cmd, params); + }).then(() => { + return execCommand(`del ${profileFilename}`); + }).then(() => { + callback && callback(); + }).catch(err => { + execFile( 'netsh', ['wlan', 'delete', `profile "${ap.ssid}"`], - { env }, + {env}, () => { callback && callback(err); } - ); - }); + ); + }); } function getHexSsid(plainTextSsid) { @@ -93,12 +99,21 @@ function getHexSsid(plainTextSsid) { return hex; } -function win32WirelessProfileBuilder(selectedAp, key) { - let profile_content = ` ${ - selectedAp.ssid - } ${getHexSsid( - selectedAp.ssid - )} ${selectedAp.ssid} `; +function win32WirelessProfileBuilder(selectedAp, key, hiddenWifi = false) { + let profile_content = ` + + ${ selectedAp.ssid } + + + + ${getHexSsid(selectedAp.ssid,)} + + ${selectedAp.ssid} + + + ${hiddenWifi ?'true' : 'false'} + + `; if (selectedAp.security.includes('WPA2')) { profile_content += `ESS auto true WPA2PSK AES false passPhrase false ${key} `; From f2750d9dd971629ee7bdba9c170a61681f58fd56 Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Fri, 16 Sep 2022 12:04:29 +0200 Subject: [PATCH 2/8] feat: Fix profile xml formatting Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index 8c1dddd..a6fb9a3 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -100,20 +100,13 @@ function getHexSsid(plainTextSsid) { } function win32WirelessProfileBuilder(selectedAp, key, hiddenWifi = false) { - let profile_content = ` - - ${ selectedAp.ssid } - - - - ${getHexSsid(selectedAp.ssid,)} - - ${selectedAp.ssid} - - - ${hiddenWifi ?'true' : 'false'} - - `; + let profile_content = ` ${ + selectedAp.ssid + } ${getHexSsid( + selectedAp.ssid + )} ${selectedAp.ssid} ${ + hiddenWifi ? 'true' : '' + } `; if (selectedAp.security.includes('WPA2')) { profile_content += `ESS auto true WPA2PSK AES false passPhrase false ${key} `; From 4c300d3f0bcf01e0f4cda4e45b3fd7dfa495ef03 Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Fri, 16 Sep 2022 12:05:10 +0200 Subject: [PATCH 3/8] feat: Write profile file async and continue to connect Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 84 ++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index a6fb9a3..f351cf5 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -28,7 +28,7 @@ function connectToWifi(config, ap, callback) { if (ap.hiddenWifi) { selectedAp = { ssid: ap.ssid, - security: ['WPA2'], + security: ['WPA2'] }; profile = Promise.resolve(selectedAp); @@ -44,43 +44,57 @@ function connectToWifi(config, ap, callback) { throw 'SSID not found'; } fs.writeFileSync( - profileFilename, - win32WirelessProfileBuilder(selectedAp, ap.password, ap.hiddenWifi), + profileFilename, + win32WirelessProfileBuilder(selectedAp, ap.password, ap.hiddenWifi) ); - profile.then(() => { - return execCommand('netsh', [ - 'wlan', - 'add', - 'profile', - `filename=${profileFilename}`, - ]); - }).then(() => { - const cmd = 'netsh'; - const params = [ - 'wlan', - 'connect', - `ssid="${ap.ssid}"`, - `name="${ap.ssid}"`, - ]; - if (config.iface) { - params.push(`interface="${config.iface}"`); + fs.writeFile( + profileFilename, + win32WirelessProfileBuilder(selectedAp, ap.password, ap.hiddenWifi), + err => { + if (err) { + return Promise.reject(err); + } + profile + .then(() => { + return execCommand('netsh', [ + 'wlan', + 'add', + 'profile', + `filename=${profileFilename}` + ]); + }) + .then(() => { + const cmd = 'netsh'; + const params = [ + 'wlan', + 'connect', + `ssid="${ap.ssid}"`, + `name="${ap.ssid}"` + ]; + if (config.iface) { + params.push(`interface="${config.iface}"`); + } + return execCommand(cmd, params); + }) + .then(() => { + return execCommand(`del ${profileFilename}`); + }) + .then(() => { + callback && callback(); + }) + .catch(err => { + execFile( + 'netsh', + ['wlan', 'delete', `profile "${ap.ssid}"`], + { env }, + () => { + callback && callback(err); + } + ); + }); } - return execCommand(cmd, params); - }).then(() => { - return execCommand(`del ${profileFilename}`); - }).then(() => { - callback && callback(); - }).catch(err => { - execFile( - 'netsh', - ['wlan', 'delete', `profile "${ap.ssid}"`], - {env}, - () => { - callback && callback(err); - } - ); - }); + ); } function getHexSsid(plainTextSsid) { From bf9e01ce5bf3e09322524299ae7a4826dbf04bdb Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Fri, 16 Sep 2022 12:10:01 +0200 Subject: [PATCH 4/8] feat: Remove sync file writing Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index f351cf5..bbc3de8 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -43,10 +43,6 @@ function connectToWifi(config, ap, callback) { if (selectedAp === undefined) { throw 'SSID not found'; } - fs.writeFileSync( - profileFilename, - win32WirelessProfileBuilder(selectedAp, ap.password, ap.hiddenWifi) - ); fs.writeFile( profileFilename, From f9179f3317b1f303505f4761a4e8ff053f10ae33 Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Mon, 19 Sep 2022 08:15:24 +0200 Subject: [PATCH 5/8] fix: Rename parameter Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index bbc3de8..c5cc01f 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -25,7 +25,7 @@ function execCommand(cmd, params) { function connectToWifi(config, ap, callback) { let selectedAp = null; let profile; - if (ap.hiddenWifi) { + if (ap.isHidden) { selectedAp = { ssid: ap.ssid, security: ['WPA2'] @@ -46,7 +46,7 @@ function connectToWifi(config, ap, callback) { fs.writeFile( profileFilename, - win32WirelessProfileBuilder(selectedAp, ap.password, ap.hiddenWifi), + win32WirelessProfileBuilder(selectedAp, ap.password, ap.isHidden), err => { if (err) { return Promise.reject(err); @@ -109,13 +109,13 @@ function getHexSsid(plainTextSsid) { return hex; } -function win32WirelessProfileBuilder(selectedAp, key, hiddenWifi = false) { +function win32WirelessProfileBuilder(selectedAp, key, isHidden = false) { let profile_content = ` ${ selectedAp.ssid } ${getHexSsid( selectedAp.ssid )} ${selectedAp.ssid} ${ - hiddenWifi ? 'true' : '' + isHidden ? 'true' : '' } `; if (selectedAp.security.includes('WPA2')) { From a7cc8186f438a15fd5169589b8172e1dce39f4f2 Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Mon, 19 Sep 2022 10:57:09 +0200 Subject: [PATCH 6/8] fix: Form promise also from hidden network Visible networks caused problems since the promise of the last wifi scan got not resolved. Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 99 ++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index c5cc01f..4ff0ca1 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -30,8 +30,7 @@ function connectToWifi(config, ap, callback) { ssid: ap.ssid, security: ['WPA2'] }; - - profile = Promise.resolve(selectedAp); + profile = new Promise(resolve => resolve(selectedAp)); } else { profile = scan(config)().then(networks => { selectedAp = networks.find(network => { @@ -40,57 +39,53 @@ function connectToWifi(config, ap, callback) { }); } - if (selectedAp === undefined) { - throw 'SSID not found'; - } - - fs.writeFile( - profileFilename, - win32WirelessProfileBuilder(selectedAp, ap.password, ap.isHidden), - err => { - if (err) { - return Promise.reject(err); - } - profile - .then(() => { - return execCommand('netsh', [ - 'wlan', - 'add', - 'profile', - `filename=${profileFilename}` - ]); - }) - .then(() => { - const cmd = 'netsh'; - const params = [ - 'wlan', - 'connect', - `ssid="${ap.ssid}"`, - `name="${ap.ssid}"` - ]; - if (config.iface) { - params.push(`interface="${config.iface}"`); - } - return execCommand(cmd, params); - }) - .then(() => { - return execCommand(`del ${profileFilename}`); - }) - .then(() => { - callback && callback(); - }) - .catch(err => { - execFile( - 'netsh', - ['wlan', 'delete', `profile "${ap.ssid}"`], - { env }, - () => { - callback && callback(err); - } - ); - }); + profile.then(err => { + if (err) { + return Promise.reject(err); + } + if (selectedAp === undefined) { + return Promise.reject('SSID not found'); } - ); + fs.writeFileSync( + profileFilename, + win32WirelessProfileBuilder(selectedAp, ap.password, ap.isHidden) + ); + return execCommand('netsh', [ + 'wlan', + 'add', + 'profile', + `filename=${profileFilename}` + ]) + .then(() => { + const cmd = 'netsh'; + const params = [ + 'wlan', + 'connect', + `ssid="${ap.ssid}"`, + `name="${ap.ssid}"` + ]; + if (config.iface) { + params.push(`interface="${config.iface}"`); + } + return execCommand(cmd, params); + }) + .then(() => { + return execCommand(`del ${profileFilename}`); + }) + .then(() => { + callback && callback(); + }) + .catch(err => { + execFile( + 'netsh', + ['wlan', 'delete', `profile "${ap.ssid}"`], + { env }, + () => { + callback && callback(err); + } + ); + }); + }); } function getHexSsid(plainTextSsid) { From f0772368e9daec5c41b89d616d138f85fcd376ee Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Tue, 20 Sep 2022 09:07:28 +0200 Subject: [PATCH 7/8] fix: Wifi selection Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 101 +++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index 4ff0ca1..9b36b5d 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -22,70 +22,71 @@ function execCommand(cmd, params) { }); } -function connectToWifi(config, ap, callback) { +function connectToWifi(config, givenAP, callback) { let selectedAp = null; let profile; - if (ap.isHidden) { + if (givenAP.isHidden) { selectedAp = { - ssid: ap.ssid, + ssid: givenAP.ssid, security: ['WPA2'] }; profile = new Promise(resolve => resolve(selectedAp)); } else { profile = scan(config)().then(networks => { selectedAp = networks.find(network => { - return network.ssid === ap.ssid; + return network.ssid === givenAP.ssid; }); + return Promise.resolve(selectedAp); }); } - profile.then(err => { - if (err) { - return Promise.reject(err); - } - if (selectedAp === undefined) { - return Promise.reject('SSID not found'); - } - fs.writeFileSync( - profileFilename, - win32WirelessProfileBuilder(selectedAp, ap.password, ap.isHidden) - ); - return execCommand('netsh', [ - 'wlan', - 'add', - 'profile', - `filename=${profileFilename}` - ]) - .then(() => { - const cmd = 'netsh'; - const params = [ - 'wlan', - 'connect', - `ssid="${ap.ssid}"`, - `name="${ap.ssid}"` - ]; - if (config.iface) { - params.push(`interface="${config.iface}"`); - } - return execCommand(cmd, params); - }) - .then(() => { - return execCommand(`del ${profileFilename}`); - }) - .then(() => { - callback && callback(); - }) - .catch(err => { - execFile( - 'netsh', - ['wlan', 'delete', `profile "${ap.ssid}"`], - { env }, - () => { - callback && callback(err); + profile + .then(resolvedAP => { + if (resolvedAP == null) { + return Promise.reject('SSID not found'); + } + + fs.writeFileSync( + profileFilename, + win32WirelessProfileBuilder( + resolvedAP, + givenAP.password, + givenAP.isHidden + ) + ); + return execCommand('netsh', [ + 'wlan', + 'add', + 'profile', + `filename=${profileFilename}` + ]) + .then(() => { + const cmd = 'netsh'; + const params = [ + 'wlan', + 'connect', + `ssid="${givenAP.ssid}"`, + `name="${givenAP.ssid}"` + ]; + if (config.iface) { + params.push(`interface="${config.iface}"`); } - ); - }); - }); + return execCommand(cmd, params); + }) + .then(() => execCommand(`del ${profileFilename}`)) + .then(() => callback && callback()) + .catch(err => { + execFile( + 'netsh', + ['wlan', 'delete', `profile "${givenAP.ssid}"`], + { env }, + () => { + callback && callback(err); + } + ); + }); + }) + .catch(e => Promise.reject(e)); } function getHexSsid(plainTextSsid) { From e1560c38d8f0362eb87f4cb03121c30b4ce1ce8b Mon Sep 17 00:00:00 2001 From: Max Hellwig Date: Tue, 20 Sep 2022 09:57:06 +0200 Subject: [PATCH 8/8] fix: Handle profile writing using a Promise to sync file write operation Related to #22 https://github.com/friedrith/node-wifi/issues/22 --- src/windows-connect.js | 65 ++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/windows-connect.js b/src/windows-connect.js index 9b36b5d..b321498 100644 --- a/src/windows-connect.js +++ b/src/windows-connect.js @@ -1,4 +1,4 @@ -const fs = require('fs'); +const fs = require('fs').promises; const execFile = require('child_process').execFile; const env = require('./env'); const scan = require('./windows-scan'); @@ -46,45 +46,48 @@ function connectToWifi(config, givenAP, callback) { return Promise.reject('SSID not found'); } - fs.writeFileSync( + fs.writeFile( profileFilename, win32WirelessProfileBuilder( resolvedAP, givenAP.password, givenAP.isHidden ) - ); - return execCommand('netsh', [ - 'wlan', - 'add', - 'profile', - `filename=${profileFilename}` - ]) + ) .then(() => { - const cmd = 'netsh'; - const params = [ + return execCommand('netsh', [ 'wlan', - 'connect', - `ssid="${givenAP.ssid}"`, - `name="${givenAP.ssid}"` - ]; - if (config.iface) { - params.push(`interface="${config.iface}"`); - } - return execCommand(cmd, params); + 'add', + 'profile', + `filename=${profileFilename}` + ]) + .then(() => { + const cmd = 'netsh'; + const params = [ + 'wlan', + 'connect', + `ssid="${givenAP.ssid}"`, + `name="${givenAP.ssid}"` + ]; + if (config.iface) { + params.push(`interface="${config.iface}"`); + } + return execCommand(cmd, params); + }) + .then(() => execCommand(`del ${profileFilename}`)) + .then(() => callback && callback()) + .catch(err => { + execFile( + 'netsh', + ['wlan', 'delete', `profile "${givenAP.ssid}"`], + { env }, + () => { + callback && callback(err); + } + ); + }); }) - .then(() => execCommand(`del ${profileFilename}`)) - .then(() => callback && callback()) - .catch(err => { - execFile( - 'netsh', - ['wlan', 'delete', `profile "${givenAP.ssid}"`], - { env }, - () => { - callback && callback(err); - } - ); - }); + .catch(e => Promise.reject(e)); }) .catch(e => Promise.reject(e)); }