refactor: deprecate camoufox

This commit is contained in:
zhom
2026-06-07 23:03:42 +04:00
parent 15f3aa03f7
commit fc9a00b97d
26 changed files with 679 additions and 842 deletions
+3
View File
@@ -32,6 +32,7 @@ export type BackendErrorCode =
| "PROXY_NOT_WORKING"
| "PROXY_PAYMENT_REQUIRED"
| "VPN_NOT_WORKING"
| "CAMOUFOX_IMPORT_DEPRECATED"
| "INTERNAL_ERROR";
export interface BackendError {
@@ -132,6 +133,8 @@ export function translateBackendError(t: TFunction, err: unknown): string {
return t("backendErrors.proxyPaymentRequired");
case "VPN_NOT_WORKING":
return t("backendErrors.vpnNotWorking");
case "CAMOUFOX_IMPORT_DEPRECATED":
return t("backendErrors.camoufoxImportDeprecated");
case "INTERNAL_ERROR":
return t("backendErrors.internal", {
detail: parsed.params?.detail ?? "",
+86
View File
@@ -0,0 +1,86 @@
import type { CloudUser, Entitlements } from "@/types";
const DEFAULT_REQUESTS_PER_HOUR = 100;
interface Capabilities {
browserAutomation: boolean;
crossOsFingerprints: boolean;
cloudBackup: boolean;
teamCollaboration: boolean;
}
const NONE: Entitlements = {
active: false,
browserAutomation: false,
crossOsFingerprints: false,
cloudBackup: false,
teamCollaboration: false,
profileLimit: 0,
requestsPerHour: 0,
};
// Mirror of PLAN_CAPABILITIES in apps/backend/src/plans/entitlements.ts. Keep in
// sync — a new plan must be declared here too, or it falls back to DEFAULT_PAID.
const PLAN_CAPABILITIES: Record<string, Capabilities> = {
starter: {
browserAutomation: false,
crossOsFingerprints: true,
cloudBackup: true,
teamCollaboration: false,
},
pro: {
browserAutomation: true,
crossOsFingerprints: true,
cloudBackup: true,
teamCollaboration: false,
},
team: {
browserAutomation: true,
crossOsFingerprints: true,
cloudBackup: true,
teamCollaboration: true,
},
enterprise: {
browserAutomation: true,
crossOsFingerprints: true,
cloudBackup: true,
teamCollaboration: true,
},
};
// Unknown paid plan -> pro-level (never team), matching the backend default.
const DEFAULT_PAID: Capabilities = {
browserAutomation: true,
crossOsFingerprints: true,
cloudBackup: true,
teamCollaboration: false,
};
/**
* The user's effective entitlements. Prefers the backend-resolved object the
* desktop attaches to CloudUser; only falls back to deriving from the plan
* fields when it's missing (older cached state). The fallback mirrors the
* backend matrix in `apps/backend/src/plans/entitlements.ts`.
*/
export function getEntitlements(
user: CloudUser | null | undefined,
): Entitlements {
if (user?.entitlements) return user.entitlements;
if (!user) return NONE;
const active =
user.plan !== "free" &&
(user.subscriptionStatus === "active" || user.planPeriod === "lifetime");
if (!active) return NONE;
const caps = PLAN_CAPABILITIES[user.plan] ?? DEFAULT_PAID;
return {
active: true,
browserAutomation: caps.browserAutomation,
crossOsFingerprints: caps.crossOsFingerprints,
cloudBackup: caps.cloudBackup,
teamCollaboration: caps.teamCollaboration,
profileLimit: user.profileLimit,
requestsPerHour: caps.browserAutomation ? DEFAULT_REQUESTS_PER_HOUR : 0,
};
}