Last commit july 5th

This commit is contained in:
2024-07-05 13:46:23 +02:00
parent dad0d86e8c
commit b0e4dfbb76
24982 changed files with 2621219 additions and 413 deletions

222
spa/node_modules/systeminformation/lib/audio.js generated vendored Normal file
View File

@@ -0,0 +1,222 @@
'use strict';
// @ts-check
// ==================================================================================
// audio.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 16. audio
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function parseAudioType(str, input, output) {
str = str.toLowerCase();
let result = '';
if (str.indexOf('input') >= 0) { result = 'Microphone'; }
if (str.indexOf('display audio') >= 0) { result = 'Speaker'; }
if (str.indexOf('speak') >= 0) { result = 'Speaker'; }
if (str.indexOf('laut') >= 0) { result = 'Speaker'; }
if (str.indexOf('loud') >= 0) { result = 'Speaker'; }
if (str.indexOf('head') >= 0) { result = 'Headset'; }
if (str.indexOf('mic') >= 0) { result = 'Microphone'; }
if (str.indexOf('mikr') >= 0) { result = 'Microphone'; }
if (str.indexOf('phone') >= 0) { result = 'Phone'; }
if (str.indexOf('controll') >= 0) { result = 'Controller'; }
if (str.indexOf('line o') >= 0) { result = 'Line Out'; }
if (str.indexOf('digital o') >= 0) { result = 'Digital Out'; }
if (str.indexOf('smart sound technology') >= 0) { result = 'Digital Signal Processor'; }
if (str.indexOf('high definition audio') >= 0) { result = 'Sound Driver'; }
if (!result && output) {
result = 'Speaker';
} else if (!result && input) {
result = 'Microphone';
}
return result;
}
function getLinuxAudioPci() {
let cmd = 'lspci -v 2>/dev/null';
let result = [];
try {
const parts = execSync(cmd).toString().split('\n\n');
parts.forEach(element => {
const lines = element.split('\n');
if (lines && lines.length && lines[0].toLowerCase().indexOf('audio') >= 0) {
const audio = {};
audio.slotId = lines[0].split(' ')[0];
audio.driver = util.getValue(lines, 'Kernel driver in use', ':', true) || util.getValue(lines, 'Kernel modules', ':', true);
result.push(audio);
}
});
return result;
} catch (e) {
return result;
}
}
function parseLinuxAudioPciMM(lines, audioPCI) {
const result = {};
const slotId = util.getValue(lines, 'Slot');
const pciMatch = audioPCI.filter(function (item) { return item.slotId === slotId; });
result.id = slotId;
result.name = util.getValue(lines, 'SDevice');
result.manufacturer = util.getValue(lines, 'SVendor');
result.revision = util.getValue(lines, 'Rev');
result.driver = pciMatch && pciMatch.length === 1 && pciMatch[0].driver ? pciMatch[0].driver : '';
result.default = null;
result.channel = 'PCIe';
result.type = parseAudioType(result.name, null, null);
result.in = null;
result.out = null;
result.status = 'online';
return result;
}
function parseDarwinChannel(str) {
let result = '';
if (str.indexOf('builtin') >= 0) { result = 'Built-In'; }
if (str.indexOf('extern') >= 0) { result = 'Audio-Jack'; }
if (str.indexOf('hdmi') >= 0) { result = 'HDMI'; }
if (str.indexOf('displayport') >= 0) { result = 'Display-Port'; }
if (str.indexOf('usb') >= 0) { result = 'USB'; }
if (str.indexOf('pci') >= 0) { result = 'PCIe'; }
return result;
}
function parseDarwinAudio(audioObject, id) {
const result = {};
const channelStr = ((audioObject.coreaudio_device_transport || '') + ' ' + (audioObject._name || '')).toLowerCase();
result.id = id;
result.name = audioObject._name;
result.manufacturer = audioObject.coreaudio_device_manufacturer;
result.revision = null;
result.driver = null;
result.default = !!(audioObject.coreaudio_default_audio_input_device || '') || !!(audioObject.coreaudio_default_audio_output_device || '');
result.channel = parseDarwinChannel(channelStr);
result.type = parseAudioType(result.name, !!(audioObject.coreaudio_device_input || ''), !!(audioObject.coreaudio_device_output || ''));
result.in = !!(audioObject.coreaudio_device_input || '');
result.out = !!(audioObject.coreaudio_device_output || '');
result.status = 'online';
return result;
}
function parseWindowsAudio(lines) {
const result = {};
const status = util.getValue(lines, 'StatusInfo', ':');
result.id = util.getValue(lines, 'DeviceID', ':'); // PNPDeviceID??
result.name = util.getValue(lines, 'name', ':');
result.manufacturer = util.getValue(lines, 'manufacturer', ':');
result.revision = null;
result.driver = null;
result.default = null;
result.channel = null;
result.type = parseAudioType(result.name, null, null);
result.in = null;
result.out = null;
result.status = status;
return result;
}
function audio(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
if (_linux || _freebsd || _openbsd || _netbsd) {
let cmd = 'lspci -vmm 2>/dev/null';
exec(cmd, function (error, stdout) {
// PCI
if (!error) {
const audioPCI = getLinuxAudioPci();
const parts = stdout.toString().split('\n\n');
parts.forEach(element => {
const lines = element.split('\n');
if (util.getValue(lines, 'class', ':', true).toLowerCase().indexOf('audio') >= 0) {
const audio = parseLinuxAudioPciMM(lines, audioPCI);
result.push(audio);
}
});
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_darwin) {
let cmd = 'system_profiler SPAudioDataType -json';
exec(cmd, function (error, stdout) {
if (!error) {
try {
const outObj = JSON.parse(stdout.toString());
if (outObj.SPAudioDataType && outObj.SPAudioDataType.length && outObj.SPAudioDataType[0] && outObj.SPAudioDataType[0]['_items'] && outObj.SPAudioDataType[0]['_items'].length) {
for (let i = 0; i < outObj.SPAudioDataType[0]['_items'].length; i++) {
const audio = parseDarwinAudio(outObj.SPAudioDataType[0]['_items'][i], i);
result.push(audio);
}
}
} catch (e) {
util.noop();
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_windows) {
util.powerShell('Get-CimInstance Win32_SoundDevice | select DeviceID,StatusInfo,Name,Manufacturer | fl').then((stdout, error) => {
if (!error) {
const parts = stdout.toString().split(/\n\s*\n/);
parts.forEach(element => {
const lines = element.split('\n');
if (util.getValue(lines, 'name', ':')) {
result.push(parseWindowsAudio(lines));
}
});
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_sunos) {
resolve(null);
}
});
});
}
exports.audio = audio;

311
spa/node_modules/systeminformation/lib/battery.js generated vendored Normal file
View File

@@ -0,0 +1,311 @@
'use strict';
// @ts-check;
// ==================================================================================
// battery.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 6. Battery
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
const fs = require('fs');
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function parseWinBatteryPart(lines, designedCapacity, fullChargeCapacity) {
const result = {};
let status = util.getValue(lines, 'BatteryStatus', ':').trim();
// 1 = "Discharging"
// 2 = "On A/C"
// 3 = "Fully Charged"
// 4 = "Low"
// 5 = "Critical"
// 6 = "Charging"
// 7 = "Charging High"
// 8 = "Charging Low"
// 9 = "Charging Critical"
// 10 = "Undefined"
// 11 = "Partially Charged"
if (status >= 0) {
const statusValue = status ? parseInt(status) : 0;
result.status = statusValue;
result.hasBattery = true;
result.maxCapacity = fullChargeCapacity || parseInt(util.getValue(lines, 'DesignCapacity', ':') || 0);
result.designedCapacity = parseInt(util.getValue(lines, 'DesignCapacity', ':') || designedCapacity);
result.voltage = parseInt(util.getValue(lines, 'DesignVoltage', ':') || 0) / 1000.0;
result.capacityUnit = 'mWh';
result.percent = parseInt(util.getValue(lines, 'EstimatedChargeRemaining', ':') || 0);
result.currentCapacity = parseInt(result.maxCapacity * result.percent / 100);
result.isCharging = (statusValue >= 6 && statusValue <= 9) || statusValue === 11 || ((statusValue !== 3) && (statusValue !== 1) && result.percent < 100);
result.acConnected = result.isCharging || statusValue === 2;
result.model = util.getValue(lines, 'DeviceID', ':');
} else {
result.status = -1;
}
return result;
}
module.exports = function (callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
hasBattery: false,
cycleCount: 0,
isCharging: false,
designedCapacity: 0,
maxCapacity: 0,
currentCapacity: 0,
voltage: 0,
capacityUnit: '',
percent: 0,
timeRemaining: null,
acConnected: true,
type: '',
model: '',
manufacturer: '',
serial: ''
};
if (_linux) {
let battery_path = '';
if (fs.existsSync('/sys/class/power_supply/BAT1/uevent')) {
battery_path = '/sys/class/power_supply/BAT1/';
} else if (fs.existsSync('/sys/class/power_supply/BAT0/uevent')) {
battery_path = '/sys/class/power_supply/BAT0/';
}
let acConnected = false;
let acPath = '';
if (fs.existsSync('/sys/class/power_supply/AC/online')) {
acPath = '/sys/class/power_supply/AC/online';
} else if (fs.existsSync('/sys/class/power_supply/AC0/online')) {
acPath = '/sys/class/power_supply/AC0/online';
}
if (acPath) {
const file = fs.readFileSync(acPath);
acConnected = file.toString().trim() === '1';
}
if (battery_path) {
fs.readFile(battery_path + 'uevent', function (error, stdout) {
if (!error) {
let lines = stdout.toString().split('\n');
result.isCharging = (util.getValue(lines, 'POWER_SUPPLY_STATUS', '=').toLowerCase() === 'charging');
result.acConnected = acConnected || result.isCharging;
result.voltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_NOW', '='), 10) / 1000000.0;
result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
result.cycleCount = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CYCLE_COUNT', '='), 10);
result.maxCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL', '=', true, true), 10) / 1000.0 * (result.voltage || 1));
const desingedMinVoltage = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_VOLTAGE_MIN_DESIGN', '='), 10) / 1000000.0;
result.designedCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_FULL_DESIGN', '=', true, true), 10) / 1000.0 * (desingedMinVoltage || result.voltage || 1));
result.currentCapacity = Math.round(parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10) / 1000.0 * (result.voltage || 1));
if (!result.maxCapacity) {
result.maxCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL', '=', true, true), 10) / 1000.0;
result.designedCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_FULL_DESIGN', '=', true, true), 10) / 1000.0 | result.maxCapacity;
result.currentCapacity = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10) / 1000.0;
}
const percent = util.getValue(lines, 'POWER_SUPPLY_CAPACITY', '=');
const energy = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_ENERGY_NOW', '='), 10);
const power = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_POWER_NOW', '='), 10);
const current = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CURRENT_NOW', '='), 10);
const charge = parseInt('0' + util.getValue(lines, 'POWER_SUPPLY_CHARGE_NOW', '='), 10);
result.percent = parseInt('0' + percent, 10);
if (result.maxCapacity && result.currentCapacity) {
result.hasBattery = true;
if (!percent) {
result.percent = 100.0 * result.currentCapacity / result.maxCapacity;
}
}
if (result.isCharging) {
result.hasBattery = true;
}
if (energy && power) {
result.timeRemaining = Math.floor(energy / power * 60);
} else if (current && charge) {
result.timeRemaining = Math.floor(charge / current * 60);
} else if (current && result.currentCapacity) {
result.timeRemaining = Math.floor(result.currentCapacity / current * 60);
}
result.type = util.getValue(lines, 'POWER_SUPPLY_TECHNOLOGY', '=');
result.model = util.getValue(lines, 'POWER_SUPPLY_MODEL_NAME', '=');
result.manufacturer = util.getValue(lines, 'POWER_SUPPLY_MANUFACTURER', '=');
result.serial = util.getValue(lines, 'POWER_SUPPLY_SERIAL_NUMBER', '=');
if (callback) { callback(result); }
resolve(result);
} else {
if (callback) { callback(result); }
resolve(result);
}
});
} else {
if (callback) { callback(result); }
resolve(result);
}
}
if (_freebsd || _openbsd || _netbsd) {
exec('sysctl -i hw.acpi.battery hw.acpi.acline', function (error, stdout) {
let lines = stdout.toString().split('\n');
const batteries = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.units'), 10);
const percent = parseInt('0' + util.getValue(lines, 'hw.acpi.battery.life'), 10);
result.hasBattery = (batteries > 0);
result.cycleCount = null;
result.isCharging = util.getValue(lines, 'hw.acpi.acline') !== '1';
result.acConnected = result.isCharging;
result.maxCapacity = null;
result.currentCapacity = null;
result.capacityUnit = 'unknown';
result.percent = batteries ? percent : null;
if (callback) { callback(result); }
resolve(result);
});
}
if (_darwin) {
exec('ioreg -n AppleSmartBattery -r | egrep "CycleCount|IsCharging|DesignCapacity|MaxCapacity|CurrentCapacity|BatterySerialNumber|TimeRemaining|Voltage"; pmset -g batt | grep %', function (error, stdout) {
if (stdout) {
let lines = stdout.toString().replace(/ +/g, '').replace(/"+/g, '').replace(/-/g, '').split('\n');
result.cycleCount = parseInt('0' + util.getValue(lines, 'cyclecount', '='), 10);
result.voltage = parseInt('0' + util.getValue(lines, 'voltage', '='), 10) / 1000.0;
result.capacityUnit = result.voltage ? 'mWh' : 'mAh';
result.maxCapacity = Math.round(parseInt('0' + util.getValue(lines, 'applerawmaxcapacity', '='), 10) * (result.voltage || 1));
result.currentCapacity = Math.round(parseInt('0' + util.getValue(lines, 'applerawcurrentcapacity', '='), 10) * (result.voltage || 1));
result.designedCapacity = Math.round(parseInt('0' + util.getValue(lines, 'DesignCapacity', '='), 10) * (result.voltage || 1));
result.manufacturer = 'Apple';
result.serial = util.getValue(lines, 'BatterySerialNumber', '=');
let percent = null;
const line = util.getValue(lines, 'internal', 'Battery');
let parts = line.split(';');
if (parts && parts[0]) {
let parts2 = parts[0].split('\t');
if (parts2 && parts2[1]) {
percent = parseFloat(parts2[1].trim().replace(/%/g, ''));
}
}
if (parts && parts[1]) {
result.isCharging = (parts[1].trim() === 'charging');
result.acConnected = (parts[1].trim() !== 'discharging');
} else {
result.isCharging = util.getValue(lines, 'ischarging', '=').toLowerCase() === 'yes';
result.acConnected = result.isCharging;
}
if (result.maxCapacity && result.currentCapacity) {
result.hasBattery = true;
result.type = 'Li-ion';
result.percent = percent !== null ? percent : Math.round(100.0 * result.currentCapacity / result.maxCapacity);
if (!result.isCharging) {
result.timeRemaining = parseInt('0' + util.getValue(lines, 'TimeRemaining', '='), 10);
}
}
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
if (callback) { callback(result); }
resolve(result);
}
if (_windows) {
try {
const workload = [];
workload.push(util.powerShell('Get-CimInstance Win32_Battery | select BatteryStatus, DesignCapacity, DesignVoltage, EstimatedChargeRemaining, DeviceID | fl'));
workload.push(util.powerShell('(Get-WmiObject -Class BatteryStaticData -Namespace ROOT/WMI).DesignedCapacity'));
workload.push(util.powerShell('(Get-CimInstance -Class BatteryFullChargedCapacity -Namespace ROOT/WMI).FullChargedCapacity'));
util.promiseAll(
workload
).then((data) => {
if (data) {
let parts = data.results[0].split(/\n\s*\n/);
let batteries = [];
const hasValue = value => /\S/.test(value);
for (let i = 0; i < parts.length; i++) {
if (hasValue(parts[i]) && (!batteries.length || !hasValue(parts[i - 1]))) {
batteries.push([]);
}
if (hasValue(parts[i])) {
batteries[batteries.length - 1].push(parts[i]);
}
}
let designCapacities = data.results[1].split('\r\n').filter(e => e);
let fullChargeCapacities = data.results[2].split('\r\n').filter(e => e);
if (batteries.length) {
let first = false;
let additionalBatteries = [];
for (let i = 0; i < batteries.length; i++) {
let lines = batteries[i][0].split('\r\n');
const designedCapacity = designCapacities && designCapacities.length >= (i + 1) && designCapacities[i] ? util.toInt(designCapacities[i]) : 0;
const fullChargeCapacity = fullChargeCapacities && fullChargeCapacities.length >= (i + 1) && fullChargeCapacities[i] ? util.toInt(fullChargeCapacities[i]) : 0;
const parsed = parseWinBatteryPart(lines, designedCapacity, fullChargeCapacity);
if (!first && parsed.status > 0 && parsed.status !== 10) {
result.hasBattery = parsed.hasBattery;
result.maxCapacity = parsed.maxCapacity;
result.designedCapacity = parsed.designedCapacity;
result.voltage = parsed.voltage;
result.capacityUnit = parsed.capacityUnit;
result.percent = parsed.percent;
result.currentCapacity = parsed.currentCapacity;
result.isCharging = parsed.isCharging;
result.acConnected = parsed.acConnected;
result.model = parsed.model;
first = true;
} else if (parsed.status !== -1) {
additionalBatteries.push(
{
hasBattery: parsed.hasBattery,
maxCapacity: parsed.maxCapacity,
designedCapacity: parsed.designedCapacity,
voltage: parsed.voltage,
capacityUnit: parsed.capacityUnit,
percent: parsed.percent,
currentCapacity: parsed.currentCapacity,
isCharging: parsed.isCharging,
timeRemaining: null,
acConnected: parsed.acConnected,
model: parsed.model,
type: '',
manufacturer: '',
serial: ''
}
);
}
}
if (!first && additionalBatteries.length) {
result = additionalBatteries[0];
additionalBatteries.shift();
}
if (additionalBatteries.length) {
result.additionalBatteries = additionalBatteries;
}
}
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
};

231
spa/node_modules/systeminformation/lib/bluetooth.js generated vendored Normal file
View File

@@ -0,0 +1,231 @@
'use strict';
// @ts-check
// ==================================================================================
// audio.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 17. bluetooth
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const path = require('path');
const util = require('./util');
const fs = require('fs');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function parseBluetoothType(str) {
let result = '';
if (str.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
if (str.indexOf('mouse') >= 0) { result = 'Mouse'; }
if (str.indexOf('trackpad') >= 0) { result = 'Trackpad'; }
if (str.indexOf('speaker') >= 0) { result = 'Speaker'; }
if (str.indexOf('headset') >= 0) { result = 'Headset'; }
if (str.indexOf('phone') >= 0) { result = 'Phone'; }
if (str.indexOf('macbook') >= 0) { result = 'Computer'; }
if (str.indexOf('imac') >= 0) { result = 'Computer'; }
if (str.indexOf('ipad') >= 0) { result = 'Tablet'; }
if (str.indexOf('watch') >= 0) { result = 'Watch'; }
if (str.indexOf('headphone') >= 0) { result = 'Headset'; }
// to be continued ...
return result;
}
function parseBluetoothManufacturer(str) {
let result = str.split(' ')[0];
str = str.toLowerCase();
if (str.indexOf('apple') >= 0) { result = 'Apple'; }
if (str.indexOf('ipad') >= 0) { result = 'Apple'; }
if (str.indexOf('imac') >= 0) { result = 'Apple'; }
if (str.indexOf('iphone') >= 0) { result = 'Apple'; }
if (str.indexOf('magic mouse') >= 0) { result = 'Apple'; }
if (str.indexOf('magic track') >= 0) { result = 'Apple'; }
if (str.indexOf('macbook') >= 0) { result = 'Apple'; }
// to be continued ...
return result;
}
function parseLinuxBluetoothInfo(lines, macAddr1, macAddr2) {
const result = {};
result.device = null;
result.name = util.getValue(lines, 'name', '=');
result.manufacturer = null;
result.macDevice = macAddr1;
result.macHost = macAddr2;
result.batteryPercent = null;
result.type = parseBluetoothType(result.name.toLowerCase());
result.connected = false;
return result;
}
function parseDarwinBluetoothDevices(bluetoothObject, macAddr2) {
const result = {};
const typeStr = ((bluetoothObject.device_minorClassOfDevice_string || bluetoothObject.device_majorClassOfDevice_string || bluetoothObject.device_minorType || '') + (bluetoothObject.device_name || '')).toLowerCase();
result.device = bluetoothObject.device_services || '';
result.name = bluetoothObject.device_name || '';
result.manufacturer = bluetoothObject.device_manufacturer || parseBluetoothManufacturer(bluetoothObject.device_name || '') || '';
result.macDevice = (bluetoothObject.device_addr || bluetoothObject.device_address || '').toLowerCase().replace(/-/g, ':');
result.macHost = macAddr2;
result.batteryPercent = bluetoothObject.device_batteryPercent || null;
result.type = parseBluetoothType(typeStr);
result.connected = bluetoothObject.device_isconnected === 'attrib_Yes' || false;
return result;
}
function parseWindowsBluetooth(lines) {
const result = {};
result.device = null;
result.name = util.getValue(lines, 'name', ':');
result.manufacturer = util.getValue(lines, 'manufacturer', ':');
result.macDevice = null;
result.macHost = null;
result.batteryPercent = null;
result.type = parseBluetoothType(result.name.toLowerCase());
result.connected = null;
return result;
}
function bluetoothDevices(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
if (_linux) {
// get files in /var/lib/bluetooth/ recursive
const btFiles = util.getFilesInPath('/var/lib/bluetooth/');
btFiles.forEach((element) => {
const filename = path.basename(element);
const pathParts = element.split('/');
const macAddr1 = pathParts.length >= 6 ? pathParts[pathParts.length - 2] : null;
const macAddr2 = pathParts.length >= 7 ? pathParts[pathParts.length - 3] : null;
if (filename === 'info') {
const infoFile = fs.readFileSync(element, { encoding: 'utf8' }).split('\n');
result.push(parseLinuxBluetoothInfo(infoFile, macAddr1, macAddr2));
}
});
// determine "connected" with hcitool con
try {
const hdicon = execSync('hcitool con').toString().toLowerCase();
for (let i = 0; i < result.length; i++) {
if (result[i].macDevice && result[i].macDevice.length > 10 && hdicon.indexOf(result[i].macDevice.toLowerCase()) >= 0) {
result[i].connected = true;
}
}
} catch (e) {
util.noop();
}
if (callback) {
callback(result);
}
resolve(result);
}
if (_darwin) {
let cmd = 'system_profiler SPBluetoothDataType -json';
exec(cmd, function (error, stdout) {
if (!error) {
try {
const outObj = JSON.parse(stdout.toString());
if (outObj.SPBluetoothDataType && outObj.SPBluetoothDataType.length && outObj.SPBluetoothDataType[0] && outObj.SPBluetoothDataType[0]['device_title'] && outObj.SPBluetoothDataType[0]['device_title'].length) {
// missing: host BT Adapter macAddr ()
let macAddr2 = null;
if (outObj.SPBluetoothDataType[0]['local_device_title'] && outObj.SPBluetoothDataType[0].local_device_title.general_address) {
macAddr2 = outObj.SPBluetoothDataType[0].local_device_title.general_address.toLowerCase().replace(/-/g, ':');
}
outObj.SPBluetoothDataType[0]['device_title'].forEach((element) => {
const obj = element;
const objKey = Object.keys(obj);
if (objKey && objKey.length === 1) {
const innerObject = obj[objKey[0]];
innerObject.device_name = objKey[0];
const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
result.push(bluetoothDevice);
}
});
}
if (outObj.SPBluetoothDataType && outObj.SPBluetoothDataType.length && outObj.SPBluetoothDataType[0] && outObj.SPBluetoothDataType[0]['device_connected'] && outObj.SPBluetoothDataType[0]['device_connected'].length) {
const macAddr2 = outObj.SPBluetoothDataType[0].controller_properties && outObj.SPBluetoothDataType[0].controller_properties.controller_address ? outObj.SPBluetoothDataType[0].controller_properties.controller_address.toLowerCase().replace(/-/g, ':') : null;
outObj.SPBluetoothDataType[0]['device_connected'].forEach((element) => {
const obj = element;
const objKey = Object.keys(obj);
if (objKey && objKey.length === 1) {
const innerObject = obj[objKey[0]];
innerObject.device_name = objKey[0];
innerObject.device_isconnected = 'attrib_Yes';
const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
result.push(bluetoothDevice);
}
});
}
if (outObj.SPBluetoothDataType && outObj.SPBluetoothDataType.length && outObj.SPBluetoothDataType[0] && outObj.SPBluetoothDataType[0]['device_not_connected'] && outObj.SPBluetoothDataType[0]['device_not_connected'].length) {
const macAddr2 = outObj.SPBluetoothDataType[0].controller_properties && outObj.SPBluetoothDataType[0].controller_properties.controller_address ? outObj.SPBluetoothDataType[0].controller_properties.controller_address.toLowerCase().replace(/-/g, ':') : null;
outObj.SPBluetoothDataType[0]['device_not_connected'].forEach((element) => {
const obj = element;
const objKey = Object.keys(obj);
if (objKey && objKey.length === 1) {
const innerObject = obj[objKey[0]];
innerObject.device_name = objKey[0];
innerObject.device_isconnected = 'attrib_No';
const bluetoothDevice = parseDarwinBluetoothDevices(innerObject, macAddr2);
result.push(bluetoothDevice);
}
});
}
} catch (e) {
util.noop();
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_windows) {
util.powerShell('Get-CimInstance Win32_PNPEntity | select PNPClass, Name, Manufacturer | fl').then((stdout, error) => {
if (!error) {
const parts = stdout.toString().split(/\n\s*\n/);
parts.forEach((part) => {
if (util.getValue(part.split('\n'), 'PNPClass', ':') === 'Bluetooth') {
result.push(parseWindowsBluetooth(part.split('\n')));
}
});
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_freebsd || _netbsd || _openbsd || _sunos) {
resolve(null);
}
});
});
}
exports.bluetoothDevices = bluetoothDevices;

91
spa/node_modules/systeminformation/lib/cli.js generated vendored Executable file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/env node
'use strict';
// @ts-check
// ==================================================================================
// cli.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// ----------------------------------------------------------------------------------
// Dependencies
// ----------------------------------------------------------------------------------
const si = require('./index');
const lib_version = require('../package.json').version;
function capFirst(string) {
return string[0].toUpperCase() + string.slice(1);
}
function printLines(obj) {
for (const property in obj) {
console.log(capFirst(property) + ' '.substring(0, 17 - property.length) + ': ' + (obj[property] || ''));
}
console.log();
}
function info() {
console.log('┌─────────────────────────────────────────────────────────────────────────────────────────┐');
console.log('│ SYSTEMINFORMATION '.substring(0, 80 - lib_version.length) + 'Version: ' + lib_version + ' │');
console.log('└─────────────────────────────────────────────────────────────────────────────────────────┘');
si.osInfo().then(res => {
console.log();
console.log('Operating System:');
console.log('──────────────────────────────────────────────────────────────────────────────────────────');
delete res.serial;
delete res.servicepack;
delete res.logofile;
delete res.fqdn;
delete res.uefi;
printLines(res);
si.system().then(res => {
console.log('System:');
console.log('──────────────────────────────────────────────────────────────────────────────────────────');
delete res.serial;
delete res.uuid;
delete res.sku;
delete res.uuid;
printLines(res);
si.cpu().then(res => {
console.log('CPU:');
console.log('──────────────────────────────────────────────────────────────────────────────────────────');
delete res.cache;
delete res.governor;
delete res.flags;
delete res.virtualization;
delete res.revision;
delete res.voltage;
delete res.vendor;
delete res.speedMin;
delete res.speedMax;
printLines(res);
});
});
});
}
// ----------------------------------------------------------------------------------
// Main
// ----------------------------------------------------------------------------------
(function () {
const args = process.argv.slice(2);
if (args[0] === 'info') {
info();
} else {
si.getStaticData().then(
((data) => {
data.time = si.time();
console.log(JSON.stringify(data, null, 2));
}
));
}
})();

1834
spa/node_modules/systeminformation/lib/cpu.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

758
spa/node_modules/systeminformation/lib/docker.js generated vendored Normal file
View File

@@ -0,0 +1,758 @@
'use strict';
// @ts-check
// ==================================================================================
// docker.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 13. Docker
// ----------------------------------------------------------------------------------
const util = require('./util');
const DockerSocket = require('./dockerSocket');
let _platform = process.platform;
const _windows = (_platform === 'win32');
let _docker_container_stats = {};
let _docker_socket;
let _docker_last_read = 0;
// --------------------------
// get containers (parameter all: get also inactive/exited containers)
function dockerInfo(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
const result = {};
_docker_socket.getInfo((data) => {
result.id = data.ID;
result.containers = data.Containers;
result.containersRunning = data.ContainersRunning;
result.containersPaused = data.ContainersPaused;
result.containersStopped = data.ContainersStopped;
result.images = data.Images;
result.driver = data.Driver;
result.memoryLimit = data.MemoryLimit;
result.swapLimit = data.SwapLimit;
result.kernelMemory = data.KernelMemory;
result.cpuCfsPeriod = data.CpuCfsPeriod;
result.cpuCfsQuota = data.CpuCfsQuota;
result.cpuShares = data.CPUShares;
result.cpuSet = data.CPUSet;
result.ipv4Forwarding = data.IPv4Forwarding;
result.bridgeNfIptables = data.BridgeNfIptables;
result.bridgeNfIp6tables = data.BridgeNfIp6tables;
result.debug = data.Debug;
result.nfd = data.NFd;
result.oomKillDisable = data.OomKillDisable;
result.ngoroutines = data.NGoroutines;
result.systemTime = data.SystemTime;
result.loggingDriver = data.LoggingDriver;
result.cgroupDriver = data.CgroupDriver;
result.nEventsListener = data.NEventsListener;
result.kernelVersion = data.KernelVersion;
result.operatingSystem = data.OperatingSystem;
result.osType = data.OSType;
result.architecture = data.Architecture;
result.ncpu = data.NCPU;
result.memTotal = data.MemTotal;
result.dockerRootDir = data.DockerRootDir;
result.httpProxy = data.HttpProxy;
result.httpsProxy = data.HttpsProxy;
result.noProxy = data.NoProxy;
result.name = data.Name;
result.labels = data.Labels;
result.experimentalBuild = data.ExperimentalBuild;
result.serverVersion = data.ServerVersion;
result.clusterStore = data.ClusterStore;
result.clusterAdvertise = data.ClusterAdvertise;
result.defaultRuntime = data.DefaultRuntime;
result.liveRestoreEnabled = data.LiveRestoreEnabled;
result.isolation = data.Isolation;
result.initBinary = data.InitBinary;
result.productLicense = data.ProductLicense;
if (callback) { callback(result); }
resolve(result);
});
});
});
}
exports.dockerInfo = dockerInfo;
function dockerImages(all, callback) {
// fallback - if only callback is given
if (util.isFunction(all) && !callback) {
callback = all;
all = false;
}
if (typeof all === 'string' && all === 'true') {
all = true;
}
if (typeof all !== 'boolean' && all !== undefined) {
all = false;
}
all = all || false;
let result = [];
return new Promise((resolve) => {
process.nextTick(() => {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
const workload = [];
_docker_socket.listImages(all, data => {
let dockerImages = {};
try {
dockerImages = data;
if (dockerImages && Object.prototype.toString.call(dockerImages) === '[object Array]' && dockerImages.length > 0) {
dockerImages.forEach(function (element) {
if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) {
element.Name = element.Names[0].replace(/^\/|\/$/g, '');
}
workload.push(dockerImagesInspect(element.Id.trim(), element));
});
if (workload.length) {
Promise.all(
workload
).then((data) => {
if (callback) { callback(data); }
resolve(data);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
} else {
if (callback) { callback(result); }
resolve(result);
}
} catch (err) {
if (callback) { callback(result); }
resolve(result);
}
});
});
});
}
// --------------------------
// container inspect (for one container)
function dockerImagesInspect(imageID, payload) {
return new Promise((resolve) => {
process.nextTick(() => {
imageID = imageID || '';
if (typeof imageID !== 'string') {
return resolve();
}
const imageIDSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(imageID, true)).trim();
if (imageIDSanitized) {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
_docker_socket.inspectImage(imageIDSanitized.trim(), data => {
try {
resolve({
id: payload.Id,
container: data.Container,
comment: data.Comment,
os: data.Os,
architecture: data.Architecture,
parent: data.Parent,
dockerVersion: data.DockerVersion,
size: data.Size,
sharedSize: payload.SharedSize,
virtualSize: data.VirtualSize,
author: data.Author,
created: data.Created ? Math.round(new Date(data.Created).getTime() / 1000) : 0,
containerConfig: data.ContainerConfig ? data.ContainerConfig : {},
graphDriver: data.GraphDriver ? data.GraphDriver : {},
repoDigests: data.RepoDigests ? data.RepoDigests : {},
repoTags: data.RepoTags ? data.RepoTags : {},
config: data.Config ? data.Config : {},
rootFS: data.RootFS ? data.RootFS : {},
});
} catch (err) {
resolve();
}
});
} else {
resolve();
}
});
});
}
exports.dockerImages = dockerImages;
function dockerContainers(all, callback) {
function inContainers(containers, id) {
let filtered = containers.filter(obj => {
/**
* @namespace
* @property {string} Id
*/
return (obj.Id && (obj.Id === id));
});
return (filtered.length > 0);
}
// fallback - if only callback is given
if (util.isFunction(all) && !callback) {
callback = all;
all = false;
}
if (typeof all === 'string' && all === 'true') {
all = true;
}
if (typeof all !== 'boolean' && all !== undefined) {
all = false;
}
all = all || false;
let result = [];
return new Promise((resolve) => {
process.nextTick(() => {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
const workload = [];
_docker_socket.listContainers(all, data => {
let docker_containers = {};
try {
docker_containers = data;
if (docker_containers && Object.prototype.toString.call(docker_containers) === '[object Array]' && docker_containers.length > 0) {
// GC in _docker_container_stats
for (let key in _docker_container_stats) {
if ({}.hasOwnProperty.call(_docker_container_stats, key)) {
if (!inContainers(docker_containers, key)) { delete _docker_container_stats[key]; }
}
}
docker_containers.forEach(function (element) {
if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) {
element.Name = element.Names[0].replace(/^\/|\/$/g, '');
}
workload.push(dockerContainerInspect(element.Id.trim(), element));
});
if (workload.length) {
Promise.all(
workload
).then((data) => {
if (callback) { callback(data); }
resolve(data);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
} else {
if (callback) { callback(result); }
resolve(result);
}
} catch (err) {
// GC in _docker_container_stats
for (let key in _docker_container_stats) {
if ({}.hasOwnProperty.call(_docker_container_stats, key)) {
if (!inContainers(docker_containers, key)) { delete _docker_container_stats[key]; }
}
}
if (callback) { callback(result); }
resolve(result);
}
});
});
});
}
// --------------------------
// container inspect (for one container)
function dockerContainerInspect(containerID, payload) {
return new Promise((resolve) => {
process.nextTick(() => {
containerID = containerID || '';
if (typeof containerID !== 'string') {
return resolve();
}
const containerIdSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerID, true)).trim();
if (containerIdSanitized) {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
_docker_socket.getInspect(containerIdSanitized.trim(), data => {
try {
resolve({
id: payload.Id,
name: payload.Name,
image: payload.Image,
imageID: payload.ImageID,
command: payload.Command,
created: payload.Created,
started: data.State && data.State.StartedAt ? Math.round(new Date(data.State.StartedAt).getTime() / 1000) : 0,
finished: data.State && data.State.FinishedAt && !data.State.FinishedAt.startsWith('0001-01-01') ? Math.round(new Date(data.State.FinishedAt).getTime() / 1000) : 0,
createdAt: data.Created ? data.Created : '',
startedAt: data.State && data.State.StartedAt ? data.State.StartedAt : '',
finishedAt: data.State && data.State.FinishedAt && !data.State.FinishedAt.startsWith('0001-01-01') ? data.State.FinishedAt : '',
state: payload.State,
restartCount: data.RestartCount || 0,
platform: data.Platform || '',
driver: data.Driver || '',
ports: payload.Ports,
mounts: payload.Mounts,
// hostconfig: payload.HostConfig,
// network: payload.NetworkSettings
});
} catch (err) {
resolve();
}
});
} else {
resolve();
}
});
});
}
exports.dockerContainers = dockerContainers;
// --------------------------
// helper functions for calculation of docker stats
function docker_calcCPUPercent(cpu_stats, precpu_stats) {
/**
* @namespace
* @property {object} cpu_usage
* @property {number} cpu_usage.total_usage
* @property {number} system_cpu_usage
* @property {object} cpu_usage
* @property {Array} cpu_usage.percpu_usage
*/
if (!_windows) {
let cpuPercent = 0.0;
// calculate the change for the cpu usage of the container in between readings
let cpuDelta = cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage;
// calculate the change for the entire system between readings
let systemDelta = cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage;
if (systemDelta > 0.0 && cpuDelta > 0.0) {
// calculate the change for the cpu usage of the container in between readings
if (precpu_stats.online_cpus) {
cpuPercent = (cpuDelta / systemDelta) * precpu_stats.online_cpus * 100.0;
}
else {
cpuPercent = (cpuDelta / systemDelta) * cpu_stats.cpu_usage.percpu_usage.length * 100.0;
}
}
return cpuPercent;
} else {
let nanoSecNow = util.nanoSeconds();
let cpuPercent = 0.0;
if (_docker_last_read > 0) {
let possIntervals = (nanoSecNow - _docker_last_read); // / 100 * os.cpus().length;
let intervalsUsed = cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage;
if (possIntervals > 0) {
cpuPercent = 100.0 * intervalsUsed / possIntervals;
}
}
_docker_last_read = nanoSecNow;
return cpuPercent;
}
}
function docker_calcNetworkIO(networks) {
let rx;
let wx;
for (let key in networks) {
// skip loop if the property is from prototype
if (!{}.hasOwnProperty.call(networks, key)) { continue; }
/**
* @namespace
* @property {number} rx_bytes
* @property {number} tx_bytes
*/
let obj = networks[key];
rx = +obj.rx_bytes;
wx = +obj.tx_bytes;
}
return {
rx,
wx
};
}
function docker_calcBlockIO(blkio_stats) {
let result = {
r: 0,
w: 0
};
/**
* @namespace
* @property {Array} io_service_bytes_recursive
*/
if (blkio_stats && blkio_stats.io_service_bytes_recursive && Object.prototype.toString.call(blkio_stats.io_service_bytes_recursive) === '[object Array]' && blkio_stats.io_service_bytes_recursive.length > 0) {
blkio_stats.io_service_bytes_recursive.forEach(function (element) {
/**
* @namespace
* @property {string} op
* @property {number} value
*/
if (element.op && element.op.toLowerCase() === 'read' && element.value) {
result.r += element.value;
}
if (element.op && element.op.toLowerCase() === 'write' && element.value) {
result.w += element.value;
}
});
}
return result;
}
function dockerContainerStats(containerIDs, callback) {
let containerArray = [];
return new Promise((resolve) => {
process.nextTick(() => {
// fallback - if only callback is given
if (util.isFunction(containerIDs) && !callback) {
callback = containerIDs;
containerArray = ['*'];
} else {
containerIDs = containerIDs || '*';
if (typeof containerIDs !== 'string') {
if (callback) { callback([]); }
return resolve([]);
}
let containerIDsSanitized = '';
containerIDsSanitized.__proto__.toLowerCase = util.stringToLower;
containerIDsSanitized.__proto__.replace = util.stringReplace;
containerIDsSanitized.__proto__.trim = util.stringTrim;
containerIDsSanitized = containerIDs;
containerIDsSanitized = containerIDsSanitized.trim();
if (containerIDsSanitized !== '*') {
containerIDsSanitized = '';
const s = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerIDs, true)).trim();
const l = util.mathMin(s.length, 2000);
for (let i = 0; i <= l; i++) {
if (s[i] !== undefined) {
s[i].__proto__.toLowerCase = util.stringToLower;
const sl = s[i].toLowerCase();
if (sl && sl[0] && !sl[1]) {
containerIDsSanitized = containerIDsSanitized + sl[0];
}
}
}
}
containerIDsSanitized = containerIDsSanitized.trim().toLowerCase().replace(/,+/g, '|');
containerArray = containerIDsSanitized.split('|');
}
const result = [];
const workload = [];
if (containerArray.length && containerArray[0].trim() === '*') {
containerArray = [];
dockerContainers().then(allContainers => {
for (let container of allContainers) {
containerArray.push(container.id.substring(0, 12));
}
if (containerArray.length) {
dockerContainerStats(containerArray.join(',')).then(result => {
if (callback) { callback(result); }
resolve(result);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
});
} else {
for (let containerID of containerArray) {
workload.push(dockerContainerStatsSingle(containerID.trim()));
}
if (workload.length) {
Promise.all(
workload
).then((data) => {
if (callback) { callback(data); }
resolve(data);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
// --------------------------
// container stats (for one container)
function dockerContainerStatsSingle(containerID) {
containerID = containerID || '';
let result = {
id: containerID,
memUsage: 0,
memLimit: 0,
memPercent: 0,
cpuPercent: 0,
pids: 0,
netIO: {
rx: 0,
wx: 0
},
blockIO: {
r: 0,
w: 0
},
restartCount: 0,
cpuStats: {},
precpuStats: {},
memoryStats: {},
networks: {},
};
return new Promise((resolve) => {
process.nextTick(() => {
if (containerID) {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
_docker_socket.getInspect(containerID, dataInspect => {
try {
_docker_socket.getStats(containerID, data => {
try {
let stats = data;
if (!stats.message) {
if (data.id) { result.id = data.id; }
result.memUsage = (stats.memory_stats && stats.memory_stats.usage ? stats.memory_stats.usage : 0);
result.memLimit = (stats.memory_stats && stats.memory_stats.limit ? stats.memory_stats.limit : 0);
result.memPercent = (stats.memory_stats && stats.memory_stats.usage && stats.memory_stats.limit ? stats.memory_stats.usage / stats.memory_stats.limit * 100.0 : 0);
result.cpuPercent = (stats.cpu_stats && stats.precpu_stats ? docker_calcCPUPercent(stats.cpu_stats, stats.precpu_stats) : 0);
result.pids = (stats.pids_stats && stats.pids_stats.current ? stats.pids_stats.current : 0);
result.restartCount = (dataInspect.RestartCount ? dataInspect.RestartCount : 0);
if (stats.networks) { result.netIO = docker_calcNetworkIO(stats.networks); }
if (stats.blkio_stats) { result.blockIO = docker_calcBlockIO(stats.blkio_stats); }
result.cpuStats = (stats.cpu_stats ? stats.cpu_stats : {});
result.precpuStats = (stats.precpu_stats ? stats.precpu_stats : {});
result.memoryStats = (stats.memory_stats ? stats.memory_stats : {});
result.networks = (stats.networks ? stats.networks : {});
}
} catch (err) {
util.noop();
}
// }
resolve(result);
});
} catch (err) {
util.noop();
}
});
} else {
resolve(result);
}
});
});
}
exports.dockerContainerStats = dockerContainerStats;
// --------------------------
// container processes (for one container)
function dockerContainerProcesses(containerID, callback) {
let result = [];
return new Promise((resolve) => {
process.nextTick(() => {
containerID = containerID || '';
if (typeof containerID !== 'string') {
return resolve(result);
}
const containerIdSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerID, true)).trim();
if (containerIdSanitized) {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
_docker_socket.getProcesses(containerIdSanitized, data => {
/**
* @namespace
* @property {Array} Titles
* @property {Array} Processes
**/
try {
if (data && data.Titles && data.Processes) {
let titles = data.Titles.map(function (value) {
return value.toUpperCase();
});
let pos_pid = titles.indexOf('PID');
let pos_ppid = titles.indexOf('PPID');
let pos_pgid = titles.indexOf('PGID');
let pos_vsz = titles.indexOf('VSZ');
let pos_time = titles.indexOf('TIME');
let pos_elapsed = titles.indexOf('ELAPSED');
let pos_ni = titles.indexOf('NI');
let pos_ruser = titles.indexOf('RUSER');
let pos_user = titles.indexOf('USER');
let pos_rgroup = titles.indexOf('RGROUP');
let pos_group = titles.indexOf('GROUP');
let pos_stat = titles.indexOf('STAT');
let pos_rss = titles.indexOf('RSS');
let pos_command = titles.indexOf('COMMAND');
data.Processes.forEach(process => {
result.push({
pidHost: (pos_pid >= 0 ? process[pos_pid] : ''),
ppid: (pos_ppid >= 0 ? process[pos_ppid] : ''),
pgid: (pos_pgid >= 0 ? process[pos_pgid] : ''),
user: (pos_user >= 0 ? process[pos_user] : ''),
ruser: (pos_ruser >= 0 ? process[pos_ruser] : ''),
group: (pos_group >= 0 ? process[pos_group] : ''),
rgroup: (pos_rgroup >= 0 ? process[pos_rgroup] : ''),
stat: (pos_stat >= 0 ? process[pos_stat] : ''),
time: (pos_time >= 0 ? process[pos_time] : ''),
elapsed: (pos_elapsed >= 0 ? process[pos_elapsed] : ''),
nice: (pos_ni >= 0 ? process[pos_ni] : ''),
rss: (pos_rss >= 0 ? process[pos_rss] : ''),
vsz: (pos_vsz >= 0 ? process[pos_vsz] : ''),
command: (pos_command >= 0 ? process[pos_command] : '')
});
});
}
} catch (err) {
util.noop();
}
if (callback) { callback(result); }
resolve(result);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
});
});
}
exports.dockerContainerProcesses = dockerContainerProcesses;
function dockerVolumes(callback) {
let result = [];
return new Promise((resolve) => {
process.nextTick(() => {
if (!_docker_socket) {
_docker_socket = new DockerSocket();
}
_docker_socket.listVolumes((data) => {
let dockerVolumes = {};
try {
dockerVolumes = data;
if (dockerVolumes && dockerVolumes.Volumes && Object.prototype.toString.call(dockerVolumes.Volumes) === '[object Array]' && dockerVolumes.Volumes.length > 0) {
dockerVolumes.Volumes.forEach(function (element) {
result.push({
name: element.Name,
driver: element.Driver,
labels: element.Labels,
mountpoint: element.Mountpoint,
options: element.Options,
scope: element.Scope,
created: element.CreatedAt ? Math.round(new Date(element.CreatedAt).getTime() / 1000) : 0,
});
});
if (callback) { callback(result); }
resolve(result);
} else {
if (callback) { callback(result); }
resolve(result);
}
} catch (err) {
if (callback) { callback(result); }
resolve(result);
}
});
});
});
}
exports.dockerVolumes = dockerVolumes;
function dockerAll(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
dockerContainers(true).then(result => {
if (result && Object.prototype.toString.call(result) === '[object Array]' && result.length > 0) {
let l = result.length;
result.forEach(function (element) {
dockerContainerStats(element.id).then((res) => {
// include stats in array
element.memUsage = res[0].memUsage;
element.memLimit = res[0].memLimit;
element.memPercent = res[0].memPercent;
element.cpuPercent = res[0].cpuPercent;
element.pids = res[0].pids;
element.netIO = res[0].netIO;
element.blockIO = res[0].blockIO;
element.cpuStats = res[0].cpuStats;
element.precpuStats = res[0].precpuStats;
element.memoryStats = res[0].memoryStats;
element.networks = res[0].networks;
dockerContainerProcesses(element.id).then(processes => {
element.processes = processes;
l -= 1;
if (l === 0) {
if (callback) { callback(result); }
resolve(result);
}
});
// all done??
});
});
} else {
if (callback) { callback(result); }
resolve(result);
}
});
});
});
}
exports.dockerAll = dockerAll;

327
spa/node_modules/systeminformation/lib/dockerSocket.js generated vendored Normal file
View File

@@ -0,0 +1,327 @@
'use strict';
// @ts-check
// ==================================================================================
// dockerSockets.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 13. DockerSockets
// ----------------------------------------------------------------------------------
const net = require('net');
const isWin = require('os').type() === 'Windows_NT';
const socketPath = isWin ? '//./pipe/docker_engine' : '/var/run/docker.sock';
class DockerSocket {
getInfo(callback) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/info HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
}
listImages(all, callback) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/images/json' + (all ? '?all=1' : '') + ' HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
}
inspectImage(id, callback) {
id = id || '';
if (id) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/images/' + id + '/json?stream=0 HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
} else {
callback({});
}
}
listContainers(all, callback) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/containers/json' + (all ? '?all=1' : '') + ' HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
}
getStats(id, callback) {
id = id || '';
if (id) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/containers/' + id + '/stats?stream=0 HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
} else {
callback({});
}
}
getInspect(id, callback) {
id = id || '';
if (id) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/containers/' + id + '/json?stream=0 HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
} else {
callback({});
}
}
getProcesses(id, callback) {
id = id || '';
if (id) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/containers/' + id + '/top?ps_args=-opid,ppid,pgid,vsz,time,etime,nice,ruser,user,rgroup,group,stat,rss,args HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
} else {
callback({});
}
}
listVolumes(callback) {
try {
let socket = net.createConnection({ path: socketPath });
let alldata = '';
let data;
socket.on('connect', () => {
socket.write('GET http:/volumes HTTP/1.0\r\n\r\n');
});
socket.on('data', data => {
alldata = alldata + data.toString();
});
socket.on('error', () => {
socket = false;
callback({});
});
socket.on('end', () => {
let startbody = alldata.indexOf('\r\n\r\n');
alldata = alldata.substring(startbody + 4);
socket = false;
try {
data = JSON.parse(alldata);
callback(data);
} catch (err) {
callback({});
}
});
} catch (err) {
callback({});
}
}
}
module.exports = DockerSocket;

1510
spa/node_modules/systeminformation/lib/filesystem.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1122
spa/node_modules/systeminformation/lib/graphics.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1041
spa/node_modules/systeminformation/lib/index.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

504
spa/node_modules/systeminformation/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,504 @@
'use strict';
// @ts-check
// ==================================================================================
// index.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// Contributors: Guillaume Legrain (https://github.com/glegrain)
// Riccardo Novaglia (https://github.com/richy24)
// Quentin Busuttil (https://github.com/Buzut)
// Lapsio (https://github.com/lapsio)
// csy (https://github.com/csy1983)
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// ----------------------------------------------------------------------------------
// Dependencies
// ----------------------------------------------------------------------------------
const lib_version = require('../package.json').version;
const util = require('./util');
const system = require('./system');
const osInfo = require('./osinfo');
const cpu = require('./cpu');
const memory = require('./memory');
const battery = require('./battery');
const graphics = require('./graphics');
const filesystem = require('./filesystem');
const network = require('./network');
const wifi = require('./wifi');
const processes = require('./processes');
const users = require('./users');
const internet = require('./internet');
const docker = require('./docker');
const vbox = require('./virtualbox');
const printer = require('./printer');
const usb = require('./usb');
const audio = require('./audio');
const bluetooth = require('./bluetooth');
let _platform = process.platform;
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
// ----------------------------------------------------------------------------------
// init
// ----------------------------------------------------------------------------------
if (_windows) {
util.getCodepage();
}
// ----------------------------------------------------------------------------------
// General
// ----------------------------------------------------------------------------------
function version() {
return lib_version;
}
// ----------------------------------------------------------------------------------
// Get static and dynamic data (all)
// ----------------------------------------------------------------------------------
// --------------------------
// get static data - they should not change until restarted
function getStaticData(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let data = {};
data.version = version();
Promise.all([
system.system(),
system.bios(),
system.baseboard(),
system.chassis(),
osInfo.osInfo(),
osInfo.uuid(),
osInfo.versions(),
cpu.cpu(),
cpu.cpuFlags(),
graphics.graphics(),
network.networkInterfaces(),
memory.memLayout(),
filesystem.diskLayout()
]).then((res) => {
data.system = res[0];
data.bios = res[1];
data.baseboard = res[2];
data.chassis = res[3];
data.os = res[4];
data.uuid = res[5];
data.versions = res[6];
data.cpu = res[7];
data.cpu.flags = res[8];
data.graphics = res[9];
data.net = res[10];
data.memLayout = res[11];
data.diskLayout = res[12];
if (callback) { callback(data); }
resolve(data);
});
});
});
}
// --------------------------
// get all dynamic data - e.g. for monitoring agents
// may take some seconds to get all data
// --------------------------
// 2 additional parameters needed
// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql"
// - iface: define network interface for which you like to monitor network speed e.g. "eth0"
function getDynamicData(srv, iface, callback) {
if (util.isFunction(iface)) {
callback = iface;
iface = '';
}
if (util.isFunction(srv)) {
callback = srv;
srv = '';
}
return new Promise((resolve) => {
process.nextTick(() => {
iface = iface || network.getDefaultNetworkInterface();
srv = srv || '';
// use closure to track ƒ completion
let functionProcessed = (function () {
let totalFunctions = 15;
if (_windows) { totalFunctions = 13; }
if (_freebsd || _openbsd || _netbsd) { totalFunctions = 11; }
if (_sunos) { totalFunctions = 6; }
return function () {
if (--totalFunctions === 0) {
if (callback) {
callback(data);
}
resolve(data);
}
};
})();
let data = {};
// get time
data.time = osInfo.time();
/**
* @namespace
* @property {Object} versions
* @property {string} versions.node
* @property {string} versions.v8
*/
data.node = process.versions.node;
data.v8 = process.versions.v8;
cpu.cpuCurrentSpeed().then((res) => {
data.cpuCurrentSpeed = res;
functionProcessed();
});
users.users().then((res) => {
data.users = res;
functionProcessed();
});
processes.processes().then((res) => {
data.processes = res;
functionProcessed();
});
cpu.currentLoad().then((res) => {
data.currentLoad = res;
functionProcessed();
});
if (!_sunos) {
cpu.cpuTemperature().then((res) => {
data.temp = res;
functionProcessed();
});
}
if (!_openbsd && !_freebsd && !_netbsd && !_sunos) {
network.networkStats(iface).then((res) => {
data.networkStats = res;
functionProcessed();
});
}
if (!_sunos) {
network.networkConnections().then((res) => {
data.networkConnections = res;
functionProcessed();
});
}
memory.mem().then((res) => {
data.mem = res;
functionProcessed();
});
if (!_sunos) {
battery().then((res) => {
data.battery = res;
functionProcessed();
});
}
if (!_sunos) {
processes.services(srv).then((res) => {
data.services = res;
functionProcessed();
});
}
if (!_sunos) {
filesystem.fsSize().then((res) => {
data.fsSize = res;
functionProcessed();
});
}
if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) {
filesystem.fsStats().then((res) => {
data.fsStats = res;
functionProcessed();
});
}
if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) {
filesystem.disksIO().then((res) => {
data.disksIO = res;
functionProcessed();
});
}
if (!_openbsd && !_freebsd && !_netbsd && !_sunos) {
wifi.wifiNetworks().then((res) => {
data.wifiNetworks = res;
functionProcessed();
});
}
internet.inetLatency().then((res) => {
data.inetLatency = res;
functionProcessed();
});
});
});
}
// --------------------------
// get all data at once
// --------------------------
// 2 additional parameters needed
// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql"
// - iface: define network interface for which you like to monitor network speed e.g. "eth0"
function getAllData(srv, iface, callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let data = {};
if (iface && util.isFunction(iface) && !callback) {
callback = iface;
iface = '';
}
if (srv && util.isFunction(srv) && !iface && !callback) {
callback = srv;
srv = '';
iface = '';
}
getStaticData().then((res) => {
data = res;
getDynamicData(srv, iface).then((res) => {
for (let key in res) {
if ({}.hasOwnProperty.call(res, key)) {
data[key] = res[key];
}
}
if (callback) { callback(data); }
resolve(data);
});
});
});
});
}
function get(valueObject, callback) {
return new Promise((resolve) => {
process.nextTick(() => {
const allPromises = Object.keys(valueObject)
.filter(func => ({}.hasOwnProperty.call(exports, func)))
.map(func => {
const params = valueObject[func].substring(valueObject[func].lastIndexOf('(') + 1, valueObject[func].lastIndexOf(')'));
let funcWithoutParams = func.indexOf(')') >= 0 ? func.split(')')[1].trim() : func;
funcWithoutParams = func.indexOf('|') >= 0 ? func.split('|')[0].trim() : funcWithoutParams;
if (params) {
return exports[funcWithoutParams](params);
} else {
return exports[funcWithoutParams]('');
}
});
Promise.all(allPromises).then((data) => {
const result = {};
let i = 0;
for (let key in valueObject) {
if ({}.hasOwnProperty.call(valueObject, key) && {}.hasOwnProperty.call(exports, key) && data.length > i) {
if (valueObject[key] === '*' || valueObject[key] === 'all') {
result[key] = data[i];
} else {
let keys = valueObject[key];
let filter = '';
let filterParts = [];
// remove params
if (keys.indexOf(')') >= 0) {
keys = keys.split(')')[1].trim();
}
// extract filter and remove it from keys
if (keys.indexOf('|') >= 0) {
filter = keys.split('|')[1].trim();
filterParts = filter.split(':');
keys = keys.split('|')[0].trim();
}
keys = keys.replace(/,/g, ' ').replace(/ +/g, ' ').split(' ');
if (data[i]) {
if (Array.isArray(data[i])) {
// result is in an array, go through all elements of array and pick only the right ones
const partialArray = [];
data[i].forEach(element => {
let partialRes = {};
if (keys.length === 1 && (keys[0] === '*' || keys[0] === 'all')) {
partialRes = element;
} else {
keys.forEach(k => {
if ({}.hasOwnProperty.call(element, k)) {
partialRes[k] = element[k];
}
});
}
// if there is a filter, then just take those elements
if (filter && filterParts.length === 2) {
if ({}.hasOwnProperty.call(partialRes, filterParts[0].trim())) {
const val = partialRes[filterParts[0].trim()];
if (typeof val == 'number') {
if (val === parseFloat(filterParts[1].trim())) {
partialArray.push(partialRes);
}
} else if (typeof val == 'string') {
if (val.toLowerCase() === filterParts[1].trim().toLowerCase()) {
partialArray.push(partialRes);
}
}
}
} else {
partialArray.push(partialRes);
}
});
result[key] = partialArray;
} else {
const partialRes = {};
keys.forEach(k => {
if ({}.hasOwnProperty.call(data[i], k)) {
partialRes[k] = data[i][k];
}
});
result[key] = partialRes;
}
} else {
result[key] = {};
}
}
i++;
}
}
if (callback) { callback(result); }
resolve(result);
});
});
});
}
function observe(valueObject, interval, callback) {
let _data = null;
const result = setInterval(() => {
get(valueObject).then((data) => {
if (JSON.stringify(_data) !== JSON.stringify(data)) {
_data = Object.assign({}, data);
callback(data);
}
});
}, interval);
return result;
}
// ----------------------------------------------------------------------------------
// export all libs
// ----------------------------------------------------------------------------------
exports.version = version;
exports.system = system.system;
exports.bios = system.bios;
exports.baseboard = system.baseboard;
exports.chassis = system.chassis;
exports.time = osInfo.time;
exports.osInfo = osInfo.osInfo;
exports.versions = osInfo.versions;
exports.shell = osInfo.shell;
exports.uuid = osInfo.uuid;
exports.cpu = cpu.cpu;
exports.cpuFlags = cpu.cpuFlags;
exports.cpuCache = cpu.cpuCache;
exports.cpuCurrentSpeed = cpu.cpuCurrentSpeed;
exports.cpuTemperature = cpu.cpuTemperature;
exports.currentLoad = cpu.currentLoad;
exports.fullLoad = cpu.fullLoad;
exports.mem = memory.mem;
exports.memLayout = memory.memLayout;
exports.battery = battery;
exports.graphics = graphics.graphics;
exports.fsSize = filesystem.fsSize;
exports.fsOpenFiles = filesystem.fsOpenFiles;
exports.blockDevices = filesystem.blockDevices;
exports.fsStats = filesystem.fsStats;
exports.disksIO = filesystem.disksIO;
exports.diskLayout = filesystem.diskLayout;
exports.networkInterfaceDefault = network.networkInterfaceDefault;
exports.networkGatewayDefault = network.networkGatewayDefault;
exports.networkInterfaces = network.networkInterfaces;
exports.networkStats = network.networkStats;
exports.networkConnections = network.networkConnections;
exports.wifiNetworks = wifi.wifiNetworks;
exports.wifiInterfaces = wifi.wifiInterfaces;
exports.wifiConnections = wifi.wifiConnections;
exports.services = processes.services;
exports.processes = processes.processes;
exports.processLoad = processes.processLoad;
exports.users = users.users;
exports.inetChecksite = internet.inetChecksite;
exports.inetLatency = internet.inetLatency;
exports.dockerInfo = docker.dockerInfo;
exports.dockerImages = docker.dockerImages;
exports.dockerContainers = docker.dockerContainers;
exports.dockerContainerStats = docker.dockerContainerStats;
exports.dockerContainerProcesses = docker.dockerContainerProcesses;
exports.dockerVolumes = docker.dockerVolumes;
exports.dockerAll = docker.dockerAll;
exports.vboxInfo = vbox.vboxInfo;
exports.printer = printer.printer;
exports.usb = usb.usb;
exports.audio = audio.audio;
exports.bluetoothDevices = bluetooth.bluetoothDevices;
exports.getStaticData = getStaticData;
exports.getDynamicData = getDynamicData;
exports.getAllData = getAllData;
exports.get = get;
exports.observe = observe;
exports.powerShellStart = util.powerShellStart;
exports.powerShellRelease = util.powerShellRelease;

237
spa/node_modules/systeminformation/lib/internet.js generated vendored Normal file
View File

@@ -0,0 +1,237 @@
'use strict';
// @ts-check
// ==================================================================================
// internet.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 12. Internet
// ----------------------------------------------------------------------------------
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
// --------------------------
// check if external site is available
function inetChecksite(url, callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
url: url,
ok: false,
status: 404,
ms: null
};
if (typeof url !== 'string') {
if (callback) { callback(result); }
return resolve(result);
}
let urlSanitized = '';
const s = util.sanitizeShellString(url, true);
const l = util.mathMin(s.length, 2000);
for (let i = 0; i <= l; i++) {
if (s[i] !== undefined) {
s[i].__proto__.toLowerCase = util.stringToLower;
const sl = s[i].toLowerCase();
if (sl && sl[0] && !sl[1] && sl[0].length === 1) {
urlSanitized = urlSanitized + sl[0];
}
}
}
result.url = urlSanitized;
try {
if (urlSanitized && !util.isPrototypePolluted()) {
urlSanitized.__proto__.startsWith = util.stringStartWith;
if (urlSanitized.startsWith('file:') || urlSanitized.startsWith('gopher:') || urlSanitized.startsWith('telnet:') || urlSanitized.startsWith('mailto:') || urlSanitized.startsWith('news:') || urlSanitized.startsWith('nntp:')) {
if (callback) { callback(result); }
return resolve(result);
}
let t = Date.now();
if (_linux || _freebsd || _openbsd || _netbsd || _darwin || _sunos) {
let args = ['-I', '--connect-timeout', '5', '-m', '5'];
args.push(urlSanitized);
let cmd = 'curl';
util.execSafe(cmd, args).then((stdout) => {
const lines = stdout.split('\n');
let statusCode = lines[0] && lines[0].indexOf(' ') >= 0 ? parseInt(lines[0].split(' ')[1], 10) : 404;
result.status = statusCode || 404;
result.ok = (statusCode === 200 || statusCode === 301 || statusCode === 302 || statusCode === 304);
result.ms = (result.ok ? Date.now() - t : null);
if (callback) { callback(result); }
resolve(result);
});
}
if (_windows) { // if this is stable, this can be used for all OS types
const http = (urlSanitized.startsWith('https:') ? require('https') : require('http'));
try {
http.get(urlSanitized, (res) => {
const statusCode = res.statusCode;
result.status = statusCode || 404;
result.ok = (statusCode === 200 || statusCode === 301 || statusCode === 302 || statusCode === 304);
if (statusCode !== 200) {
res.resume();
result.ms = (result.ok ? Date.now() - t : null);
if (callback) { callback(result); }
resolve(result);
} else {
res.on('data', () => { });
res.on('end', () => {
result.ms = (result.ok ? Date.now() - t : null);
if (callback) { callback(result); }
resolve(result);
});
}
}).on('error', () => {
if (callback) { callback(result); }
resolve(result);
});
} catch (err) {
if (callback) { callback(result); }
resolve(result);
}
}
} else {
if (callback) { callback(result); }
resolve(result);
}
} catch (err) {
if (callback) { callback(result); }
resolve(result);
}
});
});
}
exports.inetChecksite = inetChecksite;
// --------------------------
// check inet latency
function inetLatency(host, callback) {
// fallback - if only callback is given
if (util.isFunction(host) && !callback) {
callback = host;
host = '';
}
host = host || '8.8.8.8';
return new Promise((resolve) => {
process.nextTick(() => {
if (typeof host !== 'string') {
if (callback) { callback(null); }
return resolve(null);
}
let hostSanitized = '';
const s = (util.isPrototypePolluted() ? '8.8.8.8' : util.sanitizeShellString(host, true)).trim();
const l = util.mathMin(s.length, 2000);
for (let i = 0; i <= l; i++) {
if (!(s[i] === undefined)) {
s[i].__proto__.toLowerCase = util.stringToLower;
const sl = s[i].toLowerCase();
if (sl && sl[0] && !sl[1]) {
hostSanitized = hostSanitized + sl[0];
}
}
}
hostSanitized.__proto__.startsWith = util.stringStartWith;
if (hostSanitized.startsWith('file:') || hostSanitized.startsWith('gopher:') || hostSanitized.startsWith('telnet:') || hostSanitized.startsWith('mailto:') || hostSanitized.startsWith('news:') || hostSanitized.startsWith('nntp:')) {
if (callback) { callback(null); }
return resolve(null);
}
let params;
if (_linux || _freebsd || _openbsd || _netbsd || _darwin) {
if (_linux) {
params = ['-c', '2', '-w', '3', hostSanitized];
}
if (_freebsd || _openbsd || _netbsd) {
params = ['-c', '2', '-t', '3', hostSanitized];
}
if (_darwin) {
params = ['-c2', '-t3', hostSanitized];
}
util.execSafe('ping', params).then((stdout) => {
let result = null;
if (stdout) {
const lines = stdout.split('\n').filter((line) => (line.indexOf('rtt') >= 0 || line.indexOf('round-trip') >= 0 || line.indexOf('avg') >= 0)).join('\n');
const line = lines.split('=');
if (line.length > 1) {
const parts = line[1].split('/');
if (parts.length > 1) {
result = parseFloat(parts[1]);
}
}
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
const params = ['-s', '-a', hostSanitized, '56', '2'];
const filt = 'avg';
util.execSafe('ping', params, { timeout: 3000 }).then((stdout) => {
let result = null;
if (stdout) {
const lines = stdout.split('\n').filter(line => line.indexOf(filt) >= 0).join('\n');
const line = lines.split('=');
if (line.length > 1) {
const parts = line[1].split('/');
if (parts.length > 1) {
result = parseFloat(parts[1].replace(',', '.'));
}
}
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_windows) {
let result = null;
try {
const params = [hostSanitized, '-n', '1'];
util.execSafe('ping', params, util.execOptsWin).then((stdout) => {
if (stdout) {
let lines = stdout.split('\r\n');
lines.shift();
lines.forEach(function (line) {
if ((line.toLowerCase().match(/ms/g) || []).length === 3) {
let l = line.replace(/ +/g, ' ').split(' ');
if (l.length > 6) {
result = parseFloat(l[l.length - 1]);
}
}
});
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.inetLatency = inetLatency;

575
spa/node_modules/systeminformation/lib/memory.js generated vendored Normal file
View File

@@ -0,0 +1,575 @@
'use strict';
// @ts-check
// ==================================================================================
// memory.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 5. Memory
// ----------------------------------------------------------------------------------
const os = require('os');
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const util = require('./util');
const fs = require('fs');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
const OSX_RAM_manufacturers = {
'0x014F': 'Transcend Information',
'0x2C00': 'Micron Technology Inc.',
'0x802C': 'Micron Technology Inc.',
'0x80AD': 'Hynix Semiconductor Inc.',
'0x80CE': 'Samsung Electronics Inc.',
'0xAD00': 'Hynix Semiconductor Inc.',
'0xCE00': 'Samsung Electronics Inc.',
'0x02FE': 'Elpida',
'0x5105': 'Qimonda AG i. In.',
'0x8551': 'Qimonda AG i. In.',
'0x859B': 'Crucial',
'0x04CD': 'G-Skill'
};
const LINUX_RAM_manufacturers = {
'017A': 'Apacer',
'0198': 'HyperX',
'029E': 'Corsair',
'04CB': 'A-DATA',
'04CD': 'G-Skill',
'059B': 'Crucial',
'00CE': 'Samsung',
'1315': 'Crucial',
'014F': 'Transcend Information',
'2C00': 'Micron Technology Inc.',
'802C': 'Micron Technology Inc.',
'80AD': 'Hynix Semiconductor Inc.',
'80CE': 'Samsung Electronics Inc.',
'AD00': 'Hynix Semiconductor Inc.',
'CE00': 'Samsung Electronics Inc.',
'02FE': 'Elpida',
'5105': 'Qimonda AG i. In.',
'8551': 'Qimonda AG i. In.',
'859B': 'Crucial'
};
// _______________________________________________________________________________________
// | R A M | H D |
// |______________________|_________________________| | |
// | active buffers/cache | | |
// |________________________________________________|___________|_________|______________|
// | used free | used free |
// |____________________________________________________________|________________________|
// | total | swap |
// |____________________________________________________________|________________________|
// free (older versions)
// ----------------------------------
// # free
// total used free shared buffers cached
// Mem: 16038 (1) 15653 (2) 384 (3) 0 (4) 236 (5) 14788 (6)
// -/+ buffers/cache: 628 (7) 15409 (8)
// Swap: 16371 83 16288
//
// |------------------------------------------------------------|
// | R A M |
// |______________________|_____________________________________|
// | active (2-(5+6) = 7) | available (3+5+6 = 8) |
// |______________________|_________________________|___________|
// | active | buffers/cache (5+6) | |
// |________________________________________________|___________|
// | used (2) | free (3) |
// |____________________________________________________________|
// | total (1) |
// |____________________________________________________________|
//
// free (since free von procps-ng 3.3.10)
// ----------------------------------
// # free
// total used free shared buffers/cache available
// Mem: 16038 (1) 628 (2) 386 (3) 0 (4) 15024 (5) 14788 (6)
// Swap: 16371 83 16288
//
// |------------------------------------------------------------|
// | R A M |
// |______________________|_____________________________________|
// | | available (6) estimated |
// |______________________|_________________________|___________|
// | active (2) | buffers/cache (5) | free (3) |
// |________________________________________________|___________|
// | total (1) |
// |____________________________________________________________|
//
// Reference: http://www.software-architect.net/blog/article/date/2015/06/12/-826c6e5052.html
// /procs/meminfo - sample (all in kB)
//
// MemTotal: 32806380 kB
// MemFree: 17977744 kB
// MemAvailable: 19768972 kB
// Buffers: 517028 kB
// Cached: 2161876 kB
// SwapCached: 456 kB
// Active: 12081176 kB
// Inactive: 2164616 kB
// Active(anon): 10832884 kB
// Inactive(anon): 1477272 kB
// Active(file): 1248292 kB
// Inactive(file): 687344 kB
// Unevictable: 0 kB
// Mlocked: 0 kB
// SwapTotal: 16768892 kB
// SwapFree: 16768304 kB
// Dirty: 268 kB
// Writeback: 0 kB
// AnonPages: 11568832 kB
// Mapped: 719992 kB
// Shmem: 743272 kB
// Slab: 335716 kB
// SReclaimable: 256364 kB
// SUnreclaim: 79352 kB
function mem(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
total: os.totalmem(),
free: os.freemem(),
used: os.totalmem() - os.freemem(),
active: os.totalmem() - os.freemem(), // temporarily (fallback)
available: os.freemem(), // temporarily (fallback)
buffers: 0,
cached: 0,
slab: 0,
buffcache: 0,
swaptotal: 0,
swapused: 0,
swapfree: 0,
writeback: null,
dirty: null
};
if (_linux) {
try {
fs.readFile('/proc/meminfo', function (error, stdout) {
if (!error) {
const lines = stdout.toString().split('\n');
result.total = parseInt(util.getValue(lines, 'memtotal'), 10);
result.total = result.total ? result.total * 1024 : os.totalmem();
result.free = parseInt(util.getValue(lines, 'memfree'), 10);
result.free = result.free ? result.free * 1024 : os.freemem();
result.used = result.total - result.free;
result.buffers = parseInt(util.getValue(lines, 'buffers'), 10);
result.buffers = result.buffers ? result.buffers * 1024 : 0;
result.cached = parseInt(util.getValue(lines, 'cached'), 10);
result.cached = result.cached ? result.cached * 1024 : 0;
result.slab = parseInt(util.getValue(lines, 'slab'), 10);
result.slab = result.slab ? result.slab * 1024 : 0;
result.buffcache = result.buffers + result.cached + result.slab;
let available = parseInt(util.getValue(lines, 'memavailable'), 10);
result.available = available ? available * 1024 : result.free + result.buffcache;
result.active = result.total - result.available;
result.swaptotal = parseInt(util.getValue(lines, 'swaptotal'), 10);
result.swaptotal = result.swaptotal ? result.swaptotal * 1024 : 0;
result.swapfree = parseInt(util.getValue(lines, 'swapfree'), 10);
result.swapfree = result.swapfree ? result.swapfree * 1024 : 0;
result.swapused = result.swaptotal - result.swapfree;
result.writeback = parseInt(util.getValue(lines, 'writeback'), 10);
result.writeback = result.writeback ? result.writeback * 1024 : 0;
result.dirty = parseInt(util.getValue(lines, 'dirty'), 10);
result.dirty = result.dirty ? result.dirty * 1024 : 0;
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
if (_freebsd || _openbsd || _netbsd) {
try {
exec('/sbin/sysctl hw.realmem hw.physmem vm.stats.vm.v_page_count vm.stats.vm.v_wire_count vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count vm.stats.vm.v_cache_count vm.stats.vm.v_free_count vm.stats.vm.v_page_size', function (error, stdout) {
if (!error) {
let lines = stdout.toString().split('\n');
const pagesize = parseInt(util.getValue(lines, 'vm.stats.vm.v_page_size'), 10);
const inactive = parseInt(util.getValue(lines, 'vm.stats.vm.v_inactive_count'), 10) * pagesize;
const cache = parseInt(util.getValue(lines, 'vm.stats.vm.v_cache_count'), 10) * pagesize;
result.total = parseInt(util.getValue(lines, 'hw.realmem'), 10);
if (isNaN(result.total)) { result.total = parseInt(util.getValue(lines, 'hw.physmem'), 10); }
result.free = parseInt(util.getValue(lines, 'vm.stats.vm.v_free_count'), 10) * pagesize;
result.buffcache = inactive + cache;
result.available = result.buffcache + result.free;
result.active = result.total - result.free - result.buffcache;
result.swaptotal = 0;
result.swapfree = 0;
result.swapused = 0;
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
if (_sunos) {
if (callback) { callback(result); }
resolve(result);
}
if (_darwin) {
let pageSize = 4096;
try {
let sysPpageSize = util.toInt(execSync('sysctl -n vm.pagesize').toString());
pageSize = sysPpageSize || pageSize;
} catch (e) {
util.noop();
}
try {
exec('vm_stat 2>/dev/null | grep "Pages active"', function (error, stdout) {
if (!error) {
let lines = stdout.toString().split('\n');
result.active = parseInt(lines[0].split(':')[1], 10) * pageSize;
result.buffcache = result.used - result.active;
result.available = result.free + result.buffcache;
}
exec('sysctl -n vm.swapusage 2>/dev/null', function (error, stdout) {
if (!error) {
let lines = stdout.toString().split('\n');
if (lines.length > 0) {
let firstline = lines[0].replace(/,/g, '.').replace(/M/g, '');
let lineArray = firstline.trim().split(' ');
lineArray.forEach(line => {
if (line.toLowerCase().indexOf('total') !== -1) { result.swaptotal = parseFloat(line.split('=')[1].trim()) * 1024 * 1024; }
if (line.toLowerCase().indexOf('used') !== -1) { result.swapused = parseFloat(line.split('=')[1].trim()) * 1024 * 1024; }
if (line.toLowerCase().indexOf('free') !== -1) { result.swapfree = parseFloat(line.split('=')[1].trim()) * 1024 * 1024; }
});
}
}
if (callback) { callback(result); }
resolve(result);
});
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
if (_windows) {
let swaptotal = 0;
let swapused = 0;
try {
util.powerShell('Get-CimInstance Win32_PageFileUsage | Select AllocatedBaseSize, CurrentUsage').then((stdout, error) => {
if (!error) {
let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
lines.forEach(function (line) {
if (line !== '') {
line = line.trim().split(/\s\s+/);
swaptotal = swaptotal + (parseInt(line[0], 10) || 0);
swapused = swapused + (parseInt(line[1], 10) || 0);
}
});
}
result.swaptotal = swaptotal * 1024 * 1024;
result.swapused = swapused * 1024 * 1024;
result.swapfree = result.swaptotal - result.swapused;
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.mem = mem;
function memLayout(callback) {
function getManufacturerDarwin(manId) {
if ({}.hasOwnProperty.call(OSX_RAM_manufacturers, manId)) {
return (OSX_RAM_manufacturers[manId]);
}
return manId;
}
function getManufacturerLinux(manId) {
const manIdSearch = manId.replace('0x', '').toUpperCase();
if (manIdSearch.length === 4 && {}.hasOwnProperty.call(LINUX_RAM_manufacturers, manIdSearch)) {
return (LINUX_RAM_manufacturers[manIdSearch]);
}
return manId;
}
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
if (_linux || _freebsd || _openbsd || _netbsd) {
exec('export LC_ALL=C; dmidecode -t memory 2>/dev/null | grep -iE "Size:|Type|Speed|Manufacturer|Form Factor|Locator|Memory Device|Serial Number|Voltage|Part Number"; unset LC_ALL', function (error, stdout) {
if (!error) {
let devices = stdout.toString().split('Memory Device');
devices.shift();
devices.forEach(function (device) {
let lines = device.split('\n');
const sizeString = util.getValue(lines, 'Size');
const size = sizeString.indexOf('GB') >= 0 ? parseInt(sizeString, 10) * 1024 * 1024 * 1024 : parseInt(sizeString, 10) * 1024 * 1024;
let bank = util.getValue(lines, 'Bank Locator');
if (bank.toLowerCase().indexOf('bad') >= 0) {
bank = '';
}
if (parseInt(util.getValue(lines, 'Size'), 10) > 0) {
const totalWidth = util.toInt(util.getValue(lines, 'Total Width'));
const dataWidth = util.toInt(util.getValue(lines, 'Data Width'));
result.push({
size,
bank,
type: util.getValue(lines, 'Type:'),
ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
clockSpeed: (util.getValue(lines, 'Configured Clock Speed:') ? parseInt(util.getValue(lines, 'Configured Clock Speed:'), 10) : (util.getValue(lines, 'Speed:') ? parseInt(util.getValue(lines, 'Speed:'), 10) : null)),
formFactor: util.getValue(lines, 'Form Factor:'),
manufacturer: getManufacturerLinux(util.getValue(lines, 'Manufacturer:')),
partNum: util.getValue(lines, 'Part Number:'),
serialNum: util.getValue(lines, 'Serial Number:'),
voltageConfigured: parseFloat(util.getValue(lines, 'Configured Voltage:')) || null,
voltageMin: parseFloat(util.getValue(lines, 'Minimum Voltage:')) || null,
voltageMax: parseFloat(util.getValue(lines, 'Maximum Voltage:')) || null,
});
} else {
result.push({
size: 0,
bank,
type: 'Empty',
ecc: null,
clockSpeed: 0,
formFactor: util.getValue(lines, 'Form Factor:'),
partNum: '',
serialNum: '',
voltageConfigured: null,
voltageMin: null,
voltageMax: null,
});
}
});
}
if (!result.length) {
result.push({
size: os.totalmem(),
bank: '',
type: '',
ecc: null,
clockSpeed: 0,
formFactor: '',
partNum: '',
serialNum: '',
voltageConfigured: null,
voltageMin: null,
voltageMax: null,
});
// Try Raspberry PI
try {
let stdout = execSync('cat /proc/cpuinfo 2>/dev/null');
let lines = stdout.toString().split('\n');
let model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
let version = util.getValue(lines, 'revision', ':', true).toLowerCase();
if (model === 'BCM2835' || model === 'BCM2708' || model === 'BCM2709' || model === 'BCM2835' || model === 'BCM2837') {
const clockSpeed = {
'0': 400,
'1': 450,
'2': 450,
'3': 3200
};
result[0].type = 'LPDDR2';
result[0].type = version && version[2] && version[2] === '3' ? 'LPDDR4' : result[0].type;
result[0].ecc = false;
result[0].clockSpeed = version && version[2] && clockSpeed[version[2]] || 400;
result[0].clockSpeed = version && version[4] && version[4] === 'd' ? 500 : result[0].clockSpeed;
result[0].formFactor = 'SoC';
stdout = execSync('vcgencmd get_config sdram_freq 2>/dev/null');
lines = stdout.toString().split('\n');
let freq = parseInt(util.getValue(lines, 'sdram_freq', '=', true), 10) || 0;
if (freq) {
result[0].clockSpeed = freq;
}
stdout = execSync('vcgencmd measure_volts sdram_p 2>/dev/null');
lines = stdout.toString().split('\n');
let voltage = parseFloat(util.getValue(lines, 'volt', '=', true)) || 0;
if (voltage) {
result[0].voltageConfigured = voltage;
result[0].voltageMin = voltage;
result[0].voltageMax = voltage;
}
}
} catch (e) {
util.noop();
}
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_darwin) {
exec('system_profiler SPMemoryDataType', function (error, stdout) {
if (!error) {
const allLines = stdout.toString().split('\n');
const eccStatus = util.getValue(allLines, 'ecc', ':', true).toLowerCase();
let devices = stdout.toString().split(' BANK ');
let hasBank = true;
if (devices.length === 1) {
devices = stdout.toString().split(' DIMM');
hasBank = false;
}
devices.shift();
devices.forEach(function (device) {
let lines = device.split('\n');
const bank = (hasBank ? 'BANK ' : 'DIMM') + lines[0].trim().split('/')[0];
const size = parseInt(util.getValue(lines, ' Size'));
if (size) {
result.push({
size: size * 1024 * 1024 * 1024,
bank: bank,
type: util.getValue(lines, ' Type:'),
ecc: eccStatus ? eccStatus === 'enabled' : null,
clockSpeed: parseInt(util.getValue(lines, ' Speed:'), 10),
formFactor: '',
manufacturer: getManufacturerDarwin(util.getValue(lines, ' Manufacturer:')),
partNum: util.getValue(lines, ' Part Number:'),
serialNum: util.getValue(lines, ' Serial Number:'),
voltageConfigured: null,
voltageMin: null,
voltageMax: null,
});
} else {
result.push({
size: 0,
bank: bank,
type: 'Empty',
ecc: null,
clockSpeed: 0,
formFactor: '',
manufacturer: '',
partNum: '',
serialNum: '',
voltageConfigured: null,
voltageMin: null,
voltageMax: null,
});
}
});
}
if (!result.length) {
const lines = stdout.toString().split('\n');
const size = parseInt(util.getValue(lines, ' Memory:'));
const type = util.getValue(lines, ' Type:');
if (size && type) {
result.push({
size: size * 1024 * 1024 * 1024,
bank: '0',
type,
ecc: false,
clockSpeed: 0,
formFactor: '',
manufacturer: 'Apple',
partNum: '',
serialNum: '',
voltageConfigured: null,
voltageMin: null,
voltageMax: null,
});
}
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
if (callback) { callback(result); }
resolve(result);
}
if (_windows) {
// https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.4.0a.pdf
const memoryTypes = 'Unknown|Other|DRAM|Synchronous DRAM|Cache DRAM|EDO|EDRAM|VRAM|SRAM|RAM|ROM|FLASH|EEPROM|FEPROM|EPROM|CDRAM|3DRAM|SDRAM|SGRAM|RDRAM|DDR|DDR2|DDR2 FB-DIMM|Reserved|DDR3|FBD2|DDR4|LPDDR|LPDDR2|LPDDR3|LPDDR4|Logical non-volatile device|HBM|HBM2|DDR5|LPDDR5'.split('|');
const FormFactors = 'Unknown|Other|SIP|DIP|ZIP|SOJ|Proprietary|SIMM|DIMM|TSOP|PGA|RIMM|SODIMM|SRIMM|SMD|SSMP|QFP|TQFP|SOIC|LCC|PLCC|BGA|FPBGA|LGA'.split('|');
try {
util.powerShell('Get-CimInstance Win32_PhysicalMemory | select DataWidth,TotalWidth,Capacity,BankLabel,MemoryType,SMBIOSMemoryType,ConfiguredClockSpeed,FormFactor,Manufacturer,PartNumber,SerialNumber,ConfiguredVoltage,MinVoltage,MaxVoltage,Tag | fl').then((stdout, error) => {
if (!error) {
let devices = stdout.toString().split(/\n\s*\n/);
devices.shift();
devices.forEach(function (device) {
let lines = device.split('\r\n');
const dataWidth = util.toInt(util.getValue(lines, 'DataWidth', ':'));
const totalWidth = util.toInt(util.getValue(lines, 'TotalWidth', ':'));
const size = parseInt(util.getValue(lines, 'Capacity', ':'), 10) || 0;
const tag = util.getValue(lines, 'Tag', ':');
const tagInt = util.splitByNumber(tag);
if (size) {
result.push({
size,
bank: util.getValue(lines, 'BankLabel', ':') + (tagInt[1] ? '/' + tagInt[1] : ''), // BankLabel
type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', ':'), 10) || parseInt(util.getValue(lines, 'SMBIOSMemoryType', ':'), 10)],
ecc: dataWidth && totalWidth ? totalWidth > dataWidth : false,
clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', ':'), 10) || parseInt(util.getValue(lines, 'Speed', ':'), 10) || 0,
formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', ':'), 10) || 0],
manufacturer: util.getValue(lines, 'Manufacturer', ':'),
partNum: util.getValue(lines, 'PartNumber', ':'),
serialNum: util.getValue(lines, 'SerialNumber', ':'),
voltageConfigured: (parseInt(util.getValue(lines, 'ConfiguredVoltage', ':'), 10) || 0) / 1000.0,
voltageMin: (parseInt(util.getValue(lines, 'MinVoltage', ':'), 10) || 0) / 1000.0,
voltageMax: (parseInt(util.getValue(lines, 'MaxVoltage', ':'), 10) || 0) / 1000.0,
});
}
});
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.memLayout = memLayout;

1783
spa/node_modules/systeminformation/lib/network.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1179
spa/node_modules/systeminformation/lib/osinfo.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

210
spa/node_modules/systeminformation/lib/printer.js generated vendored Normal file
View File

@@ -0,0 +1,210 @@
'use strict';
// @ts-check
// ==================================================================================
// printers.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 15. printers
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
const winPrinterStatus = {
1: 'Other',
2: 'Unknown',
3: 'Idle',
4: 'Printing',
5: 'Warmup',
6: 'Stopped Printing',
7: 'Offline',
};
function parseLinuxCupsHeader(lines) {
const result = {};
if (lines && lines.length) {
if (lines[0].indexOf(' CUPS v') > 0) {
const parts = lines[0].split(' CUPS v');
result.cupsVersion = parts[1];
}
}
return result;
}
function parseLinuxCupsPrinter(lines) {
const result = {};
const printerId = util.getValue(lines, 'PrinterId', ' ');
result.id = printerId ? parseInt(printerId, 10) : null;
result.name = util.getValue(lines, 'Info', ' ');
result.model = lines.length > 0 && lines[0] ? lines[0].split(' ')[0] : '';
result.uri = util.getValue(lines, 'DeviceURI', ' ');
result.uuid = util.getValue(lines, 'UUID', ' ');
result.status = util.getValue(lines, 'State', ' ');
result.local = util.getValue(lines, 'Location', ' ').toLowerCase().startsWith('local');
result.default = null;
result.shared = util.getValue(lines, 'Shared', ' ').toLowerCase().startsWith('yes');
return result;
}
function parseLinuxLpstatPrinter(lines, id) {
const result = {};
result.id = id;
result.name = util.getValue(lines, 'Description', ':', true);
result.model = lines.length > 0 && lines[0] ? lines[0].split(' ')[0] : '';
result.uri = null;
result.uuid = null;
result.status = lines.length > 0 && lines[0] ? (lines[0].indexOf(' idle') > 0 ? 'idle' : (lines[0].indexOf(' printing') > 0 ? 'printing' : 'unknown')) : null;
result.local = util.getValue(lines, 'Location', ':', true).toLowerCase().startsWith('local');
result.default = null;
result.shared = util.getValue(lines, 'Shared', ' ').toLowerCase().startsWith('yes');
return result;
}
function parseDarwinPrinters(printerObject, id) {
const result = {};
const uriParts = printerObject.uri.split('/');
result.id = id;
result.name = printerObject._name;
result.model = uriParts.length ? uriParts[uriParts.length - 1] : '';
result.uri = printerObject.uri;
result.uuid = null;
result.status = printerObject.status;
result.local = printerObject.printserver === 'local';
result.default = printerObject.default === 'yes';
result.shared = printerObject.shared === 'yes';
return result;
}
function parseWindowsPrinters(lines, id) {
const result = {};
const status = parseInt(util.getValue(lines, 'PrinterStatus', ':'), 10);
result.id = id;
result.name = util.getValue(lines, 'name', ':');
result.model = util.getValue(lines, 'DriverName', ':');
result.uri = null;
result.uuid = null;
result.status = winPrinterStatus[status] ? winPrinterStatus[status] : null;
result.local = util.getValue(lines, 'Local', ':').toUpperCase() === 'TRUE';
result.default = util.getValue(lines, 'Default', ':').toUpperCase() === 'TRUE';
result.shared = util.getValue(lines, 'Shared', ':').toUpperCase() === 'TRUE';
return result;
}
function printer(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
if (_linux || _freebsd || _openbsd || _netbsd) {
let cmd = 'cat /etc/cups/printers.conf 2>/dev/null';
exec(cmd, function (error, stdout) {
// printers.conf
if (!error) {
const parts = stdout.toString().split('<Printer ');
const printerHeader = parseLinuxCupsHeader(parts[0]);
for (let i = 1; i < parts.length; i++) {
const printers = parseLinuxCupsPrinter(parts[i].split('\n'));
if (printers.name) {
printers.engine = 'CUPS';
printers.engineVersion = printerHeader.cupsVersion;
result.push(printers);
}
}
}
if (result.length === 0) {
if (_linux) {
cmd = 'export LC_ALL=C; lpstat -lp 2>/dev/null; unset LC_ALL';
// lpstat
exec(cmd, function (error, stdout) {
const parts = ('\n' + stdout.toString()).split('\nprinter ');
for (let i = 1; i < parts.length; i++) {
const printers = parseLinuxLpstatPrinter(parts[i].split('\n'), i);
result.push(printers);
}
});
if (callback) {
callback(result);
}
resolve(result);
} else {
if (callback) {
callback(result);
}
resolve(result);
}
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
}
if (_darwin) {
let cmd = 'system_profiler SPPrintersDataType -json';
exec(cmd, function (error, stdout) {
if (!error) {
try {
const outObj = JSON.parse(stdout.toString());
if (outObj.SPPrintersDataType && outObj.SPPrintersDataType.length) {
for (let i = 0; i < outObj.SPPrintersDataType.length; i++) {
const printer = parseDarwinPrinters(outObj.SPPrintersDataType[i], i);
result.push(printer);
}
}
} catch (e) {
util.noop();
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_windows) {
util.powerShell('Get-CimInstance Win32_Printer | select PrinterStatus,Name,DriverName,Local,Default,Shared | fl').then((stdout, error) => {
if (!error) {
const parts = stdout.toString().split(/\n\s*\n/);
for (let i = 0; i < parts.length; i++) {
const printer = parseWindowsPrinters(parts[i].split('\n'), i);
if (printer.name || printer.model) {
result.push(printer);
}
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_sunos) {
resolve(null);
}
});
});
}
exports.printer = printer;

1292
spa/node_modules/systeminformation/lib/processes.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

748
spa/node_modules/systeminformation/lib/system.js generated vendored Normal file
View File

@@ -0,0 +1,748 @@
'use strict';
// @ts-check
// ==================================================================================
// system.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 2. System (Hardware, BIOS, Base Board)
// ----------------------------------------------------------------------------------
const fs = require('fs');
const os = require('os');
const util = require('./util');
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const execPromise = util.promisify(require('child_process').exec);
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function system(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
manufacturer: '',
model: 'Computer',
version: '',
serial: '-',
uuid: '-',
sku: '-',
virtual: false
};
if (_linux || _freebsd || _openbsd || _netbsd) {
exec('export LC_ALL=C; dmidecode -t system 2>/dev/null; unset LC_ALL', function (error, stdout) {
let lines = stdout.toString().split('\n');
result.manufacturer = util.getValue(lines, 'manufacturer');
result.model = util.getValue(lines, 'product name');
result.version = util.getValue(lines, 'version');
result.serial = util.getValue(lines, 'serial number');
result.uuid = util.getValue(lines, 'uuid').toLowerCase();
result.sku = util.getValue(lines, 'sku number');
// Non-Root values
const cmd = `echo -n "product_name: "; cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null; echo;
echo -n "product_serial: "; cat /sys/devices/virtual/dmi/id/product_serial 2>/dev/null; echo;
echo -n "product_uuid: "; cat /sys/devices/virtual/dmi/id/product_uuid 2>/dev/null; echo;
echo -n "product_version: "; cat /sys/devices/virtual/dmi/id/product_version 2>/dev/null; echo;
echo -n "sys_vendor: "; cat /sys/devices/virtual/dmi/id/sys_vendor 2>/dev/null; echo;`;
try {
lines = execSync(cmd).toString().split('\n');
result.manufacturer = result.manufacturer === '' ? util.getValue(lines, 'sys_vendor') : result.manufacturer;
result.model = result.model === '' ? util.getValue(lines, 'product_name') : result.model;
result.version = result.version === '' ? util.getValue(lines, 'product_version') : result.version;
result.serial = result.serial === '' ? util.getValue(lines, 'product_serial') : result.serial;
result.uuid = result.uuid === '' ? util.getValue(lines, 'product_uuid').toLowerCase() : result.uuid;
} catch (e) {
util.noop();
}
if (!result.serial || result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
if (!result.manufacturer || result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = ''; }
if (!result.model || result.model.toLowerCase().indexOf('o.e.m.') !== -1) { result.model = 'Computer'; }
if (!result.version || result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = ''; }
if (!result.sku || result.sku.toLowerCase().indexOf('o.e.m.') !== -1) { result.sku = '-'; }
// detect virtual (1)
if (result.model.toLowerCase() === 'virtualbox' || result.model.toLowerCase() === 'kvm' || result.model.toLowerCase() === 'virtual machine' || result.model.toLowerCase() === 'bochs' || result.model.toLowerCase().startsWith('vmware') || result.model.toLowerCase().startsWith('droplet')) {
result.virtual = true;
switch (result.model.toLowerCase()) {
case 'virtualbox':
result.virtualHost = 'VirtualBox';
break;
case 'vmware':
result.virtualHost = 'VMware';
break;
case 'kvm':
result.virtualHost = 'KVM';
break;
case 'bochs':
result.virtualHost = 'bochs';
break;
}
}
if (result.manufacturer.toLowerCase().startsWith('vmware') || result.manufacturer.toLowerCase() === 'xen') {
result.virtual = true;
switch (result.manufacturer.toLowerCase()) {
case 'vmware':
result.virtualHost = 'VMware';
break;
case 'xen':
result.virtualHost = 'Xen';
break;
}
}
if (!result.virtual) {
try {
const disksById = execSync('ls -1 /dev/disk/by-id/ 2>/dev/null').toString();
if (disksById.indexOf('_QEMU_') >= 0) {
result.virtual = true;
result.virtualHost = 'QEMU';
}
if (disksById.indexOf('_VBOX_') >= 0) {
result.virtual = true;
result.virtualHost = 'VirtualBox';
}
} catch (e) {
util.noop();
}
}
if (!result.virtual && (os.release().toLowerCase().indexOf('microsoft') >= 0 || os.release().toLowerCase().endsWith('wsl2'))) {
const kernelVersion = parseFloat(os.release().toLowerCase());
result.virtual = true;
result.manufacturer = 'Microsoft';
result.model = 'WSL';
result.version = kernelVersion < 4.19 ? '1' : '2';
}
if ((_freebsd || _openbsd || _netbsd) && !result.virtualHost) {
try {
const procInfo = execSync('dmidecode -t 4');
const procLines = procInfo.toString().split('\n');
const procManufacturer = util.getValue(procLines, 'manufacturer', ':', true);
switch (procManufacturer.toLowerCase()) {
case 'virtualbox':
result.virtualHost = 'VirtualBox';
break;
case 'vmware':
result.virtualHost = 'VMware';
break;
case 'kvm':
result.virtualHost = 'KVM';
break;
case 'bochs':
result.virtualHost = 'bochs';
break;
}
} catch (e) {
util.noop();
}
}
// detect docker
if (fs.existsSync('/.dockerenv') || fs.existsSync('/.dockerinit')) {
result.model = 'Docker Container';
}
try {
const stdout = execSync('dmesg 2>/dev/null | grep -iE "virtual|hypervisor" | grep -iE "vmware|qemu|kvm|xen" | grep -viE "Nested Virtualization|/virtual/"');
// detect virtual machines
let lines = stdout.toString().split('\n');
if (lines.length > 0) {
if (result.model === 'Computer') { result.model = 'Virtual machine'; }
result.virtual = true;
if (stdout.toString().toLowerCase().indexOf('vmware') >= 0 && !result.virtualHost) {
result.virtualHost = 'VMware';
}
if (stdout.toString().toLowerCase().indexOf('qemu') >= 0 && !result.virtualHost) {
result.virtualHost = 'QEMU';
}
if (stdout.toString().toLowerCase().indexOf('xen') >= 0 && !result.virtualHost) {
result.virtualHost = 'Xen';
}
if (stdout.toString().toLowerCase().indexOf('kvm') >= 0 && !result.virtualHost) {
result.virtualHost = 'KVM';
}
}
} catch (e) {
util.noop();
}
if (result.manufacturer === '' && result.model === 'Computer' && result.version === '') {
// Check Raspberry Pi
fs.readFile('/proc/cpuinfo', function (error, stdout) {
if (!error) {
let lines = stdout.toString().split('\n');
result.model = util.getValue(lines, 'hardware', ':', true).toUpperCase();
result.version = util.getValue(lines, 'revision', ':', true).toLowerCase();
result.serial = util.getValue(lines, 'serial', ':', true);
const model = util.getValue(lines, 'model:', ':', true);
// reference values: https://elinux.org/RPi_HardwareHistory
// https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
if ((result.model === 'BCM2835' || result.model === 'BCM2708' || result.model === 'BCM2709' || result.model === 'BCM2710' || result.model === 'BCM2711' || result.model === 'BCM2836' || result.model === 'BCM2837') && model.toLowerCase().indexOf('raspberry') >= 0) {
const rPIRevision = util.decodePiCpuinfo(lines);
result.model = rPIRevision.model;
result.version = rPIRevision.revisionCode;
result.manufacturer = 'Raspberry Pi Foundation';
result.raspberry = {
manufacturer: rPIRevision.manufacturer,
processor: rPIRevision.processor,
type: rPIRevision.type,
revision: rPIRevision.revision
};
}
}
if (callback) { callback(result); }
resolve(result);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
});
}
if (_darwin) {
exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
if (!error) {
let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
const model = util.splitByNumber(util.getValue(lines, 'model', '=', true));
const version = util.getValue(lines, 'version', '=', true);
result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
result.model = version ? util.getValue(lines, 'model', '=', true) : model[0];
result.version = version || model[1];
result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
result.uuid = util.getValue(lines, 'ioplatformuuid', '=', true).toLowerCase();
result.sku = util.getValue(lines, 'board-id', '=', true) || util.getValue(lines, 'target-sub-type', '=', true);
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
if (callback) { callback(result); }
resolve(result);
}
if (_windows) {
try {
util.powerShell('Get-CimInstance Win32_ComputerSystemProduct | select Name,Vendor,Version,IdentifyingNumber,UUID | fl').then((stdout, error) => {
if (!error) {
let lines = stdout.split('\r\n');
result.manufacturer = util.getValue(lines, 'vendor', ':');
result.model = util.getValue(lines, 'name', ':');
result.version = util.getValue(lines, 'version', ':');
result.serial = util.getValue(lines, 'identifyingnumber', ':');
result.uuid = util.getValue(lines, 'uuid', ':').toLowerCase();
// detect virtual (1)
const model = result.model.toLowerCase();
if (model === 'virtualbox' || model === 'kvm' || model === 'virtual machine' || model === 'bochs' || model.startsWith('vmware') || model.startsWith('qemu') || model.startsWith('parallels')) {
result.virtual = true;
if (model.startsWith('virtualbox')) { result.virtualHost = 'VirtualBox'; }
if (model.startsWith('vmware')) { result.virtualHost = 'VMware'; }
if (model.startsWith('kvm')) { result.virtualHost = 'KVM'; }
if (model.startsWith('bochs')) { result.virtualHost = 'bochs'; }
if (model.startsWith('qemu')) { result.virtualHost = 'KVM'; }
if (model.startsWith('parallels')) { result.virtualHost = 'Parallels'; }
}
const manufacturer = result.manufacturer.toLowerCase();
if (manufacturer.startsWith('vmware') || manufacturer.startsWith('qemu') || manufacturer === 'xen' || manufacturer.startsWith('parallels')) {
result.virtual = true;
if (manufacturer.startsWith('vmware')) { result.virtualHost = 'VMware'; }
if (manufacturer.startsWith('xen')) { result.virtualHost = 'Xen'; }
if (manufacturer.startsWith('qemu')) { result.virtualHost = 'KVM'; }
if (manufacturer.startsWith('parallels')) { result.virtualHost = 'Parallels'; }
}
util.powerShell('Get-CimInstance MS_Systeminformation -Namespace "root/wmi" | select systemsku | fl ').then((stdout, error) => {
if (!error) {
let lines = stdout.split('\r\n');
result.sku = util.getValue(lines, 'systemsku', ':');
}
if (!result.virtual) {
util.powerShell('Get-CimInstance Win32_bios | select Version, SerialNumber, SMBIOSBIOSVersion').then((stdout, error) => {
if (!error) {
let lines = stdout.toString();
if (lines.indexOf('VRTUAL') >= 0 || lines.indexOf('A M I ') >= 0 || lines.indexOf('VirtualBox') >= 0 || lines.indexOf('VMWare') >= 0 || lines.indexOf('Xen') >= 0 || lines.indexOf('Parallels') >= 0) {
result.virtual = true;
if (lines.indexOf('VirtualBox') >= 0 && !result.virtualHost) {
result.virtualHost = 'VirtualBox';
}
if (lines.indexOf('VMware') >= 0 && !result.virtualHost) {
result.virtualHost = 'VMware';
}
if (lines.indexOf('Xen') >= 0 && !result.virtualHost) {
result.virtualHost = 'Xen';
}
if (lines.indexOf('VRTUAL') >= 0 && !result.virtualHost) {
result.virtualHost = 'Hyper-V';
}
if (lines.indexOf('A M I') >= 0 && !result.virtualHost) {
result.virtualHost = 'Virtual PC';
}
if (lines.indexOf('Parallels') >= 0 && !result.virtualHost) {
result.virtualHost = 'Parallels';
}
}
if (callback) { callback(result); }
resolve(result);
} else {
if (callback) { callback(result); }
resolve(result);
}
});
} else {
if (callback) { callback(result); }
resolve(result);
}
});
} else {
if (callback) { callback(result); }
resolve(result);
}
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.system = system;
function cleanDefaults(s) {
const cmpStr = s.toLowerCase();
if (cmpStr.indexOf('o.e.m.') === -1 && cmpStr.indexOf('default string') === -1 && cmpStr !== 'default') {
return s || '';
}
return '';
}
function bios(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
vendor: '',
version: '',
releaseDate: '',
revision: '',
};
let cmd = '';
if (_linux || _freebsd || _openbsd || _netbsd) {
if (process.arch === 'arm') {
cmd = 'cat /proc/cpuinfo | grep Serial';
} else {
cmd = 'export LC_ALL=C; dmidecode -t bios 2>/dev/null; unset LC_ALL';
}
exec(cmd, function (error, stdout) {
let lines = stdout.toString().split('\n');
result.vendor = util.getValue(lines, 'Vendor');
result.version = util.getValue(lines, 'Version');
let datetime = util.getValue(lines, 'Release Date');
result.releaseDate = util.parseDateTime(datetime).date;
result.revision = util.getValue(lines, 'BIOS Revision');
result.serial = util.getValue(lines, 'SerialNumber');
let language = util.getValue(lines, 'Currently Installed Language').split('|')[0];
if (language) {
result.language = language;
}
if (lines.length && stdout.toString().indexOf('Characteristics:') >= 0) {
const features = [];
lines.forEach(line => {
if (line.indexOf(' is supported') >= 0) {
const feature = line.split(' is supported')[0].trim();
features.push(feature);
}
});
result.features = features;
}
// Non-Root values
const cmd = `echo -n "bios_date: "; cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null; echo;
echo -n "bios_vendor: "; cat /sys/devices/virtual/dmi/id/bios_vendor 2>/dev/null; echo;
echo -n "bios_version: "; cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null; echo;`;
try {
lines = execSync(cmd).toString().split('\n');
result.vendor = !result.vendor ? util.getValue(lines, 'bios_vendor') : result.vendor;
result.version = !result.version ? util.getValue(lines, 'bios_version') : result.version;
datetime = util.getValue(lines, 'bios_date');
result.releaseDate = !result.releaseDate ? util.parseDateTime(datetime).date : result.releaseDate;
} catch (e) {
util.noop();
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_darwin) {
result.vendor = 'Apple Inc.';
exec(
'system_profiler SPHardwareDataType -json', function (error, stdout) {
try {
const hardwareData = JSON.parse(stdout.toString());
if (hardwareData && hardwareData.SPHardwareDataType && hardwareData.SPHardwareDataType.length) {
let bootRomVersion = hardwareData.SPHardwareDataType[0].boot_rom_version;
bootRomVersion = bootRomVersion ? bootRomVersion.split('(')[0].trim() : null;
result.version = bootRomVersion;
}
} catch (e) {
util.noop();
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
result.vendor = 'Sun Microsystems';
if (callback) { callback(result); }
resolve(result);
}
if (_windows) {
try {
util.powerShell('Get-CimInstance Win32_bios | select Description,Version,Manufacturer,@{n="ReleaseDate";e={$_.ReleaseDate.ToString("yyyy-MM-dd")}},BuildNumber,SerialNumber,SMBIOSBIOSVersion | fl').then((stdout, error) => {
if (!error) {
let lines = stdout.toString().split('\r\n');
const description = util.getValue(lines, 'description', ':');
const version = util.getValue(lines, 'SMBIOSBIOSVersion', ':');
if (description.indexOf(' Version ') !== -1) {
// ... Phoenix ROM BIOS PLUS Version 1.10 A04
result.vendor = description.split(' Version ')[0].trim();
result.version = description.split(' Version ')[1].trim();
} else if (description.indexOf(' Ver: ') !== -1) {
// ... BIOS Date: 06/27/16 17:50:16 Ver: 1.4.5
result.vendor = util.getValue(lines, 'manufacturer', ':');
result.version = description.split(' Ver: ')[1].trim();
} else {
result.vendor = util.getValue(lines, 'manufacturer', ':');
result.version = version || util.getValue(lines, 'version', ':');
}
result.releaseDate = util.getValue(lines, 'releasedate', ':');
result.revision = util.getValue(lines, 'buildnumber', ':');
result.serial = cleanDefaults(util.getValue(lines, 'serialnumber', ':'));
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.bios = bios;
function baseboard(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
manufacturer: '',
model: '',
version: '',
serial: '-',
assetTag: '-',
memMax: null,
memSlots: null
};
let cmd = '';
if (_linux || _freebsd || _openbsd || _netbsd) {
if (process.arch === 'arm') {
cmd = 'cat /proc/cpuinfo | grep Serial';
// 'BCM2709', 'BCM2835', 'BCM2708' -->
} else {
cmd = 'export LC_ALL=C; dmidecode -t 2 2>/dev/null; unset LC_ALL';
}
const workload = [];
workload.push(execPromise(cmd));
workload.push(execPromise('export LC_ALL=C; dmidecode -t memory 2>/dev/null'));
util.promiseAll(
workload
).then((data) => {
let lines = data.results[0] ? data.results[0].toString().split('\n') : [''];
result.manufacturer = util.getValue(lines, 'Manufacturer');
result.model = util.getValue(lines, 'Product Name');
result.version = util.getValue(lines, 'Version');
result.serial = util.getValue(lines, 'Serial Number');
result.assetTag = util.getValue(lines, 'Asset Tag');
// Non-Root values
const cmd = `echo -n "board_asset_tag: "; cat /sys/devices/virtual/dmi/id/board_asset_tag 2>/dev/null; echo;
echo -n "board_name: "; cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null; echo;
echo -n "board_serial: "; cat /sys/devices/virtual/dmi/id/board_serial 2>/dev/null; echo;
echo -n "board_vendor: "; cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null; echo;
echo -n "board_version: "; cat /sys/devices/virtual/dmi/id/board_version 2>/dev/null; echo;`;
try {
lines = execSync(cmd).toString().split('\n');
result.manufacturer = !result.manufacturer ? util.getValue(lines, 'board_vendor') : result.manufacturer;
result.model = !result.model ? util.getValue(lines, 'board_name') : result.model;
result.version = !result.version ? util.getValue(lines, 'board_version') : result.version;
result.serial = !result.serial ? util.getValue(lines, 'board_serial') : result.serial;
result.assetTag = !result.assetTag ? util.getValue(lines, 'board_asset_tag') : result.assetTag;
} catch (e) {
util.noop();
}
if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
// mem
lines = data.results[1] ? data.results[1].toString().split('\n') : [''];
result.memMax = util.toInt(util.getValue(lines, 'Maximum Capacity')) * 1024 * 1024 * 1024 || null;
result.memSlots = util.toInt(util.getValue(lines, 'Number Of Devices')) || null;
// raspberry
let linesRpi = '';
try {
linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
} catch (e) {
util.noop();
}
if (linesRpi) {
const hardware = util.getValue(linesRpi, 'hardware');
if (hardware.startsWith('BCM')) {
const rpi = util.decodePiCpuinfo(linesRpi);
result.manufacturer = rpi.manufacturer;
result.model = 'Raspberry Pi';
result.serial = rpi.serial;
result.version = rpi.type + ' - ' + rpi.revision;
result.memMax = os.totalmem();
result.memSlots = 0;
}
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_darwin) {
const workload = [];
workload.push(execPromise('ioreg -c IOPlatformExpertDevice -d 2'));
workload.push(execPromise('system_profiler SPMemoryDataType'));
util.promiseAll(
workload
).then((data) => {
let lines = data.results[0] ? data.results[0].toString().replace(/[<>"]/g, '').split('\n') : [''];
result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
result.model = util.getValue(lines, 'model', '=', true);
result.version = util.getValue(lines, 'version', '=', true);
result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
result.assetTag = util.getValue(lines, 'board-id', '=', true);
// mem
let devices = data.results[1] ? data.results[1].toString().split(' BANK ') : [''];
if (devices.length === 1) {
devices = data.results[1] ? data.results[1].toString().split(' DIMM') : [''];
}
devices.shift();
result.memSlots = devices.length;
if (os.arch() === 'arm64') {
result.memSlots = 0;
result.memMax = os.totalmem();
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
if (callback) { callback(result); }
resolve(result);
}
if (_windows) {
try {
const workload = [];
const win10plus = parseInt(os.release()) >= 10;
const maxCapacityAttribute = win10plus ? 'MaxCapacityEx' : 'MaxCapacity';
workload.push(util.powerShell('Get-CimInstance Win32_baseboard | select Model,Manufacturer,Product,Version,SerialNumber,PartNumber,SKU | fl'));
workload.push(util.powerShell(`Get-CimInstance Win32_physicalmemoryarray | select ${maxCapacityAttribute}, MemoryDevices | fl`));
util.promiseAll(
workload
).then((data) => {
let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
result.manufacturer = cleanDefaults(util.getValue(lines, 'manufacturer', ':'));
result.model = cleanDefaults(util.getValue(lines, 'model', ':'));
if (!result.model) {
result.model = cleanDefaults(util.getValue(lines, 'product', ':'));
}
result.version = cleanDefaults(util.getValue(lines, 'version', ':'));
result.serial = cleanDefaults(util.getValue(lines, 'serialnumber', ':'));
result.assetTag = cleanDefaults(util.getValue(lines, 'partnumber', ':'));
if (!result.assetTag) {
result.assetTag = cleanDefaults(util.getValue(lines, 'sku', ':'));
}
// memphysical
lines = data.results[1] ? data.results[1].toString().split('\r\n') : [''];
result.memMax = util.toInt(util.getValue(lines, maxCapacityAttribute, ':')) * (win10plus ? 1024 : 1) || null;
result.memSlots = util.toInt(util.getValue(lines, 'MemoryDevices', ':')) || null;
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.baseboard = baseboard;
function macOsChassisType(model) {
model = model.toLowerCase();
if (model.startsWith('macbookair')) { return 'Notebook'; }
if (model.startsWith('macbookpro')) { return 'Laptop'; }
if (model.startsWith('macbook')) { return 'Notebook'; }
if (model.startsWith('macmini')) { return 'Desktop'; }
if (model.startsWith('imac')) { return 'Desktop'; }
if (model.startsWith('macstudio')) { return 'Desktop'; }
if (model.startsWith('macpro')) { return 'Tower'; }
return 'Other';
}
function chassis(callback) {
const chassisTypes = ['Other',
'Unknown',
'Desktop',
'Low Profile Desktop',
'Pizza Box',
'Mini Tower',
'Tower',
'Portable',
'Laptop',
'Notebook',
'Hand Held',
'Docking Station',
'All in One',
'Sub Notebook',
'Space-Saving',
'Lunch Box',
'Main System Chassis',
'Expansion Chassis',
'SubChassis',
'Bus Expansion Chassis',
'Peripheral Chassis',
'Storage Chassis',
'Rack Mount Chassis',
'Sealed-Case PC',
'Multi-System Chassis',
'Compact PCI',
'Advanced TCA',
'Blade',
'Blade Enclosure',
'Tablet',
'Convertible',
'Detachable',
'IoT Gateway ',
'Embedded PC',
'Mini PC',
'Stick PC',
];
return new Promise((resolve) => {
process.nextTick(() => {
let result = {
manufacturer: '',
model: '',
type: '',
version: '',
serial: '-',
assetTag: '-',
sku: '',
};
if (_linux || _freebsd || _openbsd || _netbsd) {
const cmd = `echo -n "chassis_asset_tag: "; cat /sys/devices/virtual/dmi/id/chassis_asset_tag 2>/dev/null; echo;
echo -n "chassis_serial: "; cat /sys/devices/virtual/dmi/id/chassis_serial 2>/dev/null; echo;
echo -n "chassis_type: "; cat /sys/devices/virtual/dmi/id/chassis_type 2>/dev/null; echo;
echo -n "chassis_vendor: "; cat /sys/devices/virtual/dmi/id/chassis_vendor 2>/dev/null; echo;
echo -n "chassis_version: "; cat /sys/devices/virtual/dmi/id/chassis_version 2>/dev/null; echo;`;
exec(cmd, function (error, stdout) {
let lines = stdout.toString().split('\n');
result.manufacturer = util.getValue(lines, 'chassis_vendor');
const ctype = parseInt(util.getValue(lines, 'chassis_type').replace(/\D/g, ''));
result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
result.version = util.getValue(lines, 'chassis_version');
result.serial = util.getValue(lines, 'chassis_serial');
result.assetTag = util.getValue(lines, 'chassis_asset_tag');
if (result.manufacturer.toLowerCase().indexOf('o.e.m.') !== -1) { result.manufacturer = '-'; }
if (result.version.toLowerCase().indexOf('o.e.m.') !== -1) { result.version = '-'; }
if (result.serial.toLowerCase().indexOf('o.e.m.') !== -1) { result.serial = '-'; }
if (result.assetTag.toLowerCase().indexOf('o.e.m.') !== -1) { result.assetTag = '-'; }
if (callback) { callback(result); }
resolve(result);
});
}
if (_darwin) {
exec('ioreg -c IOPlatformExpertDevice -d 2', function (error, stdout) {
if (!error) {
let lines = stdout.toString().replace(/[<>"]/g, '').split('\n');
const model = util.getValue(lines, 'model', '=', true);
const modelParts = util.splitByNumber(model);
const version = util.getValue(lines, 'version', '=', true);
result.manufacturer = util.getValue(lines, 'manufacturer', '=', true);
result.model = version ? util.getValue(lines, 'model', '=', true) : modelParts[0];
result.type = macOsChassisType(result.model);
result.version = version || model;
result.serial = util.getValue(lines, 'ioplatformserialnumber', '=', true);
result.assetTag = util.getValue(lines, 'board-id', '=', true) || util.getValue(lines, 'target-type', '=', true);
result.sku = util.getValue(lines, 'target-sub-type', '=', true);
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
if (callback) { callback(result); }
resolve(result);
}
if (_windows) {
try {
util.powerShell('Get-CimInstance Win32_SystemEnclosure | select Model,Manufacturer,ChassisTypes,Version,SerialNumber,PartNumber,SKU,SMBIOSAssetTag | fl').then((stdout, error) => {
if (!error) {
let lines = stdout.toString().split('\r\n');
result.manufacturer = cleanDefaults(util.getValue(lines, 'manufacturer', ':'));
result.model = cleanDefaults(util.getValue(lines, 'model', ':'));
const ctype = parseInt(util.getValue(lines, 'ChassisTypes', ':').replace(/\D/g, ''));
result.type = (ctype && !isNaN(ctype) && ctype < chassisTypes.length) ? chassisTypes[ctype - 1] : '';
result.version = cleanDefaults(util.getValue(lines, 'version', ':'));
result.serial = cleanDefaults(util.getValue(lines, 'serialnumber', ':'));
result.assetTag = cleanDefaults(util.getValue(lines, 'partnumber', ':'));
if (!result.assetTag) {
result.assetTag = cleanDefaults(util.getValue(lines, 'SMBIOSAssetTag', ':'));
}
result.sku = cleanDefaults(util.getValue(lines, 'sku', ':'));
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
exports.chassis = chassis;

274
spa/node_modules/systeminformation/lib/usb.js generated vendored Normal file
View File

@@ -0,0 +1,274 @@
'use strict';
// @ts-check
// ==================================================================================
// usb.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 16. usb
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function getLinuxUsbType(type, name) {
let result = type;
const str = (name + ' ' + type).toLowerCase();
if (str.indexOf('camera') >= 0) { result = 'Camera'; }
else if (str.indexOf('hub') >= 0) { result = 'Hub'; }
else if (str.indexOf('keybrd') >= 0) { result = 'Keyboard'; }
else if (str.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
else if (str.indexOf('mouse') >= 0) { result = 'Mouse'; }
else if (str.indexOf('stora') >= 0) { result = 'Storage'; }
else if (str.indexOf('mic') >= 0) { result = 'Microphone'; }
else if (str.indexOf('headset') >= 0) { result = 'Audio'; }
else if (str.indexOf('audio') >= 0) { result = 'Audio'; }
return result;
}
function parseLinuxUsb(usb) {
const result = {};
const lines = usb.split('\n');
if (lines && lines.length && lines[0].indexOf('Device') >= 0) {
const parts = lines[0].split(' ');
result.bus = parseInt(parts[0], 10);
if (parts[2]) {
result.deviceId = parseInt(parts[2], 10);
} else {
result.deviceId = null;
}
} else {
result.bus = null;
result.deviceId = null;
}
const idVendor = util.getValue(lines, 'idVendor', ' ', true).trim();
let vendorParts = idVendor.split(' ');
vendorParts.shift();
const vendor = vendorParts.join(' ');
const idProduct = util.getValue(lines, 'idProduct', ' ', true).trim();
let productParts = idProduct.split(' ');
productParts.shift();
const product = productParts.join(' ');
const interfaceClass = util.getValue(lines, 'bInterfaceClass', ' ', true).trim();
let interfaceClassParts = interfaceClass.split(' ');
interfaceClassParts.shift();
const usbType = interfaceClassParts.join(' ');
const iManufacturer = util.getValue(lines, 'iManufacturer', ' ', true).trim();
let iManufacturerParts = iManufacturer.split(' ');
iManufacturerParts.shift();
const manufacturer = iManufacturerParts.join(' ');
result.id = (idVendor.startsWith('0x') ? idVendor.split(' ')[0].substr(2, 10) : '') + ':' + (idProduct.startsWith('0x') ? idProduct.split(' ')[0].substr(2, 10) : '');
result.name = product;
result.type = getLinuxUsbType(usbType, product);
result.removable = null;
result.vendor = vendor;
result.manufacturer = manufacturer;
result.maxPower = util.getValue(lines, 'MaxPower', ' ', true);
result.serialNumber = null;
return result;
}
function getDarwinUsbType(name) {
let result = '';
if (name.indexOf('camera') >= 0) { result = 'Camera'; }
else if (name.indexOf('touch bar') >= 0) { result = 'Touch Bar'; }
else if (name.indexOf('controller') >= 0) { result = 'Controller'; }
else if (name.indexOf('headset') >= 0) { result = 'Audio'; }
else if (name.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
else if (name.indexOf('trackpad') >= 0) { result = 'Trackpad'; }
else if (name.indexOf('sensor') >= 0) { result = 'Sensor'; }
else if (name.indexOf('bthusb') >= 0) { result = 'Bluetooth'; }
else if (name.indexOf('bth') >= 0) { result = 'Bluetooth'; }
else if (name.indexOf('rfcomm') >= 0) { result = 'Bluetooth'; }
else if (name.indexOf('usbhub') >= 0) { result = 'Hub'; }
else if (name.indexOf(' hub') >= 0) { result = 'Hub'; }
else if (name.indexOf('mouse') >= 0) { result = 'Mouse'; }
else if (name.indexOf('mic') >= 0) { result = 'Microphone'; }
else if (name.indexOf('removable') >= 0) { result = 'Storage'; }
return result;
}
function parseDarwinUsb(usb, id) {
const result = {};
result.id = id;
usb = usb.replace(/ \|/g, '');
usb = usb.trim();
let lines = usb.split('\n');
lines.shift();
try {
for (let i = 0; i < lines.length; i++) {
lines[i] = lines[i].trim();
lines[i] = lines[i].replace(/=/g, ':');
if (lines[i] !== '{' && lines[i] !== '}' && lines[i + 1] && lines[i + 1].trim() !== '}') {
lines[i] = lines[i] + ',';
}
lines[i] = lines[i].replace(':Yes,', ':"Yes",');
lines[i] = lines[i].replace(': Yes,', ': "Yes",');
lines[i] = lines[i].replace(': Yes', ': "Yes"');
lines[i] = lines[i].replace(':No,', ':"No",');
lines[i] = lines[i].replace(': No,', ': "No",');
lines[i] = lines[i].replace(': No', ': "No"');
// In this case (("com.apple.developer.driverkit.transport.usb"))
lines[i] = lines[i].replace('((', '').replace('))', '');
// In case we have <923c11> we need make it "<923c11>" for correct JSON parse
const match = /<(\w+)>/.exec(lines[i]);
if (match) {
const number = match[0];
lines[i] = lines[i].replace(number, `"${number}"`);
}
}
const usbObj = JSON.parse(lines.join('\n'));
const removableDrive = (usbObj['Built-In'] ? usbObj['Built-In'].toLowerCase() !== 'yes' : true) && (usbObj['non-removable'] ? usbObj['non-removable'].toLowerCase() === 'no' : true);
result.bus = null;
result.deviceId = null;
result.id = usbObj['USB Address'] || null;
result.name = usbObj['kUSBProductString'] || usbObj['USB Product Name'] || null;
result.type = getDarwinUsbType((usbObj['kUSBProductString'] || usbObj['USB Product Name'] || '').toLowerCase() + (removableDrive ? ' removable' : ''));
result.removable = usbObj['non-removable'] ? usbObj['non-removable'].toLowerCase() || '' === 'no' : true;
result.vendor = usbObj['kUSBVendorString'] || usbObj['USB Vendor Name'] || null;
result.manufacturer = usbObj['kUSBVendorString'] || usbObj['USB Vendor Name'] || null;
result.maxPower = null;
result.serialNumber = usbObj['kUSBSerialNumberString'] || null;
if (result.name) {
return result;
} else {
return null;
}
} catch (e) {
return null;
}
}
function getWindowsUsbTypeCreation(creationclass, name) {
let result = '';
if (name.indexOf('storage') >= 0) { result = 'Storage'; }
else if (name.indexOf('speicher') >= 0) { result = 'Storage'; }
else if (creationclass.indexOf('usbhub') >= 0) { result = 'Hub'; }
else if (creationclass.indexOf('storage') >= 0) { result = 'Storage'; }
else if (creationclass.indexOf('usbcontroller') >= 0) { result = 'Controller'; }
else if (creationclass.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
else if (creationclass.indexOf('pointing') >= 0) { result = 'Mouse'; }
else if (creationclass.indexOf('disk') >= 0) { result = 'Storage'; }
return result;
}
function parseWindowsUsb(lines, id) {
const usbType = getWindowsUsbTypeCreation(util.getValue(lines, 'CreationClassName', ':').toLowerCase(), util.getValue(lines, 'name', ':').toLowerCase());
if (usbType) {
const result = {};
result.bus = null;
result.deviceId = util.getValue(lines, 'deviceid', ':');
result.id = id;
result.name = util.getValue(lines, 'name', ':');
result.type = usbType;
result.removable = null;
result.vendor = null;
result.manufacturer = util.getValue(lines, 'Manufacturer', ':');
result.maxPower = null;
result.serialNumber = null;
return result;
} else {
return null;
}
}
function usb(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
if (_linux) {
const cmd = 'export LC_ALL=C; lsusb -v 2>/dev/null; unset LC_ALL';
exec(cmd, { maxBuffer: 1024 * 1024 * 128 }, function (error, stdout) {
if (!error) {
const parts = ('\n\n' + stdout.toString()).split('\n\nBus ');
for (let i = 1; i < parts.length; i++) {
const usb = parseLinuxUsb(parts[i]);
result.push(usb);
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_darwin) {
let cmd = 'ioreg -p IOUSB -c AppleUSBRootHubDevice -w0 -l';
exec(cmd, { maxBuffer: 1024 * 1024 * 128 }, function (error, stdout) {
if (!error) {
const parts = (stdout.toString()).split(' +-o ');
for (let i = 1; i < parts.length; i++) {
const usb = parseDarwinUsb(parts[i]);
if (usb) {
result.push(usb);
}
}
if (callback) {
callback(result);
}
resolve(result);
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_windows) {
util.powerShell('Get-CimInstance CIM_LogicalDevice | where { $_.Description -match "USB"} | select Name,CreationClassName,DeviceId,Manufacturer | fl').then((stdout, error) => {
if (!error) {
const parts = stdout.toString().split(/\n\s*\n/);
for (let i = 0; i < parts.length; i++) {
const usb = parseWindowsUsb(parts[i].split('\n'), i);
if (usb) {
result.push(usb);
}
}
}
if (callback) {
callback(result);
}
resolve(result);
});
}
if (_sunos || _freebsd || _openbsd || _netbsd) {
resolve(null);
}
});
});
}
exports.usb = usb;

363
spa/node_modules/systeminformation/lib/users.js generated vendored Normal file
View File

@@ -0,0 +1,363 @@
'use strict';
// @ts-check
// ==================================================================================
// users.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 11. Users/Sessions
// ----------------------------------------------------------------------------------
const exec = require('child_process').exec;
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function parseUsersLinux(lines, phase) {
let result = [];
let result_who = [];
let result_w = {};
let w_first = true;
let w_header = [];
let w_pos = [];
let who_line = {};
let is_whopart = true;
lines.forEach(function (line) {
if (line === '---') {
is_whopart = false;
} else {
let l = line.replace(/ +/g, ' ').split(' ');
// who part
if (is_whopart) {
result_who.push({
user: l[0],
tty: l[1],
date: l[2],
time: l[3],
ip: (l && l.length > 4) ? l[4].replace(/\(/g, '').replace(/\)/g, '') : ''
});
} else {
// w part
if (w_first) { // header
w_header = l;
w_header.forEach(function (item) {
w_pos.push(line.indexOf(item));
});
w_first = false;
} else {
// split by w_pos
result_w.user = line.substring(w_pos[0], w_pos[1] - 1).trim();
result_w.tty = line.substring(w_pos[1], w_pos[2] - 1).trim();
result_w.ip = line.substring(w_pos[2], w_pos[3] - 1).replace(/\(/g, '').replace(/\)/g, '').trim();
result_w.command = line.substring(w_pos[7], 1000).trim();
// find corresponding 'who' line
who_line = result_who.filter(function (obj) {
return (obj.user.substring(0, 8).trim() === result_w.user && obj.tty === result_w.tty);
});
if (who_line.length === 1) {
result.push({
user: who_line[0].user,
tty: who_line[0].tty,
date: who_line[0].date,
time: who_line[0].time,
ip: who_line[0].ip,
command: result_w.command
});
}
}
}
}
});
if (result.length === 0 && phase === 2) {
return result_who;
} else {
return result;
}
}
function parseUsersDarwin(lines) {
let result = [];
let result_who = [];
let result_w = {};
let who_line = {};
let is_whopart = true;
lines.forEach(function (line) {
if (line === '---') {
is_whopart = false;
} else {
let l = line.replace(/ +/g, ' ').split(' ');
// who part
if (is_whopart) {
result_who.push({
user: l[0],
tty: l[1],
date: ('' + new Date().getFullYear()) + '-' + ('0' + ('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.indexOf(l[2].toUpperCase()) / 3 + 1)).slice(-2) + '-' + ('0' + l[3]).slice(-2),
time: l[4],
});
} else {
// w part
// split by w_pos
result_w.user = l[0];
result_w.tty = l[1];
result_w.ip = (l[2] !== '-') ? l[2] : '';
result_w.command = l.slice(5, 1000).join(' ');
// find corresponding 'who' line
who_line = result_who.filter(function (obj) {
return (obj.user === result_w.user && (obj.tty.substring(3, 1000) === result_w.tty || obj.tty === result_w.tty));
});
if (who_line.length === 1) {
result.push({
user: who_line[0].user,
tty: who_line[0].tty,
date: who_line[0].date,
time: who_line[0].time,
ip: result_w.ip,
command: result_w.command
});
}
}
}
});
return result;
}
function users(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
// linux
if (_linux) {
exec('who --ips; echo "---"; w | tail -n +2', function (error, stdout) {
if (!error) {
// lines / split
let lines = stdout.toString().split('\n');
result = parseUsersLinux(lines, 1);
if (result.length === 0) {
exec('who; echo "---"; w | tail -n +2', function (error, stdout) {
if (!error) {
// lines / split
lines = stdout.toString().split('\n');
result = parseUsersLinux(lines, 2);
}
if (callback) { callback(result); }
resolve(result);
});
} else {
if (callback) { callback(result); }
resolve(result);
}
} else {
if (callback) { callback(result); }
resolve(result);
}
});
}
if (_freebsd || _openbsd || _netbsd) {
exec('who; echo "---"; w -ih', function (error, stdout) {
if (!error) {
// lines / split
let lines = stdout.toString().split('\n');
result = parseUsersDarwin(lines);
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_sunos) {
exec('who; echo "---"; w -h', function (error, stdout) {
if (!error) {
// lines / split
let lines = stdout.toString().split('\n');
result = parseUsersDarwin(lines);
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_darwin) {
exec('who; echo "---"; w -ih', function (error, stdout) {
if (!error) {
// lines / split
let lines = stdout.toString().split('\n');
result = parseUsersDarwin(lines);
}
if (callback) { callback(result); }
resolve(result);
});
}
if (_windows) {
try {
let cmd = 'Get-CimInstance Win32_LogonSession | select LogonId,@{n="StartTime";e={$_.StartTime.ToString("yyyy-MM-dd HH:mm:ss")}} | fl' + '; echo \'#-#-#-#\';';
cmd += 'Get-CimInstance Win32_LoggedOnUser | select antecedent,dependent | fl ' + '; echo \'#-#-#-#\';';
cmd += '$process = (Get-CimInstance Win32_Process -Filter "name = \'explorer.exe\'"); Invoke-CimMethod -InputObject $process[0] -MethodName GetOwner | select user, domain | fl; get-process -name explorer | select-object sessionid | fl; echo \'#-#-#-#\';';
cmd += 'query user';
util.powerShell(cmd).then((data) => {
if (data) {
data = data.split('#-#-#-#');
let sessions = parseWinSessions((data[0] || '').split(/\n\s*\n/));
let loggedons = parseWinLoggedOn((data[1] || '').split(/\n\s*\n/));
let queryUser = parseWinUsersQuery((data[3] || '').split('\r\n'));
let users = parseWinUsers((data[2] || '').split(/\n\s*\n/), queryUser);
for (let id in loggedons) {
if ({}.hasOwnProperty.call(loggedons, id)) {
loggedons[id].dateTime = {}.hasOwnProperty.call(sessions, id) ? sessions[id] : '';
}
}
users.forEach(user => {
let dateTime = '';
for (let id in loggedons) {
if ({}.hasOwnProperty.call(loggedons, id)) {
if (loggedons[id].user === user.user && (!dateTime || dateTime < loggedons[id].dateTime)) {
dateTime = loggedons[id].dateTime;
}
}
}
result.push({
user: user.user,
tty: user.tty,
date: `${dateTime.substring(0, 10)}`,
time: `${dateTime.substring(11, 19)}`,
ip: '',
command: ''
});
});
}
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
}
});
});
}
function parseWinSessions(sessionParts) {
const sessions = {};
sessionParts.forEach(session => {
const lines = session.split('\r\n');
const id = util.getValue(lines, 'LogonId');
const starttime = util.getValue(lines, 'starttime');
if (id) {
sessions[id] = starttime;
}
});
return sessions;
}
function fuzzyMatch(name1, name2) {
name1 = name1.toLowerCase();
name2 = name2.toLowerCase();
let eq = 0;
let len = name1.length;
if (name2.length > len) { len = name2.length; }
for (let i = 0; i < len; i++) {
const c1 = name1[i] || '';
const c2 = name2[i] || '';
if (c1 === c2) { eq++; }
}
return (len > 10 ? eq / len > 0.9 : (len > 0 ? eq / len > 0.8 : false));
}
function parseWinUsers(userParts, userQuery) {
const users = [];
userParts.forEach(user => {
const lines = user.split('\r\n');
const domain = util.getValue(lines, 'domain', ':', true);
const username = util.getValue(lines, 'user', ':', true);
const sessionid = util.getValue(lines, 'sessionid', ':', true);
if (username) {
const quser = userQuery.filter(item => fuzzyMatch(item.user, username));
users.push({
domain,
user: username,
tty: quser && quser[0] && quser[0].tty ? quser[0].tty : sessionid
});
}
});
return users;
}
function parseWinLoggedOn(loggedonParts) {
const loggedons = {};
loggedonParts.forEach(loggedon => {
const lines = loggedon.split('\r\n');
const antecendent = util.getValue(lines, 'antecedent', ':', true);
let parts = antecendent.split('=');
const name = parts.length > 2 ? parts[1].split(',')[0].replace(/"/g, '').trim() : '';
const domain = parts.length > 2 ? parts[2].replace(/"/g, '').replace(/\)/g, '').trim() : '';
const dependent = util.getValue(lines, 'dependent', ':', true);
parts = dependent.split('=');
const id = parts.length > 1 ? parts[1].replace(/"/g, '').replace(/\)/g, '').trim() : '';
if (id) {
loggedons[id] = {
domain,
user: name
};
}
});
return loggedons;
}
function parseWinUsersQuery(lines) {
lines = lines.filter(item => item);
let result = [];
const header = lines[0];
const headerDelimiter = [];
if (header) {
const start = (header[0] === ' ') ? 1 : 0;
headerDelimiter.push(start - 1);
let nextSpace = 0;
for (let i = start + 1; i < header.length; i++) {
if (header[i] === ' ' && ((header[i - 1] === ' ') || (header[i - 1] === '.'))) {
nextSpace = i;
} else {
if (nextSpace) {
headerDelimiter.push(nextSpace);
nextSpace = 0;
}
}
}
for (let i = 1; i < lines.length; i++) {
if (lines[i].trim()) {
const user = lines[i].substring(headerDelimiter[0] + 1, headerDelimiter[1]).trim() || '';
const tty = lines[i].substring(headerDelimiter[1] + 1, headerDelimiter[2] - 2).trim() || '';
result.push({
user: user,
tty: tty,
});
}
}
}
return result;
}
exports.users = users;

1366
spa/node_modules/systeminformation/lib/util.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

107
spa/node_modules/systeminformation/lib/virtualbox.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
'use strict';
// @ts-check
// ==================================================================================
// virtualbox.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 14. Docker
// ----------------------------------------------------------------------------------
const os = require('os');
const exec = require('child_process').exec;
const util = require('./util');
function vboxInfo(callback) {
// fallback - if only callback is given
let result = [];
return new Promise((resolve) => {
process.nextTick(() => {
try {
exec(util.getVboxmanage() + ' list vms --long', function (error, stdout) {
let parts = (os.EOL + stdout.toString()).split(os.EOL + 'Name:');
parts.shift();
parts.forEach(part => {
const lines = ('Name:' + part).split(os.EOL);
const state = util.getValue(lines, 'State');
const running = state.startsWith('running');
const runningSinceString = running ? state.replace('running (since ', '').replace(')', '').trim() : '';
let runningSince = 0;
try {
if (running) {
const sinceDateObj = new Date(runningSinceString);
const offset = sinceDateObj.getTimezoneOffset();
runningSince = Math.round((Date.now() - Date.parse(sinceDateObj)) / 1000) + offset * 60;
}
} catch (e) {
util.noop();
}
const stoppedSinceString = !running ? state.replace('powered off (since', '').replace(')', '').trim() : '';
let stoppedSince = 0;
try {
if (!running) {
const sinceDateObj = new Date(stoppedSinceString);
const offset = sinceDateObj.getTimezoneOffset();
stoppedSince = Math.round((Date.now() - Date.parse(sinceDateObj)) / 1000) + offset * 60;
}
} catch (e) {
util.noop();
}
result.push({
id: util.getValue(lines, 'UUID'),
name: util.getValue(lines, 'Name'),
running,
started: runningSinceString,
runningSince,
stopped: stoppedSinceString,
stoppedSince,
guestOS: util.getValue(lines, 'Guest OS'),
hardwareUUID: util.getValue(lines, 'Hardware UUID'),
memory: parseInt(util.getValue(lines, 'Memory size', ' '), 10),
vram: parseInt(util.getValue(lines, 'VRAM size'), 10),
cpus: parseInt(util.getValue(lines, 'Number of CPUs'), 10),
cpuExepCap: util.getValue(lines, 'CPU exec cap'),
cpuProfile: util.getValue(lines, 'CPUProfile'),
chipset: util.getValue(lines, 'Chipset'),
firmware: util.getValue(lines, 'Firmware'),
pageFusion: util.getValue(lines, 'Page Fusion') === 'enabled',
configFile: util.getValue(lines, 'Config file'),
snapshotFolder: util.getValue(lines, 'Snapshot folder'),
logFolder: util.getValue(lines, 'Log folder'),
hpet: util.getValue(lines, 'HPET') === 'enabled',
pae: util.getValue(lines, 'PAE') === 'enabled',
longMode: util.getValue(lines, 'Long Mode') === 'enabled',
tripleFaultReset: util.getValue(lines, 'Triple Fault Reset') === 'enabled',
apic: util.getValue(lines, 'APIC') === 'enabled',
x2Apic: util.getValue(lines, 'X2APIC') === 'enabled',
acpi: util.getValue(lines, 'ACPI') === 'enabled',
ioApic: util.getValue(lines, 'IOAPIC') === 'enabled',
biosApicMode: util.getValue(lines, 'BIOS APIC mode'),
bootMenuMode: util.getValue(lines, 'Boot menu mode'),
bootDevice1: util.getValue(lines, 'Boot Device 1'),
bootDevice2: util.getValue(lines, 'Boot Device 2'),
bootDevice3: util.getValue(lines, 'Boot Device 3'),
bootDevice4: util.getValue(lines, 'Boot Device 4'),
timeOffset: util.getValue(lines, 'Time offset'),
rtc: util.getValue(lines, 'RTC'),
});
});
if (callback) { callback(result); }
resolve(result);
});
} catch (e) {
if (callback) { callback(result); }
resolve(result);
}
});
});
}
exports.vboxInfo = vboxInfo;

834
spa/node_modules/systeminformation/lib/wifi.js generated vendored Normal file
View File

@@ -0,0 +1,834 @@
'use strict';
// @ts-check
// ==================================================================================
// wifi.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2024
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 9. wifi
// ----------------------------------------------------------------------------------
const os = require('os');
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const util = require('./util');
let _platform = process.platform;
const _linux = (_platform === 'linux' || _platform === 'android');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
function wifiDBFromQuality(quality) {
const qual = parseFloat(quality);
if (qual < 0) { return 0; }
if (qual >= 100) { return -50; }
return (qual / 2 - 100);
}
function wifiQualityFromDB(db) {
const result = 2 * (parseFloat(db) + 100);
return result <= 100 ? result : 100;
}
const _wifi_frequencies = {
1: 2412,
2: 2417,
3: 2422,
4: 2427,
5: 2432,
6: 2437,
7: 2442,
8: 2447,
9: 2452,
10: 2457,
11: 2462,
12: 2467,
13: 2472,
14: 2484,
32: 5160,
34: 5170,
36: 5180,
38: 5190,
40: 5200,
42: 5210,
44: 5220,
46: 5230,
48: 5240,
50: 5250,
52: 5260,
54: 5270,
56: 5280,
58: 5290,
60: 5300,
62: 5310,
64: 5320,
68: 5340,
96: 5480,
100: 5500,
102: 5510,
104: 5520,
106: 5530,
108: 5540,
110: 5550,
112: 5560,
114: 5570,
116: 5580,
118: 5590,
120: 5600,
122: 5610,
124: 5620,
126: 5630,
128: 5640,
132: 5660,
134: 5670,
136: 5680,
138: 5690,
140: 5700,
142: 5710,
144: 5720,
149: 5745,
151: 5755,
153: 5765,
155: 5775,
157: 5785,
159: 5795,
161: 5805,
165: 5825,
169: 5845,
173: 5865,
183: 4915,
184: 4920,
185: 4925,
187: 4935,
188: 4940,
189: 4945,
192: 4960,
196: 4980
};
function wifiFrequencyFromChannel(channel) {
return {}.hasOwnProperty.call(_wifi_frequencies, channel) ? _wifi_frequencies[channel] : null;
}
function wifiChannelFromFrequencs(frequency) {
let channel = 0;
for (let key in _wifi_frequencies) {
if ({}.hasOwnProperty.call(_wifi_frequencies, key)) {
if (_wifi_frequencies[key] === frequency) { channel = util.toInt(key); }
}
}
return channel;
}
function ifaceListLinux() {
const result = [];
const cmd = 'iw dev 2>/dev/null';
try {
const all = execSync(cmd).toString().split('\n').map(line => line.trim()).join('\n');
const parts = all.split('\nInterface ');
parts.shift();
parts.forEach(ifaceDetails => {
const lines = ifaceDetails.split('\n');
const iface = lines[0];
const id = util.toInt(util.getValue(lines, 'ifindex', ' '));
const mac = util.getValue(lines, 'addr', ' ');
const channel = util.toInt(util.getValue(lines, 'channel', ' '));
result.push({
id,
iface,
mac,
channel
});
});
return result;
} catch (e) {
try {
const all = execSync('nmcli -t -f general,wifi-properties,wired-properties,interface-flags,capabilities,nsp device show 2>/dev/null').toString();
const parts = all.split('\n\n');
let i = 1;
parts.forEach(ifaceDetails => {
const lines = ifaceDetails.split('\n');
const iface = util.getValue(lines, 'GENERAL.DEVICE');
const type = util.getValue(lines, 'GENERAL.TYPE');
const id = i++; // // util.getValue(lines, 'GENERAL.PATH');
const mac = util.getValue(lines, 'GENERAL.HWADDR');
const channel = '';
if (type.toLowerCase() === 'wifi') {
result.push({
id,
iface,
mac,
channel
});
}
});
return result;
} catch (e) {
return [];
}
}
}
function nmiDeviceLinux(iface) {
const cmd = `nmcli -t -f general,wifi-properties,capabilities,ip4,ip6 device show ${iface} 2>/dev/null`;
try {
const lines = execSync(cmd).toString().split('\n');
const ssid = util.getValue(lines, 'GENERAL.CONNECTION');
return {
iface,
type: util.getValue(lines, 'GENERAL.TYPE'),
vendor: util.getValue(lines, 'GENERAL.VENDOR'),
product: util.getValue(lines, 'GENERAL.PRODUCT'),
mac: util.getValue(lines, 'GENERAL.HWADDR').toLowerCase(),
ssid: ssid !== '--' ? ssid : null
};
} catch (e) {
return {};
}
}
function nmiConnectionLinux(ssid) {
const cmd = `nmcli -t --show-secrets connection show ${ssid} 2>/dev/null`;
try {
const lines = execSync(cmd).toString().split('\n');
const bssid = util.getValue(lines, '802-11-wireless.seen-bssids').toLowerCase();
return {
ssid: ssid !== '--' ? ssid : null,
uuid: util.getValue(lines, 'connection.uuid'),
type: util.getValue(lines, 'connection.type'),
autoconnect: util.getValue(lines, 'connection.autoconnect') === 'yes',
security: util.getValue(lines, '802-11-wireless-security.key-mgmt'),
bssid: bssid !== '--' ? bssid : null
};
} catch (e) {
return {};
}
}
function wpaConnectionLinux(iface) {
if (!iface) {
return {};
}
const cmd = `wpa_cli -i ${iface} status 2>&1`;
try {
const lines = execSync(cmd).toString().split('\n');
const freq = util.toInt(util.getValue(lines, 'freq', '='));
return {
ssid: util.getValue(lines, 'ssid', '='),
uuid: util.getValue(lines, 'uuid', '='),
security: util.getValue(lines, 'key_mgmt', '='),
freq,
channel: wifiChannelFromFrequencs(freq),
bssid: util.getValue(lines, 'bssid', '=').toLowerCase()
};
} catch (e) {
return {};
}
}
function getWifiNetworkListNmi() {
const result = [];
const cmd = 'nmcli -t -m multiline --fields active,ssid,bssid,mode,chan,freq,signal,security,wpa-flags,rsn-flags device wifi list 2>/dev/null';
try {
const stdout = execSync(cmd, { maxBuffer: 1024 * 20000 });
const parts = stdout.toString().split('ACTIVE:');
parts.shift();
parts.forEach(part => {
part = 'ACTIVE:' + part;
const lines = part.split(os.EOL);
const channel = util.getValue(lines, 'CHAN');
const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim();
const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '');
const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '');
const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '');
const quality = util.getValue(lines, 'SIGNAL');
result.push({
ssid: util.getValue(lines, 'SSID'),
bssid: util.getValue(lines, 'BSSID').toLowerCase(),
mode: util.getValue(lines, 'MODE'),
channel: channel ? parseInt(channel, 10) : null,
frequency: frequency ? parseInt(frequency, 10) : null,
signalLevel: wifiDBFromQuality(quality),
quality: quality ? parseInt(quality, 10) : null,
security: security && security !== 'none' ? security.split(' ') : [],
wpaFlags: wpaFlags && wpaFlags !== 'none' ? wpaFlags.split(' ') : [],
rsnFlags: rsnFlags && rsnFlags !== 'none' ? rsnFlags.split(' ') : []
});
});
return result;
} catch (e) {
return [];
}
}
function getWifiNetworkListIw(iface) {
const result = [];
try {
let iwlistParts = execSync(`export LC_ALL=C; iwlist ${iface} scan 2>&1; unset LC_ALL`).toString().split(' Cell ');
if (iwlistParts[0].indexOf('resource busy') >= 0) { return -1; }
if (iwlistParts.length > 1) {
iwlistParts.shift();
iwlistParts.forEach(element => {
const lines = element.split('\n');
const channel = util.getValue(lines, 'channel', ':', true);
const address = (lines && lines.length && lines[0].indexOf('Address:') >= 0 ? lines[0].split('Address:')[1].trim().toLowerCase() : '');
const mode = util.getValue(lines, 'mode', ':', true);
const frequency = util.getValue(lines, 'frequency', ':', true);
const qualityString = util.getValue(lines, 'Quality', '=', true);
const dbParts = qualityString.toLowerCase().split('signal level=');
const db = dbParts.length > 1 ? util.toInt(dbParts[1]) : 0;
const quality = db ? wifiQualityFromDB(db) : 0;
const ssid = util.getValue(lines, 'essid', ':', true);
// security and wpa-flags
const isWpa = element.indexOf(' WPA ') >= 0;
const isWpa2 = element.indexOf('WPA2 ') >= 0;
const security = [];
if (isWpa) { security.push('WPA'); }
if (isWpa2) { security.push('WPA2'); }
const wpaFlags = [];
let wpaFlag = '';
lines.forEach(function (line) {
const l = line.trim().toLowerCase();
if (l.indexOf('group cipher') >= 0) {
if (wpaFlag) {
wpaFlags.push(wpaFlag);
}
const parts = l.split(':');
if (parts.length > 1) {
wpaFlag = parts[1].trim().toUpperCase();
}
}
if (l.indexOf('pairwise cipher') >= 0) {
const parts = l.split(':');
if (parts.length > 1) {
if (parts[1].indexOf('tkip')) { wpaFlag = (wpaFlag ? 'TKIP/' + wpaFlag : 'TKIP'); }
else if (parts[1].indexOf('ccmp')) { wpaFlag = (wpaFlag ? 'CCMP/' + wpaFlag : 'CCMP'); }
else if (parts[1].indexOf('proprietary')) { wpaFlag = (wpaFlag ? 'PROP/' + wpaFlag : 'PROP'); }
}
}
if (l.indexOf('authentication suites') >= 0) {
const parts = l.split(':');
if (parts.length > 1) {
if (parts[1].indexOf('802.1x')) { wpaFlag = (wpaFlag ? '802.1x/' + wpaFlag : '802.1x'); }
else if (parts[1].indexOf('psk')) { wpaFlag = (wpaFlag ? 'PSK/' + wpaFlag : 'PSK'); }
}
}
});
if (wpaFlag) {
wpaFlags.push(wpaFlag);
}
result.push({
ssid,
bssid: address,
mode,
channel: channel ? util.toInt(channel) : null,
frequency: frequency ? util.toInt(frequency.replace('.', '')) : null,
signalLevel: db,
quality,
security,
wpaFlags,
rsnFlags: []
});
});
}
return result;
} catch (e) {
return -1;
}
}
function parseWifiDarwin(wifiObj) {
const result = [];
if (wifiObj) {
wifiObj.forEach(function (wifiItem) {
const signalLevel = wifiItem.RSSI;
let security = [];
let wpaFlags = [];
let ssid = wifiItem.SSID_STR || '';
if (wifiItem.WPA_IE) {
security.push('WPA');
if (wifiItem.WPA_IE.IE_KEY_WPA_UCIPHERS) {
wifiItem.WPA_IE.IE_KEY_WPA_UCIPHERS.forEach(function (ciphers) {
if (ciphers === 0 && wpaFlags.indexOf('unknown/TKIP') === -1) { wpaFlags.push('unknown/TKIP'); }
if (ciphers === 2 && wpaFlags.indexOf('PSK/TKIP') === -1) { wpaFlags.push('PSK/TKIP'); }
if (ciphers === 4 && wpaFlags.indexOf('PSK/AES') === -1) { wpaFlags.push('PSK/AES'); }
});
}
}
if (wifiItem.RSN_IE) {
security.push('WPA2');
if (wifiItem.RSN_IE.IE_KEY_RSN_UCIPHERS) {
wifiItem.RSN_IE.IE_KEY_RSN_UCIPHERS.forEach(function (ciphers) {
if (ciphers === 0 && wpaFlags.indexOf('unknown/TKIP') === -1) { wpaFlags.push('unknown/TKIP'); }
if (ciphers === 2 && wpaFlags.indexOf('TKIP/TKIP') === -1) { wpaFlags.push('TKIP/TKIP'); }
if (ciphers === 4 && wpaFlags.indexOf('PSK/AES') === -1) { wpaFlags.push('PSK/AES'); }
});
}
}
if (wifiItem.SSID && ssid === '') {
try {
ssid = Buffer.from(wifiItem.SSID, 'base64').toString('utf8');
} catch (err) {
util.noop();
}
}
result.push({
ssid,
bssid: wifiItem.BSSID || '',
mode: '',
channel: wifiItem.CHANNEL,
frequency: wifiFrequencyFromChannel(wifiItem.CHANNEL),
signalLevel: signalLevel ? parseInt(signalLevel, 10) : null,
quality: wifiQualityFromDB(signalLevel),
security,
wpaFlags,
rsnFlags: []
});
});
}
return result;
}
function wifiNetworks(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
let result = [];
if (_linux) {
result = getWifiNetworkListNmi();
if (result.length === 0) {
try {
const iwconfigParts = execSync('export LC_ALL=C; iwconfig 2>/dev/null; unset LC_ALL').toString().split('\n\n');
let iface = '';
iwconfigParts.forEach(element => {
if (element.indexOf('no wireless') === -1 && element.trim() !== '') {
iface = element.split(' ')[0];
}
});
if (iface) {
let ifaceSanitized = '';
const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(iface, true);
const l = util.mathMin(s.length, 2000);
for (let i = 0; i <= l; i++) {
if (s[i] !== undefined) {
ifaceSanitized = ifaceSanitized + s[i];
}
}
const res = getWifiNetworkListIw(ifaceSanitized);
if (res === -1) {
// try again after 4 secs
setTimeout(function (iface) {
const res = getWifiNetworkListIw(iface);
if (res != -1) { result = res; }
if (callback) {
callback(result);
}
resolve(result);
}, 4000);
} else {
result = res;
if (callback) {
callback(result);
}
resolve(result);
}
} else {
if (callback) {
callback(result);
}
resolve(result);
}
} catch (e) {
if (callback) {
callback(result);
}
resolve(result);
}
} else {
if (callback) {
callback(result);
}
resolve(result);
}
} else if (_darwin) {
let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s -x';
exec(cmd, { maxBuffer: 1024 * 40000 }, function (error, stdout) {
const output = stdout.toString();
result = parseWifiDarwin(util.plistParser(output));
if (callback) {
callback(result);
}
resolve(result);
});
} else if (_windows) {
let cmd = 'netsh wlan show networks mode=Bssid';
util.powerShell(cmd).then((stdout) => {
const ssidParts = stdout.toString('utf8').split(os.EOL + os.EOL + 'SSID ');
ssidParts.shift();
ssidParts.forEach(ssidPart => {
const ssidLines = ssidPart.split(os.EOL);
if (ssidLines && ssidLines.length >= 8 && ssidLines[0].indexOf(':') >= 0) {
const bssidsParts = ssidPart.split(' BSSID');
bssidsParts.shift();
bssidsParts.forEach((bssidPart) => {
const bssidLines = bssidPart.split(os.EOL);
const bssidLine = bssidLines[0].split(':');
bssidLine.shift();
const bssid = bssidLine.join(':').trim().toLowerCase();
const channel = bssidLines[3].split(':').pop().trim();
const quality = bssidLines[1].split(':').pop().trim();
result.push({
ssid: ssidLines[0].split(':').pop().trim(),
bssid,
mode: '',
channel: channel ? parseInt(channel, 10) : null,
frequency: wifiFrequencyFromChannel(channel),
signalLevel: wifiDBFromQuality(quality),
quality: quality ? parseInt(quality, 10) : null,
security: [ssidLines[2].split(':').pop().trim()],
wpaFlags: [ssidLines[3].split(':').pop().trim()],
rsnFlags: []
});
});
}
});
if (callback) {
callback(result);
}
resolve(result);
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
});
}
exports.wifiNetworks = wifiNetworks;
function getVendor(model) {
model = model.toLowerCase();
let result = '';
if (model.indexOf('intel') >= 0) { result = 'Intel'; }
else if (model.indexOf('realtek') >= 0) { result = 'Realtek'; }
else if (model.indexOf('qualcom') >= 0) { result = 'Qualcom'; }
else if (model.indexOf('broadcom') >= 0) { result = 'Broadcom'; }
else if (model.indexOf('cavium') >= 0) { result = 'Cavium'; }
else if (model.indexOf('cisco') >= 0) { result = 'Cisco'; }
else if (model.indexOf('marvel') >= 0) { result = 'Marvel'; }
else if (model.indexOf('zyxel') >= 0) { result = 'Zyxel'; }
else if (model.indexOf('melanox') >= 0) { result = 'Melanox'; }
else if (model.indexOf('d-link') >= 0) { result = 'D-Link'; }
else if (model.indexOf('tp-link') >= 0) { result = 'TP-Link'; }
else if (model.indexOf('asus') >= 0) { result = 'Asus'; }
else if (model.indexOf('linksys') >= 0) { result = 'Linksys'; }
return result;
}
function formatBssid(s) {
s = s.replace(/</g, '').replace(/>/g, '').match(/.{1,2}/g) || [];
return s.join(':');
}
function wifiConnections(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
const result = [];
if (_linux) {
const ifaces = ifaceListLinux();
const networkList = getWifiNetworkListNmi();
ifaces.forEach(ifaceDetail => {
let ifaceSanitized = '';
const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(ifaceDetail.iface, true);
const ll = util.mathMin(s.length, 2000);
for (let i = 0; i <= ll; i++) {
if (s[i] !== undefined) {
ifaceSanitized = ifaceSanitized + s[i];
}
}
const nmiDetails = nmiDeviceLinux(ifaceSanitized);
const wpaDetails = wpaConnectionLinux(ifaceSanitized);
const ssid = nmiDetails.ssid || wpaDetails.ssid;
const network = networkList.filter(nw => nw.ssid === ssid);
let ssidSanitized = '';
const t = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(ssid, true);
const l = util.mathMin(t.length, 2000);
for (let i = 0; i <= l; i++) {
if (t[i] !== undefined) {
ssidSanitized = ssidSanitized + t[i];
}
}
const nmiConnection = nmiConnectionLinux(ssidSanitized);
const channel = network && network.length && network[0].channel ? network[0].channel : (wpaDetails.channel ? wpaDetails.channel : null);
const bssid = network && network.length && network[0].bssid ? network[0].bssid : (wpaDetails.bssid ? wpaDetails.bssid : null);
const signalLevel = network && network.length && network[0].signalLevel ? network[0].signalLevel : null;
if (ssid && bssid) {
result.push({
id: ifaceDetail.id,
iface: ifaceDetail.iface,
model: nmiDetails.product,
ssid,
bssid: network && network.length && network[0].bssid ? network[0].bssid : (wpaDetails.bssid ? wpaDetails.bssid : null),
channel,
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type: nmiConnection.type ? nmiConnection.type : '802.11',
security: nmiConnection.security ? nmiConnection.security : (wpaDetails.security ? wpaDetails.security : null),
signalLevel,
quality: wifiQualityFromDB(signalLevel),
txRate: null
});
}
});
if (callback) {
callback(result);
}
resolve(result);
} else if (_darwin) {
let cmd = 'system_profiler SPNetworkDataType';
exec(cmd, function (error, stdout) {
const parts1 = stdout.toString().split('\n\n Wi-Fi:\n\n');
if (parts1.length > 1) {
const lines = parts1[1].split('\n\n')[0].split('\n');
const iface = util.getValue(lines, 'BSD Device Name', ':', true);
const model = util.getValue(lines, 'hardware', ':', true);
cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I 2>/dev/null; echo "######" ; ioreg -n AppleBCMWLANSkywalkInterface -r 2>/dev/null';
exec(cmd, function (error, stdout) {
const parts = stdout.toString().split('######');
const lines2 = parts[0].split('\n');
let lines3 = [];
if (parts[1].indexOf(' | {') > 0 && parts[1].indexOf(' | }') > parts[1].indexOf(' | {')) {
lines3 = parts[1].split(' | {')[1].split(' | }')[0].replace(/ \| /g, '').replace(/"/g, '').split('\n');
}
if (lines2.length > 10) {
const ssid = util.getValue(lines2, 'ssid', ':', true);
const bssid = util.getValue(lines2, 'bssid', ':', true) || formatBssid(util.getValue(lines3, 'IO80211BSSID', '=', true));
const security = util.getValue(lines2, 'link auth', ':', true);
const txRate = util.getValue(lines2, 'lastTxRate', ':', true);
const channel = util.getValue(lines2, 'channel', ':', true).split(',')[0];
const type = '802.11';
const rssi = util.toInt(util.getValue(lines2, 'agrCtlRSSI', ':', true));
/// const noise = util.toInt(util.getValue(lines2, 'agrCtlNoise', ':', true));
const signalLevel = rssi;
if (ssid || bssid) {
result.push({
id: 'Wi-Fi',
iface,
model,
ssid,
bssid,
channel: util.toInt(channel),
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type,
security,
signalLevel,
quality: wifiQualityFromDB(signalLevel),
txRate
});
}
}
if (lines3.length > 10) {
const ssid = util.getValue(lines3, 'IO80211SSID', '=', true);
const bssid = formatBssid(util.getValue(lines3, 'IO80211BSSID', '=', true));
const security = '';
const txRate = -1;
const signalLevel = -1;
const quality = -1;
const channel = util.getValue(lines3, 'IO80211Channel', '=', true);
const type = '802.11';
if ((ssid || bssid) && !result.length) {
result.push({
id: 'Wi-Fi',
iface,
model,
ssid,
bssid,
channel: util.toInt(channel),
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type,
security,
signalLevel,
quality,
txRate
});
}
}
if (callback) {
callback(result);
}
resolve(result);
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
} else if (_windows) {
let cmd = 'netsh wlan show interfaces';
util.powerShell(cmd).then(function (stdout) {
const allLines = stdout.toString().split('\r\n');
for (let i = 0; i < allLines.length; i++) {
allLines[i] = allLines[i].trim();
}
const parts = allLines.join('\r\n').split(':\r\n\r\n');
parts.shift();
parts.forEach(part => {
const lines = part.split('\r\n');
if (lines.length >= 5) {
const iface = lines[0].indexOf(':') >= 0 ? lines[0].split(':')[1].trim() : '';
const model = lines[1].indexOf(':') >= 0 ? lines[1].split(':')[1].trim() : '';
const id = lines[2].indexOf(':') >= 0 ? lines[2].split(':')[1].trim() : '';
const ssid = util.getValue(lines, 'SSID', ':', true);
const bssid = util.getValue(lines, 'BSSID', ':', true);
const quality = util.getValue(lines, 'Signal', ':', true);
const signalLevel = wifiDBFromQuality(quality);
const type = util.getValue(lines, 'Radio type', ':', true) || util.getValue(lines, 'Type de radio', ':', true) || util.getValue(lines, 'Funktyp', ':', true) || null;
const security = util.getValue(lines, 'authentication', ':', true) || util.getValue(lines, 'Authentification', ':', true) || util.getValue(lines, 'Authentifizierung', ':', true) || null;
const channel = util.getValue(lines, 'Channel', ':', true) || util.getValue(lines, 'Canal', ':', true) || util.getValue(lines, 'Kanal', ':', true) || null;
const txRate = util.getValue(lines, 'Transmit rate (mbps)', ':', true) || util.getValue(lines, 'Transmission (mbit/s)', ':', true) || util.getValue(lines, 'Empfangsrate (MBit/s)', ':', true) || null;
if (model && id && ssid && bssid) {
result.push({
id,
iface,
model,
ssid,
bssid,
channel: util.toInt(channel),
frequency: channel ? wifiFrequencyFromChannel(channel) : null,
type,
security,
signalLevel,
quality: quality ? parseInt(quality, 10) : null,
txRate: util.toInt(txRate) || null
});
}
}
});
if (callback) {
callback(result);
}
resolve(result);
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
});
}
exports.wifiConnections = wifiConnections;
function wifiInterfaces(callback) {
return new Promise((resolve) => {
process.nextTick(() => {
const result = [];
if (_linux) {
const ifaces = ifaceListLinux();
ifaces.forEach(ifaceDetail => {
const nmiDetails = nmiDeviceLinux(ifaceDetail.iface);
result.push({
id: ifaceDetail.id,
iface: ifaceDetail.iface,
model: nmiDetails.product ? nmiDetails.product : null,
vendor: nmiDetails.vendor ? nmiDetails.vendor : null,
mac: ifaceDetail.mac,
});
});
if (callback) {
callback(result);
}
resolve(result);
} else if (_darwin) {
let cmd = 'system_profiler SPNetworkDataType';
exec(cmd, function (error, stdout) {
const parts1 = stdout.toString().split('\n\n Wi-Fi:\n\n');
if (parts1.length > 1) {
const lines = parts1[1].split('\n\n')[0].split('\n');
const iface = util.getValue(lines, 'BSD Device Name', ':', true);
const mac = util.getValue(lines, 'MAC Address', ':', true);
const model = util.getValue(lines, 'hardware', ':', true);
result.push({
id: 'Wi-Fi',
iface,
model,
vendor: '',
mac
});
}
if (callback) {
callback(result);
}
resolve(result);
});
} else if (_windows) {
let cmd = 'netsh wlan show interfaces';
util.powerShell(cmd).then(function (stdout) {
const allLines = stdout.toString().split('\r\n');
for (let i = 0; i < allLines.length; i++) {
allLines[i] = allLines[i].trim();
}
const parts = allLines.join('\r\n').split(':\r\n\r\n');
parts.shift();
parts.forEach(part => {
const lines = part.split('\r\n');
if (lines.length >= 5) {
const iface = lines[0].indexOf(':') >= 0 ? lines[0].split(':')[1].trim() : '';
const model = lines[1].indexOf(':') >= 0 ? lines[1].split(':')[1].trim() : '';
const id = lines[2].indexOf(':') >= 0 ? lines[2].split(':')[1].trim() : '';
const macParts = lines[3].indexOf(':') >= 0 ? lines[3].split(':') : [];
macParts.shift();
const mac = macParts.join(':').trim();
const vendor = getVendor(model);
if (iface && model && id && mac) {
result.push({
id,
iface,
model,
vendor,
mac,
});
}
}
});
if (callback) {
callback(result);
}
resolve(result);
});
} else {
if (callback) {
callback(result);
}
resolve(result);
}
});
});
}
exports.wifiInterfaces = wifiInterfaces;