From 08253c9e49c3ebe3165fbeb8b9fbce25507346c2 Mon Sep 17 00:00:00 2001 From: lecepin <383810086@qq.com> Date: Fri, 20 May 2022 18:49:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=A3=E7=90=86/=E8=AF=81=E4=B9=A6/?= =?UTF-8?q?=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/cert.js | 42 ++++++++++++++ electron/const.js | 30 ++++++---- electron/index.js | 37 +++++++------ electron/proxyServer.js | 37 +++++++++++++ electron/setProxy.js | 118 ++++++++++++++++++++++++++++++++++++++++ electron/utils.js | 18 +++--- package.json | 18 ++++-- public/w_c.exe | Bin 0 -> 81208 bytes src/App.jsx | 10 ++-- src/index.css | 8 +-- src/index.js | 6 +- webpack.electron.js | 15 +++++ 12 files changed, 286 insertions(+), 53 deletions(-) create mode 100644 electron/cert.js create mode 100644 electron/proxyServer.js create mode 100644 electron/setProxy.js create mode 100644 public/w_c.exe create mode 100644 webpack.electron.js diff --git a/electron/cert.js b/electron/cert.js new file mode 100644 index 0000000..b0920a5 --- /dev/null +++ b/electron/cert.js @@ -0,0 +1,42 @@ +import CONFIG from './const'; +import mkdirp from 'mkdirp'; +import fs from 'fs'; +import path from 'path'; +import sudo from 'sudo-prompt'; +import { clipboard, dialog } from 'electron'; + +function checkCertInstalled() { + return fs.existsSync(CONFIG.INSTALL_CERT_FLAG); +} + +export async function installCert(checkInstalled = true) { + if (checkInstalled && checkCertInstalled()) { + return; + } + + if (process.platform === 'darwin') { + return new Promise((resolve, reject) => { + mkdirp.sync(path.dirname(CONFIG.INSTALL_CERT_FLAG)); + clipboard.writeText( + `echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${CONFIG.CERT_PUBLIC_PATH}" && touch ${CONFIG.INSTALL_CERT_FLAG} && echo "安装完成"`, + ); + dialog.showMessageBoxSync({ + type: 'info', + message: `命令已复制到剪贴板,粘贴命令到终端并运行以安装并信任证书`, + }); + + reject(); + }); + } else { + return sudo.exec( + `${CONFIG.WIN_CERT_INSTALL_HELPER} -c -add ${CONFIG.CERT_PUBLIC_PATH} -s root`, + { name: CONFIG.APP_EN_NAME }, + (error, stdout) => { + if (error) { + reject(error); + } + resolve(stdout); + }, + ); + } +} diff --git a/electron/const.js b/electron/const.js index de9f7a3..afe473f 100644 --- a/electron/const.js +++ b/electron/const.js @@ -1,24 +1,34 @@ -import path from "path"; -import isDev from "electron-is-dev"; -import url from "url"; -import { app } from "electron"; +import path from 'path'; +import isDev from 'electron-is-dev'; +import url from 'url'; +import os from 'os'; +import { app } from 'electron'; const APP_PATH = app.getAppPath(); // 对于一些 shell 去执行的文件,asar 目录下无法使用。配合 extraResources const EXECUTABLE_PATH = path.join( - APP_PATH.indexOf("app.asar") > -1 - ? APP_PATH.substring(0, APP_PATH.indexOf("app.asar")) + APP_PATH.indexOf('app.asar') > -1 + ? APP_PATH.substring(0, APP_PATH.indexOf('app.asar')) : APP_PATH, - "public" + 'public', ); +const HOME_PATH = path.join(os.homedir(), '.wechat-video-downloader'); export default { APP_START_URL: isDev - ? "http://localhost:3000" + ? 'http://localhost:3000' : url.format({ - pathname: path.join(APP_PATH, "./build/index.html"), - protocol: "file:", + pathname: path.join(APP_PATH, './build/index.html'), + protocol: 'file:', slashes: true, }), IS_DEV: isDev, + EXECUTABLE_PATH, + HOME_PATH, + CERT_PRIVATE_PATH: path.join(EXECUTABLE_PATH, './keys/private.pem'), + CERT_PUBLIC_PATH: path.join(EXECUTABLE_PATH, './keys/public.pem'), + INSTALL_CERT_FLAG: path.join(HOME_PATH, './installed.lock'), + WIN_CERT_INSTALL_HELPER: path.join(EXECUTABLE_PATH, './w_c.exe'), + APP_CN_NAME: '微信视频号下载器', + APP_EN_NAME: 'WeChat Video Downloader', }; diff --git a/electron/index.js b/electron/index.js index a02ea5a..8e38b8c 100644 --- a/electron/index.js +++ b/electron/index.js @@ -1,18 +1,20 @@ -import { app, BrowserWindow } from "electron"; -import log from "electron-log"; -import CONFIG from "./const"; -import { checkUpdate } from "./utils"; +import { app, BrowserWindow } from 'electron'; +import log from 'electron-log'; +import CONFIG from './const'; +import { checkUpdate } from './utils'; +import { startServer } from './proxyServer'; +import { installCert } from './cert'; -app.commandLine.appendSwitch("--no-proxy-server"); +app.commandLine.appendSwitch('--no-proxy-server'); function createWindow() { // electron.Menu.setApplicationMenu(null); checkUpdate( - "https://cdn.jsdelivr.net/gh/lecepin/electron-react-tpl/package.json", - "https://github.com/lecepin/electron-react-tpl/releases" + 'https://cdn.jsdelivr.net/gh/lecepin/electron-react-tpl/package.json', + 'https://github.com/lecepin/electron-react-tpl/releases', ); - mainWindow = new BrowserWindow({ + const mainWindow = new BrowserWindow({ width: 800, height: 600, // resizable: false, @@ -24,26 +26,29 @@ function createWindow() { }, }); - mainWindow.loadURL(CONFIG.APP_START_URL); + mainWindow.loadURL('https://baidu.com' ?? CONFIG.APP_START_URL); CONFIG.IS_DEV && mainWindow.webContents.openDevTools(); - - mainWindow.on("closed", function () { - mainWindow = null; - }); + installCert() + .then(data => { + console.log('install cert success', data); + }) + .catch(err => { + log.error('err', err); + }); } app.whenReady().then(() => { createWindow(); - app.on("activate", () => { + app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); }); -app.on("window-all-closed", () => { - if (process.platform !== "darwin") { +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { app.quit(); } }); diff --git a/electron/proxyServer.js b/electron/proxyServer.js new file mode 100644 index 0000000..3752ee3 --- /dev/null +++ b/electron/proxyServer.js @@ -0,0 +1,37 @@ +import path from 'path'; +import fs from 'fs'; +import hoxy from 'hoxy'; +import getPort from 'get-port'; +import { app } from 'electron'; +import CONFIG from './const'; +import { setProxy, closeProxy } from './setProxy'; + +export async function startServer({ interceptCallback = f => f, errorCallback = f => f }) { + const port = await getPort(); + const proxy = hoxy + .createServer({ + certAuthority: { + key: fs.readFileSync(CONFIG.CERT_PRIVATE_PATH), + cert: fs.readFileSync(CONFIG.CERT_PUBLIC_PATH), + }, + }) + .listen(port, () => { + setProxy('127.0.0.1', port).catch(errorCallback); + }); + + proxy.intercept( + { + phase: 'request', + }, + interceptCallback, + ); +} + +app.on('before-quit', async e => { + e.preventDefault(); + try { + await closeProxy(); + } catch (error) {} + + app.exit(); +}); diff --git a/electron/setProxy.js b/electron/setProxy.js new file mode 100644 index 0000000..4cad461 --- /dev/null +++ b/electron/setProxy.js @@ -0,0 +1,118 @@ +import { exec } from 'child_process'; +import regedit from 'regedit'; + +export async function setProxy(host, port) { + if (process.platform === 'darwin') { + const networks = await getMacAvailableNetworks(); + + if (networks.length === 0) { + throw 'no network'; + } + + return Promise.all( + networks.map(network => { + return new Promise((resolve, reject) => { + exec(`networksetup -setsecurewebproxy "${network}" ${host} ${port}`, error => { + if (error) { + reject(null); + } else { + resolve(network); + } + }); + }); + }), + ); + } else { + const valuesToPut = { + 'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings': { + ProxyServer: { + value: `${host}:${port}`, + type: 'REG_SZ', + }, + ProxyEnable: { + value: 1, + type: 'REG_DWORD', + }, + }, + }; + return editWinRegPromise(valuesToPut); + } +} + +export async function closeProxy() { + if (process.platform === 'darwin') { + const networks = await getMacAvailableNetworks(); + + if (networks.length === 0) { + throw 'no network'; + } + + return Promise.all( + networks.map(network => { + return new Promise((resolve, reject) => { + exec(`networksetup -setsecurewebproxystate "${network}" off`, error => { + if (error) { + reject(null); + } else { + resolve(network); + } + }); + }); + }), + ); + } else { + const valuesToPut = { + 'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings': { + ProxyEnable: { + value: 0, + type: 'REG_DWORD', + }, + }, + }; + return editWinRegPromise(valuesToPut); + } +} + +function getMacAvailableNetworks() { + return new Promise((resolve, reject) => { + exec('networksetup -listallnetworkservices', (error, stdout) => { + if (error) { + reject(error); + } else { + Promise.all( + stdout + .toString() + .split('\n') + .map(network => { + return new Promise(resolve => { + exec( + `networksetup getinfo "${network}" | grep "^IP address:\\s\\d"`, + (error, stdout) => { + if (error) { + resolve(null); + } else { + resolve(stdout ? network : null); + } + }, + ); + }); + }), + ).then(networks => { + resolve(networks.filter(Boolean)); + }); + } + }); + }); +} + +function editWinRegPromise(valuesToPut) { + return new Promise((resolve, reject) => { + regedit.putValue(valuesToPut, function (err) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); +} diff --git a/electron/utils.js b/electron/utils.js index c0fd25c..61e9648 100644 --- a/electron/utils.js +++ b/electron/utils.js @@ -1,22 +1,22 @@ -import { get } from "axios"; -const { app, dialog, shell } = require("electron"); -import semver from "semver"; +import { get } from 'axios'; +const { app, dialog, shell } = require('electron'); +import semver from 'semver'; // packageUrl 需要包含 { "version": "1.0.0" } 结构 function checkUpdate( // 可以使用加速地址 https://cdn.jsdelivr.net/gh/lecepin/electron-react-tpl/package.json - packageUrl = "https://raw.githubusercontent.com/lecepin/electron-react-tpl/master/package.json", - downloadUrl = "https://github.com/lecepin/electron-react-tpl/releases" + packageUrl = 'https://raw.githubusercontent.com/lecepin/electron-react-tpl/master/package.json', + downloadUrl = 'https://github.com/lecepin/electron-react-tpl/releases', ) { get(packageUrl) .then(({ data }) => { if (semver.gt(data?.version, app.getVersion())) { const result = dialog.showMessageBoxSync({ - message: "发现新版本,是否更新?", - type: "question", + message: '发现新版本,是否更新?', + type: 'question', cancelId: 1, defaultId: 0, - buttons: ["进入新版本下载页面", "取消"], + buttons: ['进入新版本下载页面', '取消'], }); if (result === 0 && downloadUrl) { @@ -24,7 +24,7 @@ function checkUpdate( } } }) - .catch((err) => {}); + .catch(err => {}); } export { checkUpdate }; diff --git a/package.json b/package.json index 748a543..5accc21 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,13 @@ "postinstall": "husky install", "start": "concurrently \"cross-env BROWSER=none npm run start-web\" \"wait-on http://localhost:3000 && npm run start-electron\" ", "start-web": "react-app-rewired start", - "start-electron": "parcel build --target electron --no-cache && electron .", + "start-electron": "webpack --config webpack.electron.js && electron .", "build-web": "react-app-rewired build", - "build-electron": "parcel build --target electron --no-cache", + "build-electron": "webpack --config webpack.electron.js", "build-all": "rm -rf ./build && rm -rf ./build-electron && npm run build-electron && npm run build-web", "pack": "npm run build-all && electron-builder", - "gen-icon": "electron-icon-builder --input=./public/icon/icon.png --output=./public/icon" + "gen-icon": "electron-icon-builder --input=./public/icon/icon.png --output=./public/icon", + "pretty": "prettier -c --write \"(src/**/*|electron/**/*)\"" }, "targets": { "electron": { @@ -41,15 +42,22 @@ "prettier": "^2.6.2", "react-app-rewired": "^2.2.1", "react-scripts": "5.0.1", - "wait-on": "^6.0.1" + "wait-on": "^6.0.1", + "webpack": "^5.72.1", + "webpack-cli": "^4.9.2" }, "dependencies": { "axios": "^0.27.2", "electron-is-dev": "^2.0.0", "electron-log": "^4.4.7", + "get-port": "^6.1.2", + "hoxy": "^3.3.1", + "mkdirp": "^1.0.4", "react": "^18.1.0", "react-dom": "^18.1.0", - "semver": "^7.3.7" + "regedit": "^5.1.1", + "semver": "^7.3.7", + "sudo-prompt": "^9.2.1" }, "author": "lecepin", "license": "ISC", diff --git a/public/w_c.exe b/public/w_c.exe new file mode 100644 index 0000000000000000000000000000000000000000..860788473a8df6680bb9618fc4bba1bbc66014fd GIT binary patch literal 81208 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 literal 0 HcmV?d00001 diff --git a/src/App.jsx b/src/App.jsx index 22f5052..c74eb8d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ -import logo from "./logo.png"; -import { shell } from "electron"; -import "./App.css"; +import logo from './logo.png'; +import { shell } from 'electron'; +import './App.css'; function App() { return ( @@ -11,9 +11,9 @@ function App() { Edit src/App.js and save to reload.

{ + onClick={e => { e.preventDefault(); - shell.openExternal("https://github.com/lecepin/electron-react-tpl"); + shell.openExternal('https://github.com/lecepin/electron-react-tpl'); }} className="App-link" href="#" diff --git a/src/index.css b/src/index.css index ec2585e..89e57c7 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,11 @@ body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', + 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } diff --git a/src/index.js b/src/index.js index a5781c7..dac4ede 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,11 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; -import App from './App'; +import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - -); \ No newline at end of file + , +); diff --git a/webpack.electron.js b/webpack.electron.js new file mode 100644 index 0000000..af448cb --- /dev/null +++ b/webpack.electron.js @@ -0,0 +1,15 @@ +const path = require('path'); + +module.exports = { + entry: path.resolve(__dirname, './electron/index.js'), + output: { + filename: 'index.js', + path: path.resolve(__dirname, './build-electron'), + }, + module: { + rules: [], + }, + devtool: false && 'source-map', + target: 'electron-main', + node: false, +};