From b4cfd91ff480244f9b5be521e328c9aa22563d0f Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 8 Dec 2024 09:31:31 +0100 Subject: [PATCH] Preload a CSRF token on the registration page --- app/[slug]/page.tsx | 14 +++++++++++++- app/api/authentication.tsx | 19 ++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/[slug]/page.tsx b/app/[slug]/page.tsx index 5f518f7..ea3b9a4 100644 --- a/app/[slug]/page.tsx +++ b/app/[slug]/page.tsx @@ -5,10 +5,22 @@ import LoginForm from '@/app/ui/components/login-form'; import RegistrationForm from '@/app/ui/components/registration-form'; import { useParams } from 'next/navigation' +import { useEffect } from 'react'; +import { retrieveCSRFToken } from '../api/authentication'; +import { getCsrfToken } from '../lib/utils'; export default async function Page() { const params = useParams<{ slug: string }>() - localStorage.setItem('slug', await params.slug); + + useEffect(() => { + if (getCsrfToken() == 'unknown') { + retrieveCSRFToken(); + } + }, []); + + if (typeof window !== 'undefined') { + localStorage.setItem('slug', await params.slug); + } return (
diff --git a/app/api/authentication.tsx b/app/api/authentication.tsx index 5390fd5..69a52b4 100644 --- a/app/api/authentication.tsx +++ b/app/api/authentication.tsx @@ -35,7 +35,7 @@ export function logout({ onLogout }: { onLogout: () => void }) { } function flattenErrors(errors: StructuredErrors): string[] { - if(errors instanceof Array) { + if (errors instanceof Array) { return errors; } return Object.keys(errors).map((key) => { @@ -43,7 +43,16 @@ function flattenErrors(errors: StructuredErrors): string[] { }); } -export function register({slug, email, password, passwordConfirmation, captcha, onRegister, onError}: { +// At this moment we're making an initial request to get a valid CSRF token +export function retrieveCSRFToken() { + return fetch(`/api/token`, { + headers: { + 'Accept': 'application/json', + } + }).then((response) => { return null }); +} + +export function register({ slug, email, password, passwordConfirmation, captcha, onRegister, onError }: { slug: string, email: string, password: string, @@ -51,11 +60,11 @@ export function register({slug, email, password, passwordConfirmation, captcha, captcha: Captcha, onRegister: () => void, onError: (errors: string[]) => void -}){ +}) { fetch(`/api/${slug}/users`, { method: 'POST', body: JSON.stringify( - { + { user: { email, password, password_confirmation: passwordConfirmation }, captcha: { id: captcha.id, answer: captcha.answer } } @@ -66,7 +75,7 @@ export function register({slug, email, password, passwordConfirmation, captcha, 'X-CSRF-TOKEN': getCsrfToken(), } }).then((response) => { - if(response.ok) { + if (response.ok) { response.json().then(onRegister); } else { response.json().then((data: any) => {