diff --git a/lib/auth-secret.js b/lib/auth-secret.js new file mode 100644 index 0000000..2916283 --- /dev/null +++ b/lib/auth-secret.js @@ -0,0 +1,12 @@ +const JWT_SECRET = process.env.JWT_SECRET; + +if (!JWT_SECRET) { + throw new Error( + 'JWT_SECRET environment variable is not set. ' + + 'Set it in .env.local for local dev, or in the Vercel project settings for deploys. ' + + 'Generate a strong secret with: openssl rand -hex 32' + ); +} + +export { JWT_SECRET }; +export const JWT_TOKEN_TTL = '24h'; diff --git a/lib/permission-middleware.js b/lib/permission-middleware.js index 53e1cad..49bd3d0 100644 --- a/lib/permission-middleware.js +++ b/lib/permission-middleware.js @@ -1,7 +1,6 @@ import { sql } from '@vercel/postgres'; import jwt from 'jsonwebtoken'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +import { JWT_SECRET } from './auth-secret.js'; /** * Get user ID from request headers diff --git a/pages/api/auth-utils.js b/pages/api/auth-utils.js index b9169f4..3a92321 100644 --- a/pages/api/auth-utils.js +++ b/pages/api/auth-utils.js @@ -1,7 +1,6 @@ import jwt from 'jsonwebtoken'; import { db } from '../../lib/database.js'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key'; +import { JWT_SECRET, JWT_TOKEN_TTL } from '../../lib/auth-secret.js'; export async function hashPassword(password) { const bcrypt = await import('bcryptjs'); @@ -21,7 +20,7 @@ export function generateToken(user) { role: user.role }, JWT_SECRET, - { expiresIn: '7d' } + { expiresIn: JWT_TOKEN_TTL } ); } diff --git a/pages/api/auth/login.js b/pages/api/auth/login.js index ac2ec71..fd135c8 100644 --- a/pages/api/auth/login.js +++ b/pages/api/auth/login.js @@ -1,8 +1,6 @@ import bcrypt from 'bcryptjs'; -import jwt from 'jsonwebtoken'; import { sql } from '@vercel/postgres'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +import { generateToken } from '../auth-utils.js'; export default async function handler(req, res) { // Set CORS headers @@ -48,11 +46,7 @@ export default async function handler(req, res) { } // Generate JWT token - const token = jwt.sign( - { userId: user.id, email: user.email, role: user.role }, - JWT_SECRET, - { expiresIn: '24h' } - ); + const token = generateToken({ id: user.id, email: user.email, role: user.role }); // Return user data (without password) and token const { password: _, ...userWithoutPassword } = user; diff --git a/pages/api/auth/register.js b/pages/api/auth/register.js index ea25ec4..44bb475 100644 --- a/pages/api/auth/register.js +++ b/pages/api/auth/register.js @@ -1,9 +1,7 @@ import bcrypt from 'bcryptjs'; -import jwt from 'jsonwebtoken'; import { sql } from '@vercel/postgres'; import { generateUniqueSlug } from '../../../lib/slug-utils.js'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +import { generateToken } from '../auth-utils.js'; export default async function handler(req, res) { // Set CORS headers @@ -140,11 +138,7 @@ export default async function handler(req, res) { } // Generate JWT token - const token = jwt.sign( - { userId: user.id, email: user.email, role: user.role }, - JWT_SECRET, - { expiresIn: '24h' } - ); + const token = generateToken({ id: user.id, email: user.email, role: user.role }); // Return user data without password const userResponse = { diff --git a/pages/api/auth/verify.js b/pages/api/auth/verify.js index 174c6b7..7d9675d 100644 --- a/pages/api/auth/verify.js +++ b/pages/api/auth/verify.js @@ -1,7 +1,6 @@ import { sql } from '@vercel/postgres'; import jwt from 'jsonwebtoken'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +import { JWT_SECRET } from '../../../lib/auth-secret.js'; export default async function handler(req, res) { // Set CORS headers diff --git a/pages/api/favorites.js b/pages/api/favorites.js index 5f9eec2..f6db406 100644 --- a/pages/api/favorites.js +++ b/pages/api/favorites.js @@ -1,7 +1,6 @@ import { sql } from '@vercel/postgres'; import jwt from 'jsonwebtoken'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +import { JWT_SECRET } from '../../lib/auth-secret.js'; export default async function handler(req, res) { // Set CORS headers diff --git a/pages/api/users/search.js b/pages/api/users/search.js index 72ede3f..d80d6be 100644 --- a/pages/api/users/search.js +++ b/pages/api/users/search.js @@ -1,7 +1,6 @@ import { sql } from '@vercel/postgres'; import jwt from 'jsonwebtoken'; - -const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +import { JWT_SECRET } from '../../../lib/auth-secret.js'; export default async function handler(req, res) { // Set CORS headers