diff --git a/.electron-builder.config.js b/.electron-builder.config.js
index 4220a83..2bfaa16 100644
--- a/.electron-builder.config.js
+++ b/.electron-builder.config.js
@@ -9,6 +9,7 @@
* @see https://www.electron.build/configuration/configuration
*/
require('dotenv').config();
+
function getBuildTime() {
return process.env.BUILD_TIME || new Date().getTime();
}
@@ -100,20 +101,34 @@ module.exports = async function () {
target: [
{
target: 'dmg',
- arch: ['x64', 'arm64'],
+ arch: process.env.BUILD_ARCH || 'arm64',
},
],
category: 'public.app-category.developer-tools',
- hardenedRuntime: false,
+ hardenedRuntime: true,
gatekeeperAssess: false,
- entitlements: null,
- entitlementsInherit: null,
+ entitlements: 'buildResources/entitlements.mac.plist',
+ entitlementsInherit: 'buildResources/entitlements.mac.plist',
artifactName: '${productName}-${version}-${arch}-${os}-' + getBuildTime() + '.${ext}',
compression: 'store',
darkModeSupport: true,
+ signIgnore: [
+ 'node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-arm64/node_sqlite3.node',
+ 'node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-x64/node_sqlite3.node',
+ ],
+ // extendInfo: {
+ // NSAppleEventsUsageDescription: "Please allow access to system events",
+ // NSCameraUsageDescription: "Please allow access to camera",
+ // },
+ // protocols: [],
+ // helperBundleId: `${process.env.APP_BUNDLE_ID}.helper`,
+ // helperEHBundleId: `${process.env.APP_BUNDLE_ID}.helper.EH`,
+ // helperGPUBundleId: `${process.env.APP_BUNDLE_ID}.helper.GPU`,
+ // helperPluginBundleId: `${process.env.APP_BUNDLE_ID}.helper.Plugin`,
+ // helperRendererBundleId: `${process.env.APP_BUNDLE_ID}.helper.Renderer`,
};
config.dmg = {
- sign: false,
+ sign: true,
writeUpdateInfo: false,
format: 'ULFO',
};
@@ -146,5 +161,21 @@ module.exports = async function () {
releaseType: 'draft',
};
+ // CI 环境特定配置(GitHub Actions 使用)
+ if (process.env.CI && process.platform === 'darwin') {
+ config.mac = {
+ ...config.mac, // 保留基础配置
+ identity: process.env.APPLE_IDENTITY, // CI 环境使用签名
+ hardenedRuntime: true,
+ gatekeeperAssess: false,
+ entitlements: 'buildResources/entitlements.mac.plist',
+ entitlementsInherit: 'buildResources/entitlements.mac.plist',
+ signIgnore: [
+ 'node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-arm64/node_sqlite3.node',
+ 'node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-x64/node_sqlite3.node',
+ ],
+ };
+ }
+
return config;
};
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4c0e9d6..f368c2c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -41,5 +41,9 @@ jobs:
dry-run: ${{ github.event_name != 'push' || (github.ref_type != 'tag' && github.ref_name != 'main') }}
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
+ BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
+ P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
+ KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
+ APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }}
VITE_APP_API: ${{ secrets.VITE_APP_API }}
VITE_START_PAGE_URL: ${{ secrets.VITE_START_PAGE_URL }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6592df9..3d57b27 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -11,6 +11,14 @@ on:
secrets:
GH_TOKEN:
required: true
+ BUILD_CERTIFICATE_BASE64:
+ required: true
+ P12_PASSWORD:
+ required: true
+ KEYCHAIN_PASSWORD:
+ required: true
+ APPLE_IDENTITY:
+ required: true
VITE_APP_API:
required: true
VITE_START_PAGE_URL:
@@ -156,31 +164,69 @@ jobs:
echo "VITE_APP_API=${{ secrets.VITE_APP_API }}" > .env.production.local
echo "VITE_START_PAGE_URL=${{ secrets.VITE_START_PAGE_URL }}" >> .env.production.local
- - name: Build Project
+ - name: Install Apple certificates
+ if: matrix.os == 'macos-latest'
+ env:
+ BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
+ P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
+ KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
+ APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }}
run: |
- npm run build
- ls -la packages/main/dist/
- ls -la packages/preload/dist/
- ls -la packages/renderer/dist/
+ CERTIFICATE_PATH=$HOME/certificates
+ KEYCHAIN_PATH=$HOME/Library/Keychains/build.keychain-db
+
+ mkdir -p $CERTIFICATE_PATH
+
+ # 输出证书长度(不要显示内容)
+ echo "Certificate length: ${#BUILD_CERTIFICATE_BASE64}"
+
+ # 使用 -D 参数进行解码
+ echo "$BUILD_CERTIFICATE_BASE64" | base64 -D > $CERTIFICATE_PATH/certificate.p12
+
+ # 检查证书文件
+ ls -l $CERTIFICATE_PATH/certificate.p12
+
+ # 创建并配置钥匙串
+ security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
+ security set-keychain-settings -t 3600 -u build.keychain
+ security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
+ security default-keychain -s build.keychain
+
+ # 导入证书
+ security import $CERTIFICATE_PATH/certificate.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
+
+ # 列出所有身份
+ echo "All identities in keychain:"
+ security find-identity -v -p codesigning build.keychain
+
+ # 设置钥匙串访问权限
+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
+
+ # 尝试查找特定证书
+ echo "Looking for specific certificate: $APPLE_IDENTITY"
+ security find-certificate -a -c "$APPLE_IDENTITY" -Z build.keychain || true
- name: Build macOS
if: matrix.os == 'macos-latest'
run: |
- # 设置 Xcode
- sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
- sudo xcodebuild -license accept
+ # 设置构建架构
+ export BUILD_ARCH="${{ matrix.arch }}"
- # 构建 native addon(添加详细日志)
- npm run build:native-addon:mac --verbose
- npm run rebuild-deps:mac --verbose
-
- # 检查构建产物
- ls -la packages/main/src/native-addon/build/Release/
+ # 构建指定架构
+ if [ "$BUILD_ARCH" = "x64" ]; then
+ npm run rebuild-deps:mac:x64 --verbose
+ npm run build:native-addon:mac:x64 --verbose
+ elif [ "$BUILD_ARCH" = "arm64" ]; then
+ npm run rebuild-deps:mac:arm64 --verbose
+ npm run build:native-addon:mac:arm64 --verbose
+ fi
# 构建和发布
npm run publish --verbose
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }}
+ BUILD_ARCH: ${{ matrix.arch }}
- name: Build and Publish
uses: nick-fields/retry@v2
diff --git a/buildResources/entitlements.mac.plist b/buildResources/entitlements.mac.plist
index cb492c5..1361ffa 100644
--- a/buildResources/entitlements.mac.plist
+++ b/buildResources/entitlements.mac.plist
@@ -27,5 +27,10 @@
NSAccessibilityUsageDescription
Chrome Power needs accessibility permission to manage windows. Please enable it in System Preferences.
+ com.apple.security.files.user-selected.read-write
+
+ com.apple.security.files.downloads.read-write
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index e197500..a79a151 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,9 @@
"postinstall": "electron-builder install-app-deps && cross-env ELECTRON_RUN_AS_NODE=1 electron scripts/update-electron-vendors.mjs && npm run build:native-addon",
"format": "npx prettier --write \"**/*.{js,mjs,cjs,ts,mts,cts,vue,json}\"",
"rebuild-deps": "npm rebuild sqlite3 --build-from-source --arch=x64 && npm rebuild sqlite3 --build-from-source --arch=arm64",
- "rebuild-deps:mac": "npm rebuild sqlite3 --build-from-source --arch=x64 && npm rebuild sqlite3 --build-from-source --arch=arm64"
+ "rebuild-deps:mac": "npm rebuild sqlite3 --build-from-source --arch=x64 && npm rebuild sqlite3 --build-from-source --arch=arm64",
+ "rebuild-deps:mac:x64": "npm rebuild sqlite3 --build-from-source --arch=x64",
+ "rebuild-deps:mac:arm64": "npm rebuild sqlite3 --build-from-source --arch=arm64"
},
"devDependencies": {
"@iconify/react": "^4.1.1",
diff --git a/packages/main/src/fingerprint/index.ts b/packages/main/src/fingerprint/index.ts
index a7f9234..8cd6bdf 100644
--- a/packages/main/src/fingerprint/index.ts
+++ b/packages/main/src/fingerprint/index.ts
@@ -403,7 +403,7 @@ async function createSocksProxy(proxyData: DB.Proxy) {
});
// 添加更多错误处理
- proxyServer.on('error', (err) => {
+ proxyServer.on('error', err => {
logger.error('Socks server error:', err);
});
diff --git a/packages/main/src/proxy-server/socks-server.ts b/packages/main/src/proxy-server/socks-server.ts
index 6483840..4374ca0 100644
--- a/packages/main/src/proxy-server/socks-server.ts
+++ b/packages/main/src/proxy-server/socks-server.ts
@@ -57,11 +57,11 @@ class HttpProxy extends EventEmitter {
};
// 添加未捕获异常处理
- this.on('error', (error) => {
+ this.on('error', error => {
logger.error('Proxy server error:', error);
});
-
- process.on('uncaughtException', (error) => {
+
+ process.on('uncaughtException', error => {
if (error instanceof Error && 'code' in error && error.code === 'ECONNRESET') {
logger.error('Connection reset by peer');
} else {
@@ -106,7 +106,7 @@ class HttpProxy extends EventEmitter {
proxy: `${proxy.ipaddress}:${proxy.port}`,
url: uReq.url,
});
-
+
if (this.retryCount < this.maxRetries) {
this.retryCount++;
setTimeout(() => handleRequest(), 1000);
@@ -127,7 +127,7 @@ class HttpProxy extends EventEmitter {
pReq.on('response', pRes => {
try {
this.retryCount = 0;
-
+
// 为响应添加错误处理
pRes.on('error', error => {
logger.error('Response error:', error);
@@ -144,7 +144,7 @@ class HttpProxy extends EventEmitter {
pRes.pipe(uRes);
uRes.writeHead(pRes.statusCode!, pRes.headers);
}
-
+
this.emit('request:success');
} catch (error) {
logger.error('Error handling response:', error);
diff --git a/packages/main/src/server/index.ts b/packages/main/src/server/index.ts
index b16c413..6181ae0 100644
--- a/packages/main/src/server/index.ts
+++ b/packages/main/src/server/index.ts
@@ -29,7 +29,7 @@ app.get('/status', async (req, res) => {
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
console.error('Express error:', err);
if (!res.headersSent) {
- res.status(500).json({ error: 'Internal server error' });
+ res.status(500).json({error: 'Internal server error'});
}
next(err);
});