Skip to content

Commit

Permalink
Email verification option
Browse files Browse the repository at this point in the history
  • Loading branch information
Cannonb4ll committed Jun 24, 2022
1 parent 52ea8c4 commit 216b57b
Show file tree
Hide file tree
Showing 22 changed files with 151 additions and 50 deletions.
1 change: 1 addition & 0 deletions app/Console/Commands/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ protected function createUser()

$user = User::create($this->getUserData());
$user->role = UserRole::Admin;
$user->email_verified_at = now();
$user->save();

$this->info('User created!');
Expand Down
4 changes: 4 additions & 0 deletions app/Filament/Pages/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ protected function getFormSchema(): array
->hidden(fn (Closure $get) => $get('select_board_when_creating_item') === false)
->columnSpan(2),

Toggle::make('users_must_verify_email')
->label('Users must verify their email before they can submit items, or reply to items.')
->columnSpan(2),

Grid::make()->schema([
Select::make('inbox_workflow')
->options(InboxWorkflow::getSelectOptions())
Expand Down
2 changes: 1 addition & 1 deletion app/Filament/Pages/System.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace App\Filament\Pages;

use App\Filament\Pages\Widgets\System\SystemInfo;
use Filament\Pages\Page;
use App\Filament\Pages\Widgets\System\SystemInfo;

class System extends Page
{
Expand Down
2 changes: 1 addition & 1 deletion app/Filament/Pages/Widgets/System/SystemInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace App\Filament\Pages\Widgets\System;

use App\Services\SystemChecker;
use Filament\Widgets\Widget;
use App\Services\SystemChecker;

class SystemInfo extends Widget
{
Expand Down
12 changes: 12 additions & 0 deletions app/Filament/Resources/CommentResource/Pages/EditComment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

namespace App\Filament\Resources\CommentResource\Pages;

use Filament\Pages\Actions\Action;
use Filament\Resources\Pages\EditRecord;
use App\Filament\Resources\CommentResource;

class EditComment extends EditRecord
{
protected static string $resource = CommentResource::class;

public function getActions(): array
{
return [
Action::make('view_public')
->color('secondary')
->openUrlInNewTab()
->url(fn () => route('items.show', $this->record->item) . '#comment-' . $this->record->id),
...parent::getActions()
];
}
}
30 changes: 9 additions & 21 deletions app/Http/Controllers/Auth/VerificationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,23 @@

class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/

use VerifiesEmails;

/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;

/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}

public function show()
{
if (auth()->user()->hasVerifiedEmail()) {
return redirect($this->redirectPath());
}

return view('auth.verify-email');
}
}
4 changes: 4 additions & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Kernel extends HttpKernel
\App\Http\Middleware\PasswordProtected::class,
],

'authed' => [
'auth',
],

'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
Expand Down
10 changes: 9 additions & 1 deletion app/Http/Livewire/Item/Comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace App\Http\Livewire\Item;

use App\Models\Item;
use App\Settings\GeneralSettings;
use Filament\Http\Livewire\Concerns\CanNotify;
use Livewire\Component;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Contracts\HasForms;
Expand All @@ -11,7 +13,7 @@

class Comments extends Component implements HasForms
{
use InteractsWithForms;
use CanNotify, InteractsWithForms;

public Item $item;
public $comments;
Expand All @@ -32,6 +34,12 @@ public function submit()
return redirect()->route('login');
}

if (app(GeneralSettings::class)->users_must_verify_email && !auth()->user()->hasVerifiedEmail()) {
$this->notify('primary', 'Please verify your email before replying to items.');

return redirect()->route('verification.notice');
}

$formState = array_merge($this->form->getState(), [
'parent_id' => $this->reply,
'user_id' => auth()->id(),
Expand Down
6 changes: 6 additions & 0 deletions app/Http/Livewire/Modals/Item/CreateItemModal.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ public function submit()
return redirect()->route('login');
}

if (app(GeneralSettings::class)->users_must_verify_email && !auth()->user()->hasVerifiedEmail()) {
$this->notify('primary', 'Please verify your email before submitting items.');

return redirect()->route('verification.notice');
}

$data = $this->form->getState();

$item = Item::create([
Expand Down
3 changes: 2 additions & 1 deletion app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
use Filament\Models\Contracts\HasAvatar;
use Illuminate\Notifications\Notifiable;
use Filament\Models\Contracts\FilamentUser;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser, HasAvatar
class User extends Authenticatable implements FilamentUser, HasAvatar, MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;

Expand Down
40 changes: 25 additions & 15 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace App\Providers;

use App\Http\Kernel;
use Filament\Facades\Filament;
use App\Settings\GeneralSettings;
use App\Services\OgImageGenerator;
use Illuminate\Support\Collection;
use App\SocialProviders\SsoProvider;
Expand All @@ -13,17 +15,17 @@

class AppServiceProvider extends ServiceProvider
{
public function boot(): void
public function boot(Kernel $kernel): void
{
View::composer('partials.meta', static function ($view) {
$view->with(
'defaultImage',
OgImageGenerator::make(config('app.name'))
->withSubject('Roadmap')
->withPolygonDecoration()
->withFilename('og.jpg')
->generate()
->getPublicUrl()
->withSubject('Roadmap')
->withPolygonDecoration()
->withFilename('og.jpg')
->generate()
->getPublicUrl()
);
});

Expand All @@ -33,21 +35,24 @@ public function boot(): void

Filament::registerNavigationItems([
NavigationItem::make()
->group('External')
->sort(101)
->label('Public view')
->icon('heroicon-o-rewind')
->isActiveWhen(fn (): bool => false)
->url('/'),
->group('External')
->sort(101)
->label('Public view')
->icon('heroicon-o-rewind')
->isActiveWhen(fn (): bool => false)
->url('/'),
]);

if (file_exists($favIcon = storage_path('app/public/favicon.png'))) {
config(['filament.favicon' => asset('storage/favicon.png') . '?v=' . md5_file($favIcon)]);
}

$this->bootSsoSocialite();

$this->bootCollectionMacros();

// if (app(GeneralSettings::class)->users_must_verify_email) {
// $this->addVerificationMiddleware($kernel);
// }
}

private function bootSsoSocialite(): void
Expand All @@ -67,8 +72,13 @@ private function bootCollectionMacros(): void
$nonPrioritized = $this->reject($callback);

return $this
->filter($callback)
->merge($nonPrioritized);
->filter($callback)
->merge($nonPrioritized);
});
}

protected function addVerificationMiddleware(Kernel $kernel)
{
$kernel->appendMiddlewareToGroup('authed', 'verified');
}
}
1 change: 1 addition & 0 deletions app/Settings/GeneralSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class GeneralSettings extends Settings
public bool $project_required_when_creating_item;
public bool $block_robots;
public string $inbox_workflow;
public bool $users_must_verify_email;

public function getInboxWorkflow(): InboxWorkflow
{
Expand Down
5 changes: 5 additions & 0 deletions app/View/Components/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class App extends Component
public Collection $projects;
public string $brandColors;
public bool $blockRobots = false;
public bool $userNeedsToVerify = false;

public function __construct(public array $breadcrumbs = [])
{
Expand All @@ -38,6 +39,10 @@ public function render()

$this->brandColors = $tw->getCssFormat();

$this->userNeedsToVerify = app(GeneralSettings::class)->users_must_verify_email &&
auth()->check() &&
!auth()->user()->hasVerifiedEmail();

return view('components.app');
}
}
7 changes: 3 additions & 4 deletions database/migrations/2022_06_24_092158_create_jobs_table.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

return new class extends Migration
{
return new class extends Migration {
/**
* Run the migrations.
*
Expand Down
11 changes: 11 additions & 0 deletions database/settings/2022_06_24_095822_add_user_verified_setting.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

use Spatie\LaravelSettings\Migrations\SettingsMigration;

class AddUserVerifiedSetting extends SettingsMigration
{
public function up(): void
{
$this->migrator->add('general.users_must_verify_email', false);
}
}
1 change: 1 addition & 0 deletions lang/en/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

return [
'login' => 'Log in',
'verify-email' => 'Verify email',
'register' => 'Register',
'profile' => 'Profile',
'register_for_free' => 'Or <a class="text-brand-600 transition hover:text-brand-500 focus:outline-none focus:underline" href=":route">register</a> for free.',
Expand Down
1 change: 1 addition & 0 deletions lang/nl/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

return [
'login' => 'Inloggen',
'verify-email' => 'Verifieer email',
'register' => 'Registreren',
'profile' => 'Profiel',
'register_for_free' => 'Of <a class="text-brand-600 transition hover:text-brand-500 focus:outline-none focus:underline" href=":route">maak een gratis account aan</a>.',
Expand Down
29 changes: 29 additions & 0 deletions resources/views/auth/verify-email.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@section('title', trans('auth.verify-email'))
@section('image', App\Services\OgImageGenerator::make('Verify email')->withSubject('Roadmap')->withFilename('verify-email.jpg')->generate()->getPublicUrl())

<x-app>
<div class=" relative overflow-hidden flex justify-center">
<div class="z-10 flex-1 w-full max-w-lg py-8 md:py-16">
<div class="w-full max-w-lg px-4 mx-auto sm:px-6 md:px-8 space-y-4">
<h1 class="text-xl font-semibold tracking-tight md:text-2xl">
{{ trans('auth.verify-email') }}
</h1>

@if (session('resent'))
<div class="alert-success" role="alert">
{{ __('A fresh verification link has been sent to your email address.') }}
</div>
@endif

<div class="alert-info">
{{ __('Before proceeding, please check your email for a verification link.') }}
{{ __('If you did not receive the email') }},
<form method="POST" action="{{ route('verification.resend') }}">
@csrf
<button type="submit" class="border-b border-dotted border-blue-500 font-semibold">{{ __('click here to request another') }}</button>.
</form>
</div>
</div>
</div>
</div>
</x-app>
15 changes: 15 additions & 0 deletions resources/views/components/app.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@
@endif
</head>
<body class="antialiased bg-gray-50">
@if($userNeedsToVerify)
<div class="relative bg-brand-600">
<div class="max-w-7xl mx-auto py-3 px-3 sm:px-6 lg:px-8">
<div class="pr-16 sm:text-center sm:px-16">
<p class="font-medium text-white">
<span class="md:inline"> You have not verified your email yet, please verify your email.</span>
<span class="block sm:ml-2 sm:inline-block">
<a href="{{ route('verification.notice') }}" class="text-white font-bold underline"> Verify <span
aria-hidden="true">&rarr;</span></a>
</span>
</p>
</div>
</div>
</div>
@endif

@include('partials.header')

Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/comment.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@class([
'ml-1 md:ml-6' => $comment->parent_id !== null,
'mr-1 bg-brand-50 rounded-lg ring-1 ring-brand-200' => $reply == $comment->id,
'bg-yellow-50 border border-yellow-700 rounded-md mt-1' => $comment->private && !$comment->parent?->private,
'bg-yellow-50 border border-yellow-700 rounded-md mt-1 mb-1' => $comment->private && !$comment->parent?->private,
'block py-2 overflow-hidden transition'
])
id="comment-{{ $comment->id }}">
Expand Down
2 changes: 1 addition & 1 deletion resources/views/livewire/item/comments.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
if (hash) {
const commentElement = document.getElementById(hash.replace('#', ''));
commentElement.classList.add('bg-brand-50', 'rounded-lg', 'ring-1', 'ring-brand-200');
commentElement.classList.add('bg-brand-50', 'rounded-lg', 'ring-1', 'ring-brand-200', 'mt-2', 'mb-2');
}
})();
</script>
Expand Down
Loading

0 comments on commit 216b57b

Please sign in to comment.