Permalink
Browse files

Episode 73

  • Loading branch information...
JeffreyWay committed Aug 25, 2017
1 parent 04e172d commit 66c74ef5bb0febfb2b7dcf1ea10d67c980efb623
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
class RegisterConfirmationController extends Controller
{
/**
* Confirm a user's email address.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function index()
{
$user = User::where('confirmation_token', request('token'))->first();
if (! $user) {
return redirect(route('threads'))->with('flash', 'Unknown token.');
}
$user->confirm();
return redirect(route('threads'))
->with('flash', 'Your account is now confirmed! You may post to the forum.');
}
}
@@ -2,10 +2,13 @@
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use App\Mail\PleaseConfirmYourEmail;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
@@ -42,7 +45,7 @@ public function __construct()
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
@@ -57,15 +60,28 @@ protected function validator(array $data)
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @param array $data
* @return User
*/
protected function create(array $data)
{
return User::create([
return User::forceCreate([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'confirmation_token' => str_random(25)
]);
}
/**
* The user has been registered.
*
* @param \Illuminate\Http\Request $request
* @param \App\User $user
* @return void
*/
protected function registered(Request $request, $user)
{
Mail::to($user)->send(new PleaseConfirmYourEmail($user));
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class PleaseConfirmYourEmail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
/**
* The user associated with the email.
*
* @var \App\User
*/
public $user;
/**
* Create a new mailable instance.
*
* @param \App\User $user
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Build the email.
*
* @return $this
*/
public function build()
{
return $this->markdown('emails.confirm-email');
}
}
@@ -16,7 +16,10 @@ class User extends Authenticatable
* @var array
*/
protected $fillable = [
'name', 'email', 'password', 'avatar_path'
'name',
'email',
'password',
'avatar_path'
];
/**
@@ -25,7 +28,18 @@ class User extends Authenticatable
* @var array
*/
protected $hidden = [
'password', 'remember_token', 'email',
'password',
'remember_token',
'email',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'confirmed' => 'boolean'
];
/**
@@ -68,6 +82,16 @@ public function activity()
return $this->hasMany(Activity::class);
}
/**
* Mark the user's account as confirmed.
*/
public function confirm()
{
$this->confirmed = true;
$this->save();
}
/**
* Record that the user has read the given thread.
*
@@ -20,6 +20,13 @@
'email' => $faker->unique()->safeEmail,
'password' => $password ?: $password = bcrypt('secret'),
'remember_token' => str_random(10),
'confirmed' => true
];
});
$factory->state(App\User::class, 'unconfirmed', function () {
return [
'confirmed' => false
];
});
@@ -20,6 +20,7 @@ public function up()
$table->string('password');
$table->string('avatar_path')->nullable();
$table->boolean('confirmed')->default(false);
$table->string('confirmation_token', 25)->nullable();
$table->rememberToken();
$table->timestamps();
});
@@ -0,0 +1,12 @@
@component('mail::message')
# One Last Step
We just need you to confirm your email address to prove that you're a human. You get it, right? Coo.
@component('mail::button', ['url' => url('/register/confirm?token=' . $user->confirmation_token)])
Confirm Email
@endcomponent
Thanks,<br>
{{ config('app.name') }}
@endcomponent
@@ -12,14 +12,15 @@
*/
Route::get('/', function () {
\Mail::to(App\User::first())->send(new \App\Mail\PleaseConfirmYourEmail());
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index');
Route::get('threads', 'ThreadsController@index');
Route::get('threads', 'ThreadsController@index')->name('threads');
Route::get('threads/create', 'ThreadsController@create');
Route::get('threads/{channel}/{thread}', 'ThreadsController@show');
Route::delete('threads/{channel}/{thread}', 'ThreadsController@destroy');
@@ -40,5 +41,7 @@
Route::get('/profiles/{user}/notifications', 'UserNotificationsController@index');
Route::delete('/profiles/{user}/notifications/{notification}', 'UserNotificationsController@destroy');
Route::get('/register/confirm', 'Auth\RegisterConfirmationController@index')->name('register.confirm');
Route::get('api/users', 'Api\UsersController@index');
Route::post('api/users/{user}/avatar', 'Api\UserAvatarController@store')->middleware('auth')->name('avatar');
@@ -16,22 +16,28 @@ function guests_may_not_create_threads()
$this->withExceptionHandling();
$this->get('/threads/create')
->assertRedirect('/login');
->assertRedirect(route('login'));
$this->post('/threads')
->assertRedirect('/login');
$this->post(route('threads'))
->assertRedirect(route('login'));
}
/** @test */
function authenticated_users_must_first_confirm_their_email_address_before_creating_threads()
function new_users_must_first_confirm_their_email_address_before_creating_threads()
{
$this->publishThread()
->assertRedirect('/threads')
$user = factory('App\User')->states('unconfirmed')->create();
$this->signIn($user);
$thread = make('App\Thread');
$this->post(route('threads'), $thread->toArray())
->assertRedirect(route('threads'))
->assertSessionHas('flash', 'You must first confirm your email address.');
}
/** @test */
function an_authenticated_user_can_create_new_forum_threads()
function a_user_can_create_new_forum_threads()
{
$this->signIn();
@@ -107,6 +113,6 @@ protected function publishThread($overrides = [])
$thread = make('App\Thread', $overrides);
return $this->post('/threads', $thread->toArray());
return $this->post(route('threads'), $thread->toArray());
}
}
@@ -0,0 +1,60 @@
<?php
namespace Tests\Feature;
use App\Mail\PleaseConfirmYourEmail;
use App\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;
class RegistrationTest extends TestCase
{
use DatabaseMigrations;
/** @test */
public function a_confirmation_email_is_sent_upon_registration()
{
Mail::fake();
$this->post(route('register'), [
'name' => 'John',
'email' => 'john@example.com',
'password' => 'foobar',
'password_confirmation' => 'foobar'
]);
Mail::assertSent(PleaseConfirmYourEmail::class);
}
/** @test */
function user_can_fully_confirm_their_email_addresses()
{
Mail::fake();
$this->post(route('register'), [
'name' => 'John',
'email' => 'john@example.com',
'password' => 'foobar',
'password_confirmation' => 'foobar'
]);
$user = User::whereName('John')->first();
$this->assertFalse($user->confirmed);
$this->assertNotNull($user->confirmation_token);
$this->get(route('register.confirm', ['token' => $user->confirmation_token]))
->assertRedirect(route('threads'));
$this->assertTrue($user->fresh()->confirmed);
}
/** @test */
function confirming_an_invalid_token()
{
$this->get(route('register.confirm', ['token' => 'invalid']))
->assertRedirect(route('threads'))
->assertSessionHas('flash', 'Unknown token.');
}
}

0 comments on commit 66c74ef

Please sign in to comment.