edia all routes
This commit is contained in:
237
routes/api.js
237
routes/api.js
@@ -139,8 +139,12 @@ async function requireApiKey(req, res, next) {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PUBLIC API ROUTES (/api/v1/public/)
|
||||
// ============================================================================
|
||||
|
||||
// Login-Route (bleibt für Web-Interface)
|
||||
router.post('/login', async (req, res) => {
|
||||
router.post('/v1/public/login', async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
|
||||
if (!username || !password) {
|
||||
@@ -209,7 +213,7 @@ router.post('/login', async (req, res) => {
|
||||
});
|
||||
|
||||
// Logout-Route (bleibt für Web-Interface)
|
||||
router.post('/logout', (req, res) => {
|
||||
router.post('/v1/public/logout', (req, res) => {
|
||||
req.session.destroy((err) => {
|
||||
if (err) {
|
||||
return res.status(500).json({
|
||||
@@ -224,8 +228,12 @@ router.post('/logout', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// PRIVATE API ROUTES (/api/v1/private/)
|
||||
// ============================================================================
|
||||
|
||||
// API Endpunkt zum Speichern der Tokens (geschützt mit API-Key)
|
||||
router.post('/save-token', requireApiKey, async (req, res) => {
|
||||
router.post('/v1/private/save-token', requireApiKey, async (req, res) => {
|
||||
const { token, description, standorte } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -298,7 +306,7 @@ router.post('/save-token', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt zum Abrufen aller Tokens (geschützt mit API-Key)
|
||||
router.get('/tokens', requireApiKey, async (req, res) => {
|
||||
router.get('/v1/private/tokens', requireApiKey, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`SELECT id, token, description, standorte, created_at, expires_at, is_active
|
||||
@@ -321,7 +329,7 @@ router.get('/tokens', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt zum Validieren eines Tokens (geschützt mit API-Key)
|
||||
router.post('/validate-token', requireApiKey, async (req, res) => {
|
||||
router.post('/v1/private/validate-token', requireApiKey, async (req, res) => {
|
||||
const { token } = req.body;
|
||||
|
||||
if (!token) {
|
||||
@@ -378,7 +386,7 @@ router.post('/validate-token', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// Neue API-Route für Standortverwaltung (geschützt mit API-Key)
|
||||
router.post('/create-location', requireApiKey, async (req, res) => {
|
||||
router.post('/v1/private/create-location', requireApiKey, async (req, res) => {
|
||||
const { name, lat, lon } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -449,7 +457,7 @@ router.post('/create-location', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt zum Abrufen aller Standorte (geschützt mit API-Key)
|
||||
router.get('/locations', requireApiKey, async (req, res) => {
|
||||
router.get('/v1/private/locations', requireApiKey, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`SELECT id, name, latitude, longitude, time_threshold, created_at
|
||||
@@ -472,7 +480,7 @@ router.get('/locations', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt zum Aktualisieren des Zeit-Schwellenwerts für einen Standort
|
||||
router.put('/locations/:id/threshold', requireApiKey, async (req, res) => {
|
||||
router.put('/v1/private/locations/:id/threshold', requireApiKey, async (req, res) => {
|
||||
const { id } = req.params;
|
||||
const { time_threshold } = req.body;
|
||||
|
||||
@@ -525,8 +533,12 @@ router.put('/locations/:id/threshold', requireApiKey, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// WEB-AUTHENTICATED ROUTES (/api/v1/web/)
|
||||
// ============================================================================
|
||||
|
||||
// Neue Route zum Generieren eines API-Keys (nur für authentifizierte Web-Benutzer)
|
||||
router.post('/generate-api-key', async (req, res) => {
|
||||
router.post('/v1/web/generate-api-key', async (req, res) => {
|
||||
// Diese Route bleibt für das Web-Interface verfügbar
|
||||
// Hier können Sie einen neuen API-Key generieren
|
||||
try {
|
||||
@@ -570,7 +582,7 @@ router.post('/generate-api-key', async (req, res) => {
|
||||
// These endpoints use session authentication instead of API key authentication
|
||||
|
||||
// Web-authenticated endpoint for creating locations
|
||||
router.post('/web/create-location', async (req, res) => {
|
||||
router.post('/v1/web/create-location', async (req, res) => {
|
||||
// Check if user is authenticated via web session
|
||||
if (!req.session || !req.session.userId) {
|
||||
return res.status(401).json({
|
||||
@@ -649,7 +661,7 @@ router.post('/web/create-location', async (req, res) => {
|
||||
});
|
||||
|
||||
// Web-authenticated endpoint for saving tokens
|
||||
router.post('/web/save-token', async (req, res) => {
|
||||
router.post('/v1/web/save-token', async (req, res) => {
|
||||
// Check if user is authenticated via web session
|
||||
if (!req.session || !req.session.userId) {
|
||||
return res.status(401).json({
|
||||
@@ -713,7 +725,7 @@ router.post('/web/save-token', async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt für GetLocations (geschützt mit API-Key)
|
||||
router.get('/get-locations', requireApiKey, async (req, res) => {
|
||||
router.get('/v1/private/get-locations', requireApiKey, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query('SELECT * FROM "GetLocations"');
|
||||
|
||||
@@ -732,7 +744,7 @@ router.get('/get-locations', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Entpunkt zum erstellen eines neuen Spielers
|
||||
router.post('/create-player', requireApiKey, async (req, res) => {
|
||||
router.post('/v1/private/create-player', requireApiKey, async (req, res) => {
|
||||
const { firstname, lastname, birthdate, rfiduid } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -790,7 +802,7 @@ router.post('/create-player', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt zum erstellen einer neuen Zeit mit RFID UID und Location Name
|
||||
router.post('/create-time', requireApiKey, async (req, res) => {
|
||||
router.post('/v1/private/create-time', requireApiKey, async (req, res) => {
|
||||
const { rfiduid, location_name, recorded_time } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -928,7 +940,7 @@ router.post('/create-time', requireApiKey, async (req, res) => {
|
||||
});
|
||||
|
||||
// API Endpunkt zum Überprüfen eines Benutzers anhand der RFID UID
|
||||
router.post('/users/find', requireApiKey, async (req, res) => {
|
||||
router.post('/v1/private/users/find', requireApiKey, async (req, res) => {
|
||||
const { uid } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -1005,7 +1017,7 @@ router.post('/users/find', requireApiKey, async (req, res) => {
|
||||
// ============================================================================
|
||||
|
||||
// Get all players for RFID linking (no auth required for dashboard)
|
||||
router.get('/players', async (req, res) => {
|
||||
router.get('/v1/public/players', async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`SELECT id, firstname, lastname, birthdate, rfiduid, created_at
|
||||
@@ -1025,7 +1037,7 @@ router.get('/players', async (req, res) => {
|
||||
});
|
||||
|
||||
// Create new player with optional Supabase user linking (no auth required for dashboard)
|
||||
router.post('/players', async (req, res) => {
|
||||
router.post('/v1/public/players', async (req, res) => {
|
||||
const { firstname, lastname, birthdate, rfiduid, supabase_user_id } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -1099,7 +1111,7 @@ router.post('/players', async (req, res) => {
|
||||
});
|
||||
|
||||
// Link existing player to Supabase user (no auth required for dashboard)
|
||||
router.post('/link-player', async (req, res) => {
|
||||
router.post('/v1/public/link-player', async (req, res) => {
|
||||
const { player_id, supabase_user_id } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -1159,7 +1171,7 @@ router.post('/link-player', async (req, res) => {
|
||||
});
|
||||
|
||||
// Get user times by Supabase user ID (no auth required for dashboard)
|
||||
router.get('/user-times/:supabase_user_id', async (req, res) => {
|
||||
router.get('/v1/public/user-times/:supabase_user_id', async (req, res) => {
|
||||
const { supabase_user_id } = req.params;
|
||||
|
||||
try {
|
||||
@@ -1202,7 +1214,7 @@ router.get('/user-times/:supabase_user_id', async (req, res) => {
|
||||
});
|
||||
|
||||
// Get player info by Supabase user ID (no auth required for dashboard)
|
||||
router.get('/user-player/:supabase_user_id', async (req, res) => {
|
||||
router.get('/v1/public/user-player/:supabase_user_id', async (req, res) => {
|
||||
const { supabase_user_id } = req.params;
|
||||
|
||||
try {
|
||||
@@ -1233,7 +1245,7 @@ router.get('/user-player/:supabase_user_id', async (req, res) => {
|
||||
});
|
||||
|
||||
// Link user by RFID UID (scanned from QR code)
|
||||
router.post('/link-by-rfid', async (req, res) => {
|
||||
router.post('/v1/public/link-by-rfid', async (req, res) => {
|
||||
const { rfiduid, supabase_user_id } = req.body;
|
||||
|
||||
// Validierung
|
||||
@@ -1336,7 +1348,7 @@ function requireLevel2Access(req, res, next) {
|
||||
}
|
||||
|
||||
// Session-Check für Dashboard
|
||||
router.get('/check-session', (req, res) => {
|
||||
router.get('/v1/web/check-session', (req, res) => {
|
||||
if (req.session.userId) {
|
||||
res.json({
|
||||
success: true,
|
||||
@@ -1354,8 +1366,12 @@ router.get('/check-session', (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// ADMIN DASHBOARD ROUTES (/api/v1/admin/)
|
||||
// ============================================================================
|
||||
|
||||
// Admin Statistiken
|
||||
router.get('/admin-stats', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/stats', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const playersResult = await pool.query('SELECT COUNT(*) FROM players');
|
||||
const runsResult = await pool.query('SELECT COUNT(*) FROM times');
|
||||
@@ -1381,7 +1397,7 @@ router.get('/admin-stats', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Spieler-Verwaltung
|
||||
router.get('/admin-players', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/players', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(`
|
||||
SELECT
|
||||
@@ -1405,7 +1421,7 @@ router.get('/admin-players', requireAdminAuth, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/admin-players/:id', requireAdminAuth, async (req, res) => {
|
||||
router.delete('/v1/admin/players/:id', requireAdminAuth, async (req, res) => {
|
||||
const playerId = req.params.id;
|
||||
|
||||
try {
|
||||
@@ -1430,7 +1446,7 @@ router.delete('/admin-players/:id', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Läufe-Verwaltung
|
||||
router.get('/admin-runs', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/runs', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(`
|
||||
SELECT
|
||||
@@ -1463,7 +1479,7 @@ router.get('/admin-runs', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// GET einzelner Lauf
|
||||
router.get('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/runs/:id', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
@@ -1503,7 +1519,7 @@ router.get('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
||||
router.delete('/v1/admin/runs/:id', requireAdminAuth, async (req, res) => {
|
||||
const runId = req.params.id;
|
||||
|
||||
try {
|
||||
@@ -1524,7 +1540,7 @@ router.delete('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Standort-Verwaltung
|
||||
router.get('/admin-locations', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/locations', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query('SELECT * FROM locations ORDER BY name');
|
||||
|
||||
@@ -1541,7 +1557,7 @@ router.get('/admin-locations', requireAdminAuth, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/admin-locations/:id', requireAdminAuth, async (req, res) => {
|
||||
router.delete('/v1/admin/locations/:id', requireAdminAuth, async (req, res) => {
|
||||
const locationId = req.params.id;
|
||||
|
||||
try {
|
||||
@@ -1573,7 +1589,7 @@ router.delete('/admin-locations/:id', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin-Benutzer-Verwaltung
|
||||
router.get('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/adminusers', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(`
|
||||
SELECT id, username, access_level, is_active, created_at, last_login
|
||||
@@ -1594,7 +1610,7 @@ router.get('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
|
||||
router.delete('/v1/admin/adminusers/:id', requireAdminAuth, async (req, res) => {
|
||||
const userId = req.params.id;
|
||||
|
||||
// Verhindern, dass sich selbst löscht
|
||||
@@ -1627,7 +1643,7 @@ router.delete('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
|
||||
// ============================================================================
|
||||
|
||||
// Track page view
|
||||
router.post('/track-page-view', async (req, res) => {
|
||||
router.post('/v1/public/track-page-view', async (req, res) => {
|
||||
try {
|
||||
const { page, userAgent, ipAddress, referer } = req.body;
|
||||
|
||||
@@ -1646,8 +1662,145 @@ router.post('/track-page-view', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// LEADERBOARD ROUTES (moved from public.js)
|
||||
// ============================================================================
|
||||
|
||||
// Public endpoint für Standorte (keine Authentifizierung erforderlich)
|
||||
router.get('/v1/public/locations', async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query('SELECT * FROM "GetLocations"');
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der getlocations:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Fehler beim Abrufen der Standorte'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Public route to get times for location with parameter
|
||||
router.get('/v1/public/times', async (req, res) => {
|
||||
const { location } = req.query;
|
||||
|
||||
try {
|
||||
// First, let's check if the view exists and has data
|
||||
const viewCheck = await pool.query('SELECT COUNT(*) as count FROM "GetTimesWithPlayerAndLocation"');
|
||||
|
||||
// Check what location names are available
|
||||
const availableLocations = await pool.query('SELECT DISTINCT location_name FROM "GetTimesWithPlayerAndLocation"');
|
||||
|
||||
// Now search for the specific location
|
||||
const result = await pool.query('SELECT * FROM "GetTimesWithPlayerAndLocation" WHERE location_name = $1', [location]);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.rows,
|
||||
debug: {
|
||||
searchedFor: location,
|
||||
totalRecords: viewCheck.rows[0].count,
|
||||
availableLocations: availableLocations.rows.map(r => r.location_name),
|
||||
foundRecords: result.rows.length
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Fehler beim Abrufen der Zeiten:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Fehler beim Abrufen der Zeiten',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Public route to get all times with player and location details for leaderboard
|
||||
router.get('/v1/public/times-with-details', async (req, res) => {
|
||||
try {
|
||||
const { location, period } = req.query;
|
||||
|
||||
// Build WHERE clause for location filter
|
||||
let locationFilter = '';
|
||||
if (location && location !== 'all') {
|
||||
locationFilter = `AND l.name ILIKE '%${location}%'`;
|
||||
}
|
||||
|
||||
// Build WHERE clause for date filter using PostgreSQL timezone functions
|
||||
let dateFilter = '';
|
||||
if (period === 'today') {
|
||||
// Today in local timezone (UTC+2)
|
||||
dateFilter = `AND DATE(t.created_at AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE`;
|
||||
} else if (period === 'week') {
|
||||
// This week starting from Monday in local timezone
|
||||
dateFilter = `AND DATE(t.created_at AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Berlin') >= DATE_TRUNC('week', CURRENT_DATE)`;
|
||||
} else if (period === 'month') {
|
||||
// This month starting from 1st in local timezone
|
||||
dateFilter = `AND DATE(t.created_at AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Berlin') >= DATE_TRUNC('month', CURRENT_DATE)`;
|
||||
}
|
||||
|
||||
// Get all times with player and location details, ordered by time (fastest first)
|
||||
const result = await pool.query(`
|
||||
SELECT
|
||||
t.id,
|
||||
EXTRACT(EPOCH FROM t.recorded_time) as recorded_time_seconds,
|
||||
t.created_at,
|
||||
json_build_object(
|
||||
'id', p.id,
|
||||
'firstname', p.firstname,
|
||||
'lastname', p.lastname,
|
||||
'rfiduid', p.rfiduid
|
||||
) as player,
|
||||
json_build_object(
|
||||
'id', l.id,
|
||||
'name', l.name,
|
||||
'latitude', l.latitude,
|
||||
'longitude', l.longitude
|
||||
) as location
|
||||
FROM times t
|
||||
LEFT JOIN players p ON t.player_id = p.id
|
||||
LEFT JOIN locations l ON t.location_id = l.id
|
||||
WHERE 1=1 ${locationFilter} ${dateFilter}
|
||||
ORDER BY t.recorded_time ASC
|
||||
LIMIT 50
|
||||
`);
|
||||
|
||||
// Convert seconds to minutes:seconds.milliseconds format
|
||||
const formattedResults = result.rows.map(row => {
|
||||
const totalSeconds = parseFloat(row.recorded_time_seconds);
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const seconds = Math.floor(totalSeconds % 60);
|
||||
const milliseconds = Math.floor((totalSeconds % 1) * 1000);
|
||||
|
||||
return {
|
||||
...row,
|
||||
recorded_time: {
|
||||
minutes: minutes,
|
||||
seconds: seconds,
|
||||
milliseconds: milliseconds
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
res.json(formattedResults);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Fehler beim Abrufen der Zeiten mit Details:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Fehler beim Abrufen der Zeiten mit Details',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Get page statistics
|
||||
router.get('/admin-page-stats', requireAdminAuth, async (req, res) => {
|
||||
router.get('/v1/admin/page-stats', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
// Page views for today, this week, this month
|
||||
const today = new Date();
|
||||
@@ -1729,7 +1882,7 @@ router.get('/admin-page-stats', requireAdminAuth, async (req, res) => {
|
||||
// ============================================================================
|
||||
|
||||
// Admin Spieler - POST (Hinzufügen)
|
||||
router.post('/admin-players', requireAdminAuth, async (req, res) => {
|
||||
router.post('/v1/admin/players', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const { full_name, rfiduid, supabase_user_id } = req.body;
|
||||
|
||||
@@ -1760,7 +1913,7 @@ router.post('/admin-players', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Spieler - PUT (Bearbeiten)
|
||||
router.put('/admin-players/:id', requireAdminAuth, async (req, res) => {
|
||||
router.put('/v1/admin/players/:id', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const playerId = req.params.id;
|
||||
const { full_name, rfiduid, supabase_user_id } = req.body;
|
||||
@@ -1797,7 +1950,7 @@ router.put('/admin-players/:id', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Standorte - POST (Hinzufügen)
|
||||
router.post('/admin-locations', requireAdminAuth, async (req, res) => {
|
||||
router.post('/v1/admin/locations', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const { name, latitude, longitude, time_threshold } = req.body;
|
||||
|
||||
@@ -1823,7 +1976,7 @@ router.post('/admin-locations', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Standorte - PUT (Bearbeiten)
|
||||
router.put('/admin-locations/:id', requireAdminAuth, async (req, res) => {
|
||||
router.put('/v1/admin/locations/:id', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const locationId = req.params.id;
|
||||
const { name, latitude, longitude, time_threshold } = req.body;
|
||||
@@ -1855,7 +2008,7 @@ router.put('/admin-locations/:id', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Läufe - POST (Hinzufügen)
|
||||
router.post('/admin-runs', requireAdminAuth, async (req, res) => {
|
||||
router.post('/v1/admin/runs', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const { player_id, location_id, time_seconds } = req.body;
|
||||
|
||||
@@ -1884,7 +2037,7 @@ router.post('/admin-runs', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin Läufe - PUT (Bearbeiten)
|
||||
router.put('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
||||
router.put('/v1/admin/runs/:id', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const runId = req.params.id;
|
||||
const { player_id, location_id, time_seconds } = req.body;
|
||||
@@ -1919,7 +2072,7 @@ router.put('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin-Benutzer - POST (Hinzufügen)
|
||||
router.post('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
||||
router.post('/v1/admin/adminusers', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const { username, password, access_level } = req.body;
|
||||
|
||||
@@ -1956,7 +2109,7 @@ router.post('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
||||
});
|
||||
|
||||
// Admin-Benutzer - PUT (Bearbeiten)
|
||||
router.put('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
|
||||
router.put('/v1/admin/adminusers/:id', requireAdminAuth, async (req, res) => {
|
||||
try {
|
||||
const userId = req.params.id;
|
||||
const { username, password, access_level } = req.body;
|
||||
|
||||
Reference in New Issue
Block a user