diff --git a/backend/mobile/mobileAuth.route.ts b/backend/mobile/mobileAuth.route.ts
index 017443b..76da6f8 100644
--- a/backend/mobile/mobileAuth.route.ts
+++ b/backend/mobile/mobileAuth.route.ts
@@ -263,6 +263,10 @@ r.patch("/user/:id", requireAuth, async (req, res) => {
updates.active = req.body.active;
}
+ if (req.body?.excludedCommand !== undefined) {
+ updates.excludedCommand = req.body.excludedCommand;
+ }
+
if (req.body?.role !== undefined) {
updates.role = req.body.role;
}
diff --git a/lstMobile/app.json b/lstMobile/app.json
index 42d4d41..d1a0261 100644
--- a/lstMobile/app.json
+++ b/lstMobile/app.json
@@ -15,8 +15,8 @@
"foregroundImage": "./assets/adaptive-icon-white.png",
"backgroundColor": "#ffffff"
},
- "versionCode": 24,
- "minSupportedVersionCode": 21,
+ "versionCode": 30,
+ "minSupportedVersionCode": 26,
"predictiveBackGestureEnabled": false,
"package": "net.alpla.lst.mobile"
},
diff --git a/lstMobile/src/app/(tabs)/_layout.tsx b/lstMobile/src/app/(tabs)/_layout.tsx
index bcdeb4f..98eca0b 100644
--- a/lstMobile/src/app/(tabs)/_layout.tsx
+++ b/lstMobile/src/app/(tabs)/_layout.tsx
@@ -15,9 +15,11 @@ export default function TabsLayout() {
const isUnlocked = useMobileAuthStore((s) => s.isUnlocked);
const port = parseInt(serverPort || "0", 10) >= 50000;
-
- if (!user || (!isUnlocked && !port)) {
- return ;
+ console.log(port);
+ if (!port) {
+ if (!user || !isUnlocked) {
+ return ;
+ }
}
const isNormalScanner = parseInt(serverPort || "0", 10) >= 50000;
diff --git a/lstMobile/src/app/login.tsx b/lstMobile/src/app/login.tsx
index a4dd642..4890f35 100644
--- a/lstMobile/src/app/login.tsx
+++ b/lstMobile/src/app/login.tsx
@@ -2,7 +2,7 @@ import axios from "axios";
import { useRouter } from "expo-router";
import { useState } from "react";
-import { Button, Text, View } from "react-native";
+import { Alert, Button, Text, View } from "react-native";
import { Input } from "../components/ui/input";
import { useAppStore } from "../hooks/useAppStore";
import { useMobileAuthStore } from "../hooks/useMobileAuth";
@@ -38,6 +38,7 @@ export default function Login() {
}
} catch (error) {
console.log(error);
+ Alert.alert("Login Error", `Invalid pin please try again`);
}
};
@@ -70,7 +71,7 @@ export default function Login() {
-
+
Warning: If you are logged into another scanner you will encounter
scan errors, please do not try to log into more than 1 scanner at a
time.
diff --git a/lstMobile/src/app/setup.tsx b/lstMobile/src/app/setup.tsx
index 7c672cb..8f081ca 100644
--- a/lstMobile/src/app/setup.tsx
+++ b/lstMobile/src/app/setup.tsx
@@ -25,6 +25,8 @@ export default function Setup() {
const server = useServerStore((s) => s.serverVersion);
+ // TODO: if on lst version and the user is manager or admin just login
+
const authCheck = () => {
if (pin === "6971") {
setAuth(true);
diff --git a/lstMobile/src/components/LSTScanner.tsx b/lstMobile/src/components/LSTScanner.tsx
index c621ab0..0c3d981 100644
--- a/lstMobile/src/components/LSTScanner.tsx
+++ b/lstMobile/src/components/LSTScanner.tsx
@@ -7,6 +7,7 @@ import { useMobileAuthStore } from "../hooks/useMobileAuth";
import { useScannerStore } from "../hooks/useScannerStore";
import { scannerFeedback } from "../lib/feedbackScan";
import { sendTcpMessage } from "../lib/tcpScan";
+import { versionCheck } from "../lib/versionValidation";
import { type ZebraScanResult, zebraScanner } from "../lib/ZebraScanner";
import { ScannedLabelBox } from "./ScannedLabels";
import { GlobalFooter } from "./UpdateFooter";
@@ -45,10 +46,15 @@ export default function LSTScanner() {
scan.data.toLowerCase().includes(cmd.toLowerCase()),
);
+ console.log(user?.excludedCommand);
+
if (isAlphaStart && isExcluded) {
Alert.alert(
- `Command: ${scan.data} is not allowed to be used, please contact logistics if this is an error`,
+ "Command not allowed",
+ `Command: ${scan.data}\n\nPlease contact logistics if this is an error`,
);
+
+ return;
}
let commandToSend = `${STX}${user?.scannerId}@${scan.data}${ETX}`;
@@ -68,16 +74,24 @@ export default function LSTScanner() {
const scanned = (await sendTcpMessage(
commandToSend,
serverIp,
- parseInt(serverPort || "0", 10),
+ 50004,
)) as any;
+
// send the logs to lst but allow it to time out if it dose not exist just bc.
- const logInfo = { ...scanned, user: user?.name };
try {
- await axios.post(
- `http://${serverIp.trim()}:3000/lst/api/mobile/logs`,
- logInfo,
- );
+ await axios.post(`http://${serverIp.trim()}:3000/lst/api/mobile/logs`, {
+ scannerId: user?.scannerId ?? "0",
+ message: scanned.data.message,
+ prompt: scanned.data.prompt,
+ commandDescription: scanned.data.commandDescription,
+ status: scanned.data.status,
+ lines: scanned.data.lines,
+ user: user?.name ?? "prodScan",
+ runningNumber: scan.data.startsWith("000")
+ ? parseInt(scan.data.slice(10, -1) || "000", 10).toString()
+ : "0",
+ });
} catch (error) {
console.log(error);
}
@@ -90,7 +104,15 @@ export default function LSTScanner() {
vibrate: true,
led: true,
});
+
setBGColor("bg-green-500");
+
+ // version check
+ versionCheck();
+
+ // auth update
+ useMobileAuthStore.getState().updateLastScan();
+
setTimeout(() => {
setBGColor(null);
}, 1 * 1000);
@@ -117,7 +139,6 @@ export default function LSTScanner() {
},
[
serverIp,
- serverPort,
setLastScan,
user?.scannerId,
user?.name,
diff --git a/lstMobile/src/components/ProdScanner.tsx b/lstMobile/src/components/ProdScanner.tsx
index f3ba186..d56fcc4 100644
--- a/lstMobile/src/components/ProdScanner.tsx
+++ b/lstMobile/src/components/ProdScanner.tsx
@@ -3,9 +3,11 @@ import { format } from "date-fns-tz";
import { useCallback, useEffect, useState } from "react";
import { Text, View } from "react-native";
import { useAppStore } from "../hooks/useAppStore";
+import { useMobileAuthStore } from "../hooks/useMobileAuth";
import { useScannerStore } from "../hooks/useScannerStore";
import { scannerFeedback } from "../lib/feedbackScan";
import { sendTcpMessage } from "../lib/tcpScan";
+import { versionCheck } from "../lib/versionValidation";
import { type ZebraScanResult, zebraScanner } from "../lib/ZebraScanner";
import { ScannedLabelBox } from "./ScannedLabels";
import { GlobalFooter } from "./UpdateFooter";
@@ -52,11 +54,16 @@ export default function ProdScanner() {
parseInt(serverPort || "0", 10),
)) as any;
// send the logs to lst but allow it to time out if it dose not exist just bc.
-
+ const data = {
+ ...scanned.data,
+ runningNumber: scan.data.startsWith("000")
+ ? parseInt(scan.data.slice(10, -1) || "000", 10).toString()
+ : "0",
+ };
try {
await axios.post(
`http://${serverIp.trim()}:3000/lst/api/mobile/logs`,
- scanned,
+ data,
);
} catch (error) {
console.log(error);
@@ -71,6 +78,13 @@ export default function ProdScanner() {
led: true,
});
setBGColor("bg-green-500");
+
+ // version check
+ versionCheck();
+
+ // auth update
+ useMobileAuthStore.getState().updateLastScan();
+
setTimeout(() => {
setBGColor(null);
}, 1 * 1000);
diff --git a/lstMobile/src/hooks/useAppStartup.tsx b/lstMobile/src/hooks/useAppStartup.tsx
index 1d7a50b..b509ab0 100644
--- a/lstMobile/src/hooks/useAppStartup.tsx
+++ b/lstMobile/src/hooks/useAppStartup.tsx
@@ -2,6 +2,7 @@ import axios from "axios";
import Constants from "expo-constants";
import { useEffect, useRef, useState } from "react";
import { devDelay } from "../lib/devMode";
+import { versionCheck } from "../lib/versionValidation";
import { useAppStore } from "./useAppStore";
import { useServerStore } from "./useServerCheck";
@@ -24,7 +25,6 @@ export function useAppStartup() {
const hasHydrated = useAppStore((s) => s.hasHydrated);
const serverPort = useAppStore((s) => s.serverPort);
const serverIp = useAppStore((s) => s.serverIp);
- const setServerVersion = useServerStore((s) => s.setServerVersion);
useEffect(() => {
if (!hasHydrated) {
@@ -62,29 +62,7 @@ export function useAppStartup() {
return;
}
- const port =
- parseInt(serverPort || "0", 10) >= 50000 ? "3000" : serverPort;
-
- try {
- const res = await axios.get(
- `http://${serverIp}:${port}/lst/api/mobile/version`,
- { timeout: 5000 },
- );
-
- if (res.status === 200) {
- setServerVersion(res.data);
- }
-
- const build = Constants.expoConfig?.android?.versionCode ?? 1;
-
- if (build < res.data.minSupportedVersionCode) {
- setStartupRoute("/updateScreen");
- setReady(true);
- return;
- }
- } catch (error) {
- console.log("Version check error:", error);
- }
+ await versionCheck();
setStatus("scannerMode");
await devDelay(1500);
@@ -123,7 +101,7 @@ export function useAppStartup() {
return () => {
cancelled = true;
};
- }, [hasHydrated, serverIp, serverPort, setServerVersion]);
+ }, [hasHydrated, serverIp, serverPort]);
return {
ready,
diff --git a/lstMobile/src/hooks/useMobileAuth.ts b/lstMobile/src/hooks/useMobileAuth.ts
index 8652f08..a5f8961 100644
--- a/lstMobile/src/hooks/useMobileAuth.ts
+++ b/lstMobile/src/hooks/useMobileAuth.ts
@@ -1,5 +1,7 @@
import { create } from "zustand";
+const ONE_HOUR = 1000 * 60 * 60;
+
type MobileUser = {
id: string;
name: string;
@@ -11,19 +13,40 @@ type MobileUser = {
type AuthState = {
user: MobileUser | null;
isUnlocked: boolean;
+ lastScanAt: number | null;
setUser: (user: MobileUser) => void;
+ updateLastScan: () => void;
lock: () => void;
logout: () => void;
+ shouldLockForIdle: () => boolean;
};
-export const useMobileAuthStore = create((set) => ({
+export const useMobileAuthStore = create((set, get) => ({
user: null,
isUnlocked: false,
+ lastScanAt: null,
- setUser: (user) => set({ user, isUnlocked: true }),
-
+ setUser: (user) =>
+ set({
+ user,
+ isUnlocked: true,
+ lastScanAt: Date.now(),
+ }),
+ updateLastScan: () => set({ lastScanAt: Date.now() }),
lock: () => set({ isUnlocked: false }),
- logout: () => set({ user: null, isUnlocked: false }),
+ logout: () =>
+ set({
+ user: null,
+ isUnlocked: false,
+ lastScanAt: null,
+ }),
+ shouldLockForIdle: () => {
+ const lastScanAt = get().lastScanAt;
+
+ if (!lastScanAt) return true;
+
+ return Date.now() - lastScanAt > ONE_HOUR;
+ },
}));