Laravel email contact form 7 - laravel

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.

Related

How to send custom password reset link in laravel (customized link with prefix)?

I Laravel custom authentication (Laravel Breeze). I want to send my customized password reset link. In default, the link is sent in this format localhost:8000/reset-password/{token} but I want to send link localhost:8000/system/reset-password/{token}.
Route
// forgot-password
Route::get('/forgot-password',[AdminForgotPasswordController::class,'create'])->name('admin.showForgotPassword');
Route::post('/forgot-password',[AdminForgotPasswordController::class,'store'])->name('admin.forgotPassword');
controller
public function store(Request $request)
{
$request->validate([
'email' => 'required|email',
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
Following the Laravel documentation about Password Reset you would be able to override the password reset link!

Laravel Socialite Github provider email is null

I'm trying to setup login in Laravel with GitHub using Socialite.
Here is my provider callback function:
public function handleProviderCallback($provider)
{
$provider_user = Socialite::driver($provider)->user();
dd($provider_user);
if($provider_user->email) {
$user = User::firstOrCreate([
'email' => $provider_user->email
], [
'name' => $provider_user->name ?? $provider_user->nickname,
'password' => Hash::make(Str::random(16)),
]);
Auth::login($user, true);
}
return redirect('/');
}
When I dd the user that provider returns, I can see that values $provider_user->name and $provider_user->nickname are correct, but $provider_user->email is null.
Which, according to the GitHub API documentation shouldn't be the case, as my e-mail is public:
I have tried https://api.github.com/user/emails where I've tried putting user nickname, as well as client ID in place of user, but to no avail. The response is:
{ "message": "Not Found", "documentation_url": "https://docs.github.com/rest" }
So, am I doing something wrong or GitHub API simply no longer returns e-mail addresses? Is there a way to get a public e-mail address?
I was having the same problem earlier.
What I did upon creating the github app is change the User permissions->Email addresses to read only. You can update it on the permission & events:

Validation of an email address in 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'

Login by code seems to not work in laravel

Basically i'm trying to send by email a link that lets you login with a specific account and then redirects you to a page.
I can seccessfully generate link and send them via email using URL functionalities in laravel using this code:
Generating the link:
$url = "some/page/".$travel_id;
$link = URL::temporarySignedRoute(
'autologin', now()->addDay(), [
'user_id' => 3,
'url_redirect' => $url,
]
);
And sending the mail:
Mail::send('emails.travel', $data, function ($message) use ($data) {
$message->from('mail#mail.com', 'blablabla');
$message->to('reciever#mail.com', 'blablabla')->subject('test');
});
There is a route that catches the link sent by mail that is supposed to log you in with the user (in this case, the one with the id '3') and redirect you to some page but when it redirects, it prompts you to the login page, as if you are not logged.
Here is the route:
Route::get('/autologin', function (Request $request) {
$user = User::findOrFail($request->user_id);
if (! $request->hasValidSignature()) {
abort(403);
}
Auth::login($user);
return redirect($request->input('url_redirect'));
})->name('autologin');
When i try to do a Auth::check() after the Auth::login($user); it returns true, so is the user logged in?
I also tried to use Auth::loginUsingId($request->user_id); with no different results.
Any idea of what's happening?
So i found the problem,
I was logging in with a backpack user but i was using the default auth feature of laravel.
Turns out i need to use: backpack_auth()->login($user); instead of Auth::login($user); if i want to login using a backpack user.
Also use backpack_auth()->check() instead of Auth::check().

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.

Resources