Erster Docker-Stand
This commit is contained in:
31
src/db.js
Normal file
31
src/db.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const { Pool } = require('pg');
|
||||
/*const pool = new Pool({
|
||||
host: 'db', // Docker Compose service name
|
||||
port: 5432,
|
||||
user: 'admin',
|
||||
password: 'arfg486352wp',
|
||||
database: 'testdb'
|
||||
});*/
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE,
|
||||
password TEXT
|
||||
)
|
||||
`)
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE elements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
doc_id INTEGER,
|
||||
inhalt TEXT,
|
||||
bundesland TEXT,
|
||||
fach TEXT,
|
||||
version TEXT,
|
||||
stufe INTEGER,
|
||||
)
|
||||
`)
|
||||
|
||||
|
||||
module.exports = pool;
|
||||
15
src/middleware/authMiddleware.js
Normal file
15
src/middleware/authMiddleware.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
function authMiddleware(req, res, next) {
|
||||
const token = req.headers['authorization']
|
||||
|
||||
if (!token) { return res.status(401).json({ message: "No token provided" }) }
|
||||
|
||||
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
|
||||
if(err) {return res.status(401).json({message: "Invalid token"})}
|
||||
req.userId = decoded.id
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
export default authMiddleware
|
||||
14
src/prismaClient.js
Normal file
14
src/prismaClient.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { PrismaPg } from '@prisma/adapter-pg';
|
||||
import pg from 'pg';
|
||||
|
||||
// 1. Verbindungspool erstellen (nutzt deine DATABASE_URL aus der .env)
|
||||
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
||||
|
||||
// 2. Den Prisma-Adapter für Postgres erstellen
|
||||
const adapter = new PrismaPg(pool);
|
||||
|
||||
// 3. Den Client mit dem Adapter starten (WICHTIG für Prisma 7)
|
||||
const prisma = new PrismaClient({ adapter });
|
||||
|
||||
export default prisma;
|
||||
78
src/routes/authRoutes.js
Normal file
78
src/routes/authRoutes.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import express from 'express'
|
||||
import bcrypt from 'bcryptjs'
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
import prisma from '../prismaClient.js'
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
// Register a new user endpoint /auth/register (POST-Request)
|
||||
router.post('/register', async (req, res) => {
|
||||
const { username, password } = req.body
|
||||
// save the username and an irreversibly encrypted pw
|
||||
// save gilgameshj@gmail.com | njkdfasfdsa.gfdasg/ghdfshdfgs..fdsa.g..gdfad
|
||||
|
||||
// encrypt the pw
|
||||
const hashedPassword = bcrypt.hashSync(password, 8)
|
||||
|
||||
// save the new user and hashed pw to the db
|
||||
try {
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
username,
|
||||
password: hashedPassword
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// now that we have a user, I want to add their first todo for them
|
||||
const defaultTodo = `Hello :) Add your first todo!`
|
||||
await prisma.todo.create({
|
||||
data:{
|
||||
task: defaultTodo,
|
||||
userId: user.id
|
||||
}
|
||||
})
|
||||
|
||||
// create a token
|
||||
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '24h' })
|
||||
res.json({ token })
|
||||
} catch (err) {
|
||||
console.log(err.message)
|
||||
res.sendStatus(503)
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/login', async (req, res) => {
|
||||
// we get their email, and we look up the password associated with that email in the database
|
||||
// but we get it back and see its encrypted, which means that we cannot compare it to the one the user just used trying to login
|
||||
// so what we can todo, is again, one way encrypt the pw the user just entered and then compare
|
||||
|
||||
const { username, password } = req.body
|
||||
|
||||
try {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
username: username
|
||||
}
|
||||
})
|
||||
|
||||
// if we cannot find a user associated with that username, return out from the function
|
||||
if (!user) { return res.status(404).send({ message: "User not found" }) }
|
||||
|
||||
const passwordIsValid = bcrypt.compareSync(password, user.password)
|
||||
// if the password does not match, return out of the function
|
||||
if (!passwordIsValid) { return res.status(401).send({ message: "Invalid password" }) }
|
||||
|
||||
// then we have a successful authentication
|
||||
const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: '24h' })
|
||||
res.json({ token })
|
||||
} catch (err) {
|
||||
console.log(err.message)
|
||||
res.sendStatus(503)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
export default router
|
||||
18
src/routes/elementRoutes.js
Normal file
18
src/routes/elementRoutes.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import express from 'express'
|
||||
import prisma from '../prismaClient.js'
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
// Versuche es mit exakt dem Namen aus deinem Schema (Elements)
|
||||
const data = await prisma.Elements.findMany();
|
||||
res.json(data);
|
||||
} catch (err) {
|
||||
// DAS HIER IST WICHTIG: Es schreibt den echten Fehler in dein VS Code Terminal
|
||||
console.error("PRISMA FEHLER:", err);
|
||||
res.status(500).send(err.message);
|
||||
}
|
||||
});
|
||||
|
||||
export default router
|
||||
64
src/routes/todoRoutes.js
Normal file
64
src/routes/todoRoutes.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import express from 'express'
|
||||
|
||||
import prisma from '../prismaClient.js'
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
//Get all todos for loggen-in user
|
||||
router.get('/', async (req, res) => {
|
||||
const todos = await prisma.todo.findMany({
|
||||
where:{
|
||||
userId: req.userId
|
||||
}
|
||||
})
|
||||
res.json(todos)
|
||||
})
|
||||
|
||||
// create a todo
|
||||
router.post('/', async (req, res) => {
|
||||
const { task } = req.body
|
||||
|
||||
const todo = await prisma.todo.create({
|
||||
data: {
|
||||
task,
|
||||
userId: req.userId
|
||||
}
|
||||
})
|
||||
|
||||
res.json(todo)
|
||||
})
|
||||
|
||||
//update a todo
|
||||
router.put('/:id', async (req, res) => {
|
||||
const { completed } = req.body
|
||||
const { id } = req.params
|
||||
|
||||
const updatedTodo = await prisma.todo.update({
|
||||
where:{
|
||||
id: parseInt(id),
|
||||
userId: req.userId
|
||||
},
|
||||
data: {
|
||||
completed: !!completed
|
||||
}
|
||||
})
|
||||
|
||||
res.json(updatedTodo)
|
||||
})
|
||||
|
||||
//delete a todo
|
||||
router.delete('/:id', async (req, res) => {
|
||||
const {id} = req.params
|
||||
const userId = req.userId
|
||||
|
||||
await prisma.todo.delete({
|
||||
where:{
|
||||
id: parseInt(id),
|
||||
userId
|
||||
}
|
||||
})
|
||||
|
||||
res.send({message: "Todo deleted"})
|
||||
})
|
||||
|
||||
export default router
|
||||
36
src/server.js
Normal file
36
src/server.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import express from 'express'
|
||||
import cors from 'cors';
|
||||
import path, { dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import authRoutes from './routes/authRoutes.js'
|
||||
import todoRoutes from './routes/todoRoutes.js'
|
||||
import elementRoutes from './routes/elementRoutes.js';
|
||||
import authMiddleware from './middleware/authMiddleware.js'
|
||||
|
||||
const app = express()
|
||||
const PORT = process.env.PORT || 5003
|
||||
|
||||
// Get the file path from the URL of the current module
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
//Get the directory name from the file path
|
||||
const __dirname = dirname(__filename)
|
||||
|
||||
//Middleware
|
||||
app.use(express.json())
|
||||
// Serves the HTML file from the /public dir
|
||||
// Tells express to serve all files from the public folder as static assets / file. Any requests for the css files will be resolved to the public directory.
|
||||
app.use(express.static(path.join(__dirname, '../public')))
|
||||
|
||||
// Serving up the HTML file from the /public dir
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public', 'index.html'))
|
||||
})
|
||||
|
||||
//Routes
|
||||
app.use('/auth', authRoutes)
|
||||
app.use('/todos', authMiddleware, todoRoutes)
|
||||
app.use('/elements', elementRoutes);
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server has started on port: ${PORT}`);
|
||||
})
|
||||
Reference in New Issue
Block a user