Sending Email with Cakephp 3 - email

I've been using this library for sending mail
https://github.com/PHPMailer/PHPMailer
But I'm not getting the Email Send
Invalid address: (From): XXX
Array ( [error] => 1 [message] => Mailer Error: Invalid address: (From): XXX )
What I did : Disable 2 Step verification into Gmail
And Enabled Allow Less Secure Apps On
PagesController.php
<?php
namespace App\Controller;
class PagesController extends AppController
{
public $components = array("Email");
public function index()
{
$to = 'myemail#gmail.com';
$subject = 'Hi buddy, i got a message for you.';
$message = 'Nothing much. Just test out my Email Component using PHPMailer.';
try {
$mail = $this->Email->send_mail($to, $subject, $message);
print_r($mail);
} catch (Exception $e) {
echo 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
}
exit;
}
}
EmailComponent.php
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Core\App;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require ROOT. '/vendor/phpmailer/phpmailer/src/Exception.php';
require ROOT. '/vendor/phpmailer/phpmailer/src/PHPMailer.php';
require ROOT. '/vendor/phpmailer/phpmailer/src/SMTP.php';
class EmailComponent extends Component {
public function send_mail($to, $subject, $message)
{
// date_default_timezone_set('Asia/Calcutta');
$sender = "XXX"; // this will be overwritten by GMail
$header = "X-Mailer: PHP/".phpversion() . "Return-Path: $sender";
$mail = new PHPMailer();
$mail->SMTPDebug = 2; // turn it off in production
$mail->IsSMTP();
$mail->Host = "smtp.gmail.com";
$mail->SMTPAuth = true;
$mail->Username = "XXX";
$mail->Password = "XXX";
$mail->SMTPSecure = "tls"; // ssl and tls
$mail->Port = 587; // 465 and 587
$mail->SMTPOptions = array (
'tls' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
),
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
$mail->From = $sender;
$mail->FromName = "From Me";
$mail->AddAddress($to);
$mail->IsHTML(true);
$mail->CreateHeader($header);
$mail->Subject = $subject;
$mail->Body = nl2br($message);
$mail->AltBody = nl2br($message);
// return an array with two keys: error & message
if(!$mail->Send()) {
return array('error' => true, 'message' => 'Mailer Error: ' . $mail->ErrorInfo);
} else {
return array('error' => false, 'message' => "Message sent!");
}
}
}

Fixed I had to replace
thoses three lines in EmailComponent
$sender = "xxx#gmail.com";
$mail->Username = "xxx#gmail.com";
$mail->Password = "GMAIL_PASSWORD";

Related

Codeigniter 4 Rest API - 301 Moved Permanently

I have Codeigniter 4 web app that run REST API with firebase/php-jwt on Laragon 5.0.0210523 environment that run Apache-2.4.47, PHP-8.1.7, and MongoDB-4.0.28. I followed a tutorial and it works fine both server REST API and it REST client. After day work, i stop laragon server. In the next day i try run REST API server then tried then run the client but it failed and gave 301 moved permanently error, but i still can access it from postman.
REST API server side
composer.json
***
"require": {
"php": "^7.4 || ^8.0",
"codeigniter4/framework": "^4.0",
"mongodb/mongodb": "^1.12",
"firebase/php-jwt": "^6.3"
},
***
.env file
***
JWT_SECRET_KEY = SomeThing$089
JWT_TIME_TO_LIVE = 3600
app.baseURL = 'http://ci4-api.localhost'
***
Route.php
***
$routes->get('/', 'Home::index');
$routes->resource('api/users');
$routes->post('api/auth', [\App\Controllers\Api\Auth::class, 'index']);
***
JWT_Helper.php
use App\Models\ModelUsers;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
/**
* #throws Exception
*/
function getJWT($authHeader)
{
if (is_null($authHeader)){
throw new Exception("Authentication JWT failed");
}
return explode(" ", $authHeader)[1];
}
function validateJWT($encodedToken)
{
$key = getenv('JWT_SECRET_KEY');
$decodedToken = JWT::decode($encodedToken, new Key($key, 'HS256'));
$modelUsers = new ModelUsers();
$modelUsers->get_email($decodedToken->email);
}
function createJWT($email): string
{
$timeRequest = time();
$timeToken = getenv('JWT_TIME_TO_LIVE');
$timeExpired = $timeRequest + $timeToken;
$payload = [
'email' => $email,
'iat' => $timeRequest,
'exp' => $timeExpired,
];
return JWT::encode($payload, getenv('JWT_SECRET_KEY'), 'HS256');
}
FilterJWT.php
namespace App\Filters;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;
use Exception;
class FilterJWT implements FilterInterface
{
use ResponseTrait;
public function before(RequestInterface $request, $arguments = null)
{
$header = $request->getServer('HTTP_AUTHORIZATION');
try {
helper('jwt');
$encodedToken = getJWT($header);
validateJWT($encodedToken);
return $request;
} catch (Exception $ex) {
return Services::response()->setJSON(
[
'error' => $ex->getMessage(),
]
)->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// TODO: Implement after() method.
}
}
Filters.php
***
public $aliases = [
'csrf' => CSRF::class,
'toolbar' => DebugToolbar::class,
'honeypot' => Honeypot::class,
'invalidchars' => InvalidChars::class,
'secureheaders' => SecureHeaders::class,
'auth' => FilterJWT::class,
];
public $filters = [
'auth' => [
'before' => [
'api/users/*',
'api/users'
]
]
];
***
ModelUsers.php
namespace App\Models;
use App\Libraries\MongoDb;
class ModelUsers
{
private $database = 'ci4_api';
private $collection = 'user';
private $conn;
function __construct()
{
$mongodb = new MongoDb();
$this->conn = $mongodb->getConn();
}
function get_user_list() {
try {
$filter = [];
$query = new \MongoDB\Driver\Query($filter);
$result = $this->conn->executeQuery($this->database. '.' . $this->collection, $query);
return $result->toArray();
} catch (\MongoDB\Driver\Exception\RuntimeException $ex) {
show_error('Error while fetching users: ' . $ex->getMessage(), 500);
}
}
***
Auth.php
namespace App\Controllers\Api;
use App\Controllers\BaseController;
use App\Models\ModelUsers;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Validation\Validation;
use Config\Services;
class Auth extends BaseController
{
use ResponseTrait;
private ModelUsers $model;
private Validation $validation;
function __construct()
{
$this->model = new ModelUsers();
$this->validation = Services::validation();
}
public function index()
{
$email = $this->request->getVar('email');
$password = $this->request->getVar('password');
$password_hash = password_hash($password, PASSWORD_DEFAULT);
$data1 = [
'email' => $email,
'password' => $password
];
if (!$this->validation->run($data1, 'login')) {
$errors = $this->validation->getErrors();
$response = [
'status' => 201,
'error' => null,
'messages' => [
'errors' => [
$errors
]
],
];
return $this->respond($response);
}
$data1 = $this->model->get_email($email);
//return $this->respond($data1, 200);
if (!$data1) {
$response = [
'status' => 201,
'error' => null,
'messages' => [
'error' => 'Data user atau password tidak ada1'
],
];
return $this->respond($response, 200);
}
$password_user = $data1->password;
if (password_verify($password_hash, $password_user) != 0){
$response = [
'status' => 201,
'error' => null,
'messages' => [
'error' => 'Data user atau password tidak ada2'
],
];
return $this->respond($response, 200);
}
helper('jwt');
$response = [
'message' => 'Auth berhasil dilakukan',
'data' => $data1,
'access_token' => createJWT($email)
];
return $this->respond($response, 200);
}
***
users.php
namespace App\Controllers\Api;
use App\Controllers\BaseController;
use App\Models\ModelUsers;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\HTTP\Response;
use CodeIgniter\Validation\Validation;
use Config\Services;
class Users extends BaseController
{
use ResponseTrait;
private ModelUsers $model;
private Validation $validation;
function __construct()
{
$this->model = new ModelUsers();
$this->validation = Services::validation();
}
public function index(): Response
{
$data = $this->model->get_user_list();
$count = count($data);
if ($count <= 0) {
$data = [
'status' => 201,
'error' => null,
'message' => [
'success' => 'Tidak ada data daftar pegawai'
],
];
}
return $this->respond($data, 200);
}
***
REST Client
.env file
***
app.baseURL = 'http://ci4-test.localhost'
***
Routes.php
***
$routes->get('/rest', [\App\Controllers\Rest\RestClient::class, 'index']);
***
RestClient.php
namespace App\Controllers\Rest;
use App\Controllers\BaseController;
use Config\Services;
class RestClient extends BaseController
{
public function index()
{
$client = Services::curlrequest();
$token = "someToken";
$url = "http://ci4-api.localhost/api/users/";
$headers = [
'Authorization' => 'Bearer ' . $token,
];
$response = $client->request('GET', $url, ['headers' => $headers, 'http_errors' => false]);
return $response->getBody();
}
}
Postman
api auth
api all user list
I have already tried some simple solution, like reload all laragon service like apache server and mongodb, restart the windows and tried find online, but it only suggest that the url is incorectly used like in this one []https://stackoverflow.com/questions/56700991/codeigniter-301-moved-permanently[3]
Is there anyone have same issue or solution, thanks in advance.
After trying some few more time, i found the problem. It still around about url similiar like in case of Codeigniter 301 Moved Permanently, but my problem i added "/" on my url.
eg
RestClient.php
//Read all users
$url = "http://ci4-api.localhost/api/users/";
Maybe i added it after copy paste process
so the correct url is
RestClient.php
//Read all users
$url = "http://ci4-api.localhost/api/users";
hopefully help some people facing same problem

How to send Email confirmation link via smtp Cakephp

I am working in cakephp and want to send confirmation link on user signup but i do not know much about SMTP.
Here is What i have written I am using Token to confirm email which will expire next time if user hit the same confirmation link.
Here is usercontroller/signup method:
public function signup()
{
$this->layout = 'main';
if ($this->request->is('post')) {
$this->User->create();
$this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']);
$hash = sha1($this->request->data['User']['username'] . rand(0, 100));
$this->request->data['User']['tokenhash'] = $hash;
if ($this->User->validates()) {
$this->User->save($this->request->data);
$ms = 'Click on the link below to complete registration ';
$ms .= 'http://localhost/FindTutor/users/verify/t:' . $hash . '/n:' . $this->data['User']['username'] . '';
$ms = wordwrap($ms, 70);
$this->Email->from = 'usman.jamil0308#gmail.com';
$this->Email->to = $this->request->data['User']['email'];
$this->Email->subject = 'Confirm Registration..';
$this->Email->send($ms);
$this->Session->setFlash('Please Check your email for validation Link');
$this->redirect('/users/login');
}
}
}
Here is users/verify method to confirm if user hit the confirmation link.
public function verify(){
//check if the token is valid
if (!empty($this->passedArgs['n']) && !empty($this->passedArgs['t'])){
$name = $this->passedArgs['n'];
$tokenhash = $this->passedArgs['t'];
$results = $this->User->findByUsername($name);
if ($results['User']['activate']==0){
//check the token
if($results['User']['tokenhash']==$tokenhash)
{
$results['User']['activate']=1;
//Save the data
$this->User->save($results);
$this->Session->setFlash('Your registration is complete');
$this->redirect('/users/login');
exit;
}
else{
$this->Session->setFlash('Your registration failed please try again');
$this->redirect('/users/register');
}
}
else {
$this->Session->setFlash('Token has alredy been used');
$this->redirect('/users/register');
}
}else
{
$this->Session->setFlash('Token corrupted. Please re-register');
$this->redirect('/users/register');
}
}
Error is somthing like this:
mail(): Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set()
try to use mailjet and configure your sever (wamp or xampp)the directorie sendmail and configure your app.php like that
'EmailTransport' => [
'default' => [
'className' => 'Mail',
// The following keys are used in SMTP transports
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => '',
'password' => '',
'client' => null,
'tls' => null,
],
'mailjet' => [
'className' => 'smtp',
// The following keys are used in SMTP transports
'host' => 'in-v3.mailjet.com',
'username' => 'copy that from your account mailjet',
'password' => 'copy that from your account mailjet',
'port' => 587,
'timeout' => 3000,
'client' => null,
'tls' => null,
],
],
'Email' => [
'default' => [
'transport' => 'mailjet',
'from' => 'xxxxxx#gmail.com',
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
],
],
public $smtp = array(
'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'username' => 'your email id',
'password' => 'your password',
'transport' => 'Smtp',
);
App::uses('CakeEmail', 'Network/Email');
$Email = new CakeEmail('smtp');
$Email->from('info#email.com');
$Email->to($email);
$message = "hello";
$Email->send($message);
First Include Email Component in your App Controller like this :
public $components = array(
'Email'
);
Create a sendMail function in your App controller like this
public function _sendMail( $to, $from, $replyTo, $subject, $element,$parsingParams = array(),$attachments ="", $sendAs = 'html', $bcc = array()){
$port = '';
$timeout = '';
$host = '';
$username = '';
$password = '';
$client = '';
$toAraay = array();
if (!is_array($to)) {
$toAraay[] = $to;
} else {
$toAraay = $to;
}
$this->Email->smtpOptions = array(
'port' => "$port",
'timeout' => "$timeout",
'host' => "$host",
'username' => "$username",
'password' => "$password",
'client' => "$client"
);
$this->Email->delivery = 'smtp';
foreach ($parsingParams as $key => $value) {
$this->set($key, $value);
}
foreach ($toAraay as $email) {
$this->Email->to = $email;
$this->Email->subject = $subject;
$this->Email->replyTo = $replyTo;
$this->Email->from = $from;
if(!empty($bcc)){
$this->Email->cc = $bcc[0];
}
if ($attachments!="") {
$this->Email->attachments = array();
$this->Email->attachments[0] = $attachments ;
}
$this->Email->template = $element;
$this->Email->sendAs = $sendAs;
$this->Email->send();
$this->Email->reset();
}
}
Create a sendmail.ctp file in View/Emails/html
Add this content in file and also add your header or footer
<?php echo $message; ?>
Now whenever you want to send email call this function like this :
$this->_sendMail($to, $from, $replyTo, $subject, 'sendmail', array('message' => $message), "", 'html', $bcc = array());
Now you can implement your logic for verification email like this :
$message = 'Click on the link below to complete registration ';
$message .= 'http://localhost/FindTutor/users/verify/t:' . $hash . '/n:' . $this->data['User']['username'] . '';
$from = 'usman.jamil0308#gmail.com';
$to = $this->request->data['User']['email'];
$subject = 'Confirm Registration..';
$replyTo = 'usman.jamil0308#gmail.com';
$this->_sendMail($to, $from, $replyTo, $subject, 'sendmail', array('message' => $message), "", 'html', $bcc = array());

Zend 1.12 login not working

i'm creating a login system using salt and password two columns but it's not working my code of action
public function indexAction() {
$form = new Admin_Form_Login();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
if ($this->_process($form->getValues())) {
// We're authenticated! Redirect to the home page
$this->_helper->redirector('', 'dashboard');
} else {
echo 'Password is wrong';
}
}
}
$this->view->form = $form;
}
protected function _process($values) {
// Get our authentication adapter and check credentials
$adapter = $this->_getAuthAdapter();
$adapter->setIdentity($values['email']);
$adapter->setCredential($values['password']);
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if ($result->isValid()) {
$user = $adapter->getResultRowObject();
$auth->getStorage()->write($user);
return true;
}
return false;
}
protected function _getAuthAdapter() {
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('eg_user_login')
->setIdentityColumn('email')
->setCredentialColumn('password')
->setCredentialTreatment("MD5(CONCAT(? , salt))");
return $authAdapter;
}
and code of registration action is
$regForm = new Admin_Form_Register();
$this->view->form = $regForm;
if ($this->getRequest()->isPost()) {
if ($regForm->isValid($this->_request->getPost())) {
$values = $regForm->getValues($this->_request->getPost());
$pass = $values['pass1'];
$salt = sha1($pass);
$password = MD5($salt . $pass);
$data = array(
'f_name' => $values['fname'],
'l_name' => $values['lname'],
'gender' => $values['gender'],
'email' => $values['email'],
'contact' => $values['contact'],
'password' => $password,
'salt' => $salt,
'created_on' => date("d-m-y"),
'user_role' => $values['userrole'],
'status' => 0
);
$db = new Admin_Model_Userreg();
$db->insert($data);
}
}
it is displaying any error,i think problem in encryption and decryption in password.
login page is not redirecting to dashboard and not storing the user instance .... please help me. thank you.

how to send a mail using cakephp

I have some code for send to mail but it's not working properly.
My code is here:
class EmailsController extends AppController
{
var $name="Email";
var $uses = NULL;
public function index()
{
App::import('Component', 'Email');
$path=WWW_ROOT."img";
$filename="Desert.jpg";
$email->from = 'pal#gmail.com';
$email->to='abc#gmail.com';
$email->subject='test mail';
$email->template = 'simple_message';
$email->attachments = array($path.$filename);
$email->SendAs='html';
if($email->send())
{
$this->session->setFlash("Email Send Successfully");
}
else
{
$this->session->setFlash("Email is not send");
}
}
}
I am getting the error like:
Call to undefined method stdClass::send()
Why don't you use var $components? Include Email component the right way:
class EmailsController extends AppController
{
var $name="Email";
var $components = array('Email');
var $uses = NULL;
public function index() {
$path=WWW_ROOT."img";
$filename="Desert.jpg";
$this->Email->from = 'pal#gmail.com';
$this->Email->to='abc#gmail.com';
$this->Email->subject='test mail';
$this->Email->template = 'simple_message';
$this->Email->attachments = array($path.$filename);
$this->Email->sendAs='html';
if($this->Email->send()) {
$this->Session->setFlash("Email Send Successfully");
} else {
$this->Session->setFlash("Email is not send");
}
}
}
For more info please visit: http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
<?php
App::uses('CakeEmail', 'Network/Email');
$email = new CakeEmail( $smtp );
$email->to( 'test#example.com' );
$email->subject(__("Reset Password") );
$email->emailFormat('html');
$email->send($body);
?>
For SMTP:
save this below code with "email.php" file in app/Config folder and put your smtp details in $smtp array. and assign $smtp variable in
new CakeEmail($smtp);
<?php
class EmailConfig {
public $default = array(
'transport' => 'Mail',
'from' => 'you#localhost',
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
public $smtp = array(
'transport' => 'Smtp',
'from' => array('site#localhost' => 'My Site'),
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => 'user',
'password' => 'secret',
'client' => null,
'log' => false,
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
}
?>

sending email with cakephp2

I'm having problems sending a mail with cakephp2, I know I can send emails because I have my postfix configured, and I can send e-mails with command line or php. So please, can you send me an example of cakephp2 sending emails.
This is the error message
Invalid email: "you#localhost"
Error: An Internal Error Has Occurred.
I've also tried with the ssl via gmail and it doesn't work either, and it's giving me a really hard time.
thanks guys
by the way, I'm trying the exact example of this url http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
Your app/config/Email.
class EmailConfig {
public $gmail = array(
'port' => '465',
'timeout' => '300',
'host' => 'ssl://smtp.gmail.com',
'username' => '<your_email>#gmail.com',
'password' => '<you_password>',
'transport' => 'Smtp'
); }
your file = app/controller/appController.php insert this function
public function sendEmail($type, $options){
try {
$Email = new CakeEmail($type);
$Email->config($options);
$Email->template = "email_confirmation";
$Email->emailFormat('html');
//$this->idCrudRash = $options;
$Email->send();
} catch (SocketException $e) {
die('Erro ao enviar email:'. $e->getMessage());
$this->log(sprintf('Erro ao enviar email: %s', $e->getMessage()));
}
}
for user: app/controller/contato.php
$options = array(
'emailFormat' => 'html',
'from' => array(
$config['email_noanswer'] => $config['site_name']
),
'subject' => 'Confirmação de Cadastro',
'to' => $this->request->data['User']['email'],
//'template' => 'default',
'template' => 'email_confirmation',
'viewVars' => array(
'title_for_layout' => 'Confirmação de Email ' . $config['site_name'],
'name' => $this->request->data['User']['name'],
'email' => $this->request->data['User']['email'],
//'cpf' => base64_encode($this->request->data['User']['cpf']),
'site_name' => $config['site_name'],
),
);
$this->sendEmail('gmail', $options);
In your email.php file, please remove the default 'from' value, it overrides your passed param.
public $default = array(
'transport' => 'Mail',
'from' => 'you#localhost', // remove this line
...
);
In app/config/Email
public $smtp = array(
'transport' => 'Smtp',
'from' => array('no-reply#xyz.com' => 'no-reply#xyz.com'),
'host' => 'ssl://smtp.abc.com',
'port' => 465,
'timeout' => 30,
'username' => 'username',
'password' => 'password',
'client' => null,
'log' => false,
);
In Your Controller
App::uses('AppController', 'Controller');
App::uses('CakeEmail', 'Network/Email');
public function index()
{
$this->layout = 'layout';
$this->set('title', "Title");
if ($this->request->is('Post')) {
if (!empty($this->request->data)) {
if ($this->Modal->Save($this->request->data)) {
$to = 'test#anc.com';
$subject = 'Your_subject';
$message = $this->request->data;
if ($this->sendmail($to, $subject, $message)) {
echo"sent";die;
}
} else {
echo"wrong";die;
}
}
}
}
public function sendmail($to = null, $subject = '', $messages = null, $ccParam = null, $from = null, $reply = null, $path = null, $file_name = null)
{
$this->layout = false;
$this->render(false);
$name = $messages['Modalname']['name'];
$email = $messages['Modalname']['email'];
$Email = new CakeEmail();
$Email->config('smtp');
$Email->viewVars(array('name' => $name, 'email' => $email));
$Email->template('comman_email_template', 'comman_email_template');
return $Email->emailFormat('html')
->from(array('no-reply#xyz.com' => 'no-reply#xyz.com'))
->to($to)
->subject($subject)
->send();
}
Create a layout and view for email template.and add the data value that have been sent.