From db24ee4d379758dc6dd5ebf88ee402cc494c4d49 Mon Sep 17 00:00:00 2001 From: Alexis Svinartchouk Date: Wed, 8 Jan 2020 15:15:29 +0100 Subject: [PATCH] Convert catalina-sudo/sudo.js to typescript Change-type: patch --- lib/shared/catalina-sudo/sudo.js | 55 ------------------------- lib/shared/catalina-sudo/sudo.ts | 70 ++++++++++++++++++++++++++++++++ lib/shared/permissions.js | 1 + 3 files changed, 71 insertions(+), 55 deletions(-) delete mode 100644 lib/shared/catalina-sudo/sudo.js create mode 100644 lib/shared/catalina-sudo/sudo.ts diff --git a/lib/shared/catalina-sudo/sudo.js b/lib/shared/catalina-sudo/sudo.js deleted file mode 100644 index a5d6a8df..00000000 --- a/lib/shared/catalina-sudo/sudo.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict' - -const { execFile } = require('child_process') -const { argv, env } = require('process') -const { join } = require('path') -const { promisify } = require('util') - -const execFileAsync = promisify(execFile) - -const SUCCESSFUL_AUTH_MARKER = 'AUTHENTICATION SUCCEEDED' -const EXPECTED_SUCCESSFUL_AUTH_MARKER = `${SUCCESSFUL_AUTH_MARKER}\n` - -/* eslint-disable-next-line require-jsdoc */ -const getAppPath = () => { - for (const arg of argv) { - /* eslint-disable-next-line lodash/prefer-lodash-method */ - const [ option, value ] = arg.split('=') - if (option === '--app-path') { - return value - } - } - /* eslint-disable-next-line quotes */ - throw new Error("Couldn't find --app-path= in argv") -} - -exports.sudo = async (command) => { - try { - const { stdout, stderr } = await execFileAsync( - 'sudo', - [ '--askpass', 'sh', '-c', `echo ${SUCCESSFUL_AUTH_MARKER} && ${command}` ], - { - encoding: 'utf8', - env: { - PATH: env.PATH, - SUDO_ASKPASS: join(getAppPath(), __dirname, 'sudo-askpass.osascript.js') - } - } - ) - return { - cancelled: false, - stdout: stdout.slice(EXPECTED_SUCCESSFUL_AUTH_MARKER.length), - stderr - } - } catch (error) { - /* eslint-disable-next-line no-magic-numbers */ - if (error.code === 1) { - /* eslint-disable-next-line lodash/prefer-lodash-method */ - if (!error.stdout.startsWith(EXPECTED_SUCCESSFUL_AUTH_MARKER)) { - return { cancelled: true } - } - error.stdout = error.stdout.slice(EXPECTED_SUCCESSFUL_AUTH_MARKER.length) - } - throw error - } -} diff --git a/lib/shared/catalina-sudo/sudo.ts b/lib/shared/catalina-sudo/sudo.ts new file mode 100644 index 00000000..ef9d48e4 --- /dev/null +++ b/lib/shared/catalina-sudo/sudo.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2019 balena.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { execFile } from 'child_process'; +import { join } from 'path'; +import { argv, env } from 'process'; +import { promisify } from 'util'; + +const execFileAsync = promisify(execFile); + +const SUCCESSFUL_AUTH_MARKER = 'AUTHENTICATION SUCCEEDED'; +const EXPECTED_SUCCESSFUL_AUTH_MARKER = `${SUCCESSFUL_AUTH_MARKER}\n`; + +function getAppPath() { + for (const arg of argv) { + const [option, value] = arg.split('='); + if (option === '--app-path') { + return value; + } + } + throw new Error("Couldn't find --app-path= in argv"); +} + +export async function sudo( + command: string, +): Promise<{ cancelled: boolean; stdout?: string; stderr?: string }> { + try { + const { stdout, stderr } = await execFileAsync( + 'sudo', + ['--askpass', 'sh', '-c', `echo ${SUCCESSFUL_AUTH_MARKER} && ${command}`], + { + encoding: 'utf8', + env: { + PATH: env.PATH, + SUDO_ASKPASS: join( + getAppPath(), + __dirname, + 'sudo-askpass.osascript.js', + ), + }, + }, + ); + return { + cancelled: false, + stdout: stdout.slice(EXPECTED_SUCCESSFUL_AUTH_MARKER.length), + stderr, + }; + } catch (error) { + if (error.code === 1) { + if (!error.stdout.startsWith(EXPECTED_SUCCESSFUL_AUTH_MARKER)) { + return { cancelled: true }; + } + error.stdout = error.stdout.slice(EXPECTED_SUCCESSFUL_AUTH_MARKER.length); + } + throw error; + } +} diff --git a/lib/shared/permissions.js b/lib/shared/permissions.js index a8ee05fd..3a35c2d0 100755 --- a/lib/shared/permissions.js +++ b/lib/shared/permissions.js @@ -31,6 +31,7 @@ const { promisify } = require('util') const errors = require('./errors') const { tmpFileDisposer } = require('./utils') +// eslint-disable-next-line node/no-missing-require const { sudo: catalinaSudo } = require('./catalina-sudo/sudo') const writeFileAsync = promisify(fs.writeFile)