toggleTwoFactorService = $toggleTwoFactorService;
}
public function getMaxWidth(): MaxWidth|string
{
return config('panel.filament.display-width', 'screen-2xl');
}
protected function getForms(): array
{
return [
'form' => $this->form(
$this->makeForm()
->schema([
Tabs::make()->persistTabInQueryString()
->schema([
Tab::make('Account')
->label(trans('strings.account'))
->icon('tabler-user')
->schema([
TextInput::make('username')
->label(trans('strings.username'))
->disabled()
->readOnly()
->dehydrated(false)
->maxLength(255)
->unique(ignoreRecord: true)
->autofocus(),
TextInput::make('email')
->prefixIcon('tabler-mail')
->label(trans('strings.email'))
->email()
->required()
->maxLength(255)
->unique(ignoreRecord: true),
TextInput::make('password')
->label(trans('strings.password'))
->password()
->prefixIcon('tabler-password')
->revealable(filament()->arePasswordsRevealable())
->rule(Password::default())
->autocomplete('new-password')
->dehydrated(fn ($state): bool => filled($state))
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
->live(debounce: 500)
->same('passwordConfirmation'),
TextInput::make('passwordConfirmation')
->label(trans('strings.password_confirmation'))
->password()
->prefixIcon('tabler-password-fingerprint')
->revealable(filament()->arePasswordsRevealable())
->required()
->visible(fn (Get $get): bool => filled($get('password')))
->dehydrated(false),
Select::make('timezone')
->required()
->prefixIcon('tabler-clock-pin')
->options(fn () => collect(DateTimeZone::listIdentifiers())->mapWithKeys(fn ($tz) => [$tz => $tz]))
->searchable(),
Select::make('language')
->label(trans('strings.language'))
->required()
->prefixIcon('tabler-flag')
->live()
->default('en')
->helperText(fn ($state, LanguageService $languageService) => new HtmlString($languageService->isLanguageTranslated($state) ? '' : "
Your language ($state) has not been translated yet!
But never fear, you can help fix that by
contributing directly here.
"))
->options(fn (LanguageService $languageService) => $languageService->getAvailableLanguages()),
]),
Tab::make('OAuth')
->icon('tabler-brand-oauth')
->visible(function () {
$oauthProviders = OAuthProvider::get();
foreach ($oauthProviders as $oauthProvider) {
if ($oauthProvider->isEnabled()) {
return true;
}
}
return false;
})
->schema(function () {
$actions = [];
$oauthProviders = OAuthProvider::get();
foreach ($oauthProviders as $oauthProvider) {
if (!$oauthProvider->isEnabled()) {
continue;
}
$id = $oauthProvider->getId();
$name = $oauthProvider->getName();
$unlink = array_key_exists($id, $this->getUser()->oauth ?? []);
$actions[] = Action::make("oauth_$id")
->label(($unlink ? 'Unlink ' : 'Link ') . $name)
->icon($unlink ? 'tabler-unlink' : 'tabler-link')
->color(Color::hex($oauthProvider->getHexColor()))
->action(function (UserUpdateService $updateService) use ($id, $name, $unlink) {
if ($unlink) {
$oauth = auth()->user()->oauth;
unset($oauth[$id]);
$updateService->handle(auth()->user(), ['oauth' => $oauth]);
$this->fillForm();
Notification::make()
->title("OAuth provider '$name' unlinked")
->success()
->send();
} else {
redirect(Socialite::with($name)->redirect()->getTargetUrl());
}
});
}
return [Actions::make($actions)];
}),
Tab::make('2FA')
->icon('tabler-shield-lock')
->schema(function (TwoFactorSetupService $setupService) {
if ($this->getUser()->use_totp) {
return [
Placeholder::make('2fa-already-enabled')
->label('Two Factor Authentication is currently enabled!'),
Textarea::make('backup-tokens')
->hidden(fn () => !cache()->get("users.{$this->getUser()->id}.2fa.tokens"))
->rows(10)
->readOnly()
->dehydrated(false)
->formatStateUsing(fn () => cache()->get("users.{$this->getUser()->id}.2fa.tokens"))
->helperText('These will not be shown again!')
->label('Backup Tokens:'),
TextInput::make('2fa-disable-code')
->label('Disable 2FA')
->helperText('Enter your current 2FA code to disable Two Factor Authentication'),
];
}
['image_url_data' => $url, 'secret' => $secret] = cache()->remember(
"users.{$this->getUser()->id}.2fa.state",
now()->addMinutes(5), fn () => $setupService->handle($this->getUser())
);
$options = new QROptions([
'svgLogo' => public_path('pelican.svg'),
'svgLogoScale' => 0.05,
'addLogoSpace' => true,
'logoSpaceWidth' => 13,
'logoSpaceHeight' => 13,
'version' => Version::AUTO,
// 'outputInterface' => QRSvgWithLogo::class,
'outputBase64' => false,
'eccLevel' => EccLevel::H, // ECC level H is necessary when using logos
'addQuietzone' => true,
// 'drawLightModules' => true,
'connectPaths' => true,
'drawCircularModules' => true,
// 'circleRadius' => 0.45,
'svgDefs' => '