phpmailer passwort reset

This commit is contained in:
Peter Hoppe
2023-02-08 16:09:00 +01:00
parent 9821f20dee
commit 0c5cfcbd19
15 changed files with 247 additions and 56 deletions

View File

@ -0,0 +1,22 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
class CNetcupMailer extends PHPMailer
{
public function __construct($debug = false)
{
parent::__construct($debug);
// $this->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output
$this->SMTPDebug = SMTP::DEBUG_OFF; //no output
$this->isSMTP(); //Send using SMTP
$this->Host = 'mxe8bd.netcup.net'; //Set the SMTP server to send through
$this->SMTPAuth = true; //Enable SMTP authentication
$this->Username = 'dog@hope-fly.de'; //SMTP username
$this->Password = 'DgQduKV6uBWXQcCqmAjL'; //SMTP password
$this->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
$this->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
}
}
?>

View File

@ -1,20 +1,4 @@
<?php <?php
class CNetcupMailer extends PHPMailer
{
public function __construct($debug = false)
{
parent::__construct($debug);
$this->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output
$this->isSMTP(); //Send using SMTP
$this->Host = 'mxe8bd.netcup.net'; //Set the SMTP server to send through
$this->SMTPAuth = true; //Enable SMTP authentication
$this->Username = 'dog@hope-fly.de'; //SMTP username
$this->Password = 'DgQduKV6uBWXQcCqmAjL'; //SMTP password
$this->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
$this->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
}
}
class CMsg class CMsg
{ {
var $success; var $success;

View File

@ -1,4 +1,8 @@
<?php <?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access"); header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: POST"); header("Access-Control-Allow-Methods: POST");
@ -7,6 +11,12 @@ header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers
session_start(); session_start();
//Load Composer's autoloader
require __DIR__.'/../../vendor/autoload.php';
require __DIR__.'/classes/CNetcupMailer.php';
require __DIR__.'/classes/Database.php'; require __DIR__.'/classes/Database.php';
require __DIR__.'/classes/lib.php'; require __DIR__.'/classes/lib.php';
@ -77,27 +87,45 @@ $headers .= 'Bcc: ' . 'dog@hope-fly.de' . "\r\n\r\n";
//var_dump($headers); //var_dump($headers);
try
{ $mail = new CNetcupMailer();
$ret = mail($toEmail, $subject, $msg, $headers);
if($ret)
try {
//Server settings
//Recipients
$mail->setFrom($fromEmail);
$mail->addAddress($toEmail); //Add a recipient
$mail->addReplyTo($fromEmail);
$mail->addCC($fromEmail);
$mail->addBCC('dog@hope-fly.de');
//Attachments
//Content
$mail->Subject = $subject;
$mail->Body = $msg;
if ($mail->send())
{ {
$result = new CMsg(1, 200, "Email send successfully."); $result = new CMsg(1, 200, "Email send successfully.");
$storeResult = storeEmail(); $storeResult = storeEmail();
} }
else else
{ {
$result = new CMsg(1, 500, "Sorry, there was an error sending your email your file."); $result = new CMsg(1, 500, "Sorry, there was an error sending your email.");
} }
echo $result->jsonarray(); echo $result->jsonarray();
} }
catch (Exception $e) catch (Exception $e)
{ {
$result = new CMsg(0, 500, $e->getMessage() ); $err = "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
$err .= "\r\n" . $e->getMessage();
$result = new CMsg(0, 500, $err);
echo $result->jsonarray(); echo $result->jsonarray();
} }
function storeEmail() function storeEmail()
{ {
global $qr_id, $conn, $msg, $fromEmail; global $qr_id, $conn, $msg, $fromEmail;

View File

@ -16,4 +16,5 @@ $conn = $db_connection->dbConnection();
$auth = new Auth($conn, $allHeaders); $auth = new Auth($conn, $allHeaders);
echo $auth->isValid(); echo $auth->isValid();
//echo (__DIR__);
?> ?>

View File

@ -4,13 +4,13 @@ use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception; use PHPMailer\PHPMailer\Exception;
//Load Composer's autoloader //Load Composer's autoloader
require __DIR__.'../../vendor/autoload.php'; require '../../vendor/autoload.php';
//Load Composer's autoloader require './classes/lib.php';
require __DIR__.'./classes/lib.php';
//Create an instance; passing `true` enables exceptions //Create an instance; passing `true` enables exceptions
$mail = new CNetcupMailer(true); $mail = new CNetcupMailer(true);
//$mail = new PHPMailer(true);
try { try {
@ -26,9 +26,11 @@ try {
//Attachments //Attachments
//Content //Content
$mail->Subject = 'jo subject jo XXXXX'; $mail->Subject = 'aaaa jo subject jo XXXXX';
$mail->Body = 'XXXX This is the txt message bodyThis is the txt message body This is the txt message bodyThis is the txt message body'; $mail->Body = 'aaaaaa XXXX This is the txt message bodyThis is the txt message body This is the txt message bodyThis is the txt message body';
// $mail->send();
// echo 'Message has been NOT sent';
$mail->send(); $mail->send();
echo 'Message has been sent'; echo 'Message has been sent';
} }

View File

@ -3,7 +3,6 @@ import './App.css';
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './components/Login'; import Login from './components/Login';
import Register from './components/Register'; import Register from './components/Register';
import Home from './components/Home';
import Dog from './components/Dog'; import Dog from './components/Dog';
import Qr from './components/Qr'; import Qr from './components/Qr';
import Header from './components/Header'; import Header from './components/Header';
@ -16,6 +15,8 @@ import useSWR from 'swr';
import {getUser} from './services/PhpApi' import {getUser} from './services/PhpApi'
import toast, { Toaster } from 'react-hot-toast'; import toast, { Toaster } from 'react-hot-toast';
import { TUser } from './context/UserContext'; import { TUser } from './context/UserContext';
import PasswordReset from './components/PasswordReset';
import WantNewPw from './components/WantNewPw';
const App: React.FC = () => const App: React.FC = () =>
{ {
@ -60,6 +61,8 @@ const App: React.FC = () =>
<Route path="/login" element={<Login/>} /> <Route path="/login" element={<Login/>} />
<Route path="/reg" element={<Register/>} /> <Route path="/reg" element={<Register/>} />
<Route path="/impressum" element={<Impressum/>} /> <Route path="/impressum" element={<Impressum/>} />
<Route path="/pwreset/:pwtoken" element={<PasswordReset/>} />
<Route path="/wantnewpw" element={<WantNewPw/>} />
{user && <Route path="/upload" element={<FileUpload/>} />} {user && <Route path="/upload" element={<FileUpload/>} />}
{user && <Route path="/profil" element={<Profil/>} />} {user && <Route path="/profil" element={<Profil/>} />}
</Routes> </Routes>

View File

@ -1,4 +1,4 @@
.Login .InputForm
form form
{ {
width: 65%; width: 65%;

View File

@ -1,6 +1,6 @@
import {useState} from 'react'; import {useState} from 'react';
import { Link/*, useNavigate*/ } from 'react-router-dom'; import { Link/*, useNavigate*/ } from 'react-router-dom';
import './Login.css'; import './InputForm.css';
import {getUser, loginUser} from '../services/PhpApi' import {getUser, loginUser} from '../services/PhpApi'
import { toast, Toaster } from 'react-hot-toast'; import { toast, Toaster } from 'react-hot-toast';
import useSWR from 'swr'; import useSWR from 'swr';
@ -67,7 +67,7 @@ const Login = () =>
} }
return ( return (
<div className='Login'> <div className='InputForm'>
<Toaster toastOptions={{ position: "top-center" }} /> <Toaster toastOptions={{ position: "top-center" }} />
<h2>Login</h2> <h2>Login</h2>
@ -82,6 +82,7 @@ const Login = () =>
</div> </div>
<button type="submit">Login</button> <button type="submit">Login</button>
<div className="bottom-link"><Link to="/reg">Register</Link></div> <div className="bottom-link"><Link to="/reg">Register</Link></div>
<div className="bottom-link"><Link to="/wantnewpw">Passwort vergessen</Link></div>
</form> </form>
</div> </div>
) )

View File

@ -0,0 +1,82 @@
import React, { useState } from 'react'
import toast, { Toaster } from 'react-hot-toast';
import { Link, useParams } from 'react-router-dom';
import { passwordReset } from '../services/PhpApi';
import './InputForm.css';
export default function PasswordReset()
{
const params = useParams();
const passwordToken = Object.values(params)[0];
const [formData, setFormData] = useState({
password1:'',
password2:''
});
const onChangeInput = (e: React.FormEvent<HTMLInputElement> ) => {
setFormData({
...formData,
[e.currentTarget.name]:e.currentTarget.value
})
}
const submitForm = async (e: React.FormEvent<HTMLFormElement>) =>
{
e.preventDefault();
if(!Object.values(formData).every(val => val.trim() !== ''))
{
toast.error('Bitte alle Felder ausfüllen!');
return;
}
if(formData.password1 !== formData.password2)
{
toast.error('Bitte 2mal das gleiche Passwort eingeben!');
return;
}
const sendData = new FormData();
const values = Object.values(formData);
const keys = Object.keys(formData);
for (const key of keys)
{
const index = keys.indexOf(key);
sendData.append(key, values[index]);
}
sendData.append('passwordToken', passwordToken!);
const data = await passwordReset(sendData);
if(data.success)
{
toast.success('Erfolgreich Passwort geändert!');
e.currentTarget.reset();
}
else if(!data.success && data.message)
{
toast.error(data.message);
}
}
return (
<div className='InputForm'>
<Toaster toastOptions={{ position: "top-center" }} />
<h2>Passwort zurücksetzten!</h2>
<form onSubmit={submitForm}>
<div className='neben'>
<label htmlFor="password1">Passwort: </label>
<input type="password" name="password1" onChange={onChangeInput} placeholder="Neues Passwort" id="password1" value={formData.password1} required />
</div>
<div className='neben'>
<label htmlFor="password2">Passwort wiederholen: </label>
<input type="password" name="password2" onChange={onChangeInput} placeholder="Neues Passwort wiederholen!" id="password2" value={formData.password2} required />
</div>
<button type="submit" >Passwort </button>
<div className="bottom-link"><Link to="/login">Login</Link></div>
</form>
</div>
)
}

View File

@ -1,12 +1,3 @@
.Profil
form
{
width: 65%;
display: flex;
flex-direction: column;
align-items: flex-end;
}
button.QRakt button.QRakt
{ {
max-width: 80%; max-width: 80%;

View File

@ -6,6 +6,7 @@ import {TUser} from '../context/UserContext';
import {getProfilData, updateDog} from '../services/PhpApi'; import {getProfilData, updateDog} from '../services/PhpApi';
import CreateQr from '../services/CreateQr'; import CreateQr from '../services/CreateQr';
import Img from './Img'; import Img from './Img';
import './InputForm.css';
import './Profil.css'; import './Profil.css';
function Profil() function Profil()
@ -141,7 +142,7 @@ function Profil()
console.log(formData_loc); console.log(formData_loc);
return ( return (
<div className='Profil'> <div className='InputForm'>
<Toaster toastOptions={{ position: "top-center" }} /> <Toaster toastOptions={{ position: "top-center" }} />
<h2>Profil</h2> <h2>Profil</h2>
<div className='neben'> <div className='neben'>

View File

@ -1,8 +0,0 @@
.Register
form
{
width: 65%;
display: flex;
flex-direction: column;
align-items: flex-end;
}

View File

@ -1,7 +1,7 @@
import {useState} from 'react' import {useState} from 'react'
import {Link} from 'react-router-dom' import {Link} from 'react-router-dom'
import toast, { Toaster } from 'react-hot-toast'; import toast, { Toaster } from 'react-hot-toast';
import './Register.css'; import './InputForm.css';
import {registerUser} from '../services/PhpApi'; import {registerUser} from '../services/PhpApi';
const Register = () => const Register = () =>
@ -48,7 +48,7 @@ const Register = () =>
} }
return ( return (
<div className='Register'> <div className='InputForm'>
<Toaster toastOptions={{ position: "top-center" }} /> <Toaster toastOptions={{ position: "top-center" }} />
<h2>Register</h2> <h2>Register</h2>
<form onSubmit={submitForm}> <form onSubmit={submitForm}>

View File

@ -0,0 +1,52 @@
import React, { useState } from 'react'
import toast, { Toaster } from 'react-hot-toast';
import './ImportForm.css';
function WantNewPw()
{
const [email, setEmail] = useState('');
const onChangeInput = (e: React.FormEvent<HTMLInputElement> ) => {
setEmail(e.currentTarget.value);
}
const submitForm = async (e: React.FormEvent<HTMLFormElement>) =>
{
e.preventDefault();
if(e.currentTarget.value.trim() !== '')
{
toast.error('Bitte Feld ausfüllen!');
return;
}
const data = await wantNewPw(email);
if(data.success)
{
toast.success('Erfolgreich Passwort geändert!');
e.currentTarget.reset();
}
else if(!data.success && data.message)
{
toast.error(data.message);
}
}
return (
<div className='InputForm'>
<Toaster toastOptions={{ position: "top-center" }} />
<h2>Neues Passwort setzen!</h2>
<form onSubmit={submitForm}>
<div className='neben'>
<label htmlFor="email">Email: </label>
<input type="email" name="email" onChange={onChangeInput}
placeholder="Gleiche Email, wie bei der Registrierung angeben"
id="email" value={email} required />
</div>
<button type="submit" >Passwort anfordern</button>
</form>
</div>
)
}
export default WantNewPw

View File

@ -22,7 +22,7 @@ export const updateDog = async ({email, name, phone}:
return data; return data;
} }
catch(err){ catch(err){
return {success:0, message:'Server Error!'}; return {success:0, message:'Update Dog Server Error!'};
} }
} }
@ -81,7 +81,7 @@ export const registerUser = async ({email,password}:
} }
catch(err) catch(err)
{ {
return {success:0, message:'Server Error!'}; return {success:0, message:'Register User Server Error!'};
} }
} }
@ -106,7 +106,7 @@ export const foundMsg = async (form_data:
} }
catch(err) catch(err)
{ {
return {success:0, message:'Server Error!'}; return {success:0, message:'Found Msg Server Error!'};
} }
} }
@ -137,7 +137,7 @@ export const updateQR = async ({qr_width_cm, qr_height_cm, qr_fontsize, qr_visib
} }
catch(err) catch(err)
{ {
return {success:0, message:'Server Error!'}; return {success:0, message:'Update QR Server Error!'};
} }
} }
@ -240,6 +240,38 @@ export const logOut = () =>
.catch((err) => console.error(err)); .catch((err) => console.error(err));
} }
export const passwordReset = async (form_data:
FormData) =>
{
try
{
const {data} = await Axios.post('passwordReset.php', form_data);
console.log('Api passwordReset');
console.log(data);
return data;
}
catch(err)
{
return {success:0, message:'Password Reset Server Error!'};
}
}
export const wantNewPw = async ({email}:{email: string}) =>
{
try
{
const {data} = await Axios.post('wantNewPw.php', {email});
console.log('Api wantNewPw');
console.log(data);
return data;
}
catch(err)
{
return {success:0, message:'Password Reset Server Error!'};
}
}
// export const sleep = (ms: number) => // export const sleep = (ms: number) =>
// { // {
// return new Promise((resolve) => setTimeout(resolve, ms)); // return new Promise((resolve) => setTimeout(resolve, ms));