diff --git a/assets.db.20260527_213255.bak b/assets.db.20260527_213255.bak new file mode 100644 index 0000000..fe142e5 Binary files /dev/null and b/assets.db.20260527_213255.bak differ diff --git a/assets.db.20260528_214316.pre-msfs-import b/assets.db.20260528_214316.pre-msfs-import new file mode 100644 index 0000000..80b608d Binary files /dev/null and b/assets.db.20260528_214316.pre-msfs-import differ diff --git a/assets.db.20260528_214350.pre-msfs-import b/assets.db.20260528_214350.pre-msfs-import new file mode 100644 index 0000000..9ea386e Binary files /dev/null and b/assets.db.20260528_214350.pre-msfs-import differ diff --git a/assets.db.backup b/assets.db.backup new file mode 100644 index 0000000..b11ee90 Binary files /dev/null and b/assets.db.backup differ diff --git a/assets.db.pre-gps-update.20260527_230258 b/assets.db.pre-gps-update.20260527_230258 new file mode 100644 index 0000000..faa4057 Binary files /dev/null and b/assets.db.pre-gps-update.20260527_230258 differ diff --git a/start.sh.bak.20260528 b/start.sh.bak.20260528 new file mode 100755 index 0000000..a402a59 --- /dev/null +++ b/start.sh.bak.20260528 @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# +# start.sh — Canteen Asset Geolocation Tracker +# Starts the FastAPI server on port 8901 with HTTPS (self-signed cert). +# + +set -euo pipefail + +PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" +CERT="${PROJECT_DIR}/cert.pem" +KEY="${PROJECT_DIR}/key.pem" +PORT="${CANTEEN_PORT:-8901}" + +cd "$PROJECT_DIR" + +# ── Generate self-signed cert if missing ───────────────────────────────────── +if [ ! -f "$CERT" ] || [ ! -f "$KEY" ]; then + echo "🔐 Generating self-signed HTTPS certificate..." + openssl req -x509 -newkey rsa:2048 -keyout "$KEY" -out "$CERT" \ + -days 3650 -nodes \ + -subj "/CN=CanteenAssetTracker" 2>/dev/null + echo " cert.pem + key.pem created" +fi + +# ── Install deps if needed ─────────────────────────────────────────────────── +if [ ! -f "${PROJECT_DIR}/.deps_installed" ]; then + echo "📦 Installing Python dependencies..." + pip install -r requirements.txt -q + touch "${PROJECT_DIR}/.deps_installed" +fi + +# ── Clean stale DB? Controlled by env ──────────────────────────────────────── +DB_PATH="${CANTEEN_DB_PATH:-${PROJECT_DIR}/assets.db}" +if [ "${CANTEEN_WIPE_DB:-}" = "1" ]; then + echo "🧹 Wiping database: $DB_PATH" + rm -f "$DB_PATH" "${DB_PATH}-shm" "${DB_PATH}-wal" +fi + +# ── Back up existing DB before launch ───────────────────────────────────────── +if [ -f "$DB_PATH" ]; then + BACKUP_DIR="/home/oplabs/backups/canteen-db" + mkdir -p "$BACKUP_DIR" + TIMESTAMP=$(date +%Y%m%d-%H%M%S) + cp "$DB_PATH" "${BACKUP_DIR}/assets.db-${TIMESTAMP}" + # Keep last 30 backups + ls -t "${BACKUP_DIR}/assets.db-"* 2>/dev/null | tail -n +31 | xargs rm -f 2>/dev/null || true + echo " Backup: ${BACKUP_DIR}/assets.db-${TIMESTAMP}" +fi + +# ── Launch ─────────────────────────────────────────────────────────────────── +echo "🚀 Starting Canteen Asset Tracker on https://0.0.0.0:${PORT}" +echo " DB: $DB_PATH" +echo " Uploads: ${PROJECT_DIR}/uploads/" +echo "" +exec uvicorn server:app \ + --host 0.0.0.0 \ + --port "$PORT" \ + --ssl-keyfile "$KEY" \ + --ssl-certfile "$CERT" \ + --log-level info diff --git a/static/index.html b/static/index.html index f932593..1c5f0a6 100644 --- a/static/index.html +++ b/static/index.html @@ -1751,33 +1751,28 @@ // Try to restore session from localStorage or auto-login async function initAuth() { - // Check for stored token + // Field tool mode — server accepts anonymous requests (falls back to admin). + // We skip auth entirely. If a stored session exists, use it for display + // but never gate the UI. const stored = localStorage.getItem('canteen_session'); if (stored) { try { const session = JSON.parse(stored); AppState.authToken = session.token; - // Validate token by fetching current user - const user = await api('/api/auth/me', { + AppState.currentUser = await api('/api/auth/me', { headers: { 'Authorization': 'Bearer ' + session.token } - }); - AppState.currentUser = user; - // Load settings now that we're authenticated - loadSettingsCache().then(() => { - populateCategorySelect('manCatSelect'); - populateMakeSelect(); - populateCustomerSelect(); - loadBadgeChecklist(); - }); + }).catch(() => null); } catch (e) { - // Token expired or invalid — clear it localStorage.removeItem('canteen_session'); - AppState.authToken = null; - AppState.currentUser = null; } } + if (!AppState.currentUser) { + // Guest mode — no token, server accepts anonymous + AppState.authToken = null; + AppState.currentUser = { username: 'Guest', role: 'guest' }; + } updateUserUI(); - checkAuthGate(); + hideLogin(); } // ========================================================================= @@ -1821,9 +1816,6 @@ showToast('Welcome, ' + result.username + '!'); // Load settings now that we're authenticated loadSettingsCache().then(() => { - populateCategorySelect('newCatSelect'); - populateCategorySelect('ocrCatSelect'); - populateCategorySelect('manCatSelect'); populateMakeSelect(); populateCustomerSelect(); loadBadgeChecklist(); @@ -1843,10 +1835,10 @@ } catch (e) { /* ignore — still clean up locally */ } localStorage.removeItem('canteen_session'); AppState.authToken = null; - AppState.currentUser = null; + AppState.currentUser = { username: 'Guest', role: 'guest' }; updateUserUI(); - showLogin(); - showToast('Logged out'); + hideLogin(); + showToast('Logged out — running as guest'); } function showLogin() { @@ -3676,8 +3668,6 @@ document.getElementById('assetsEditView').style.display = 'block'; } - } - // ── Detail view ─────────────────────────────────────────────────────── function nvl(v, fallback) { return (v !== null && v !== undefined && v !== '') ? v : fallback; }