diff --git a/src/addon-manager.ts b/src/addon-manager.ts index 8b210ed63..aae825c15 100644 --- a/src/addon-manager.ts +++ b/src/addon-manager.ts @@ -78,7 +78,7 @@ export class AddonManager extends EventEmitter { private updateTimeout: NodeJS.Timeout | null = null; - private updateInterval: number | null = null; + private updateInterval: NodeJS.Timeout | null = null; private pairingTimeout: NodeJS.Timeout | null = null; diff --git a/src/controllers/login_controller.ts b/src/controllers/login_controller.ts index c2960fca6..ff4b04af0 100644 --- a/src/controllers/login_controller.ts +++ b/src/controllers/login_controller.ts @@ -92,7 +92,9 @@ function build(): express.Router { // Issue a new JWT for this user. const jwt = await JSONWebToken.issueToken(user.getId()!); - limiter.resetKey(request.ip); + if (request.ip) { + limiter.resetKey(request.ip); + } response.status(200).json({ jwt }); }); diff --git a/src/log-timestamps.ts b/src/log-timestamps.ts index 5377ab51f..dcba0a7f3 100644 --- a/src/log-timestamps.ts +++ b/src/log-timestamps.ts @@ -45,7 +45,7 @@ const logger = winston.createLogger({ error: 'red', }, }), - winston.format.printf((info) => info.message) + winston.format.printf((info) => String(info.message)) ), }), new DailyRotateFile({ @@ -59,7 +59,7 @@ const logger = winston.createLogger({ format: winston.format.combine( timestampFormat, new CustomFormatter(), - winston.format.printf((info) => info.message) + winston.format.printf((info) => String(info.message)) ), }), ], diff --git a/src/platforms/linux-raspbian.ts b/src/platforms/linux-raspbian.ts index c2b28c163..d0ac8e495 100644 --- a/src/platforms/linux-raspbian.ts +++ b/src/platforms/linux-raspbian.ts @@ -158,7 +158,7 @@ class LinuxRaspbianPlatform extends BasePlatform { mgmt = ''; const options: Record = {}; - let proc = child_process.spawnSync('systemctl', ['is-active', 'hostapd.service']); + const proc = child_process.spawnSync('systemctl', ['is-active', 'hostapd.service']); if (proc.status === 0) { mode = 'ap'; enabled = true; @@ -212,13 +212,15 @@ class LinuxRaspbianPlatform extends BasePlatform { } } else { mode = 'sta'; - proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'status'], { encoding: 'utf8' }); + const startProc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'status'], { + encoding: 'utf8', + }); if (proc.status !== 0) { return { enabled, mode, options }; } - for (const line of proc.stdout.split('\n')) { + for (const line of startProc.stdout.split('\n')) { const [key, value] = line.split('=', 2); switch (key) { case 'wpa_state': @@ -248,7 +250,7 @@ class LinuxRaspbianPlatform extends BasePlatform { } } - proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'list_networks'], { + const listProc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'list_networks'], { encoding: 'utf8', }); if (proc.status !== 0) { @@ -256,7 +258,7 @@ class LinuxRaspbianPlatform extends BasePlatform { } options.networks = []; - for (const line of proc.stdout.trim().split('\n')) { + for (const line of listProc.stdout.trim().split('\n')) { if (line.startsWith('network')) { continue; } @@ -299,19 +301,24 @@ class LinuxRaspbianPlatform extends BasePlatform { } // First, remove existing networks - let proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'list_networks'], { + const listProc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'list_networks'], { encoding: 'utf8', }); - if (proc.status === 0) { - const networks = proc.stdout + if (listProc.status === 0) { + const networks = listProc.stdout .split('\n') .filter((l) => !l.startsWith('network')) .map((l) => l.split(' ')[0]) .reverse(); for (const id of networks) { - proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'remove_network', id]); - if (proc.status !== 0) { + const removeNetworkProc = child_process.spawnSync('wpa_cli', [ + '-i', + 'wlan0', + 'remove_network', + id, + ]); + if (removeNetworkProc.status !== 0) { console.log('Failed to remove network with id:', id); } } @@ -319,54 +326,58 @@ class LinuxRaspbianPlatform extends BasePlatform { // Then, stop hostapd. It will either need to be off or reconfigured, so // this is valid in both modes. - proc = child_process.spawnSync('sudo', ['systemctl', 'stop', 'hostapd.service']); - if (proc.status !== 0) { + const stopProc = child_process.spawnSync('sudo', ['systemctl', 'stop', 'hostapd.service']); + if (stopProc.status !== 0) { return false; } if (!enabled) { - proc = child_process.spawnSync('sudo', ['systemctl', 'disable', 'hostapd.service']); - return proc.status === 0; + const disableProc = child_process.spawnSync('sudo', [ + 'systemctl', + 'disable', + 'hostapd.service', + ]); + return disableProc.status === 0; } // Make sure Wi-Fi isn't blocked by rfkill child_process.spawnSync('sudo', ['rfkill', 'unblock', 'wifi']); // Now, set the IP address back to a sane state - proc = child_process.spawnSync('sudo', ['ifconfig', 'wlan0', '0.0.0.0']); - if (proc.status !== 0) { + const configProc = child_process.spawnSync('sudo', ['ifconfig', 'wlan0', '0.0.0.0']); + if (configProc.status !== 0) { return false; } if (mode === 'sta') { - proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'add_network'], { + const addProc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'add_network'], { encoding: 'utf8', }); - if (proc.status !== 0) { + if (addProc.status !== 0) { return false; } - const id = proc.stdout.trim(); + const id = addProc.stdout.trim(); options.ssid = (options.ssid).replace('"', '\\"'); - proc = child_process.spawnSync( + let setProc = child_process.spawnSync( 'wpa_cli', // the ssid argument MUST be quoted ['-i', 'wlan0', 'set_network', id, 'ssid', `"${options.ssid}"`] ); - if (proc.status !== 0) { + if (setProc.status !== 0) { return false; } if (options.key) { options.key = (options.key).replace('"', '\\"'); - proc = child_process.spawnSync( + setProc = child_process.spawnSync( 'wpa_cli', // the psk argument MUST be quoted ['-i', 'wlan0', 'set_network', id, 'psk', `"${options.key}"`] ); } else { - proc = child_process.spawnSync('wpa_cli', [ + setProc = child_process.spawnSync('wpa_cli', [ '-i', 'wlan0', 'set_network', @@ -376,22 +387,26 @@ class LinuxRaspbianPlatform extends BasePlatform { ]); } - if (proc.status !== 0) { + if (setProc.status !== 0) { return false; } - proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'enable_network', id]); - if (proc.status !== 0) { + const enableProc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'enable_network', id]); + if (enableProc.status !== 0) { return false; } - proc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'save_config']); - if (proc.status !== 0) { + const saveProc = child_process.spawnSync('wpa_cli', ['-i', 'wlan0', 'save_config']); + if (saveProc.status !== 0) { return false; } - proc = child_process.spawnSync('sudo', ['systemctl', 'disable', 'hostapd.service']); - if (proc.status !== 0) { + const disableProc = child_process.spawnSync('sudo', [ + 'systemctl', + 'disable', + 'hostapd.service', + ]); + if (disableProc.status !== 0) { return false; } } else { @@ -409,30 +424,38 @@ class LinuxRaspbianPlatform extends BasePlatform { fs.writeFileSync('/tmp/hostapd.conf', config); - proc = child_process.spawnSync('sudo', [ + const mvProc = child_process.spawnSync('sudo', [ 'mv', '/tmp/hostapd.conf', '/etc/hostapd/hostapd.conf', ]); - if (proc.status !== 0) { + if (mvProc.status !== 0) { return false; } - proc = child_process.spawnSync('sudo', ['systemctl', 'start', 'hostapd.service']); - if (proc.status !== 0) { + const startProc = child_process.spawnSync('sudo', ['systemctl', 'start', 'hostapd.service']); + if (startProc.status !== 0) { return false; } - proc = child_process.spawnSync('sudo', ['systemctl', 'enable', 'hostapd.service']); - if (proc.status !== 0) { + const enableProc = child_process.spawnSync('sudo', [ + 'systemctl', + 'enable', + 'hostapd.service', + ]); + if (enableProc.status !== 0) { return false; } } if (options.ipaddr) { - proc = child_process.spawnSync('sudo', ['ifconfig', 'wlan0', options.ipaddr]); - if (proc.status !== 0) { + const configProc = child_process.spawnSync('sudo', [ + 'ifconfig', + 'wlan0', + options.ipaddr, + ]); + if (configProc.status !== 0) { return false; } diff --git a/src/plugin/plugin.ts b/src/plugin/plugin.ts index 4b9e17311..5c3c9e388 100644 --- a/src/plugin/plugin.ts +++ b/src/plugin/plugin.ts @@ -145,7 +145,7 @@ export default class Plugin { asDict(): Record { let pid: string | number = 'not running'; - if (this.process.p) { + if (this.process.p && typeof this.process.p.pid != 'undefined') { pid = this.process.p.pid; } return { diff --git a/src/test/common.ts b/src/test/common.ts index 76f25931b..94139f011 100644 --- a/src/test/common.ts +++ b/src/test/common.ts @@ -28,7 +28,7 @@ interface TestGlobals { } export const chai = _chai; -(global).chai = chai; +(global).chai = chai; expect.extend({ assert(value, message = 'expected condition to be truthy') { @@ -41,7 +41,7 @@ expect.extend({ }); import { servers, serverStartup } from '../app'; -(global).server = servers.https!; +(global).server = servers.https!; import addonManager from '../addon-manager'; @@ -50,7 +50,7 @@ export function mockAdapter(): MockAdapter { expect(adapter).not.toBeUndefined(); return (adapter!); } -(global).mockAdapter = mockAdapter; +(global).mockAdapter = mockAdapter; function removeTestManifest(): void { const testManifestJsonFilename = path.join( diff --git a/src/test/jsdom-common.ts b/src/test/jsdom-common.ts index 26a1288e1..0a05781b0 100644 --- a/src/test/jsdom-common.ts +++ b/src/test/jsdom-common.ts @@ -24,11 +24,11 @@ interface TestGlobals { } beforeEach(() => { - (global).sandbox = sinon.createSandbox(); + (global).sandbox = sinon.createSandbox(); }); afterEach(() => { - (global).sandbox.restore(); + (global).sandbox.restore(); // Clean up any nodes added to the DOM document.body.innerHTML = ''; }); diff --git a/src/test/schema-form/form-test.ts b/src/test/schema-form/form-test.ts index 0330d30d3..300204abb 100644 --- a/src/test/schema-form/form-test.ts +++ b/src/test/schema-form/form-test.ts @@ -359,7 +359,7 @@ describe('Form', () => { foo: { type: 'string' }, }, }; - const onSubmit = (global).sandbox.stub(); + const onSubmit = (global).sandbox.stub(); const { node } = createSchemaForm({ schema, diff --git a/src/test/websocket-util.ts b/src/test/websocket-util.ts index ff3c89123..bbec0d18d 100644 --- a/src/test/websocket-util.ts +++ b/src/test/websocket-util.ts @@ -77,12 +77,15 @@ export async function webSocketRead( * @param {Object|string} message */ export async function webSocketSend(ws: WebSocket, message: unknown): Promise { - if (typeof message !== 'string') { - message = JSON.stringify(message); + let messageString: string; + if (typeof message == 'string') { + messageString = message; + } else { + messageString = JSON.stringify(message); } await new Promise((resolve) => { - ws.send(message, () => { + ws.send(messageString, () => { resolve(); }); }); diff --git a/static/js/schema-form/schema-utils.ts b/static/js/schema-form/schema-utils.ts index 34525c8df..e9857ac51 100644 --- a/static/js/schema-form/schema-utils.ts +++ b/static/js/schema-form/schema-utils.ts @@ -121,7 +121,7 @@ export function withDependentSchema( schema = mergeSchemas(schema, dependentSchema); return typeof oneOf === 'undefined' ? schema - : withExactlyOneSubschema(schema, definitions, formData, dependencyKey, oneOf); + : withExactlyOneSubschema(schema, definitions, formData, dependencyKey, oneOf); } export function withExactlyOneSubschema( @@ -129,7 +129,7 @@ export function withExactlyOneSubschema( definitions: Record, formData: Record, dependencyKey: string, - oneOf: unknown[] + oneOf: JsonSchema[] ): Record { if (!Array.isArray(oneOf)) { throw new Error(`invalid oneOf: it is some ${typeof oneOf} instead of an array`); @@ -432,3 +432,11 @@ export function getOptionsList(schema: Record): Record; +} + +interface PropertySchema { + type: string; +}