Add Email Verification
This commit is contained in:
parent
faec46069b
commit
a415b421cb
10 changed files with 206 additions and 3 deletions
15
app/EmailVerification.php
Normal file
15
app/EmailVerification.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class EmailVerification extends Model
|
||||
{
|
||||
public function url()
|
||||
{
|
||||
$base = config('app.url');
|
||||
$path = '/i/confirm-email/' . $this->user_token . '/' . $this->random_token;
|
||||
return "{$base}{$path}";
|
||||
}
|
||||
}
|
|
@ -4,8 +4,9 @@ namespace App\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
use Auth, Cache, Redis;
|
||||
use App\{Notification, Profile, User};
|
||||
use App\Mail\ConfirmEmail;
|
||||
use Auth, DB, Cache, Mail, Redis;
|
||||
use App\{EmailVerification, Notification, Profile, User};
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
|
@ -30,6 +31,46 @@ class AccountController extends Controller
|
|||
return view('account.activity', compact('profile', 'notifications'));
|
||||
}
|
||||
|
||||
public function verifyEmail(Request $request)
|
||||
{
|
||||
return view('account.verify_email');
|
||||
}
|
||||
|
||||
public function sendVerifyEmail(Request $request)
|
||||
{
|
||||
if(EmailVerification::whereUserId(Auth::id())->count() !== 0) {
|
||||
return redirect()->back()->with('status', 'A verification email has already been sent! Please check your email.');
|
||||
}
|
||||
|
||||
$user = User::whereNull('email_verified_at')->find(Auth::id());
|
||||
$utoken = hash('sha512', $user->id);
|
||||
$rtoken = str_random(40);
|
||||
|
||||
$verify = new EmailVerification;
|
||||
$verify->user_id = $user->id;
|
||||
$verify->email = $user->email;
|
||||
$verify->user_token = $utoken;
|
||||
$verify->random_token = $rtoken;
|
||||
$verify->save();
|
||||
|
||||
Mail::to($user->email)->send(new ConfirmEmail($verify));
|
||||
|
||||
return redirect()->back()->with('status', 'Email verification email sent!');
|
||||
}
|
||||
|
||||
public function confirmVerifyEmail(Request $request, $userToken, $randomToken)
|
||||
{
|
||||
$verify = EmailVerification::where(DB::raw('BINARY `user_token`'), $userToken)
|
||||
->where(DB::raw('BINARY `random_token`'), $randomToken)
|
||||
->firstOrFail();
|
||||
if(Auth::id() === $verify->user_id) {
|
||||
$user = User::find(Auth::id());
|
||||
$user->email_verified_at = Carbon::now();
|
||||
$user->save();
|
||||
return redirect('/timeline');
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchNotifications($id)
|
||||
{
|
||||
$key = config('cache.prefix') . ":user.{$id}.notifications";
|
||||
|
|
|
@ -60,5 +60,6 @@ class Kernel extends HttpKernel
|
|||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'validemail' => \App\Http\Middleware\EmailVerificationCheck::class,
|
||||
];
|
||||
}
|
||||
|
|
28
app/Http/Middleware/EmailVerificationCheck.php
Normal file
28
app/Http/Middleware/EmailVerificationCheck.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Auth, Closure;
|
||||
|
||||
class EmailVerificationCheck
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if($request->user() &&
|
||||
config('pixelfed.enforce_email_verification') &&
|
||||
is_null($request->user()->email_verified_at) &&
|
||||
!$request->is('i/verify-email') && !$request->is('login') &&
|
||||
!$request->is('i/confirm-email/*')
|
||||
) {
|
||||
return redirect('/i/verify-email');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
34
app/Mail/ConfirmEmail.php
Normal file
34
app/Mail/ConfirmEmail.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\EmailVerification;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class ConfirmEmail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(EmailVerification $verify)
|
||||
{
|
||||
$this->verify = $verify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->markdown('emails.confirm_email')->with(['verify'=>$this->verify]);
|
||||
}
|
||||
}
|
|
@ -107,4 +107,14 @@ return [
|
|||
*/
|
||||
'max_album_length' => env('MAX_ALBUM_LENGTH', 4),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Require email verification before a new user can do anything.
|
||||
|
|
||||
*/
|
||||
'enforce_email_verification' => env('ENFORCE_EMAIL_VERIFICATION', true),
|
||||
|
||||
];
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateEmailVerificationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('email_verifications', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->bigInteger('user_id')->unsigned();
|
||||
$table->string('email')->nullable();
|
||||
$table->string('user_token')->index();
|
||||
$table->string('random_token')->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('email_verifications');
|
||||
}
|
||||
}
|
24
resources/views/account/verify_email.blade.php
Normal file
24
resources/views/account/verify_email.blade.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mt-4">
|
||||
<div class="col-12 col-md-8 offset-md-2">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
<div class="card">
|
||||
<div class="card-header font-weight-bold bg-white">Confirm Email Address</div>
|
||||
<div class="card-body">
|
||||
<p class="lead">You need to confirm your email address (<span class="font-weight-bold">{{Auth::user()->email}}</span>) before you can proceed.</p>
|
||||
<hr>
|
||||
<form method="post">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-primary btn-block py-1 font-weight-bold">Send Confirmation Email</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
12
resources/views/emails/confirm_email.blade.php
Normal file
12
resources/views/emails/confirm_email.blade.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
@component('mail::message')
|
||||
# Email Confirmation
|
||||
|
||||
Please confirm your email address.
|
||||
|
||||
@component('mail::button', ['url' => $verify->url()])
|
||||
Confirm Email
|
||||
@endcomponent
|
||||
|
||||
Thanks,<br>
|
||||
{{ config('app.name') }}
|
||||
@endcomponent
|
|
@ -25,7 +25,7 @@ Route::domain(config('pixelfed.domain.admin'))->group(function() {
|
|||
Route::get('media/list', 'AdminController@media')->name('admin.media');
|
||||
});
|
||||
|
||||
Route::domain(config('pixelfed.domain.app'))->group(function() {
|
||||
Route::domain(config('pixelfed.domain.app'))->middleware('validemail')->group(function() {
|
||||
|
||||
Route::view('/', 'welcome');
|
||||
|
||||
|
@ -62,6 +62,9 @@ Route::domain(config('pixelfed.domain.app'))->group(function() {
|
|||
Route::post('follow', 'FollowerController@store');
|
||||
Route::post('bookmark', 'BookmarkController@store');
|
||||
Route::get('lang/{locale}', 'SiteController@changeLocale');
|
||||
Route::get('verify-email', 'AccountController@verifyEmail');
|
||||
Route::post('verify-email', 'AccountController@sendVerifyEmail');
|
||||
Route::get('confirm-email/{userToken}/{randomToken}', 'AccountController@confirmVerifyEmail');
|
||||
|
||||
Route::group(['prefix' => 'report'], function() {
|
||||
Route::get('/', 'ReportController@showForm')->name('report.form');
|
||||
|
|
Loading…
Reference in a new issue