Display a captcha in the registration form
This commit is contained in:
parent
12fe9b5b80
commit
d085a2ab19
@ -1,11 +1,8 @@
|
||||
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||
|
||||
'use client';
|
||||
import Link from 'next/link';
|
||||
import styles from '@/app/ui/home.module.css';
|
||||
import LoginForm from '@/app/ui/components/login-form';
|
||||
|
||||
|
||||
import RegistrationForm from '@/app/ui/components/registration-form';
|
||||
|
||||
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
||||
|
||||
@ -14,17 +11,15 @@ export default async function Page({ params }: { params: Promise<{ slug: string
|
||||
<main className="flex min-h-screen flex-col p-6">
|
||||
<div className="flex flex-row">
|
||||
<div className="w-1/2">
|
||||
|
||||
Already have an account? Sign in
|
||||
|
||||
<LoginForm />
|
||||
</div>
|
||||
|
||||
<div className="w-1/2">
|
||||
Don't have an account? Register now!
|
||||
<RegistrationForm />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||
|
||||
import { getCsrfToken, getSlug } from '@/app/lib/utils';
|
||||
import { User } from '@/app/lib/definitions';
|
||||
import { Captcha, User } from '@/app/lib/definitions';
|
||||
|
||||
export function login({ email, password, onLogin }: { email: string, password: string, onLogin: (user: User) => void }) {
|
||||
console.log(email, password);
|
||||
return fetch(`/api/${getSlug()}/users/sign_in`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ user: { email, password } }),
|
||||
@ -34,3 +33,28 @@ export function logout({ onLogout }: { onLogout: () => void }) {
|
||||
}).then(onLogout)
|
||||
.catch((error) => console.error(error));
|
||||
}
|
||||
|
||||
export function register({slug, email, password, passwordConfirmation, captcha, onRegister}: {
|
||||
slug: string,
|
||||
email: string,
|
||||
password: string,
|
||||
passwordConfirmation: string,
|
||||
captcha: Captcha,
|
||||
onRegister: () => void
|
||||
}){
|
||||
fetch(`/api/${slug}/users`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(
|
||||
{
|
||||
user: { email, password, password_confirmation: passwordConfirmation },
|
||||
captcha: { id: captcha.id, answer: captcha.answer }
|
||||
}
|
||||
),
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': getCsrfToken(),
|
||||
}
|
||||
}).then(onRegister)
|
||||
.catch((error) => console.error(error));
|
||||
}
|
||||
|
17
app/api/captcha.tsx
Normal file
17
app/api/captcha.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { data } from "autoprefixer";
|
||||
import { getCsrfToken } from "../lib/utils";
|
||||
|
||||
export function getCaptchaChallenge({onRetrieve}: {onRetrieve: (id: string, url: string) => void}){
|
||||
return fetch('/api/captcha', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': getCsrfToken(),
|
||||
}
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data: any) => {
|
||||
onRetrieve(data.id, data.media_url)
|
||||
})
|
||||
.catch((error) => console.error(error));
|
||||
}
|
@ -65,3 +65,8 @@ export type User = {
|
||||
id: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export type Captcha = {
|
||||
id: string;
|
||||
answer: string;
|
||||
}
|
81
app/ui/components/registration-form.tsx
Normal file
81
app/ui/components/registration-form.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
/* Copyright (C) 2024 Manuel Bustillo*/
|
||||
|
||||
'use client';
|
||||
|
||||
import { FloatLabel } from 'primereact/floatlabel';
|
||||
import { InputText } from 'primereact/inputtext';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { classNames } from './button';
|
||||
import { getSlug } from '@/app/lib/utils';
|
||||
import { register } from '@/app/api/authentication';
|
||||
import { getCaptchaChallenge } from '@/app/api/captcha';
|
||||
|
||||
export default function RegistrationForm() {
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [password, setPassword] = useState<string>("");
|
||||
const [passwordConfirmation, setPasswordConfirmation] = useState<string>("");
|
||||
const [slug, setSlug] = useState<string>(getSlug());
|
||||
|
||||
const [captchaId, setCaptchaId] = useState<string>("");
|
||||
const [captchaUrl, setCaptchaUrl] = useState<string>("");
|
||||
const [captchaAnswer, setCaptchaAnswer] = useState<string>("");
|
||||
|
||||
const refreshCaptcha = () => {
|
||||
getCaptchaChallenge({
|
||||
onRetrieve: (id, url) => {
|
||||
console.log(id, url);
|
||||
setCaptchaId(id);
|
||||
setCaptchaUrl(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(refreshCaptcha, [])
|
||||
|
||||
return (
|
||||
<div className="card flex justify-evenly py-5 flex-col">
|
||||
<FloatLabel className="my-4">
|
||||
<InputText id="email" type="email" className='rounded-sm' onChange={(e) => setEmail(e.target.value)} />
|
||||
<label htmlFor="email">Email</label>
|
||||
</FloatLabel>
|
||||
<FloatLabel className="my-4">
|
||||
<InputText id="password" type="password" className='rounded-sm' onChange={(e) => setPassword(e.target.value)} />
|
||||
<label htmlFor="password">Password</label>
|
||||
</FloatLabel>
|
||||
<FloatLabel className="my-4">
|
||||
<InputText id="passwordConfirmation" type="password" className='rounded-sm' onChange={(e) => setPasswordConfirmation(e.target.value)} />
|
||||
<label htmlFor="passwordConfirmation">Confirm Password</label>
|
||||
</FloatLabel>
|
||||
<FloatLabel className="my-4">
|
||||
<InputText id="slug" type="text" className='rounded-sm' onChange={(e) => setSlug(e.target.value)} />
|
||||
<label htmlFor="slug">Slug</label>
|
||||
</FloatLabel>
|
||||
<img className="w-96" src={captchaUrl} alt="captcha" />
|
||||
<FloatLabel className="my-4">
|
||||
<InputText id="captcha" type="text" className='rounded-sm' onChange={(e) => setCaptchaAnswer(e.target.value)} />
|
||||
<label htmlFor="captcha">Captcha</label>
|
||||
</FloatLabel>
|
||||
|
||||
|
||||
<button
|
||||
className={classNames('primary')}
|
||||
disabled={!(email && password && passwordConfirmation && slug && captchaAnswer)}
|
||||
onClick={() => register(
|
||||
{
|
||||
slug: slug,
|
||||
email: email,
|
||||
password: password,
|
||||
passwordConfirmation: passwordConfirmation,
|
||||
captcha: {
|
||||
id: captchaId,
|
||||
answer: captchaAnswer
|
||||
},
|
||||
onRegister: () => { console.log("registered") }
|
||||
}
|
||||
)}
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user