Yii smtp mail sending fails for office365 host - yii

While sending mail from YII, for smtp protocol, it gives below error:
Swift_TransportException: Expected response code 250 but got code "530", with message "530 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM [BM1PR01CA0097.INDPRD01.PROD.OUTLOOK.COM] " in /var/www/html/vvf.kritva.in/protected/extensions/yii-mail/vendors/swiftMailer/classes/Swift/Transport/AbstractSmtpTransport.php:406
Even if port change to 587, it gives same error.
'transportType' => 'smtp',
'transportOptions' => array(
'host'=>'smtp.office365.com',
'username'=>'xyz#xyz.com',
'password'=>'password',
'port'=>'587',
// 'encryption' => 'tls'
),
The code in controller is as below :
$message = new YiiMailMessage;
$message->setBody('Message content here with HTML', 'text/html');
$message->subject = 'xyz';
$message->addTo('xyz#xyz.com');
$message->from = 'xyz#xyz.com';
Yii::app()->mail->send($message);
Please help to rectify this issue.
Thanks in advance.

So main problem is this line:
$message->from = 'xyz#xyz.com';
You have to change this e-mail address to be exacly same as this registered in office365.com. If you created email called monica#office365.com then you have to put this as from() before sending.

I ran into this issue also, I could send from one account but not another, many times this is due to the fact that the account you are trying to send from is in a protected group, such as, administrators or printers.

\config\web.php
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'enableSwiftMailerLogging' => true,
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'plugins' =>
[
[
'class' => 'Swift_Plugins_LoggerPlugin',
'constructArgs' => [new Swift_Plugins_Loggers_ArrayLogger],
],
],
'host' => 'smtp.office365.com',
'authMode' => 'login',
'username' => 'your email id',
'password' => 'your password',
'port' => '587',
'encryption' => 'tls',
],
],
////////////use this function to send mail/////////////
public function sendemail($from,$to,$subject,$content)
{
try{
$mailCompose = Yii::$app->mailer->compose()
->setFrom($from)
->setTo($to);
$mailCompose->setBcc($bccEmailIds);
$mailCompose->setSubject($subject)
->setHtmlBody($content)
->send();
$msg = 'Email sent';
}catch(Exception $e){
$msg = $e->getMessage();
}
}

Related

Cakephp 4 logintest

I'm doing the test for my UserController and I'm having trouble with my login test. I'm using cakephp4 with phpunit.
The test I'm doing is this:
public function testLogin(): void
{
$this->enableSecurityToken();
$this->enableCsrfToken();
$this->get('/user/login');
$this->assertResponseOk();
$this->post('/user/login', [
'DNI_CIF' => '22175395Z',
'password' => '$2y$10$ND67aMGqm.qK86MW1wuW9OQLC9vyJQGUn2HnLuSInwrFbXQKBT.V.'
]);
$this->assertResponseCode(302); //Si correcto redirige
// $this->assertSession(1, 'Auth.User.id');
}
My UserController:
public function login()
{
$this->request->allowMethod(['get', 'post']);
$result = $this->Authentication->getResult();
// regardless of POST or GET, redirect if user is logged in
if ($result && $result->isValid()) {
return $this->redirect('/');
}
// display error if user submitted and authentication failed
if ($this->request->is('post') && !$result->isValid()) {
$this->Flash->error(__('Alias de usuario o contraseƱa incorrecta.'));
}
}
My Application:
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
$authenticationService = new AuthenticationService([
'unauthenticatedRedirect' => Router::url('/user/login'),
'queryParam' => 'redirect',
]);
// Load identifiers, ensure we check email and password fields
$authenticationService->loadIdentifier('Authentication.Password', [
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'User',
],
'fields' => [
'username' => 'DNI_CIF',
'password' => 'password',
]
]);
// Load the authenticators, you want session first
$authenticationService->loadAuthenticator('Authentication.Session');
// Configure form data check to pick email and password
$authenticationService->loadAuthenticator('Authentication.Form', [
'fields' => [
'username' => 'DNI_CIF',
'password' => 'password',
],
'loginUrl' => Router::url('/user/login'),
]);
return $authenticationService;
}
But I'm having this error:
.......object(Authentication\Authenticator\Result)#826 (3) {
["_status":protected]=>
string(27) "FAILURE_CREDENTIALS_MISSING"
["_data":protected]=>
NULL
["_errors":protected]=>
array(1) {
[0]=>
string(27) "Login credentials not found"
}
}
Can someone tell my what I'm doing wrong?
I tried several combinations like:
'username' => '22175395Z',
'password' => '$2y$10$ND67aMGqm.qK86MW1wuW9OQLC9vyJQGUn2HnLuSInwrFbXQKBT.V.'
or:
'DNI_CIF' => '22175395Z',
'password' => 'prueba'
or
'username' => '22175395Z',
'password' => 'prueba'
but nothing works.
In order to validate against a password stored in the database, the stored password must be hashed, and the submitted password must not be.
A want to add, in case of someone having the same problem, to be careful if you are using a user added in Fixture to login because it's password may not be hashed and login test will not work. I added a user and used it in the login test.

Laravel queue:work not behaving same as queue:listen

<?php
namespace App\Notifications;
use Illuminate\Notifications\Channels\MailChannel;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Config;
class DynamicEmailChannel extends MailChannel
{
public function send($notifiable, Notification $notification)
{
$service = $notification->service;
$customConfig = [];
$from = [];
if ($service->sender_email && $service->sender_password) {
$customConfig = [
'transport' => 'smtp',
'host' => 'smtp.googlemail.com',
'port' => 587,
'encryption' => 'tls',
'username' => $service->sender_email,
'password' => $service->sender_password,
'timeout' => null,
'auth_mode' => null,
];
$from = [
'address' => $service->sender_email,
'name' => $service->title
];
} else {
$customConfig = [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'auth_mode' => null,
];
$from = [
'address' => env('MAIL_FROM_ADDRESS', 'hello#example.com'),
'name' => env('MAIL_FROM_NAME', 'Example')
];
}
Config::set('mail.mailers.smtp', $customConfig);
Config::set('mail.from', $from);
app()->forgetInstance('mail.manager');
parent::send($notifiable, $notification);
}
}
this program works when run through php artisan queue:listen but the app()->forgetInstance('mail.manager'); runs only once when run through php artisan queue:work. How do i make it behave as with queue:listen?
I am trying to send mail notifications through credentials saved in database.
If i am not wrong, if i delete the 'mail.manager' serviceInstance, it will create new one when called with latest config. it works the same way for queue:listen but not for queue:work. what am i missing, or not understanding here.
After doing some digging replacing app()->forgetInstance('mail.manager'); with Mail::purge('smtp'); solved the issue.

cakephp 3.8.13 add admad/cakephp-jwt-auth

This question is asked many times in the stack overflow but I tried every accepted solution.
I'm new to cake PHP and I was assigned to add JWT in our application. Previously the team used the default cake sessions. In order to integrate, I used admad/cakephp-jwt-auth. So In the AppController
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Recurring');
$this->loadComponent('Auth', [
'storage' => 'Memory',
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'user_name',
'password' => 'password',
],
'contain' => ['Roles']
],
'ADmad/JwtAuth.Jwt' => [
'parameter' => 'token',
'userModel' => 'CbEmployees',
'fields' => [
'username' => 'id'
],
'queryDatasource' => true
]
],
'unauthorizedRedirect' => false,
'checkAuthIn' => 'Controller.initialize'
]);
}
I have to use CbEmployees which is our user model.
Then in my custom controller, I add my login function
public function login()
{
$user = $this->Auth->identify();
if (!$user) {
$data = "Invalid login details";
} else {
$tokenId = base64_encode(32);
$issuedAt = time();
$key = Security::salt();
$data = JWT::encode(
[
'alg' => 'HS256',
'id' => $user['id'],
'sub' => $user['id'],
'iat' => time(),
'exp' => time() + 86400,
],
$key
);
}
$this->ApiResponse([
"data" => $data
]);
}
Then I call this function using postman with body
{
"username": "developer",
"password": "dev2020"
}
I always get the response as Invalid login details. So the suggested solution is to check the password data type and length. The password is varchar(255). Another solution is to check the password in the entity. In the entity I have
protected function _setPassword($password)
{
if (strlen($password) > 0) {
return Security::hash($password, 'sha1', true);
// return (new DefaultPasswordHasher)->hash($password);
}
}
I specifically asked why the team is using Security::hash($password, 'sha1', true); due to migration from cake 2 to cake 3 they have to use the same.
Why I'm getting always Invalid login details? What I'm doing wrong here? I can log in the using the same credentials when I'm using the application.

cakePHP3 Form Authentication fails on identify() and manual DefaultPasswordHasher check()

I copied code from examples to create a basic login screen based on the table individuals with email and password. My AppController has this:
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => ['username' => 'email', 'password' => 'password'],
'userModel' => 'Individuals']
],
'loginAction' => [
'controller' => 'Individuals',
'action' => 'login'
],
'loginRedirect' => [
'controller' => 'Associations',
'action' => 'login'
],
'logoutRedirect' => [
'controller' => 'Association',
'action' => 'login',
'home'
]
]);
Password resets are done via a token emailed to the user. The controller saves the unencrypted value and /src/Model/Entity/Individual.php has _setPassword that ensures the database has an encrypted value. Every save for the same password is different but that, I gather, is normal.
protected function _setPassword($password) {
if (strlen($password) > 0) {
return (new DefaultPasswordHasher)->hash($password);
}
}
My login function started with the standard stuff, but it always returns false
$user = $this->Auth->identify();
My login function now has this debug code that always gets a "no match"
debug($this->request->data);
$email = $this->request->data['email'];
$pwd = $this->request->data['password'];
$user = $this->Individuals->find()
->select(['Individuals.id', 'Individuals.email', 'Individuals.password'])
->where(['Individuals.email' => $email])
->first();
if ($user) {
if ((new DefaultPasswordHasher)->check($pwd, $user->password)) {
debug('match');
}
else{
debug('no match');
}
if ($user->password == (new DefaultPasswordHasher)->hash($pwd)) {
debug('match2');
}
else {
debug('no match2');
}
}
There's a lot more code in and around that and I'm pretty confident I've got it right. Let me know if you need more. I'm keen to crack this.
thanks in advance.

configuring database config for live site in codeigniter keep getting 500 internal server error

Im pretty done new to actually setting up sites as a live version, I've only done websites using local host. Im using codeigniter for this one, and i've traced my problem to the model where it loads the database. This makes me think that my database config isn't set up correctly.
The model's function is as follows:
public function register($email, $password, $first_name, $last_name, $gender, $birthday){
$salt = $this->generateSalt();
$password = $this->hash($password, $salt);
$data = array('email' => $email, 'password' => $password, 'salt' => $salt, 'first_name' => $first_name,
"last_name" => $last_name, 'gender' => $gender, "birthday" => $birthday);
$this->load->database();
if($this->db->insert('users', $data)){
$this->loginById($this->db->insert_id());
return true;
}else{
return false;
}
}
And the database config looks like this though I removed the password and username for privacy the username and pass I used are the same as I used to get into phpmyadmin though:
$db['default'] = array(
'dsn' => '',
'hostname' => 'http://130.184.99.114/',
'username' => '',
'password' => '',
'database' => 'meetings',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => TRUE,
'db_debug' => TRUE,
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array()
);
So, how do I need to set this up? I think Im on the right track, but im really new to this, so please explain it in a way I can learn please! :D IF you need any more information please let me know.
The hostname you have listed is incorrect.
It should either be:
'hostname' => '130.184.99.114',
or
'hostname' => 'localhost',
depending on how the server has been set up.
Have you set this up in the /application/config/database.php file, or are you doing it differently? I ask as I see failover => array() in there, which isn't in the default configuration file.