Send email with TDD Laravel 5.6 - testing

I am doing the registration user
public function register(RegistrationUser $request)
{
$user = $this->usersRepo->create($request->all());
$user->activation_token = str_random(48);
$user->save();
Mail::to($user->email)->queue(new ActivationAccount($user->first_name, $user->last_name, $user->email, $request->input('password'), $url));
return redirect()->route('successful.registration')
}
My registration test is:
public function it_creates_a_new_user()
{
$this->withExceptionHandling();
$response = $this->get(route('register'))
->assertStatus(200);
$this->post('register', [
'first_name' => 'Juan',
'last_name' => 'Lopez',
'email' => 'jlopez#gmail.com',
'password' => 'secret',
'activation_tone' => str_random(48)
])->assertRedirect(route('successful.registration'));
$this->assertDatabaseHas('users', [
'email' => 'jlopez#gmail.com',
]);
}
I have two questions:
1) How can I write a test to send the registration email and verify that it sends and arrives well?
2) When the user clicks on his email he calls a method where the activation token is passed to activate his account

In my opinion you should use mail fake ,which will prevent mail from being sent. You may then assert that mailables were sent to users and even inspect the data they received.
please read laravel docs: https://laravel.com/docs/5.6/mocking#mail-fake
There must be a route which is handling activation token and functionality, so try to get the token and call route with specific token
Note: As a developer we need to make sure that our code works which our tests are confirming, Sending and delivering email should be not be covered as they considered to work as expected(by any email service provider).

Related

How to send user login credentials after user registers

I am using laravel's default login and registration. I have successfully set up authentication, however I would like to send user's username and password to the emails they used during registration. How can I achieve this?
You can initiate a mail to user after you validated input received and before your create functions of your register controller present in
$email = new UserRegisterData(new User(['password' => $user->password, 'name' => $user->name]));
To do this you need to rewrite
protected function validator(array $data)
function in your register controller and modify that with this mail. as
protected function validator(array $data)
{
$email = new UserRegisterData(new User(['password' => $user->password, 'name' => $user->name]));
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:customers',
'password' => 'required|min:6|confirmed',
]);
}
once you hashed your password in create function, i think it can't be read. Also check if any security issue it may generate. Also you need to create mail as 'UserRegisterData' and add necessary code in it.

How to do a Sign Up with OAuth (facebook, twitter, google)?

I use Laravel (5) as my php framework, it recently added a library for social authentication (facebook, google, twitter and github).
I've been wondering how would you do a Sign Up with OAuth, a login can easily be done by getting the user's email via OAuth, checking if it exists in your DB, and if it does, then log in that user. But how would you do the Sign Up?
Mathius - I've recently been working on a site doing something similar to what you've described and this is what has worked for me:
public function syncUserDetails($userData)
{
// First I check to see if there is a user in the DB
// with the oAuth email address
if ( $user = $this->user->where('email', $userData->email)->first() )
{
// If there is a user, I simply update their local info
// with what is on their oAuth account
$user->token = $userData->token;
$user->google_id = $userData->id;
$user->name = $userData->name;
$user->avatar = $userData->avatar;
$user->first_name = $userData->user['given_name'];
$user->last_name = $userData->user['family_name'];
$user->save();
return $user;
}
// Otherwise, if the user doesn't already exist,
// I create them in my local user's DB
return $this->user->firstOrCreate([
'email' => $userData->email,
'token' => $userData->token,
'google_id' => $userData->id,
'name' => $userData->name,
'avatar' => $userData->avatar,
'first_name' => $userData->user['given_name'],
'last_name' => $userData->user['family_name']
]);
}
This is what I'm using to log in a user. However, you could just as easily run this alongside your regular Laravel login method.

Google + sign in with laravel

I have been struggling a lot for G+ sign-in with laravel, I have downloaded the php-sdk using composer. I am also using JavaScript to sign-in, once the once the user signs in I redirect him to a route from JavaScript to /gLogin?email=abc#gmail.com&name=John Doe where I have following code.
$user_profile['email']=Input::get('email');
$user_profile['name']=Input::get('name');
$user_id=DB::table('users') -> where('dyp_user_email', $user_profile['email'])-> pluck('dyp_user_id');
if($user_id)
{
$user_to_be_logged_in=new user();
$user_to_be_logged_in = User::find($user_id);
}
else
{
$password=$token = str_random(16);
$hash=Hash::make($password);
$user_to_be_logged_in = user::create(array('dyp_user_type' => 'IN', 'dyp_name' => $user_profile['name'], 'dyp_user_email' => $user_profile['email'], 'dyp_mobile_number' => '','dyp_password'=> $hash,'dyp_user_status' => 'VF'));
$data = array('name' => $user_to_be_logged_in -> dyp_name, 'password' => $password);
Mail::send('emails.fbUserRegistration', $data, function($message) use ($user_to_be_logged_in) {
$message -> to($user_to_be_logged_in->dyp_user_email, $user_to_be_logged_in->dyp_name) -> subject('Thanks for registering with dreamyourproperty.com');
});
}
Auth::login($user_to_be_logged_in);
There is a serious security problem here, that I am not able to validate the user's session.
I someone manually hits the url /gLoin?email=abc#gmail.com&name=xyz then also my code will authenticate him.
In comparison to G+ signin FB login was pretty simple.Can someone provide me guidance, I am seriously stuck with this part.
They way you want to handle this is /gLogin?access_token=xyz where xyz is the users Google+ access_token. Make a request to people.get authenticated with that access token. That way you have server side validation the current user is validated for the specific Google+ profile.

Laravel 4, how to send different flash messages depending on users credentials and hidden input

I am trying to check the status of a users account when the user logs into the application with Laravel 4.1.
$attempt = Auth::attempt(array('email' => $input['email'], 'password' => $input['password'], 'active'
=> $input['active']), true);
if($attempt) return Redirect::route('photos.index');
return Redirect::back()->withInput()->with('message', 'Your email or password are incorrect.');
I am using a hidden input "active" to check whether a user account is still active or not. This works fine. However, if this check fails, the user gets to see the same flash message that is displayed when he enters wrong credentials. How could I send a second flash message that states to the user that his account is not active anymore even if he had entered correct credentials?
Any help would be much appreciated.
Thanks!
If the Auth::attempt() fails you can check with this if it succeeded without an active account.
$attempt = Auth::attempt(array('email' => $input['email'], 'password' => $input['password'], 'active'
=> $input['active']), true);
if($attempt) return Redirect::route('photos.index');
// Check if credentials are correct but the account is not active
if (Auth::validate(array('email' => $input['email'], 'password' => $input['password'])))
{
// Valid but not active
return Redirect::back()->withInput()->with('message', 'Account not active.');
}
return Redirect::back()->withInput()->with('message', 'Your email or password are incorrect.');

Drupal 7 - how to allow an application to access a certain drupal url (from menu hook), either with super basic url-based auth or anonymously

I'm pretty new to drupal, so bear with me if I'm not using correct terms.
I'm trying to give a stupidly basic application access to a drupal url - this application cannot do any complicated authentication.
Otherwise, this drupal system needs authentication and all other menu hooks use 'access arguments' => array('access content')
Even before looking a solution for easy authentication method with drupal like http://user:password#server.com/awesome/member/12345, I've tried just giving anonymous access with the following code block in a drupal .module file
function awesome_module_menu() {
$items['awesome/member/%'] = array(
'title' => 'Awesome member',
'type' => MENU_NORMAL_ITEM,
'page callback' => 'aw_memberdata_fetch',
'delivery callback' => 'aw_memberdata_deliver',
'access arguments' => TRUE // this supposedly should allow anonymous access - from the web
);
return $items;
}
I have these two functions, one to fetch the data, one to show it:
function aw_memberdata_fetch(memberId)
{
//fetch array of objects from DB
...
return $items;
}
function aw_memberdata_deliver($items)
{
switch(arg(3)) //format, comes after items
{
case 'json':
drupal_json_output($items);
break;
default:
$output = makeHtml($items); //makes HTML
drupal_deliver_html_page($output);
}
}
With an authenticated browser, this works as intented. From a browser with no auth cookie I'm allowed to see the HTML, but the results are not there, it's like the page callback function doesn't run for anon users, but delivery callback does.
How do I make this work for anon users?
You are using access arguments with the default user_access function for permission verification. This will basically call user_access(true) which will return
true for authenticated user (you are probably testing with the administrator account (uid = 1)) which bypasses the verification check. Administrator has full privileges.
false for anonymous users because the string value of the first argument passed to the user_access true doesn't exist as a permission setting.
You should use either use
a custom YOURMODULE_access hook which does the permission verification
declare custom permissions for your module (YOURMODULE_permission hook)
don't use permission verification by using 'access callback' => true which gives access to anonymous and authenticated users
function awesome_module_menu() {
$items['awesome/member/%'] = array(
'title' => 'Awesome member',
'type' => MENU_NORMAL_ITEM,
'page callback' => 'aw_memberdata_fetch',
'delivery callback' => 'aw_memberdata_deliver',
'access callback' => true,
);
return $items;
}