import postgres from 'npm:postgres@3.4.4'; import bcrypt from 'npm:bcryptjs@2.4.3'; import jwt from 'npm:jsonwebtoken@9.0.2'; function getDb() { return postgres({ host: Deno.env.get('PG_HOST'), port: parseInt(Deno.env.get('PG_PORT') || '5432'), user: Deno.env.get('PG_USER'), password: Deno.env.get('PG_PASSWORD'), database: Deno.env.get('PG_DBNAME'), ssl: false, max: 1, }); } Deno.serve(async (req) => { const sql = getDb(); try { // Ensure users table exists await sql` CREATE TABLE IF NOT EXISTS app_users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(255) NOT NULL DEFAULT '', role VARCHAR(50) NOT NULL DEFAULT 'user', created_at TIMESTAMP DEFAULT NOW() ) `; // Seed default admin if no users exist const countResult = await sql`SELECT COUNT(*) as cnt FROM app_users`; if (parseInt(countResult[0].cnt) === 0) { const hash = await bcrypt.hash('admin123', 10); await sql` INSERT INTO app_users (email, password_hash, full_name, role) VALUES ('admin@admin.com', ${hash}, 'Administrátor', 'admin') `; } const body = await req.json(); const { email, password } = body; if (!email || !password) { await sql.end(); return Response.json({ error: 'Email a heslo sú povinné' }, { status: 400 }); } const users = await sql`SELECT * FROM app_users WHERE email = ${email}`; if (users.length === 0) { await sql.end(); return Response.json({ error: 'Nesprávny email alebo heslo' }, { status: 401 }); } const user = users[0]; const valid = await bcrypt.compare(password, user.password_hash); if (!valid) { await sql.end(); return Response.json({ error: 'Nesprávny email alebo heslo' }, { status: 401 }); } const token = jwt.sign( { id: user.id, email: user.email, full_name: user.full_name, role: user.role }, Deno.env.get('JWT_SECRET'), { expiresIn: '24h' } ); await sql.end(); return Response.json({ token, user: { id: user.id, email: user.email, full_name: user.full_name, role: user.role } }); } catch (error) { await sql.end(); return Response.json({ error: error.message }, { status: 500 }); } });