diff options
Diffstat (limited to 'src/application/actions/viewuser/post.php')
-rw-r--r-- | src/application/actions/viewuser/post.php | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/application/actions/viewuser/post.php b/src/application/actions/viewuser/post.php new file mode 100644 index 0000000..e16a6a8 --- /dev/null +++ b/src/application/actions/viewuser/post.php @@ -0,0 +1,173 @@ +<?php + +use mystic\forum\orm\User; +use mystic\forum\orm\UserPermissions; +use mystic\forum\utils\RequestUtils; +use mystic\forum\utils\ValidationUtils; +use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Email; + +$formId = $_POST["form_id"] ?? null; +if ($formId === null) { + http_response_code(400); + msg_error("Missing form_id"); + exit; +} + +if ($formId === "update_password") { + if (!$currentUser) { + http_response_code(403); + msg_error(__("You must be logged in to update your password")); + exit; + } + + if (!$isOwnProfile) { + RequestUtils::triggerFormError(__("You don't have permission to update this user's password"), $formId); + } + + RequestUtils::ensureRequestMethod("POST"); + $currentPassword = RequestUtils::getRequiredField("current_password", $formId); + $newPassword = RequestUtils::getRequiredField("new_password", $formId); + $retypePassword = RequestUtils::getRequiredField("retype_password", $formId); + + if (!password_verify($currentPassword, $currentUser->passwordHash)) { + RequestUtils::triggerFormError(__("Current password is incorrect"), $formId); + } + + 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); + } + + $currentUser->passwordHash = password_hash($newPassword, PASSWORD_DEFAULT); + + if (!$db->update($currentUser)) { + RequestUtils::triggerFormError(__("Failed to update password"), $formId); + } + + header("Location: $_SERVER[REQUEST_URI]"); +} elseif ($formId === "update_profile") { + if (!$currentUser) { + http_response_code(403); + msg_error(__("You must be logged in to update your profile")); + exit; + } + + $canEdit = ($currentUser?->id === $user?->id && $user?->hasPermission(UserPermissions::EDIT_OWN_USER)) + || ($currentUser?->hasPermission(UserPermissions::EDIT_OTHER_USER)); + + if (!$canEdit) { + http_response_code(403); + msg_error(__("You don't have permission to update this profile")); + exit; + } + + $displayName = RequestUtils::getRequiredField("display_name", $formId); + $pfpAction = RequestUtils::getRequiredField("pfp_action", $formId); + + $userName = $_POST["name"] ?? $user->name; + $email = $_POST["email"] ?? $user->email; + + $user->displayName = $displayName; + + $userName = strtolower($userName); + + if ($userName !== $user->name) { + if ($lastNameChangeTooRecent) { + RequestUtils::triggerFormError(__("You can only change your username every 30 days!"), $formId); + } else { + if (!ValidationUtils::isUsernameValid($userName)) + RequestUtils::triggerFormError(__("Invalid username!"), $formId); + if (!ValidationUtils::isUsernameAvailable($db, $userName)) + RequestUtils::triggerFormError(__("This username is already taken!"), $formId); + $user->name = $userName; + $user->nameLastChanged = new DateTimeImmutable(); + } + } + + if ($email !== $user->email) { + if ($user->pendingEmailCreated !== null) { + RequestUtils::triggerFormError(__("Please verify your email first!"), $formId); + } else { + $queryUser = new User(); + $queryUser->email = $email; + $queryUser->pendingEmail = $email; + if ($db->fetchWhere($queryUser, "email") || $db->fetchWhere($queryUser, "pending_email")) { + RequestUtils::triggerFormError(__("This email address is already in use!"), $formId); + } + $user->pendingEmail = $email; + $user->pendingEmailCreated = new DateTimeImmutable(); + $user->activationToken = $db->generateId(12); + + try { + Transport::fromDsn(env("MAILER_DSN"))->send( + (new Email()) + ->from(env("MAILER_FROM")) + ->to(new Address($email, $displayName)) + ->text(__( + "Hello, %user_display_name%!\n" . + "\n" . + "Please verify your new email address by clicking the link below:\n" . + "%verify_link%\n" . + "\n" . + "Kind regards,\n" . + "%forum_copyright%", + params: [ + "forum_title" => (env("MYSTIC_FORUM_TITLE") ?? "Forum"), + "user_display_name" => $displayName, + "verify_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 verify your email address")) + ); + } catch (TransportException $_) { + RequestUtils::triggerFormError(__("Failed to send verification email"), $formId); + } + } + } + + switch ($pfpAction) { + case "keep": + // Do nothing + break; + case "remove": + $user->profilePicture = null; + break; + case "replace": { + if (!isset($_FILES["pfp"]) || $_FILES["pfp"]["error"] !== UPLOAD_ERR_OK) { + RequestUtils::triggerFormError(__("Please upload an image to change your profile picture"), $formId); + } + $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"), $formId); + /** @var \GdImage $im */ + $thumb = imagecreatetruecolor(64, 64); + imagecopyresampled($thumb, $im, 0, 0, 0, 0, 64, 64, imagesx($im), imagesy($im)); + imagedestroy($im); + $stream = fopen("php://memory", "w+"); + imagejpeg($thumb, $stream, 50); + rewind($stream); + imagedestroy($thumb); + $user->profilePicture = stream_get_contents($stream); + fclose($stream); + } break; + default: + RequestUtils::triggerFormError("Invalid value for pfp_action", $formId); + break; + } + + if (!$db->update($user)) + RequestUtils::triggerFormError(__("Failed to save changes", context: "Update profile"), $formId); + + header("Location: $_SERVER[REQUEST_URI]"); +} else { + msg_error("Invalid formId"); +} |