Skip to content

Commit

Permalink
Merge branches 'fix/compteurs-places-ouvertes-2023', 'feat/accessibil…
Browse files Browse the repository at this point in the history
…ite/titles', 'fix/reset-password-msg' and 'fix/clean-console' into feat/merged-pr-next
  • Loading branch information
LucasDetre committed Nov 25, 2024
4 parents f88c66f + 4a0043c + c845c16 + 22308f5 commit 621d788
Show file tree
Hide file tree
Showing 23 changed files with 424 additions and 206 deletions.
2 changes: 1 addition & 1 deletion .bin/scripts/buildkitd.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[worker.oci]
max-parallelism = 2

[[worker.oci.gcpolicy]]
all = true
keepBytes = "20GB"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ describe("resetPassword usecase", () => {
repeatPassword: correctPassword,
resetPasswordToken: undefined as unknown as string,
})
).rejects.toThrow("missing token");
).rejects.toThrow(
"Lien de réinitialisation incorrect ou expiré. Veuillez reprendre la procédure de réinitialisation depuis le début."
);
});

it("should throw an exception if the token is invalid", async () => {
Expand All @@ -38,7 +40,9 @@ describe("resetPassword usecase", () => {
repeatPassword: correctPassword,
resetPasswordToken: "fakeToken",
})
).rejects.toThrow("wrong token");
).rejects.toThrow(
"Lien de réinitialisation incorrect ou expiré. Veuillez reprendre la procédure de réinitialisation depuis le début."
);
});

it("should throw an exception if passwords are different", async () => {
Expand All @@ -53,7 +57,7 @@ describe("resetPassword usecase", () => {
repeatPassword: "bbb",
resetPasswordToken,
})
).rejects.toThrow("different passwords");
).rejects.toThrow("Mot de passe non identiques.");
});

it("should throw an exception if password is unsafe", async () => {
Expand All @@ -68,7 +72,9 @@ describe("resetPassword usecase", () => {
repeatPassword: "azerty",
resetPasswordToken,
})
).rejects.toThrow("password unsafe");
).rejects.toThrow(
"Le mot de passe doit contenir entre 8 et 15 caractères, une lettre en minuscule, une lettre en majuscule, un chiffre et un caractère spécial (les espaces ne sont pas acceptés)"
);
});

it("should set password", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,32 @@ export const [resetPassword, resetPasswordFactory] = inject(
repeatPassword: string;
resetPasswordToken: string;
}) => {
if (!resetPasswordToken) throw Boom.unauthorized("missing token");
if (!resetPasswordToken)
throw Boom.unauthorized(
"Lien de réinitialisation incorrect ou expiré. Veuillez reprendre la procédure de réinitialisation depuis le début."
);

let decryptedToken: { email: string };
try {
decryptedToken = jwt.verify(resetPasswordToken, deps.jwtSecret) as {
email: string;
};
} catch {
throw Boom.unauthorized("wrong token");
throw Boom.unauthorized(
"Lien de réinitialisation incorrect ou expiré. Veuillez reprendre la procédure de réinitialisation depuis le début."
);
}

const email = decryptedToken.email.toLowerCase();

if (password !== repeatPassword) {
throw Boom.badRequest("different passwords");
throw Boom.badRequest("Mot de passe non identiques.");
}

if (!password.match(passwordRegex)) {
throw Boom.badRequest("password unsafe");
throw Boom.badRequest(
"Le mot de passe doit contenir entre 8 et 15 caractères, une lettre en minuscule, une lettre en majuscule, un chiffre et un caractère spécial (les espaces ne sont pas acceptés)"
);
}

const hashedPassword = hashPassword(password);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ export const [submitRequeteEnregistreeUsecase, submitRequeteEnregistreeFactory]
user: Pick<RequestUser, "id" | "role" | "codeRegion" | "uais">;
requeteEnregistree: RequeteEnregistree;
}) => {
const requeteEnregistreeVide = Object.keys(requeteEnregistree.filtres).length === 0;

if (requeteEnregistreeVide) {
throw Boom.badRequest("Requête enregistrée vide", {
errors: {
empty_requete:
"La requête enregistrée ne peut pas être vide. Choisissez des filtres pour enregistrer une requête.",
},
});
}

const requeteEnregistreeExistante = await findOneSimilarRequeteEnregistreeQuery({
...requeteEnregistree,
userId: user.id,
Expand Down
117 changes: 20 additions & 97 deletions server/src/modules/utils/countCapacite/countPlacesOuvertes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,60 +28,35 @@ export const countPlacesOuvertesScolaireTransitionEcologique = ({
eb,
}: {
eb: ExpressionBuilder<DB, "demande" | "rome" | "campagne">;
}) =>
eb
.case()
.when(inTransitionEcologique(eb))
.then(countPlacesOuvertesScolaire(eb))
.else(0)
.end();
}) => eb.case().when(inTransitionEcologique(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();

export const countPlacesOuvertesApprentissageTransitionEcologique = ({
eb,
}: {
eb: ExpressionBuilder<DB, "demande" | "rome" | "campagne">;
}) =>
eb
.case()
.when(inTransitionEcologique(eb))
.then(countPlacesOuvertesApprentissage(eb))
.else(0)
.end();
}) => eb.case().when(inTransitionEcologique(eb)).then(countPlacesOuvertesApprentissage(eb)).else(0).end();

export const countPlacesOuvertes = ({
eb,
}: {
eb: ExpressionBuilder<DB, "demande" | "campagne">;
}) => sql<number>`
export const countPlacesOuvertes = ({ eb }: { eb: ExpressionBuilder<DB, "demande" | "campagne"> }) => sql<number>`
${countPlacesOuvertesScolaire(eb)} +
${countPlacesOuvertesApprentissage(eb)}
`;

export const countPlacesOuvertesQ1 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ1(eb)).then(countPlacesOuvertes(eb)).else(0).end();

export const countPlacesOuvertesQ2 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ2(eb)).then(countPlacesOuvertes(eb)).else(0).end();

export const countPlacesOuvertesQ1Q2 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ1Q2(eb)).then(countPlacesOuvertes(eb)).else(0).end();

export const countPlacesOuvertesCorrection = ({ eb }: { eb: ExpressionBuilder<DB, "correction" | "demande"> }) =>
Expand All @@ -90,11 +65,7 @@ export const countPlacesOuvertesCorrection = ({ eb }: { eb: ExpressionBuilder<DB
${countPlacesOuvertesApprentissageCorrection(eb)}
`;

export const countPlacesOuvertesScolaire = ({
eb,
}: {
eb: ExpressionBuilder<DB, "demande" | "campagne">;
}) =>
export const countPlacesOuvertesScolaire = ({ eb }: { eb: ExpressionBuilder<DB, "demande" | "campagne"> }) =>
eb
.case()
.when(
Expand Down Expand Up @@ -156,37 +127,20 @@ export const countPlacesOuvertesScolaire = ({
export const countPlacesOuvertesScolaireQ1 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
}) =>
eb.case().when(inQ1(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ1(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();

export const countPlacesOuvertesScolaireQ2 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
}) =>
eb.case().when(inQ2(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ2(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();

export const countPlacesOuvertesScolaireQ1Q2 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
}) =>
eb
.case()
.when(inQ1Q2(eb))
.then(countPlacesOuvertesScolaire(eb))
.else(0)
.end();
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ1Q2(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();

export const countPlacesOuvertesScolaireCorrection = ({
eb,
Expand All @@ -198,11 +152,7 @@ export const countPlacesOuvertesScolaireCorrection = ({
${eb.ref("correction.capaciteScolaireActuelle")}
)`;

export const countPlacesOuvertesApprentissage = ({
eb,
}: {
eb: ExpressionBuilder<DB, "demande" | "campagne">;
}) =>
export const countPlacesOuvertesApprentissage = ({ eb }: { eb: ExpressionBuilder<DB, "demande" | "campagne"> }) =>
eb
.case()
.when(
Expand Down Expand Up @@ -269,47 +219,20 @@ export const countPlacesOuvertesApprentissage = ({
export const countPlacesOuvertesApprentissageQ1 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
}) =>
eb
.case()
.when(inQ1(eb))
.then(countPlacesOuvertesApprentissage(eb))
.else(0)
.end();
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ1(eb)).then(countPlacesOuvertesApprentissage(eb)).else(0).end();

export const countPlacesOuvertesApprentissageQ2 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
}) =>
eb
.case()
.when(inQ2(eb))
.then(countPlacesOuvertesApprentissage(eb))
.else(0)
.end();
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ2(eb)).then(countPlacesOuvertesApprentissage(eb)).else(0).end();

export const countPlacesOuvertesApprentissageQ1Q2 = ({
eb,
}: {
eb: ExpressionBuilder<
DB,
"demande" | "positionFormationRegionaleQuadrant" | "campagne"
>;
}) =>
eb
.case()
.when(inQ1Q2(eb))
.then(countPlacesOuvertesScolaire(eb))
.else(0)
.end();
eb: ExpressionBuilder<DB, "demande" | "positionFormationRegionaleQuadrant" | "campagne">;
}) => eb.case().when(inQ1Q2(eb)).then(countPlacesOuvertesScolaire(eb)).else(0).end();

export const countPlacesOuvertesApprentissageCorrection = ({
eb,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const ActivateAccountForm = ({ activationToken }: { activationToken: stri
pattern: {
value: new RegExp(passwordRegex),
message:
"Le mot de passe doit contenir au moins 8 caractères, une lettre en minuscule, une lettre en majuscule, un chiffre et un caractère spécial (les espaces ne sont pas acceptés)",
"Le mot de passe doit contenir entre 8 et 15 caractères, une lettre en minuscule, une lettre en majuscule, un chiffre et un caractère spécial (les espaces ne sont pas acceptés)",
},
})}
/>
Expand Down
17 changes: 12 additions & 5 deletions ui/app/(wrapped)/auth/reset-password/ResetPasswordForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Input,
Text,
} from "@chakra-ui/react";
import { isAxiosError } from "axios";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { passwordRegex } from "shared/utils/passwordRegex";
Expand All @@ -31,6 +32,7 @@ export const ResetPasswordForm = ({ resetPasswordToken }: { resetPasswordToken:

const {
mutate: activateAccount,
error,
isError,
isLoading,
} = client.ref("[POST]/auth/reset-password").useMutation({
Expand All @@ -54,7 +56,7 @@ export const ResetPasswordForm = ({ resetPasswordToken }: { resetPasswordToken:
pattern: {
value: new RegExp(passwordRegex),
message:
"Le mot de passe doit contenir au moins 8 caractères, une lettre en minuscule, une lettre en majuscule, un chiffre et un caractère spécial (les espaces ne sont pas acceptés)",
"Le mot de passe doit contenir entre 8 et 15 caractères, une lettre en minuscule, une lettre en majuscule, un chiffre et un caractère spécial (les espaces ne sont pas acceptés)",
},
})}
/>
Expand All @@ -75,10 +77,15 @@ export const ResetPasswordForm = ({ resetPasswordToken }: { resetPasswordToken:
/>
{!!errors.repeatPassword && <FormErrorMessage>{errors.repeatPassword.message}</FormErrorMessage>}
</FormControl>
{isError && (
<Text fontSize="sm" mt="4" textAlign="center" color="red.500">
Erreur lors de la réinitialisation du mot de passe
</Text>
{isError && isAxiosError(error) && (
<>
<Text fontSize="sm" mt="4" textAlign="center" color="red.500">
Erreur lors de la réinitialisation du mot de passe :
</Text>
<Text fontSize="sm" mt="4" textAlign="center" color="red.500">
{error.response?.data?.message}
</Text>
</>
)}
<Flex>
<Button isLoading={isLoading} type="submit" mt="4" ml="auto" variant="primary">
Expand Down
12 changes: 11 additions & 1 deletion ui/app/(wrapped)/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ import { useSelectedLayoutSegments } from "next/navigation";
import { LandingFooter } from "./LandingFooter";
import { MinimalFooter } from "./MinimalFooter";

const LANDING_FOOTER_SEGMENTS = ["panorama", "pilotage", "pilotage-reforme", "ressources", "changelog"];
const LANDING_FOOTER_SEGMENTS = [
"panorama",
"pilotage",
"pilotage-reforme",
"ressources",
"changelog",
"declaration-accessibilite",
"politique-de-confidentialite",
"cgu",
"mentions-legales",
];

export const Footer = () => {
const segments = useSelectedLayoutSegments();
Expand Down
9 changes: 1 addition & 8 deletions ui/app/(wrapped)/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,7 @@ export const Header = ({ isMaintenance }: { isMaintenance?: boolean }) => {
</Flex>
</VStack>
{!isMaintenance && (
<Box
boxShadow="0 2px 3px rgba(0,0,18,0.16)"
position="sticky"
top={0}
left={0}
zIndex="docked"
backgroundColor="white"
>
<Box boxShadow="0 2px 3px rgba(0,0,18,0.16)" position="sticky" top={0} zIndex="docked" backgroundColor="white">
<Container maxWidth={"container.xl"} px={0}>
<Nav />
</Container>
Expand Down
Loading

0 comments on commit 621d788

Please sign in to comment.