mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-29 22:20:39 +02:00
refactor: cleanup
This commit is contained in:
@@ -41,6 +41,14 @@ const isFingerprintEditingDisabled = (config: WayfernConfig): boolean => {
|
||||
return config.randomize_fingerprint_on_launch === true;
|
||||
};
|
||||
|
||||
/** What `generate_sample_fingerprint` returns. Identity fields are null on a
|
||||
* browser version that predates the Wayfern identity API. */
|
||||
interface GeneratedFingerprint {
|
||||
fingerprint: string;
|
||||
identity_id: string | null;
|
||||
identity_baseline: string | null;
|
||||
}
|
||||
|
||||
const getCurrentOS = (): WayfernOS => {
|
||||
if (typeof navigator === "undefined") return "linux";
|
||||
const platform = navigator.platform.toLowerCase();
|
||||
@@ -83,12 +91,23 @@ export function WayfernConfigForm({
|
||||
setIsGeneratingFingerprint(true);
|
||||
try {
|
||||
const configJson = JSON.stringify(config);
|
||||
const result = await invoke<string>("generate_sample_fingerprint", {
|
||||
browser: profileBrowser ?? "wayfern",
|
||||
version: profileVersion,
|
||||
configJson,
|
||||
});
|
||||
onConfigChange("fingerprint", result);
|
||||
const result = await invoke<GeneratedFingerprint>(
|
||||
"generate_sample_fingerprint",
|
||||
{
|
||||
browser: profileBrowser ?? "wayfern",
|
||||
version: profileVersion,
|
||||
configJson,
|
||||
},
|
||||
);
|
||||
onConfigChange("fingerprint", result.fingerprint);
|
||||
// The identity travels with the fingerprint it produced. Storing one
|
||||
// without the other leaves a device the launch path cannot reproduce, so
|
||||
// it would be discarded and re-minted on the next launch.
|
||||
onConfigChange("identity_id", result.identity_id ?? undefined);
|
||||
onConfigChange(
|
||||
"identity_baseline",
|
||||
result.identity_baseline ?? undefined,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Failed to generate fingerprint:", error);
|
||||
} finally {
|
||||
@@ -171,6 +190,12 @@ export function WayfernConfigForm({
|
||||
|
||||
const isEditingDisabled = isFingerprintEditingDisabled(config) || readOnly;
|
||||
|
||||
/** For an identity-backed profile these fields have no stored value to show,
|
||||
* and editing them by hand produces an inconsistent device. Hidden rather
|
||||
* than rendered blank-and-disabled, because a blank box reads as data loss
|
||||
* whereas their absence is the truth. */
|
||||
const isIdentityDerived = config.identity_id != null;
|
||||
|
||||
const renderAdvancedForm = () => (
|
||||
<div className="space-y-6">
|
||||
{/* Operating System Selection */}
|
||||
@@ -894,21 +919,23 @@ export function WayfernConfigForm({
|
||||
</div>
|
||||
|
||||
{/* WebGL Parameters (JSON) */}
|
||||
<div className="space-y-3">
|
||||
<Label>{t("fingerprint.webglParametersJson")}</Label>
|
||||
<Textarea
|
||||
value={fingerprintConfig.webglParameters ?? ""}
|
||||
onChange={(e) => {
|
||||
updateFingerprintConfig(
|
||||
"webglParameters",
|
||||
e.target.value || undefined,
|
||||
);
|
||||
}}
|
||||
placeholder='{"7936": "Intel", "7937": "Intel(R) HD Graphics"}'
|
||||
className="font-mono text-sm"
|
||||
rows={4}
|
||||
/>
|
||||
</div>
|
||||
{!isIdentityDerived && (
|
||||
<div className="space-y-3">
|
||||
<Label>{t("fingerprint.webglParametersJson")}</Label>
|
||||
<Textarea
|
||||
value={fingerprintConfig.webglParameters ?? ""}
|
||||
onChange={(e) => {
|
||||
updateFingerprintConfig(
|
||||
"webglParameters",
|
||||
e.target.value || undefined,
|
||||
);
|
||||
}}
|
||||
placeholder='{"7936": "Intel", "7937": "Intel(R) HD Graphics"}'
|
||||
className="font-mono text-sm"
|
||||
rows={4}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Canvas Noise Seed */}
|
||||
<div className="space-y-3">
|
||||
@@ -1040,37 +1067,49 @@ export function WayfernConfigForm({
|
||||
{/* Vendor Info */}
|
||||
<div className="space-y-3">
|
||||
<Label>{t("fingerprint.vendorInfo")}</Label>
|
||||
<div className="grid grid-cols-1 gap-4 @md:grid-cols-2 @2xl:grid-cols-3">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="vendor">{t("fingerprint.vendor")}</Label>
|
||||
<Input
|
||||
id="vendor"
|
||||
value={fingerprintConfig.vendor ?? ""}
|
||||
onChange={(e) => {
|
||||
updateFingerprintConfig(
|
||||
"vendor",
|
||||
e.target.value || undefined,
|
||||
);
|
||||
}}
|
||||
placeholder={t("common.placeholders.example", {
|
||||
value: "Google Inc.",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="vendor-sub">{t("fingerprint.vendorSub")}</Label>
|
||||
<Input
|
||||
id="vendor-sub"
|
||||
value={fingerprintConfig.vendorSub ?? ""}
|
||||
onChange={(e) => {
|
||||
updateFingerprintConfig(
|
||||
"vendorSub",
|
||||
e.target.value || undefined,
|
||||
);
|
||||
}}
|
||||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
isIdentityDerived
|
||||
? "grid grid-cols-1 gap-4"
|
||||
: "grid grid-cols-1 gap-4 @md:grid-cols-2 @2xl:grid-cols-3"
|
||||
}
|
||||
>
|
||||
{!isIdentityDerived && (
|
||||
<>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="vendor">{t("fingerprint.vendor")}</Label>
|
||||
<Input
|
||||
id="vendor"
|
||||
value={fingerprintConfig.vendor ?? ""}
|
||||
onChange={(e) => {
|
||||
updateFingerprintConfig(
|
||||
"vendor",
|
||||
e.target.value || undefined,
|
||||
);
|
||||
}}
|
||||
placeholder={t("common.placeholders.example", {
|
||||
value: "Google Inc.",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="vendor-sub">
|
||||
{t("fingerprint.vendorSub")}
|
||||
</Label>
|
||||
<Input
|
||||
id="vendor-sub"
|
||||
value={fingerprintConfig.vendorSub ?? ""}
|
||||
onChange={(e) => {
|
||||
updateFingerprintConfig(
|
||||
"vendorSub",
|
||||
e.target.value || undefined,
|
||||
);
|
||||
}}
|
||||
placeholder=""
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="product-sub">
|
||||
{t("fingerprint.productSub")}
|
||||
|
||||
@@ -994,6 +994,7 @@
|
||||
"autoLocationDescription": "Automatically configure location information based on proxy configuration or your connection if no proxy provided",
|
||||
"editingDisabledRunning": "Fingerprint editing is disabled because the profile is currently running. Stop the profile to make changes.",
|
||||
"editingDisabledRandomized": "Fingerprint editing is disabled because random fingerprint generation is enabled. Disable the option above to manually edit the fingerprint configuration.",
|
||||
"derivedFromIdentity": "Derived from this profile's identity and not editable.",
|
||||
"advancedWarning": "Warning: Only edit these parameters if you know what you're doing. Incorrect values may break websites, make them detect you, and lead to hard-to-debug bugs.",
|
||||
"basicWarning": "Warning: Only edit these parameters if you know what you're doing.",
|
||||
"automatic": "Automatic",
|
||||
@@ -1977,7 +1978,11 @@
|
||||
"noE2ePasswordSet": "No end-to-end encryption password is set. Set one before syncing encrypted data.",
|
||||
"importSourceNotChromium": "This folder is not a Chromium browser profile",
|
||||
"importSourceNotChromiumNamed": "{{family}} profiles cannot be imported; only Chromium-based browsers are supported",
|
||||
"importSourceBrowserRunning": "Close {{browser}} first, or choose to import anyway"
|
||||
"importSourceBrowserRunning": "Close {{browser}} first, or choose to import anyway",
|
||||
"wayfernFingerprintApplyFailed": "Could not apply this profile's fingerprint, so the browser was not started. {{detail}}",
|
||||
"wayfernFingerprintGenerationFailed": "Could not create a fingerprint for this profile. {{detail}}",
|
||||
"wayfernGenerationLimitReached": "The fingerprint generation limit for this account has been reached. New fingerprints are unavailable for up to 24 hours. This limit applies to this computer, not to one profile.",
|
||||
"wayfernCrossOsRequiresPlan": "This profile claims {{detail}}, which needs a paid plan and an active sign-in. Sign in or switch the profile to your own operating system."
|
||||
},
|
||||
"rail": {
|
||||
"profiles": "Profiles",
|
||||
|
||||
@@ -128,6 +128,21 @@ export type BackendErrorCode =
|
||||
| "COOKIE_BOT_REQUIRES_PROXY"
|
||||
| "COOKIE_BOT_TOUCH_FINGERPRINT_UNSUPPORTED"
|
||||
| "FINGERPRINT_EXIT_MISMATCH"
|
||||
// The launch refuses instead of opening a window on an unmanaged device: a
|
||||
// silent fallback would leave the user browsing a random fingerprint while
|
||||
// the UI reported success, which is the worst failure an anti-detect product
|
||||
// can have. `detail` carries the underlying browser error for support.
|
||||
| "WAYFERN_FINGERPRINT_APPLY_FAILED"
|
||||
| "WAYFERN_FINGERPRINT_GENERATION_FAILED"
|
||||
// Its own code rather than a generation failure: the browser's quota block is
|
||||
// account-wide and lasts 24 hours, so "try again" is wrong advice, and a user
|
||||
// whose every profile refuses at once has to be told this is one limit and
|
||||
// not a broken install.
|
||||
| "WAYFERN_GENERATION_LIMIT_REACHED"
|
||||
// A cross-OS claim needs a signed plan token, so an expired or offline
|
||||
// session cannot apply one. Distinct from the generic apply failure because
|
||||
// signing in again is the fix; `detail` names the claimed OS.
|
||||
| "WAYFERN_CROSS_OS_REQUIRES_PLAN"
|
||||
| "LAUNCH_CONSENT_EXPIRED"
|
||||
| "VPN_WORKER_START_FAILED"
|
||||
| "EXIT_PROBE_FAILED"
|
||||
@@ -472,6 +487,20 @@ export function translateBackendError(t: TFunction, err: unknown): string {
|
||||
// room for one sentence.
|
||||
case "FINGERPRINT_EXIT_MISMATCH":
|
||||
return t("backendErrors.fingerprintExitMismatch");
|
||||
case "WAYFERN_FINGERPRINT_APPLY_FAILED":
|
||||
return t("backendErrors.wayfernFingerprintApplyFailed", {
|
||||
detail: parsed.params?.detail ?? "",
|
||||
});
|
||||
case "WAYFERN_FINGERPRINT_GENERATION_FAILED":
|
||||
return t("backendErrors.wayfernFingerprintGenerationFailed", {
|
||||
detail: parsed.params?.detail ?? "",
|
||||
});
|
||||
case "WAYFERN_GENERATION_LIMIT_REACHED":
|
||||
return t("backendErrors.wayfernGenerationLimitReached");
|
||||
case "WAYFERN_CROSS_OS_REQUIRES_PLAN":
|
||||
return t("backendErrors.wayfernCrossOsRequiresPlan", {
|
||||
detail: parsed.params?.detail ?? "",
|
||||
});
|
||||
case "LAUNCH_CONSENT_EXPIRED":
|
||||
return t("backendErrors.launchConsentExpired");
|
||||
case "VPN_WORKER_START_FAILED":
|
||||
|
||||
@@ -395,6 +395,8 @@ export interface WayfernConfig {
|
||||
randomize_fingerprint_on_launch?: boolean; // Generate new fingerprint on every launch
|
||||
os?: WayfernOS; // Operating system for fingerprint generation
|
||||
geo_proxy_signature?: string; // Internal: routing the fingerprint's location was computed for
|
||||
identity_id?: string; // Internal: UUID the device is derived from on browsers with the identity API
|
||||
identity_baseline?: string; // Internal: derived fingerprint before edits, diffed to recover overrides
|
||||
}
|
||||
|
||||
// Wayfern fingerprint config - matches the C++ FingerprintData structure
|
||||
|
||||
Reference in New Issue
Block a user