From 69aed755425b8f129bc612e031ca99569614e41a Mon Sep 17 00:00:00 2001 From: Jesse <90865804+dxu104@users.noreply.github.com> Date: Thu, 19 Mar 2026 16:47:42 -0700 Subject: [PATCH 1/2] fix: resolve dashboard login hidden-state bug and rename auth routes to session - Add global [hidden] { display: none !important } to fix login screen staying visible after successful sign-in (CSS display rule was overriding hidden attr) - Rename /api/auth/* endpoints to /api/session/* for clarity - Upgrade better-sqlite3 from v11 to v12 Co-Authored-By: Claude Opus 4.6 (1M context) --- package-lock.json | 173 +++++++++++++++++++++++++++++++++++++- package.json | 2 +- src/public/app.js | 4 +- src/public/styles.css | 4 + src/routes/auth-routes.js | 4 +- 5 files changed, 178 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb2bc8e..1204179 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@modelcontextprotocol/sdk": "^1.0.0", "bcryptjs": "^2.4.3", "better-auth": "^1.5.5", - "better-sqlite3": "^11.0.0", + "better-sqlite3": "^12.0.0", "cors": "^2.8.6", "dotenv": "^17.3.1", "express": "^4.21.0", @@ -989,6 +989,16 @@ "node": ">= 0.6" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@noble/ciphers": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.1.1.tgz", @@ -1092,6 +1102,23 @@ "undici-types": "~7.18.0" } }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1311,14 +1338,17 @@ } }, "node_modules/better-sqlite3": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", - "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", + "version": "12.8.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.8.0.tgz", + "integrity": "sha512-RxD2Vd96sQDjQr20kdP+F+dK/1OUNiVOl200vKBZY8u0vTwysfolF6Hq+3ZK2+h8My9YvZhHsF+RSGZW2VYrPQ==", "hasInstallScript": true, "license": "MIT", "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" + }, + "engines": { + "node": "20.x || 22.x || 23.x || 24.x || 25.x" } }, "node_modules/bindings": { @@ -1401,6 +1431,16 @@ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "license": "MIT" }, + "node_modules/bson": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.2.0.tgz", + "integrity": "sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=20.19.0" + } + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -2355,6 +2395,13 @@ "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT", + "peer": true + }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -2466,6 +2513,67 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, + "node_modules/mongodb": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.1.0.tgz", + "integrity": "sha512-kMfnKunbolQYwCIyrkxNJFB4Ypy91pYqua5NargS/f8ODNSJxT03ZU3n1JqL4mCzbSih8tvmMEMLpKTT7x5gCg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.1.1", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.1.tgz", + "integrity": "sha512-h0AZ9A7IDVwwHyMxmdMXKy+9oNlF0zFoahHiX3vQ8e3KFcSP3VmsmfvtRSuLPxmyv2vjIDxqty8smTgie/SNRQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2768,6 +2876,16 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.14.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", @@ -3257,6 +3375,16 @@ "simple-concat": "^1.0.0" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -3389,6 +3517,19 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "peer": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -3478,6 +3619,30 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 1d0d37b..046da2e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@modelcontextprotocol/sdk": "^1.0.0", "bcryptjs": "^2.4.3", "better-auth": "^1.5.5", - "better-sqlite3": "^11.0.0", + "better-sqlite3": "^12.0.0", "cors": "^2.8.6", "dotenv": "^17.3.1", "express": "^4.21.0", diff --git a/src/public/app.js b/src/public/app.js index 140cccf..fb2a077 100644 --- a/src/public/app.js +++ b/src/public/app.js @@ -4,7 +4,7 @@ let currentDocId = null; // Init document.addEventListener('DOMContentLoaded', async () => { - const res = await fetch('/api/auth/check'); + const res = await fetch('/api/session/check'); const data = await res.json(); if (data.authenticated) { showApp(); @@ -309,7 +309,7 @@ document.getElementById('password-form').addEventListener('submit', async (e) => e.preventDefault(); const current = document.getElementById('current-password').value; const newPassword = document.getElementById('new-password').value; - const res = await fetch('/api/auth/password', { + const res = await fetch('/api/session/password', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ current: current, newPassword: newPassword }), diff --git a/src/public/styles.css b/src/public/styles.css index d8a39b2..e42b550 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -5,6 +5,10 @@ padding: 0; } +[hidden] { + display: none !important; +} + body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0d1117; diff --git a/src/routes/auth-routes.js b/src/routes/auth-routes.js index 43d474f..dfd5a82 100644 --- a/src/routes/auth-routes.js +++ b/src/routes/auth-routes.js @@ -5,9 +5,9 @@ const router = Router(); router.post('/api/login', loginHandler); router.post('/api/logout', logoutHandler); -router.get('/api/auth/check', checkAuthHandler); +router.get('/api/session/check', checkAuthHandler); -router.put('/api/auth/password', authMiddleware, (req, res) => { +router.put('/api/session/password', authMiddleware, (req, res) => { const { current, newPassword } = req.body || {}; if (!current || !newPassword) { return res.status(400).json({ error: 'Both current and newPassword are required' }); From ed2a8dcef8c95ff985ba5f23e3541277d29c3c4e Mon Sep 17 00:00:00 2001 From: Jesse <90865804+dxu104@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:15:33 -0700 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20address=20PR=20review=20=E2=80=94=20?= =?UTF-8?q?unify=20routes=20under=20/api/session,=20bump=20node=20engine,?= =?UTF-8?q?=20rename=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump engines.node to >=20.0.0 to match better-sqlite3@12 requirement - Move /api/login and /api/logout to /api/session/login and /api/session/logout for consistent API surface with /api/session/check and /api/session/password - Rename auth-routes.js to session-routes.js to match route namespace - Update frontend fetch paths in app.js accordingly Co-Authored-By: Claude Opus 4.6 (1M context) --- package.json | 2 +- src/public/app.js | 4 ++-- src/routes/{auth-routes.js => session-routes.js} | 4 ++-- src/server.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/routes/{auth-routes.js => session-routes.js} (87%) diff --git a/package.json b/package.json index 046da2e..6c0a8f4 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "main": "./src/index.js", "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "dependencies": { "@huggingface/transformers": "^3.8.1", diff --git a/src/public/app.js b/src/public/app.js index fb2a077..c596991 100644 --- a/src/public/app.js +++ b/src/public/app.js @@ -29,7 +29,7 @@ function showApp() { document.getElementById('login-form').addEventListener('submit', async (e) => { e.preventDefault(); const password = document.getElementById('login-password').value; - const res = await fetch('/api/login', { + const res = await fetch('/api/session/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password }), @@ -63,7 +63,7 @@ function showSection(name) { // Logout document.getElementById('logout-btn').addEventListener('click', async () => { - await fetch('/api/logout', { method: 'POST' }); + await fetch('/api/session/logout', { method: 'POST' }); showLogin(); }); diff --git a/src/routes/auth-routes.js b/src/routes/session-routes.js similarity index 87% rename from src/routes/auth-routes.js rename to src/routes/session-routes.js index dfd5a82..165195b 100644 --- a/src/routes/auth-routes.js +++ b/src/routes/session-routes.js @@ -3,8 +3,8 @@ import { loginHandler, logoutHandler, checkAuthHandler, authMiddleware, checkPas const router = Router(); -router.post('/api/login', loginHandler); -router.post('/api/logout', logoutHandler); +router.post('/api/session/login', loginHandler); +router.post('/api/session/logout', logoutHandler); router.get('/api/session/check', checkAuthHandler); router.put('/api/session/password', authMiddleware, (req, res) => { diff --git a/src/server.js b/src/server.js index 9e2c0ac..b83c2d4 100644 --- a/src/server.js +++ b/src/server.js @@ -9,7 +9,7 @@ import { hasPassword, setPassword, promptPassword, authMiddleware } from './auth import { getDocumentCount } from './db.js'; import { ingestDirectory } from './ingest.js'; import cors from 'cors'; -import authRoutes from './routes/auth-routes.js'; +import authRoutes from './routes/session-routes.js'; import apiRoutes from './routes/api.js'; import { toNodeHandler } from 'better-auth/node'; import { auth } from './auth-oauth.js';