mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-29 14:16:36 +00:00
patch: refactor permission code for windows
This commit is contained in:
parent
2eb3acd094
commit
fdf8820b5a
@ -102,31 +102,7 @@ export async function elevateCommand(
|
|||||||
return { cancelled: false };
|
return { cancelled: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const isWindows = os.platform() === 'win32';
|
if (os.platform() === 'win32') {
|
||||||
|
|
||||||
// Augment the command to pass the environment variables as args
|
|
||||||
// Powershell (required to ask for elevated privileges) as of win10 cannot pass environment variables as a map, so we pass them as args
|
|
||||||
// For the sake of consistency, we do the same for Linux and macOS, but it's likely not required
|
|
||||||
// Once we deprecate win10 we can move to a more elegant solution (passing the env to powershell)
|
|
||||||
// const envFilter: string[] = [
|
|
||||||
// 'ETCHER_SERVER_ADDRESS',
|
|
||||||
// 'ETCHER_SERVER_PORT',
|
|
||||||
// 'ETCHER_SERVER_ID',
|
|
||||||
// 'ETCHER_NO_SPAWN_UTIL',
|
|
||||||
// 'ETCHER_TERMINATE_TIMEOUT',
|
|
||||||
// 'UV_THREADPOOL_SIZE',
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// const preparedCmd = [
|
|
||||||
// command[0],
|
|
||||||
// ...command.slice(1),
|
|
||||||
// ...Object.keys(options.env)
|
|
||||||
// .filter((key) => Object.prototype.hasOwnProperty.call(options.env, key))
|
|
||||||
// .filter((key) => envFilter.includes(key))
|
|
||||||
// .map((key) => `--${key}=${options.env[key]}`),
|
|
||||||
// ];
|
|
||||||
|
|
||||||
if (isWindows) {
|
|
||||||
return elevateScriptWindows(command, options.env);
|
return elevateScriptWindows(command, options.env);
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
/*
|
/* *
|
||||||
* This is heavily inspired (read: a ripof) https://github.com/balena-io-modules/sudo-prompt
|
|
||||||
* Which was a fork of https://github.com/jorangreef/sudo-prompt
|
|
||||||
*
|
*
|
||||||
* This and the original code was released under The MIT License (MIT)
|
* Copyright (c) 2025 Balena
|
||||||
*
|
|
||||||
* Copyright (c) 2015 Joran Dirk Greef
|
|
||||||
* Copyright (c) 2024 Balena
|
|
||||||
*
|
*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
@ -35,7 +30,29 @@ export async function sudo(
|
|||||||
env: any,
|
env: any,
|
||||||
): Promise<{ cancelled: boolean; stdout?: string; stderr?: string }> {
|
): Promise<{ cancelled: boolean; stdout?: string; stderr?: string }> {
|
||||||
try {
|
try {
|
||||||
// WindowsWriteCommandScript(instance, end)
|
// Augment the command to pass the environment variables as args
|
||||||
|
|
||||||
|
// Powershell (required to ask for elevated privileges) as of win10
|
||||||
|
// cannot pass environment variables as a map, so we pass them as args
|
||||||
|
// this is a workaround as we can't use an equivalent of `sudo -E` on Windows
|
||||||
|
|
||||||
|
const envFilter: string[] = [
|
||||||
|
'ETCHER_SERVER_ADDRESS',
|
||||||
|
'ETCHER_SERVER_PORT',
|
||||||
|
'ETCHER_SERVER_ID',
|
||||||
|
'ETCHER_NO_SPAWN_UTIL',
|
||||||
|
'ETCHER_TERMINATE_TIMEOUT',
|
||||||
|
'UV_THREADPOOL_SIZE',
|
||||||
|
];
|
||||||
|
|
||||||
|
const preparedCmd = [
|
||||||
|
command[0],
|
||||||
|
...command.slice(1),
|
||||||
|
...Object.keys(env)
|
||||||
|
.filter((key) => Object.prototype.hasOwnProperty.call(env, key))
|
||||||
|
.filter((key) => envFilter.includes(key))
|
||||||
|
.map((key) => `--${key}=${env[key]}`),
|
||||||
|
];
|
||||||
|
|
||||||
const spawnCommand = [];
|
const spawnCommand = [];
|
||||||
spawnCommand.push('Start-Process');
|
spawnCommand.push('Start-Process');
|
||||||
@ -45,12 +62,13 @@ export async function sudo(
|
|||||||
// Escape characters for PowerShell using single quotes:
|
// Escape characters for PowerShell using single quotes:
|
||||||
// Escape single quotes for PowerShell using backtick:
|
// Escape single quotes for PowerShell using backtick:
|
||||||
// See: https://ss64.com/ps/syntax-esc.html
|
// See: https://ss64.com/ps/syntax-esc.html
|
||||||
spawnCommand.push(`'${command[0].replace(/'/g, "`'")}'`);
|
spawnCommand.push(`'${preparedCmd[0].replace(/'/g, "`'")}'`);
|
||||||
|
|
||||||
spawnCommand.push('-ArgumentList');
|
spawnCommand.push('-ArgumentList');
|
||||||
|
|
||||||
// Join and escape arguments for PowerShell
|
// Join and escape arguments for PowerShell
|
||||||
spawnCommand.push(
|
spawnCommand.push(
|
||||||
`'${command
|
`'${preparedCmd
|
||||||
.slice(1)
|
.slice(1)
|
||||||
.map((a) => a.replace(/'/g, "`'"))
|
.map((a) => a.replace(/'/g, "`'"))
|
||||||
.join(' ')}'`,
|
.join(' ')}'`,
|
||||||
@ -58,18 +76,27 @@ export async function sudo(
|
|||||||
spawnCommand.push('-WindowStyle hidden');
|
spawnCommand.push('-WindowStyle hidden');
|
||||||
spawnCommand.push('-Verb runAs');
|
spawnCommand.push('-Verb runAs');
|
||||||
|
|
||||||
const child = spawn('powershell.exe', spawnCommand, {
|
const child = spawn('powershell.exe', spawnCommand);
|
||||||
env,
|
|
||||||
});
|
|
||||||
|
|
||||||
let result = { status: 'waiting' };
|
let result = { status: 'waiting' };
|
||||||
|
|
||||||
|
// child.stdout.on('data', (data) => {
|
||||||
|
// console.log(`stdout: ${data}`);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// child.stderr.on('data', (data) => {
|
||||||
|
// console.error(`stderr: ${data}`);
|
||||||
|
// result = { status: data.toString() };
|
||||||
|
// });
|
||||||
|
|
||||||
child.on('close', (code) => {
|
child.on('close', (code) => {
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
// User accepted UAC, process started
|
// User accepted UAC, process started
|
||||||
|
console.log('UAC accepted, process started');
|
||||||
result = { status: 'granted' };
|
result = { status: 'granted' };
|
||||||
} else {
|
} else {
|
||||||
// User cancelled or error occurred
|
// User cancelled or error occurred
|
||||||
|
console.log('UAC cancelled or error occurred');
|
||||||
result = { status: 'cancelled' };
|
result = { status: 'cancelled' };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -80,7 +107,7 @@ export async function sudo(
|
|||||||
|
|
||||||
// we don't spawn directly in the promise otherwise resolving stop the process
|
// we don't spawn directly in the promise otherwise resolving stop the process
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
setTimeout(() => {
|
setInterval(() => {
|
||||||
if (result.status === 'waiting') {
|
if (result.status === 'waiting') {
|
||||||
// Still waiting for user input, don't resolve or reject yet
|
// Still waiting for user input, don't resolve or reject yet
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user