Validation of an email address in Laravel - laravel

I have created an edit form in my Laravel application form which accepts an email address. I have used Laravel validation on the server-side. It is validating the email address correctly when I pass a clearly invalid value like 'xxxxxx'.
But the problem is when I send an email address with only a top level domain and no dot like 'xxxxxx#yyyyyy', it accepts it as a valid email address.
How can I validate the email address to ensure it's using a proper domain?

With Laravel 7: you can use
'email' => 'email:rfc,dns'

You can simply do:
$validator = Validator::make($request->all(), [
'Email'=>'required|email'
]);

Try this:
$this->validate($request, [
'email' => 'required|regex:/(.+)#(.+)\.(.+)/i',
]);

It is not a Laravel issue. That is technically a valid email address.
Notice that if you tell the browser to validate the email address, it will also pass.
But you can use package EmailValidator for validating email addresses.
At first, also check these: https://laravel.com/docs/6.x/validation#rule-email
Or,
use the checkdnsrr function.
<?php
$email = 'email#gmail.com';
list($username, $domain) = explode('#', $email);
if (checkdnsrr($domain, 'MX')) {
echo "verified";
}
else {
echo "failed";
}

Laravel email validation and unique email insert database use for code:
'email_address' => 'required|email|unique:customers,email_address'

Related

Laravel email contact form 7

I'm developing a small script locally, which allows users to send an email from the post posted by another user. A simple contact form that then sends an email from user to user.
I have configured my .env with the corresponding Mailtrap sample data.
My problem is that every email sent is sent to Mailtrap and not to the user's email.
public function html_email(Request $request)
{
$request->validate([
'message_to' => 'required|string|max:255',
]);
$data = array('name' => Auth::user()->name);
Mail::send('mail', $data, function($message) {
$message
->to(request('email_to'))
->subject('Someone is interested in your ad!');
$message->from(Auth::user()->email, Auth::user()->name);
});
return back()
->with('success', __('app.email_successfully_sent'));
}
What am I doing wrong?
Ok, but setting a real email in .env when in a post a user has to contact another user, where is the email addressed? To the email set by default to .env? I want it to be sent to the email address of the user who posted the post.

How can i validate an list of emails in Laravel 5.4

I have a list of emails that get sent from the client side which are seperated by a comma. How can i validate all these emails to ensure that they are valid emails? e.g a user can capture emails in a text box like this one#one.com, two#two.com,three#three.com etc
I built a similar functionality at some point by using customer validation functions
Validator::extend("emails", function($attribute, $value, $parameters) {
$rules = ['email' => 'required|email'];
$emails = array_map('trim', explode(';', $value)); //$value
foreach ($emails as $email) {
$data = ['email' => $email];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return false;
}
}
return true;
});
If you are looking for how to verify the email to check whether they are valid and real email, you can simply do it by using SMTP server. There is a free github project for you: https://github.com/tintnaingwinn/email-checker
If you read through the readme, the package provides a custom validation rule for you.
EDIT: I apologize if this is off the topic since the question was about validating list of emails. But you can use this package if you want to test the email with SMTP server.
Hope this helps.
If you are trying to validate an array of emails then easiest way to validate is to use dot . syntax with a wildcard *. Here's the example:
$request->validate([
'emails.*' => ['email'],
...
]);

Password resetting in laravel when email address is not unique

This might sound like an antipattern or a weak system design, but the client of my app has demanded that there can be multiple users with same email address.
So I added another unique column named username to the users table and removed ->unique() constraint from email column.
Registration, Login are working fine but the problem arises during the password reset.
Consider the scenario:
username - johndoe, email - john#example.com
username - janedoe, email - john#example.com
username - jimmydoe, email - john#example.com
If any one of them makes a request for a password reset link, they would have to use johndoe#example.com as their email. So which user's password is actually going to be reset when they click on reset link from mail? Turns out, the first user, in this case, johndoe. Even if the request was made by janedoe or jimmydoe.
So how do I reset password for a single username, rather than an email? What changes should I make in the ForgotPasswordController and/or ResetPasswordController controllers to solve this? Or, do I have to make changes in the core framework? If so, where and how?
Tested in Laravel 5.3 [This answer modifies some core files(you may override it if capable) and it's not a clean solution.]
Ask user for the unique username value instead of email on password forget form.
Override the sendResetLinkEmail() method in ForgotPasswordController.php as folows. [Originally written in SendsPasswordResetEmails.php].
public function sendResetLinkEmail(Request $request)
{
$this->validateEmail($request);
$response = $this->broker()->sendResetLink(
$request->only('username')
);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
you would also need to override the validateEmail() method.
protected function validateEmail(Request $request)
{
$this->validate($request, ['username' => 'required']);
}
Add username field instead of email on password reset form.
Override rules() in ResetPasswordController.php to over come the email field change.
protected function rules()
{
return [
'token' => 'required',
'username' => 'required',
'password' => 'required|confirmed|min:6',
];
}
Also override the credentials() in ResetPasswordController.php
protected function credentials(Request $request)
{
return $request->only(
'username', 'password', 'password_confirmation', 'token'
);
}
Update or override the getEmailForPasswordReset() method in Illuminate\Auth\Passwords\CanResetPassword.php to the folowing.
public function getEmailForPasswordReset()
{
return $this->username;
}
Laravel uses key-value pair to find the user and send email. If you pass 'username => 'xyz' it will look for the first record with value 'xyz' in username field.
Note: The unique column in users table is expected as username.
Illuminate\Auth\Passwords\CanResetPassword.php is a trait, and I was not able to overide the getEmailForPasswordReset method, so i just modified the core file itself.
This might sound like an antipattern or a weak system design, but the client of my app has demanded that there can be multiple users with same email address.
Then you need to rewrite this feature and ask user for some more unique information, no matter what it is going to be. Laravel provided password reset expects email to be unique and with your current design it won't work. There's no magic here. You you cannot disambiguate your user using non unique data.
You will need to rework some things for this, but I feel like the user experience is better. Generate a unique key for each user (for data hiding). There is a helper method for creating unique keys.
Then, when the email is sent out, link the button to a route that utilizes this key.
Then, modify or create that route that points to the reset password controller. You would then know which user it was referring to.
Remove the need for the user to insert their password because you'd already know who it was.

How to change From Name in Laravel Mail Notification

This is the problem:
The name associated with the email shows up as "Example"
In config/mail.php
set from property as:
'from' => ['address' => 'someemail#example.com', 'name' => 'Firstname Lastname']
Here, address should be the one that you want to display in from email and name should be the one what you want to display in from name.
P.S. This will be a default email setting for each email you send.
If you need to use the Name as a variable through code, you can also call the function from() as follows (copying from Brad Ahrens answer below which I think is good to mention here):
return $this
->from($address = 'noreply#example.com', $name = 'Sender name')
->subject('Here is my subject')
->view('emails.view');
You can use
Mail::send('emails.welcome', $data, function($message)
{
$message->from('us#example.com', 'Laravel');
$message->to('foo#example.com')->cc('bar#example.com');
});
Reference - https://laravel.com/docs/5.0/mail
A better way would be to add the variable names and values in the .env file.
Example:
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=example#example.com
MAIL_PASSWORD=password
MAIL_ENCRYPTION=tls
MAIL_FROM_NAME="My Name"
MAIL_FROM_ADDRESS=support#example.com
Notice the last two lines. Those will correlate with the from name and from email fields within the Email that is sent.
In the case of google SMTP, the from address won't change even if you give this in the mail class.
This is due to google mail's policy, and not a Laravel issue.
Thought I will share it here.
For anyone who is using Laravel 5.8 and landed on this question, give this a shot, it worked for me:
Within the build function of the mail itself (not the view, but the mail):
public function build()
{
return $this
->from($address = 'noreply#example.com', $name = 'Sender name')
->subject('Here is my subject')
->view('emails.welcome');
}
Happy coding :)
If you want global 'from name' and 'from email',
Create these 2 keys in .env file
MAIL_FROM_NAME="global from name"
MAIL_FROM_ADDRESS=support#example.com
And remove 'from' on the controller. or PHP code if you declare manually.
now it access from name and from email.
config\mail.php
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'info#example.com'),
'name' => env('MAIL_FROM_NAME', 'write name if not found in env'),
],
ON my controller.
$conUsBody = '';
$conUsBody .= '<h2 class="text-center">Hello Admin,</h2>
<b><p> '.trim($request->name).' Want some assesment</p></b>
<p>Here are the details:</p>
<p>Name: '.trim($request->name).'</p>
<p>Email: '.trim($request->email).'</p>
<p>Subject: '.trim($request->subject).'</p>';
$contactContent = array('contactusbody' => $conUsBody);
Mail::send(['html' => 'emails.mail'], $contactContent,
function($message) use ($mailData)
{
$message->to('my.personal.email#example.com', 'Admin')->subject($mailData['subject']);
$message->attach($mailData['attachfilepath']);
});
return back()->with('success', 'Thanks for contacting us!');
}
My blade template.
<body>
{!! $contactusbody !!}
</body>
I think that you have an error in your fragment of code. You have
from(config('app.senders.info'), 'My Full Name')
so config('app.senders.info') returns array.
Method from should have two arguments: first is string contains address and second is string with name of sender. So you should change this to
from(config('app.senders.info.address'), config('app.senders.info.name'))

Laravel 4 Mail function not working properly

I'm currently working on a web application which requires users to verify before they are able to use their account.
I'm using Cartalyst's Sentry to register the users, and sending the email using the built in Mail function, but whenever I register I get the following error:
Argument 1 passed to Illuminate\Mail\Mailer::__construct() must be an instance of
Illuminate\View\Environment, instance of Illuminate\View\Factory given,
called in
/var/www/vendor/laravel/framework/src/Illuminate/Mail/MailServiceProvider.php
on line 34 and defined
I can't figure out what causes this.
At the top of my code I included "use Mail" otherwise I would get another error:
Class '\Services\Account\Mail' not found
Code
// Create the user
$user = $this->sentry->register(array(
'email' => e($input['email']),
'password' => e($input['password'])
));
$activationCode = $user->getActivationCode();
$data = array(
'activation_code' => $activationCode,
'email' => e($input['email']),
'company_name' => e($input['partnerable_name'])
);
// Email the activation code to the user
Mail::send('emails.auth.activate', $data, function($message) use ($input)
{
$message->to(e($input['email']), e($input['partnerable_name']))
->subject('Activate your account');
});
Anybody got an idea what the solution for this error is?
Thanks in advance,
Kibo
Remove /bootstrap/compiled.php I think it will work for you.
You need to remove this from your Mail::send call. The function should be the third parameter so I'm not sure what you're trying to do here -- the $input['email'] field will already be available within the function due to your "use ($input)"
$email = e($input['email']

Resources