diff options
author | Jonas Kohl | 2024-09-15 19:55:12 +0200 |
---|---|---|
committer | Jonas Kohl | 2024-09-15 19:55:12 +0200 |
commit | cb9b87997993702131ca24d4d0e1fd45ef64805c (patch) | |
tree | 3ba1725028665f90b546703c461394b577b3e596 /src/index.php | |
parent | cc97f36b8c9a9522636d5b50fbcd2f52de06a01a (diff) |
Begun i18n work & more
Diffstat (limited to 'src/index.php')
-rw-r--r-- | src/index.php | 159 |
1 files changed, 112 insertions, 47 deletions
diff --git a/src/index.php b/src/index.php index c75d112..de46204 100644 --- a/src/index.php +++ b/src/index.php @@ -12,6 +12,9 @@ use mystic\forum\orm\UserPermissions; use mystic\forum\utils\FileUtils; use mystic\forum\utils\RequestUtils; use mystic\forum\utils\ValidationUtils; +use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Email; header_remove("X-Powered-By"); @@ -122,12 +125,15 @@ function env(string $key): ?string { require_once __DIR__ . "/vendor/autoload.php"; +require_once __DIR__ . "/application/i18n.php"; +i18n_locale("de"); + $db = null; try { $db = new Database(Database::getConnectionString("db", getenv("POSTGRES_USER"), getenv("POSTGRES_PASSWORD"), getenv("POSTGRES_DBNAME"))); } catch (DatabaseConnectionException $ex) { Messaging::error([ - Messaging::bold("Failed to connect to database!"), + Messaging::bold(__("Failed to connect to database!")), Messaging::italic($ex->getMessage()), ]); exit; @@ -175,7 +181,7 @@ $GLOBALS["currentUser"] = &$currentUser; if ($_action === "auth") { if ($currentUser) { - header("Location: " . $_GET["next"] ?? "."); + header("Location: " . ($_GET["next"] ?? ".")); exit; } @@ -186,17 +192,17 @@ if ($_action === "auth") { $user = new User(); $user->name = $username; if (!$db->fetchWhere($user, "name") || !password_verify($password, $user->passwordHash)) { - RequestUtils::triggerFormError("Username or password incorrect!"); + RequestUtils::triggerFormError(__("Username or password incorrect!")); } if (!$user->activated) { - RequestUtils::triggerFormError("Please activate your user account first!"); + RequestUtils::triggerFormError(__("Please activate your user account first!")); } RequestUtils::setAuthorizedUser($user); - header("Location: " . $_GET["next"] ?? "."); + header("Location: " . ($_GET["next"] ?? ".")); } else { - _view("template_start", ["_title" => "Log in"]); + _view("template_start", ["_title" => __("Log in")]); _view("template_navigation_start"); _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($db)]); _view("template_navigation_end"); @@ -205,19 +211,19 @@ if ($_action === "auth") { } } elseif ($_action === "register") { if ($currentUser) { - header("Location: " . $_GET["next"] ?? "."); + header("Location: " . ($_GET["next"] ?? ".")); exit; } if (!REGISTRATION_ENABLED) { http_response_code(403); - Messaging::error("Public registration disabled"); + Messaging::error(__("Public registration disabled")); exit; } if (RequestUtils::isRequestMethod("POST")) { $doNotFill = $_POST["username"] ?? null; - if ($doNotFill !== null) { + if (!empty($doNotFill)) { sleep(10); http_response_code(204); exit; @@ -229,27 +235,27 @@ if ($_action === "auth") { $displayName = RequestUtils::getRequiredField("display_name"); $captcha = RequestUtils::getRequiredField("captcha"); - if ($captcha !== $_SESSION["captchaPhrase"]) { - RequestUtils::triggerFormError("Incorrect CAPTCHA text!"); + if ($captcha !== ($_SESSION["captchaPhrase"] ?? null)) { + RequestUtils::triggerFormError(__("Incorrect CAPTCHA text!")); } // usernames are always lowercase $username = strtolower($username); if ($password !== $passwordRetype) { - RequestUtils::triggerFormError("Passwords do not match!"); + RequestUtils::triggerFormError(__("Passwords do not match!")); } if (strlen($password) < 8) { - RequestUtils::triggerFormError("Password too short! Your password must consist of 8 or more characters"); + RequestUtils::triggerFormError(__("Password too short! Your password must consist of 8 or more characters")); } if (!ValidationUtils::isUsernameValid($username)) { - RequestUtils::triggerFormError("Username has an invalid format"); + RequestUtils::triggerFormError(__("Username has an invalid format")); } if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { - RequestUtils::triggerFormError("Invalid email address"); + RequestUtils::triggerFormError(__("Invalid email address")); } $user = new User(); @@ -257,11 +263,11 @@ if ($_action === "auth") { $user->email = $email; if ($db->fetchWhere($user, "name")) { - RequestUtils::triggerFormError("This username is already taken!"); + RequestUtils::triggerFormError(__("This username is already taken!")); } if ($db->fetchWhere($user, "email")) { - RequestUtils::triggerFormError("This email address is already in use!"); + RequestUtils::triggerFormError(__("This email address is already in use!")); } // re-create user so we don't forget to clear properties set by the above queries @@ -278,26 +284,85 @@ if ($_action === "auth") { $user->activationToken = $db->generateId(12); $user->created = new \DateTimeImmutable(); - // TODO Send verification email + Transport::fromDsn(env("MAILER_DSN"))->send( + (new Email()) + ->from(env("MAILER_FROM")) + ->to(new Address($email, $displayName)) + ->text(__( + "Welcome to %forum_title%, %user_display_name%!\n" . + "\n" . + "Please activate your account by clicking the link below:\n" . + "%activation_link%\n" . + "\n" . + "Kind regards,\n" . + "%forum_copyright%", + params: [ + "forum_title" => (env("MYSTIC_FORUM_TITLE") ?? "Forum"), + "user_display_name" => $displayName, + "activation_link" => env("PUBLIC_URL") . "?_action=verifyemail&token=" . urlencode($user->activationToken) . "&sig=" . urlencode(base64_encode(hash("sha256", env("SECRET") . $user->activationToken . $user->id, true))), + "forum_copyright" => (env("MYSTIC_FORUM_COPYRIGHT") ?? env("MYSTIC_FORUM_TITLE") ?? "Forum") + ] + )) + ->subject("Please activate your account") + ); $db->insert($user); - Messaging::info([ - "Your account has been created!", - //"Please check your emails for an activation link!", - Messaging::html('<p>Please click <a href="?_action=auth">here</a> to log in!</p>'), - ]); + Messaging::info( + Messaging::html(nl2br(htmlentities(__("Your account has been created!\nPlease check your emails for an activation link!"), true))) + ); } else { - _view("template_start", ["_title" => "Register"]); + _view("template_start", ["_title" => __("Register")]); _view("template_navigation_start"); _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($db)]); _view("template_navigation_end"); _view("form_register"); _view("template_end"); } +} elseif ($_action === "verifyemail") { + RequestUtils::ensureRequestMethod("GET"); + $token = $_GET["token"] ?? throw new Exception("Missing token"); + $sig = $_GET["sig"] ?? throw new Exception("Missing signature"); + + $user = new User(); + $user->activated = false; + $user->activationToken = $token; + + if (!$db->fetchWhere($user, [ "activated", "activation_token" ])) { + http_response_code(400); + Messaging::error(__("Invalid token")); + exit; + } + + $expectedSignature = base64_encode(hash("sha256", env("SECRET") . $user->activationToken . $user->id, true)); + + if ($expectedSignature !== $sig) { + http_response_code(400); + Messaging::error(__("Invalid signature.")); + exit; + } + + $user->activated = true; + $user->activationToken = ""; + + if (!$db->update($user)) { + http_response_code(400); + Messaging::error(__("Failed to update user")); + exit; + } + + Messaging::info([ + Messaging::html(nl2br(__( + "Your account has been activated!\nPlease click %link%here%/link% to log in!", + [ + "link" => '<a href="?_action=auth">', + "/link" => '</a>', + ] + )), true), + ]); } elseif ($_action === "logout") { RequestUtils::unsetAuthorizedUser(); - header("Location: " . $_GET["next"] ?? "."); + header("Location: " . ($_GET["next"] ?? ".")); } elseif ($_action === "viewtopic") { $topicId = $_GET["topic"] ?? throw new Exception("Missing topic id"); $topic = new Topic(); @@ -318,19 +383,19 @@ if ($_action === "auth") { $attachments = reArrayFiles($_FILES["files"]); if (count($attachments) > MAX_ATTACHMENT_COUNT) - RequestUtils::triggerFormError("Too many attachments"); + RequestUtils::triggerFormError(__("Too many attachments")); // check all attachments before saving one foreach ($attachments as $att) { if ($att["size"] > MAX_ATTACHMENT_SIZE) { - RequestUtils::triggerFormError("Individual file size exceeded"); + RequestUtils::triggerFormError(__("Individual file size exceeded")); } } $message = trim(RequestUtils::getRequiredField("message")); if (strlen($message) < 1 || strlen($message) > 0x8000) { - RequestUtils::triggerFormError("Message too short or too long!"); + RequestUtils::triggerFormError(__("Message too short or too long!")); } $post = new Post(); @@ -425,21 +490,21 @@ if ($_action === "auth") { $attachments = reArrayFiles($_FILES["files"]); if (count($attachments) > MAX_ATTACHMENT_COUNT) - RequestUtils::triggerFormError("Too many attachments"); + RequestUtils::triggerFormError(__("Too many attachments")); // check all attachments before saving one foreach ($attachments as $att) { if ($att["size"] > MAX_ATTACHMENT_SIZE) { - RequestUtils::triggerFormError("Individual file size exceeded"); + RequestUtils::triggerFormError(__("Individual file size exceeded")); } } if (strlen($title) < 1 || strlen($title) > 255) { - RequestUtils::triggerFormError("Title too short or too long!"); + RequestUtils::triggerFormError(__("Title too short or too long!")); } if (strlen($message) < 1 || strlen($message) > 0x8000) { - RequestUtils::triggerFormError("Message too short or too long!"); + RequestUtils::triggerFormError(__("Message too short or too long!")); } $topic = new Topic(); @@ -479,7 +544,7 @@ if ($_action === "auth") { header("Location: ?_action=viewtopic&topic=" . urlencode($topic->id)); } else { - _view("template_start", ["_title" => "New topic"]); + _view("template_start", ["_title" => __("New topic")]); _view("template_navigation_start"); _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($db)]); _view("template_navigation_end"); @@ -495,7 +560,7 @@ if ($_action === "auth") { if (!$db->fetchWhere($user, "name")) { http_response_code(404); - Messaging::error("No user with name @$userHandle"); + Messaging::error(__("No user with name @%user_handle%", [ "user_handle" => $userHandle ])); exit; } @@ -506,7 +571,7 @@ if ($_action === "auth") { $user->id = $userId; if (!$db->fetch($user)) { http_response_code(404); - Messaging::error("No user exists with this id"); + Messaging::error(__("No user exists with this id")); exit; } @@ -531,12 +596,12 @@ if ($_action === "auth") { if ($userName !== $user->name) { if ($lastNameChangeTooRecent) { - RequestUtils::triggerFormError("You can only change your username every 30 days!"); + RequestUtils::triggerFormError(__("You can only change your username every 30 days!")); } else { if (!ValidationUtils::isUsernameValid($userName)) - RequestUtils::triggerFormError("Invalid username!"); + RequestUtils::triggerFormError(__("Invalid username!")); if (!ValidationUtils::isUsernameAvailable($db, $userName)) - RequestUtils::triggerFormError("This username is already taken!"); + RequestUtils::triggerFormError(__("This username is already taken!")); $user->name = $userName; $user->nameLastChanged = new DateTimeImmutable(); } @@ -551,13 +616,13 @@ if ($_action === "auth") { break; case "replace": { if (!isset($_FILES["pfp"]) || $_FILES["pfp"]["error"] !== UPLOAD_ERR_OK) { - RequestUtils::triggerFormError("Please upload an image to change your profile picture"); + RequestUtils::triggerFormError(__("Please upload an image to change your profile picture")); } $im = @imagecreatefromjpeg($_FILES["pfp"]["tmp_name"]); if ($im === false) $im = @imagecreatefrompng($_FILES["pfp"]["tmp_name"]); if ($im === false) - RequestUtils::triggerFormError("Please upload a valid PNG or JPEG file"); + RequestUtils::triggerFormError(__("Please upload a valid PNG or JPEG file")); /** @var \GdImage $im */ $thumb = imagecreatetruecolor(64, 64); imagecopyresampled($thumb, $im, 0, 0, 0, 0, 64, 64, imagesx($im), imagesy($im)); @@ -575,7 +640,7 @@ if ($_action === "auth") { } if (!$db->update($user)) - RequestUtils::triggerFormError("Failed to save changes"); + RequestUtils::triggerFormError(__("Failed to save changes", context: "Update profile")); header("Location: $_SERVER[REQUEST_URI]"); } else { @@ -605,7 +670,7 @@ if ($_action === "auth") { } elseif ($_action === "attachment") { if (!$currentUser) { http_response_code(403); - Messaging::error("You must be logged in to view attachments"); + Messaging::error(__("You must be logged in to view attachments")); exit; } @@ -614,7 +679,7 @@ if ($_action === "auth") { $attachment->id = $attId; if (!$db->fetch($attachment)) { http_response_code(404); - Messaging::error("No attachment exists with this id"); + Messaging::error(__("No attachment exists with this id")); exit; } @@ -645,7 +710,7 @@ if ($_action === "auth") { $user->id = $userId; if (!$db->fetch($user)) { http_response_code(404); - Messaging::error("No user exists with this id"); + Messaging::error(__("No user exists with this id")); exit; } @@ -682,13 +747,13 @@ if ($_action === "auth") { $attachment->id = $attId; if (!$db->fetch($attachment)) { http_response_code(404); - Messaging::error("No attachment exists with this id"); + Messaging::error(__("No attachment exists with this id")); exit; } if (!str_starts_with($attachment->mimeType, "image/")) { http_response_code(400); - Messaging::error("Attachment is not an image"); + Messaging::error(__("Attachment is not an image")); exit; } @@ -805,7 +870,7 @@ if ($_action === "auth") { header("Location: ?_action=viewtopic&topic=" . urlencode($post->topicId)); } else { - _view("template_start", ["_title" => "Delete post"]); + _view("template_start", ["_title" => __("Delete post")]); _view("template_navigation_start"); _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($db)]); _view("template_navigation_end"); |