Dateien nach "backend/src" hochladen
This commit is contained in:
@@ -182,15 +182,13 @@ db.exec("UPDATE order_items SET qty_warteliste=stueckzahl WHERE qty_warteliste=0
|
|||||||
if (!db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='messages'").get()) {
|
if (!db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='messages'").get()) {
|
||||||
db.exec(`
|
db.exec(`
|
||||||
CREATE TABLE messages (
|
CREATE TABLE messages (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
recipient_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
recipient_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
encrypted_content TEXT NOT NULL,
|
encrypted_content TEXT NOT NULL,
|
||||||
iv TEXT NOT NULL,
|
iv TEXT NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
deleted_by_sender INTEGER NOT NULL DEFAULT 0,
|
read_by_recipient INTEGER NOT NULL DEFAULT 0
|
||||||
deleted_by_recipient INTEGER NOT NULL DEFAULT 0,
|
|
||||||
read_by_recipient INTEGER NOT NULL DEFAULT 0
|
|
||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
@@ -212,9 +210,33 @@ if (!db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='pus
|
|||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
// Falls messages-Tabelle alt ist und read_by_recipient fehlt
|
// Migration: Soft-Delete-Spalten entfernen (nur Nachrichten übernehmen die noch sichtbar waren)
|
||||||
const msgCols = db.prepare("PRAGMA table_info(messages)").all().map(r => r.name);
|
const msgCols = db.prepare("PRAGMA table_info(messages)").all().map(r => r.name);
|
||||||
if (msgCols.length && !msgCols.includes('read_by_recipient'))
|
if (msgCols.includes('deleted_by_sender')) {
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE messages_v2 (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
recipient_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
encrypted_content TEXT NOT NULL,
|
||||||
|
iv TEXT NOT NULL,
|
||||||
|
created_at DATETIME DEFAULT NULL,
|
||||||
|
read_by_recipient INTEGER NOT NULL DEFAULT 0
|
||||||
|
);
|
||||||
|
INSERT INTO messages_v2 (id, sender_id, recipient_id, encrypted_content, iv, created_at, read_by_recipient)
|
||||||
|
SELECT id, sender_id, recipient_id, encrypted_content, iv, created_at,
|
||||||
|
COALESCE(read_by_recipient, 0)
|
||||||
|
FROM messages
|
||||||
|
WHERE deleted_by_sender = 0 AND deleted_by_recipient = 0;
|
||||||
|
DROP TABLE messages;
|
||||||
|
ALTER TABLE messages_v2 RENAME TO messages;
|
||||||
|
`);
|
||||||
|
console.log('✅ Migration: messages → Hard-Delete (Soft-Delete-Spalten entfernt)');
|
||||||
|
}
|
||||||
|
// Falls read_by_recipient noch fehlt (sehr alte Installation)
|
||||||
|
const msgCols2 = db.prepare("PRAGMA table_info(messages)").all().map(r => r.name);
|
||||||
|
if (msgCols2.length && !msgCols2.includes('read_by_recipient')) {
|
||||||
db.exec("ALTER TABLE messages ADD COLUMN read_by_recipient INTEGER NOT NULL DEFAULT 0");
|
db.exec("ALTER TABLE messages ADD COLUMN read_by_recipient INTEGER NOT NULL DEFAULT 0");
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = db;
|
module.exports = db;
|
||||||
|
|||||||
@@ -7,6 +7,29 @@ require('./db');
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
|
// ── Security Headers ──────────────────────────────────────────────────────────
|
||||||
|
app.use((_req, res, next) => {
|
||||||
|
res.setHeader('Content-Security-Policy', [
|
||||||
|
"default-src 'self'",
|
||||||
|
"script-src 'self'",
|
||||||
|
// unsafe-inline nötig für React inline-styles + @import Google Fonts
|
||||||
|
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
|
||||||
|
"font-src 'self' https://fonts.gstatic.com",
|
||||||
|
// iCal-Feeds werden serverseitig geprosxt → nur 'self' nötig
|
||||||
|
"connect-src 'self'",
|
||||||
|
// data: für Avatare (base64), google.com für Favicons im QuickLinks-Widget
|
||||||
|
"img-src 'self' data: https://www.google.com",
|
||||||
|
"worker-src 'self'",
|
||||||
|
"object-src 'none'",
|
||||||
|
"base-uri 'self'",
|
||||||
|
"form-action 'self'",
|
||||||
|
].join('; '));
|
||||||
|
res.setHeader('X-Content-Type-Options', 'nosniff');
|
||||||
|
res.setHeader('X-Frame-Options', 'DENY');
|
||||||
|
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
// ── API ───────────────────────────────────────────────────────────────────────
|
// ── API ───────────────────────────────────────────────────────────────────────
|
||||||
app.use('/api/auth', require('./routes/auth'));
|
app.use('/api/auth', require('./routes/auth'));
|
||||||
app.use('/api/admin', require('./routes/admin'));
|
app.use('/api/admin', require('./routes/admin'));
|
||||||
|
|||||||
Reference in New Issue
Block a user