├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── assets ├── linux.png ├── osx.png └── win32.png ├── dist ├── bin │ ├── applet.app │ │ ├── Contents │ │ │ ├── Info.plist │ │ │ ├── MacOS │ │ │ │ └── applet │ │ │ ├── PkgInfo │ │ │ └── Resources │ │ │ │ ├── Scripts │ │ │ │ └── main.scpt │ │ │ │ ├── applet.icns │ │ │ │ ├── applet.rsrc │ │ │ │ └── description.rtfd │ │ │ │ └── TXT.rtf │ │ └── LICENSE │ ├── elevate.exe │ ├── gksudo │ ├── libgksu2.so.0 │ └── libgksu2.so.0.0.2 └── index.js ├── package.json ├── src ├── bin │ ├── applet.app │ │ └── Contents │ │ │ ├── Info.plist │ │ │ ├── MacOS │ │ │ └── applet │ │ │ ├── PkgInfo │ │ │ └── Resources │ │ │ ├── Scripts │ │ │ └── main.scpt │ │ │ ├── applet.icns │ │ │ ├── applet.rsrc │ │ │ └── description.rtfd │ │ │ └── TXT.rtf │ ├── elevate.exe │ ├── gksudo │ ├── libgksu2.so.0 │ └── libgksu2.so.0.0.2 ├── index.js ├── lib │ ├── sudoer.js │ └── utils.js └── vendor │ └── win32 │ ├── .gitignore │ ├── Elevate.sln │ ├── Elevate │ ├── Elevate.rc │ ├── Elevate.vcproj │ ├── Elevate.vcxproj │ ├── Elevate.vcxproj.filters │ ├── main.c │ ├── resource.h │ └── stdafx.h │ ├── LICENSE.md │ └── README.md ├── tests └── index.js └── webpack ├── chmod.js └── config.babel.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "development": {} 4 | }, 5 | "presets": ["stage-0", "es2015"], 6 | "compact": true, 7 | "plugins": [ 8 | "transform-runtime", 9 | "transform-regenerator", 10 | "transform-decorators-legacy", 11 | "transform-class-properties", 12 | "transform-flow-strip-types", 13 | "syntax-object-rest-spread", 14 | "syntax-decorators", 15 | "syntax-async-functions", 16 | "array-includes", 17 | ["transform-async-to-module-method", { 18 | "module": "bluebird", 19 | "method": "coroutine" 20 | }], 21 | ["babel-plugin-module-alias", [ 22 | { "src": "./src/", "expose": "~" }, 23 | { "src": "./test", "expose": "t" } 24 | ]], 25 | "lodash" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | browser: true 4 | node: true 5 | es6: true 6 | jquery: true 7 | mocha: true 8 | parser: "babel-eslint" 9 | parserOptions: 10 | ecmaVersion: 7 11 | sourceType: "module" 12 | ecmaFeatures: 13 | arrowFunctions: true 14 | blockBindings: true 15 | classes: true 16 | defaultParams: true 17 | destructuring: true 18 | forOf: false 19 | generators: true 20 | modules: true 21 | objectLiteralComputedProperties: true 22 | objectLiteralDuplicateProperties: true 23 | objectLiteralShorthandMethods: true 24 | objectLiteralShorthandProperties: true 25 | octalLiterals: true 26 | regexUFlag: true 27 | regexYFlag: true 28 | restParams: true 29 | spread: true 30 | superInFunctions: true 31 | templateStrings: true 32 | unicodeCodePointEscapes: true 33 | globalReturn: false 34 | rules: 35 | indent: 36 | - "error" 37 | - 4 38 | - 39 | SwitchCase: 1 40 | semi: 41 | - 2 42 | - "always" 43 | quotes: 44 | - 2 45 | - "single" 46 | strict: 47 | - 2 48 | - "never" 49 | eqeqeq: 50 | - 2 51 | - "smart" 52 | no-var: 2 53 | valid-jsdoc: "error" 54 | no-undef: "error" 55 | no-unused-labels: "error" 56 | no-unused-expressions: "error" 57 | no-useless-concat: "error" 58 | block-scoped-var: 2 59 | camelcase: 60 | - "error" 61 | - 62 | properties: "never" 63 | comma-style: 64 | - 2 65 | - "last" 66 | curly: 67 | - 2 68 | - "all" 69 | dot-notation: 70 | - 2 71 | - 72 | allowKeywords: true 73 | no-caller: 2 74 | no-cond-assign: 75 | - 2 76 | - "except-parens" 77 | no-debugger: 2 78 | no-extend-native: 2 79 | no-extra-parens: 2 80 | no-irregular-whitespace: 2 81 | no-iterator: 2 82 | no-loop-func: 2 83 | no-multi-str: 2 84 | no-new: 2 85 | no-proto: 2 86 | no-script-url: 2 87 | no-sequences: 2 88 | no-unused-vars: 89 | - "error" 90 | - 91 | caughtErrors: "none" 92 | args: "none" 93 | no-with: 2 94 | valid-typeof: 2 95 | wrap-iife: 96 | - 2 97 | - "inside" 98 | no-multi-spaces: "error" 99 | newline-per-chained-call: 100 | - "error" 101 | - 102 | ignoreChainWithDepth: 3 103 | no-duplicate-imports: 104 | - "error" 105 | - 106 | includeExports: true 107 | no-dupe-class-members: "error" 108 | no-const-assign: "error" 109 | no-confusing-arrow: "error" 110 | constructor-super: "error" 111 | babel/generator-star-spacing: 1 112 | babel/new-cap: 113 | - 2 114 | - 115 | capIsNewExceptions: 116 | - "$.Event" 117 | babel/object-shorthand: 1 118 | babel/arrow-parens: 1 119 | babel/no-await-in-loop: 1 120 | 121 | plugins: 122 | - "babel" 123 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS X 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Logs 7 | logs 8 | *.log 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Compiled binary addons (http://nodejs.org/api/addons.html) 19 | build/Release 20 | 21 | # Dependency directory 22 | # Deployed apps should consider commenting this line out: 23 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 24 | node_modules 25 | cache 26 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .npmignore 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Aleksandr Komlev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Electron subprocess with administrative privileges 2 | 3 | Run a subprocess with administrative privileges, prompting the user with a graphical OS dialog if necessary. Useful for background subprocesse which run native Electron apps that need sudo. 4 | 5 | - `Windows`, uses [elevate utility](https://github.com/automation-stack/electron-sudo/tree/master/src/vendor/win32) with native `User Account Control (UAC)` prompt (no `PowerShell` required) 6 | - `OS X`, uses bundled [applet](https://github.com/automation-stack/electron-sudo/tree/master/src/bin/applet.app) (inspired by [Joran Dirk Greef](https://github.com/jorangreef)) 7 | - `Linux`, uses system `pkexec` or [gksudo](http://www.nongnu.org/gksu) (system or bundled). 8 | 9 | If you don't trust binaries bundled in `npm` package you can manually build tools and use them instead. 10 | 11 | 12 | 13 | ## Features 14 | - Supports ```spawn``` and ```exec``` subprocess behavior 15 | - Supports applications packaged as ```asar``` archive 16 | - Separate password prompt for each call (use ```sh``` or ```bat``` script for single prompt) 17 | - No external dependencies, does not depend on OS versions 18 | 19 | ## Installation 20 | ``` 21 | npm install electron-sudo 22 | ``` 23 | 24 | ## Usage 25 | **Note: Your command should not start with the ```sudo``` prefix.** 26 | 27 | ### Version 4.0.* 28 | 29 | ```js 30 | import Sudoer from 'electron-sudo'; 31 | 32 | let options = {name: 'electron sudo application'}, 33 | sudoer = new Sudoer(options); 34 | 35 | /* Spawn subprocess behavior */ 36 | let cp = await sudoer.spawn( 37 | 'echo', ['$PARAM'], {env: {PARAM: 'VALUE'}} 38 | ); 39 | cp.on('close', () => { 40 | /* 41 | cp.output.stdout (Buffer) 42 | cp.output.stderr (Buffer) 43 | */ 44 | }); 45 | 46 | /* Exec subprocess behavior */ 47 | let result = await sudoer.exec( 48 | 'echo $PARAM', {env: {PARAM: 'VALUE'}} 49 | ); 50 | /* result is Buffer with mixed (both stdout and stderr) output */ 51 | 52 | 53 | /* Usage with Vanila JS */ 54 | 55 | var Sudoer = require('electron-sudo').default; 56 | var sudoer = new Sudoer(options); 57 | sudoer.spawn('echo', ['$PARAM'], {env: {PARAM: 'VALUE'}}).then(function (cp) { 58 | /* 59 | cp.output.stdout (Buffer) 60 | cp.output.stderr (Buffer) 61 | */ 62 | }); 63 | 64 | ``` 65 | 66 | ### Version 3.0.* (deprecated) 67 | 68 | ```js 69 | var sudo = require('electron-sudo'); 70 | var options = { 71 | name: 'Your application name', 72 | icns: '/path/to/icns/file' // (optional, only for MacOS), 73 | process: { 74 | options: { 75 | // Can use custom environment variables for your privileged subprocess 76 | env: {'VAR': 'VALUE'} 77 | // ... and all other subprocess options described here 78 | // https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback 79 | }, 80 | on: function(ps) { 81 | ps.stdout.on('data', function(data) {}); 82 | setTimeout(function() { 83 | ps.kill() 84 | }.bind(ps), 50000); 85 | } 86 | } 87 | }; 88 | sudo.exec('echo hello', options, function(error) {}); 89 | ``` 90 | 91 | ## Tests 92 | ``` 93 | npm i && npm test 94 | ``` 95 | 96 | ## Usage with Webpack 97 | 98 | Webpack config should contain ```__dirname``` equals ```true``` for work properly 99 | 100 | ```js 101 | 102 | let nodeModules = fs.readdirSync('./node_modules') 103 | .filter((module) => { 104 | return module !== '.bin'; 105 | }) 106 | .reduce((prev, module) => { 107 | return Object.assign(prev, {[module]: 'commonjs ' + module}); 108 | }, {}); 109 | 110 | export default { 111 | ... 112 | target: 'electron', 113 | node: { 114 | /* http://webpack.github.io/docs/configuration.html#node */ 115 | __dirname: true 116 | }, 117 | externals: nodeModules 118 | }; 119 | ``` 120 | -------------------------------------------------------------------------------- /assets/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/assets/linux.png -------------------------------------------------------------------------------- /assets/osx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/assets/osx.png -------------------------------------------------------------------------------- /assets/win32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/assets/win32.png -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleAllowMixedLocalizations 6 | 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | applet 11 | CFBundleIconFile 12 | applet.icns 13 | CFBundleIdentifier 14 | com.electron-sudo 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | Password Prompt 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | aplt 25 | LSMinimumSystemVersionByArchitecture 26 | 27 | x86_64 28 | 10.6 29 | 30 | LSRequiresCarbon 31 | 32 | LSUIElement 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/MacOS/applet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/applet.app/Contents/MacOS/applet -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPLaplt -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/Resources/Scripts/main.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/applet.app/Contents/Resources/Scripts/main.scpt -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/Resources/applet.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/applet.app/Contents/Resources/applet.icns -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/Resources/applet.rsrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/applet.app/Contents/Resources/applet.rsrc -------------------------------------------------------------------------------- /dist/bin/applet.app/Contents/Resources/description.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf130 2 | {\fonttbl} 3 | {\colortbl;\red255\green255\blue255;} 4 | } -------------------------------------------------------------------------------- /dist/bin/applet.app/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Joran Dirk Greef 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dist/bin/elevate.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/elevate.exe -------------------------------------------------------------------------------- /dist/bin/gksudo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/gksudo -------------------------------------------------------------------------------- /dist/bin/libgksu2.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/libgksu2.so.0 -------------------------------------------------------------------------------- /dist/bin/libgksu2.so.0.0.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/dist/bin/libgksu2.so.0.0.2 -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("bluebird"),require("fs"),require("child_process"),require("crypto"),require("os"),require("path"),require("regenerator-runtime")):"function"==typeof define&&define.amd?define(["bluebird","fs","child_process","crypto","os","path","regenerator-runtime"],e):"object"==typeof exports?exports["electron-sudo"]=e(require("bluebird"),require("fs"),require("child_process"),require("crypto"),require("os"),require("path"),require("regenerator-runtime")):t["electron-sudo"]=e(t.bluebird,t.fs,t.child_process,t.crypto,t.os,t.path,t["regenerator-runtime"])}(this,function(t,e,n,r,u,o,i){return function(t){function e(r){if(n[r])return n[r].exports;var u=n[r]={exports:{},id:r,loaded:!1};return t[r].call(u.exports,u,u.exports,e),u.loaded=!0,u.exports}var n={};return e.m=t,e.c=n,e.p="./dist",e(0)}([function(t,e,n){t.exports=n(61)},function(t,e){var n=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=n)},function(t,e,n){var r=n(31)("wks"),u=n(22),o=n(3).Symbol,i="function"==typeof o,a=t.exports=function(t){return r[t]||(r[t]=i&&o[t]||(i?o:u)("Symbol."+t))};a.store=r},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){var r=n(3),u=n(1),o=n(11),i=n(9),a="prototype",c=function(t,e,n){var s,f,p,l=t&c.F,d=t&c.G,v=t&c.S,h=t&c.P,y=t&c.B,b=t&c.W,x=d?u:u[e]||(u[e]={}),w=x[a],m=d?r:v?r[e]:(r[e]||{})[a];d&&(n=e);for(s in n)f=!l&&m&&void 0!==m[s],f&&s in x||(p=f?m[s]:n[s],x[s]=d&&"function"!=typeof m[s]?n[s]:y&&f?o(p,r):b&&m[s]==p?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e[a]=t[a],e}(p):h&&"function"==typeof p?o(Function.call,p):p,h&&((x.virtual||(x.virtual={}))[s]=p,t&c.R&&w&&!w[s]&&i(w,s,p)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,e,n){var r=n(6),u=n(44),o=n(34),i=Object.defineProperty;e.f=n(7)?Object.defineProperty:function(t,e,n){if(r(t),e=o(e,!0),r(n),u)try{return i(t,e,n)}catch(a){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){var r=n(13);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e,n){t.exports=!n(12)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var r=n(5),u=n(17);t.exports=n(7)?function(t,e,n){return r.f(t,e,u(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var r=n(45),u=n(25);t.exports=function(t){return r(u(t))}},function(t,e,n){var r=n(24);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,u){return t.call(e,n,r,u)}}return function(){return t.apply(e,arguments)}}},function(t,e){t.exports=function(t){try{return!!t()}catch(e){return!0}}},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){t.exports={}},function(t,e,n){var r=n(53),u=n(27);t.exports=Object.keys||function(t){return r(t,u)}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e){t.exports=!0},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){var r=n(5).f,u=n(8),o=n(2)("toStringTag");t.exports=function(t,e,n){t&&!u(t=n?t:t.prototype,o)&&r(t,o,{configurable:!0,value:e})}},function(t,e,n){var r=n(25);t.exports=function(t){return Object(r(t))}},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var u=n(70),o=r(u),i=n(69),a=r(i),c="function"==typeof a["default"]&&"symbol"==typeof o["default"]?function(t){return typeof t}:function(t){return t&&"function"==typeof a["default"]&&t.constructor===a["default"]&&t!==a["default"].prototype?"symbol":typeof t};e["default"]="function"==typeof a["default"]&&"symbol"===c(o["default"])?function(t){return"undefined"==typeof t?"undefined":c(t)}:function(t){return t&&"function"==typeof a["default"]&&t.constructor===a["default"]&&t!==a["default"].prototype?"symbol":"undefined"==typeof t?"undefined":c(t)}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e,n){var r=n(13),u=n(3).document,o=r(u)&&r(u.createElement);t.exports=function(t){return o?u.createElement(t):{}}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(6),u=n(99),o=n(27),i=n(30)("IE_PROTO"),a=function(){},c="prototype",s=function(){var t,e=n(26)("iframe"),r=o.length,u="<",i=">";for(e.style.display="none",n(43).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(u+"script"+i+"document.F=Object"+u+"/script"+i),t.close(),s=t.F;r--;)delete s[c][o[r]];return s()};t.exports=Object.create||function(t,e){var n;return null!==t?(a[c]=r(t),n=new a,a[c]=null,n[i]=t):n=s(),void 0===e?n:u(n,e)}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){var r=n(31)("keys"),u=n(22);t.exports=function(t){return r[t]||(r[t]=u(t))}},function(t,e,n){var r=n(3),u="__core-js_shared__",o=r[u]||(r[u]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(32),u=Math.min;t.exports=function(t){return t>0?u(r(t),9007199254740991):0}},function(t,e,n){var r=n(13);t.exports=function(t,e){if(!r(t))return t;var n,u;if(e&&"function"==typeof(n=t.toString)&&!r(u=n.call(t)))return u;if("function"==typeof(n=t.valueOf)&&!r(u=n.call(t)))return u;if(!e&&"function"==typeof(n=t.toString)&&!r(u=n.call(t)))return u;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var r=n(3),u=n(1),o=n(18),i=n(36),a=n(5).f;t.exports=function(t){var e=u.Symbol||(u.Symbol=o?{}:r.Symbol||{});"_"==t.charAt(0)||t in e||a(e,t,{value:i.f(t)})}},function(t,e,n){e.f=n(2)},function(t,e,n){"use strict";var r=n(106)(!0);n(48)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e,n){t.exports={"default":n(77),__esModule:!0}},function(t,e,n){t.exports={"default":n(82),__esModule:!0}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var u=n(64),o=r(u);e["default"]=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);ec;)r(a,n=e[c++])&&(~o(s,n)||s.push(n));return s}},function(t,e,n){t.exports=n(9)},function(t,e,n){var r,u,o,i=n(11),a=n(91),c=n(43),s=n(26),f=n(3),p=f.process,l=f.setImmediate,d=f.clearImmediate,v=f.MessageChannel,h=0,y={},b="onreadystatechange",x=function(){var t=+this;if(y.hasOwnProperty(t)){var e=y[t];delete y[t],e()}},w=function(t){x.call(t.data)};l&&d||(l=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return y[++h]=function(){a("function"==typeof t?t:Function(t),e)},r(h),h},d=function(t){delete y[t]},"process"==n(14)(p)?r=function(t){p.nextTick(i(x,t,1))}:v?(u=new v,o=u.port2,u.port1.onmessage=w,r=i(o.postMessage,o,1)):f.addEventListener&&"function"==typeof postMessage&&!f.importScripts?(r=function(t){f.postMessage(t+"","*")},f.addEventListener("message",w,!1)):r=b in s("script")?function(t){c.appendChild(s("script"))[b]=function(){c.removeChild(this),x.call(t)}}:function(t){setTimeout(i(x,t,1),0)}),t.exports={set:l,clear:d}},function(t,e,n){var r=n(42),u=n(2)("iterator"),o=n(15);t.exports=n(1).getIteratorMethod=function(t){return void 0!=t?t[u]||t["@@iterator"]||o[r(t)]:void 0}},function(t,e){},function(t,e,n){n(109);for(var r=n(3),u=n(9),o=n(15),i=n(2)("toStringTag"),a=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],c=0;5>c;c++){var s=a[c],f=r[s],p=f&&f.prototype;p&&!p[i]&&u(p,i,s),o[s]=o.Array}},function(t,e){t.exports=require("bluebird")},function(t,e){t.exports=require("fs")},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(62);e["default"]=function(){var t=process,e=t.platform;switch(e){case"darwin":return r.SudoerDarwin;case"win32":return r.SudoerWin32;case"linux":return r.SudoerLinux;default:throw new Error("Unsupported platform: "+e)}}()},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0}),e.SudoerWin32=e.SudoerLinux=e.SudoerDarwin=void 0;var u=n(38),o=r(u),i=n(40),a=r(i),c=n(41),s=r(c),f=n(39),p=r(f),l=n(59),d=n(67),v=r(d),h=n(75),y=r(h),b=n(74),x=r(b),w=n(23),m=r(w),_=n(71),g=r(_),k=n(72),j=r(k),O=n(121),S=n(60),E=n(122),P=n(120),M=n(63),F=process,A=F.platform,T=F.env,q=function(){function t(e){(0,g["default"])(this,t),this.platform=A,this.options=e,this.cp=null,this.tmpdir=(0,O.tmpdir)()}return(0,j["default"])(t,[{key:"hash",value:function e(t){var e=(0,P.createHash)("sha256");return e.update("electron-sudo"),e.update(this.options.name||""),e.update(t||new Buffer(0)),e.digest("hex").slice(-32)}},{key:"joinEnv",value:function(t){var e=t.env,n=[];if(e&&"object"==("undefined"==typeof e?"undefined":(0,m["default"])(e)))for(var r in e)n.push(r.concat("=",e[r]));return n}},{key:"escapeDoubleQuotes",value:function(t){return t.replace(/"/g,'\\"')}},{key:"encloseDoubleQuotes",value:function(t){return t.replace(/(.+)/g,'"$1"')}},{key:"kill",value:function(t){}}]),t}(),D=function(t){function e(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];(0,g["default"])(this,e);var n=(0,y["default"])(this,(0,v["default"])(e).call(this,t));return n.options.name||(n.options.name="Electron"),n}return(0,x["default"])(e,t),(0,j["default"])(e,[{key:"copy",value:function(){function t(t,n){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t,e){var r=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,o){var i;return s["default"].wrap(function(u){for(;;)switch(u.prev=u.next){case 0:return t=r.escapeDoubleQuotes((0,E.normalize)(t)),e=r.escapeDoubleQuotes((0,E.normalize)(e)),u.prev=2,u.next=5,(0,M.exec)('/bin/cp -R -p "'+t+'" "'+e+'"');case 5:i=u.sent,n(i),u.next=12;break;case 9:u.prev=9,u.t0=u["catch"](2),o(u.t0);case 12:case"end":return u.stop()}},u,r,[[2,9]])}));return function(t,e){return n.apply(this,arguments)}}()));case 1:case"end":return n.stop()}},n,this)}));return t}()},{key:"remove",value:function(){function t(t){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e,r=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return e=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,o){var i;return s["default"].wrap(function(u){for(;;)switch(u.prev=u.next){case 0:if(t.startsWith(e.tmpdir)){u.next=2;break}throw new Error("Try to remove suspicious target: "+t+".");case 2:return t=r.escapeDoubleQuotes((0,E.normalize)(t)),u.prev=3,u.next=6,(0,M.exec)('rm -rf "'+t+'"');case 6:i=u.sent,n(i),u.next=13;break;case 10:u.prev=10,u.t0=u["catch"](3),o(u.t0);case 13:case"end":return u.stop()}},u,r,[[3,10]])}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()},{key:"reset",value:function(){function t(){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(){return s["default"].wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,(0,M.exec)("/usr/bin/sudo -k");case 2:case"end":return t.stop()}},n,this)}));return t}()}]),e}(q),I=function(t){function e(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];(0,g["default"])(this,e);var n=(0,y["default"])(this,(0,v["default"])(e).call(this,t));if(t.icns&&"string"!=typeof t.icns)throw new Error("options.icns must be a string if provided.");if(t.icns&&0===t.icns.trim().length)throw new Error("options.icns must be a non-empty string if provided.");return n.up=!1,n}return(0,x["default"])(e,t),(0,j["default"])(e,[{key:"isValidName",value:function(t){return/^[a-z0-9 ]+$/i.test(t)&&t.trim().length>0&&t.length<70}},{key:"joinEnv",value:function(t){var e=t.env,n=[];if(e&&"object"==("undefined"==typeof e?"undefined":(0,m["default"])(e)))for(var r in e)n.push(r.concat("=",e[r]));return n}},{key:"exec",value:function(){function t(t,n){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e=this,r=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,o){var i,a,c,f;return s["default"].wrap(function(u){for(;;)switch(u.prev=u.next){case 0:return i=e,a=i.joinEnv(r),c=["/usr/bin/sudo -n",a.join(" "),"-s",t].join(" "),f=void 0,u.next=3,i.reset();case 3:return u.prev=3,u.next=6,(0,M.exec)(c,r);case 6:f=u.sent,n(f),u.next=24;break;case 10:return u.prev=10,u.t0=u["catch"](3),u.prev=12,u.next=15,i.prompt();case 15:return u.next=17,(0,M.exec)(c,r);case 17:f=u.sent,n(f),u.next=24;break;case 21:u.prev=21,u.t1=u["catch"](12),o(u.t1);case 24:case"end":return u.stop()}},u,e,[[3,10],[12,21]])}));return function(t,e){return n.apply(this,arguments)}}()));case 1:case"end":return n.stop()}},n,this)}));return t}()},{key:"spawn",value:function(){function t(t,n,r){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t,e){var r=this,u=arguments.length<=2||void 0===arguments[2]?{}:arguments[2];return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function o(n,i){var c,f,p;return s["default"].wrap(function(o){for(;;)switch(o.prev=o.next){case 0:return c=r,f="/usr/bin/sudo",p=void 0,o.next=3,c.reset();case 3:return o.next=5,c.prompt();case 5:p=(0,M.spawn)(f,["-n","-s","-E",[t].concat((0,a["default"])(e)).join(" ")],u),p.on("error",function(){var t=(0,l.coroutine)(s["default"].mark(function e(t){return s["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:i(t);case 1:case"end":return e.stop()}},e,r)}));return function(e){return t.apply(this,arguments)}}()),c.cp=p,n(p);case 9:case"end":return o.stop()}},o,r)}));return function(t,e){return n.apply(this,arguments)}}()));case 1:case"end":return n.stop()}},n,this)}));return t}()},{key:"prompt",value:function(){function t(){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(){var t,e=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return t=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function r(n,u){var o,i,a,c;return s["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t.tmpdir){e.next=2;break}return e.abrupt("return",u(new Error("Requires os.tmpdir() to be defined.")));case 2:if(T.USER){e.next=4;break}return e.abrupt("return",u(new Error("Requires env['USER'] to be defined.")));case 4:return t.up=!0,e.next=7,t.readIcns();case 7:return o=e.sent,i=t.hash(o),a=(0,E.join)((0,E.dirname)(__filename)+"/bin","applet.app"),c=(0,E.join)(t.tmpdir,i,t.options.name+".app"),e.prev=10,e.next=13,(0,M.mkdir)((0,E.dirname)(c));case 13:e.next=19;break;case 15:if(e.prev=15,e.t0=e["catch"](10),"EEXIST"===e.t0.code){e.next=19;break}return e.abrupt("return",u(e.t0));case 19:return e.prev=19,e.next=22,t.copy(a,c);case 22:return e.next=24,t.icon(c);case 24:return e.next=26,t.propertyList(c);case 26:return e.next=28,t.open(c);case 28:return e.next=30,t.remove(c);case 30:e.next=35;break;case 32:return e.prev=32,e.t1=e["catch"](19),e.abrupt("return",u(e.t1));case 35:return e.abrupt("return",n(i));case 36:case"end":return e.stop()}},r,e,[[10,15],[19,32]])}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()},{key:"icon",value:function(){function t(t){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e,r=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return e=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,o){var i;return s["default"].wrap(function(u){for(;;)switch(u.prev=u.next){case 0:if(r.options.icns){u.next=2;break}return u.abrupt("return",n());case 2:return u.next=4,e.copy(r.options.icns,(0,E.join)(t,"Contents","Resources","applet.icns"));case 4:return i=u.sent,u.abrupt("return",n(i));case 6:case"end":return u.stop()}},u,r)}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()},{key:"open",value:function(){function t(t){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e,r=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return e=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,o){var i;return s["default"].wrap(function(r){for(;;)switch(r.prev=r.next){case 0:return t=e.escapeDoubleQuotes((0,E.normalize)(t)),r.prev=1,r.next=4,(0,M.exec)('open -n -W "'+t+'"');case 4:return i=r.sent,r.abrupt("return",n(i));case 8:return r.prev=8,r.t0=r["catch"](1),r.abrupt("return",o(r.t0));case 11:case"end":return r.stop()}},u,r,[[1,8]])}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()},{key:"readIcns",value:function(){function t(t){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function r(n,u){var o;return s["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t&&"darwin"===A){e.next=2;break}return e.abrupt("return",n(new Buffer(0)));case 2:return e.prev=2,e.next=5,(0,M.readFile)(t);case 5:return o=e.sent,e.abrupt("return",n(o));case 9:return e.prev=9,e.t0=e["catch"](2),e.abrupt("return",u(e.t0));case 12:case"end":return e.stop()}},r,e,[[2,9]])}));return function(t,e){return n.apply(this,arguments)}}()));case 1:case"end":return n.stop()}},n,this)}));return t}()},{key:"propertyList",value:function(){function t(t){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e,r=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return e=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,o){var i,a,c,f;return s["default"].wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(i=e.escapeDoubleQuotes((0,E.join)(t,"Contents","Info.plist")),a=e.escapeDoubleQuotes("CFBundleName"),c=e.options.name+" Password Prompt",!/'/.test(c)){r.next=3;break}return r.abrupt("return",o(new Error("Value should not contain single quotes.")));case 3:return r.next=5,(0,M.exec)('defaults write "'+i+'" "'+a+"\" '"+c+"'");case 5:return f=r.sent,r.abrupt("return",n(f));case 7:case"end":return r.stop()}},u,r)}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()}]),e}(D),B=function(t){function e(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];(0,g["default"])(this,e);var n=(0,y["default"])(this,(0,v["default"])(e).call(this,t));return n.binary=null,n.paths=["/usr/bin/gksudo","/usr/bin/pkexec","./bin/gksudo"],n}return(0,x["default"])(e,t),(0,j["default"])(e,[{key:"getBinary",value:function(){function t(){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(){var t=this;return s["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,p["default"].all(this.paths.map(function(){var e=(0,l.coroutine)(s["default"].mark(function n(e){return s["default"].wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,t.next=3,(0,M.stat)(e);case 3:return e=t.sent,t.abrupt("return",e);case 7:return t.prev=7,t.t0=t["catch"](0),t.abrupt("return",null);case 10:case"end":return t.stop()}},n,t,[[0,7]])}));return function(t){return e.apply(this,arguments)}}()));case 2:return e.t0=function(t){return t},e.abrupt("return",e.sent.filter(e.t0)[0]);case 4:case"end":return e.stop()}},n,this)}));return t}()},{key:"exec",value:function(){function t(t,n){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e=this,r=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function u(n,i){var a,c,f;return s["default"].wrap(function(u){for(;;)switch(u.prev=u.next){case 0:if(a=e,c=void 0,a.binary){u.next=5;break}return u.next=4,a.getBinary();case 4:a.binary=u.sent;case 5:return r.env instanceof Object&&!r.env.DISPLAY&&(r.env=(0,o["default"])(r.env,{DISPLAY:":0"})),f=void 0,/gksudo/i.test(a.binary)?f="--preserve-env --sudo-mode "+('--description="'+a.escapeDoubleQuotes(a.options.name)+'"'):/pkexec/i.test(a.binary)&&(f="--disable-internal-agent"),t=e.binary+" "+f+" "+t,u.prev=9,u.next=12,(0,M.exec)(t,r);case 12:return c=u.sent,u.abrupt("return",n(c));case 16:return u.prev=16,u.t0=u["catch"](9),u.abrupt("return",i(u.t0));case 19:case"end":return u.stop()}},u,e,[[9,16]])}));return function(t,e){return n.apply(this,arguments)}}()));case 1:case"end":return n.stop()}},n,this)}));return t}()},{key:"spawn",value:function(){function t(t,n,r){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t,e){var r,u=this,i=arguments.length<=2||void 0===arguments[2]?{}:arguments[2];return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return r=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function a(n,c){var f,p;return s["default"].wrap(function(u){for(;;)switch(u.prev=u.next){case 0:if(r.binary){u.next=5;break}return u.next=3,r.getBinary();case 3:u.t0=function(t){return t},r.binary=u.sent.filter(u.t0)[0];case 5:return i.env instanceof Object&&!i.env.DISPLAY&&(i.env=(0,o["default"])(i.env,{DISPLAY:":0"})),f=[],/gksudo/i.test(r.binary)?(f.push("--preserve-env"),f.push("--sudo-mode"),f.push('--description="'+r.escapeDoubleQuotes(r.options.name)+'"'),f.push("--sudo-mode")):/pkexec/i.test(r.binary)&&f.push("--disable-internal-agent"),f.push(t),f.push(e),u.prev=10,p=(0,M.spawn)(r.binary,f,i),u.abrupt("return",n(p));case 15:return u.prev=15,u.t1=u["catch"](10),u.abrupt("return",c(u.t1));case 18:case"end":return u.stop()}},a,u,[[10,15]])}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()}]),e}(D),R=function(t){function e(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];(0,g["default"])(this,e);var n=(0,y["default"])(this,(0,v["default"])(e).call(this,t));return n.bundled="src\\bin\\elevate.exe",n.binary=null,n}return(0,x["default"])(e,t),(0,j["default"])(e,[{key:"writeBatch",value:function(){function t(t,n,r){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t,e,r){var u,o,i,a,c;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,(0,M.exec)("echo %temp%");case 2:return u=n.sent.stdout.toString().replace(/\r\n$/,""),o=u+"\\batch-"+Math.random()+".bat",i=u+"\\output-"+Math.random(),a=this.joinEnv(r),c="setlocal enabledelayedexpansion\r\n",a.length&&(c+="set "+a.join("\r\nset ")+"\r\n"),c+=e&&e.length?t+" "+e.join(" "):t,n.next=11,(0,M.writeFile)(o,c+" > "+i+" 2>&1");case 11:return n.next=13,(0,M.writeFile)(i,"");case 13:return n.abrupt("return",{batch:o,output:i});case 14:case"end":return n.stop()}},n,this)}));return t}()},{key:"watchOutput",value:function(){function t(t){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e,r,u;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return e=this,n.next=3,(0,M.readFile)(t.files.output);case 3:return r=n.sent,t.stdout.emit("data",r),u=(0,S.watchFile)(t.files.output,{persistent:!0,interval:1},function(){var e=(0,S.createReadStream)(t.files.output,{start:u.last}),n=0;e.on("data",function(e){n+=e.length,t&&t.stdout.emit("data",e)}),e.on("close",function(){t.last+=n})}),t.last=r.length,t.on("exit",function(){e.clean(t)}),n.abrupt("return",t);case 9:case"end":return n.stop()}},n,this)}));return t}()},{key:"prepare",value:function(){function t(){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(){var t,e=this;return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return t=this,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function r(n,u){var o,i;return s["default"].wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(!t.binary){r.next=2;break}return r.abrupt("return",n(t.binary));case 2:return o=(0,E.join)(e.tmpdir,"elevate.exe"),r.next=5,(0,M.stat)(o);case 5:if(r.sent){r.next=12;break}i=(0,S.createWriteStream)(o),(0,S.createReadStream)(t.bundled).pipe(i),i.on("close",function(){return t.binary=o,n(t.binary)}),i.on("error",function(t){return u(t)}),r.next=14;break;case 12:t.binary=o,n(t.binary);case 14:case"end":return r.stop()}},r,e)}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()},{key:"exec",value:function(){function t(t,n){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t){var e,r,u,o=this,i=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return e=this,r=void 0,u=void 0,n.abrupt("return",new p["default"](function(){var n=(0,l.coroutine)(s["default"].mark(function a(n,c){return s["default"].wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return a.prev=0,a.next=3,o.prepare();case 3:return a.next=5,e.writeBatch(t,[],i);case 5:return r=a.sent,t=e.encloseDoubleQuotes(e.binary)+" -wait "+r.batch,a.next=9,(0,M.exec)(t,i);case 9:return a.next=11,(0,M.readFile)(r.output);case 11:return u=a.sent,a.abrupt("return",n(u));case 15:return a.prev=15,a.t0=a["catch"](0),a.abrupt("return",c(a.t0));case 18:case"end":return a.stop()}},a,o,[[0,15]])}));return function(t,e){return n.apply(this,arguments)}}()));case 2:case"end":return n.stop()}},n,this)}));return t}()},{key:"spawn",value:function(){function t(t,n,r){return e.apply(this,arguments)}var e=(0,l.coroutine)(s["default"].mark(function n(t,e){var r,u,o,i=arguments.length<=2||void 0===arguments[2]?{}:arguments[2];return s["default"].wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,this.writeBatch(t,e,i);case 2:return r=n.sent,u=[],o=void 0,u.push("-wait"),u.push(r.batch),n.next=9,this.prepare();case 9:return o=(0,M.spawn)(this.binary,u,i,{wait:!1}),o.files=r,n.next=13,this.watchOutput(o);case 13:return n.abrupt("return",o);case 14:case"end":return n.stop()}},n,this)}));return t}()},{key:"clean",value:function(t){(0,S.unwatchFile)(t.files.output),(0,S.unlink)(t.files.batch),(0,S.unlink)(t.files.output)}}]),e}(q);e.SudoerDarwin=I,e.SudoerLinux=B,e.SudoerWin32=R},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function u(t){return function(){var e=arguments;return new h["default"](function(n,r){t.apply(void 0,Array.prototype.slice.call(e).concat([function(){arguments[0]instanceof Error?r(arguments[0]):n.apply(void 0,(0,d["default"])(Array.prototype.slice.call(arguments,1)))}]))})}}function o(t,e){var n=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],r=_["default"].spawn(t,e,(0,c["default"])({},n,{shell:!0}));return r.output={stdout:new Buffer(0),stderr:new Buffer(0)},r.stdout.on("data",function(t){r.output.stdout=i(t,r.output.stdout)}),r.stderr.on("data",function(t){r.output.stderr=i(t,r.output.stderr)}),r}function i(t,e){return t instanceof Buffer||(t=new Buffer(t,"utf8")),!e instanceof Buffer&&(e=new Buffer(0)),Buffer.concat([e,t])}Object.defineProperty(e,"__esModule",{value:!0}),e.open=e.stat=e.mkdir=e.exec=e.spawn=e.writeFile=e.readFile=void 0; 2 | var a=n(73),c=r(a),s=n(41),f=r(s),p=n(59),l=n(40),d=r(l),v=n(39),h=r(v),y=function(){var t=(0,p.coroutine)(f["default"].mark(function e(t){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return f["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",new h["default"](function(e,r){_["default"].exec(t,n,function(t,n,u){return t?r(t):e({stdout:n,stderr:u})})}));case 1:case"end":return e.stop()}},e,this)}));return function(e,n){return t.apply(this,arguments)}}(),b=function(){var t=(0,p.coroutine)(f["default"].mark(function e(t){var n,r;return f["default"].wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return n=u(w["default"].stat),e.prev=1,e.next=4,n(t);case 4:return r=e.sent,e.abrupt("return",r);case 8:return e.prev=8,e.t0=e["catch"](1),e.abrupt("return",null);case 11:case"end":return e.stop()}},e,this,[[1,8]])}));return function(e){return t.apply(this,arguments)}}(),x=n(60),w=r(x),m=n(119),_=r(m),g=u(w["default"].open),k=u(w["default"].mkdir),j=u(w["default"].readFile),O=u(w["default"].writeFile);e.readFile=j,e.writeFile=O,e.spawn=o,e.exec=y,e.mkdir=k,e.stat=b,e.open=g},function(t,e,n){t.exports={"default":n(76),__esModule:!0}},function(t,e,n){t.exports={"default":n(78),__esModule:!0}},function(t,e,n){t.exports={"default":n(79),__esModule:!0}},function(t,e,n){t.exports={"default":n(80),__esModule:!0}},function(t,e,n){t.exports={"default":n(81),__esModule:!0}},function(t,e,n){t.exports={"default":n(83),__esModule:!0}},function(t,e,n){t.exports={"default":n(84),__esModule:!0}},function(t,e){"use strict";e.__esModule=!0,e["default"]=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var u=n(66),o=r(u);e["default"]=function(){function t(t,e){for(var n=0;nf;)if(a=c[f++],a!=a)return!0}else for(;s>f;f++)if((t||f in c)&&c[f]===n)return t||f||0;return!t&&-1}}},function(t,e,n){"use strict";var r=n(5),u=n(17);t.exports=function(t,e,n){e in t?r.f(t,e,u(0,n)):t[e]=n}},function(t,e,n){var r=n(16),u=n(29),o=n(19);t.exports=function(t){var e=r(t),n=u.f;if(n)for(var i,a=n(t),c=o.f,s=0;a.length>s;)c.call(t,i=a[s++])&&e.push(i);return e}},function(t,e,n){var r=n(11),u=n(47),o=n(46),i=n(6),a=n(33),c=n(56),s={},f={},e=t.exports=function(t,e,n,p,l){var d,v,h,y,b=l?function(){return t}:c(t),x=r(n,p,e?2:1),w=0;if("function"!=typeof b)throw TypeError(t+" is not iterable!");if(o(b)){for(d=a(t.length);d>w;w++)if(y=e?x(i(v=t[w])[0],v[1]):x(t[w]),y===s||y===f)return y}else for(h=b.call(t);!(v=h.next()).done;)if(y=u(h,x,v.value,e),y===s||y===f)return y};e.BREAK=s,e.RETURN=f},function(t,e){t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},function(t,e,n){var r=n(14);t.exports=Array.isArray||function(t){return"Array"==r(t)}},function(t,e,n){"use strict";var r=n(28),u=n(17),o=n(20),i={};n(9)(i,n(2)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(i,{next:u(1,n)}),o(t,e+" Iterator")}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){var r=n(16),u=n(10);t.exports=function(t,e){for(var n,o=u(t),i=r(o),a=i.length,c=0;a>c;)if(o[n=i[c++]]===e)return n}},function(t,e,n){var r=n(22)("meta"),u=n(13),o=n(8),i=n(5).f,a=0,c=Object.isExtensible||function(){return!0},s=!n(12)(function(){return c(Object.preventExtensions({}))}),f=function(t){i(t,r,{value:{i:"O"+ ++a,w:{}}})},p=function(t,e){if(!u(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,r)){if(!c(t))return"F";if(!e)return"E";f(t)}return t[r].i},l=function(t,e){if(!o(t,r)){if(!c(t))return!0;if(!e)return!1;f(t)}return t[r].w},d=function(t){return s&&v.NEED&&c(t)&&!o(t,r)&&f(t),t},v=t.exports={KEY:r,NEED:!1,fastKey:p,getWeak:l,onFreeze:d}},function(t,e,n){var r=n(3),u=n(55).set,o=r.MutationObserver||r.WebKitMutationObserver,i=r.process,a=r.Promise,c="process"==n(14)(i);t.exports=function(){var t,e,n,s=function(){var r,u;for(c&&(r=i.domain)&&r.exit();t;){u=t.fn,t=t.next;try{u()}catch(o){throw t?n():e=void 0,o}}e=void 0,r&&r.enter()};if(c)n=function(){i.nextTick(s)};else if(o){var f=!0,p=document.createTextNode("");new o(s).observe(p,{characterData:!0}),n=function(){p.data=f=!f}}else if(a&&a.resolve){var l=a.resolve();n=function(){l.then(s)}}else n=function(){u.call(r,s)};return function(r){var u={fn:r,next:void 0};e&&(e.next=u),t||(t=u,n()),e=u}}},function(t,e,n){"use strict";var r=n(16),u=n(29),o=n(19),i=n(21),a=n(45),c=Object.assign;t.exports=!c||n(12)(function(){var t={},e={},n=Symbol(),r="abcdefghijklmnopqrst";return t[n]=7,r.split("").forEach(function(t){e[t]=t}),7!=c({},t)[n]||Object.keys(c({},e)).join("")!=r})?function(t,e){for(var n=i(t),c=arguments.length,s=1,f=u.f,p=o.f;c>s;)for(var l,d=a(arguments[s++]),v=f?r(d).concat(f(d)):r(d),h=v.length,y=0;h>y;)p.call(d,l=v[y++])&&(n[l]=d[l]);return n}:c},function(t,e,n){var r=n(5),u=n(6),o=n(16);t.exports=n(7)?Object.defineProperties:function(t,e){u(t);for(var n,i=o(e),a=i.length,c=0;a>c;)r.f(t,n=i[c++],e[n]);return t}},function(t,e,n){var r=n(10),u=n(51).f,o={}.toString,i="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],a=function(t){try{return u(t)}catch(e){return i.slice()}};t.exports.f=function(t){return i&&"[object Window]"==o.call(t)?a(t):u(r(t))}},function(t,e,n){var r=n(4),u=n(1),o=n(12);t.exports=function(t,e){var n=(u.Object||{})[t]||Object[t],i={};i[t]=e(n),r(r.S+r.F*o(function(){n(1)}),"Object",i)}},function(t,e,n){var r=n(9);t.exports=function(t,e,n){for(var u in e)n&&t[u]?t[u]=e[u]:r(t,u,e[u]);return t}},function(t,e,n){var r=n(13),u=n(6),o=function(t,e){if(u(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,r){try{r=n(11)(Function.call,n(50).f(Object.prototype,"__proto__").set,2),r(t,[]),e=!(t instanceof Array)}catch(u){e=!0}return function(t,n){return o(t,n),e?t.__proto__=n:r(t,n),t}}({},!1):void 0),check:o}},function(t,e,n){"use strict";var r=n(3),u=n(1),o=n(5),i=n(7),a=n(2)("species");t.exports=function(t){var e="function"==typeof u[t]?u[t]:r[t];i&&e&&!e[a]&&o.f(e,a,{configurable:!0,get:function(){return this}})}},function(t,e,n){var r=n(6),u=n(24),o=n(2)("species");t.exports=function(t,e){var n,i=r(t).constructor;return void 0===i||void 0==(n=r(i)[o])?e:u(n)}},function(t,e,n){var r=n(32),u=n(25);t.exports=function(t){return function(e,n){var o,i,a=String(u(e)),c=r(n),s=a.length;return 0>c||c>=s?t?"":void 0:(o=a.charCodeAt(c),55296>o||o>56319||c+1===s||(i=a.charCodeAt(c+1))<56320||i>57343?t?a.charAt(c):o:t?a.slice(c,c+2):(o-55296<<10)+(i-56320)+65536)}}},function(t,e,n){var r=n(32),u=Math.max,o=Math.min;t.exports=function(t,e){return t=r(t),0>t?u(t+e,0):o(t,e)}},function(t,e,n){"use strict";var r=n(11),u=n(4),o=n(21),i=n(47),a=n(46),c=n(33),s=n(88),f=n(56);u(u.S+u.F*!n(49)(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,u,p,l=o(t),d="function"==typeof this?this:Array,v=arguments.length,h=v>1?arguments[1]:void 0,y=void 0!==h,b=0,x=f(l);if(y&&(h=r(h,v>2?arguments[2]:void 0,2)),void 0==x||d==Array&&a(x))for(e=c(l.length),n=new d(e);e>b;b++)s(n,b,y?h(l[b],b):l[b]);else for(p=x.call(l),n=new d;!(u=p.next()).done;b++)s(n,b,y?i(p,h,[u.value,b],!0):u.value);return n.length=b,n}})},function(t,e,n){"use strict";var r=n(85),u=n(94),o=n(15),i=n(10);t.exports=n(48)(Array,"Array",function(t,e){this._t=i(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,u(1)):"keys"==e?u(0,n):"values"==e?u(0,t[n]):u(0,[n,t[n]])},"values"),o.Arguments=o.Array,r("keys"),r("values"),r("entries")},function(t,e,n){var r=n(4);r(r.S+r.F,"Object",{assign:n(98)})},function(t,e,n){var r=n(4);r(r.S,"Object",{create:n(28)})},function(t,e,n){var r=n(4);r(r.S+r.F*!n(7),"Object",{defineProperty:n(5).f})},function(t,e,n){var r=n(21),u=n(52);n(101)("getPrototypeOf",function(){return function(t){return u(r(t))}})},function(t,e,n){var r=n(4);r(r.S,"Object",{setPrototypeOf:n(103).set})},function(t,e,n){"use strict";var r,u,o,i=n(18),a=n(3),c=n(11),s=n(42),f=n(4),p=n(13),l=n(24),d=n(86),v=n(90),h=n(105),y=n(55).set,b=n(97)(),x="Promise",w=a.TypeError,m=a.process,_=a[x],m=a.process,g="process"==s(m),k=function(){},j=!!function(){try{var t=_.resolve(1),e=(t.constructor={})[n(2)("species")]=function(t){t(k,k)};return(g||"function"==typeof PromiseRejectionEvent)&&t.then(k)instanceof e}catch(r){}}(),O=function(t,e){return t===e||t===_&&e===o},S=function(t){var e;return p(t)&&"function"==typeof(e=t.then)?e:!1},E=function(t){return O(_,t)?new P(t):new u(t)},P=u=function(t){var e,n;this.promise=new t(function(t,r){if(void 0!==e||void 0!==n)throw w("Bad Promise constructor");e=t,n=r}),this.resolve=l(e),this.reject=l(n)},M=function(t){try{t()}catch(e){return{error:e}}},F=function(t,e){if(!t._n){t._n=!0;var n=t._c;b(function(){for(var r=t._v,u=1==t._s,o=0,i=function(e){var n,o,i=u?e.ok:e.fail,a=e.resolve,c=e.reject,s=e.domain;try{i?(u||(2==t._h&&q(t),t._h=1),i===!0?n=r:(s&&s.enter(),n=i(r),s&&s.exit()),n===e.promise?c(w("Promise-chain cycle")):(o=S(n))?o.call(n,a,c):a(n)):c(r)}catch(f){c(f)}};n.length>o;)i(n[o++]);t._c=[],t._n=!1,e&&!t._h&&A(t)})}},A=function(t){y.call(a,function(){var e,n,r,u=t._v;if(T(t)&&(e=M(function(){g?m.emit("unhandledRejection",u,t):(n=a.onunhandledrejection)?n({promise:t,reason:u}):(r=a.console)&&r.error&&r.error("Unhandled promise rejection",u)}),t._h=g||T(t)?2:1),t._a=void 0,e)throw e.error})},T=function(t){if(1==t._h)return!1;for(var e,n=t._a||t._c,r=0;n.length>r;)if(e=n[r++],e.fail||!T(e.promise))return!1;return!0},q=function(t){y.call(a,function(){var e;g?m.emit("rejectionHandled",t):(e=a.onrejectionhandled)&&e({promise:t,reason:t._v})})},D=function(t){var e=this;e._d||(e._d=!0,e=e._w||e,e._v=t,e._s=2,e._a||(e._a=e._c.slice()),F(e,!0))},I=function(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw w("Promise can't be resolved itself");(e=S(t))?b(function(){var r={_w:n,_d:!1};try{e.call(t,c(I,r,1),c(D,r,1))}catch(u){D.call(r,u)}}):(n._v=t,n._s=1,F(n,!1))}catch(r){D.call({_w:n,_d:!1},r)}}};j||(_=function(t){d(this,_,x,"_h"),l(t),r.call(this);try{t(c(I,this,1),c(D,this,1))}catch(e){D.call(this,e)}},r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},r.prototype=n(102)(_.prototype,{then:function(t,e){var n=E(h(this,_));return n.ok="function"==typeof t?t:!0,n.fail="function"==typeof e&&e,n.domain=g?m.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&F(this,!1),n.promise},"catch":function(t){return this.then(void 0,t)}}),P=function(){var t=new r;this.promise=t,this.resolve=c(I,t,1),this.reject=c(D,t,1)}),f(f.G+f.W+f.F*!j,{Promise:_}),n(20)(_,x),n(104)(x),o=n(1)[x],f(f.S+f.F*!j,x,{reject:function(t){var e=E(this),n=e.reject;return n(t),e.promise}}),f(f.S+f.F*(i||!j),x,{resolve:function(t){if(t instanceof _&&O(t.constructor,this))return t;var e=E(this),n=e.resolve;return n(t),e.promise}}),f(f.S+f.F*!(j&&n(49)(function(t){_.all(t)["catch"](k)})),x,{all:function(t){var e=this,n=E(e),r=n.resolve,u=n.reject,o=M(function(){var n=[],o=0,i=1;v(t,!1,function(t){var a=o++,c=!1;n.push(void 0),i++,e.resolve(t).then(function(t){c||(c=!0,n[a]=t,--i||r(n))},u)}),--i||r(n)});return o&&u(o.error),n.promise},race:function(t){var e=this,n=E(e),r=n.reject,u=M(function(){v(t,!1,function(t){e.resolve(t).then(n.resolve,r)})});return u&&r(u.error),n.promise}})},function(t,e,n){"use strict";var r=n(3),u=n(8),o=n(7),i=n(4),a=n(54),c=n(96).KEY,s=n(12),f=n(31),p=n(20),l=n(22),d=n(2),v=n(36),h=n(35),y=n(95),b=n(89),x=n(92),w=n(6),m=n(10),_=n(34),g=n(17),k=n(28),j=n(100),O=n(50),S=n(5),E=n(16),P=O.f,M=S.f,F=j.f,A=r.Symbol,T=r.JSON,q=T&&T.stringify,D="prototype",I=d("_hidden"),B=d("toPrimitive"),R={}.propertyIsEnumerable,N=f("symbol-registry"),L=f("symbols"),C=f("op-symbols"),W=Object[D],Q="function"==typeof A,z=r.QObject,U=!z||!z[D]||!z[D].findChild,Y=o&&s(function(){return 7!=k(M({},"a",{get:function(){return M(this,"a",{value:7}).a}})).a})?function(t,e,n){var r=P(W,e);r&&delete W[e],M(t,e,n),r&&t!==W&&M(W,e,r)}:M,K=function(t){var e=L[t]=k(A[D]);return e._k=t,e},G=Q&&"symbol"==typeof A.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof A},J=function(t,e,n){return t===W&&J(C,e,n),w(t),e=_(e,!0),w(n),u(L,e)?(n.enumerable?(u(t,I)&&t[I][e]&&(t[I][e]=!1),n=k(n,{enumerable:g(0,!1)})):(u(t,I)||M(t,I,g(1,{})),t[I][e]=!0),Y(t,e,n)):M(t,e,n)},$=function(t,e){w(t);for(var n,r=b(e=m(e)),u=0,o=r.length;o>u;)J(t,n=r[u++],e[n]);return t},H=function(t,e){return void 0===e?k(t):$(k(t),e)},V=function(t){var e=R.call(this,t=_(t,!0));return this===W&&u(L,t)&&!u(C,t)?!1:e||!u(this,t)||!u(L,t)||u(this,I)&&this[I][t]?e:!0},X=function(t,e){if(t=m(t),e=_(e,!0),t!==W||!u(L,e)||u(C,e)){var n=P(t,e);return!n||!u(L,e)||u(t,I)&&t[I][e]||(n.enumerable=!0),n}},Z=function(t){for(var e,n=F(m(t)),r=[],o=0;n.length>o;)u(L,e=n[o++])||e==I||e==c||r.push(e);return r},tt=function(t){for(var e,n=t===W,r=F(n?C:m(t)),o=[],i=0;r.length>i;)u(L,e=r[i++])&&(n?u(W,e):!0)&&o.push(L[e]);return o};Q||(A=function(){if(this instanceof A)throw TypeError("Symbol is not a constructor!");var t=l(arguments.length>0?arguments[0]:void 0),e=function(n){this===W&&e.call(C,n),u(this,I)&&u(this[I],t)&&(this[I][t]=!1),Y(this,t,g(1,n))};return o&&U&&Y(W,t,{configurable:!0,set:e}),K(t)},a(A[D],"toString",function(){return this._k}),O.f=X,S.f=J,n(51).f=j.f=Z,n(19).f=V,n(29).f=tt,o&&!n(18)&&a(W,"propertyIsEnumerable",V,!0),v.f=function(t){return K(d(t))}),i(i.G+i.W+i.F*!Q,{Symbol:A});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)d(et[nt++]);for(var et=E(d.store),nt=0;et.length>nt;)h(et[nt++]);i(i.S+i.F*!Q,"Symbol",{"for":function(t){return u(N,t+="")?N[t]:N[t]=A(t)},keyFor:function(t){if(G(t))return y(N,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){U=!0},useSimple:function(){U=!1}}),i(i.S+i.F*!Q,"Object",{create:H,defineProperty:J,defineProperties:$,getOwnPropertyDescriptor:X,getOwnPropertyNames:Z,getOwnPropertySymbols:tt}),T&&i(i.S+i.F*(!Q||s(function(){var t=A();return"[null]"!=q([t])||"{}"!=q({a:t})||"{}"!=q(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!G(t)){for(var e,n,r=[t],u=1;arguments.length>u;)r.push(arguments[u++]);return e=r[1],"function"==typeof e&&(n=e),!n&&x(e)||(e=function(t,e){return n&&(e=n.call(this,t,e)),G(e)?void 0:e}),r[1]=e,q.apply(T,r)}}}),A[D][B]||n(9)(A[D],B,A[D].valueOf),p(A,"Symbol"),p(Math,"Math",!0),p(r.JSON,"JSON",!0)},function(t,e,n){n(35)("asyncIterator")},function(t,e,n){n(35)("observable")},function(t,e){t.exports=require("child_process")},function(t,e){t.exports=require("crypto")},function(t,e){t.exports=require("os")},function(t,e){t.exports=require("path")},function(t,e){t.exports=require("regenerator-runtime")}])}); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-sudo", 3 | "version": "4.0.12", 4 | "description": "Electron subprocess with administrative privileges, prompting the user with an OS dialog if necessary.", 5 | "main": "./dist/index.js", 6 | "author": "Aleksandr Komlev", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "git@github.com:automation-stack/electron-sudo.git" 11 | }, 12 | "keywords": [ 13 | "sudo", 14 | "os", 15 | "dialog", 16 | "prompt", 17 | "command", 18 | "exec", 19 | "ui", 20 | "electron", 21 | "elevate", 22 | "administrative", 23 | "privileges", 24 | "UAC", 25 | "subprocess" 26 | ], 27 | "bugs": { 28 | "url": "https://github.com/automation-stack/electron-sudo/issues" 29 | }, 30 | "homepage": "https://github.com/automation-stack/electron-sudo#readme", 31 | "scripts": { 32 | "build": "node_modules/webpack/bin/webpack.js --config ./webpack/config.babel.js", 33 | "build-win32": "node node_modules\\webpack\\bin\\webpack.js --config webpack\\config.babel.js", 34 | "prepublish": "npm run test", 35 | "lint": "node_modules/eslint/bin/eslint.js -c .eslintrc ./src", 36 | "test-win32": "npm run build-win32 && node node_modules\\mocha\\bin\\mocha --compilers js:babel-core/register tests", 37 | "test": "npm run build && node_modules/mocha/bin/mocha --compilers js:babel-core/register ./tests" 38 | }, 39 | "devDependencies": { 40 | "babel-cli": "^6.10.1", 41 | "babel-core": "^6.10.4", 42 | "babel-eslint": "^6.0.0", 43 | "babel-loader": "^6.2.4", 44 | "babel-plugin-array-includes": "^2.0.3", 45 | "babel-plugin-lodash": "^2.2.1", 46 | "babel-plugin-module-alias": "^1.2.0", 47 | "babel-plugin-syntax-async-functions": "^6.5.0", 48 | "babel-plugin-syntax-decorators": "^6.5.0", 49 | "babel-plugin-syntax-flow": "^6.8.0", 50 | "babel-plugin-syntax-object-rest-spread": "^6.5.0", 51 | "babel-plugin-transform-async-to-module-method": "^6.7.0", 52 | "babel-plugin-transform-class-properties": "^6.6.0", 53 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 54 | "babel-plugin-transform-flow-strip-types": "^6.8.0", 55 | "babel-plugin-transform-regenerator": "^6.6.5", 56 | "babel-plugin-transform-runtime": "^6.6.0", 57 | "babel-polyfill": "^6.16.0", 58 | "babel-preset-es2015": "^6.9.0", 59 | "babel-preset-stage-0": "^6.5.0", 60 | "babel-runtime": "^6.9.2", 61 | "chai": "^3.5.0", 62 | "copy-webpack-plugin": "^3.0.1", 63 | "dirty-chai": "^1.2.2", 64 | "eslint": "^2.6.0", 65 | "eslint-loader": "^1.3.0", 66 | "eslint-plugin-babel": "^3.2.0", 67 | "estraverse-fb": "^1.3.1", 68 | "json-loader": "^0.5.4", 69 | "mocha": "^2.4.5", 70 | "raw-loader": "^0.5.1", 71 | "source-map-support": "^0.4.0", 72 | "webpack": "^1.12.14", 73 | "webpack-dev-server": "^1.14.1", 74 | "webpack-module-hot-accept": "^1.0.4", 75 | "webpack-shell-plugin": "^0.4.2" 76 | }, 77 | "dependencies": { 78 | "babel-runtime": "^6.18.0", 79 | "bluebird": "^3.4.6" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleAllowMixedLocalizations 6 | 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | applet 11 | CFBundleIconFile 12 | applet.icns 13 | CFBundleIdentifier 14 | com.electron-sudo 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | Password Prompt 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | aplt 25 | LSMinimumSystemVersionByArchitecture 26 | 27 | x86_64 28 | 10.6 29 | 30 | LSRequiresCarbon 31 | 32 | LSUIElement 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/MacOS/applet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/applet.app/Contents/MacOS/applet -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPLaplt -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/Resources/Scripts/main.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/applet.app/Contents/Resources/Scripts/main.scpt -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/Resources/applet.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/applet.app/Contents/Resources/applet.icns -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/Resources/applet.rsrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/applet.app/Contents/Resources/applet.rsrc -------------------------------------------------------------------------------- /src/bin/applet.app/Contents/Resources/description.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf130 2 | {\fonttbl} 3 | {\colortbl;\red255\green255\blue255;} 4 | } -------------------------------------------------------------------------------- /src/bin/elevate.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/elevate.exe -------------------------------------------------------------------------------- /src/bin/gksudo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/gksudo -------------------------------------------------------------------------------- /src/bin/libgksu2.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/libgksu2.so.0 -------------------------------------------------------------------------------- /src/bin/libgksu2.so.0.0.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/automation-stack/electron-sudo/fd0a78d8979723c77ea50daf1bd930abfae5866f/src/bin/libgksu2.so.0.0.2 -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import {SudoerDarwin, SudoerWin32, SudoerLinux} from '~/lib/sudoer'; 2 | 3 | export default (() => { 4 | let {platform} = process; 5 | switch (platform) { 6 | case 'darwin': 7 | return SudoerDarwin; 8 | case 'win32': 9 | return SudoerWin32; 10 | case 'linux': 11 | return SudoerLinux; 12 | default: 13 | throw new Error(`Unsupported platform: ${platform}`); 14 | } 15 | })(); 16 | -------------------------------------------------------------------------------- /src/lib/sudoer.js: -------------------------------------------------------------------------------- 1 | import {tmpdir} from 'os'; 2 | import {watchFile, unwatchFile, unlink, createReadStream, createWriteStream} from 'fs'; 3 | import {normalize, join, dirname} from 'path'; 4 | import {createHash} from 'crypto'; 5 | 6 | import {readFile, writeFile, exec, spawn, mkdir, stat} from '~/lib/utils'; 7 | 8 | let {platform, env} = process; 9 | 10 | 11 | class Sudoer { 12 | 13 | constructor(options) { 14 | this.platform = platform; 15 | this.options = options; 16 | this.cp = null; 17 | this.tmpdir = tmpdir(); 18 | } 19 | 20 | hash(buffer) { 21 | let hash = createHash('sha256'); 22 | hash.update('electron-sudo'); 23 | hash.update(this.options.name || ''); 24 | hash.update(buffer || new Buffer(0)); 25 | return hash.digest('hex').slice(-32); 26 | } 27 | 28 | joinEnv(options) { 29 | let {env} = options, 30 | spreaded = []; 31 | if (env && typeof env == 'object') { 32 | for (let key in env) { 33 | spreaded.push(key.concat('=', env[key])); 34 | } 35 | } 36 | return spreaded; 37 | } 38 | 39 | escapeDoubleQuotes(string) { 40 | return string.replace(/"/g, '\\"'); 41 | } 42 | 43 | encloseDoubleQuotes(string) { 44 | return string.replace(/(.+)/g, '"$1"'); 45 | } 46 | 47 | kill(pid) { 48 | if (!pid) { 49 | return; 50 | } else { 51 | return; 52 | } 53 | } 54 | } 55 | 56 | 57 | class SudoerUnix extends Sudoer { 58 | 59 | constructor(options={}) { 60 | super(options); 61 | if (!this.options.name) { this.options.name = 'Electron'; } 62 | } 63 | 64 | async copy(source, target) { 65 | return new Promise(async (resolve, reject) => { 66 | source = this.escapeDoubleQuotes(normalize(source)); 67 | target = this.escapeDoubleQuotes(normalize(target)); 68 | try { 69 | let result = await exec(`/bin/cp -R -p "${source}" "${target}"`); 70 | resolve(result); 71 | } 72 | catch (err) { 73 | reject(err); 74 | } 75 | }); 76 | } 77 | 78 | async remove(target) { 79 | let self = this; 80 | return new Promise(async (resolve, reject) => { 81 | if (!target.startsWith(self.tmpdir)) { 82 | throw new Error(`Try to remove suspicious target: ${target}.`); 83 | } 84 | target = this.escapeDoubleQuotes(normalize(target)); 85 | try { 86 | let result = await exec(`rm -rf "${target}"`); 87 | resolve(result); 88 | } 89 | catch (err) { 90 | reject(err); 91 | } 92 | }); 93 | } 94 | 95 | async reset() { 96 | await exec('/usr/bin/sudo -k'); 97 | } 98 | } 99 | 100 | 101 | class SudoerDarwin extends SudoerUnix { 102 | 103 | constructor(options={}) { 104 | super(options); 105 | if (options.icns && typeof options.icns !== 'string') { 106 | throw new Error('options.icns must be a string if provided.'); 107 | } else if (options.icns && options.icns.trim().length === 0) { 108 | throw new Error('options.icns must be a non-empty string if provided.'); 109 | } 110 | this.up = false; 111 | } 112 | 113 | isValidName(name) { 114 | return /^[a-z0-9 ]+$/i.test(name) && name.trim().length > 0 && name.length < 70; 115 | } 116 | 117 | joinEnv(options) { 118 | let {env} = options, 119 | spreaded = []; 120 | if (env && typeof env == 'object') { 121 | for (let key in env) { 122 | spreaded.push(key.concat('=', env[key])); 123 | } 124 | } 125 | return spreaded; 126 | } 127 | 128 | async exec(command, options={}) { 129 | return new Promise(async (resolve, reject) => { 130 | let self = this, 131 | env = self.joinEnv(options), 132 | sudoCommand = ['/usr/bin/sudo -n', env.join(' '), '-s', command].join(' '), 133 | result; 134 | await self.reset(); 135 | try { 136 | result = await exec(sudoCommand, options); 137 | resolve(result); 138 | } catch (err) { 139 | try { 140 | // Prompt password 141 | await self.prompt(); 142 | // Try once more 143 | result = await exec(sudoCommand, options); 144 | resolve(result); 145 | } catch (err) { 146 | reject(err); 147 | } 148 | } 149 | }); 150 | } 151 | 152 | async spawn(command, args, options={}) { 153 | return new Promise(async (resolve, reject) => { 154 | let self = this, 155 | bin = '/usr/bin/sudo', 156 | cp; 157 | await self.reset(); 158 | // Prompt password 159 | await self.prompt(); 160 | cp = spawn(bin, ['-n', '-s', '-E', [command, ...args].join(' ')], options); 161 | cp.on('error', async (err) => { 162 | reject(err); 163 | }); 164 | self.cp = cp; 165 | resolve(cp); 166 | }); 167 | } 168 | 169 | async prompt() { 170 | let self = this; 171 | return new Promise(async (resolve, reject) => { 172 | if (!self.tmpdir) { 173 | return reject( 174 | new Error('Requires os.tmpdir() to be defined.') 175 | ); 176 | } 177 | if (!env.USER) { 178 | return reject( 179 | new Error('Requires env[\'USER\'] to be defined.') 180 | ); 181 | } 182 | // Keep prompt in single instance 183 | self.up = true; 184 | // Read ICNS-icon and hash it 185 | let icon = await self.readIcns(), 186 | hash = self.hash(icon); 187 | // Copy applet to temporary directory 188 | let source = join(`${dirname(__filename)}/bin`, 'applet.app'), 189 | target = join(self.tmpdir, hash, `${self.options.name}.app`); 190 | try { 191 | await mkdir(dirname(target)); 192 | } catch (err) { 193 | if (err.code !== 'EEXIST') { return reject(err); } 194 | } 195 | try { 196 | // Copy application to temporary directory 197 | await self.copy(source, target); 198 | // Create application icon from source 199 | await self.icon(target); 200 | // Create property list for application 201 | await self.propertyList(target); 202 | // Open UI dialog with password prompt 203 | await self.open(target); 204 | // Remove applet from temporary directory 205 | await self.remove(target); 206 | } catch (err) { 207 | return reject(err); 208 | } 209 | return resolve(hash); 210 | }); 211 | } 212 | 213 | async icon(target) { 214 | let self = this; 215 | return new Promise(async (resolve, reject) => { 216 | if (!this.options.icns) { return resolve(); } 217 | let result = await self.copy( 218 | this.options.icns, 219 | join(target, 'Contents', 'Resources', 'applet.icns') 220 | ); 221 | return resolve(result); 222 | }); 223 | } 224 | 225 | async open(target) { 226 | let self = this; 227 | return new Promise(async (resolve, reject) => { 228 | target = self.escapeDoubleQuotes(normalize(target)); 229 | try { 230 | let result = await exec(`open -n -W "${target}"`); 231 | return resolve(result); 232 | } catch (err) { 233 | return reject(err); 234 | } 235 | }); 236 | } 237 | 238 | async readIcns(icnsPath) { 239 | return new Promise(async (resolve, reject) => { 240 | // ICNS is supported only on Mac. 241 | if (!icnsPath || platform !== 'darwin') { 242 | return resolve(new Buffer(0)); 243 | } 244 | try { 245 | let data = await readFile(icnsPath); 246 | return resolve(data); 247 | } catch (err) { 248 | return reject(err); 249 | } 250 | }); 251 | } 252 | 253 | async propertyList(target) { 254 | let self = this; 255 | return new Promise(async (resolve, reject) => { 256 | let path = self.escapeDoubleQuotes(join(target, 'Contents', 'Info.plist')), 257 | key = self.escapeDoubleQuotes('CFBundleName'), 258 | value = `${self.options.name} Password Prompt`; 259 | if (/'/.test(value)) { 260 | return reject(new Error('Value should not contain single quotes.')); 261 | } 262 | let result = await exec(`defaults write "${path}" "${key}" '${value}'`); 263 | return resolve(result); 264 | }); 265 | } 266 | } 267 | 268 | class SudoerLinux extends SudoerUnix { 269 | 270 | constructor(options={}) { 271 | super(options); 272 | this.binary = null; 273 | // We prefer gksudo over pkexec since it gives a nicer prompt: 274 | this.paths = [ 275 | '/usr/bin/gksudo', 276 | '/usr/bin/pkexec', 277 | './bin/gksudo' 278 | ]; 279 | } 280 | 281 | async getBinary() { 282 | return (await Promise.all( 283 | this.paths.map(async (path) => { 284 | try { 285 | path = await stat(path); 286 | return path; 287 | } catch (err) { 288 | return null; 289 | } 290 | }) 291 | )).filter((v) => v)[0]; 292 | } 293 | 294 | async exec(command, options={}) { 295 | return new Promise(async (resolve, reject) => { 296 | let self = this, 297 | result; 298 | /* Detect utility for sudo mode */ 299 | if (!self.binary) { 300 | self.binary = await self.getBinary(); 301 | } 302 | if (options.env instanceof Object && !options.env.DISPLAY) { 303 | // Force DISPLAY variable with default value which is required for UI dialog 304 | options.env = Object.assign(options.env, {DISPLAY: ':0'}); 305 | } 306 | let flags; 307 | if (/gksudo/i.test(self.binary)) { 308 | flags = '--preserve-env --sudo-mode ' + 309 | `--description="${self.escapeDoubleQuotes(self.options.name)}"`; 310 | } else if (/pkexec/i.test(self.binary)) { 311 | flags = '--disable-internal-agent'; 312 | } 313 | command = `${this.binary} ${flags} ${command}`; 314 | try { 315 | result = await exec(command, options); 316 | return resolve(result); 317 | } catch (err) { 318 | return reject(err); 319 | } 320 | }); 321 | } 322 | 323 | async spawn(command, args, options={}) { 324 | let self = this; 325 | return new Promise(async (resolve, reject) => { 326 | /* Detect utility for sudo mode */ 327 | if (!self.binary) { 328 | self.binary = await self.getBinary(); 329 | } 330 | if (options.env instanceof Object && !options.env.DISPLAY) { 331 | // Force DISPLAY variable with default value which is required for UI dialog 332 | options.env = Object.assign(options.env, {DISPLAY: ':0'}); 333 | } 334 | // In order to guarantee succees execution we'll use execFile 335 | // due to fallback binary bundled in package 336 | let sudoArgs = []; 337 | if (/gksudo/i.test(self.binary)) { 338 | sudoArgs.push('--preserve-env'); 339 | sudoArgs.push('--sudo-mode'); 340 | sudoArgs.push(`--description="${self.escapeDoubleQuotes(self.options.name)}"`); 341 | sudoArgs.push('--sudo-mode'); 342 | } else if (/pkexec/i.test(self.binary)) { 343 | sudoArgs.push('--disable-internal-agent'); 344 | } 345 | sudoArgs.push(command); 346 | sudoArgs.push(args); 347 | try { 348 | let cp = spawn(self.binary, sudoArgs, options); 349 | return resolve(cp); 350 | } catch (err) { 351 | return reject(err); 352 | } 353 | }); 354 | } 355 | } 356 | 357 | class SudoerWin32 extends Sudoer { 358 | 359 | constructor(options={}) { 360 | super(options); 361 | this.bundled = 'src\\bin\\elevate.exe'; 362 | this.binary = null; 363 | } 364 | 365 | async writeBatch(command, args, options) { 366 | let tmpDir = (await exec('echo %temp%')) 367 | .stdout.toString() 368 | .replace(/\r\n$/, ''), 369 | tmpBatchFile = `${tmpDir}\\batch-${Math.random()}.bat`, 370 | tmpOutputFile = `${tmpDir}\\output-${Math.random()}`, 371 | env = this.joinEnv(options), 372 | batch = `setlocal enabledelayedexpansion\r\n`; 373 | if (env.length) { 374 | batch += `set ${env.join('\r\nset ')}\r\n`; 375 | } 376 | if (args && args.length) { 377 | batch += `${command} ${args.join(' ')}`; 378 | } else { 379 | batch += command; 380 | } 381 | await writeFile(tmpBatchFile, `${batch} > ${tmpOutputFile} 2>&1`); 382 | await writeFile(tmpOutputFile, ''); 383 | return { 384 | batch: tmpBatchFile, output: tmpOutputFile 385 | }; 386 | } 387 | 388 | async watchOutput(cp) { 389 | let self = this, 390 | output = await readFile(cp.files.output); 391 | // If we have process then emit watched and stored data to stdout 392 | cp.stdout.emit('data', output); 393 | let watcher = watchFile( 394 | cp.files.output, {persistent: true, interval: 1}, 395 | () => { 396 | let stream = createReadStream( 397 | cp.files.output, 398 | {start: watcher.last} 399 | ), 400 | size = 0; 401 | stream.on('data', (data) => { 402 | size += data.length; 403 | if (cp) { cp.stdout.emit('data', data); } 404 | }); 405 | stream.on('close', () => { 406 | cp.last += size; 407 | }); 408 | } 409 | ); 410 | cp.last = output.length; 411 | cp.on('exit', () => { 412 | self.clean(cp); 413 | }); 414 | return cp; 415 | } 416 | 417 | async prepare() { 418 | let self = this; 419 | return new Promise(async (resolve, reject) => { 420 | if (self.binary) { return resolve(self.binary); } 421 | // Copy applet to temporary directory 422 | let target = join(this.tmpdir, 'elevate.exe'); 423 | if (!(await stat(target))) { 424 | let copied = createWriteStream(target); 425 | createReadStream(self.bundled).pipe(copied); 426 | copied.on('close', () => { 427 | self.binary = target; 428 | return resolve(self.binary); 429 | }); 430 | copied.on('error', (err) => { 431 | return reject(err); 432 | }); 433 | } else { 434 | self.binary = target; 435 | resolve(self.binary); 436 | } 437 | }); 438 | } 439 | 440 | async exec(command, options={}) { 441 | let self = this, files, output; 442 | return new Promise(async (resolve, reject) => { 443 | try { 444 | await this.prepare(); 445 | files = await self.writeBatch(command, [], options); 446 | command = `${self.encloseDoubleQuotes(self.binary)} -wait ${files.batch}`; 447 | // No need to wait exec output because output is redirected to temporary file 448 | await exec(command, options); 449 | // Read entire output from redirected file on process exit 450 | output = await readFile(files.output); 451 | return resolve(output); 452 | } catch (err) { 453 | return reject(err); 454 | } 455 | }); 456 | } 457 | 458 | async spawn(command, args, options={}) { 459 | let files = await this.writeBatch(command, args, options), 460 | sudoArgs = [], 461 | cp; 462 | sudoArgs.push('-wait'); 463 | sudoArgs.push(files.batch); 464 | await this.prepare(); 465 | cp = spawn(this.binary, sudoArgs, options, {wait: false}); 466 | cp.files = files; 467 | await this.watchOutput(cp); 468 | return cp; 469 | } 470 | 471 | clean (cp) { 472 | unwatchFile(cp.files.output); 473 | unlink(cp.files.batch); 474 | unlink(cp.files.output); 475 | } 476 | } 477 | 478 | 479 | export {SudoerDarwin, SudoerLinux, SudoerWin32}; 480 | -------------------------------------------------------------------------------- /src/lib/utils.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import child from 'child_process'; 3 | 4 | 5 | function promisify(fn) { 6 | return function() { 7 | return new Promise((resolve, reject) => { 8 | fn(...arguments, function () { 9 | if (arguments[0] instanceof Error) { 10 | reject(arguments[0]); 11 | } else { 12 | resolve(...Array.prototype.slice.call(arguments, 1)); 13 | } 14 | }); 15 | }); 16 | }; 17 | } 18 | 19 | async function exec(cmd, options={}) { 20 | return new Promise((resolve, reject) => { 21 | child.exec(cmd, options, (err, stdout, stderr) => { 22 | if (err) { return reject(err); } 23 | return resolve({stdout, stderr}); 24 | }); 25 | }); 26 | } 27 | 28 | function spawn(cmd, args, options={}) { 29 | let cp = child.spawn(cmd, args, {...options, shell: true}); 30 | cp.output = { stdout: new Buffer(0), stderr: new Buffer(0) }; 31 | cp.stdout.on('data', (data) => { 32 | cp.output.stdout = concat(data, cp.output.stdout); 33 | }); 34 | cp.stderr.on('data', (data) => { 35 | cp.output.stderr = concat(data, cp.output.stderr); 36 | }); 37 | return cp; 38 | } 39 | 40 | function concat(source, target) { 41 | if (!(source instanceof Buffer)) { 42 | source = new Buffer(source, 'utf8'); 43 | } 44 | if (!target instanceof Buffer) { 45 | target = new Buffer(0); 46 | } 47 | return Buffer.concat([target, source]); 48 | } 49 | 50 | async function stat(target) { 51 | let _stat = promisify(fs.stat); 52 | try { 53 | let fileStat = await _stat(target); 54 | return fileStat; 55 | } catch (err) { 56 | return null; 57 | } 58 | } 59 | 60 | let open = promisify(fs.open), 61 | mkdir = promisify(fs.mkdir), 62 | readFile = promisify(fs.readFile), 63 | writeFile = promisify(fs.writeFile); 64 | 65 | 66 | export {readFile, writeFile, spawn, exec, mkdir, stat, open}; 67 | -------------------------------------------------------------------------------- /src/vendor/win32/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | *.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.pfx 193 | *.publishsettings 194 | node_modules/ 195 | orleans.codegen.cs 196 | 197 | # Since there are multiple workflows, uncomment next line to ignore bower_components 198 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 199 | #bower_components/ 200 | 201 | # RIA/Silverlight projects 202 | Generated_Code/ 203 | 204 | # Backup & report files from converting an old project file 205 | # to a newer Visual Studio version. Backup files are not needed, 206 | # because we have git ;-) 207 | _UpgradeReport_Files/ 208 | Backup*/ 209 | UpgradeLog*.XML 210 | UpgradeLog*.htm 211 | 212 | # SQL Server files 213 | *.mdf 214 | *.ldf 215 | 216 | # Business Intelligence projects 217 | *.rdl.data 218 | *.bim.layout 219 | *.bim_*.settings 220 | 221 | # Microsoft Fakes 222 | FakesAssemblies/ 223 | 224 | # GhostDoc plugin setting file 225 | *.GhostDoc.xml 226 | 227 | # Node.js Tools for Visual Studio 228 | .ntvs_analysis.dat 229 | 230 | # Visual Studio 6 build log 231 | *.plg 232 | 233 | # Visual Studio 6 workspace options file 234 | *.opt 235 | 236 | # Visual Studio LightSwitch build output 237 | **/*.HTMLClient/GeneratedArtifacts 238 | **/*.DesktopClient/GeneratedArtifacts 239 | **/*.DesktopClient/ModelManifest.xml 240 | **/*.Server/GeneratedArtifacts 241 | **/*.Server/ModelManifest.xml 242 | _Pvt_Extensions 243 | 244 | # Paket dependency manager 245 | .paket/paket.exe 246 | paket-files/ 247 | 248 | # FAKE - F# Make 249 | .fake/ 250 | 251 | # JetBrains Rider 252 | .idea/ 253 | *.sln.iml 254 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Elevate", "Elevate\Elevate.vcxproj", "{D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x64 = Debug|x64 9 | Debug|x86 = Debug|x86 10 | Release|x64 = Release|x64 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Debug|x64.ActiveCfg = Debug|x64 15 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Debug|x64.Build.0 = Debug|x64 16 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Debug|x86.ActiveCfg = Debug|Win32 17 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Debug|x86.Build.0 = Debug|Win32 18 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Release|x64.ActiveCfg = Release|x64 19 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Release|x64.Build.0 = Release|x64 20 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Release|x86.ActiveCfg = Release|Win32 21 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C}.Release|x86.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/Elevate.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // German (Germany) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_GERMAN, SUBLANG_GERMAN 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Version 53 | // 54 | 55 | VS_VERSION_INFO VERSIONINFO 56 | FILEVERSION 1,0,0,2894 57 | PRODUCTVERSION 1,0,0,2894 58 | FILEFLAGSMASK 0x17L 59 | #ifdef _DEBUG 60 | FILEFLAGS 0x1L 61 | #else 62 | FILEFLAGS 0x0L 63 | #endif 64 | FILEOS 0x4L 65 | FILETYPE 0x1L 66 | FILESUBTYPE 0x0L 67 | BEGIN 68 | BLOCK "StringFileInfo" 69 | BEGIN 70 | BLOCK "000004b0" 71 | BEGIN 72 | VALUE "Comments", "Tool for elevating applications on the command line" 73 | VALUE "CompanyName", "Johannes Passing" 74 | VALUE "FileDescription", "Elevate" 75 | VALUE "FileVersion", "1, 0, 0, 2894" 76 | VALUE "InternalName", "Elevate" 77 | VALUE "LegalCopyright", "Copyright (C) 2007" 78 | VALUE "OriginalFilename", "Elevate.exe" 79 | VALUE "ProductName", "Elevate Application" 80 | VALUE "ProductVersion", "1, 0, 0, 2894" 81 | END 82 | END 83 | BLOCK "VarFileInfo" 84 | BEGIN 85 | VALUE "Translation", 0x0, 1200 86 | END 87 | END 88 | 89 | #endif // German (Germany) resources 90 | ///////////////////////////////////////////////////////////////////////////// 91 | 92 | 93 | 94 | #ifndef APSTUDIO_INVOKED 95 | ///////////////////////////////////////////////////////////////////////////// 96 | // 97 | // Generated from the TEXTINCLUDE 3 resource. 98 | // 99 | 100 | 101 | ///////////////////////////////////////////////////////////////////////////// 102 | #endif // not APSTUDIO_INVOKED 103 | 104 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/Elevate.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 17 | 18 | 19 | 20 | 21 | 28 | 31 | 34 | 37 | 40 | 43 | 58 | 61 | 64 | 67 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 98 | 99 | 106 | 109 | 112 | 115 | 118 | 122 | 137 | 140 | 143 | 146 | 153 | 156 | 159 | 162 | 165 | 168 | 171 | 174 | 177 | 178 | 186 | 189 | 192 | 195 | 198 | 201 | 213 | 216 | 219 | 222 | 231 | 234 | 237 | 240 | 243 | 246 | 249 | 252 | 255 | 256 | 264 | 267 | 270 | 273 | 276 | 280 | 292 | 295 | 298 | 301 | 310 | 313 | 316 | 319 | 322 | 325 | 328 | 331 | 334 | 335 | 336 | 337 | 338 | 339 | 344 | 347 | 348 | 349 | 354 | 357 | 358 | 361 | 362 | 363 | 368 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/Elevate.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {D44F41E2-0CEE-4B9B-825D-1AEBF6DCAB1C} 23 | Elevate 24 | Win32Proj 25 | 26 | 27 | 28 | Application 29 | Unicode 30 | true 31 | v140 32 | 33 | 34 | Application 35 | Unicode 36 | v140 37 | 38 | 39 | Application 40 | Unicode 41 | true 42 | v140 43 | 44 | 45 | Application 46 | Unicode 47 | v140 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | <_ProjectFileVersion>10.0.40219.1 67 | $(SolutionDir)bin\x86\$(Configuration)\ 68 | $(SolutionDir)bin\x86\$(Configuration)\ 69 | true 70 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 71 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 72 | true 73 | $(SolutionDir)bin\x86\$(Configuration)\ 74 | $(SolutionDir)bin\x86\$(Configuration)\ 75 | false 76 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 77 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 78 | false 79 | 80 | 81 | 82 | Disabled 83 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 84 | true 85 | 86 | 87 | EnableFastChecks 88 | MultiThreadedDebug 89 | 90 | 91 | Level4 92 | EditAndContinue 93 | StdCall 94 | CompileAsC 95 | 96 | 97 | true 98 | Console 99 | MachineX86 100 | 101 | 102 | 103 | 104 | X64 105 | 106 | 107 | Disabled 108 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 109 | true 110 | 111 | 112 | EnableFastChecks 113 | MultiThreadedDebug 114 | 115 | 116 | Level4 117 | ProgramDatabase 118 | StdCall 119 | CompileAsC 120 | 121 | 122 | true 123 | Console 124 | MachineX64 125 | 126 | 127 | 128 | 129 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | 131 | 132 | MultiThreaded 133 | 134 | 135 | Level4 136 | ProgramDatabase 137 | StdCall 138 | CompileAsC 139 | 140 | 141 | true 142 | Console 143 | true 144 | true 145 | MachineX86 146 | 147 | 148 | 149 | 150 | X64 151 | 152 | 153 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 154 | 155 | 156 | MultiThreaded 157 | 158 | 159 | Level4 160 | ProgramDatabase 161 | StdCall 162 | CompileAsC 163 | 164 | 165 | true 166 | Console 167 | true 168 | true 169 | MachineX64 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/Elevate.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | 31 | 32 | Resource Files 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/main.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | /*---------------------------------------------------------------------- 4 | * Purpose: 5 | * Execute a process on the command line with elevated rights on Vista 6 | * 7 | * Copyright: 8 | * Johannes Passing (johannes.passing@googlemail.com) 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2.1 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with this library; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | */ 24 | 25 | #define BANNER L"(c) 2007 - Johannes Passing - http://int3.de/\n\n" 26 | 27 | 28 | typedef struct _COMMAND_LINE_ARGS 29 | { 30 | BOOL ShowHelp; 31 | BOOL Wait; 32 | BOOL StartComspec; 33 | PCWSTR ApplicationName; 34 | PCWSTR CommandLine; 35 | } COMMAND_LINE_ARGS, *PCOMMAND_LINE_ARGS; 36 | 37 | INT Launch( 38 | __in PCWSTR ApplicationName, 39 | __in PCWSTR CommandLine, 40 | __in BOOL Wait 41 | ) 42 | { 43 | SHELLEXECUTEINFO Shex; 44 | ZeroMemory( &Shex, sizeof( SHELLEXECUTEINFO ) ); 45 | Shex.cbSize = sizeof( SHELLEXECUTEINFO ); 46 | Shex.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; 47 | Shex.lpVerb = L"runas"; 48 | Shex.lpFile = ApplicationName; 49 | Shex.lpParameters = CommandLine; 50 | Shex.nShow = SW_HIDE; 51 | 52 | if ( ! ShellExecuteEx( &Shex ) ) 53 | { 54 | DWORD Err = GetLastError(); 55 | fwprintf( 56 | stderr, 57 | L"%s could not be launched: %d\n", 58 | ApplicationName, 59 | Err ); 60 | return EXIT_FAILURE; 61 | } 62 | 63 | _ASSERTE( Shex.hProcess ); 64 | 65 | if ( Wait ) 66 | { 67 | WaitForSingleObject( Shex.hProcess, INFINITE ); 68 | } 69 | CloseHandle( Shex.hProcess ); 70 | return EXIT_SUCCESS; 71 | } 72 | 73 | INT DispatchCommand( 74 | __in PCOMMAND_LINE_ARGS Args 75 | ) 76 | { 77 | WCHAR AppNameBuffer[ MAX_PATH ]; 78 | WCHAR CmdLineBuffer[ MAX_PATH * 2 ]; 79 | 80 | if ( Args->ShowHelp ) 81 | { 82 | wprintf( 83 | BANNER 84 | L"Execute a process on the command line with elevated rights\n" 85 | L"\n" 86 | L"Usage: Elevate [-?|-wait|-k] program [args]\n" 87 | L"-? - Shows this help\n" 88 | L"-wait - Waits until program terminates\n" 89 | L"-k - Starts the the %%COMSPEC%% environment variable value and\n" 90 | L" executes program in it (CMD.EXE, 4NT.EXE, etc.)\n" 91 | L"prog - The program to execute\n" 92 | L"args - Optional command line arguments to program\n" ); 93 | 94 | return EXIT_SUCCESS; 95 | } 96 | 97 | if ( Args->StartComspec ) 98 | { 99 | // 100 | // Resolve COMSPEC 101 | // 102 | if ( 0 == GetEnvironmentVariable( L"COMSPEC", AppNameBuffer, _countof( AppNameBuffer ) ) ) 103 | { 104 | fwprintf( stderr, L"%%COMSPEC%% is not defined\n" ); 105 | return EXIT_FAILURE; 106 | } 107 | Args->ApplicationName = AppNameBuffer; 108 | 109 | // 110 | // Prepend /K and quote arguments 111 | // 112 | if ( FAILED( StringCchPrintf( 113 | CmdLineBuffer, 114 | _countof( CmdLineBuffer ), 115 | L"/K \"%s\"", 116 | Args->CommandLine ) ) ) 117 | { 118 | fwprintf( stderr, L"Creating command line failed\n" ); 119 | return EXIT_FAILURE; 120 | } 121 | Args->CommandLine = CmdLineBuffer; 122 | } 123 | 124 | //wprintf( L"App: %s,\nCmd: %s\n", Args->ApplicationName, Args->CommandLine ); 125 | return Launch( Args->ApplicationName, Args->CommandLine, Args->Wait ); 126 | } 127 | 128 | int __cdecl wmain( 129 | __in int Argc, 130 | __in WCHAR* Argv[] 131 | ) 132 | { 133 | OSVERSIONINFO OsVer; 134 | COMMAND_LINE_ARGS Args; 135 | INT Index; 136 | BOOL FlagsRead = FALSE; 137 | WCHAR CommandLineBuffer[ 260 ] = { 0 }; 138 | 139 | ZeroMemory( &OsVer, sizeof( OSVERSIONINFO ) ); 140 | OsVer.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); 141 | 142 | ZeroMemory( &Args, sizeof( COMMAND_LINE_ARGS ) ); 143 | Args.CommandLine = CommandLineBuffer; 144 | 145 | // 146 | // Check OS version 147 | // 148 | if ( GetVersionEx( &OsVer ) && 149 | OsVer.dwMajorVersion < 6 ) 150 | { 151 | fwprintf( stderr, L"This tool is for Windows Vista and above only.\n" ); 152 | return EXIT_FAILURE; 153 | } 154 | 155 | // 156 | // Parse command line 157 | // 158 | for ( Index = 1; Index < Argc; Index++ ) 159 | { 160 | if ( ! FlagsRead && 161 | ( Argv[ Index ][ 0 ] == L'-' || Argv[ Index ][ 0 ] == L'/' ) ) 162 | { 163 | PCWSTR FlagName = &Argv[ Index ][ 1 ]; 164 | if ( 0 == _wcsicmp( FlagName, L"?" ) ) 165 | { 166 | Args.ShowHelp = TRUE; 167 | } 168 | else if ( 0 == _wcsicmp( FlagName, L"wait" ) ) 169 | { 170 | Args.Wait = TRUE; 171 | } 172 | else if ( 0 == _wcsicmp( FlagName, L"k" ) ) 173 | { 174 | Args.StartComspec = TRUE; 175 | } 176 | else 177 | { 178 | fwprintf( stderr, L"Unrecognized Flag %s\n", FlagName ); 179 | return EXIT_FAILURE; 180 | } 181 | } 182 | else 183 | { 184 | FlagsRead = TRUE; 185 | if ( Args.ApplicationName == NULL && ! Args.StartComspec ) 186 | { 187 | Args.ApplicationName = Argv[ Index ]; 188 | } 189 | else 190 | { 191 | if ( FAILED( StringCchCat( 192 | CommandLineBuffer, 193 | _countof( CommandLineBuffer ), 194 | Argv[ Index ] ) ) || 195 | FAILED( StringCchCat( 196 | CommandLineBuffer, 197 | _countof( CommandLineBuffer ), 198 | L" " ) ) ) 199 | { 200 | fwprintf( stderr, L"Command Line too long\n" ); 201 | return EXIT_FAILURE; 202 | } 203 | } 204 | } 205 | } 206 | 207 | #ifdef _DEBUG 208 | wprintf( 209 | L"ShowHelp: %s\n" 210 | L"Wait: %s\n" 211 | L"StartComspec: %s\n" 212 | L"ApplicationName: %s\n" 213 | L"CommandLine: %s\n", 214 | Args.ShowHelp ? L"Y" : L"N", 215 | Args.Wait ? L"Y" : L"N", 216 | Args.StartComspec ? L"Y" : L"N", 217 | Args.ApplicationName, 218 | Args.CommandLine ); 219 | #endif 220 | 221 | // 222 | // Validate args 223 | // 224 | if ( Argc <= 1 ) 225 | { 226 | Args.ShowHelp = TRUE; 227 | } 228 | 229 | if ( ! Args.ShowHelp && 230 | ( ( Args.StartComspec && 0 == wcslen( Args.CommandLine ) ) || 231 | ( ! Args.StartComspec && Args.ApplicationName == NULL ) ) ) 232 | { 233 | fwprintf( stderr, L"Invalid arguments\n" ); 234 | return EXIT_FAILURE; 235 | } 236 | 237 | return DispatchCommand( &Args ); 238 | } 239 | 240 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Elevate.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/vendor/win32/Elevate/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /*---------------------------------------------------------------------- 4 | * Copyright: 5 | * Johannes Passing (johannes.passing@googlemail.com) 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #define _WIN32_WINNT _WIN32_WINNT_VISTA 23 | #define NTDDI_VERSION NTDDI_VISTA 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include -------------------------------------------------------------------------------- /src/vendor/win32/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/vendor/win32/README.md: -------------------------------------------------------------------------------- 1 | elevate.exe 2 | ======= 3 | 4 | This tool allows you to start a program with elevated privileges from the command line. 5 | 6 | Fixed and extended version of the original tool https://github.com/jpassing/elevate 7 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | import chai from 'chai'; 2 | import dirtyChai from 'dirty-chai'; 3 | import Sudoer from '../dist/index'; 4 | 5 | let {expect} = chai, 6 | {platform} = process, 7 | options = { 8 | name: 'Electron.Sudo', 9 | icns: '/Applications/Automator.app/Contents/Resources/AutomatorApplet.icns' 10 | }, 11 | sudoer = new Sudoer(options); 12 | chai.use(dirtyChai); 13 | 14 | describe(`electron-sudo :: ${platform}`, function () { 15 | 16 | this.timeout(100000); 17 | this.slow(100000); 18 | 19 | if (platform === 'darwin') { 20 | describe('[exec] with ENV vars', async function () { 21 | it('should available environment variables', async function () { 22 | let result = await sudoer.exec('echo $PARAM', {env: {PARAM: 'VALUE'}}); 23 | expect(result.stdout.trim()).to.be.equals('VALUE'); 24 | }); 25 | }); 26 | describe('[spawn] with ENV vars', async function () { 27 | it('should available environment variables', async function (done) { 28 | let cp = await sudoer.spawn('echo', ['$PARAM'], {env: {PARAM: 'VALUE'}}); 29 | cp.on('close', () => { 30 | expect(cp.output.stdout.toString().trim()).to.be.equals('VALUE'); 31 | expect(cp.pid).to.be.a('number'); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | } 37 | 38 | if (platform === 'linux') { 39 | describe('[gksudo: exec] with ENV vars', async function () { 40 | it('should available environment variables', async function () { 41 | sudoer.binary = './dist/bin/gksudo'; 42 | let result = await sudoer.exec('echo $PARAM', {env: {PARAM: 'VALUE'}}); 43 | expect(result.stdout.trim()).to.be.equals('VALUE'); 44 | }); 45 | }); 46 | describe('[pkexec: exec] with ENV vars', async function () { 47 | it('should available environment variables', async function () { 48 | sudoer.binary = '/usr/bin/pkexec'; 49 | // sudoer.exec('echo $PARAM', {env: {PARAM: 'VALUE'}}); 50 | // await sudoer.exec('echo $PARAM', {env: {PARAM: 'VALUE'}}); 51 | let result = await sudoer.exec('echo $PARAM', {env: {PARAM: 'VALUE'}}); 52 | expect(result.stdout.trim()).to.be.equals('VALUE'); 53 | }); 54 | }); 55 | describe('[gksudo: spawn] with ENV vars', async function () { 56 | it('should available environment variables', async function (done) { 57 | sudoer.binary = './dist/bin/gksudo'; 58 | let cp = await sudoer.spawn('echo', ['$PARAM'], {env: {PARAM: 'VALUE'}}); 59 | cp.on('close', () => { 60 | expect(cp.output.stdout.toString().trim()).to.be.equals('VALUE'); 61 | expect(cp.pid).to.be.a('number'); 62 | done(); 63 | }); 64 | }); 65 | }); 66 | describe('[pkexec: spawn] with ENV vars', async function () { 67 | it('should available environment variables', async function (done) { 68 | sudoer.binary = '/usr/bin/pkexec'; 69 | let cp = await sudoer.spawn('echo', ['$PARAM'], {env: {PARAM: 'VALUE'}}); 70 | cp.on('close', () => { 71 | expect(cp.output.stdout.toString().trim()).to.be.equals('VALUE'); 72 | expect(cp.pid).to.be.a('number'); 73 | done(); 74 | }); 75 | }); 76 | }); 77 | } 78 | 79 | if (platform === 'win32') { 80 | describe('[exec] with ENV vars', async function () { 81 | it('should available environment variables', async function () { 82 | let result = await sudoer.exec('echo %PARAM%', {env: {PARAM: 'VALUE'}}); 83 | expect(result.toString().trim()).to.be.equals('VALUE'); 84 | }); 85 | }); 86 | describe('[spawn] with ENV vars', async function () { 87 | it('should available environment variables', async function (done) { 88 | let cp = await sudoer.spawn('echo', ['%PARAM%'], {env: {PARAM: 'VALUE'}}); 89 | cp.on('close', () => { 90 | expect(cp.output.stdout.toString().trim()).to.be.equals('VALUE'); 91 | expect(cp.pid).to.be.a('number'); 92 | done(); 93 | }); 94 | }); 95 | }); 96 | } 97 | 98 | 99 | }); 100 | -------------------------------------------------------------------------------- /webpack/chmod.js: -------------------------------------------------------------------------------- 1 | import {execSync} from 'child_process'; 2 | let {platform, argv} = process; 3 | 4 | switch (platform) { 5 | case 'darwin': 6 | case 'linux': 7 | execSync(`chmod +x ${argv.slice(2, argv.length).join(' ')}`); 8 | break; 9 | default: 10 | break; 11 | } 12 | -------------------------------------------------------------------------------- /webpack/config.babel.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import webpack from 'webpack'; 3 | import CopyWebpackPlugin from 'copy-webpack-plugin'; 4 | import ShellPlugin from 'webpack-shell-plugin'; 5 | 6 | let nodeModules = fs.readdirSync('./node_modules') 7 | .filter((module) => { 8 | return module !== '.bin'; 9 | }) 10 | .reduce((prev, module) => { 11 | return Object.assign(prev, {[module]: 'commonjs ' + module}); 12 | }, {}), 13 | srcPath = './src/', 14 | distPath = './dist', 15 | babelNode = './node_modules/babel-cli/bin/babel-node.js'; 16 | 17 | export default { 18 | entry: [`${srcPath}/index.js`], 19 | output: { 20 | path: distPath, 21 | publicPath: distPath, 22 | filename: 'index.js', 23 | library: 'electron-sudo', 24 | libraryTarget: 'umd' 25 | }, 26 | target: 'electron', 27 | debug: false, 28 | //devtool: 'source-map', 29 | module: { 30 | loaders: [ 31 | { 32 | test: /\.js$/, 33 | exclude: /node_modules/, 34 | loader: 'babel', 35 | query: { 36 | cacheDirectory: true 37 | } 38 | }, 39 | { 40 | test: /\.json$/, 41 | loader: 'json' 42 | } 43 | ] 44 | }, 45 | plugins: [ 46 | new webpack.IgnorePlugin(/node_modules/), 47 | new webpack.BannerPlugin( 48 | 'require("source-map-support").install();', 49 | { raw: false, entryOnly: true } 50 | ), 51 | new CopyWebpackPlugin([ 52 | {from: `${srcPath}/bin`, to: './bin'} 53 | ]), 54 | new ShellPlugin({ 55 | onBuildExit: [ 56 | `node ${babelNode} ./webpack/chmod.js ` + 57 | `${distPath}/bin/applet.app ` + 58 | `${distPath}/bin/applet.app/Contents/MacOS/applet ` + 59 | `${distPath}/bin/gksudo`, 60 | ] 61 | }), 62 | new webpack.optimize.OccurenceOrderPlugin(), 63 | new webpack.optimize.DedupePlugin(), 64 | new webpack.optimize.UglifyJsPlugin({ 65 | compress: { warnings: false }, 66 | output: { comments: false }, 67 | }) 68 | ], 69 | node: { 70 | //do not include polyfills... 71 | //http://webpack.github.io/docs/configuration.html#node 72 | console: false, 73 | process: false, 74 | child_process: false, 75 | global: false, 76 | buffer: false, 77 | crypto: false, 78 | __filename: false, 79 | __dirname: false 80 | }, 81 | externals: nodeModules 82 | }; 83 | --------------------------------------------------------------------------------