From 23f6c65a141bbe1ce1d64097574b38bcc06b567d Mon Sep 17 00:00:00 2001
From: Shivam Kumar
Date: Fri, 5 Sep 2025 16:30:09 +0530
Subject: [PATCH 1/2] feat(profile): display version number from .env in
profile menu
---
package-lock.json | 17 +++++++++++++++++
package.json | 1 +
public/locales/en/translation.json | 1 +
src/components/ui/sidebar.tsx | 2 +-
src/ui/User/UserProfile.tsx | 21 +++++++++++++++++++++
src/ui/main-axios.ts | 1 +
6 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/package-lock.json b/package-lock.json
index a3195012..e83da684 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -96,6 +96,7 @@
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
+ "prettier": "^3.6.2",
"ts-node": "^10.9.2",
"tw-animate-css": "^1.3.5",
"typescript": "~5.9.2",
@@ -7558,6 +7559,22 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
diff --git a/package.json b/package.json
index 81530bff..6e8b4c90 100644
--- a/package.json
+++ b/package.json
@@ -100,6 +100,7 @@
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
+ "prettier": "^3.6.2",
"ts-node": "^10.9.2",
"tw-animate-css": "^1.3.5",
"typescript": "~5.9.2",
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index d1d55c02..ccdd4d3a 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -72,6 +72,7 @@
"register": "Register",
"username": "Username",
"password": "Password",
+ "version" : "Version",
"confirmPassword": "Confirm Password",
"back": "Back",
"email": "Email",
diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx
index 291c11b2..350c8400 100644
--- a/src/components/ui/sidebar.tsx
+++ b/src/components/ui/sidebar.tsx
@@ -1,6 +1,6 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
-import { cva, VariantProps } from "class-variance-authority"
+import { cva, type VariantProps } from "class-variance-authority"
import { PanelLeftIcon } from "lucide-react"
import { useIsMobile } from "@/hooks/use-mobile"
diff --git a/src/ui/User/UserProfile.tsx b/src/ui/User/UserProfile.tsx
index 2f165472..9031620c 100644
--- a/src/ui/User/UserProfile.tsx
+++ b/src/ui/User/UserProfile.tsx
@@ -8,11 +8,13 @@ import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs.tsx
import {User, Shield, Key, AlertCircle} from "lucide-react";
import {TOTPSetup} from "@/ui/User/TOTPSetup.tsx";
import {getUserInfo} from "@/ui/main-axios.ts";
+import { getVersionInfo } from "@/ui/main-axios.ts";
import {toast} from "sonner";
import {PasswordReset} from "@/ui/User/PasswordReset.tsx";
import {useTranslation} from "react-i18next";
import {LanguageSwitcher} from "@/components/LanguageSwitcher";
+
interface UserProfileProps {
isTopbarOpen?: boolean;
}
@@ -27,11 +29,23 @@ export function UserProfile({isTopbarOpen = true}: UserProfileProps) {
} | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ const [versionInfo, setVersionInfo] = useState<{ version: string } | null>(null);
+
useEffect(() => {
fetchUserInfo();
+ fetchVersion();
}, []);
+ const fetchVersion = async () => {
+ try {
+ const info = await getVersionInfo();
+ setVersionInfo({ version: info.version });
+ } catch (err) {
+ console.error("Failed to load version info", err);
+ }
+ };
+
const fetchUserInfo = async () => {
setLoading(true);
setError(null);
@@ -146,6 +160,13 @@ export function UserProfile({isTopbarOpen = true}: UserProfileProps) {
)}
+
+
+
+ {versionInfo?.version || t('common.loading')}
+
+
+
diff --git a/src/ui/main-axios.ts b/src/ui/main-axios.ts
index 6fa29322..e9a2d97a 100644
--- a/src/ui/main-axios.ts
+++ b/src/ui/main-axios.ts
@@ -140,6 +140,7 @@ interface AuthResponse {
}
interface UserInfo {
+ totp_enabled: boolean;
id: string;
username: string;
is_admin: boolean;
--
2.49.1
From a40504b13b3c6e9b4d9d6b319afafdb3e7b4ddd0 Mon Sep 17 00:00:00 2001
From: LukeGus
Date: Mon, 8 Sep 2025 00:13:50 -0500
Subject: [PATCH 2/2] Update version checking process
---
package-lock.json | 28 +++++++++++-----------------
package.json | 1 +
src/backend/database/database.ts | 9 ++-------
src/ui/Desktop/User/UserProfile.tsx | 28 ++++++++++++++--------------
4 files changed, 28 insertions(+), 38 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e83da684..8193800a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -69,6 +69,7 @@
"react-hook-form": "^7.60.0",
"react-i18next": "^15.7.3",
"react-resizable-panels": "^3.0.3",
+ "react-simple-keyboard": "^3.8.120",
"react-xtermjs": "^1.0.10",
"sonner": "^2.0.7",
"speakeasy": "^2.0.0",
@@ -96,7 +97,6 @@
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
- "prettier": "^3.6.2",
"ts-node": "^10.9.2",
"tw-animate-css": "^1.3.5",
"typescript": "~5.9.2",
@@ -7559,22 +7559,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/prettier": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
- "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "prettier": "bin/prettier.cjs"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -7835,6 +7819,16 @@
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
}
},
+ "node_modules/react-simple-keyboard": {
+ "version": "3.8.120",
+ "resolved": "https://registry.npmjs.org/react-simple-keyboard/-/react-simple-keyboard-3.8.120.tgz",
+ "integrity": "sha512-VREEGZWXUeqRKvRVg0n8hmoAqz/TSWZEs5UwbfLuan4yKvOQZUFHtS11QGnvIVYjkThh+JYslO2CHT4Lxf5d0w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/react-style-singleton": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
diff --git a/package.json b/package.json
index 81530bff..0c4ff32c 100644
--- a/package.json
+++ b/package.json
@@ -73,6 +73,7 @@
"react-hook-form": "^7.60.0",
"react-i18next": "^15.7.3",
"react-resizable-panels": "^3.0.3",
+ "react-simple-keyboard": "^3.8.120",
"react-xtermjs": "^1.0.10",
"sonner": "^2.0.7",
"speakeasy": "^2.0.0",
diff --git a/src/backend/database/database.ts b/src/backend/database/database.ts
index a56faf1d..40466490 100644
--- a/src/backend/database/database.ts
+++ b/src/backend/database/database.ts
@@ -147,22 +147,16 @@ app.get('/health', (req, res) => {
app.get('/version', async (req, res) => {
let localVersion = process.env.VERSION;
-
- // Fallback to package.json version if env variable not set
+
if (!localVersion) {
try {
const packagePath = path.resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
localVersion = packageJson.version;
- logger.info(`Using version from package.json: ${localVersion}`);
} catch (error) {
logger.error('Failed to read version from package.json:', error);
}
}
-
- // Debug logging
- logger.debug(`Final version: ${localVersion}`);
- logger.debug(`Working directory: ${process.cwd()}`);
if (!localVersion) {
logger.error('No version information available');
@@ -186,6 +180,7 @@ app.get('/version', async (req, res) => {
const response = {
status: localVersion === remoteVersion ? 'up_to_date' : 'requires_update',
+ localVersion: localVersion,
version: remoteVersion,
latest_release: {
tag_name: releaseData.data.tag_name,
diff --git a/src/ui/Desktop/User/UserProfile.tsx b/src/ui/Desktop/User/UserProfile.tsx
index ad160950..2cc462b0 100644
--- a/src/ui/Desktop/User/UserProfile.tsx
+++ b/src/ui/Desktop/User/UserProfile.tsx
@@ -8,7 +8,7 @@ import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs.tsx
import {User, Shield, Key, AlertCircle} from "lucide-react";
import {TOTPSetup} from "@/ui/Desktop/User/TOTPSetup.tsx";
import {getUserInfo} from "@/ui/main-axios.ts";
-import { getVersionInfo } from "@/ui/main-axios.ts";
+import {getVersionInfo} from "@/ui/main-axios.ts";
import {toast} from "sonner";
import {PasswordReset} from "@/ui/Desktop/User/PasswordReset.tsx";
import {useTranslation} from "react-i18next";
@@ -38,12 +38,12 @@ export function UserProfile({isTopbarOpen = true}: UserProfileProps) {
}, []);
const fetchVersion = async () => {
- try {
- const info = await getVersionInfo();
- setVersionInfo({ version: info.version });
- } catch (err) {
- console.error("Failed to load version info", err);
- }
+ try {
+ const info = await getVersionInfo();
+ setVersionInfo({version: info.localVersion});
+ } catch (err) {
+ console.error("Failed to load version info", err);
+ }
};
const fetchUserInfo = async () => {
@@ -160,22 +160,22 @@ export function UserProfile({isTopbarOpen = true}: UserProfileProps) {
)}
-
-
-
- {versionInfo?.version || t('common.loading')}
-
+
+
+
+ {versionInfo?.version || t('common.loading')}
+
-
+
{t('profile.selectPreferredLanguage')}
-
+
--
2.49.1