diff options
| -rw-r--r-- | lib/partials.php | 11 | ||||
| -rw-r--r-- | lib/utils.php | 11 | ||||
| -rw-r--r-- | register.php | 105 | ||||
| -rw-r--r-- | static/style.css | 113 |
4 files changed, 240 insertions, 0 deletions
diff --git a/lib/partials.php b/lib/partials.php new file mode 100644 index 0000000..e11e194 --- /dev/null +++ b/lib/partials.php @@ -0,0 +1,11 @@ +<?php +function html_navbar() +{ + echo '' ?> + <header> + <a href="/"> + <img src="/static/brand/big.webp" alt="ilt.su"> + </a> + </header> + <?php ; +}
\ No newline at end of file diff --git a/lib/utils.php b/lib/utils.php new file mode 100644 index 0000000..b81ddda --- /dev/null +++ b/lib/utils.php @@ -0,0 +1,11 @@ +<?php +function json_response(int $code, string|null $message, mixed $data) +{ + header('Content-Type: application/json'); + http_response_code($code); + return json_encode([ + 'status_code' => $code, + 'message' => $message, + 'data' => $data + ], JSON_UNESCAPED_SLASHES); +}
\ No newline at end of file diff --git a/register.php b/register.php new file mode 100644 index 0000000..0804d3d --- /dev/null +++ b/register.php @@ -0,0 +1,105 @@ +<?php +include_once $_SERVER['DOCUMENT_ROOT'] . '/lib/partials.php'; +include_once $_SERVER['DOCUMENT_ROOT'] . '/lib/utils.php'; +include_once $_SERVER['DOCUMENT_ROOT'] . '/lib/config.php'; + +if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $username = $_POST['username'] ?? null; + $password = $_POST['password'] ?? null; + + if (!isset($username, $password)) { + exit(json_response(400, 'Username and password must be sent!', null)); + } + + $username = trim($username); + + if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) { + exit(json_response(400, 'Your username must contain only letters and numbers!', null)); + } + + $username_len = strlen($username); + + if ($username_len < 4 || $username_len > 20) { + exit(json_response(400, 'Your username must be between 4 and 20 characters long', null)); + } + + if (strlen($password) < 8) { + exit(json_response(400, 'Your password must be at least 8 characters long', null)); + } + + $db = new PDO(DB_URL, DB_USER, DB_PASS); + + // checking for already existing accounts + $stmt = $db->prepare('SELECT id FROM users WHERE username = ?'); + $stmt->execute([$username]); + if ($stmt->rowCount() > 0) { + exit(json_response(409, 'This username has been taken.', null)); + } + + $userid = 0; + do { + $userid = random_int(90_000_000_000_000_000, 99_000_000_000_000_000); + $stmt = $db->prepare('SELECT username FROM users WHERE id = ?'); + $stmt->execute([$userid]); + } while ($stmt->rowCount() > 0); + + $password = password_hash($password, PASSWORD_DEFAULT); + $db->prepare('INSERT INTO users(id, username, `password`) VALUES (?, ?, ?)') + ->execute([$userid, $username, $password]); + + $stmt = $db->prepare('SELECT id, username, joined_at FROM users WHERE id = ?'); + $stmt->execute([$userid]); + $user = $stmt->fetch(PDO::FETCH_ASSOC) ?: null; + + exit(json_response(200, null, $user)); +} +?> +<!DOCTYPE html> +<html> + +<head> + <title>Register - id</title> + <link rel="stylesheet" href="/static/style.css"> +</head> + +<body> + <main> + <?php html_navbar(); ?> + + <form action="/register.php" method="post" class="column gap-16"> + <h1>Register new ilt.su account</h1> + + <div class="row"> + <div class="box"> + <div class="tab"> + <p>Account credentials</p> + </div> + <div class="content column gap-8"> + <div class="column"> + <label for="username">Username</label> + <input type="text" name="username" id="username" placeholder="Username" + pattern="^[a-zA-Z0-9_]+$" required> + </div> + <div class="row gap-8"> + <div class="column"> + <label for="password">Password</label> + <input type="password" name="password" id="password" placeholder="Enter password" + required> + </div> + </div> + </div> + </div> + </div> + <div> + <input type="checkbox" name="tos" id="tos" required> + <label for="tos">I accept the <a href="/static/txt/TOS.txt">TOS</a>, including <a + href="/static/txt/PRIVACY.txt">Privacy Policy</a></label> + </div> + <div> + <button type="submit">Register</button> + </div> + </form> + </main> +</body> + +</html>
\ No newline at end of file diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..e2c5064 --- /dev/null +++ b/static/style.css @@ -0,0 +1,113 @@ +:root { + --anchor: #584800; + --anchor-hover: #8a7000; + + --box-primary-color: #ccb800; + --box-secondary-color: #8b6600; + + --button-submit-background: linear-gradient(0deg, #ccb800, #ffe600); + --button-submit-background-hover: linear-gradient(180deg, #ccb800, #ffe600); + --button-submit-border: #8b6600; + --button-submit-color: #302300; +} + +* { + margin: 0; + padding: 0; +} + +body { + width: 100%; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + + font-family: Arial, Helvetica, sans-serif; +} + +main { + display: flex; + flex-direction: column; + width: 50%; +} + +header { + margin: 32px 0; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +a { + color: var(--anchor); + font-weight: bold; +} + +a:hover { + color: var(--anchor-hover); + cursor: pointer; +} + +input[type=text], +input[type=password] { + padding: 4px; + border: 1px solid var(--box-primary-color); +} + +button[type=submit] { + padding: 4px 32px; + font-size: 24px; + background: var(--button-submit-background); + color: var(--button-submit-color); + border: 1px solid var(--button-submit-border); + border-radius: 4px; + text-shadow: 0 1px 0 var(--button-submit-border); +} + +button[type=submit]:hover { + background: var(--button-submit-background-hover); + text-shadow: 0 -1px 0 var(--button-submit-border); + cursor: pointer; +} + +.box { + padding: 8px; + border: 1px solid var(--box-primary-color); +} + +.box:has(.content) { + padding: 0; +} + +.box>.tab { + display: flex; + flex-direction: row; + background: var(--box-primary-color); + color: var(--box-secondary-color); + padding: 4px; + text-transform: uppercase; + font-size: 10px; +} + +.box>.content { + padding: 16px; +} + +.column { + display: flex; + flex-direction: column; +} + +.row { + display: flex; + flex-direction: row; +} + +.gap-8 { + gap: 8px; +} + +.gap-16 { + gap: 16px; +}
\ No newline at end of file |
