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"); |