diff --git a/CHANGELOG.fr.md b/CHANGELOG.fr.md
index 6af08d3..c5fe501 100644
--- a/CHANGELOG.fr.md
+++ b/CHANGELOG.fr.md
@@ -6,6 +6,9 @@
- CI : nouveau workflow `check.yml` qui exécute `cargo check`/`cargo test` et le build frontend sur chaque push de branche et PR, détectant les erreurs avant le merge plutôt qu'au moment de la release (#60)
- Carte de licence dans les Paramètres : affiche l'édition actuelle (Gratuite/Base/Premium), accepte une clé de licence et redirige vers la page d'achat (#47)
+### Modifié
+- Les mises à jour automatiques sont maintenant réservées à l'édition Base ; l'édition Gratuite affiche un message invitant à activer une licence (#48)
+
## [0.6.7] - 2026-03-29
### Modifié
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0364c7..70b1dbd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@
- CI: new `check.yml` workflow runs `cargo check`/`cargo test` and the frontend build on every branch push and PR, catching errors before merge instead of waiting for the release tag (#60)
- License card in Settings page: shows the current edition (Free/Base/Premium), accepts a license key, and links to the purchase page (#47)
+### Changed
+- Automatic updates are now gated behind the Base edition entitlement; the Free edition shows an upgrade hint instead of fetching updates (#48)
+
## [0.6.7] - 2026-03-29
### Changed
diff --git a/src/components/shared/ErrorPage.tsx b/src/components/shared/ErrorPage.tsx
index 630c95b..0cfbca8 100644
--- a/src/components/shared/ErrorPage.tsx
+++ b/src/components/shared/ErrorPage.tsx
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { AlertTriangle, ChevronDown, ChevronUp, RefreshCw, Download, Mail, Bug } from "lucide-react";
import { check } from "@tauri-apps/plugin-updater";
+import { invoke } from "@tauri-apps/api/core";
interface ErrorPageProps {
error?: string;
@@ -10,7 +11,7 @@ interface ErrorPageProps {
export default function ErrorPage({ error }: ErrorPageProps) {
const { t } = useTranslation();
const [showDetails, setShowDetails] = useState(false);
- const [updateStatus, setUpdateStatus] = useState<"idle" | "checking" | "available" | "upToDate" | "error">("idle");
+ const [updateStatus, setUpdateStatus] = useState<"idle" | "checking" | "available" | "upToDate" | "notEntitled" | "error">("idle");
const [updateVersion, setUpdateVersion] = useState
+ {t("error.updateNotEntitled")} +
+ )} {updateStatus === "error" && updateError && ({updateError}
)} diff --git a/src/hooks/useUpdater.ts b/src/hooks/useUpdater.ts index b694786..9bf9f34 100644 --- a/src/hooks/useUpdater.ts +++ b/src/hooks/useUpdater.ts @@ -1,6 +1,7 @@ import { useReducer, useCallback, useRef } from "react"; import { check, type Update } from "@tauri-apps/plugin-updater"; import { relaunch } from "@tauri-apps/plugin-process"; +import { invoke } from "@tauri-apps/api/core"; type UpdateStatus = | "idle" @@ -10,6 +11,7 @@ type UpdateStatus = | "downloading" | "readyToInstall" | "installing" + | "notEntitled" | "error"; interface UpdaterState { @@ -29,6 +31,7 @@ type UpdaterAction = | { type: "DOWNLOAD_PROGRESS"; downloaded: number; contentLength: number | null } | { type: "READY_TO_INSTALL" } | { type: "INSTALLING" } + | { type: "NOT_ENTITLED" } | { type: "ERROR"; error: string }; const initialState: UpdaterState = { @@ -56,6 +59,8 @@ function reducer(state: UpdaterState, action: UpdaterAction): UpdaterState { return { ...state, status: "readyToInstall", error: null }; case "INSTALLING": return { ...state, status: "installing", error: null }; + case "NOT_ENTITLED": + return { ...state, status: "notEntitled", error: null }; case "ERROR": return { ...state, status: "error", error: action.error }; } @@ -68,6 +73,16 @@ export function useUpdater() { const checkForUpdate = useCallback(async () => { dispatch({ type: "CHECK_START" }); try { + // Auto-updates are gated behind the entitlements module (Issue #46/#48). + // The check is centralized server-side via `check_entitlement` so the + // tier→feature mapping lives in one place. + const allowed = await invoke{t("settings.updates.notEntitled")}
+