Email Verification in afterCreate() event

Hello, I have an application with two panels: admin and employee Admin creates employee accounts and sends the email for verification i use the code below in afterCreate() event
use Filament\Notifications\Auth\VerifyEmail;
use Filament\Facades\Filament;

protected function afterCreate(): void
{
$user = $this->getRecord();

$notification = new VerifyEmail();
$notification->url = Filament::getVerifyEmailUrl($user);
$user->notify($notification);
}
use Filament\Notifications\Auth\VerifyEmail;
use Filament\Facades\Filament;

protected function afterCreate(): void
{
$user = $this->getRecord();

$notification = new VerifyEmail();
$notification->url = Filament::getVerifyEmailUrl($user);
$user->notify($notification);
}
the email is sent correctly but Employee not have permission to access admin Panel and can't confirm the mail How can I solve the problem?
28 Replies
toeknee
toeknee2w ago
What is the url generated?
Zoltar
Zoltar2w ago
/admin for admin panel /employee for employee panel
toeknee
toeknee2w ago
So you need to call the panel which you are verifying against and not the current panel
toeknee
toeknee2w ago
Filament::getPanel('employee')->getVerifyEmailUrl($user);
Zoltar
Zoltar2w ago
http://xxx.server:8080/employee/email-verification/verify/22/efbee9998761bf518e8a0c66b055209c8e90051d?expires=1719327695&signature=a6bb7b4a3d21682e7482f063d30f243518eebfb0ecef461bd43a3710688699f3 the url is ok but the result is forbidden in User model i have set this:
public function canAccessPanel(Panel $panel): bool
{
//Verifica pannello admin / hr
if ($panel->getId() === 'admin') {
return ($this->hasVerifiedEmail() && $this->role == 'admin');
}

//Verifica pannello dipendenti
if ($panel->getId() === 'employee') {
return ($this->hasVerifiedEmail() && $this->role == 'employee');
}

return true;
}
public function canAccessPanel(Panel $panel): bool
{
//Verifica pannello admin / hr
if ($panel->getId() === 'admin') {
return ($this->hasVerifiedEmail() && $this->role == 'admin');
}

//Verifica pannello dipendenti
if ($panel->getId() === 'employee') {
return ($this->hasVerifiedEmail() && $this->role == 'employee');
}

return true;
}
No description
LeandroFerreira
does it work if you return true in this method?
Zoltar
Zoltar2w ago
yes need to create Custom EmailNotification?
LeandroFerreira
Try to authenticate in the employee panel with this account created before clicking the email verification link. I think this link should work if you are logged into the panel because when you create an account via the registration form, a session is created, and you are redirected to the panel without permissions to see the menu, etc, only the logout button.
Zoltar
Zoltar2w ago
No man not work because in canAccessPanel() i set $this->hasVerifiedEmail()
LeandroFerreira
I think they need to access the panel to validate the account
LeandroFerreira
GitHub
Resetting Password for Admin-Created User Accounts via Email. · fil...
How can an admin send a password reset link to a user after creating their account via mail? protected function afterCreate(): void { Password::sendResetLink(['email' => $this->record...
Zoltar
Zoltar2w ago
thnks go to test 🙂
LeandroFerreira
worked?
Zoltar
Zoltar2w ago
hello, switch to this solution
Zoltar
Zoltar2w ago
FilamentApps
Filament: Invite Only Registration via Email Invitations
Learn how to implement an invite-only registration feature using Filament, ensuring exclusive access to your platform and enhancing user engagement through personalized invitations and controlled membership enrollment.
Zoltar
Zoltar2w ago
in class UserInvitationMail extends Mailable in function public function content(): Content { return new Content( markdown: 'mail.auth.invitation', with: [ 'acceptUrl' => URL::signedRoute( 'filament.app.register', [ 'token' => $this->invitation->code, ], ), ], ); } got error in Route [filament.app.register] not defined. @Leandro Ferreira how to fix?
LeandroFerreira
hum, custom registration you should check if this route exists
Zoltar
Zoltar2w ago
Doesn't this seem like a good solution?
LeandroFerreira
not sure, I don't know this content.. but you can try
Zoltar
Zoltar2w ago
Ok its work at 99% There's only one thing that doesn't work... in class CustomRegister extends BaseRegister in function register() user after account creation go to /admin panel with forbidden error (because is it default???) instead of /employee panel Is there a way to point to the correct panel? return a redirect url?
public function register(): ?RegistrationResponse
{
$data = $this->form->getState();
$user = $this->getUserModel()::create($data);
$this->invitation->delete();

/*
app()->bind(
\Illuminate\Auth\Listeners\SendEmailVerificationNotification::class,
);
*/

//event(new Registered($user));

Filament::getPanel('employee')->auth()->login($user);

session()->regenerate();

return app(RegistrationResponse::class);
}
public function register(): ?RegistrationResponse
{
$data = $this->form->getState();
$user = $this->getUserModel()::create($data);
$this->invitation->delete();

/*
app()->bind(
\Illuminate\Auth\Listeners\SendEmailVerificationNotification::class,
);
*/

//event(new Registered($user));

Filament::getPanel('employee')->auth()->login($user);

session()->regenerate();

return app(RegistrationResponse::class);
}
LeandroFerreira
maybe setting the current panel?
filament()->setCurrentPanel(filament()->getPanel('employee'));
filament()->setCurrentPanel(filament()->getPanel('employee'));
Zoltar
Zoltar2w ago
99,9% :squint: Route [login] not defined. go /employee instead of employee/login if refresh page go to login correctly ok its works add this in web.php Route::get('/login', function () { return redirect(route('filament.employee.auth.login')); })->name('login');
DavidSP
DavidSP2w ago
Isn't that route automatically created when chaining the login() method to the panel?
Zoltar
Zoltar2w ago
it should..but custom register use /login route and not panelid/login route
Zoltar
Zoltar2w ago
No description
LeandroFerreira
try to add in the web.php
Route::redirect('login', 'employee/login')->name('login');
Route::redirect('login', 'employee/login')->name('login');
ahh, I didn't notice.. this is the same as you did
Zoltar
Zoltar2w ago
test your code and works