diff --git a/Login1.html b/Login1.html index e2e1c9c..b587d5e 100644 --- a/Login1.html +++ b/Login1.html @@ -1,11 +1,13 @@ + Space Odyssey +
@@ -14,66 +16,149 @@

SPACE
ODYSSEY

-
Initializing Spaceship
+
Initializing Spaceship
-

Access Terminal

- - - +

Access Terminal

+ + + + - +
- +
+
+
+ \ No newline at end of file diff --git a/api/config.php b/api/config.php new file mode 100644 index 0000000..f23828c --- /dev/null +++ b/api/config.php @@ -0,0 +1,34 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]); +} catch (Throwable $e) { + json_out(500, ['ok' => false, 'error' => 'DB connection failed']); +} + +function current_user(PDO $pdo): ?array { + if (!isset($_SESSION['user_id'])) return null; + $stmt = $pdo->prepare('SELECT id, username, email, created_at FROM users WHERE id = ? LIMIT 1'); + $stmt->execute([(int)$_SESSION['user_id']]); + $u = $stmt->fetch(); + return $u ?: null; +} diff --git a/api/login.php b/api/login.php new file mode 100644 index 0000000..f60d499 --- /dev/null +++ b/api/login.php @@ -0,0 +1,33 @@ + false, 'error' => 'Invalid JSON']); + +$login = isset($data['login']) ? trim((string)$data['login']) : ''; +$password = isset($data['password']) ? (string)$data['password'] : ''; + +if ($login === '' || $password === '') { + json_out(400, ['ok' => false, 'error' => 'Missing login or password']); +} + +$stmt = $pdo->prepare('SELECT id, username, email, password_hash, created_at FROM users WHERE username = ? OR email = ? LIMIT 1'); +$stmt->execute([$login, $login]); +$user = $stmt->fetch(); + +if (!$user || !password_verify($password, (string)$user['password_hash'])) { + json_out(401, ['ok' => false, 'error' => 'Invalid credentials']); +} + +$_SESSION['user_id'] = (int)$user['id']; + +json_out(200, [ + 'ok' => true, + 'user' => [ + 'id' => (int)$user['id'], + 'username' => (string)$user['username'], + 'email' => $user['email'], + 'created_at' => $user['created_at'], + ] +]); diff --git a/api/logout.php b/api/logout.php new file mode 100644 index 0000000..aa0f90b --- /dev/null +++ b/api/logout.php @@ -0,0 +1,12 @@ + true]); diff --git a/api/me.php b/api/me.php new file mode 100644 index 0000000..5d7388a --- /dev/null +++ b/api/me.php @@ -0,0 +1,6 @@ + true, 'user' => $u]); diff --git a/api/register.php b/api/register.php new file mode 100644 index 0000000..efa90fe --- /dev/null +++ b/api/register.php @@ -0,0 +1,41 @@ + false, 'error' => 'Invalid JSON']); + +$username = isset($data['username']) ? trim((string)$data['username']) : ''; +$email = isset($data['email']) ? trim((string)$data['email']) : ''; +$password = isset($data['password']) ? (string)$data['password'] : ''; + +if ($username === '' || strlen($username) < 3 || strlen($username) > 32) { + json_out(400, ['ok' => false, 'error' => 'Username must be 3-32 chars']); +} +if (!preg_match('/^[A-Za-z0-9_]+$/', $username)) { + json_out(400, ['ok' => false, 'error' => 'Username must be letters/numbers/_ only']); +} +if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) { + json_out(400, ['ok' => false, 'error' => 'Invalid email']); +} +if (strlen($password) < 6) { + json_out(400, ['ok' => false, 'error' => 'Password must be at least 6 chars']); +} + +$hash = password_hash($password, PASSWORD_DEFAULT); + +try { + $stmt = $pdo->prepare('INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)'); + $stmt->execute([$username, ($email === '' ? null : $email), $hash]); + + $_SESSION['user_id'] = (int)$pdo->lastInsertId(); + $u = current_user($pdo); + + json_out(201, ['ok' => true, 'user' => $u]); +} catch (Throwable $e) { + $msg = $e->getMessage(); + if (stripos($msg, 'Duplicate') !== false || stripos($msg, 'uq_') !== false) { + json_out(409, ['ok' => false, 'error' => 'Username or email already used']); + } + json_out(500, ['ok' => false, 'error' => 'Register failed']); +} diff --git a/img/module_table_bottom.png b/img/module_table_bottom.png new file mode 100644 index 0000000..536f757 Binary files /dev/null and b/img/module_table_bottom.png differ diff --git a/img/module_table_top.png b/img/module_table_top.png new file mode 100644 index 0000000..5174a22 Binary files /dev/null and b/img/module_table_top.png differ