Repository: dzt/easy-proxy
Branch: master
Commit: 8323c70ee480
Files: 16
Total size: 48.9 KB
Directory structure:
gitextract_h1rwq2co/
├── .gitignore
├── LICENSE
├── README.md
├── confg/
│ ├── nouserpass/
│ │ └── squid.conf
│ └── userpass/
│ └── squid.conf
├── create.js
├── index.js
├── package.json
├── scripts/
│ └── installer.js
├── settings-manager.js
└── static/
├── app.js
├── icons/
│ └── logo.icns
├── index.html
├── main.css
├── settings.html
└── settings.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
config.json
gs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
package-lock.json
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
dist
out
# macOS
.DS_Store
package-lock.json
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2017 Peter Soboyejo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# easy-proxy
Mass proxy distribution made easy with the DigitalOcean API

[DOWNLOADS CAN BE FOUND HERE](https://github.com/dzt/easy-proxy/releases)
[Community Discord Server](https://discord.gg/BkDxcjT)
### Setup (for development)
easy-proxy requires [Node.js](http://nodejs.org/).
Development Setup:
```sh
$ git clone https://github.com/dzt/easy-proxy.git
$ cd easy-proxy
$ npm install # sudo npm install if you're on macOS
$ npm run dev
```
# Videos
[Preview & Explanation Video](https://youtu.be/Uy0EpcAgaAs)
[RSA ID Setup on macOS](https://streamable.com/6gnpe)
### Who
Written by @dzt, made better by you.
## License
```
The MIT License (MIT)
Copyright (c) 2017 Peter Soboyejo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
================================================
FILE: confg/nouserpass/squid.conf
================================================
http_port 3128
cache deny all
hierarchy_stoplist cgi-bin ?
access_log none
cache_store_log none
cache_log /dev/null
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
acl SSL_ports port 1-65535
acl Safe_ports port 1-65535
acl CONNECT method CONNECT
acl siteblacklist dstdomain "/etc/squid/blacklist.acl"
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny siteblacklist
#auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
#auth_param basic children 5
#auth_param basic realm Squid proxy-caching web server
#auth_param basic credentialsttl 2 hours
#acl password proxy_auth REQUIRED
http_access allow localhost
http_access allow password
http_access allow all
forwarded_for off
request_header_access Allow allow all
request_header_access Authorization allow all
request_header_access WWW-Authenticate allow all
request_header_access Proxy-Authorization allow all
request_header_access Proxy-Authenticate allow all
request_header_access Cache-Control allow all
request_header_access Content-Encoding allow all
request_header_access Content-Length allow all
request_header_access Content-Type allow all
request_header_access Date allow all
request_header_access Expires allow all
request_header_access Host allow all
request_header_access If-Modified-Since allow all
request_header_access Last-Modified allow all
request_header_access Location allow all
request_header_access Pragma allow all
request_header_access Accept allow all
request_header_access Accept-Charset allow all
request_header_access Accept-Encoding allow all
request_header_access Accept-Language allow all
request_header_access Content-Language allow all
request_header_access Mime-Version allow all
request_header_access Retry-After allow all
request_header_access Title allow all
request_header_access Connection allow all
request_header_access Proxy-Connection allow all
request_header_access User-Agent allow all
request_header_access Cookie allow all
request_header_access All deny all
================================================
FILE: confg/userpass/squid.conf
================================================
http_port 3128
cache deny all
hierarchy_stoplist cgi-bin ?
access_log none
cache_store_log none
cache_log /dev/null
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
acl SSL_ports port 1-65535
acl Safe_ports port 1-65535
acl CONNECT method CONNECT
acl siteblacklist dstdomain "/etc/squid/blacklist.acl"
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny siteblacklist
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
acl password proxy_auth REQUIRED
http_access allow localhost
http_access allow password
http_access deny all
forwarded_for off
request_header_access Allow allow all
request_header_access Authorization allow all
request_header_access WWW-Authenticate allow all
request_header_access Proxy-Authorization allow all
request_header_access Proxy-Authenticate allow all
request_header_access Cache-Control allow all
request_header_access Content-Encoding allow all
request_header_access Content-Length allow all
request_header_access Content-Type allow all
request_header_access Date allow all
request_header_access Expires allow all
request_header_access Host allow all
request_header_access If-Modified-Since allow all
request_header_access Last-Modified allow all
request_header_access Location allow all
request_header_access Pragma allow all
request_header_access Accept allow all
request_header_access Accept-Charset allow all
request_header_access Accept-Encoding allow all
request_header_access Accept-Language allow all
request_header_access Content-Language allow all
request_header_access Mime-Version allow all
request_header_access Retry-After allow all
request_header_access Title allow all
request_header_access Connection allow all
request_header_access Proxy-Connection allow all
request_header_access User-Agent allow all
request_header_access Cookie allow all
request_header_access All deny all
================================================
FILE: create.js
================================================
const randomstring = require('randomstring')
const DigitalOcean = require('do-wrapper').default
const eSettings = require('electron-settings')
const request = require('request')
const _ = require('underscore')
const ipcMain = require('electron').ipcMain
var task = function(win, info, settings, no, callback) {
var sender = win.webContents;
var ssh_key_id = null;
var id = null;
var stopped = false;
api = new DigitalOcean(eSettings.getSync('do_api_key'), '9999')
var host = null;
ipcMain.on('stopTasks', function(event) {
if (stopped == false) {
sender.send('updateMonitor', {
no: no,
msg: 'Cancelled',
username: info.username,
password: info.password,
ip: 'n/a',
error: true
});
stopped = true
}
});
sender.send('updateMonitor', {
no: no,
msg: 'Started',
username: info.username,
password: info.password,
ip: 'n/a',
error: false
});
createDroplet();
function createDroplet() {
sender.send('updateMonitor', {
no: no,
msg: `Creating Droplet`,
username: info.username,
password: info.password,
ip: 'n/a',
error: false
});
var dropletName = randomstring.generate(14) + '-ep';
var dropletData = {
name: dropletName,
region: info.region,
size: '512mb',
image: parseInt(info.slug),
ssh_keys: [ssh_key_id],
monitoring: true,
user_data:
'#!/bin/bash \n' +
'yum install squid wget httpd-tools -y &&' +
'touch /etc/squid/passwd &&' +
`htpasswd -b /etc/squid/passwd ${info.username} ${info.password} &&` +
'wget -O /etc/squid/squid.conf https://raw.githubusercontent.com/dzt/easy-proxy/master/confg/userpass/squid.conf --no-check-certificate &&' +
'touch /etc/squid/blacklist.acl &&' +
'systemctl restart squid.service && systemctl enable squid.service &&' +
'iptables -I INPUT -p tcp --dport 3128 -j ACCEPT &&' +
'iptables-save'
};
/*
var dropletData = {
name: dropletName,
region: info.region,
size: '512mb',
image: parseInt(info.slug),
ssh_keys: [ssh_key_id],
monitoring: true,
user_data:
'#!/bin/bash \n' +
'yum install squid wget httpd-tools -y &&' +
//'touch /etc/squid/passwd &&' +
//`htpasswd -b /etc/squid/passwd ${info.username} ${info.password} &&` +
'wget -O /etc/squid/squid.conf https://raw.githubusercontent.com/dzt/easy-proxy/master/confg/nouserpass/squid.conf --no-check-certificate &&' +
'touch /etc/squid/blacklist.acl &&' +
'systemctl restart squid.service && systemctl enable squid.service &&' +
'iptables -I INPUT -p tcp --dport 3128 -j ACCEPT &&' +
'iptables-save'
};
*/
console.log(dropletData);
api.dropletsCreate(dropletData, function(err, resp, body) {
if (err) {
sender.send('updateMonitor', {
no: no,
msg: 'An error occured while trying to create your droplet.',
username: info.username,
password: info.password,
ip: 'n/a',
error: true
});
console.log(`[${no}] Error creating droplet.`);
console.log(err);
return callback(null, true);
}
setTimeout(function() {
if (stopped) {
destroyDroplet(id, api, function(err, resp) {
if (err) {
return callback(null, true);
}
return callback(null, true);
});
}
api.dropletsGetAll({}, function(err, resp, body) {
id = _.findWhere(resp.body.droplets, {
name: dropletName
}).id
host = _.findWhere(resp.body.droplets, {
name: dropletName
}).networks.v4[0].ip_address
var para = null;
if (eSettings.getSync('ssh_passphrase') != null) {
para = eSettings.getSync('ssh_passphrase');
}
if (stopped) {
destroyDroplet(id, api, function(err, resp) {
if (err) {
return callback(null, true);
}
return callback(null, true);
});
}
if (stopped) {
destroyDroplet(id, api, function(err, resp) {
if (err) {
return callback(null, true);
}
return callback(null, true);
});
} else {
sender.send('updateMonitor', {
no: no,
msg: `Droplet Created`,
username: info.username,
password: info.password,
ip: host,
error: false
});
}
console.log("http://" + info.username + ":" + info.password + "@" + host + ":" + '3128')
var count = 119;
for (var i = 0; i < 119; i++) {
setTimeout(function() {
sender.send('updateMonitor', {
no: no,
msg: `Testing Proxy in ${count}s`,
username: info.username,
password: info.password,
ip: host,
error: false
});
count--;
}, 1000*i);
}
setTimeout(function() {
request({
method: 'get',
url: 'https://google.com/',
proxy: "http://" + info.username + ":" + info.password + "@" + host + ":" + '3128',
gzip: true,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3107.4 Safari/537.36'
}
}, (error, resp, body) => {
if (error) {
console.log(error);
sender.send('updateMonitor', {
no: no,
msg: `Proxy Invalid, destroying droplet.`,
username: info.username,
password: info.password,
ip: host,
error: true
});
destroyDroplet(id, api, function(err, resp) {
if (err) {
sender.send('updateMonitor', {
no: no,
msg: `Error Occured while destroying droplet due to bad proxy Connection.`,
username: info.username,
password: info.password,
ip: host,
error: true
});
return callback(null, true);
}
sender.send('updateMonitor', {
no: no,
msg: `Droplet Destroyed due to bad proxy connection.`,
username: info.username,
password: info.password,
ip: host,
error: true
});
return callback(null, true);
});
} else {
sender.send('updateMonitor', {
no: no,
msg: `Created!`,
username: info.username,
password: info.password,
ip: host,
error: false
});
console.log(`[${no}] Created!`);
return callback(null, true);
}
});
}, 120000);
});
}, 60000);
});
}
}
function destroyDroplet(id, api, cb) {
api.dropletsDelete(id, function(err, resp, body) {
if (err) {
return cb(true, null);
}
return cb(null, true)
});
}
module.exports = {
task: task
};
================================================
FILE: index.js
================================================
const electron = require('electron')
const {
app,
BrowserWindow,
Menu
} = electron
const settings = require('./settings-manager')
const eSettings = require('electron-settings')
const create = require('./create')
const path = require('path')
const async = require('async')
const ChildProcess = require('child_process')
var DigitalOcean = require('do-wrapper').default,
api = null;
var win, settingsWin;
const debug = /--debug/.test(process.argv[2])
// Launch Menu Spawn System
var createShortcut = function(callback) {
spawnUpdate([
'--createShortcut',
path.basename(process.execPath),
'--shortcut-locations',
'StartMenu'
], callback)
}
var removeShortcut = function(callback) {
spawnUpdate([
'--removeShortcut',
path.basename(process.execPath)
], callback)
}
var spawnUpdate = function(args, callback) {
var updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe')
var stdout = ''
var spawned = null
try {
spawned = ChildProcess.spawn(updateExe, args)
} catch (error) {
if (error && error.stdout == null)
error.stdout = stdout
process.nextTick(function() {
callback(error)
})
return
}
var error = null
spawned.stdout.on('data', function(data) {
stdout += data
})
spawned.on('error', function(processError) {
if (!error)
error = processError
})
spawned.on('close', function(code, signal) {
if (!error && code !== 0) {
error = new Error('Command failed: ' + code + ' ' + signal)
}
if (error && error.code == null)
error.code = code
if (error && error.stdout == null)
error.stdout = stdout
callback(error)
})
}
switch (process.argv[1]) {
case '--squirrel-install':
createShortcut(function() {
app.quit()
});
break;
case '--squirrel-uninstall':
removeShortcut(function() {
app.quit();
});
break;
case '--squirrel-obsolete':
case '--squirrel-updated':
app.quit();
break;
default:
init();
}
function init() {
app.on('ready', () => {
settings.init()
app.ep = {
settings
}
win = new BrowserWindow({
width: 750,
height: 670,
minWidth: 750,
minHeight: 670,
resizable: true,
maxWidth: 750,
maxHeight: 640,
fullscreenable: false,
frame: true,
show: true,
icon: `${__dirname}/static/icon.png`
})
const menuTemplate = [{
label: 'File',
submenu: [{
label: 'Settings',
click() {
initSettings()
},
accelerator: 'CmdOrCtrl+,',
},
{
label: 'Quit',
click() {
app.quit()
},
accelerator: 'CmdOrCtrl+Q',
}
]
},
{
label: 'Edit',
submenu: [{
role: 'copy'
},
{
role: 'paste'
},
{
role: 'pasteandmatchstyle'
},
{
role: 'delete'
},
{
role: 'selectall'
}
]
},
{
label: 'View',
submenu: [{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click(item, focusedWindow) {
if (focusedWindow) focusedWindow.reload()
}
}]
},
{
role: 'window',
submenu: [{
role: 'minimize'
},
{
role: 'close'
}
]
},
{
role: 'help',
submenu: [{
label: 'Learn More about EasyProxy',
click() {
require('electron').shell.openExternal('github.com/dzt/easy-proxy')
}
},
{
label: 'Toggle Developer Tools',
accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
click(item, focusedWindow) {
if (focusedWindow) focusedWindow.webContents.toggleDevTools()
}
}
]
}
]
// If the platform is Mac OS, make some changes to the window management portion of the menu
if (process.platform === 'darwin') {
menuTemplate[2].submenu = [{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Zoom',
role: 'zoom'
},
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
}
]
}
// Set menu template just created as the application menu
const mainMenu = Menu.buildFromTemplate(menuTemplate)
Menu.setApplicationMenu(mainMenu)
win.setMenu(null);
win.loadURL(`file://${__dirname}/static/index.html`);
})
}
electron.ipcMain.on('create', function(event, args) {
var tasks = []
args.map(function(task, i) {
tasks.push(function(cb) {
create.task(win, task, settings, i + 1, (err, response) => {
if (err) {
return (err)
}
return cb(null, response)
})
})
})
async.parallel(tasks, function(err, res) {
if (err) {
console.log('err', err)
} else {
console.log(res)
// TODO: When Session Ends
win.webContents.send('tasksEnded');
}
});
});
electron.ipcMain.on('openSettings', function(event, args) {
initSettings();
});
electron.ipcMain.on('open-file-dialog', function(event) {
require('electron').dialog.showOpenDialog({
properties: ['openFile'],
filters: [{
name: 'All Files',
extensions: ['*']
}]
}, function(filename) {
if (filename) {
console.log(filename[0]);
event.sender.send('selected-file', filename[0]);
}
})
});
electron.ipcMain.on('wipeDroplets', function(event) {
api = new DigitalOcean(eSettings.getSync('do_api_key'));
var droplets = [];
api.dropletsGetAll({}, function(err, resp, body) {
if (err) {
console.log(err);
event.sender.send('errDestroy');
}
for (var i = 0; i < body.droplets.length; i++) {
var id = body.droplets[i].id;
var dropletName = body.droplets[i].name;
if (dropletName.endsWith('-ep')) {
api.dropletsDelete(id, function(err, resp, body) {});
}
}
event.sender.send('wipe-complete');
//console.log(body);
});
});
electron.ipcMain.on('resetApp', (event, args) => {
win.close()
settingsWin.close()
app.quit();
})
electron.ipcMain.on('refreshMainWindow', (event, args) => {
win.webContents.send('refreshMain');
})
electron.ipcMain.on('fetchForImages', function(event) {
var options = [];
var regionDict = [];
api = new DigitalOcean(eSettings.getSync('do_api_key'));
function fetchFullRegionName(shortName) {
for (var i = 0; i < regionDict.length; i++) {
if (regionDict[i].slug == shortName) {
return regionDict[i].fullName;
}
}
}
// Fetch for Regions and Slug Names
api.regionsGetAll({}, function(err, resp, body) {
if (err) {
// Return Error to Window
console.log('err', err);
win.webContents.send('initError');
return
}
for (var i = 0; i < body.regions.length; i++) {
regionDict.push({
fullName: body.regions[i].name,
slug: body.regions[i].slug
})
}
api.imagesGetAll({type: 'distribution'}, function(err, resp, body) {
if (err) {
// Return Error to Window
win.webContents.send('initError');
return
}
for (var i = 0; i < body.images.length; i++) {
// Look for 64bit versions of CentOS 7
if (body.images[i].distribution.indexOf('CentOS') > -1) {
if (body.images[i].name.split(' ')[0].startsWith('7')) {
for (var x = 0; x < body.images[i].regions.length; x++) {
if (fetchFullRegionName(body.images[i].regions[x]) != undefined) {
options.push({
title: `CentOS ${body.images[i].name} - ${body.images[i].id} - (${fetchFullRegionName(body.images[i].regions[x])})`,
region: body.images[i].regions[x],
slug: body.images[i].id
})
}
}
}
}
}
win.webContents.send('updateOptionList', options);
});
});
});
function initSettings() {
settingsWin = new electron.BrowserWindow({
backgroundColor: '#ffffff',
center: true,
fullscreen: false,
height: 700,
icon: `${__dirname}/static/icon.png`,
maximizable: false,
minimizable: false,
resizable: false,
show: false,
skipTaskbar: true,
title: 'Settings',
useContentSize: true,
width: 550
})
settingsWin.loadURL(`file://${__dirname}/static/settings.html`);
// No menu on the About settingsWindow
settingsWin.setMenu(null);
//settingsWin.webContents.openDevTools()
settingsWin.once('ready-to-show', function() {
settingsWin.show()
})
settingsWin.once('closed', function() {
aboutWin = null
})
return settingsWin.show()
}
================================================
FILE: package.json
================================================
{
"name": "EasyProxy",
"version": "2.1.2",
"description": "Easy Proxy Creation",
"main": "index.js",
"scripts": {
"start": "electron .",
"dev": "electron . --debug",
"dist:win": "build --windows --x64 --dir",
"dist:mac": "build --mac",
"installer": "node scripts/installer.js"
},
"author": "Peter Soboyejo ",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/dzt/easy-proxy.git"
},
"bugs": {
"url": "https://github.com/dzt/easy-proxy/issues"
},
"dependencies": {
"async": "^2.6.0",
"bootstrap": "^3.3.7",
"console.table": "^0.8.0",
"copy-paste": "^1.3.0",
"do-wrapper": "^3.11.1",
"electron-config": "^1.0.0",
"electron-settings": "^2.2.2",
"font-awesome": "^4.7.0",
"jquery": "^3.2.1",
"object-path": "^0.11.4",
"path": "^0.12.7",
"prompt": "^1.0.0",
"randomstring": "^1.1.5",
"request": "^2.83.0",
"rimraf": "^2.5.4",
"underscore": "^1.8.3"
},
"devDependencies": {
"electron": "1.3.4",
"electron-winstaller": "^2.5.0",
"electron-builder": "^19.13.0"
},
"build": {
"productName": "EasyProxy",
"appId": "com.petersoboyejo.easyproxy",
"mac": {
"target": "default",
"icon": "static/icons/logo.icns",
"identity": null
},
"win": {
"publisherName": "EasyProxy",
"target": "squirrel",
"icon": "static/icons/logo.ico"
}
}
}
================================================
FILE: scripts/installer.js
================================================
const createWindowsInstaller = require('electron-winstaller').createWindowsInstaller
const path = require('path')
const rimraf = require('rimraf')
deleteOutputFolder()
.then(getInstallerConfig)
.then(createWindowsInstaller)
.catch((error) => {
console.log('err')
console.error(error.message || error)
process.exit(1)
})
function getInstallerConfig () {
const rootPath = path.join(__dirname, '..')
const outPath = path.join(rootPath, 'dist')
return Promise.resolve({
appDirectory: path.join(outPath, 'win-unpacked'),
noMsi: true,
outputDirectory: path.join(outPath, 'windows-installer'),
setupExe: 'EasyProxySetup.exe',
setupIcon: path.join(rootPath, 'static', 'icons', 'logo.ico'),
skipUpdateIcon: true
})
}
function deleteOutputFolder () {
return new Promise((resolve, reject) => {
rimraf(path.join(__dirname, '..', 'out', 'windows-installer'), (error) => {
error ? reject(error) : resolve()
})
})
}
================================================
FILE: settings-manager.js
================================================
const homedir = require('os').homedir
const app = require('electron').app
const settings = require('electron-settings')
const objectPath = require('object-path')
const DEFAULTS = {
filePath: null,
do_api_key: null,
ip_auth: false,
ips: null
};
// we need to sync every setting that can be modified externally
// e.g. the `openOnStartup` setting can be modified via
// macOS' System Preferences.app
function sync() {
settings.setSync('openOnStartup', app.getLoginItemSettings().openAtLogin);
}
function init() {
settings.defaults(DEFAULTS);
settings.applyDefaultsSync();
sync();
}
function get(key) {
sync();
return objectPath.get(key) || settings.getSync(key);
}
function getAll() {
sync();
return settings.getSync();
}
function set(key, value) {
settings.setSync(key, value);
}
function observe(keyPath, handler) {
return settings.observe(keyPath, handler);
}
module.exports = {
get: get,
getAll: getAll,
set: set,
observe: observe,
init: init
};
================================================
FILE: static/app.js
================================================
require("copy-paste").global()
const remote = require('electron').remote
const app = remote.app
const $ = require('jquery')
const ipcRenderer = require('electron').ipcRenderer
const settings = require('electron-settings')
const randomstring = require('randomstring')
var settingsValues = app.ep.settings.getAll();
// Fetch for Images as soon as Window is loaded
if (settingsValues.do_api_key == null || settingsValues.do_api_key == "") {
$("#fetching").html('');
} else {
ipcRenderer.send('fetchForImages');
}
ipcRenderer.on('initError', function(event, data) {
$("#fetching").html('');
});
// When Images are Fetched return data to DOM
ipcRenderer.on('updateOptionList', function(event, data) {
if (data.length == 0) {
$("#fetching").html('');
} else {
for (var i = 0; i < data.length; i++) {
$('#sel1').append(``);
}
$("#fetching").remove();
$("#sel1").prop("disabled", false);
$("#createButton").prop("disabled", false);
}
});
ipcRenderer.on('refreshMain', function(event) {
remote.getCurrentWindow().reload();
});
// Create Proxies Button
$('#createButton').click(() => {
if ($("#count").val() == "") {
alert("You must set the number of proxies you want to create before performing this action.");
} else if (settingsValues.do_api_key == null) {
alert("You're missing crutial settings required to create proxies, please check your settings and try again.");
} else {
$("#results").empty();
$("#createButton").prop("disabled", true);
$("#sel1").prop("disabled", true);
$("#count").prop("disabled", true);
$("#clearLogsButton").prop("disabled", true);
$("#createButton").text('Creating...');
var proxyCount = parseInt($('#count').val())
var tasks = [];
for (var i = 0; i < proxyCount; i++) {
var username = randomstring.generate({
length: 6,
charset: 'alphabetic',
capitalization: 'lowercase'
});
var password = randomstring.generate({
length: 6,
charset: 'alphabetic',
capitalization: 'lowercase'
});
tasks.push({
username: username,
password: password,
slug: $('#sel1').find(":selected").attr('slug'),
region: $('#sel1').find(":selected").attr('region')
})
}
ipcRenderer.send('create', tasks);
}
});
// Update List Items in realtime
ipcRenderer.on('updateMonitor', function(event, data) {
// TODO: Add Timestamp
if ($(`#${data.username}`).length) {
// update exisiting item
if (data.error) {
var newlyAddedUpdate = `
#${data.no}
${data.ip}
3128
${data.username}
${data.password}
${data.msg}
`
} else {
var newlyAddedUpdate = `
#${data.no}
${data.ip}
3128
${data.username}
${data.password}
${data.msg}
`
}
$(`#${data.username}`).replaceWith(newlyAddedUpdate);
} else {
var newlyAddedUpdate = `
#${data.no}
${data.ip}
3128
${data.username}
${data.password}
${data.msg}
`
$('#results').append(newlyAddedUpdate);
}
});
$('#refresh').click(() => {
remote.getCurrentWindow().reload();
});
$('#copyToClipboardButton').click(() => {
var content = [];
$("tr").each(function(i) {
if (i != 0) {
if ($(this).has(`td:contains('Created!')`).length) {
var ip = $(this).find('td').eq(1).text();
var user = $(this).find('td').eq(3).text();
var pass = $(this).find('td').eq(4).text();
content.push(`${ip}:3128:${user}:${pass}`);
}
}
});
// use join function
copy(content.join('\n'))
});
$('#clearLogsButton').click(() => {
$("#results").empty();
});
$('#cancelTasksButton').click(() => {
ipcRenderer.send('stopTasks');
});
$('#settingsButton').click(() => {
ipcRenderer.send('openSettings');
});
// When all tasks are done doing there thing bring everything back to normal and purge old stuff
ipcRenderer.on('tasksEnded', function(event, data) {
$("#createButton").prop("disabled", false);
$("#sel1").prop("disabled", false);
$("#count").prop("disabled", false);
$("#clearLogsButton").prop("disabled", false);
$("#createButton").text('Create');
});
================================================
FILE: static/index.html
================================================
EasyProxy