Skip to content

Commit

Permalink
migrate hcaptcha vers turnstile (captcha cloudflare)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ornella452 committed Nov 25, 2024
1 parent 08074ac commit 03e8178
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 38 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@
})();
</script>
<script type="module" src="/src/index.js"></script>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</body>
</html>
15 changes: 11 additions & 4 deletions src/components/commun/Captcha.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';

const SITE_KEY = '84e24b30-44ca-488c-9260-ec80c290c166';
const SITE_KEY = '0x4AAAAAAA0pjEgohPDZsyqu';

export default function Captcha() {
export default function Captcha({ setWidgetId }) {
const captchaRef = useRef(null);

useEffect(() => {
if (window.hcaptcha) {
window.hcaptcha.render(captchaRef.current, {
if (window.turnstile) {
window.turnstile.remove();
const widgetId = window.turnstile.render(captchaRef.current, {
sitekey: SITE_KEY,
});
setWidgetId(widgetId);
}
}, []);

return (
<div ref={captchaRef}></div>
);
}

Captcha.propTypes = {
setWidgetId: PropTypes.func,
};
2 changes: 1 addition & 1 deletion src/components/commun/Input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function Input({ children, id, isRequired = true, autoComplete =
required={isRequired}
autoComplete={autoComplete}
pattern={pattern}
maxlength={maxlength}
maxLength={maxlength}
onChange={onChange}
list={list}
min={min}
Expand Down
2 changes: 1 addition & 1 deletion src/components/commun/ZoneDeTexte.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function ZoneDeTexte({ children, id, isRequired = true, maxlength
<label className="fr-label" htmlFor={id}>
{children}
</label>
<textarea className="fr-input" id={id} name={id} required={isRequired} maxlength={maxlength}></textarea>
<textarea className="fr-input" id={id} name={id} required={isRequired} maxLength={maxlength}></textarea>
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/views/candidature-conseiller/AddressChooser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function AddressChooser() {
</Input>
<Input type="hidden" id="lieuHabitationCodeCommune" value={codeCommune} testId="lieuHabitationCodeCommune-hidden"/>
<datalist id="resultatsRecherche">
{villes.map(({ codesPostaux, nom }, key) => (
{villes?.map(({ codesPostaux, nom }, key) => (
<option value={`${codesPostaux[0]} ${nom}`} key={key}>
{codesPostaux[0]} {nom}
</option>
Expand Down
7 changes: 4 additions & 3 deletions src/views/candidature-conseiller/CandidatureConseiller.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default function CandidatureConseiller() {
const [dateDisponibilite, setDateDisponibilite] = useState('');
const [isSituationValid, setIsSituationValid] = useState(true);
const [validationError, setValidationError] = useState('');
const [widgetId, setWidgetId] = useState(null);
const { buildConseillerData, creerCandidatureConseiller } = useApiAdmin();

const navigate = useNavigate();
Expand Down Expand Up @@ -57,11 +58,11 @@ export default function CandidatureConseiller() {
if (resultatCreation?.status >= 400) {
const error = await resultatCreation.json();
setValidationError(error.message);
window.hcaptcha.reset();
window.turnstile.reset(widgetId);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else if (!resultatCreation.status) {
setValidationError(resultatCreation.message);
window.hcaptcha.reset();
window.turnstile.reset(widgetId);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
navigate('/candidature-validee-conseiller');
Expand Down Expand Up @@ -95,7 +96,7 @@ export default function CandidatureConseiller() {
<Motivation />
<EnResume dateDisponibilite={dateDisponibilite} />
<div className="fr-mt-2w fr-mb-2w">
<Captcha />
<Captcha setWidgetId={setWidgetId} widgetId={widgetId}/>
</div>
<button className="fr-btn cc-envoyer" type="submit">
Envoyer votre candidature
Expand Down
16 changes: 9 additions & 7 deletions src/views/candidature-conseiller/CandidatureConseiller.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ describe('candidature conseiller', () => {

const descriptionMotivation = within(votreMotivation).getByLabelText('Votre message * Limité à 2500 caractères');
expect(descriptionMotivation).toHaveAttribute('name', 'motivation');
expect(descriptionMotivation).toHaveAttribute('maxlength', '2500');
expect(descriptionMotivation).toHaveAttribute('maxLength', '2500');
expect(descriptionMotivation).toBeRequired();
});

Expand Down Expand Up @@ -441,8 +441,9 @@ describe('candidature conseiller', () => {
vi.stubGlobal('fetch', vi.fn(
() => ({ status: 400, json: async () => Promise.resolve({ message: 'Cette adresse mail est déjà utilisée' }) }))
);
vi.stubGlobal('hcaptcha', {
vi.stubGlobal('turnstile', {
reset: vi.fn(),
remove: vi.fn(),
render: vi.fn()
});

Expand Down Expand Up @@ -475,7 +476,7 @@ describe('candidature conseiller', () => {
});

// THEN
expect(window.hcaptcha.reset).toHaveBeenCalledTimes(1);
expect(window.turnstile.reset).toHaveBeenCalledTimes(1);
const titreErreurValidation = screen.getByRole('heading', { level: 3, name: 'Erreur de validation' });
expect(titreErreurValidation).toBeInTheDocument();
const contenuErreurValidation = screen.getByText('Cette adresse mail est déjà utilisée', { selector: 'p' });
Expand Down Expand Up @@ -629,7 +630,7 @@ describe('candidature conseiller', () => {
'1'
],
[
'h-captcha-response',
'cf-turnstile-response',
'1'
]
];
Expand All @@ -649,7 +650,7 @@ describe('candidature conseiller', () => {
'dateDisponibilite': '2023-12-12',
'distanceMax': '5',
'motivation': 'je suis motivé !',
'h-captcha-response': '1',
'cf-turnstile-response': '1',
'estEnEmploi': false,
'estEnFormation': false,
'estDiplomeMedNum': false,
Expand Down Expand Up @@ -678,8 +679,9 @@ describe('candidature conseiller', () => {
creerCandidatureConseiller: vi.fn().mockReturnValue({ message: 'Failed to fetch' }),
buildConseillerData: vi.fn(),
}));
vi.stubGlobal('hcaptcha', {
vi.stubGlobal('turnstile', {
reset: vi.fn(),
remove: vi.fn(),
render: vi.fn()
});

Expand Down Expand Up @@ -714,7 +716,7 @@ describe('candidature conseiller', () => {
});

// THEN
expect(window.hcaptcha.reset).toHaveBeenCalledTimes(1);
expect(window.turnstile.reset).toHaveBeenCalledTimes(1);
const contenuErreurValidation = screen.getByText('Failed to fetch', { selector: 'p' });
expect(contenuErreurValidation).toBeInTheDocument();

Expand Down
4 changes: 2 additions & 2 deletions src/views/candidature-conseiller/useGeoApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useState } from 'react';
export const useGeoApi = () => {
const [villes, setVilles] = useState([]);

const distinctVilles = villes => [...new Map(villes.map(item => [item.code, item])).values()];
const distinctVilles = villes => [...new Map(villes?.map(item => [item.code, item])).values()];

const searchByName = async rechercheUtilisateur => {
const baseUrlSearch = new URL('https://api-adresse.data.gouv.fr/search');
Expand All @@ -12,7 +12,7 @@ export const useGeoApi = () => {
const villes = await fetch(url);
const communes = await villes.json();

const resultat = communes?.features.map(result => ({
const resultat = communes?.features?.map(result => ({
'nom': result.properties.municipality,
'code': result.properties.citycode,
'codesPostaux': [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import '../candidature-conseiller/CandidatureConseiller.css';
export default function CandidatureCoordinateur() {
const [geoLocation, setGeoLocation] = useState(null);
const [validationError, setValidationError] = useState('');
const [widgetId, setWidgetId] = useState(null);
const [codeCommune, setCodeCommune] = useState('');
const navigate = useNavigate();
const { buildCoordinateurData, creerCandidatureCoordinateur } = useApiAdmin();
Expand All @@ -42,11 +43,11 @@ export default function CandidatureCoordinateur() {
if (resultatCreation?.status >= 400) {
const error = await resultatCreation.json();
setValidationError(error.message);
window.hcaptcha.reset();
window.turnstile.reset(widgetId);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else if (!resultatCreation.status) {
setValidationError(resultatCreation.message);
window.hcaptcha.reset();
window.turnstile.reset(widgetId);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
navigate('/candidature-validee-structure');
Expand Down Expand Up @@ -76,7 +77,7 @@ export default function CandidatureCoordinateur() {
<Motivation />
<Engagement />
<div className="fr-mt-2w fr-mb-2w">
<Captcha />
<Captcha setWidgetId={setWidgetId} widgetId={widgetId} />
</div>
<button className="fr-btn cc-envoyer" type="submit">
Envoyer votre candidature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,9 @@ describe('candidature coordinateur', () => {
vi.stubGlobal('fetch', vi.fn(
() => ({ status: 400, json: async () => Promise.resolve({ message: 'Cette adresse mail est déjà utilisée' }) }))
);
vi.stubGlobal('hcaptcha', {
vi.stubGlobal('turnstile', {
reset: vi.fn(),
remove: vi.fn(),
render: vi.fn()
});

Expand Down Expand Up @@ -304,7 +305,7 @@ describe('candidature coordinateur', () => {
});

// THEN
expect(window.hcaptcha.reset).toHaveBeenCalledTimes(1);
expect(window.turnstile.reset).toHaveBeenCalledTimes(1);
const titreErreurValidation = screen.getByRole('heading', { level: 3, name: 'Erreur de validation' });
expect(titreErreurValidation).toBeInTheDocument();
const contenuErreurValidation = screen.getByText('Cette adresse mail est déjà utilisée', { selector: 'p' });
Expand Down Expand Up @@ -432,7 +433,7 @@ describe('candidature coordinateur', () => {
'1'
],
[
'h-captcha-response',
'cf-turnstile-response',
'1'
]
];
Expand All @@ -456,7 +457,7 @@ describe('candidature coordinateur', () => {
'dateDebutMission': '2023-12-12',
'motivation': 'je suis motivé !',
'confirmationEngagement': true,
'h-captcha-response': '1',
'cf-turnstile-response': '1',
'contact': {
'prenom': 'Jean', 'nom': 'Dupont',
'fonction': 'Test', 'email':
Expand Down Expand Up @@ -485,8 +486,9 @@ describe('candidature coordinateur', () => {
creerCandidatureCoordinateur: vi.fn().mockReturnValue({ message: 'Failed to fetch' }),
buildCoordinateurData: vi.fn(),
}));
vi.stubGlobal('hcaptcha', {
vi.stubGlobal('turnstile', {
reset: vi.fn(),
remove: vi.fn(),
render: vi.fn()
});

Expand Down Expand Up @@ -530,7 +532,7 @@ describe('candidature coordinateur', () => {


// THEN
expect(window.hcaptcha.reset).toHaveBeenCalledTimes(1);
expect(window.turnstile.reset).toHaveBeenCalledTimes(1);
const contenuErreurValidation = screen.getByText('Failed to fetch', { selector: 'p' });
expect(contenuErreurValidation).toBeInTheDocument();

Expand Down
7 changes: 4 additions & 3 deletions src/views/candidature-structure/CandidatureStructure.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import '../candidature-conseiller/CandidatureConseiller.css';
export default function CandidatureStructure() {
const [geoLocation, setGeoLocation] = useState(null);
const [codeCommune, setCodeCommune] = useState('');
const [widgetId, setWidgetId] = useState(null);
const [validationError, setValidationError] = useState('');
const navigate = useNavigate();
const { buildStructureData, creerCandidatureStructure } = useApiAdmin();
Expand All @@ -43,11 +44,11 @@ export default function CandidatureStructure() {
if (resultatCreation?.status >= 400) {
const error = await resultatCreation.json();
setValidationError(error.message);
window.hcaptcha.reset();
window.turnstile.reset(widgetId);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else if (!resultatCreation.status) {
setValidationError(resultatCreation.message);
window.hcaptcha.reset();
window.turnstile.reset(widgetId);
window.scrollTo({ top: 0, behavior: 'smooth' });
} else {
navigate('/candidature-validee-structure');
Expand Down Expand Up @@ -77,7 +78,7 @@ export default function CandidatureStructure() {
<Motivation />
<Engagement />
<div className="fr-mt-2w fr-mb-2w">
<Captcha />
<Captcha setWidgetId={setWidgetId} widgetId={widgetId}/>
</div>
<button className="fr-btn cc-envoyer" type="submit">
Envoyer votre candidature
Expand Down
14 changes: 8 additions & 6 deletions src/views/candidature-structure/CandidatureStructure.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,9 @@ describe('candidature structure', () => {
vi.stubGlobal('fetch', vi.fn(
() => ({ status: 400, json: async () => Promise.resolve({ message: 'Cette adresse mail est déjà utilisée' }) }))
);
vi.stubGlobal('hcaptcha', {
vi.stubGlobal('turnstile', {
reset: vi.fn(),
remove: vi.fn(),
render: vi.fn()
});

Expand Down Expand Up @@ -393,7 +394,7 @@ describe('candidature structure', () => {
});

// THEN
expect(window.hcaptcha.reset).toHaveBeenCalledTimes(1);
expect(window.turnstile.reset).toHaveBeenCalledTimes(1);
const titreErreurValidation = screen.getByRole('heading', { level: 3, name: 'Erreur de validation' });
expect(titreErreurValidation).toBeInTheDocument();
const contenuErreurValidation = screen.getByText('Cette adresse mail est déjà utilisée', { selector: 'p' });
Expand Down Expand Up @@ -521,7 +522,7 @@ describe('candidature structure', () => {
'1'
],
[
'h-captcha-response',
'cf-turnstile-response',
'1'
]
];
Expand All @@ -545,7 +546,7 @@ describe('candidature structure', () => {
'dateDebutMission': '2024-12-12',
'motivation': 'je suis motivé !',
'confirmationEngagement': true,
'h-captcha-response': '1',
'cf-turnstile-response': '1',
'location': { 'type': 'Point', 'coordinates': [2.3115, 48.8548] },
'contact': {
'prenom': 'Jean',
Expand Down Expand Up @@ -575,8 +576,9 @@ describe('candidature structure', () => {
creerCandidatureStructure: vi.fn().mockReturnValue({ message: 'Failed to fetch' }),
buildStructureData: vi.fn(),
}));
vi.stubGlobal('hcaptcha', {
vi.stubGlobal('turnstile', {
reset: vi.fn(),
remove: vi.fn(),
render: vi.fn()
});

Expand Down Expand Up @@ -620,7 +622,7 @@ describe('candidature structure', () => {


// THEN
expect(window.hcaptcha.reset).toHaveBeenCalledTimes(1);
expect(window.turnstile.reset).toHaveBeenCalledTimes(1);
const contenuErreurValidation = screen.getByText('Failed to fetch', { selector: 'p' });
expect(contenuErreurValidation).toBeInTheDocument();

Expand Down

0 comments on commit 03e8178

Please sign in to comment.