Hey ${name} 👋
-
Bitte bestätige deine E-Mail-Adresse, indem du auf den folgenden Button klickst:
+
Please verify your email address by clicking the button below:
- E-Mail bestätigen
+ Verify Email
- Oder kopiere diesen Link in deinen Browser:
+ Or copy this link in your browser:
${verifyUrl}
-
Der Link ist 24 Stunden gültig.
+
This link is valid for 24 hours.
-
Falls du dich nicht registriert hast, ignoriere diese E-Mail.
+
If you didn't register, please ignore this email.
`,
- text: `Hey ${name},\n\nBitte bestätige deine E-Mail: ${verifyUrl}\n\nDer Link ist 24 Stunden gültig.\n\n– ${appName}`,
+ text: `Hey ${name},\n\nPlease verify your email: ${verifyUrl}\n\nThis link is valid for 24 hours.\n\n– ${appName}`,
});
}
diff --git a/server/middleware/auth.js b/server/middleware/auth.js
index c749395..5818d25 100644
--- a/server/middleware/auth.js
+++ b/server/middleware/auth.js
@@ -8,7 +8,7 @@ export async function authenticateToken(req, res, next) {
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
- return res.status(401).json({ error: 'Authentifizierung erforderlich' });
+ return res.status(401).json({ error: 'Authentication required' });
}
try {
@@ -16,18 +16,18 @@ export async function authenticateToken(req, res, next) {
const db = getDb();
const user = await db.get('SELECT id, name, email, role, theme, language, avatar_color, avatar_image FROM users WHERE id = ?', [decoded.userId]);
if (!user) {
- return res.status(401).json({ error: 'Benutzer nicht gefunden' });
+ return res.status(401).json({ error: 'User not found' });
}
req.user = user;
next();
} catch (err) {
- return res.status(403).json({ error: 'Ungültiges Token' });
+ return res.status(403).json({ error: 'Invalid token' });
}
}
export function requireAdmin(req, res, next) {
if (req.user.role !== 'admin') {
- return res.status(403).json({ error: 'Administratorrechte erforderlich' });
+ return res.status(403).json({ error: 'Admin rights required' });
}
next();
}
diff --git a/server/routes/admin.js b/server/routes/admin.js
index c337708..b745c1d 100644
--- a/server/routes/admin.js
+++ b/server/routes/admin.js
@@ -11,11 +11,11 @@ router.post('/users', authenticateToken, requireAdmin, async (req, res) => {
const { name, email, password, role } = req.body;
if (!name || !email || !password) {
- return res.status(400).json({ error: 'Alle Felder sind erforderlich' });
+ return res.status(400).json({ error: 'All fields are required' });
}
if (password.length < 6) {
- return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' });
+ return res.status(400).json({ error: 'Password must be at least 6 characters long' });
}
const validRole = ['user', 'admin'].includes(role) ? role : 'user';
@@ -23,7 +23,7 @@ router.post('/users', authenticateToken, requireAdmin, async (req, res) => {
const existing = await db.get('SELECT id FROM users WHERE email = ?', [email.toLowerCase()]);
if (existing) {
- return res.status(409).json({ error: 'E-Mail wird bereits verwendet' });
+ return res.status(409).json({ error: 'Email is already in use' });
}
const hash = bcrypt.hashSync(password, 12);
@@ -36,7 +36,7 @@ router.post('/users', authenticateToken, requireAdmin, async (req, res) => {
res.status(201).json({ user });
} catch (err) {
console.error('Create user error:', err);
- res.status(500).json({ error: 'Benutzer konnte nicht erstellt werden' });
+ res.status(500).json({ error: 'User could not be created' });
}
});
@@ -54,7 +54,7 @@ router.get('/users', authenticateToken, requireAdmin, async (req, res) => {
res.json({ users });
} catch (err) {
console.error('List users error:', err);
- res.status(500).json({ error: 'Benutzer konnten nicht geladen werden' });
+ res.status(500).json({ error: 'Users could not be loaded' });
}
});
@@ -63,7 +63,7 @@ router.put('/users/:id/role', authenticateToken, requireAdmin, async (req, res)
try {
const { role } = req.body;
if (!['user', 'admin'].includes(role)) {
- return res.status(400).json({ error: 'Ungültige Rolle' });
+ return res.status(400).json({ error: 'Invalid role' });
}
const db = getDb();
@@ -73,7 +73,7 @@ router.put('/users/:id/role', authenticateToken, requireAdmin, async (req, res)
const adminCount = await db.get('SELECT COUNT(*) as count FROM users WHERE role = ?', ['admin']);
const currentUser = await db.get('SELECT role FROM users WHERE id = ?', [req.params.id]);
if (currentUser?.role === 'admin' && adminCount.count <= 1) {
- return res.status(400).json({ error: 'Der letzte Admin kann nicht herabgestuft werden' });
+ return res.status(400).json({ error: 'The last admin cannot be demoted' });
}
}
@@ -83,7 +83,7 @@ router.put('/users/:id/role', authenticateToken, requireAdmin, async (req, res)
res.json({ user: updated });
} catch (err) {
console.error('Update role error:', err);
- res.status(500).json({ error: 'Rolle konnte nicht aktualisiert werden' });
+ res.status(500).json({ error: 'Role could not be updated' });
}
});
@@ -93,27 +93,27 @@ router.delete('/users/:id', authenticateToken, requireAdmin, async (req, res) =>
const db = getDb();
if (parseInt(req.params.id) === req.user.id) {
- return res.status(400).json({ error: 'Sie können sich nicht selbst löschen' });
+ return res.status(400).json({ error: 'You cannot delete yourself' });
}
const user = await db.get('SELECT id, role FROM users WHERE id = ?', [req.params.id]);
if (!user) {
- return res.status(404).json({ error: 'Benutzer nicht gefunden' });
+ return res.status(404).json({ error: 'User not found' });
}
// Check if it's the last admin
if (user.role === 'admin') {
const adminCount = await db.get('SELECT COUNT(*) as count FROM users WHERE role = ?', ['admin']);
if (adminCount.count <= 1) {
- return res.status(400).json({ error: 'Der letzte Admin kann nicht gelöscht werden' });
+ return res.status(400).json({ error: 'The last admin cannot be deleted' });
}
}
await db.run('DELETE FROM users WHERE id = ?', [req.params.id]);
- res.json({ message: 'Benutzer gelöscht' });
+ res.json({ message: 'User deleted' });
} catch (err) {
console.error('Delete user error:', err);
- res.status(500).json({ error: 'Benutzer konnte nicht gelöscht werden' });
+ res.status(500).json({ error: 'User could not be deleted' });
}
});
@@ -122,17 +122,17 @@ router.put('/users/:id/password', authenticateToken, requireAdmin, async (req, r
try {
const { newPassword } = req.body;
if (!newPassword || newPassword.length < 6) {
- return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' });
+ return res.status(400).json({ error: 'Password must be at least 6 characters long' });
}
const db = getDb();
const hash = bcrypt.hashSync(newPassword, 12);
await db.run('UPDATE users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [hash, req.params.id]);
- res.json({ message: 'Passwort zurückgesetzt' });
+ res.json({ message: 'Password reset' });
} catch (err) {
console.error('Reset password error:', err);
- res.status(500).json({ error: 'Passwort konnte nicht zurückgesetzt werden' });
+ res.status(500).json({ error: 'Password could not be reset' });
}
});
diff --git a/server/routes/auth.js b/server/routes/auth.js
index 526cdb8..d5f1cbb 100644
--- a/server/routes/auth.js
+++ b/server/routes/auth.js
@@ -25,17 +25,17 @@ router.post('/register', async (req, res) => {
const { name, email, password } = req.body;
if (!name || !email || !password) {
- return res.status(400).json({ error: 'Alle Felder sind erforderlich' });
+ return res.status(400).json({ error: 'All fields are required' });
}
if (password.length < 6) {
- return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' });
+ return res.status(400).json({ error: 'Password must be at least 6 characters long' });
}
const db = getDb();
const existing = await db.get('SELECT id FROM users WHERE email = ?', [email]);
if (existing) {
- return res.status(409).json({ error: 'E-Mail wird bereits verwendet' });
+ return res.status(409).json({ error: 'Email is already in use' });
}
const hash = bcrypt.hashSync(password, 12);
@@ -63,7 +63,7 @@ router.post('/register', async (req, res) => {
await sendVerificationEmail(email.toLowerCase(), name, verifyUrl, appName);
- return res.status(201).json({ needsVerification: true, message: 'Verifizierungs-E-Mail wurde gesendet' });
+ return res.status(201).json({ needsVerification: true, message: 'Verification email has been sent' });
}
// No SMTP configured – register and login immediately (legacy behaviour)
@@ -78,7 +78,7 @@ router.post('/register', async (req, res) => {
res.status(201).json({ token, user });
} catch (err) {
console.error('Register error:', err);
- res.status(500).json({ error: 'Registrierung fehlgeschlagen' });
+ res.status(500).json({ error: 'Registration failed' });
}
});
@@ -87,7 +87,7 @@ router.get('/verify-email', async (req, res) => {
try {
const { token } = req.query;
if (!token) {
- return res.status(400).json({ error: 'Token fehlt' });
+ return res.status(400).json({ error: 'Token is missing' });
}
const db = getDb();
@@ -97,11 +97,11 @@ router.get('/verify-email', async (req, res) => {
);
if (!user) {
- return res.status(400).json({ error: 'Ungültiger oder bereits verwendeter Token' });
+ return res.status(400).json({ error: 'Invalid or already used token' });
}
if (new Date(user.verification_token_expires) < new Date()) {
- return res.status(400).json({ error: 'Token ist abgelaufen. Bitte registriere dich erneut.' });
+ return res.status(400).json({ error: 'Token has expired. Please register again.' });
}
await db.run(
@@ -109,10 +109,10 @@ router.get('/verify-email', async (req, res) => {
[user.id]
);
- res.json({ verified: true, message: 'E-Mail erfolgreich verifiziert' });
+ res.json({ verified: true, message: 'Email verified successfully' });
} catch (err) {
console.error('Verify email error:', err);
- res.status(500).json({ error: 'Verifizierung fehlgeschlagen' });
+ res.status(500).json({ error: 'Verification failed' });
}
});
@@ -121,11 +121,11 @@ router.post('/resend-verification', async (req, res) => {
try {
const { email } = req.body;
if (!email) {
- return res.status(400).json({ error: 'E-Mail ist erforderlich' });
+ return res.status(400).json({ error: 'Email is required' });
}
if (!isMailerConfigured()) {
- return res.status(400).json({ error: 'SMTP ist nicht konfiguriert' });
+ return res.status(400).json({ error: 'SMTP is not configured' });
}
const db = getDb();
@@ -133,7 +133,7 @@ router.post('/resend-verification', async (req, res) => {
if (!user || user.email_verified) {
// Don't reveal whether account exists
- return res.json({ message: 'Falls ein Konto existiert, wurde eine neue E-Mail gesendet.' });
+ return res.json({ message: 'If an account exists, a new email has been sent.' });
}
const verificationToken = uuidv4();
@@ -155,10 +155,10 @@ router.post('/resend-verification', async (req, res) => {
await sendVerificationEmail(email.toLowerCase(), user.name, verifyUrl, appName);
- res.json({ message: 'Falls ein Konto existiert, wurde eine neue E-Mail gesendet.' });
+ res.json({ message: 'If an account exists, a new email has been sent.' });
} catch (err) {
console.error('Resend verification error:', err);
- res.status(500).json({ error: 'E-Mail konnte nicht gesendet werden' });
+ res.status(500).json({ error: 'Email could not be sent' });
}
});
@@ -168,18 +168,18 @@ router.post('/login', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
- return res.status(400).json({ error: 'E-Mail und Passwort sind erforderlich' });
+ return res.status(400).json({ error: 'Email and password are required' });
}
const db = getDb();
const user = await db.get('SELECT * FROM users WHERE email = ?', [email.toLowerCase()]);
if (!user || !bcrypt.compareSync(password, user.password_hash)) {
- return res.status(401).json({ error: 'Ungültige Anmeldedaten' });
+ return res.status(401).json({ error: 'Invalid credentials' });
}
if (!user.email_verified && isMailerConfigured()) {
- return res.status(403).json({ error: 'E-Mail-Adresse noch nicht verifiziert. Bitte prüfe dein Postfach.', needsVerification: true });
+ return res.status(403).json({ error: 'Email address not yet verified. Please check your inbox.', needsVerification: true });
}
const token = generateToken(user.id);
@@ -188,7 +188,7 @@ router.post('/login', async (req, res) => {
res.json({ token, user: safeUser });
} catch (err) {
console.error('Login error:', err);
- res.status(500).json({ error: 'Anmeldung fehlgeschlagen' });
+ res.status(500).json({ error: 'Login failed' });
}
});
@@ -206,7 +206,7 @@ router.put('/profile', authenticateToken, async (req, res) => {
if (email && email !== req.user.email) {
const existing = await db.get('SELECT id FROM users WHERE email = ? AND id != ?', [email.toLowerCase(), req.user.id]);
if (existing) {
- return res.status(409).json({ error: 'E-Mail wird bereits verwendet' });
+ return res.status(409).json({ error: 'Email is already in use' });
}
}
@@ -225,7 +225,7 @@ router.put('/profile', authenticateToken, async (req, res) => {
res.json({ user: updated });
} catch (err) {
console.error('Profile update error:', err);
- res.status(500).json({ error: 'Profil konnte nicht aktualisiert werden' });
+ res.status(500).json({ error: 'Profile could not be updated' });
}
});
@@ -237,20 +237,20 @@ router.put('/password', authenticateToken, async (req, res) => {
const user = await db.get('SELECT password_hash FROM users WHERE id = ?', [req.user.id]);
if (!bcrypt.compareSync(currentPassword, user.password_hash)) {
- return res.status(401).json({ error: 'Aktuelles Passwort ist falsch' });
+ return res.status(401).json({ error: 'Current password is incorrect' });
}
if (newPassword.length < 6) {
- return res.status(400).json({ error: 'Neues Passwort muss mindestens 6 Zeichen lang sein' });
+ return res.status(400).json({ error: 'New password must be at least 6 characters long' });
}
const hash = bcrypt.hashSync(newPassword, 12);
await db.run('UPDATE users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [hash, req.user.id]);
- res.json({ message: 'Passwort erfolgreich geändert' });
+ res.json({ message: 'Password changed successfully' });
} catch (err) {
console.error('Password change error:', err);
- res.status(500).json({ error: 'Passwort konnte nicht geändert werden' });
+ res.status(500).json({ error: 'Password could not be changed' });
}
});
@@ -267,12 +267,12 @@ router.post('/avatar', authenticateToken, async (req, res) => {
// Validate content type
const contentType = req.headers['content-type'];
if (!contentType || !contentType.startsWith('image/')) {
- return res.status(400).json({ error: 'Nur Bilddateien sind erlaubt' });
+ return res.status(400).json({ error: 'Only image files are allowed' });
}
// Max 2MB
if (buffer.length > 2 * 1024 * 1024) {
- return res.status(400).json({ error: 'Bild darf maximal 2MB groß sein' });
+ return res.status(400).json({ error: 'Image must not exceed 2MB' });
}
const ext = contentType.includes('png') ? 'png' : contentType.includes('gif') ? 'gif' : contentType.includes('webp') ? 'webp' : 'jpg';
@@ -295,7 +295,7 @@ router.post('/avatar', authenticateToken, async (req, res) => {
res.json({ user: updated });
} catch (err) {
console.error('Avatar upload error:', err);
- res.status(500).json({ error: 'Avatar konnte nicht hochgeladen werden' });
+ res.status(500).json({ error: 'Avatar could not be uploaded' });
}
});
@@ -313,7 +313,7 @@ router.delete('/avatar', authenticateToken, async (req, res) => {
res.json({ user: updated });
} catch (err) {
console.error('Avatar delete error:', err);
- res.status(500).json({ error: 'Avatar konnte nicht entfernt werden' });
+ res.status(500).json({ error: 'Avatar could not be removed' });
}
});
@@ -351,7 +351,7 @@ function generateColorFromName(name) {
router.get('/avatar/:filename', (req, res) => {
const filepath = path.join(uploadsDir, req.params.filename);
if (!fs.existsSync(filepath)) {
- return res.status(404).json({ error: 'Avatar nicht gefunden' });
+ return res.status(404).json({ error: 'Avatar not found' });
}
const ext = path.extname(filepath).slice(1);
const mimeMap = { jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif', webp: 'image/webp' };
diff --git a/server/routes/recordings.js b/server/routes/recordings.js
index 1c5d208..0fcfcb0 100644
--- a/server/routes/recordings.js
+++ b/server/routes/recordings.js
@@ -26,7 +26,7 @@ router.get('/', authenticateToken, async (req, res) => {
return {
recordID: rec.recordID,
meetingID: rec.meetingID,
- name: rec.name || 'Aufnahme',
+ name: rec.name || 'Recording',
state: rec.state,
published: rec.published === 'true',
startTime: rec.startTime,
@@ -46,7 +46,7 @@ router.get('/', authenticateToken, async (req, res) => {
res.json({ recordings: formatted });
} catch (err) {
console.error('Get recordings error:', err);
- res.status(500).json({ error: 'Aufnahmen konnten nicht geladen werden', recordings: [] });
+ res.status(500).json({ error: 'Recordings could not be loaded', recordings: [] });
}
});
@@ -57,7 +57,7 @@ router.get('/room/:uid', authenticateToken, async (req, res) => {
const room = await db.get('SELECT * FROM rooms WHERE uid = ?', [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
const recordings = await getRecordings(room.uid);
@@ -90,7 +90,7 @@ router.get('/room/:uid', authenticateToken, async (req, res) => {
res.json({ recordings: formatted });
} catch (err) {
console.error('Get room recordings error:', err);
- res.status(500).json({ error: 'Aufnahmen konnten nicht geladen werden', recordings: [] });
+ res.status(500).json({ error: 'Recordings could not be loaded', recordings: [] });
}
});
@@ -98,10 +98,10 @@ router.get('/room/:uid', authenticateToken, async (req, res) => {
router.delete('/:recordID', authenticateToken, async (req, res) => {
try {
await deleteRecording(req.params.recordID);
- res.json({ message: 'Aufnahme gelöscht' });
+ res.json({ message: 'Recording deleted' });
} catch (err) {
console.error('Delete recording error:', err);
- res.status(500).json({ error: 'Aufnahme konnte nicht gelöscht werden' });
+ res.status(500).json({ error: 'Recording could not be deleted' });
}
});
@@ -110,10 +110,10 @@ router.put('/:recordID/publish', authenticateToken, async (req, res) => {
try {
const { publish } = req.body;
await publishRecording(req.params.recordID, publish);
- res.json({ message: publish ? 'Aufnahme veröffentlicht' : 'Aufnahme nicht mehr öffentlich' });
+ res.json({ message: publish ? 'Recording published' : 'Recording unpublished' });
} catch (err) {
console.error('Publish recording error:', err);
- res.status(500).json({ error: 'Aufnahme konnte nicht aktualisiert werden' });
+ res.status(500).json({ error: 'Recording could not be updated' });
}
});
diff --git a/server/routes/rooms.js b/server/routes/rooms.js
index ecffd65..88cb60f 100644
--- a/server/routes/rooms.js
+++ b/server/routes/rooms.js
@@ -46,7 +46,7 @@ router.get('/', authenticateToken, async (req, res) => {
res.json({ rooms: [...ownRooms, ...sharedRooms] });
} catch (err) {
console.error('List rooms error:', err);
- res.status(500).json({ error: 'Räume konnten nicht geladen werden' });
+ res.status(500).json({ error: 'Rooms could not be loaded' });
}
});
@@ -68,7 +68,7 @@ router.get('/users/search', authenticateToken, async (req, res) => {
res.json({ users });
} catch (err) {
console.error('Search users error:', err);
- res.status(500).json({ error: 'Benutzersuche fehlgeschlagen' });
+ res.status(500).json({ error: 'User search failed' });
}
});
@@ -84,14 +84,14 @@ router.get('/:uid', authenticateToken, async (req, res) => {
`, [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
// Check access: owner, admin, or shared
if (room.user_id !== req.user.id && req.user.role !== 'admin') {
const share = await db.get('SELECT id FROM room_shares WHERE room_id = ? AND user_id = ?', [room.id, req.user.id]);
if (!share) {
- return res.status(403).json({ error: 'Keine Berechtigung' });
+ return res.status(403).json({ error: 'No permission' });
}
room.shared = 1;
}
@@ -107,7 +107,7 @@ router.get('/:uid', authenticateToken, async (req, res) => {
res.json({ room, sharedUsers });
} catch (err) {
console.error('Get room error:', err);
- res.status(500).json({ error: 'Raum konnte nicht geladen werden' });
+ res.status(500).json({ error: 'Room could not be loaded' });
}
});
@@ -129,7 +129,7 @@ router.post('/', authenticateToken, async (req, res) => {
} = req.body;
if (!name || name.trim().length === 0) {
- return res.status(400).json({ error: 'Raumname ist erforderlich' });
+ return res.status(400).json({ error: 'Room name is required' });
}
const uid = crypto.randomBytes(8).toString('hex');
@@ -158,7 +158,7 @@ router.post('/', authenticateToken, async (req, res) => {
res.status(201).json({ room });
} catch (err) {
console.error('Create room error:', err);
- res.status(500).json({ error: 'Raum konnte nicht erstellt werden' });
+ res.status(500).json({ error: 'Room could not be created' });
}
});
@@ -169,7 +169,7 @@ router.put('/:uid', authenticateToken, async (req, res) => {
const room = await db.get('SELECT * FROM rooms WHERE uid = ? AND user_id = ?', [req.params.uid, req.user.id]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden oder keine Berechtigung' });
+ return res.status(404).json({ error: 'Room not found or no permission' });
}
const {
@@ -220,7 +220,7 @@ router.put('/:uid', authenticateToken, async (req, res) => {
res.json({ room: updated });
} catch (err) {
console.error('Update room error:', err);
- res.status(500).json({ error: 'Raum konnte nicht aktualisiert werden' });
+ res.status(500).json({ error: 'Room could not be updated' });
}
});
@@ -231,18 +231,18 @@ router.delete('/:uid', authenticateToken, async (req, res) => {
const room = await db.get('SELECT * FROM rooms WHERE uid = ?', [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
if (room.user_id !== req.user.id && req.user.role !== 'admin') {
- return res.status(403).json({ error: 'Keine Berechtigung' });
+ return res.status(403).json({ error: 'No permission' });
}
await db.run('DELETE FROM rooms WHERE uid = ?', [req.params.uid]);
- res.json({ message: 'Raum erfolgreich gelöscht' });
+ res.json({ message: 'Room deleted successfully' });
} catch (err) {
console.error('Delete room error:', err);
- res.status(500).json({ error: 'Raum konnte nicht gelöscht werden' });
+ res.status(500).json({ error: 'Room could not be deleted' });
}
});
// GET /api/rooms/:uid/shares - Get shared users for a room
@@ -251,7 +251,7 @@ router.get('/:uid/shares', authenticateToken, async (req, res) => {
const db = getDb();
const room = await db.get('SELECT * FROM rooms WHERE uid = ? AND user_id = ?', [req.params.uid, req.user.id]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden oder keine Berechtigung' });
+ return res.status(404).json({ error: 'Room not found or no permission' });
}
const shares = await db.all(`
SELECT u.id, u.name, u.email, u.avatar_color, u.avatar_image
@@ -262,7 +262,7 @@ router.get('/:uid/shares', authenticateToken, async (req, res) => {
res.json({ shares });
} catch (err) {
console.error('Get shares error:', err);
- res.status(500).json({ error: 'Fehler beim Laden der Freigaben' });
+ res.status(500).json({ error: 'Error loading shares' });
}
});
@@ -271,20 +271,20 @@ router.post('/:uid/shares', authenticateToken, async (req, res) => {
try {
const { user_id } = req.body;
if (!user_id) {
- return res.status(400).json({ error: 'Benutzer-ID erforderlich' });
+ return res.status(400).json({ error: 'User ID is required' });
}
const db = getDb();
const room = await db.get('SELECT * FROM rooms WHERE uid = ? AND user_id = ?', [req.params.uid, req.user.id]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden oder keine Berechtigung' });
+ return res.status(404).json({ error: 'Room not found or no permission' });
}
if (user_id === req.user.id) {
- return res.status(400).json({ error: 'Du kannst den Raum nicht mit dir selbst teilen' });
+ return res.status(400).json({ error: 'You cannot share the room with yourself' });
}
// Check if already shared
const existing = await db.get('SELECT id FROM room_shares WHERE room_id = ? AND user_id = ?', [room.id, user_id]);
if (existing) {
- return res.status(400).json({ error: 'Raum ist bereits mit diesem Benutzer geteilt' });
+ return res.status(400).json({ error: 'Room is already shared with this user' });
}
await db.run('INSERT INTO room_shares (room_id, user_id) VALUES (?, ?)', [room.id, user_id]);
const shares = await db.all(`
@@ -296,7 +296,7 @@ router.post('/:uid/shares', authenticateToken, async (req, res) => {
res.json({ shares });
} catch (err) {
console.error('Share room error:', err);
- res.status(500).json({ error: 'Fehler beim Teilen des Raums' });
+ res.status(500).json({ error: 'Error sharing room' });
}
});
@@ -306,7 +306,7 @@ router.delete('/:uid/shares/:userId', authenticateToken, async (req, res) => {
const db = getDb();
const room = await db.get('SELECT * FROM rooms WHERE uid = ? AND user_id = ?', [req.params.uid, req.user.id]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden oder keine Berechtigung' });
+ return res.status(404).json({ error: 'Room not found or no permission' });
}
await db.run('DELETE FROM room_shares WHERE room_id = ? AND user_id = ?', [room.id, parseInt(req.params.userId)]);
const shares = await db.all(`
@@ -318,7 +318,7 @@ router.delete('/:uid/shares/:userId', authenticateToken, async (req, res) => {
res.json({ shares });
} catch (err) {
console.error('Remove share error:', err);
- res.status(500).json({ error: 'Fehler beim Entfernen der Freigabe' });
+ res.status(500).json({ error: 'Error removing share' });
}
});
@@ -329,15 +329,15 @@ router.post('/:uid/start', authenticateToken, async (req, res) => {
const room = await db.get('SELECT * FROM rooms WHERE uid = ?', [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
- // Check access: owner or shared user
+ // Check access: owner or shared
const isOwner = room.user_id === req.user.id;
if (!isOwner) {
const share = await db.get('SELECT id FROM room_shares WHERE room_id = ? AND user_id = ?', [room.id, req.user.id]);
if (!share) {
- return res.status(403).json({ error: 'Keine Berechtigung' });
+ return res.status(403).json({ error: 'No permission' });
}
}
@@ -347,7 +347,7 @@ router.post('/:uid/start', authenticateToken, async (req, res) => {
res.json({ joinUrl });
} catch (err) {
console.error('Start meeting error:', err);
- res.status(500).json({ error: 'Meeting konnte nicht gestartet werden' });
+ res.status(500).json({ error: 'Meeting could not be started' });
}
});
@@ -358,18 +358,18 @@ router.post('/:uid/join', authenticateToken, async (req, res) => {
const room = await db.get('SELECT * FROM rooms WHERE uid = ?', [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
// Check access code if set
if (room.access_code && req.body.access_code !== room.access_code) {
- return res.status(403).json({ error: 'Falscher Zugangscode' });
+ return res.status(403).json({ error: 'Wrong access code' });
}
// Check if meeting is running
const running = await isMeetingRunning(room.uid);
if (!running) {
- return res.status(400).json({ error: 'Meeting läuft nicht. Bitte warten Sie, bis der Moderator das Meeting gestartet hat.' });
+ return res.status(400).json({ error: 'Meeting is not running. Please wait for the moderator to start the meeting.' });
}
// Owner and shared users join as moderator
@@ -381,7 +381,7 @@ router.post('/:uid/join', authenticateToken, async (req, res) => {
res.json({ joinUrl });
} catch (err) {
console.error('Join meeting error:', err);
- res.status(500).json({ error: 'Meeting konnte nicht beigetreten werden' });
+ res.status(500).json({ error: 'Could not join meeting' });
}
});
@@ -392,7 +392,7 @@ router.post('/:uid/end', authenticateToken, async (req, res) => {
const room = await db.get('SELECT * FROM rooms WHERE uid = ?', [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
// Check access: owner or shared user
@@ -400,15 +400,15 @@ router.post('/:uid/end', authenticateToken, async (req, res) => {
if (!isOwner) {
const share = await db.get('SELECT id FROM room_shares WHERE room_id = ? AND user_id = ?', [room.id, req.user.id]);
if (!share) {
- return res.status(403).json({ error: 'Keine Berechtigung' });
+ return res.status(403).json({ error: 'No permission' });
}
}
await endMeeting(room.uid);
- res.json({ message: 'Meeting beendet' });
+ res.json({ message: 'Meeting ended' });
} catch (err) {
console.error('End meeting error:', err);
- res.status(500).json({ error: 'Meeting konnte nicht beendet werden' });
+ res.status(500).json({ error: 'Meeting could not be ended' });
}
});
@@ -425,7 +425,7 @@ router.get('/:uid/public', async (req, res) => {
`, [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
const running = await isMeetingRunning(room.uid);
@@ -442,7 +442,7 @@ router.get('/:uid/public', async (req, res) => {
});
} catch (err) {
console.error('Public room info error:', err);
- res.status(500).json({ error: 'Rauminfos konnten nicht geladen werden' });
+ res.status(500).json({ error: 'Room info could not be loaded' });
}
});
@@ -452,25 +452,25 @@ router.post('/:uid/guest-join', async (req, res) => {
const { name, access_code, moderator_code } = req.body;
if (!name || name.trim().length === 0) {
- return res.status(400).json({ error: 'Name ist erforderlich' });
+ return res.status(400).json({ error: 'Name is required' });
}
const db = getDb();
const room = await db.get('SELECT * FROM rooms WHERE uid = ?', [req.params.uid]);
if (!room) {
- return res.status(404).json({ error: 'Raum nicht gefunden' });
+ return res.status(404).json({ error: 'Room not found' });
}
// Check access code if set
if (room.access_code && access_code !== room.access_code) {
- return res.status(403).json({ error: 'Falscher Zugangscode' });
+ return res.status(403).json({ error: 'Wrong access code' });
}
// Check if meeting is running (or if anyone_can_start is enabled)
const running = await isMeetingRunning(room.uid);
if (!running && !room.anyone_can_start) {
- return res.status(400).json({ error: 'Meeting läuft nicht. Bitte warten Sie, bis der Moderator das Meeting gestartet hat.' });
+ return res.status(400).json({ error: 'Meeting is not running. Please wait for the moderator to start the meeting.' });
}
// If meeting not running but anyone_can_start, create it
@@ -490,7 +490,7 @@ router.post('/:uid/guest-join', async (req, res) => {
res.json({ joinUrl });
} catch (err) {
console.error('Guest join error:', err);
- res.status(500).json({ error: 'Beitritt als Gast fehlgeschlagen' });
+ res.status(500).json({ error: 'Guest join failed' });
}
});