diff --git a/pkg/rancher-desktop/sudo-prompt/index.js b/pkg/rancher-desktop/sudo-prompt/index.js index acfd41ba963..bbb50cfb1e7 100644 --- a/pkg/rancher-desktop/sudo-prompt/index.js +++ b/pkg/rancher-desktop/sudo-prompt/index.js @@ -1,23 +1,33 @@ -var Node = { - child: require('child_process'), +const Node = { + child: require('child_process'), crypto: require('crypto'), - fs: require('fs'), - os: require('os'), - path: require('path'), - process: process, - util: require('util') + fs: require('fs'), + os: require('os'), + path: require('path'), + process, + util: require('util'), }; function Attempt(instance, end) { - var platform = Node.process.platform; - if (platform === 'darwin') return Mac(instance, end); - if (platform === 'linux') return Linux(instance, end); - if (platform === 'win32') return Windows(instance, end); + const platform = Node.process.platform; + + if (platform === 'darwin') { + return Mac(instance, end); + } + if (platform === 'linux') { + return Linux(instance, end); + } + if (platform === 'win32') { + return Windows(instance, end); + } end(new Error('Platform not yet supported.')); } function EscapeDoubleQuotes(string) { - if (typeof string !== 'string') throw new Error('Expected a string.'); + if (typeof string !== 'string') { + throw new TypeError('Expected a string.'); + } + return string.replace(/"/g, '\\"'); } @@ -25,11 +35,12 @@ function Exec() { if (arguments.length < 1 || arguments.length > 3) { throw new Error('Wrong number of arguments.'); } - var command = arguments[0]; - var options = {}; - var end = function() {}; + const command = arguments[0]; + let options = {}; + let end = function() {}; + if (typeof command !== 'string') { - throw new Error('Command should be a string.'); + throw new TypeError('Command should be a string.'); } if (arguments.length === 2) { if (Node.util.isObject(arguments[1])) { @@ -37,34 +48,37 @@ function Exec() { } else if (Node.util.isFunction(arguments[1])) { end = arguments[1]; } else { - throw new Error('Expected options or callback.'); + throw new TypeError('Expected options or callback.'); } } else if (arguments.length === 3) { if (Node.util.isObject(arguments[1])) { options = arguments[1]; } else { - throw new Error('Expected options to be an object.'); + throw new TypeError('Expected options to be an object.'); } if (Node.util.isFunction(arguments[2])) { end = arguments[2]; } else { - throw new Error('Expected callback to be a function.'); + throw new TypeError('Expected callback to be a function.'); } } if (/^sudo/i.test(command)) { return end(new Error('Command should not be prefixed with "sudo".')); } if (typeof options.name === 'undefined') { - var title = Node.process.title; + const title = Node.process.title; + if (ValidName(title)) { options.name = title; } else { return end(new Error('process.title cannot be used as a valid name.')); } } else if (!ValidName(options.name)) { - var error = ''; + let error = ''; + error += 'options.name must be alphanumeric only '; error += '(spaces are allowed) and <= 70 characters.'; + return end(new Error(error)); } if (typeof options.icns !== 'undefined') { @@ -80,11 +94,12 @@ function Exec() { } else if (Object.keys(options.env).length === 0) { return end(new Error('options.env must not be empty if provided.')); } else { - for (var key in options.env) { - var value = options.env[key]; + for (const key in options.env) { + const value = options.env[key]; + if (typeof key !== 'string' || typeof value !== 'string') { return end( - new Error('options.env environment variables must be strings.') + new Error('options.env environment variables must be strings.'), ); } // "Environment variable names used by the utilities in the Shell and @@ -96,68 +111,75 @@ function Exec() { if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) { return end( new Error( - 'options.env has an invalid environment variable name: ' + - JSON.stringify(key) - ) + `options.env has an invalid environment variable name: ${ + JSON.stringify(key) }`, + ), ); } if (/[\r\n]/.test(value)) { return end( new Error( - 'options.env has an invalid environment variable value: ' + - JSON.stringify(value) - ) + `options.env has an invalid environment variable value: ${ + JSON.stringify(value) }`, + ), ); } } } } - var platform = Node.process.platform; + const platform = Node.process.platform; + if (platform !== 'darwin' && platform !== 'linux' && platform !== 'win32') { return end(new Error('Platform not yet supported.')); } - var instance = { - command: command, - options: options, + const instance = { + command, + options, uuid: undefined, - path: undefined + path: undefined, }; + Attempt(instance, end); } function Linux(instance, end) { LinuxBinary(instance, - function(error, binary) { - if (error) return end(error); - var command = []; + (error, binary) => { + if (error) { + return end(error); + } + let command = []; + // Preserve current working directory: - command.push('cd "' + EscapeDoubleQuotes(Node.process.cwd()) + '";'); + command.push(`cd "${ EscapeDoubleQuotes(Node.process.cwd()) }";`); // Export environment variables: - for (var key in instance.options.env) { - var value = instance.options.env[key]; - command.push('export ' + key + '="' + EscapeDoubleQuotes(value) + '";'); + for (const key in instance.options.env) { + const value = instance.options.env[key]; + + command.push(`export ${ key }="${ EscapeDoubleQuotes(value) }";`); } - command.push('"' + EscapeDoubleQuotes(binary) + '"'); + command.push(`"${ EscapeDoubleQuotes(binary) }"`); if (/kdesudo/i.test(binary)) { command.push( '--comment', - '"' + instance.options.name + ' wants to make changes. ' + - 'Enter your password to allow this."' + `"${ instance.options.name } wants to make changes. ` + + `Enter your password to allow this."`, ); command.push('-d'); // Do not show the command to be run in the dialog. command.push('--'); } else if (/pkexec/i.test(binary)) { command.push('--disable-internal-agent'); } - var magic = 'SUDOPROMPT\n'; + const magic = 'SUDOPROMPT\n'; + command.push( - '/bin/bash -c "echo ' + EscapeDoubleQuotes(magic.trim()) + '; ' + - EscapeDoubleQuotes(instance.command) + - '"' + `/bin/bash -c "echo ${ EscapeDoubleQuotes(magic.trim()) }; ${ + EscapeDoubleQuotes(instance.command) + }"`, ); command = command.join(' '); Node.child.exec(command, { encoding: 'utf-8', maxBuffer: MAX_BUFFER }, - function(error, stdout, stderr) { + (error, stdout, stderr) => { // ISSUE 88: // We must distinguish between elevation errors and command errors. // @@ -175,8 +197,11 @@ function Linux(instance, end) { // // However, we do not rely on pkexec's return of 127 since our magic // marker is more reliable, and we already use it for kdesudo. - var elevated = stdout && stdout.slice(0, magic.length) === magic; - if (elevated) stdout = stdout.slice(magic.length); + const elevated = stdout && stdout.slice(0, magic.length) === magic; + + if (elevated) { + stdout = stdout.slice(magic.length); + } // Only normalize the error if it is definitely not a command error: // In other words, if we know that the command was never elevated. // We do not inspect error messages beyond NO_POLKIT_AGENT. @@ -189,128 +214,165 @@ function Linux(instance, end) { } } end(error, stdout, stderr); - } + }, ); - } + }, ); } function LinuxBinary(instance, end) { - var index = 0; + let index = 0; // We used to prefer gksudo over pkexec since it enabled a better prompt. // However, gksudo cannot run multiple commands concurrently. - var paths = ['/usr/bin/kdesudo', '/usr/bin/pkexec']; + const paths = ['/usr/bin/kdesudo', '/usr/bin/pkexec']; + function test() { if (index === paths.length) { return end(new Error('Unable to find pkexec or kdesudo.')); } - var path = paths[index++]; + const path = paths[index++]; + Node.fs.stat(path, - function(error) { + (error) => { if (error) { - if (error.code === 'ENOTDIR') return test(); - if (error.code === 'ENOENT') return test(); + if (error.code === 'ENOTDIR') { + return test(); + } + if (error.code === 'ENOENT') { + return test(); + } end(error); } else { end(undefined, path); } - } + }, ); } test(); } function Mac(instance, callback) { - var temp = Node.os.tmpdir(); - if (!temp) return callback(new Error('os.tmpdir() not defined.')); - var user = Node.process.env.USER; // Applet shell scripts require $USER. - if (!user) return callback(new Error('env[\'USER\'] not defined.')); + const temp = Node.os.tmpdir(); + + if (!temp) { + return callback(new Error('os.tmpdir() not defined.')); + } + const user = Node.process.env.USER; // Applet shell scripts require $USER. + + if (!user) { + return callback(new Error('env[\'USER\'] not defined.')); + } UUID(instance, - function(error, uuid) { - if (error) return callback(error); + (error, uuid) => { + if (error) { + return callback(error); + } instance.uuid = uuid; instance.path = Node.path.join( temp, instance.uuid, - instance.options.name + '.app' + `${ instance.options.name }.app`, ); function end(error, stdout, stderr) { Remove(Node.path.dirname(instance.path), - function(errorRemove) { - if (error) return callback(error); - if (errorRemove) return callback(errorRemove); + (errorRemove) => { + if (error) { + return callback(error); + } + if (errorRemove) { + return callback(errorRemove); + } callback(undefined, stdout, stderr); - } + }, ); } MacApplet(instance, - function(error, stdout, stderr) { - if (error) return end(error, stdout, stderr); + (error, stdout, stderr) => { + if (error) { + return end(error, stdout, stderr); + } MacIcon(instance, - function(error) { - if (error) return end(error); + (error) => { + if (error) { + return end(error); + } MacPropertyList(instance, - function(error, stdout, stderr) { - if (error) return end(error, stdout, stderr); + (error, stdout, stderr) => { + if (error) { + return end(error, stdout, stderr); + } MacCommand(instance, - function(error) { - if (error) return end(error); + (error) => { + if (error) { + return end(error); + } MacOpen(instance, - function(error, stdout, stderr) { - if (error) return end(error, stdout, stderr); + (error, stdout, stderr) => { + if (error) { + return end(error, stdout, stderr); + } MacResult(instance, end); - } + }, ); - } + }, ); - } + }, ); - } + }, ); - } + }, ); - } + }, ); } function MacApplet(instance, end) { - var parent = Node.path.dirname(instance.path); + const parent = Node.path.dirname(instance.path); + Node.fs.mkdir(parent, - function(error) { - if (error) return end(error); - var zip = Node.path.join(parent, 'sudo-prompt-applet.zip'); + (error) => { + if (error) { + return end(error); + } + const zip = Node.path.join(parent, 'sudo-prompt-applet.zip'); + Node.fs.writeFile(zip, APPLET, 'base64', - function(error) { - if (error) return end(error); - var command = []; + (error) => { + if (error) { + return end(error); + } + let command = []; + command.push('/usr/bin/unzip'); command.push('-o'); // Overwrite any existing applet. - command.push('"' + EscapeDoubleQuotes(zip) + '"'); - command.push('-d "' + EscapeDoubleQuotes(instance.path) + '"'); + command.push(`"${ EscapeDoubleQuotes(zip) }"`); + command.push(`-d "${ EscapeDoubleQuotes(instance.path) }"`); command = command.join(' '); Node.child.exec(command, { encoding: 'utf-8' }, end); - } + }, ); - } + }, ); } function MacCommand(instance, end) { - var path = Node.path.join( + const path = Node.path.join( instance.path, 'Contents', 'MacOS', - 'sudo-prompt-command' + 'sudo-prompt-command', ); - var script = []; + let script = []; + // Preserve current working directory: // We do this for commands that rely on relative paths. // This runs in a subshell and will not change the cwd of sudo-prompt-script. - script.push('cd "' + EscapeDoubleQuotes(Node.process.cwd()) + '"'); + script.push(`cd "${ EscapeDoubleQuotes(Node.process.cwd()) }"`); // Export environment variables: - for (var key in instance.options.env) { - var value = instance.options.env[key]; - script.push('export ' + key + '="' + EscapeDoubleQuotes(value) + '"'); + for (const key in instance.options.env) { + const value = instance.options.env[key]; + + script.push(`export ${ key }="${ EscapeDoubleQuotes(value) }"`); } script.push(instance.command); script = script.join('\n'); @@ -318,32 +380,38 @@ function MacCommand(instance, end) { } function MacIcon(instance, end) { - if (!instance.options.icns) return end(); + if (!instance.options.icns) { + return end(); + } Node.fs.readFile(instance.options.icns, - function(error, buffer) { - if (error) return end(error); - var icns = Node.path.join( + (error, buffer) => { + if (error) { + return end(error); + } + const icns = Node.path.join( instance.path, 'Contents', 'Resources', - 'applet.icns' + 'applet.icns', ); + Node.fs.writeFile(icns, buffer, end); - } + }, ); } function MacOpen(instance, end) { // We must run the binary directly so that the cwd will apply. - var binary = Node.path.join(instance.path, 'Contents', 'MacOS', 'applet'); + const binary = Node.path.join(instance.path, 'Contents', 'MacOS', 'applet'); // We must set the cwd so that the AppleScript can find the shell scripts. - var options = { - cwd: Node.path.dirname(binary), - encoding: 'utf-8' + const options = { + cwd: Node.path.dirname(binary), + encoding: 'utf-8', }; + // We use the relative path rather than the absolute path. The instance.path // may contain spaces which the cwd can handle, but which exec() cannot. - Node.child.exec('./' + Node.path.basename(binary), options, end); + Node.child.exec(`./${ Node.path.basename(binary) }`, options, end); } function MacPropertyList(instance, end) { @@ -352,53 +420,62 @@ function MacPropertyList(instance, end) { // The defaults command will be changed in an upcoming major release to only // operate on preferences domains. General plist manipulation utilities will // be folded into a different command-line program. - var plist = Node.path.join(instance.path, 'Contents', 'Info.plist'); - var path = EscapeDoubleQuotes(plist); - var key = EscapeDoubleQuotes('CFBundleName'); - var value = instance.options.name + ' Password Prompt'; + const plist = Node.path.join(instance.path, 'Contents', 'Info.plist'); + const path = EscapeDoubleQuotes(plist); + const key = EscapeDoubleQuotes('CFBundleName'); + const value = `${ instance.options.name } Password Prompt`; + if (/'/.test(value)) { return end(new Error('Value should not contain single quotes.')); } - var command = []; + let command = []; + command.push('/usr/bin/defaults'); command.push('write'); - command.push('"' + path + '"'); - command.push('"' + key + '"'); - command.push("'" + value + "'"); // We must use single quotes for value. + command.push(`"${ path }"`); + command.push(`"${ key }"`); + command.push(`'${ value }'`); // We must use single quotes for value. command = command.join(' '); Node.child.exec(command, { encoding: 'utf-8' }, end); } function MacResult(instance, end) { - var cwd = Node.path.join(instance.path, 'Contents', 'MacOS'); + const cwd = Node.path.join(instance.path, 'Contents', 'MacOS'); + Node.fs.readFile(Node.path.join(cwd, 'code'), 'utf-8', - function(error, code) { + (error, code) => { if (error) { - if (error.code === 'ENOENT') return end(new Error(PERMISSION_DENIED)); + if (error.code === 'ENOENT') { + return end(new Error(PERMISSION_DENIED)); + } end(error); } else { Node.fs.readFile(Node.path.join(cwd, 'stdout'), 'utf-8', - function(error, stdout) { - if (error) return end(error); + (error, stdout) => { + if (error) { + return end(error); + } Node.fs.readFile(Node.path.join(cwd, 'stderr'), 'utf-8', - function(error, stderr) { - if (error) return end(error); + (error, stderr) => { + if (error) { + return end(error); + } code = parseInt(code.trim(), 10); // Includes trailing newline. if (code === 0) { end(undefined, stdout, stderr); } else { error = new Error( - 'Command failed: ' + instance.command + '\n' + stderr + `Command failed: ${ instance.command }\n${ stderr }`, ); error.code = code; end(error, stdout, stderr); } - } + }, ); - } + }, ); } - } + }, ); } @@ -406,16 +483,17 @@ function Remove(path, end) { if (typeof path !== 'string' || !path.trim()) { return end(new Error('Argument path not defined.')); } - var command = []; + let command = []; + if (Node.process.platform === 'win32') { if (/"/.test(path)) { return end(new Error('Argument path cannot contain double-quotes.')); } - command.push('rmdir /s /q "' + path + '"'); + command.push(`rmdir /s /q "${ path }"`); } else { command.push('/bin/rm'); command.push('-rf'); - command.push('"' + EscapeDoubleQuotes(Node.path.normalize(path)) + '"'); + command.push(`"${ EscapeDoubleQuotes(Node.path.normalize(path)) }"`); } command = command.join(' '); Node.child.exec(command, { encoding: 'utf-8' }, end); @@ -423,45 +501,61 @@ function Remove(path, end) { function UUID(instance, end) { Node.crypto.randomBytes(256, - function(error, random) { - if (error) random = Date.now() + '' + Math.random(); - var hash = Node.crypto.createHash('SHA256'); + (error, random) => { + if (error) { + random = `${ Date.now() }${ Math.random() }`; + } + const hash = Node.crypto.createHash('SHA256'); + hash.update('sudo-prompt-3'); hash.update(instance.options.name); hash.update(instance.command); hash.update(random); - var uuid = hash.digest('hex').slice(-32); + const uuid = hash.digest('hex').slice(-32); + if (!uuid || typeof uuid !== 'string' || uuid.length !== 32) { // This is critical to ensure we don't remove the wrong temp directory. return end(new Error('Expected a valid UUID.')); } end(undefined, uuid); - } + }, ); } function ValidName(string) { // We use 70 characters as a limit to side-step any issues with Unicode // normalization form causing a 255 character string to exceed the fs limit. - if (!/^[a-z0-9 ]+$/i.test(string)) return false; - if (string.trim().length === 0) return false; - if (string.length > 70) return false; + if (!/^[a-z0-9 ]+$/i.test(string)) { + return false; + } + if (string.trim().length === 0) { + return false; + } + if (string.length > 70) { + return false; + } + return true; } function Windows(instance, callback) { - var temp = Node.os.tmpdir(); - if (!temp) return callback(new Error('os.tmpdir() not defined.')); + const temp = Node.os.tmpdir(); + + if (!temp) { + return callback(new Error('os.tmpdir() not defined.')); + } UUID(instance, - function(error, uuid) { - if (error) return callback(error); + (error, uuid) => { + if (error) { + return callback(error); + } instance.uuid = uuid; instance.path = Node.path.join(temp, instance.uuid); if (/"/.test(instance.path)) { // We expect double quotes to be reserved on Windows. // Even so, we test for this and abort if they are present. return callback( - new Error('instance.path cannot contain double-quotes.') + new Error('instance.path cannot contain double-quotes.'), ); } instance.pathElevate = Node.path.join(instance.path, 'elevate.vbs'); @@ -471,48 +565,63 @@ function Windows(instance, callback) { instance.pathStderr = Node.path.join(instance.path, 'stderr'); instance.pathStatus = Node.path.join(instance.path, 'status'); Node.fs.mkdir(instance.path, - function(error) { - if (error) return callback(error); + (error) => { + if (error) { + return callback(error); + } function end(error, stdout, stderr) { Remove(instance.path, - function(errorRemove) { - if (error) return callback(error); - if (errorRemove) return callback(errorRemove); + (errorRemove) => { + if (error) { + return callback(error); + } + if (errorRemove) { + return callback(errorRemove); + } callback(undefined, stdout, stderr); - } + }, ); } WindowsWriteExecuteScript(instance, - function(error) { - if (error) return end(error); + (error) => { + if (error) { + return end(error); + } WindowsWriteCommandScript(instance, - function(error) { - if (error) return end(error); + (error) => { + if (error) { + return end(error); + } WindowsElevate(instance, - function(error, stdout, stderr) { - if (error) return end(error, stdout, stderr); + (error, stdout, stderr) => { + if (error) { + return end(error, stdout, stderr); + } WindowsWaitForStatus(instance, - function(error) { - if (error) return end(error); + (error) => { + if (error) { + return end(error); + } WindowsResult(instance, end); - } + }, ); - } + }, ); - } + }, ); - } + }, ); - } + }, ); - } + }, ); } function WindowsElevate(instance, end) { // We used to use this for executing elevate.vbs: // var command = 'cscript.exe //NoLogo "' + instance.pathElevate + '"'; - var command = []; + let command = []; + command.push('powershell.exe'); command.push('Start-Process'); command.push('-FilePath'); @@ -520,49 +629,58 @@ function WindowsElevate(instance, end) { // Escape characters for PowerShell using single quotes: // Escape single quotes for PowerShell using backtick: // See: https://ss64.com/ps/syntax-esc.html - command.push('"\'' + instance.pathExecute.replace(/'/g, "`'") + '\'"'); + command.push(`"'${ instance.pathExecute.replace(/'/g, "`'") }'"`); command.push('-WindowStyle hidden'); command.push('-Verb runAs'); command = command.join(' '); - var child = Node.child.exec(command, { encoding: 'utf-8' }, - function(error, stdout, stderr) { + const child = Node.child.exec(command, { encoding: 'utf-8' }, + (error, stdout, stderr) => { // We used to return PERMISSION_DENIED only for error messages containing // the string 'canceled by the user'. However, Windows internationalizes // error messages (issue 96) so now we must assume all errors here are // permission errors. This seems reasonable, given that we already run the // user's command in a subshell. - if (error) return end(new Error(PERMISSION_DENIED), stdout, stderr); + if (error) { + return end(new Error(PERMISSION_DENIED), stdout, stderr); + } end(); - } + }, ); + child.stdin.end(); // Otherwise PowerShell waits indefinitely on Windows 7. } function WindowsResult(instance, end) { Node.fs.readFile(instance.pathStatus, 'utf-8', - function(error, code) { - if (error) return end(error); + (error, code) => { + if (error) { + return end(error); + } Node.fs.readFile(instance.pathStdout, 'utf-8', - function(error, stdout) { - if (error) return end(error); + (error, stdout) => { + if (error) { + return end(error); + } Node.fs.readFile(instance.pathStderr, 'utf-8', - function(error, stderr) { - if (error) return end(error); + (error, stderr) => { + if (error) { + return end(error); + } code = parseInt(code.trim(), 10); if (code === 0) { end(undefined, stdout, stderr); } else { error = new Error( - 'Command failed: ' + instance.command + '\r\n' + stderr + `Command failed: ${ instance.command }\r\n${ stderr }`, ); error.code = code; end(error, stdout, stderr); } - } + }, ); - } + }, ); - } + }, ); } @@ -573,51 +691,55 @@ function WindowsWaitForStatus(instance, end) { // PowerShell can be used to elevate on Windows 7 but it cannot wait. // powershell.exe Start-Process cmd.exe -Verb runAs -Wait Node.fs.stat(instance.pathStatus, - function(error, stats) { + (error, stats) => { if ((error && error.code === 'ENOENT') || stats.size < 2) { // Retry if file does not exist or is not finished writing. // We expect a file size of 2. That should cover at least "0\r". // We use a 1 second timeout to keep a light footprint for long-lived // sudo-prompt processes. setTimeout( - function() { + () => { // If administrator has no password and user clicks Yes, then // PowerShell returns no error and execute (and command) never runs. // We check that command output has been redirected to stdout file: Node.fs.stat(instance.pathStdout, - function(error) { - if (error) return end(new Error(PERMISSION_DENIED)); + (error) => { + if (error) { + return end(new Error(PERMISSION_DENIED)); + } WindowsWaitForStatus(instance, end); - } + }, ); }, - 1000 + 1000, ); } else if (error) { end(error); } else { end(); } - } + }, ); } function WindowsWriteCommandScript(instance, end) { - var cwd = Node.process.cwd(); + const cwd = Node.process.cwd(); + if (/"/.test(cwd)) { // We expect double quotes to be reserved on Windows. // Even so, we test for this and abort if they are present. return end(new Error('process.cwd() cannot contain double-quotes.')); } - var script = []; + let script = []; + script.push('@echo off'); // Set code page to UTF-8: script.push('chcp 65001>nul'); // Preserve current working directory: // We pass /d as an option in case the cwd is on another drive (issue 70). - script.push('cd /d "' + cwd + '"'); + script.push(`cd /d "${ cwd }"`); // Export environment variables: - for (var key in instance.options.env) { + for (const key in instance.options.env) { // "The characters <, >, |, &, ^ are special command shell characters, and // they must be preceded by the escape character (^) or enclosed in // quotation marks. If you use quotation marks to enclose a string that @@ -625,8 +747,9 @@ function WindowsWriteCommandScript(instance, end) { // part of the environment variable value." // In other words, Windows assigns everything that follows the equals sign // to the value of the variable, whereas Unix systems ignore double quotes. - var value = instance.options.env[key]; - script.push('set ' + key + '=' + value.replace(/([<>\\|&^])/g, '^$1')); + const value = instance.options.env[key]; + + script.push(`set ${ key }=${ value.replace(/([<>\\|&^])/g, '^$1') }`); } script.push(instance.command); script = script.join('\r\n'); @@ -646,13 +769,14 @@ function WindowsWriteElevateScript(instance, end) { } function WindowsWriteExecuteScript(instance, end) { - var script = []; + let script = []; + script.push('@echo off'); script.push( - 'call "' + instance.pathCommand + '"' + - ' > "' + instance.pathStdout + '" 2> "' + instance.pathStderr + '"' + `call "${ instance.pathCommand }"` + + ` > "${ instance.pathStdout }" 2> "${ instance.pathStderr }"`, ); - script.push('(echo %ERRORLEVEL%) > "' + instance.pathStatus + '"'); + script.push(`(echo %ERRORLEVEL%) > "${ instance.pathStatus }"`); script = script.join('\r\n'); Node.fs.writeFile(instance.pathExecute, script, 'utf-8', end); } diff --git a/pkg/rancher-desktop/sudo-prompt/test-concurrent.js b/pkg/rancher-desktop/sudo-prompt/test-concurrent.js index 808540c98fe..f904211a2cd 100644 --- a/pkg/rancher-desktop/sudo-prompt/test-concurrent.js +++ b/pkg/rancher-desktop/sudo-prompt/test-concurrent.js @@ -1,29 +1,31 @@ -var sudo = require('./'); -var exec = require('child_process').exec; +const sudo = require('./'); + +const exec = require('child_process').exec; function kill(end) { - if (process.platform === 'win32') return end(); + if (process.platform === 'win32') { + return end(); + } exec('sudo -k', end); } kill( - function() { - var options = { - name: 'Sudo Prompt' - }; + () => { + const options = { name: 'Sudo Prompt' }; + if (process.platform === 'win32') { var sleep = 'timeout /t 10\r\necho world'; } else { var sleep = 'sleep 10 && echo world'; } sudo.exec(sleep, options, - function(error, stdout, stderr) { + (error, stdout, stderr) => { console.log(error, stdout, stderr); - } + }, ); sudo.exec('echo hello', options, - function(error, stdout, stderr) { + (error, stdout, stderr) => { console.log(error, stdout, stderr); - } + }, ); - } + }, ); diff --git a/pkg/rancher-desktop/sudo-prompt/test.js b/pkg/rancher-desktop/sudo-prompt/test.js index 31477eeb419..91a321bc49d 100644 --- a/pkg/rancher-desktop/sudo-prompt/test.js +++ b/pkg/rancher-desktop/sudo-prompt/test.js @@ -1,30 +1,40 @@ -var assert = require('assert'); -var fs = require('fs'); -var sudo = require('./'); -var exec = require('child_process').exec; +const assert = require('assert'); +const fs = require('fs'); + +const sudo = require('./'); + +const exec = require('child_process').exec; function kill(end) { - if (process.platform === 'win32') return end(); + if (process.platform === 'win32') { + return end(); + } exec('sudo -k', end); } function icns() { - if (process.platform !== 'darwin') return undefined; - var path = '/Applications/Electron.app/Contents/Resources/Electron.icns'; + if (process.platform !== 'darwin') { + return undefined; + } + const path = '/Applications/Electron.app/Contents/Resources/Electron.icns'; + try { fs.statSync(path); + return path; } catch (error) {} + return undefined; } kill( - function() { - var options = { - env: { 'SUDO_PROMPT_TEST_ENV': 'hello world' }, + () => { + const options = { + env: { SUDO_PROMPT_TEST_ENV: 'hello world' }, icns: icns(), - name: 'Electron' + name: 'Electron', }; + if (process.platform === 'win32') { var command = 'echo %SUDO_PROMPT_TEST_ENV%'; var expected = 'hello world\r\n'; @@ -34,32 +44,34 @@ kill( var expected = 'hello world\n'; } console.log( - 'sudo.exec(' + - JSON.stringify(command) + ', ' + - JSON.stringify(options) + - ')' + `sudo.exec(${ + JSON.stringify(command) }, ${ + JSON.stringify(options) + })`, ); sudo.exec(command, options, - function(error, stdout, stderr) { + (error, stdout, stderr) => { console.log('error:', error); - console.log('stdout: ' + JSON.stringify(stdout)); - console.log('stderr: ' + JSON.stringify(stderr)); + console.log(`stdout: ${ JSON.stringify(stdout) }`); + console.log(`stderr: ${ JSON.stringify(stderr) }`); assert(error === undefined || typeof error === 'object'); assert(stdout === undefined || typeof stdout === 'string'); assert(stderr === undefined || typeof stderr === 'string'); kill( - function() { - if (error) throw error; + () => { + if (error) { + throw error; + } if (stdout !== expected) { - throw new Error('stdout != ' + JSON.stringify(expected)); + throw new Error(`stdout != ${ JSON.stringify(expected) }`); } if (stderr !== '') { throw new Error('stderr != ""'); } console.log('OK'); - } + }, ); - } + }, ); - } + }, );