From 64b1ec0fabbf7328a79a20ff58502ebfa80fad8b Mon Sep 17 00:00:00 2001
From: Jonas Kohl
Date: Thu, 10 Oct 2024 17:33:13 +0200
Subject: Break up actions into individual files

---
 src/application/actions/pwreset/post.php | 107 +++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 src/application/actions/pwreset/post.php

(limited to 'src/application/actions/pwreset/post.php')

diff --git a/src/application/actions/pwreset/post.php b/src/application/actions/pwreset/post.php
new file mode 100644
index 0000000..772b09c
--- /dev/null
+++ b/src/application/actions/pwreset/post.php
@@ -0,0 +1,107 @@
+<?php
+
+use mystic\forum\orm\User;
+use mystic\forum\utils\RequestUtils;
+use Symfony\Component\Mailer\Exception\TransportException;
+use Symfony\Component\Mailer\Transport;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Email;
+
+$token = $_GET["token"] ?? null;
+$signature = $_GET["sig"] ?? null;
+
+if ($token !== null && $signature !== null) {
+    RequestUtils::setFormErrorDestination("?_action=pwreset&token=" . urlencode($token) . "&sig=" . urlencode($signature));
+    $formId = "pwnew";
+    $newPassword = RequestUtils::getRequiredField("new_password", $formId);
+    $retypePassword = RequestUtils::getRequiredField("retype_password", $formId);
+    $resetUser = decodePasswordResetLink($db, $token, $signature);
+
+    if ($resetUser === null) {
+        http_response_code(400);
+        msg_error(__("The password reset link is either invalid or it expired"), true);
+        exit;
+    }
+
+    if ($newPassword !== $retypePassword) {
+        RequestUtils::triggerFormError(__("New passwords don't match"), $formId);
+    }
+
+    if (strlen($newPassword) < 8) {
+        RequestUtils::triggerFormError(__("Password too short! Your password must consist of 8 or more characters"), $formId);
+    }
+
+    $resetUser->passwordHash = password_hash($newPassword, PASSWORD_DEFAULT);
+    $resetUser->passwordResetToken = null;
+    $resetUser->passwordResetTokenCreated = null;
+    
+    if (!$db->update($resetUser)) {
+        RequestUtils::triggerFormError(__("Failed to update password"), $formId);
+    }
+
+    Transport::fromDsn(env("MAILER_DSN"))->send(
+        (new Email())
+            ->from(env("MAILER_FROM"))
+            ->to(new Address($resetUser->email, $resetUser->displayName))
+            ->text(__(
+                "Hello, %user_display_name%!\n" .
+                "\n" .
+                "We are sending this email to let you know your passwort has been reset successfully!\n" .
+                "\n" .
+                "Kind regards,\n" .
+                "%forum_copyright%",
+                params: [
+                    "forum_title" => (env("MYSTIC_FORUM_TITLE") ?? "Forum"),
+                    "user_display_name" => $resetUser->displayName,
+                    "forum_copyright" => (env("MYSTIC_FORUM_COPYRIGHT") ?? env("MYSTIC_FORUM_TITLE") ?? "Forum")
+                ]
+            ))
+            ->subject(__("Password reset successfully!"))
+    );
+
+    msg_info(__("Password reset successfully!"), true);
+} else {
+    $formId = "pwreset";
+    $email = RequestUtils::getRequiredField("email", $formId);
+
+    $user = new User();
+    $user->email = $email;
+
+    if ($db->fetchWhere($user, "email")) {
+        try {
+            Transport::fromDsn(env("MAILER_DSN"))->send(
+                (new Email())
+                    ->from(env("MAILER_FROM"))
+                    ->to(new Address($user->email, $user->displayName))
+                    ->text(__(
+                        "Hello, %user_display_name%!\n" .
+                        "\n" .
+                        "A password reset has been requested successfully! Please click the link below to set a new password:\n" .
+                        "%reset_link%\n" .
+                        "\n" .
+                        "If this wasn't you, you can safely ignore this email. The link will only be valid for one hour.\n" .
+                        "\n" .
+                        "Kind regards,\n" .
+                        "%forum_copyright%",
+                        params: [
+                            "forum_title" => (env("MYSTIC_FORUM_TITLE") ?? "Forum"),
+                            "user_display_name" => $user->displayName,
+                            "reset_link" => generatePasswordResetLink($db, $user),
+                            "forum_copyright" => (env("MYSTIC_FORUM_COPYRIGHT") ?? env("MYSTIC_FORUM_TITLE") ?? "Forum")
+                        ]
+                    ))
+                    ->subject(__("Forgot your password? No problem!"))
+        );
+        } catch (TransportException $_) {
+            // fail silently
+        }
+    } else {
+        // don't make the delay difference too obvious
+        usleep(random_int(900, 4500) * 1000);
+
+        // ideally, at some point we would just want to queue up the email
+        // and send it asynchronously, but this'll have to do for now
+    }
+
+    msg_info(__("If an account exists with the given email address, we will have sent a password reset link to that email address."), true);
+}
-- 
cgit v1.2.3