Skip to content

Commit

Permalink
feat(dashboard): création d'utilisateurs plus rapide avec valeurs par…
Browse files Browse the repository at this point in the history
… défaut et possiblité d'enchainer les uns après les autres rapidement (#1691)

* feat(dashboard): création d'utilisateurs plus rapide avec valeurs par défaut et possiblité d'enchainer les uns après les autres rapidement

* fix: no username by default
  • Loading branch information
arnaudambro authored Oct 5, 2023
1 parent c5ab685 commit 1a56eb0
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 152 deletions.
2 changes: 1 addition & 1 deletion api/src/controllers/organisation.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Un compte Mano pour votre organisation ${organisation.name} vient d'être créé
Votre identifiant pour vous connecter à Mano est ${adminUser.email}.
Vous pouvez dès à présent vous connecter pour choisir votre mot de passe ici:
https://dashboard-mano.fabrique.social.gouv.fr/auth/reset?token=${token}
https://dashboard-mano.fabrique.social.gouv.fr/auth/reset?token=${token}&newUser=true
Vous pourrez ensuite paramétrer votre organisation et commencer à utiliser Mano en suivant ce lien:
https://dashboard-mano.fabrique.social.gouv.fr/
Expand Down
13 changes: 8 additions & 5 deletions api/src/controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ router.post(
catchErrors(async (req, res, next) => {
try {
z.object({
name: z.string().optional(),
token: z.string().min(1),
password: z.string().min(1),
}).parse(req.body);
Expand All @@ -279,8 +280,9 @@ router.post(
return next(error);
}
const {
body: { token, password },
body: { token, password, name },
} = req;
console.log(req.body);

if (!validatePassword(password)) return res.status(400).send({ ok: false, error: passwordCheckError, code: PASSWORD_NOT_VALIDATED });
const user = await User.findOne({ where: { forgotPasswordResetToken: token, forgotPasswordResetExpires: { [Op.gte]: new Date() } } });
Expand All @@ -292,6 +294,7 @@ router.post(
forgotPasswordResetExpires: null,
lastChangePasswordAt: Date.now(),
});
if (name) user.set({ name: sanitizeAll(name) });
await user.save();
return res.status(200).send({ ok: true });
})
Expand All @@ -304,7 +307,7 @@ router.post(
catchErrors(async (req, res, next) => {
try {
z.object({
name: z.string().min(1),
name: z.string().optional(),
email: z.preprocess((email) => email.trim().toLowerCase(), z.string().email().optional().or(z.literal(""))),
healthcareProfessional: z.boolean(),
team: z.array(z.string().regex(looseUuidRegex)),
Expand All @@ -330,7 +333,7 @@ router.post(
};

const prevUser = await User.findOne({ where: { email: newUser.email } });
if (prevUser) return res.status(400).send({ ok: false, error: "A user already exists with this email" });
if (prevUser) return res.status(400).send({ ok: false, error: "Un utilisateur existe déjà avec cet email" });

const data = await User.create(newUser, { returning: true });

Expand All @@ -348,8 +351,8 @@ router.post(
const body = `Bonjour ${data.name} !
Votre identifiant pour vous connecter à Mano est ${data.email}.
Vous pouvez dès à présent vous connecter pour choisir votre mot de passe ici:
https://dashboard-mano.fabrique.social.gouv.fr/auth/reset?token=${token}
Vous pouvez dès à présent vous connecter pour choisir votre nom d'utilisateur et mot de passe ici:
https://dashboard-mano.fabrique.social.gouv.fr/auth/reset?token=${token}&newUser=true
NOTE: si le lien ci-dessus est expiré, vous pouvez demander une nouvelle réinitialisation de mot de passe ici: https://dashboard-mano.fabrique.social.gouv.fr
Vous pourrez ensuite commencer à utiliser Mano en suivant ce lien:
Expand Down
6 changes: 3 additions & 3 deletions dashboard/src/components/ChangePassword.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const ChangePassword = ({ onSubmit, onFinished, withCurrentPassword, centerButto
<label htmlFor="password">Mot de passe</label>
<PasswordInput
value={changePasswordForm.password}
className="tw-mb-1.5 tw-block tw-w-full tw-rounded tw-border tw-border-main75 tw-bg-transparent tw-p-2.5 tw-text-black tw-outline-main tw-transition-all"
className="tailwindui"
name="password"
id="password"
onChange={handleChange}
Expand All @@ -114,7 +114,7 @@ const ChangePassword = ({ onSubmit, onFinished, withCurrentPassword, centerButto
<PasswordInput
name="newPassword"
id="newPassword"
className="tw-mb-1.5 tw-block tw-w-full tw-rounded tw-border tw-border-main75 tw-bg-transparent tw-p-2.5 tw-text-black tw-outline-main tw-transition-all"
className="tailwindui"
value={changePasswordForm.newPassword}
onChange={handleChange}
showPassword={showPassword}
Expand All @@ -139,7 +139,7 @@ const ChangePassword = ({ onSubmit, onFinished, withCurrentPassword, centerButto
<label htmlFor="verifyPassword">Confirmez le nouveau mot de passe</label>
<PasswordInput
value={changePasswordForm.verifyPassword}
className="tw-mb-1.5 tw-block tw-w-full tw-rounded tw-border tw-border-main75 tw-bg-transparent tw-p-2.5 tw-text-black tw-outline-main tw-transition-all"
className="tailwindui"
name="verifyPassword"
id="verifyPassword"
onChange={handleChange}
Expand Down
10 changes: 0 additions & 10 deletions dashboard/src/components/createWrapper.js

This file was deleted.

13 changes: 12 additions & 1 deletion dashboard/src/scenes/auth/reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,30 @@ const Reset = () => {
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const token = searchParams.get('token');
const newUser = searchParams.get('newUser') === 'true';
const [name, setName] = useState('');

if (!token) return <Redirect to="/" />;
if (redirect) return <Redirect to="/" />;

return (
<div className="tw-mx-10 tw-my-20 tw-w-full tw-max-w-lg tw-overflow-y-auto tw-overflow-x-hidden tw-rounded-lg tw-bg-white tw-px-7 tw-pt-10 tw-pb-2 tw-text-black tw-shadow-[0_0_20px_0_rgba(0,0,0,0.2)]">
<h1 className="tw-mb-6 tw-text-center tw-text-3xl tw-font-bold">Modifiez votre mot de passe</h1>
<h1 className="tw-mb-6 tw-text-center tw-text-3xl tw-font-bold">
{newUser ? "Choisissez un nom d'utilisateur et un mot de passe" : 'Modifiez votre mot de passe'}
</h1>
{!!newUser && (
<div className="tw-mb-4 tw-flex tw-flex-col tw-py-2">
<label htmlFor="email">Nom d'utilisateur</label>
<input className="tailwindui" name="name" id="name" type="search" value={name} onChange={(e) => setName(e.target.value)} />
</div>
)}
<ChangePassword
onSubmit={({ newPassword }) => {
return API.post({
path: '/user/forgot_password_reset',
body: {
token,
name,
password: newPassword,
},
});
Expand Down
5 changes: 2 additions & 3 deletions dashboard/src/scenes/place/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { toast } from 'react-toastify';
import { SmallHeader } from '../../components/header';
import ButtonCustom from '../../components/ButtonCustom';
import Loading from '../../components/loading';
import CreateWrapper from '../../components/createWrapper';
import Table from '../../components/table';
import Search from '../../components/search';
import Page from '../../components/pagination';
Expand Down Expand Up @@ -110,7 +109,7 @@ const Create = () => {
const setPlaces = useSetRecoilState(placesState);

return (
<CreateWrapper style={{ marginBottom: 0 }}>
<div className="tw-flex tw-w-full tw-justify-end">
<ButtonCustom
disabled={!currentTeam}
onClick={() => setOpen(true)}
Expand Down Expand Up @@ -152,7 +151,7 @@ const Create = () => {
</Formik>
</ModalBody>
</Modal>
</CreateWrapper>
</div>
);
};

Expand Down
5 changes: 2 additions & 3 deletions dashboard/src/scenes/team/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';

import { SmallHeader } from '../../components/header';
import ButtonCustom from '../../components/ButtonCustom';
import CreateWrapper from '../../components/createWrapper';
import Table from '../../components/table';
import NightSessionModale from '../../components/NightSessionModale';
import { currentTeamState, organisationState, teamsState, userState } from '../../recoil/auth';
Expand Down Expand Up @@ -99,7 +98,7 @@ const Create = () => {
const onboardingForTeams = !teams.length;

return (
<CreateWrapper>
<div className="tw-mb-10 tw-flex tw-w-full tw-justify-end">
<ButtonCustom color="primary" onClick={() => setOpen(true)} title="Créer une nouvelle équipe" padding="12px 24px" />
<Modal isOpen={open} toggle={() => setOpen(false)} size="lg" backdrop="static">
<ModalHeader close={onboardingForTeams ? <></> : null} toggle={() => setOpen(false)}>
Expand Down Expand Up @@ -201,7 +200,7 @@ const Create = () => {
</ModalBody>
</Modal>
<OnboardingEndModal open={onboardingEndModalOpen} setOpen={setOnboardingEndModalOpen} />
</CreateWrapper>
</div>
);
};

Expand Down
Loading

0 comments on commit 1a56eb0

Please sign in to comment.