Skip to content

Commit 44aead4

Browse files
committed
fix(macos): restore proxy startup on Apple Silicon
1 parent dc42c02 commit 44aead4

4 files changed

Lines changed: 67 additions & 25 deletions

File tree

‎scripts/run.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ function updateNodeModules() {
167167

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

‎src/main/const.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ export const SYSTEM_IS_LINUX = systemTypelinux === 'Linux';
2727
export const IPROXY_UPDATE_DIR = path.join(IPROXY_HOME_PATH, './update');
2828
export const IPROXY_UPDATE_CONFIG = path.join(IPROXY_UPDATE_DIR, './config.json');
2929
export const IPROXY_FILES_DIR = path.join(IPROXY_HOME_PATH, './files');
30-
export const PROXY_CONF_HELPER_FILE_PATH = path.join(IPROXY_FILES_DIR, './proxy_conf_helper');
30+
export const PROXY_CONF_HELPER_FILE_PATH = path.join(
31+
IPROXY_FILES_DIR,
32+
os.arch() === 'arm64' && SYSTEM_IS_MACOS ? 'proxy_conf_helper_arm64' : 'proxy_conf_helper',
33+
);
3134
export const PROXY_CONF_HELPER_PATH = path.join(IPROXY_HOME_PATH, './proxy_conf_helper');
3235
export const PROXY_REFRESH_WINDOWS_HELPER_PATH = path.join(IPROXY_FILES_DIR, './win_proxy_helper');
3336

‎src/main/install.ts‎

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,16 @@ Application will quit
119119
treeKill(process.pid);
120120
}
121121

122-
export async function installCertAndHelper() {
123-
console.log('Install cert');
124-
const certs = (await generateCert()) as {
125-
key: string;
126-
cert: string;
127-
};
122+
export async function installCertAndHelper(installCert = true) {
123+
const dir = installCert ? (await tempdir()).replace('ADMINI~1', 'Administrator') : '';
128124

129-
const dir = (await tempdir()).replace('ADMINI~1', 'Administrator');
130-
131-
// 写入证书
132-
await fs.mkdirp(dir);
133-
await fs.writeFileAsync(path.join(dir, CERT_KEY_FILE_NAME), certs.key, 'utf-8');
134-
await fs.writeFileAsync(path.join(dir, CERT_FILE_NAME), certs.cert, 'utf-8');
125+
if (installCert) {
126+
console.log('Install cert');
127+
const certs = (await generateCert()) as { key: string; cert: string };
128+
await fs.mkdirp(dir);
129+
await fs.writeFileAsync(path.join(dir, CERT_KEY_FILE_NAME), certs.key, 'utf-8');
130+
await fs.writeFileAsync(path.join(dir, CERT_FILE_NAME), certs.cert, 'utf-8');
131+
}
135132

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

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

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

234236
async function checkCertInstall() {
@@ -258,14 +260,25 @@ async function checkHelperInstall() {
258260
// 权限不对
259261
return false;
260262
}
261-
return true;
263+
// An older install may still contain the Intel helper on Apple Silicon.
264+
// Compare the installed binary with the one packaged for this architecture.
265+
try {
266+
const [installed, packaged] = await Promise.all([
267+
fs.readFileAsync(PROXY_CONF_HELPER_PATH),
268+
fs.readFileAsync(PROXY_CONF_HELPER_FILE_PATH),
269+
]);
270+
return installed.equals(packaged);
271+
} catch (e) {
272+
return false;
273+
}
262274
}
263275

264276
// 检查安装状态,如果没安装就安装一下
265277
export default async function checkInstallStatus() {
266-
if ((await checkCertInstall()) && (await checkHelperInstall())) {
278+
const certInstalled = await checkCertInstall();
279+
if (certInstalled && (await checkHelperInstall())) {
267280
// pass
268281
} else {
269-
await installCertAndHelper();
282+
await installCertAndHelper(!certInstalled);
270283
}
271284
}

‎src/main/main.ts‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,23 @@ async function initCopyFiles() {
331331
}
332332

333333
const versionFile = path.join(IPROXY_FILES_DIR, 'version');
334-
if (fs.existsSync(versionFile) && fs.readFileSync(versionFile, 'utf-8') === version && !electronIsDev) {
334+
const whistleBundle = path.join(
335+
IPROXY_FILES_DIR,
336+
'node',
337+
'node_modules',
338+
'whistle',
339+
'biz',
340+
'webui',
341+
'htdocs',
342+
'js',
343+
'index.js',
344+
);
345+
if (
346+
fs.existsSync(versionFile) &&
347+
fs.readFileSync(versionFile, 'utf-8') === version &&
348+
fs.existsSync(whistleBundle) &&
349+
!electronIsDev
350+
) {
335351
updateSplashProgress(100, 'Files already up to date');
336352
} else {
337353
console.log('copy files');

0 commit comments

Comments
 (0)