Dateien nach "/" hochladen
This commit is contained in:
commit
8fbfd7ffeb
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Basisimage
|
||||||
|
FROM node:20
|
||||||
|
|
||||||
|
# Arbeitsverzeichnis setzen
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Dateien kopieren
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Startbefehl
|
||||||
|
CMD ["node", "index.js"]
|
||||||
264
index.js
Normal file
264
index.js
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const { Pool } = require("pg");
|
||||||
|
|
||||||
|
const cors = require('cors');
|
||||||
|
const app = express();
|
||||||
|
const port = process.env.PORT || 3000;
|
||||||
|
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
|
const JWT_SECRET = "supergeheimes_tg_cms_secret";
|
||||||
|
|
||||||
|
// Bodyparser für JSON aktivieren
|
||||||
|
app.use(cors({
|
||||||
|
origin: ["http://localhost:8080", "http://192.168.50.65:8080"],
|
||||||
|
methods: ["GET", "POST", "PUT", "DELETE"],
|
||||||
|
credentials: true
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
// PostgreSQL Verbindung aufbauen
|
||||||
|
const pool = new Pool({
|
||||||
|
user: "tgadmin",
|
||||||
|
host: "db", // Docker Container Name!
|
||||||
|
database: "tg-cms",
|
||||||
|
password: "secretpass",
|
||||||
|
port: 5432,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Testroute API-Check
|
||||||
|
app.get("/api/hello", (req, res) => {
|
||||||
|
res.send("Hello World from TG CMS API! 🚀");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Testroute DB-Check
|
||||||
|
app.get("/api/test-db", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const result = await pool.query("SELECT NOW()");
|
||||||
|
res.json({ time: result.rows[0].now });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler bei DB-Verbindung");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Alle News abrufen
|
||||||
|
app.get("/api/news", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const result = await pool.query('SELECT * FROM news ORDER BY created_at DESC');
|
||||||
|
res.json(result.rows);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Abrufen der News");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Neue News anlegen
|
||||||
|
app.post("/api/news", async (req, res) => {
|
||||||
|
const { title, description, image_url, team } = req.body;
|
||||||
|
|
||||||
|
if (!title || !description) {
|
||||||
|
return res.status(400).send("Titel und Beschreibung sind Pflichtfelder");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await pool.query(
|
||||||
|
'INSERT INTO news (title, description, image_url, team) VALUES ($1, $2, $3, $4) RETURNING *',
|
||||||
|
[title, description, image_url, team]
|
||||||
|
);
|
||||||
|
res.status(201).json(result.rows[0]);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Anlegen der News");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// News bearbeiten
|
||||||
|
app.put("/api/news/:id", async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { title, description, image_url, team } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await pool.query(
|
||||||
|
'UPDATE news SET title = $1, description = $2, image_url = $3, team = $4 WHERE id = $5 RETURNING *',
|
||||||
|
[title, description, image_url, team, id]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.rowCount === 0) {
|
||||||
|
return res.status(404).send("News-Eintrag nicht gefunden");
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(result.rows[0]);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Aktualisieren der News");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// News löschen
|
||||||
|
app.delete("/api/news/:id", async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await pool.query(
|
||||||
|
'DELETE FROM news WHERE id = $1',
|
||||||
|
[id]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.rowCount === 0) {
|
||||||
|
return res.status(404).send("News-Eintrag nicht gefunden");
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send("News-Eintrag erfolgreich gelöscht");
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Löschen der News");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Neuen Benutzer anlegen
|
||||||
|
app.post("/api/users", async (req, res) => {
|
||||||
|
const { username, password, role, email } = req.body;
|
||||||
|
|
||||||
|
if (!username || !password || !email) {
|
||||||
|
return res.status(400).send("Username, Email & Passwort sind Pflicht");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Passwort hashen
|
||||||
|
const hashedPassword = await bcrypt.hash(password, 10);
|
||||||
|
|
||||||
|
// In DB speichern
|
||||||
|
const result = await pool.query(
|
||||||
|
'INSERT INTO users (username, password, role, email) VALUES ($1, $2, $3, $4) RETURNING id, username, role, email, created_at',
|
||||||
|
[username, hashedPassword, role ||'user', email]
|
||||||
|
);
|
||||||
|
|
||||||
|
res.status(201).json(result.rows[0]);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Anlegen des Benutzers");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Benutzer Login
|
||||||
|
app.post("/api/login", async (req, res) => {
|
||||||
|
const { username, password } = req.body;
|
||||||
|
|
||||||
|
if (!username || !password) {
|
||||||
|
return res.status(400).send("Username und Passwort erforderlich");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await pool.query(
|
||||||
|
'SELECT * FROM users WHERE username = $1',
|
||||||
|
[username]
|
||||||
|
);
|
||||||
|
|
||||||
|
const user = result.rows[0];
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(400).send("Benutzer existiert nicht");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passwort prüfen
|
||||||
|
const validPassword = await bcrypt.compare(password, user.password);
|
||||||
|
|
||||||
|
if (!validPassword) {
|
||||||
|
return res.status(401).send("Passwort falsch");
|
||||||
|
}
|
||||||
|
|
||||||
|
await pool.query(
|
||||||
|
'UPDATE users SET last_logged = NOW() WHERE id = $1',
|
||||||
|
[user.id]
|
||||||
|
);
|
||||||
|
|
||||||
|
// JWT Token erzeugen
|
||||||
|
const token = jwt.sign(
|
||||||
|
{ id: user.id, username: user.username, role: user.role },
|
||||||
|
JWT_SECRET,
|
||||||
|
{ expiresIn: "6h" }
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ token });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Login");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Alle Benutzer abrufen
|
||||||
|
app.get("/api/users", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const result = await pool.query(
|
||||||
|
'SELECT id, username, role, email, created_at FROM users ORDER BY created_at DESC'
|
||||||
|
);
|
||||||
|
res.json(result.rows);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Abrufen der Benutzer");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Benutzer lÃloeschen
|
||||||
|
app.delete("/api/users/:id", async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Prüfen, ob der Benutzer existiert
|
||||||
|
const checkResult = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
|
||||||
|
if (checkResult.rowCount === 0) {
|
||||||
|
return res.status(404).send("Benutzer nicht gefunden");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benutzer löschen
|
||||||
|
await pool.query('DELETE FROM users WHERE id = $1', [id]);
|
||||||
|
|
||||||
|
res.send("Benutzer erfolgreich gelöscht");
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Löschen des Benutzers");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Benutzer bearbeiten
|
||||||
|
app.put("/api/users/:id", async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { username, password, role } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Passwort optional neu setzen
|
||||||
|
let query = 'UPDATE users SET username = $1, role = $2';
|
||||||
|
let params = [username, role, id];
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
const hashedPassword = await bcrypt.hash(password, 10);
|
||||||
|
query = 'UPDATE users SET username = $1, password = $2, role = $3 WHERE id = $4';
|
||||||
|
params = [username, hashedPassword, role, id];
|
||||||
|
} else {
|
||||||
|
query += ' WHERE id = $3';
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await pool.query(query, params);
|
||||||
|
|
||||||
|
if (result.rowCount === 0) {
|
||||||
|
return res.status(404).send("Benutzer nicht gefunden");
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send("Benutzer erfolgreich aktualisiert");
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).send("Fehler beim Aktualisieren des Benutzers");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Server starten
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server läuft auf Port ${port}`);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user