diff --git a/edu/api/auth.php b/edu/api/auth.php new file mode 100644 index 0000000..74389c2 --- /dev/null +++ b/edu/api/auth.php @@ -0,0 +1,66 @@ + 0, 'first' => time()]; + if (time() - $attempts['first'] > 60) { + $attempts = ['count' => 0, 'first' => time()]; + } + if ($attempts['count'] >= 5) { + json_error('Zu viele Anmeldeversuche. Bitte eine Minute warten.', 429); + } + + $stmt = $pdo->prepare("SELECT id, username, password_hash, display_name, is_admin FROM users WHERE username = :u"); + $stmt->execute([':u' => $username]); + $user = $stmt->fetch(); + + if (!$user || !password_verify($password, $user['password_hash'])) { + $attempts['count']++; + $_SESSION[$key] = $attempts; + json_error('Benutzername oder Passwort falsch', 401); + } + + session_regenerate_id(true); + $_SESSION['user_id'] = $user['id']; + $_SESSION['is_admin'] = $user['is_admin']; + unset($_SESSION[$key]); + + json_ok(['user' => [ + 'id' => $user['id'], + 'username' => $user['username'], + 'display_name' => $user['display_name'], + 'is_admin' => (bool) $user['is_admin'] + ]]); +} + +if ($resource === 'logout' && get_method() === 'POST') { + session_destroy(); + json_ok(['ok' => true]); +} + +if ($resource === 'me' && get_method() === 'GET') { + $user_id = require_auth(); + $stmt = $pdo->prepare("SELECT id, username, display_name, is_admin FROM users WHERE id = :id"); + $stmt->execute([':id' => $user_id]); + $user = $stmt->fetch(); + if (!$user) { session_destroy(); json_error('Benutzer nicht gefunden', 401); } + json_ok(['user' => [ + 'id' => $user['id'], + 'username' => $user['username'], + 'display_name' => $user['display_name'], + 'is_admin' => (bool) $user['is_admin'] + ]]); +} + +json_error('Unbekannte Auth-Aktion', 404); diff --git a/edu/js/auth.js b/edu/js/auth.js new file mode 100644 index 0000000..f885243 --- /dev/null +++ b/edu/js/auth.js @@ -0,0 +1,22 @@ +'use strict'; + +var Auth = { + handleLogin: function(e) { + e.preventDefault(); + var user = document.getElementById('login-user').value.trim(); + var pass = document.getElementById('login-pass').value; + var errorEl = document.getElementById('login-error'); + errorEl.style.display = 'none'; + + API.post('/login', { username: user, password: pass }) + .then(function(data) { App.setUser(data.user); }) + .catch(function(err) { + errorEl.textContent = err.message || 'Anmeldung fehlgeschlagen'; + errorEl.style.display = 'block'; + }); + }, + + handleLogout: function() { + API.post('/logout').catch(function() {}).then(function() { App.showLogin(); }); + } +};