Compare commits

...

5 Commits

17 changed files with 1034 additions and 2029 deletions
@@ -0,0 +1,60 @@
name: Dependabot Automerge
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
contents: write
checks: read
jobs:
security-scan:
name: Security Vulnerability Scan
if: ${{ github.actor == 'dependabot[bot]' }}
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@e69cc6c86b31f1e7e23935bbe7031b50e51082de" # v2.0.2
with:
scan-args: |-
-r
--skip-git
--lockfile=pnpm-lock.yaml
--lockfile=src-tauri/Cargo.lock
--lockfile=nodecar/pnpm-lock.yaml
./
permissions:
security-events: write
contents: read
actions: read
lint-js:
name: Lint JavaScript/TypeScript
if: ${{ github.actor == 'dependabot[bot]' }}
uses: ./.github/workflows/lint-js.yml
secrets: inherit
lint-rust:
name: Lint Rust
if: ${{ github.actor == 'dependabot[bot]' }}
uses: ./.github/workflows/lint-rs.yml
secrets: inherit
dependabot-automerge:
name: Dependabot Automerge
if: ${{ github.actor == 'dependabot[bot]' }}
needs: [security-scan, lint-js, lint-rust]
runs-on: ubuntu-latest
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Auto-merge minor and patch updates
uses: ridedott/merge-me-action@v2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PRESET: DEPENDABOT_MINOR
MERGE_METHOD: SQUASH
timeout-minutes: 10
+2 -3
View File
@@ -14,9 +14,8 @@ on:
- "src/**"
- "nodecar/**"
- "package.json"
- "package-lock.json"
- "yarn.lock"
- "pnpm-lock.yaml"
- "yarn.lock"
- "README.md"
- ".github/workflows/lint-js.yml"
- ".github/workflows/osv.yml"
@@ -68,7 +67,7 @@ jobs:
- name: Install nodecar dependencies
working-directory: ./nodecar
run: |
pnpm install --ignore-workspace --frozen-lockfile
pnpm install --frozen-lockfile
- name: Build nodecar binary
shell: bash
+4 -8
View File
@@ -21,11 +21,10 @@ on:
paths:
- "package.json"
- "pnpm-lock.yaml"
- "package-lock.json"
- "src-tauri/Cargo.toml"
- "src-tauri/Cargo.lock"
- "nodecar/package.json"
- "nodecar/package-lock.json"
- "nodecar/pnpm-lock.yaml"
- ".github/workflows/osv.yml"
merge_group:
branches: ["main"]
@@ -37,11 +36,10 @@ on:
paths:
- "package.json"
- "pnpm-lock.yaml"
- "package-lock.json"
- "src-tauri/Cargo.toml"
- "src-tauri/Cargo.lock"
- "nodecar/package.json"
- "nodecar/package-lock.json"
- "nodecar/pnpm-lock.yaml"
permissions:
security-events: write
@@ -57,10 +55,9 @@ jobs:
scan-args: |-
-r
--skip-git
--lockfile=package-lock.json
--lockfile=pnpm-lock.yaml
--lockfile=src-tauri/Cargo.lock
--lockfile=nodecar/package-lock.json
--lockfile=nodecar/pnpm-lock.yaml
./
scan-pr:
@@ -71,8 +68,7 @@ jobs:
scan-args: |-
-r
--skip-git
--lockfile=package-lock.json
--lockfile=pnpm-lock.yaml
--lockfile=src-tauri/Cargo.lock
--lockfile=nodecar/package-lock.json
--lockfile=nodecar/pnpm-lock.yaml
./
+18 -2
View File
@@ -11,6 +11,22 @@ env:
STABLE_RELEASE: "true"
jobs:
security-scan:
name: Security Vulnerability Scan
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@e69cc6c86b31f1e7e23935bbe7031b50e51082de" # v2.0.2
with:
scan-args: |-
-r
--skip-git
--lockfile=pnpm-lock.yaml
--lockfile=src-tauri/Cargo.lock
--lockfile=nodecar/pnpm-lock.yaml
./
permissions:
security-events: write
contents: read
actions: read
lint-js:
name: Lint JavaScript/TypeScript
uses: ./.github/workflows/lint-js.yml
@@ -22,7 +38,7 @@ jobs:
secrets: inherit
release:
needs: [lint-js, lint-rust]
needs: [security-scan, lint-js, lint-rust]
permissions:
contents: write
strategy:
@@ -101,7 +117,7 @@ jobs:
- name: Install nodecar dependencies
working-directory: ./nodecar
run: |
pnpm install --ignore-workspace --frozen-lockfile
pnpm install --frozen-lockfile
- name: Build nodecar sidecar
shell: bash
+18 -2
View File
@@ -10,6 +10,22 @@ env:
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
jobs:
security-scan:
name: Security Vulnerability Scan
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@e69cc6c86b31f1e7e23935bbe7031b50e51082de" # v2.0.2
with:
scan-args: |-
-r
--skip-git
--lockfile=pnpm-lock.yaml
--lockfile=src-tauri/Cargo.lock
--lockfile=nodecar/pnpm-lock.yaml
./
permissions:
security-events: write
contents: read
actions: read
lint-js:
name: Lint JavaScript/TypeScript
uses: ./.github/workflows/lint-js.yml
@@ -21,7 +37,7 @@ jobs:
secrets: inherit
rolling-release:
needs: [lint-js, lint-rust]
needs: [security-scan, lint-js, lint-rust]
permissions:
contents: write
strategy:
@@ -69,7 +85,7 @@ jobs:
- name: Install nodecar dependencies
working-directory: ./nodecar
run: |
pnpm install --ignore-workspace --frozen-lockfile
pnpm install --frozen-lockfile
- name: Build nodecar sidecar
shell: bash
+4
View File
@@ -5,6 +5,10 @@
/.pnp
.pnp.js
# npm/yarn lock files (project uses pnpm only)
**/package-lock.json
**/yarn.lock
# testing
/coverage
+3
View File
@@ -3,6 +3,7 @@
"applescript",
"autoconfig",
"autologin",
"biomejs",
"cdylib",
"CFURL",
"checkin",
@@ -11,6 +12,7 @@
"donutbrowser",
"dtolnay",
"elif",
"esbuild",
"gifs",
"launchservices",
"mountpoint",
@@ -39,6 +41,7 @@
"Torbrowser",
"turbopack",
"unlisten",
"unrs",
"wiremock",
"xattr",
"zhom"
+1 -1
View File
@@ -50,7 +50,7 @@ After having the above dependencies installed, proceed through the following ste
```bash
cd nodecar
pnpm install --ignore-workspace --frozen-lockfile
pnpm install --frozen-lockfile
cd ..
```
+40
View File
@@ -0,0 +1,40 @@
# Security Policy
## Reporting Security Issues
Thanks for helping make Donut Browser safe for everyone! ❤️
We take the security of Donut Browser seriously. If you believe you have found a security vulnerability in Donut Browser, please report it to us through coordinated disclosure.
**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
Instead, please send an email to **contact at donutbrowser dot com** with the subject line "Security Vulnerability Report".
Please include as much of the information listed below as you can to help us better understand and resolve the issue:
- The type of issue (e.g., buffer overflow, injection attack, privilege escalation, or cross-site scripting)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue
- Your assessment of the severity level
This information will help us triage your report more quickly.
## What to Expect
- **Response Time**: We will acknowledge receipt of your vulnerability report within 72 hours.
- **Investigation**: We will investigate the issue and provide you with updates on our progress.
- **Resolution**: We aim to resolve critical security issues as fast as possible, but no longer than in 30 days after the initial report.
- **Disclosure**: We will coordinate with you on the timing of any public disclosure.
## Contact
For urgent security matters, please contact us at **contact at donutbrowser dot com**.
For general questions about this security policy, you can also reach out through:
- [GitHub Issues](https://github.com/zhom/donutbrowser/issues) (for non-security questions only)
- [GitHub Discussions](https://github.com/zhom/donutbrowser/discussions)
-1304
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -48,8 +48,8 @@ program
ignoreProxyCertificate: options.ignoreCertificate,
});
console.log(JSON.stringify(config));
} catch (error: any) {
console.error(`Failed to start proxy: ${error.message}`);
} catch (error: unknown) {
console.error(`Failed to start proxy: ${JSON.stringify(error)}`);
}
} else if (action === "stop") {
if (options.id) {
+2 -2
View File
@@ -1,5 +1,5 @@
import { spawn } from "child_process";
import path from "path";
import { spawn } from "node:child_process";
import path from "node:path";
import getPort from "get-port";
import {
type ProxyConfig,
+3 -3
View File
@@ -1,6 +1,6 @@
import fs from "fs";
import path from "path";
import os from "os";
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
// Define the proxy configuration type
export interface ProxyConfig {
+22 -47
View File
@@ -189,18 +189,14 @@ packages:
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
'@babel/compat-data@7.27.3':
resolution: {integrity: sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==}
'@babel/compat-data@7.27.5':
resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==}
engines: {node: '>=6.9.0'}
'@babel/core@7.27.4':
resolution: {integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.27.3':
resolution: {integrity: sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.27.5':
resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==}
engines: {node: '>=6.9.0'}
@@ -239,11 +235,6 @@ packages:
resolution: {integrity: sha512-Y+bO6U+I7ZKaM5G5rDUZiYfUvQPUibYmAFe7EnKdnKBbVXDZxvp+MWOH5gYciY0EPk4EScsuFMQBbEfpdRKSCQ==}
engines: {node: '>=6.9.0'}
'@babel/parser@7.27.4':
resolution: {integrity: sha512-BRmLHGwpUqLFR2jzx9orBuX/ABDkj2jLKOXrHDTN2aOKL+jFDDKaRNo9nyYsIl9h/UE/7lMKdDjKQQyxKKDZ7g==}
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/parser@7.27.5':
resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==}
engines: {node: '>=6.0.0'}
@@ -3596,36 +3587,28 @@ snapshots:
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/compat-data@7.27.3': {}
'@babel/compat-data@7.27.5': {}
'@babel/core@7.27.4':
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.27.1
'@babel/generator': 7.27.3
'@babel/generator': 7.27.5
'@babel/helper-compilation-targets': 7.27.2
'@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4)
'@babel/helpers': 7.27.4
'@babel/parser': 7.27.4
'@babel/parser': 7.27.5
'@babel/template': 7.27.2
'@babel/traverse': 7.27.4
'@babel/types': 7.27.3
convert-source-map: 2.0.0
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
transitivePeerDependencies:
- supports-color
'@babel/generator@7.27.3':
dependencies:
'@babel/parser': 7.27.4
'@babel/types': 7.27.3
'@jridgewell/gen-mapping': 0.3.8
'@jridgewell/trace-mapping': 0.3.25
jsesc: 3.1.0
'@babel/generator@7.27.5':
dependencies:
'@babel/parser': 7.27.5
@@ -3636,7 +3619,7 @@ snapshots:
'@babel/helper-compilation-targets@7.27.2':
dependencies:
'@babel/compat-data': 7.27.3
'@babel/compat-data': 7.27.5
'@babel/helper-validator-option': 7.27.1
browserslist: 4.25.0
lru-cache: 5.1.1
@@ -3671,10 +3654,6 @@ snapshots:
'@babel/template': 7.27.2
'@babel/types': 7.27.3
'@babel/parser@7.27.4':
dependencies:
'@babel/types': 7.27.3
'@babel/parser@7.27.5':
dependencies:
'@babel/types': 7.27.3
@@ -3692,17 +3671,17 @@ snapshots:
'@babel/template@7.27.2':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/parser': 7.27.4
'@babel/parser': 7.27.5
'@babel/types': 7.27.3
'@babel/traverse@7.27.4':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/generator': 7.27.3
'@babel/parser': 7.27.4
'@babel/generator': 7.27.5
'@babel/parser': 7.27.5
'@babel/template': 7.27.2
'@babel/types': 7.27.3
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@@ -3852,7 +3831,7 @@ snapshots:
'@eslint/config-array@0.20.0':
dependencies:
'@eslint/object-schema': 2.1.6
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@@ -3866,7 +3845,7 @@ snapshots:
'@eslint/eslintrc@3.3.1':
dependencies:
ajv: 6.12.6
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
espree: 10.3.0
globals: 14.0.0
ignore: 5.3.2
@@ -4701,7 +4680,7 @@ snapshots:
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.27.4
'@babel/parser': 7.27.5
'@babel/types': 7.27.3
'@types/babel__generator': 7.27.0
'@types/babel__template': 7.4.4
@@ -4713,7 +4692,7 @@ snapshots:
'@types/babel__template@7.4.4':
dependencies:
'@babel/parser': 7.27.4
'@babel/parser': 7.27.5
'@babel/types': 7.27.3
'@types/babel__traverse@7.20.7':
@@ -4761,7 +4740,7 @@ snapshots:
'@typescript-eslint/types': 8.33.1
'@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3)
'@typescript-eslint/visitor-keys': 8.33.1
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
eslint: 9.28.0(jiti@2.4.2)
typescript: 5.8.3
transitivePeerDependencies:
@@ -4771,7 +4750,7 @@ snapshots:
dependencies:
'@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
'@typescript-eslint/types': 8.33.1
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
typescript: 5.8.3
transitivePeerDependencies:
- supports-color
@@ -4789,7 +4768,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3)
'@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
eslint: 9.28.0(jiti@2.4.2)
ts-api-utils: 2.1.0(typescript@5.8.3)
typescript: 5.8.3
@@ -4804,7 +4783,7 @@ snapshots:
'@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
'@typescript-eslint/types': 8.33.1
'@typescript-eslint/visitor-keys': 8.33.1
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
@@ -5246,10 +5225,6 @@ snapshots:
dependencies:
ms: 2.1.3
debug@4.4.1:
dependencies:
ms: 2.1.3
debug@4.4.1(supports-color@5.5.0):
dependencies:
ms: 2.1.3
@@ -5481,7 +5456,7 @@ snapshots:
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@9.28.0(jiti@2.4.2)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
eslint: 9.28.0(jiti@2.4.2)
get-tsconfig: 4.10.1
is-bun-module: 2.0.0
@@ -5605,7 +5580,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.6
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint-scope: 8.3.0
eslint-visitor-keys: 4.2.0
@@ -6109,7 +6084,7 @@ snapshots:
dependencies:
chalk: 5.4.1
commander: 14.0.0
debug: 4.4.1
debug: 4.4.1(supports-color@5.5.0)
lilconfig: 3.1.3
listr2: 8.3.3
micromatch: 4.0.8
+5 -2
View File
@@ -1,6 +1,9 @@
packages:
- "nodecar"
onlyBuiltDependencies:
- '@biomejs/biome'
- '@tailwindcss/oxide'
- "@biomejs/biome"
- "@tailwindcss/oxide"
- esbuild
- sharp
- unrs-resolver
File diff suppressed because it is too large Load Diff
+143 -55
View File
@@ -239,7 +239,7 @@ impl BrowserVersionService {
} else {
BrowserVersionInfo {
version: version.clone(),
is_prerelease: version.contains("alpha") || version.contains("beta"),
is_prerelease: false, // Zen Browser releases are usually stable
date: "".to_string(),
}
}
@@ -356,60 +356,148 @@ impl BrowserVersionService {
version: &str,
) -> Result<DownloadInfo, Box<dyn std::error::Error + Send + Sync>> {
match browser {
"firefox" => Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=firefox-{version}&os=osx&lang=en-US"),
filename: format!("firefox-{version}.dmg"),
is_archive: true,
}),
"firefox-developer" => Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=devedition-{version}&os=osx&lang=en-US"),
filename: format!("firefox-developer-{version}.dmg"),
is_archive: true,
}),
"mullvad-browser" => Ok(DownloadInfo {
url: format!(
"https://github.com/mullvad/mullvad-browser/releases/download/{version}/mullvad-browser-macos-{version}.dmg"
),
filename: format!("mullvad-browser-{version}.dmg"),
is_archive: true,
}),
"zen" => Ok(DownloadInfo {
url: format!(
"https://github.com/zen-browser/desktop/releases/download/{version}/zen.macos-universal.dmg"
),
filename: format!("zen-{version}.dmg"),
is_archive: true,
}),
"brave" => {
// For Brave, we use a placeholder URL since we need to resolve the actual asset URL dynamically
// The actual URL will be resolved in the download service using the GitHub API
Ok(DownloadInfo {
url: format!(
"https://github.com/brave/brave-browser/releases/download/{version}/Brave-Browser-universal.dmg"
),
filename: format!("brave-{version}.dmg"),
is_archive: true,
})
}
"chromium" => {
let arch = if cfg!(target_arch = "aarch64") { "Mac_Arm" } else { "Mac" };
Ok(DownloadInfo {
url: format!(
"https://commondatastorage.googleapis.com/chromium-browser-snapshots/{arch}/{version}/chrome-mac.zip"
),
filename: format!("chromium-{version}.zip"),
is_archive: true,
})
}
"tor-browser" => Ok(DownloadInfo {
url: format!(
"https://archive.torproject.org/tor-package-archive/torbrowser/{version}/tor-browser-macos-{version}.dmg"
),
filename: format!("tor-browser-{version}.dmg"),
is_archive: true,
}),
_ => Err(format!("Unsupported browser: {browser}").into()),
}
"firefox" => {
#[cfg(target_os = "macos")]
return Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=firefox-{version}&os=osx&lang=en-US"),
filename: format!("firefox-{version}.dmg"),
is_archive: true,
});
#[cfg(target_os = "windows")]
return Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=firefox-{version}&os=win64&lang=en-US"),
filename: format!("firefox-{version}.exe"),
is_archive: false,
});
#[cfg(target_os = "linux")]
return Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=firefox-{version}&os=linux64&lang=en-US"),
filename: format!("firefox-{version}.tar.bz2"),
is_archive: true,
});
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
return Err("Unsupported platform for Firefox".into());
}
"firefox-developer" => {
#[cfg(target_os = "macos")]
return Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=devedition-{version}&os=osx&lang=en-US"),
filename: format!("firefox-developer-{version}.dmg"),
is_archive: true,
});
#[cfg(target_os = "windows")]
return Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=devedition-{version}&os=win64&lang=en-US"),
filename: format!("firefox-developer-{version}.exe"),
is_archive: false,
});
#[cfg(target_os = "linux")]
return Ok(DownloadInfo {
url: format!("https://download.mozilla.org/?product=devedition-{version}&os=linux64&lang=en-US"),
filename: format!("firefox-developer-{version}.tar.bz2"),
is_archive: true,
});
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
return Err("Unsupported platform for Firefox Developer".into());
}
"mullvad-browser" => {
#[cfg(target_os = "macos")]
return Ok(DownloadInfo {
url: format!(
"https://github.com/mullvad/mullvad-browser/releases/download/{version}/mullvad-browser-macos-{version}.dmg"
),
filename: format!("mullvad-browser-{version}.dmg"),
is_archive: true,
});
#[cfg(target_os = "windows")]
return Ok(DownloadInfo {
url: format!(
"https://github.com/mullvad/mullvad-browser/releases/download/{version}/mullvad-browser-windows-{version}.exe"
),
filename: format!("mullvad-browser-{version}.exe"),
is_archive: false,
});
#[cfg(target_os = "linux")]
return Ok(DownloadInfo {
url: format!(
"https://github.com/mullvad/mullvad-browser/releases/download/{version}/mullvad-browser-linux-{version}.tar.xz"
),
filename: format!("mullvad-browser-{version}.tar.xz"),
is_archive: true,
});
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
return Err("Unsupported platform for Mullvad Browser".into());
}
"zen" => {
#[cfg(target_os = "macos")]
return Ok(DownloadInfo {
url: format!(
"https://github.com/zen-browser/desktop/releases/download/{version}/zen.macos-universal.dmg"
),
filename: format!("zen-{version}.dmg"),
is_archive: true,
});
#[cfg(target_os = "windows")]
return Ok(DownloadInfo {
url: format!(
"https://github.com/zen-browser/desktop/releases/download/{version}/zen.win.x64.zip"
),
filename: format!("zen-{version}.zip"),
is_archive: true,
});
#[cfg(target_os = "linux")]
return Ok(DownloadInfo {
url: format!(
"https://github.com/zen-browser/desktop/releases/download/{version}/zen.linux-x86_64.AppImage"
),
filename: format!("zen-{version}.AppImage"),
is_archive: false,
});
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
return Err("Unsupported platform for Zen Browser".into());
}
"brave" => {
// For Brave, we use a placeholder URL since we need to resolve the actual asset URL dynamically
// The actual URL will be resolved in the download service using the GitHub API
Ok(DownloadInfo {
url: format!(
"https://github.com/brave/brave-browser/releases/download/{version}/Brave-Browser-universal.dmg"
),
filename: format!("brave-{version}.dmg"),
is_archive: true,
})
}
"chromium" => {
let arch = if cfg!(target_arch = "aarch64") { "Mac_Arm" } else { "Mac" };
Ok(DownloadInfo {
url: format!(
"https://commondatastorage.googleapis.com/chromium-browser-snapshots/{arch}/{version}/chrome-mac.zip"
),
filename: format!("chromium-{version}.zip"),
is_archive: true,
})
}
"tor-browser" => Ok(DownloadInfo {
url: format!(
"https://archive.torproject.org/tor-package-archive/torbrowser/{version}/tor-browser-macos-{version}.dmg"
),
filename: format!("tor-browser-{version}.dmg"),
is_archive: true,
}),
_ => Err(format!("Unsupported browser: {browser}").into()),
}
}
// Private helper methods for each browser type