From dfa857c131479385aeb5aa0c36b727055aef0c82 Mon Sep 17 00:00:00 2001 From: Joshua Ryder Date: Thu, 2 Oct 2025 16:25:31 -0400 Subject: [PATCH] encryption --- README.md | 8 +++++--- package.json | 2 ++ server/api/auth/login.post.ts | 13 ++++++++++++- server/utils/database.ts | 9 ++++++--- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d3bd072..28edb53 100644 --- a/README.md +++ b/README.md @@ -172,13 +172,15 @@ The application uses SQLite with the following schema: ⚠️ **For Production Use**: -1. Change the default admin credentials -2. Implement proper password hashing (bcrypt, argon2, etc.) -3. Use a strong `AUTH_SECRET` in environment variables +1. Change the default admin credentials in your `.env` file +2. ✅ Password hashing is implemented using bcrypt +3. Use a strong `AUTH_SECRET` in environment variables (generate with `openssl rand -hex 32`) 4. Enable HTTPS 5. Consider implementing rate limiting 6. Add CSRF protection +**Note**: Passwords are now securely hashed using bcrypt with 10 salt rounds before being stored in the database. + ## Docker Commands ```bash diff --git a/package.json b/package.json index 83eefa8..704e957 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "postinstall": "nuxt prepare" }, "dependencies": { + "bcrypt": "^5.1.1", "better-sqlite3": "^11.3.0", "nuxt": "^3.13.2", "qrcode": "^1.5.4", @@ -19,6 +20,7 @@ }, "devDependencies": { "@nuxtjs/tailwindcss": "^6.12.1", + "@types/bcrypt": "^5.0.2", "@types/better-sqlite3": "^7.6.11", "@types/qrcode": "^1.5.5" } diff --git a/server/api/auth/login.post.ts b/server/api/auth/login.post.ts index 9e2d177..d46467f 100644 --- a/server/api/auth/login.post.ts +++ b/server/api/auth/login.post.ts @@ -1,5 +1,6 @@ import { getUserByUsername } from '~/server/utils/database' import { setAuthCookie } from '~/server/utils/auth' +import bcrypt from 'bcrypt' export default defineEventHandler(async (event) => { const body = await readBody(event) @@ -14,7 +15,17 @@ export default defineEventHandler(async (event) => { const user = getUserByUsername(username.toLowerCase()) - if (!user || user.password !== password) { + if (!user) { + throw createError({ + statusCode: 401, + message: 'Invalid credentials' + }) + } + + // Compare the provided password with the hashed password in the database + const passwordMatch = await bcrypt.compare(password, user.password) + + if (!passwordMatch) { throw createError({ statusCode: 401, message: 'Invalid credentials' diff --git a/server/utils/database.ts b/server/utils/database.ts index 090afed..2c75936 100644 --- a/server/utils/database.ts +++ b/server/utils/database.ts @@ -1,5 +1,6 @@ import Database from 'better-sqlite3' import { join } from 'path' +import bcrypt from 'bcrypt' let db: Database.Database | null = null @@ -52,15 +53,17 @@ export function getDatabase() { ) `) - // Insert default admin user from environment variables - // In production, this should be hashed properly + // Insert default admin user from environment variables with hashed password const config = useRuntimeConfig() const adminUsername = config.adminUsername const adminPassword = config.adminPassword const userExists = db.prepare('SELECT COUNT(*) as count FROM users WHERE username = ?').get(adminUsername) as { count: number } if (userExists.count === 0) { - db.prepare('INSERT INTO users (username, password) VALUES (?, ?)').run(adminUsername, adminPassword) + // Hash the password before storing + const saltRounds = 10 + const hashedPassword = bcrypt.hashSync(adminPassword, saltRounds) + db.prepare('INSERT INTO users (username, password) VALUES (?, ?)').run(adminUsername, hashedPassword) } }