Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions scripts/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ function updateNodeModules() {

fs.rmSync(path.join(nodeDir, 'modules'), { recursive: true, force: true });
fs.renameSync(path.join(nodeDir, 'node_modules'), path.join(nodeDir, 'modules'));
// Yarn's local package install can omit Whistle's generated web UI bundle.
// Whistle reads this file during startup, so a missing bundle prevents the proxy from listening.
const webUiBundle = path.join('biz', 'webui', 'htdocs', 'js', 'index.js');
const bundleSource = path.join(root, 'vendor', 'whistle', webUiBundle);
const bundleDest = path.join(nodeDir, 'modules', 'whistle', webUiBundle);
if (!fs.existsSync(bundleSource)) {
throw new Error(`Whistle web UI bundle is missing: ${bundleSource}`);
}
fs.mkdirSync(path.dirname(bundleDest), { recursive: true });
fs.copyFileSync(bundleSource, bundleDest);
updateZip();
}

Expand Down
5 changes: 4 additions & 1 deletion src/main/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export const SYSTEM_IS_LINUX = systemTypelinux === 'Linux';
export const IPROXY_UPDATE_DIR = path.join(IPROXY_HOME_PATH, './update');
export const IPROXY_UPDATE_CONFIG = path.join(IPROXY_UPDATE_DIR, './config.json');
export const IPROXY_FILES_DIR = path.join(IPROXY_HOME_PATH, './files');
export const PROXY_CONF_HELPER_FILE_PATH = path.join(IPROXY_FILES_DIR, './proxy_conf_helper');
export const PROXY_CONF_HELPER_FILE_PATH = path.join(
IPROXY_FILES_DIR,
os.arch() === 'arm64' && SYSTEM_IS_MACOS ? 'proxy_conf_helper_arm64' : 'proxy_conf_helper',
);
export const PROXY_CONF_HELPER_PATH = path.join(IPROXY_HOME_PATH, './proxy_conf_helper');
export const PROXY_REFRESH_WINDOWS_HELPER_PATH = path.join(IPROXY_FILES_DIR, './win_proxy_helper');

Expand Down
59 changes: 36 additions & 23 deletions src/main/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,16 @@ Application will quit
treeKill(process.pid);
}

export async function installCertAndHelper() {
console.log('Install cert');
const certs = (await generateCert()) as {
key: string;
cert: string;
};
export async function installCertAndHelper(installCert = true) {
const dir = installCert ? (await tempdir()).replace('ADMINI~1', 'Administrator') : '';

const dir = (await tempdir()).replace('ADMINI~1', 'Administrator');

// 写入证书
await fs.mkdirp(dir);
await fs.writeFileAsync(path.join(dir, CERT_KEY_FILE_NAME), certs.key, 'utf-8');
await fs.writeFileAsync(path.join(dir, CERT_FILE_NAME), certs.cert, 'utf-8');
if (installCert) {
console.log('Install cert');
const certs = (await generateCert()) as { key: string; cert: string };
await fs.mkdirp(dir);
await fs.writeFileAsync(path.join(dir, CERT_KEY_FILE_NAME), certs.key, 'utf-8');
await fs.writeFileAsync(path.join(dir, CERT_FILE_NAME), certs.cert, 'utf-8');
}

const formatPath = (path: string) => '"' + path + '"';

Expand All @@ -141,11 +138,14 @@ export async function installCertAndHelper() {
if (SYSTEM_IS_MACOS) {
// macOS big sur do not allow trust cert in any auto way
// show box to guide user run command
fs.removeSync(INSTALL_DONE_FILE);
const showGuide = () => {
const cmd = `echo "Please input local login password 请输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${path.join(
dir,
CERT_FILE_NAME,
)}" && sudo cp ${formatPath(PROXY_CONF_HELPER_FILE_PATH)} ${formatPath(
const trustCertCommand = installCert
? `sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${formatPath(
path.join(dir, CERT_FILE_NAME),
)} && `
: '';
const cmd = `echo "Please input local login password 请输入本地登录密码" && ${trustCertCommand}sudo cp ${formatPath(PROXY_CONF_HELPER_FILE_PATH)} ${formatPath(
PROXY_CONF_HELPER_PATH,
)} && sudo chown root:admin ${formatPath(PROXY_CONF_HELPER_PATH)} && sudo chmod a+rx+s ${formatPath(
PROXY_CONF_HELPER_PATH,
Expand All @@ -155,8 +155,8 @@ export async function installCertAndHelper() {

dialog.showMessageBoxSync({
type: 'info',
message: `Paste command to your Terminal and run to install cert and helper
(命令已复制到剪贴板)粘贴命令到终端并运行以安装并信任证书
message: `Paste command to your Terminal and run to install ${installCert ? 'the certificate and helper' : 'the proxy helper'}
(命令已复制到剪贴板)粘贴命令到终端并运行以安装${installCert ? '并信任证书及代理辅助程序' : '代理辅助程序'}
`,
});
};
Expand Down Expand Up @@ -227,8 +227,10 @@ export async function installCertAndHelper() {
}
console.log('after install');
// 信任完成,把证书目录拷贝过去
await fs.copyAsync(dir, IPROXY_CERT_DIR_PATH);
console.log('copy cert done');
if (installCert) {
await fs.copyAsync(dir, IPROXY_CERT_DIR_PATH);
console.log('copy cert done');
}
}

async function checkCertInstall() {
Expand Down Expand Up @@ -258,14 +260,25 @@ async function checkHelperInstall() {
// 权限不对
return false;
}
return true;
// An older install may still contain the Intel helper on Apple Silicon.
// Compare the installed binary with the one packaged for this architecture.
try {
const [installed, packaged] = await Promise.all([
fs.readFileAsync(PROXY_CONF_HELPER_PATH),
fs.readFileAsync(PROXY_CONF_HELPER_FILE_PATH),
]);
return installed.equals(packaged);
} catch (e) {
return false;
}
}

// 检查安装状态,如果没安装就安装一下
export default async function checkInstallStatus() {
if ((await checkCertInstall()) && (await checkHelperInstall())) {
const certInstalled = await checkCertInstall();
if (certInstalled && (await checkHelperInstall())) {
// pass
} else {
await installCertAndHelper();
await installCertAndHelper(!certInstalled);
}
}
18 changes: 17 additions & 1 deletion src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,23 @@ async function initCopyFiles() {
}

const versionFile = path.join(IPROXY_FILES_DIR, 'version');
if (fs.existsSync(versionFile) && fs.readFileSync(versionFile, 'utf-8') === version && !electronIsDev) {
const whistleBundle = path.join(
IPROXY_FILES_DIR,
'node',
'node_modules',
'whistle',
'biz',
'webui',
'htdocs',
'js',
'index.js',
);
if (
fs.existsSync(versionFile) &&
fs.readFileSync(versionFile, 'utf-8') === version &&
fs.existsSync(whistleBundle) &&
!electronIsDev
) {
updateSplashProgress(100, 'Files already up to date');
} else {
console.log('copy files');
Expand Down