Add tests for featured thumbnail generation; apply Pint formatting and related edits
This commit is contained in:
@@ -17,6 +17,7 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
@@ -37,10 +38,16 @@ class RegisteredUserController extends Controller
|
||||
*/
|
||||
public function create(Request $request): View
|
||||
{
|
||||
$cspNonce = $this->resolveCspNonce($request);
|
||||
|
||||
return view('auth.register', [
|
||||
'prefillEmail' => (string) $request->query('email', ''),
|
||||
'requiresCaptcha' => $this->shouldRequireCaptcha($request->ip()),
|
||||
'captcha' => $this->captchaVerifier->frontendConfig(),
|
||||
'turnstile' => [
|
||||
'enabled' => $this->turnstileVerifier->isEnabled(),
|
||||
'siteKey' => $this->turnstileVerifier->siteKey(),
|
||||
'scriptUrl' => $this->turnstileVerifier->scriptUrl(),
|
||||
'cspNonce' => $cspNonce,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -62,25 +69,35 @@ class RegisteredUserController extends Controller
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$turnstileResponse = (string) ($request->input('turnstile_token') ?: $request->input('cf-turnstile-response', ''));
|
||||
|
||||
$rules = [
|
||||
'email' => ['required', 'string', 'lowercase', 'email', 'max:255'],
|
||||
'website' => ['nullable', 'max:0'],
|
||||
'turnstile_token' => ['nullable', 'string'],
|
||||
'cf-turnstile-response' => [$this->turnstileVerifier->isEnabled() ? 'required_without:turnstile_token' : 'nullable', 'string'],
|
||||
];
|
||||
$rules[$this->captchaVerifier->inputName()] = ['nullable', 'string'];
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$errors = $validator->errors()->toArray();
|
||||
|
||||
if (array_key_exists('cf-turnstile-response', $errors) && ! array_key_exists('turnstile_token', $errors)) {
|
||||
$errors['turnstile_token'] = $errors['cf-turnstile-response'];
|
||||
unset($errors['cf-turnstile-response']);
|
||||
}
|
||||
|
||||
$this->authAuditLogger->log(
|
||||
eventType: 'register',
|
||||
request: $request,
|
||||
status: 'failed',
|
||||
reason: 'validation_failed',
|
||||
identifier: (string) $request->input('email'),
|
||||
metadata: ['fields' => array_keys($validator->errors()->toArray())],
|
||||
metadata: ['fields' => array_keys($errors)],
|
||||
);
|
||||
|
||||
$validator->validate();
|
||||
throw ValidationException::withMessages($errors);
|
||||
}
|
||||
|
||||
$validated = $validator->validated();
|
||||
@@ -90,32 +107,18 @@ class RegisteredUserController extends Controller
|
||||
|
||||
$this->trackRegisterAttempt($ip);
|
||||
|
||||
if ($this->shouldRequireCaptcha($ip)) {
|
||||
$verified = $this->captchaVerifier->verify(
|
||||
(string) $request->input($this->captchaVerifier->inputName(), ''),
|
||||
$ip
|
||||
if ($this->turnstileVerifier->isEnabled() && ! $this->turnstileVerifier->verify($turnstileResponse, $ip)) {
|
||||
$this->authAuditLogger->log(
|
||||
eventType: 'register',
|
||||
request: $request,
|
||||
status: 'failed',
|
||||
reason: 'captcha_failed',
|
||||
identifier: $email,
|
||||
);
|
||||
|
||||
if ($this->turnstileVerifier->isEnabled()) {
|
||||
$verified = $this->turnstileVerifier->verify(
|
||||
(string) $request->input($this->captchaVerifier->inputName(), ''),
|
||||
$ip
|
||||
);
|
||||
}
|
||||
|
||||
if (! $verified) {
|
||||
$this->authAuditLogger->log(
|
||||
eventType: 'register',
|
||||
request: $request,
|
||||
status: 'failed',
|
||||
reason: 'captcha_failed',
|
||||
identifier: $email,
|
||||
);
|
||||
|
||||
return back()
|
||||
->withInput($request->except('website'))
|
||||
->withErrors(['captcha' => 'Captcha verification failed. Please try again.']);
|
||||
}
|
||||
return back()
|
||||
->withInput($request->except('website', 'turnstile_token', 'cf-turnstile-response'))
|
||||
->withErrors(['turnstile_token' => 'Security verification failed. Please try again.']);
|
||||
}
|
||||
|
||||
if ($this->disposableEmailService->isDisposableEmail($email)) {
|
||||
@@ -264,23 +267,6 @@ class RegisteredUserController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
private function shouldRequireCaptcha(?string $ip): bool
|
||||
{
|
||||
if (! $this->captchaVerifier->isEnabled()) {
|
||||
if (! $this->turnstileVerifier->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! (bool) config('registration.enable_turnstile', true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->turnstileVerifier->isEnabled() && $this->shouldRequireCaptchaForIp($ip);
|
||||
}
|
||||
|
||||
return $this->shouldRequireCaptchaForIp($ip);
|
||||
}
|
||||
|
||||
private function shouldRequireCaptchaForIp(?string $ip): bool
|
||||
{
|
||||
if (! $this->captchaVerifier->isEnabled() && ! $this->turnstileVerifier->isEnabled()) {
|
||||
@@ -387,4 +373,28 @@ class RegisteredUserController extends Controller
|
||||
|
||||
return $remaining >= 0 ? 0 : abs((int) $remaining);
|
||||
}
|
||||
|
||||
private function resolveCspNonce(Request $request): ?string
|
||||
{
|
||||
$candidates = [
|
||||
$request->attributes->get('csp_nonce'),
|
||||
$request->attributes->get('cspNonce'),
|
||||
$request->headers->get('X-CSP-Nonce'),
|
||||
$request->server('HTTP_X_CSP_NONCE'),
|
||||
];
|
||||
|
||||
foreach ($candidates as $candidate) {
|
||||
if (! is_string($candidate)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$nonce = trim($candidate);
|
||||
|
||||
if ($nonce !== '') {
|
||||
return $nonce;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user