Commit bc99acb3 authored by Omar Chehab's avatar Omar Chehab

Add port-scan loading progress indicator

parent cd5bac66
......@@ -267,6 +267,9 @@
<li id="fetch-namespaces-toggl-workspaces">
Toggl Workspaces
</li>
<li id="fetch-namespaces-manager-app" style="display: none;">
Manager Desktop Edition <span id="fetch-namespaces-manager-app-progress"></span>%
</li>
<li id="fetch-namespaces-manager-businesses">
Manager Businesses
</li>
......
......@@ -12,6 +12,8 @@ const credentialsSubmit = document.getElementById('credentials-submit');
const fetchNamespacesTab = document.getElementById('fetch-namespaces');
const fetchNamespacesTogglWorkspaces = document.getElementById('fetch-namespaces-toggl-workspaces');
const fetchNamespacesManagerApp = document.getElementById('fetch-namespaces-manager-app');
const fetchNamespacesManagerAppProgress = document.getElementById('fetch-namespaces-manager-app-progress');
const fetchNamespacesManagerBusinesses = document.getElementById('fetch-namespaces-manager-businesses');
const fetchNamespacesSubmit = document.getElementById('fetch-namespaces-submit');
const fetchNamespacesError = document.getElementById('fetch-namespaces-error');
......@@ -91,6 +93,8 @@ credentialsTab.addEventListener('submit', async function(event) {
managerUsername = managerUsernameField.value;
managerPassword = managerPasswordField.value;
fetchNamespacesTogglWorkspaces.className = 'text-warning';
fetchNamespacesManagerApp.style.display = 'none';
fetchNamespacesManagerApp.className = 'text-warning';
fetchNamespacesManagerBusinesses.className = 'text-warning';
fetchNamespacesSubmit.innerText = 'Stop';
fetchNamespacesError.innerText = '';
......@@ -121,6 +125,8 @@ credentialsTab.addEventListener('submit', async function(event) {
if (!managerUrl) {
console.log('Port Scanning for Manager Desktop Edition');
fetchNamespacesManagerApp.style.display = '';
fetchNamespacesManagerAppProgress.innerText = '0';
const workers = [];
function stopAllWorkers() {
......@@ -131,25 +137,34 @@ credentialsTab.addEventListener('submit', async function(event) {
const portsToScanPerWorker = Math.floor(15535 / navigator.hardwareConcurrency);
try {
managerUrl = await new Promise((resolve) => {
managerUrl = await new Promise((resolve, reject) => {
const workerProgress = Array.from(Array(navigator.hardwareConcurrency)).map((_) => 0);
let finishedWorkers = 0;
let targetUrl;
function handlePortScanResponse(event) {
function handlePortScanResponse(workerIndex, event) {
if (event.type === 'message') {
console.log('Message from worker:', ...event.data);
const [ success, port ] = event.data;
finishedWorkers++;
if (success) {
targetUrl = `http://127.0.0.1:${port}`;
}
const type = event.data[0];
if (type === 'progress') {
const [ _, progress ] = event.data;
workerProgress[workerIndex] = progress;
fetchNamespacesManagerAppProgress.innerText = Math.round(100 * workerProgress
.reduce((t, p, a) => t + (p / workerProgress.length), 0))
} else if (type === 'finish') {
const [ _, success, port ] = event.data;
finishedWorkers++;
if (success) {
fetchNamespacesManagerAppProgress.innerText = '100';
targetUrl = `http://127.0.0.1:${port}`;
}
if (success || finishedWorkers === workers.length) {
stopAllWorkers();
if (targetUrl) {
resolve(targetUrl);
} else {
if (success || finishedWorkers === workers.length) {
stopAllWorkers();
if (targetUrl) {
resolve(targetUrl);
} else {
reject(new Error('Scanned ports 50000 to 65535, Manager app was not found.'));
}
}
......@@ -159,7 +174,7 @@ credentialsTab.addEventListener('submit', async function(event) {
for (let i = 0; i < navigator.hardwareConcurrency; i++) {
const worker = new Worker(chrome.runtime.getURL('portscan.js'));
worker.onmessage = handlePortScanResponse
worker.onmessage = handlePortScanResponse.bind(null, i);
const startPort = 50000 + i * portsToScanPerWorker;
const endPort = i < navigator.hardwareConcurrency - 1
? 50000 - 1 + (i + 1) * portsToScanPerWorker
......@@ -168,8 +183,11 @@ credentialsTab.addEventListener('submit', async function(event) {
workers.push(worker);
}
});
fetchNamespacesManagerApp.className = 'text-success';
fetchNamespacesManagerAppProgress.innerText = '100';
console.log('Manager Port Scanning: OK');
} catch (err) {
fetchNamespacesManagerApp.className = 'text-danger';
fetchNamespacesManagerBusinesses.className = 'text-danger';
console.log('Manager Port Scanning: NOT OK');
console.error(err);
......
......@@ -11,21 +11,27 @@ self.onmessage = async function(event) {
},
});
return res.ok &&
res.headers.get('Content-Type') === 'application/json' &&
port;
res.headers.get('Content-Type') === 'application/json';
} catch (err) {
return false;
}
}
const portScanResponses = (await Promise.all(
Array.from(Array(endPort - startPort + 1))
.map((_, i) => i + startPort)
.map(scanFn)
)).map(port => port ? port : false)
const ports = portScanResponses.filter(port => port !== false);
const ports = [];
for (let port = startPort; port <= endPort; port++) {
const progress = (port - startPort) / (endPort - startPort);
self.postMessage([ 'progress', progress ]);
if (await scanFn(port)) {
ports.push(port);
break;
}
}
const success = ports.length > 0;
const port = ports[0];
self.postMessage([ success, port ]);
self.postMessage([ 'finish', success, port ]);
}
};
\ No newline at end of file
};
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment