diff --git a/app/utils.php b/app/utils.php
index c3feb0c..ed221a4 100644
--- a/app/utils.php
+++ b/app/utils.php
@@ -1,4 +1,7 @@
', "\n", $message);
+ $messageNew = preg_replace('/(.*)<\\/a>/', "$2: $1", $messageNew);
+ return $messageNew;
+}
+
+function sendMail($message, $subject, $title, $preheader): bool {
+ include_once('../lib/phpmailer/Exception.php');
+ include_once('../lib/phpmailer/PHPMailer.php');
+ include_once('../lib/phpmailer/SMTP.php');
+ include_once('app/HTML.php');
+ global $RUNTIME;
+
+ $mailer = new PHPMailer(true);
+
+ try {
+ $mailer->isSMTP();
+ $mailer->Host = $RUNTIME['SMTP']['SERVER'];
+ $mailer->Port = $RUNTIME['SMTP']['PORT'];
+ $mailer->Username = $RUNTIME['SMTP']['ADDRESS'];
+ $mailer->Password = $RUNTIME['SMTP']['PASS'];
+ $mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
+
+ $mailer->setFrom($RUNTIME['SMTP']['ADDRESS'], $RUNTIME['SMTP']['NAME']);
+ $mailer->addAddress($email);
+
+ $mailer->isHTML(true);
+ $mailer->Subject = $subject;
+ $mailHtml = new HTML();
+ $mailHtml->importHTML("email.html");
+ $mailHtml->setHTMLTitle($title);
+ $mailHtml->ReplaceLayoutInhalt('%%MESSAGE%%', $message);
+ $mailHtml->ReplaceLayoutInhalt('%%PREHEADER%%', $preheader);
+ $mailHtml->build();
+ $mailer->Body = $mailHtml->ausgabe();
+ $mailer->AltBody = htmlToPlain($message);
+
+ $mailer->send();
+ return true;
+ } catch(Exception $e) {
+ error_log('Could not send email: '.$mailer->ErrorInfo);
+ return false;
+ }
+}
+
function getDataFromHTTP($URL, $contend = "", $requestTyp = "application/text")
{
try
diff --git a/config.example.php b/config.example.php
index 8633c11..e3f60bb 100644
--- a/config.example.php
+++ b/config.example.php
@@ -7,8 +7,8 @@ $RUNTIME['GRID']['HOMEURL'] = "http://...:8002";
$RUNTIME['SMTP']['SERVER'] = "localhost";
$RUNTIME['SMTP']['PORT'] = 25;
-$RUNTIME['SMTP']['ADRESS'] = "noreplay@localhost";
-$RUNTIME['SMTP']['USER'] = "noreplay@localhost";
+$RUNTIME['SMTP']['ADDRESS'] = "noreply@localhost";
+$RUNTIME['SMTP']['NAME'] = "4Creative";
$RUNTIME['SMTP']['PASS'] = "...";
$RUNTIME['TOOLS']['IMAGESERVICE'] = "https://image-service.4creative.net/";
diff --git a/pages/forgot.php b/pages/forgot.php
new file mode 100644
index 0000000..940ee1c
--- /dev/null
+++ b/pages/forgot.php
@@ -0,0 +1,67 @@
+ wir haben soeben eine Anfrage zur Zurücksetzung des Passworts für deinen 4Creative-Account erhalten. Klicke hier , um ein neues Passwort festzulegen. Dieser Link läuft in 24 Stunden ab. Falls du diese Anfrage nicht gesendet hast, ignoriere sie einfach. Bei weiteren Fragen kannst du uns unter info@4creative.net oder per Discord über @ikeytan erreichen.';
+
+ $HTML = new HTML();
+ $HTML->setHTMLTitle("Passwort vergessen");
+ $HTML->importHTML("forgot.html");
+
+ if($_SERVER['REQUEST_METHOD'] == 'POST') {
+ include_once 'app/FormValidator.php';
+ $validator = new FormValidator(array(
+ 'username' => array('required' => true, 'regex' => '/^[^\\/<>\s]{1,64} [^\\/<>\s]{1,64}$/'),
+ 'email' => array('required' => true, 'regex' => '/^\S{1,64}@\S{1,250}.\S{2,64}$/')
+ ));
+
+ if(!$validator->isValid($_POST)) {
+ $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', 'Bitte gebe deinen Benutzernamen (Vor- und Nachname) und die dazugehörige E-Mail-Adresse ein');
+ $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', 'red');
+ }
+ else {
+ $nameParts = explode(" ", $_POST['username']);
+ $email = strtolower(trim($_POST['email']));
+
+ $getAccount = $RUNTIME['pdo']->prepare('SELECT Email,FirstName,LastName,PrincipalID FROM UserAccounts WHERE FirstName = ? AND LastName = ? AND Email = ?');
+ $getAccount->execute([trim($nameParts[0]), trim($nameParts[1]), $email]);
+ $validRequest = $getAccount->rowCount() == 1;
+ if($res = $getAccount->fetch()) {
+ $email = $res['Email'];
+ $uuid = $res['PrincipalID'];
+ $name = $res['FirstName'].' '.$res['LastName'];
+ }
+
+ foreach($blockedDomains as $domain) {
+ if(str_ends_with($email, $domain)) {
+ $validRequest = false;
+ }
+ }
+
+ $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', 'Falls Name und E-Mail-Adresse bei uns registriert sind, erhältst du in Kürze eine E-Mail mit weiteren Informationen.');
+ $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', 'green');
+ $HTML->build();
+ echo $HTML->ausgabe();
+ fastcgi_finish_request();
+
+ if($validRequest) {
+ $getReqTime = $RUNTIME['pdo']->prepare('SELECT RequestTime FROM PasswordResetTokens WHERE PrincipalID=?');
+ $getReqTime->execute([$uuid]);
+ if(($res = $getReqTime->fetch()) && time() - $res['RequestTime'] < 900) {
+ return;
+ }
+
+ require_once 'app/utils.php';
+ $token = generateToken(32);
+ $setToken = $RUNTIME['pdo']->prepare('REPLACE INTO PasswordResetTokens(PrincipalID,Token,RequestTime) VALUES(?,?,?)');
+ $setToken->execute([$uuid, $token, time()]);
+
+ sendMail(str_replace('%%NAME%%', $name, str_replace('%%RESET_LINK%%', 'https://'.$RUNTIME['DOMAIN'].'/index.php?page=reset-password&token='.$token, MESSAGE)), "Zurücksetzung des Passworts für ".$name, 'Dein Passwort zurücksetzen', 'Folge diesen Anweisungen, um ein neues Passwort für deinen 4Creative-Account festzulegen');
+ }
+ }
+ }
+ else {
+ $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', '');
+ $HTML->ReplaceLayoutInhalt('%%MESSAGECOLOR%%', 'red');
+ $HTML->build();
+ echo $HTML->ausgabe();
+ }
+
+?>
\ No newline at end of file
diff --git a/pages/login.php b/pages/login.php
index f0e6444..d330678 100644
--- a/pages/login.php
+++ b/pages/login.php
@@ -38,7 +38,7 @@
$_SESSION['SALT'] = $rowAuth['passwordSalt'];
$_SESSION['UUID'] = $rowUser['PrincipalID'];
$_SESSION['LEVEL'] = $rowUser['UserLevel'];
- $_SESSION['DISPLAYNAME'] = strtoupper(trim($_POST['username']));
+ $_SESSION['DISPLAYNAME'] = strtoupper($rowUser['FirstName'].' '.$rowUser['LastName']);
$_SESSION['LOGIN'] = 'true';
header("Location: index.php?page=".urlencode($_REQUEST['page']));
@@ -47,15 +47,21 @@
}
}
- $HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "Benutzername und/oder Passwort falsch.");
- $HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", htmlspecialchars($_POST['username']));
+ $HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "Benutzername und/oder Passwort falsch.");
+ $HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", htmlspecialchars($_POST['username']));
}
}
+ else if(isset($_SESSION) && isset($_SESSION['resetMessage'])) {
+ unset($_SESSION['resetMessage']);
+ $HTML->ReplaceLayoutInhalt('%%LOGINMESSAGE%%', 'Du kannst dich jetzt mit deinem neuen Passwort einloggen!');
+ $HTML->ReplaceLayoutInhalt("%%MESSAGECOLOR%%", "darkgreen");
+ }
if(isset($_REQUEST['page']) && preg_match('/^[0-9a-zA-Z]{1-100}$/', $_REQUEST['page']) && file_exists("./pages/".$_REQUEST['page'].".php"))
$HTML->ReplaceLayoutInhalt("%%PAGENAME%%", urlencode($_REQUEST['page']));
$HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "");
+ $HTML->ReplaceLayoutInhalt("%%MESSAGECOLOR%%", "red");
$HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", "");
$HTML->ReplaceLayoutInhalt("%%PAGENAME%%", "dashboard");
diff --git a/pages/reset-password.php b/pages/reset-password.php
new file mode 100644
index 0000000..71ff68c
--- /dev/null
+++ b/pages/reset-password.php
@@ -0,0 +1,71 @@
+ das Passwort für deinen 4Creative-Account wurde soeben über die Funktion "Passwort vergessen" geändert. Solltest du diese Änderung nicht selbst durchgeführt haben, wende dich bitte umgehend per E-Mail (info@4creative.net) oder Discord (@ikeytan) an uns.';
+
+ function displayTokenError() {
+ $HTML = new HTML();
+ $HTML->importHTML("error.html");
+ $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', 'Dieser Link zur Passwortzurücksetzung ist nicht gültig. Bitte klicke oder kopiere den Link aus der E-Mail, die du erhalten hast.');
+ $HTML->build();
+ exit();
+ }
+
+ function displayPage($err) {
+ $HTML = new HTML();
+ $HTML->setHTMLTitle("");
+ $HTML->importHTML("reset-password.html");
+ $HTML->ReplaceLayoutInhalt('%%MESSAGE%%', $err);
+ $HTML->build();
+ echo $HTML->ausgabe();
+ exit();
+ }
+
+ if($_SERVER['REQUEST_METHOD'] == 'POST') {
+ include_once 'app/FormValidator.php';
+ $validator = new FormValidator(array(
+ 'password' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
+ 'passwordRepeat' => array('required' => true, 'regex' => '/^.{1,1000}$/'),
+ 'resetToken' => array('required' => true, 'regex' => '/^[a-zA-Z0-9]{32}$/')
+ ));
+
+ if($validator->isValid($_POST)) {
+ if($_POST['password'] !== $_POST['passwordRepeat']) {
+ displayPage('Du musst in beiden Feldern das gleiche Passwort eingeben');
+ }
+
+ if(strlen($_POST['password']) < $RUNTIME['PASSWORD_MIN_LENGTH']) {
+ displayPage('Dein Passwort muss mindestens '.$RUNTIME['PASSWORD_MIN_LENGTH'].' Zeichen lang sein.');
+ }
+
+ $getUuid = $RUNTIME['PDO']->prepare('SELECT PrincipalID,FirstName,LastName FROM PasswordResetTokens JOIN UserAccounts ON PasswordResetTokens.PrincipalID = PasswordResetTokens.PrincipalID WHERE Token = ?');
+ if($getUuid->rowCount() == 0) {
+ displayTokenError();
+ }
+
+ $res = $getUuid->fetch();
+ $uuid = $res['PrincipalID'];
+ $name = $res['FirstName'].' '.$res['LastName'];
+ $getToken = $RUNTIME['PDO']->prepare('DELETE FROM PasswordResetTokens WHERE Token = ?');
+ $getToken->execute([$_POST['resetToken']]);
+
+ $salt = bin2hex(random_bytes(16));
+ $hash = md5(md5(trim($_POST['password'])).':'.$salt);
+ $statement = $RUNTIME['PDO']->prepare('UPDATE auth SET passwordHash = :PasswordHash, passwordSalt = :PasswordSalt WHERE UUID = :PrincipalID');
+ $statement->execute(['PasswordHash' => $hash, 'PasswordSalt' => $salt, 'PrincipalID' => $uuid]);
+
+ session_unset();
+ $_SESSION['resetPassword'] = true;
+
+ require_once 'app/utils.php';
+ sendMail(str_replace('%%NAME%%', $name, MESSAGE), 'Passwort für '.$name.' zurückgesetzt', 'Passwort geändert', 'Das Passwort für deinen 4Creative-Account wurde soeben zurückgesetzt');
+
+ header('Location: index.php?page=login');
+ exit();
+ }
+ }
+
+ displayPage('');
+
+ if(!isset($_GET['token']) || !preg_match('/^[a-z0-9A-Z]{32}$/', $_GET['token'])) {
+ displayTokenError();
+ }
+?>
\ No newline at end of file
diff --git a/templates/error.html b/templates/error.html
new file mode 100644
index 0000000..c037e70
--- /dev/null
+++ b/templates/error.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+ Fehler - MCP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/forgot.html b/templates/forgot.html
new file mode 100644
index 0000000..71489a8
--- /dev/null
+++ b/templates/forgot.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+ Passwort vergessen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/login.html b/templates/login.html
index b2db1a6..633059a 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -27,7 +27,7 @@
Login
-
+
%%LOGINMESSAGE%%
@@ -47,7 +47,7 @@
diff --git a/templates/mail.html b/templates/mail.html
index a99fc53..232d9d6 100644
--- a/templates/mail.html
+++ b/templates/mail.html
@@ -3,7 +3,7 @@
- Simple Transactional Email
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- %%EchoInhalt%%
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/templates/reset-password.html b/templates/reset-password.html
new file mode 100644
index 0000000..97277bf
--- /dev/null
+++ b/templates/reset-password.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+ Neues Password festlegen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file