show the triggering brew command in the sudo password dialog
The askpass script is now rewritten before each brew invocation with
the current command baked into the dialog text ("...to run: brew
upgrade tailscale-app") instead of a generic message written once at
launch. The command text is whitelisted to characters that cannot
break out of the shell/AppleScript quoting it is embedded in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
421ae5c40d
commit
89921275b8
|
|
@ -145,22 +145,29 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
return "brew"
|
||||
}
|
||||
|
||||
/// Written once per launch; sudo runs it to show a GUI password dialog
|
||||
/// whenever brew needs admin rights (no terminal is attached to Process).
|
||||
static let askpassURL: URL = {
|
||||
/// Rewritten before each brew command so the sudo password dialog can say
|
||||
/// which command needs it. Sudo runs this script to show a GUI password
|
||||
/// prompt whenever brew needs admin rights (no terminal is attached to
|
||||
/// Process). If two brew commands overlap, the later one's text wins —
|
||||
/// harmless, since prompts realistically only appear during upgrades.
|
||||
static func writeAskpassScript(for command: String) -> URL {
|
||||
let dir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
|
||||
.appendingPathComponent("BrewBar", isDirectory: true)
|
||||
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
|
||||
|
||||
// the text lands inside shell single quotes AND an AppleScript string;
|
||||
// whitelist characters that cannot break out of either
|
||||
let safeCommand = command.filter { $0.isLetter || $0.isNumber || " ._@+=:/-".contains($0) }
|
||||
|
||||
let url = dir.appendingPathComponent("askpass.sh")
|
||||
let script = """
|
||||
#!/bin/zsh
|
||||
osascript -e 'display dialog "BrewBar needs your administrator password to continue:" default answer "" with hidden answer with title "BrewBar" with icon caution buttons {"Cancel", "OK"} default button "OK"' -e 'text returned of result'
|
||||
osascript -e 'display dialog "BrewBar needs your administrator password to run:\\n\\nbrew \(safeCommand)" default answer "" with hidden answer with title "BrewBar" with icon caution buttons {"Cancel", "OK"} default button "OK"' -e 'text returned of result'
|
||||
"""
|
||||
try? script.write(to: url, atomically: true, encoding: .utf8)
|
||||
try? FileManager.default.setAttributes([.posixPermissions: 0o700], ofItemAtPath: url.path)
|
||||
return url
|
||||
}()
|
||||
}
|
||||
|
||||
func runBrew(_ command: String, completion: @escaping (String) -> Void = { _ in }) {
|
||||
DispatchQueue.global().async {
|
||||
|
|
@ -177,7 +184,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
process.arguments = arguments
|
||||
|
||||
var environment = ProcessInfo.processInfo.environment
|
||||
environment["SUDO_ASKPASS"] = Self.askpassURL.path
|
||||
environment["SUDO_ASKPASS"] = Self.writeAskpassScript(for: cleaned).path
|
||||
process.environment = environment
|
||||
|
||||
let pipe = Pipe()
|
||||
|
|
|
|||
Loading…
Reference in a new issue