This commit is contained in:
2026-05-07 23:18:34 +02:00
commit 07c58f23ab
39 changed files with 6044 additions and 0 deletions

79
backend/routes/auth.js Normal file
View File

@@ -0,0 +1,79 @@
import bcrypt from 'bcrypt'
import jwt from 'jsonwebtoken'
import { prisma } from '../prisma.js'
export const login = async (req, res) => {
// Get data
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: 'All fields are required' })
}
// Check data is correct
const user = await prisma.user.findFirst({ where: { email } });
if (!user || !await bcrypt.compare(password, user.password)) {
return res.status(400).json({ error: 'Invalid credentials' })
}
// Generate JWT
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '7d' })
// Return
res.status(200).json({
id: user.id,
username: user.username,
email: user.email,
token
})
}
export const register = async (req, res) => {
// Get data
const {username, email, password } = req.body
// Check is not empty
if (!username || !email || !password) {
return res.status(400).json({ error: 'All fields are required' })
}
// Validate data
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (username.length < 3 ||username.length > 14) { return res.status(400).json({ error: 'Username must be between 3 and 14 characters' })}
if (email.length > 30 || !emailRegex.test(email)) { return res.status(400).json({ error: 'Email is not valid' })}
if (password.length < 6 || password.length > 32) { return res.status(400).json({ error: 'Password must be between 6 and 32 characters' })}
// Check email and username doesnt exists
const userExists = await prisma.user.findFirst({
where: {
OR: [ { email }, { username } ]
}
});
// If username or email exists, send error
if (userExists) {
return res.status(409).json({
error: 'User already exists'
})
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10)
// Create user
const user = await prisma.user.create({
data: { username, email, password: hashedPassword, type: "candidato" }
})
// Generates token
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '7d' })
// Return user
res.status(201).json({ id: user.id, username: user.username, email: user.email, token })
}

39
backend/routes/offer.js Normal file
View File

@@ -0,0 +1,39 @@
import { prisma } from '../prisma.js'
export const createOffer = async (req, res) => {
const { titulo, empresa, ubicacion, salario, contrato, descripcion } = req.body;
const authorId = req.user.id
if (!titulo || !empresa || !ubicacion || !salario || !contrato || !descripcion) return res.status(400).json({ error: ""})
try {
const offer = await prisma.oferta.create({
data: {
titulo, empresa, ubicacion, salario, descripcion
}
})
res.status(201).json(offer)
} catch (err) {
res.status(400).json({ error: "Ha ocurrido un error al crear la oferta de trabajo." })
}
}
export const deleteOffer = async (req, res) => {
const { offerId } = req.params;
const authorId = req.user.id;
const id = parseInt(offerId)
try {
const offer = await prisma.offer.findFirst({ where: { id }})
if (!offer) return res.status(404).json({ error: "Invalid project" })
if (authorId !== offer.authorId) return res.status(403).json({ error: "Missing permissions" })
await prisma.offer.delete({ where: { id } })
res.status(200).json({ message: "Project has been deleted" })
} catch (err) {
res.status(400).json({ error: "Ha ocurrido un error al borrar el proyecto" })
}
}

20
backend/routes/user.js Normal file
View File

@@ -0,0 +1,20 @@
import jwt from 'jsonwebtoken'
import { prisma } from '../prisma.js'
export const deleteUser = async (req, res) => {
// Get user ID from url
const { userId } = req.params
try {
// Delete user from database
await prisma.user.delete({ where: { id: Number(userId) } })
// Return status and message
res.status(200).json({ message: 'User deleted' })
} catch (error) {
// If user not found, return error 404
res.status(404).json({ message: 'User not found' })
}
}