edia all routes
This commit is contained in:
@@ -46,7 +46,7 @@ function setupEventListeners() {
|
|||||||
|
|
||||||
async function checkAuth() {
|
async function checkAuth() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/check-session');
|
const response = await fetch('/api/v1/web/check-session');
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
@@ -74,7 +74,7 @@ async function checkAuth() {
|
|||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
try {
|
try {
|
||||||
await fetch('/api/logout', { method: 'POST' });
|
await fetch('/api/v1/public/logout', { method: 'POST' });
|
||||||
window.location.href = '/adminlogin.html';
|
window.location.href = '/adminlogin.html';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Logout failed:', error);
|
console.error('Logout failed:', error);
|
||||||
@@ -84,7 +84,7 @@ async function logout() {
|
|||||||
|
|
||||||
async function loadStatistics() {
|
async function loadStatistics() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/admin-stats');
|
const response = await fetch('/api/v1/admin/stats');
|
||||||
const stats = await response.json();
|
const stats = await response.json();
|
||||||
|
|
||||||
if (stats.success) {
|
if (stats.success) {
|
||||||
@@ -100,7 +100,7 @@ async function loadStatistics() {
|
|||||||
|
|
||||||
async function loadPageStatistics() {
|
async function loadPageStatistics() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/admin-page-stats');
|
const response = await fetch('/api/v1/admin/page-stats');
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -202,7 +202,7 @@ async function loadUsers() {
|
|||||||
|
|
||||||
async function loadPlayers() {
|
async function loadPlayers() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/admin-players');
|
const response = await fetch('/api/v1/admin/players');
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -219,7 +219,7 @@ async function loadPlayers() {
|
|||||||
|
|
||||||
async function loadRuns() {
|
async function loadRuns() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/admin-runs');
|
const response = await fetch('/api/v1/admin/runs');
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -236,7 +236,7 @@ async function loadRuns() {
|
|||||||
|
|
||||||
async function loadLocations() {
|
async function loadLocations() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/admin-locations');
|
const response = await fetch('/api/v1/admin/locations');
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -253,7 +253,7 @@ async function loadLocations() {
|
|||||||
|
|
||||||
async function loadAdminUsers() {
|
async function loadAdminUsers() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/admin-adminusers');
|
const response = await fetch('/api/v1/admin/adminusers');
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -537,22 +537,22 @@ async function handleAddSubmit(e) {
|
|||||||
|
|
||||||
switch(currentDataType) {
|
switch(currentDataType) {
|
||||||
case 'players':
|
case 'players':
|
||||||
endpoint = isEdit ? `/api/admin-players/${editId}` : '/api/admin-players';
|
endpoint = isEdit ? `/api/v1/admin/players/${editId}` : '/api/v1/admin/players';
|
||||||
successMessage = isEdit ? 'Spieler erfolgreich aktualisiert' : 'Spieler erfolgreich hinzugefügt';
|
successMessage = isEdit ? 'Spieler erfolgreich aktualisiert' : 'Spieler erfolgreich hinzugefügt';
|
||||||
method = isEdit ? 'PUT' : 'POST';
|
method = isEdit ? 'PUT' : 'POST';
|
||||||
break;
|
break;
|
||||||
case 'locations':
|
case 'locations':
|
||||||
endpoint = isEdit ? `/api/admin-locations/${editId}` : '/api/admin-locations';
|
endpoint = isEdit ? `/api/v1/admin/locations/${editId}` : '/api/v1/admin/locations';
|
||||||
successMessage = isEdit ? 'Standort erfolgreich aktualisiert' : 'Standort erfolgreich hinzugefügt';
|
successMessage = isEdit ? 'Standort erfolgreich aktualisiert' : 'Standort erfolgreich hinzugefügt';
|
||||||
method = isEdit ? 'PUT' : 'POST';
|
method = isEdit ? 'PUT' : 'POST';
|
||||||
break;
|
break;
|
||||||
case 'adminusers':
|
case 'adminusers':
|
||||||
endpoint = isEdit ? `/api/admin-adminusers/${editId}` : '/api/admin-adminusers';
|
endpoint = isEdit ? `/api/v1/admin/adminusers/${editId}` : '/api/v1/admin/adminusers';
|
||||||
successMessage = isEdit ? 'Admin-Benutzer erfolgreich aktualisiert' : 'Admin-Benutzer erfolgreich hinzugefügt';
|
successMessage = isEdit ? 'Admin-Benutzer erfolgreich aktualisiert' : 'Admin-Benutzer erfolgreich hinzugefügt';
|
||||||
method = isEdit ? 'PUT' : 'POST';
|
method = isEdit ? 'PUT' : 'POST';
|
||||||
break;
|
break;
|
||||||
case 'runs':
|
case 'runs':
|
||||||
endpoint = isEdit ? `/api/admin-runs/${editId}` : '/api/admin-runs';
|
endpoint = isEdit ? `/api/v1/admin/runs/${editId}` : '/api/v1/admin/runs';
|
||||||
successMessage = isEdit ? 'Lauf erfolgreich aktualisiert' : 'Lauf erfolgreich hinzugefügt';
|
successMessage = isEdit ? 'Lauf erfolgreich aktualisiert' : 'Lauf erfolgreich hinzugefügt';
|
||||||
method = isEdit ? 'PUT' : 'POST';
|
method = isEdit ? 'PUT' : 'POST';
|
||||||
break;
|
break;
|
||||||
@@ -697,7 +697,7 @@ async function editRun(id) {
|
|||||||
async function deletePlayer(id) {
|
async function deletePlayer(id) {
|
||||||
if (await confirmDelete(`Spieler mit ID ${id} löschen?`)) {
|
if (await confirmDelete(`Spieler mit ID ${id} löschen?`)) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/admin-players/${id}`, { method: 'DELETE' });
|
const response = await fetch(`/api/v1/admin/players/${id}`, { method: 'DELETE' });
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -716,7 +716,7 @@ async function deletePlayer(id) {
|
|||||||
async function deleteRun(id) {
|
async function deleteRun(id) {
|
||||||
if (await confirmDelete(`Lauf mit ID ${id} löschen?`)) {
|
if (await confirmDelete(`Lauf mit ID ${id} löschen?`)) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/admin-runs/${id}`, { method: 'DELETE' });
|
const response = await fetch(`/api/v1/admin/runs/${id}`, { method: 'DELETE' });
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -735,7 +735,7 @@ async function deleteRun(id) {
|
|||||||
async function deleteLocation(id) {
|
async function deleteLocation(id) {
|
||||||
if (await confirmDelete(`Standort mit ID ${id} löschen?`)) {
|
if (await confirmDelete(`Standort mit ID ${id} löschen?`)) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/admin-locations/${id}`, { method: 'DELETE' });
|
const response = await fetch(`/api/v1/admin/locations/${id}`, { method: 'DELETE' });
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -754,7 +754,7 @@ async function deleteLocation(id) {
|
|||||||
async function deleteAdminUser(id) {
|
async function deleteAdminUser(id) {
|
||||||
if (await confirmDelete(`Admin-Benutzer mit ID ${id} löschen?`)) {
|
if (await confirmDelete(`Admin-Benutzer mit ID ${id} löschen?`)) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/admin-adminusers/${id}`, { method: 'DELETE' });
|
const response = await fetch(`/api/v1/admin/adminusers/${id}`, { method: 'DELETE' });
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ async function handleLogin(event) {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/login', {
|
const response = await fetch('/api/v1/public/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ async function linkUserByRfidUid(rfidUid) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// First, find the player with this RFID UID
|
// First, find the player with this RFID UID
|
||||||
const response = await fetch('/api/link-by-rfid', {
|
const response = await fetch('/api/v1/public/link-by-rfid', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -362,7 +362,7 @@ async function loadUserTimesSection(playerData) {
|
|||||||
showTimesLoading();
|
showTimesLoading();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/user-times/${currentUser.id}`);
|
const response = await fetch(`/api/v1/public/user-times/${currentUser.id}`);
|
||||||
const times = await response.json();
|
const times = await response.json();
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ function toggleTokenFields() {
|
|||||||
const standorte = document.getElementById("standorte").value.trim();
|
const standorte = document.getElementById("standorte").value.trim();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/web/save-token', {
|
const response = await fetch('/api/v1/web/save-token', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -477,7 +477,7 @@ function toggleTokenFields() {
|
|||||||
saveBtn.disabled = true;
|
saveBtn.disabled = true;
|
||||||
|
|
||||||
// Web-authenticated API für Standortverwaltung aufrufen
|
// Web-authenticated API für Standortverwaltung aufrufen
|
||||||
const response = await fetch('/api/web/create-location', {
|
const response = await fetch('/api/v1/web/create-location', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -524,7 +524,7 @@ function toggleTokenFields() {
|
|||||||
// Logout-Funktion
|
// Logout-Funktion
|
||||||
async function logout() {
|
async function logout() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/logout', {
|
const response = await fetch('/api/v1/public/logout', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ async function logout() {
|
|||||||
// Load locations from database
|
// Load locations from database
|
||||||
async function loadLocations() {
|
async function loadLocations() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/public-api/locations');
|
const response = await fetch('/api/v1/public/locations');
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to fetch locations');
|
throw new Error('Failed to fetch locations');
|
||||||
}
|
}
|
||||||
@@ -330,7 +330,7 @@ async function loadData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetch times with player and location data from local database
|
// Fetch times with player and location data from local database
|
||||||
const response = await fetch(`/public-api/times-with-details?${params.toString()}`);
|
const response = await fetch(`/api/v1/public/times-with-details?${params.toString()}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to fetch times');
|
throw new Error('Failed to fetch times');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ function trackPageView(pageName) {
|
|||||||
const referer = document.referrer || '';
|
const referer = document.referrer || '';
|
||||||
|
|
||||||
// Send tracking data to server
|
// Send tracking data to server
|
||||||
fetch('/api/track-page-view', {
|
fetch('/api/v1/public/track-page-view', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
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)
|
// 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;
|
const { username, password } = req.body;
|
||||||
|
|
||||||
if (!username || !password) {
|
if (!username || !password) {
|
||||||
@@ -209,7 +213,7 @@ router.post('/login', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Logout-Route (bleibt für Web-Interface)
|
// Logout-Route (bleibt für Web-Interface)
|
||||||
router.post('/logout', (req, res) => {
|
router.post('/v1/public/logout', (req, res) => {
|
||||||
req.session.destroy((err) => {
|
req.session.destroy((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(500).json({
|
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)
|
// 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;
|
const { token, description, standorte } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -298,7 +306,7 @@ router.post('/save-token', requireApiKey, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// API Endpunkt zum Abrufen aller Tokens (geschützt mit API-Key)
|
// 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 {
|
try {
|
||||||
const result = await pool.query(
|
const result = await pool.query(
|
||||||
`SELECT id, token, description, standorte, created_at, expires_at, is_active
|
`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)
|
// 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;
|
const { token } = req.body;
|
||||||
|
|
||||||
if (!token) {
|
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)
|
// 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;
|
const { name, lat, lon } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -449,7 +457,7 @@ router.post('/create-location', requireApiKey, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// API Endpunkt zum Abrufen aller Standorte (geschützt mit API-Key)
|
// 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 {
|
try {
|
||||||
const result = await pool.query(
|
const result = await pool.query(
|
||||||
`SELECT id, name, latitude, longitude, time_threshold, created_at
|
`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
|
// 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 { id } = req.params;
|
||||||
const { time_threshold } = req.body;
|
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)
|
// 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
|
// Diese Route bleibt für das Web-Interface verfügbar
|
||||||
// Hier können Sie einen neuen API-Key generieren
|
// Hier können Sie einen neuen API-Key generieren
|
||||||
try {
|
try {
|
||||||
@@ -570,7 +582,7 @@ router.post('/generate-api-key', async (req, res) => {
|
|||||||
// These endpoints use session authentication instead of API key authentication
|
// These endpoints use session authentication instead of API key authentication
|
||||||
|
|
||||||
// Web-authenticated endpoint for creating locations
|
// 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
|
// Check if user is authenticated via web session
|
||||||
if (!req.session || !req.session.userId) {
|
if (!req.session || !req.session.userId) {
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
@@ -649,7 +661,7 @@ router.post('/web/create-location', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Web-authenticated endpoint for saving tokens
|
// 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
|
// Check if user is authenticated via web session
|
||||||
if (!req.session || !req.session.userId) {
|
if (!req.session || !req.session.userId) {
|
||||||
return res.status(401).json({
|
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)
|
// 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 {
|
try {
|
||||||
const result = await pool.query('SELECT * FROM "GetLocations"');
|
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
|
// 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;
|
const { firstname, lastname, birthdate, rfiduid } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// 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
|
// 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;
|
const { rfiduid, location_name, recorded_time } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -928,7 +940,7 @@ router.post('/create-time', requireApiKey, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// API Endpunkt zum Überprüfen eines Benutzers anhand der RFID UID
|
// 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;
|
const { uid } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -1005,7 +1017,7 @@ router.post('/users/find', requireApiKey, async (req, res) => {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Get all players for RFID linking (no auth required for dashboard)
|
// 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 {
|
try {
|
||||||
const result = await pool.query(
|
const result = await pool.query(
|
||||||
`SELECT id, firstname, lastname, birthdate, rfiduid, created_at
|
`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)
|
// 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;
|
const { firstname, lastname, birthdate, rfiduid, supabase_user_id } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -1099,7 +1111,7 @@ router.post('/players', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Link existing player to Supabase user (no auth required for dashboard)
|
// 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;
|
const { player_id, supabase_user_id } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -1159,7 +1171,7 @@ router.post('/link-player', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get user times by Supabase user ID (no auth required for dashboard)
|
// 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;
|
const { supabase_user_id } = req.params;
|
||||||
|
|
||||||
try {
|
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)
|
// 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;
|
const { supabase_user_id } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1233,7 +1245,7 @@ router.get('/user-player/:supabase_user_id', async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Link user by RFID UID (scanned from QR code)
|
// 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;
|
const { rfiduid, supabase_user_id } = req.body;
|
||||||
|
|
||||||
// Validierung
|
// Validierung
|
||||||
@@ -1336,7 +1348,7 @@ function requireLevel2Access(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Session-Check für Dashboard
|
// Session-Check für Dashboard
|
||||||
router.get('/check-session', (req, res) => {
|
router.get('/v1/web/check-session', (req, res) => {
|
||||||
if (req.session.userId) {
|
if (req.session.userId) {
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -1354,8 +1366,12 @@ router.get('/check-session', (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ADMIN DASHBOARD ROUTES (/api/v1/admin/)
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
// Admin Statistiken
|
// Admin Statistiken
|
||||||
router.get('/admin-stats', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/stats', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const playersResult = await pool.query('SELECT COUNT(*) FROM players');
|
const playersResult = await pool.query('SELECT COUNT(*) FROM players');
|
||||||
const runsResult = await pool.query('SELECT COUNT(*) FROM times');
|
const runsResult = await pool.query('SELECT COUNT(*) FROM times');
|
||||||
@@ -1381,7 +1397,7 @@ router.get('/admin-stats', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Admin Spieler-Verwaltung
|
// Admin Spieler-Verwaltung
|
||||||
router.get('/admin-players', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/players', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
SELECT
|
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;
|
const playerId = req.params.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1430,7 +1446,7 @@ router.delete('/admin-players/:id', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Admin Läufe-Verwaltung
|
// Admin Läufe-Verwaltung
|
||||||
router.get('/admin-runs', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/runs', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
SELECT
|
SELECT
|
||||||
@@ -1463,7 +1479,7 @@ router.get('/admin-runs', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// GET einzelner Lauf
|
// GET einzelner Lauf
|
||||||
router.get('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/runs/:id', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
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;
|
const runId = req.params.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1524,7 +1540,7 @@ router.delete('/admin-runs/:id', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Admin Standort-Verwaltung
|
// Admin Standort-Verwaltung
|
||||||
router.get('/admin-locations', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/locations', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const result = await pool.query('SELECT * FROM locations ORDER BY name');
|
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;
|
const locationId = req.params.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1573,7 +1589,7 @@ router.delete('/admin-locations/:id', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Admin-Benutzer-Verwaltung
|
// Admin-Benutzer-Verwaltung
|
||||||
router.get('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/adminusers', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const result = await pool.query(`
|
const result = await pool.query(`
|
||||||
SELECT id, username, access_level, is_active, created_at, last_login
|
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;
|
const userId = req.params.id;
|
||||||
|
|
||||||
// Verhindern, dass sich selbst löscht
|
// Verhindern, dass sich selbst löscht
|
||||||
@@ -1627,7 +1643,7 @@ router.delete('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Track page view
|
// Track page view
|
||||||
router.post('/track-page-view', async (req, res) => {
|
router.post('/v1/public/track-page-view', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { page, userAgent, ipAddress, referer } = req.body;
|
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
|
// Get page statistics
|
||||||
router.get('/admin-page-stats', requireAdminAuth, async (req, res) => {
|
router.get('/v1/admin/page-stats', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Page views for today, this week, this month
|
// Page views for today, this week, this month
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
@@ -1729,7 +1882,7 @@ router.get('/admin-page-stats', requireAdminAuth, async (req, res) => {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Admin Spieler - POST (Hinzufügen)
|
// Admin Spieler - POST (Hinzufügen)
|
||||||
router.post('/admin-players', requireAdminAuth, async (req, res) => {
|
router.post('/v1/admin/players', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { full_name, rfiduid, supabase_user_id } = req.body;
|
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)
|
// Admin Spieler - PUT (Bearbeiten)
|
||||||
router.put('/admin-players/:id', requireAdminAuth, async (req, res) => {
|
router.put('/v1/admin/players/:id', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const playerId = req.params.id;
|
const playerId = req.params.id;
|
||||||
const { full_name, rfiduid, supabase_user_id } = req.body;
|
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)
|
// Admin Standorte - POST (Hinzufügen)
|
||||||
router.post('/admin-locations', requireAdminAuth, async (req, res) => {
|
router.post('/v1/admin/locations', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { name, latitude, longitude, time_threshold } = req.body;
|
const { name, latitude, longitude, time_threshold } = req.body;
|
||||||
|
|
||||||
@@ -1823,7 +1976,7 @@ router.post('/admin-locations', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Admin Standorte - PUT (Bearbeiten)
|
// Admin Standorte - PUT (Bearbeiten)
|
||||||
router.put('/admin-locations/:id', requireAdminAuth, async (req, res) => {
|
router.put('/v1/admin/locations/:id', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const locationId = req.params.id;
|
const locationId = req.params.id;
|
||||||
const { name, latitude, longitude, time_threshold } = req.body;
|
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)
|
// Admin Läufe - POST (Hinzufügen)
|
||||||
router.post('/admin-runs', requireAdminAuth, async (req, res) => {
|
router.post('/v1/admin/runs', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { player_id, location_id, time_seconds } = req.body;
|
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)
|
// 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 {
|
try {
|
||||||
const runId = req.params.id;
|
const runId = req.params.id;
|
||||||
const { player_id, location_id, time_seconds } = req.body;
|
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)
|
// Admin-Benutzer - POST (Hinzufügen)
|
||||||
router.post('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
router.post('/v1/admin/adminusers', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { username, password, access_level } = req.body;
|
const { username, password, access_level } = req.body;
|
||||||
|
|
||||||
@@ -1956,7 +2109,7 @@ router.post('/admin-adminusers', requireAdminAuth, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Admin-Benutzer - PUT (Bearbeiten)
|
// Admin-Benutzer - PUT (Bearbeiten)
|
||||||
router.put('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
|
router.put('/v1/admin/adminusers/:id', requireAdminAuth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.params.id;
|
const userId = req.params.id;
|
||||||
const { username, password, access_level } = req.body;
|
const { username, password, access_level } = req.body;
|
||||||
|
|||||||
19
server.js
19
server.js
@@ -25,7 +25,6 @@ require('dotenv').config();
|
|||||||
|
|
||||||
// Route Imports
|
// Route Imports
|
||||||
const { router: apiRoutes, requireApiKey } = require('./routes/api');
|
const { router: apiRoutes, requireApiKey } = require('./routes/api');
|
||||||
const publicRoutes = require('./routes/public');
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// SERVER CONFIGURATION
|
// SERVER CONFIGURATION
|
||||||
@@ -83,12 +82,11 @@ function requireWebAuth(req, res, next) {
|
|||||||
// ROUTE SETUP
|
// ROUTE SETUP
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Public API Routes (no authentication required)
|
// Unified API Routes (all under /api/v1/)
|
||||||
// Diese Routen sind für das Frontend-Leaderboard gedacht
|
// - /api/v1/public/* - Public routes (no authentication)
|
||||||
app.use('/public-api', publicRoutes);
|
// - /api/v1/private/* - API-Key protected routes
|
||||||
|
// - /api/v1/web/* - Session protected routes
|
||||||
// Private API Routes (API-Key authentication required)
|
// - /api/v1/admin/* - Admin protected routes
|
||||||
// Diese Routen sind für die Timer-Geräte und Admin-Interface
|
|
||||||
app.use('/api', apiRoutes);
|
app.use('/api', apiRoutes);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -242,8 +240,11 @@ server.listen(port, () => {
|
|||||||
console.log(`🔐 API-Key Authentifizierung aktiviert`);
|
console.log(`🔐 API-Key Authentifizierung aktiviert`);
|
||||||
console.log(`🔌 WebSocket-Server aktiviert`);
|
console.log(`🔌 WebSocket-Server aktiviert`);
|
||||||
console.log(`📁 Static files: /public`);
|
console.log(`📁 Static files: /public`);
|
||||||
console.log(`🌐 Public API: /public-api`);
|
console.log(`🌐 Unified API: /api/v1/`);
|
||||||
console.log(`🔑 Private API: /api`);
|
console.log(` 📖 Public: /api/v1/public/`);
|
||||||
|
console.log(` 🔒 Private: /api/v1/private/`);
|
||||||
|
console.log(` 🔐 Web: /api/v1/web/`);
|
||||||
|
console.log(` 👑 Admin: /api/v1/admin/`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user