diff --git a/app/Console/Commands/Install.php b/app/Console/Commands/Install.php
index 8570367c..5b274307 100644
--- a/app/Console/Commands/Install.php
+++ b/app/Console/Commands/Install.php
@@ -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!');
diff --git a/app/Filament/Pages/Settings.php b/app/Filament/Pages/Settings.php
index 1d991077..6bf09d8b 100644
--- a/app/Filament/Pages/Settings.php
+++ b/app/Filament/Pages/Settings.php
@@ -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())
diff --git a/app/Filament/Pages/System.php b/app/Filament/Pages/System.php
index 2985cc55..d0d31a43 100644
--- a/app/Filament/Pages/System.php
+++ b/app/Filament/Pages/System.php
@@ -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
{
diff --git a/app/Filament/Pages/Widgets/System/SystemInfo.php b/app/Filament/Pages/Widgets/System/SystemInfo.php
index af85918d..e4a200af 100644
--- a/app/Filament/Pages/Widgets/System/SystemInfo.php
+++ b/app/Filament/Pages/Widgets/System/SystemInfo.php
@@ -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
{
diff --git a/app/Filament/Resources/CommentResource/Pages/EditComment.php b/app/Filament/Resources/CommentResource/Pages/EditComment.php
index cc847053..2c4461bb 100644
--- a/app/Filament/Resources/CommentResource/Pages/EditComment.php
+++ b/app/Filament/Resources/CommentResource/Pages/EditComment.php
@@ -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()
+ ];
+ }
}
diff --git a/app/Http/Controllers/Auth/VerificationController.php b/app/Http/Controllers/Auth/VerificationController.php
index 5e749af8..e2ccdcd2 100644
--- a/app/Http/Controllers/Auth/VerificationController.php
+++ b/app/Http/Controllers/Auth/VerificationController.php
@@ -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');
+ }
}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 0035379b..7bc3f508 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -39,6 +39,10 @@ class Kernel extends HttpKernel
\App\Http\Middleware\PasswordProtected::class,
],
+ 'authed' => [
+ 'auth',
+ ],
+
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
diff --git a/app/Http/Livewire/Item/Comments.php b/app/Http/Livewire/Item/Comments.php
index 8572593a..0836526f 100644
--- a/app/Http/Livewire/Item/Comments.php
+++ b/app/Http/Livewire/Item/Comments.php
@@ -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;
@@ -11,7 +13,7 @@
class Comments extends Component implements HasForms
{
- use InteractsWithForms;
+ use CanNotify, InteractsWithForms;
public Item $item;
public $comments;
@@ -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(),
diff --git a/app/Http/Livewire/Modals/Item/CreateItemModal.php b/app/Http/Livewire/Modals/Item/CreateItemModal.php
index 27c3e225..9d034035 100644
--- a/app/Http/Livewire/Modals/Item/CreateItemModal.php
+++ b/app/Http/Livewire/Modals/Item/CreateItemModal.php
@@ -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([
diff --git a/app/Models/User.php b/app/Models/User.php
index c47dbb71..88e09468 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -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;
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 1bfeb7f2..7d6e15ff 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -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;
@@ -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()
);
});
@@ -33,12 +35,12 @@ 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'))) {
@@ -46,8 +48,11 @@ public function boot(): void
}
$this->bootSsoSocialite();
-
$this->bootCollectionMacros();
+
+// if (app(GeneralSettings::class)->users_must_verify_email) {
+// $this->addVerificationMiddleware($kernel);
+// }
}
private function bootSsoSocialite(): void
@@ -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');
+ }
}
diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php
index 1f755d5b..533cc02f 100644
--- a/app/Settings/GeneralSettings.php
+++ b/app/Settings/GeneralSettings.php
@@ -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
{
diff --git a/app/View/Components/App.php b/app/View/Components/App.php
index 025ab316..59e0f3e4 100644
--- a/app/View/Components/App.php
+++ b/app/View/Components/App.php
@@ -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 = [])
{
@@ -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');
}
}
diff --git a/database/migrations/2022_06_24_092158_create_jobs_table.php b/database/migrations/2022_06_24_092158_create_jobs_table.php
index a786a891..4de64e58 100644
--- a/database/migrations/2022_06_24_092158_create_jobs_table.php
+++ b/database/migrations/2022_06_24_092158_create_jobs_table.php
@@ -1,11 +1,10 @@
migrator->add('general.users_must_verify_email', false);
+ }
+}
diff --git a/lang/en/auth.php b/lang/en/auth.php
index 3d145862..2ff50c5f 100644
--- a/lang/en/auth.php
+++ b/lang/en/auth.php
@@ -2,6 +2,7 @@
return [
'login' => 'Log in',
+ 'verify-email' => 'Verify email',
'register' => 'Register',
'profile' => 'Profile',
'register_for_free' => 'Or register for free.',
diff --git a/lang/nl/auth.php b/lang/nl/auth.php
index 9d90af94..3221eb39 100644
--- a/lang/nl/auth.php
+++ b/lang/nl/auth.php
@@ -13,6 +13,7 @@
return [
'login' => 'Inloggen',
+ 'verify-email' => 'Verifieer email',
'register' => 'Registreren',
'profile' => 'Profiel',
'register_for_free' => 'Of maak een gratis account aan.',
diff --git a/resources/views/auth/verify-email.blade.php b/resources/views/auth/verify-email.blade.php
new file mode 100644
index 00000000..0a26b758
--- /dev/null
+++ b/resources/views/auth/verify-email.blade.php
@@ -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())
+
+
+ {{ trans('auth.verify-email') }}
+
+
+ @if (session('resent'))
+
+ You have not verified your email yet, please verify your email. + + Verify + +
+