From cf408cfafd019a6e8eb0468055e5498ae0fda726 Mon Sep 17 00:00:00 2001 From: Vinicius Gabriel Machado <vgm18@inf.ufpr.br> Date: Mon, 5 Jul 2021 21:58:55 -0300 Subject: [PATCH 1/3] Fixing password recovery --- src/App.js | 3 + .../PasswordRecoveryComponents/Default.js | 2 +- src/Pages/ChangePasswordPage.js | 132 ++++++++++++++++++ src/Pages/PasswordRecoveryPage.js | 4 +- 4 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 src/Pages/ChangePasswordPage.js diff --git a/src/App.js b/src/App.js index b5a80b2f..b87c9ad2 100644 --- a/src/App.js +++ b/src/App.js @@ -95,6 +95,8 @@ import BlockedUser from "./Admin/Pages/Pages/SubPages/BlockedUsers"; import AppBarAdmin from './Admin/Components/Components/AppBar' import createBrowserHistory from 'history/createBrowserHistory' +import ChangePasswordPage from "./Pages/ChangePasswordPage.js"; + export default function App() { // eslint-disable-next-line const { state, dispatch } = useContext(Store); @@ -210,6 +212,7 @@ export default function App() { <Route path="/participando-da-rede" component={TabNetPart} /> <Route path="/gerenciando-conta" component={TabManageAc} /> <Route path="/plataforma-mec" component={TabPlataformaMEC} /> + <Route path="/recuperar-senha/alterar-senha" component={ChangePasswordPage} /> <Route path="/recuperar-senha" component={PasswordRecoveryPage} /> <Route path="/usuario-publico/:userId" component={PublicUserPage} /> <Route diff --git a/src/Components/PasswordRecoveryComponents/Default.js b/src/Components/PasswordRecoveryComponents/Default.js index ddbb4f43..e7a45389 100644 --- a/src/Components/PasswordRecoveryComponents/Default.js +++ b/src/Components/PasswordRecoveryComponents/Default.js @@ -6,7 +6,7 @@ export default function Default (props) { return ( <div style={{overflow:"hidden", display:"inline-block"}}> <h2 style={{fontSize:"32px", fontWeight:"200", marginBottom:"20px"}}>Vamos encontrar a sua conta</h2> - <form onSubmit={(e) => props.onSubmit(e)}> + <form onSubmit={(e) => { e.preventDefault(); props.onSubmit(e); }}> <FormInput inputType={"text"} name={"email"} diff --git a/src/Pages/ChangePasswordPage.js b/src/Pages/ChangePasswordPage.js new file mode 100644 index 00000000..a2d3a689 --- /dev/null +++ b/src/Pages/ChangePasswordPage.js @@ -0,0 +1,132 @@ +import React, {useState} from "react"; +import {BackgroundDiv} from '../Components/TabPanels/StyledComponents.js' +import Paper from '@material-ui/core/Paper'; +import styled from 'styled-components' +import FormInput from "../Components/FormInput.js" +import {CompletarCadastroButton} from '../Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' +import ValidateUserInput from '../Components/HelperFunctions/FormValidationFunction.js' +import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' +import {putRequest} from '../Components/HelperFunctions/getAxiosConfig' + +export default function ChangePasswordPage (props) { + + const [formPassword, setPassword] = useState( + { + key : false, + value : "" + } + ) + + const [formPasswordConfirmation, setPasswordConfirmation] = useState( + { + key : false, + value : "" + } + ) + + const handleChange = (e, field) => { + const userInput = e.target.value; + const flag = ValidateUserInput('password', userInput); + + if (field === "password") { + setPassword({...formPassword, + key : flag, + value : userInput + }) + } else { + setPasswordConfirmation({...formPasswordConfirmation, + key : flag, + value : userInput + }) + } + + } + + const onSubmit = () => { + const flag = ValidateUserInput('confirmation', formPassword.value, formPasswordConfirmation.value); + + if (flag === true) { + //throw error to user - ### arrumar + console.log("senha não bate"); + } else { + //console.log("senha bate"); + if (!formPassword.key && !formPasswordConfirmation.key) { + console.log("senha bate"); + + const urlParams = new URLSearchParams(window.location.search); + const clientId = urlParams.get("client_id"); + const config = urlParams.get("config"); + const expiry = urlParams.get("expiry"); + const resetPassword = urlParams.get("reset_password"); + const token = urlParams.get("token"); + const uid = urlParams.get("uid"); + + const url = `/auth/password` + + const payload = { + "password" : formPassword.value, + "password_confirmation" : formPasswordConfirmation.value, + "client" : clientId, + "config" : config, + "expiry" : expiry, + "reset_password" : resetPassword, + "access-token" : token, + "uid" : uid + } + putRequest(url, payload, () => { window.location.href="/" }, (error) => {console.log(error)}) // ### arrumar + } + } + } + + return ( + <BackgroundDiv> + <div> + <CustomizedBreadcrumbs + values={["Recuperar senha", "Alterar senha"]} + /> + </div> + <div style={{justifyContent:"center", textAlign:"center", maxWidth:"600px", margin:"auto"}}> + <Paper elevation={3}> + <CardDiv> + <div style={{overflow:"hidden", display:"inline-block"}}> + <h2 style={{fontSize:"32px", fontWeight:"200", marginBottom:"20px"}}>Confirme a nova senha</h2> + <form onSubmit={(e) => { e.preventDefault(); onSubmit(e); }}> + <FormInput + inputType={"password"} + name={"senha"} + value={formPassword.value} + placeholder={"Senha"} + handleChange={e => handleChange(e, 'password')} + required={true} + error = {formPassword.key} + help = {formPassword.key ? (formPassword.value.length === 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mÃnimo 8 caracteres.") : ""} + /> + <br/> + <FormInput + inputType={"password"} + name={"confirme a senha"} + value={formPasswordConfirmation.value} + placeholder={"Confirme a senha"} + handleChange={e => handleChange(e, 'confirmation')} + required={true} + error = {formPasswordConfirmation.key} + help = {formPasswordConfirmation.key ? (formPasswordConfirmation.value.length === 0 ? "Faltou confirmar sua senha." : "A confirmação precisa ter no mÃnimo 8 caracteres e ser igual a senha.") : ""} + /> + <div style={{display:"flex", justifyContent:"center"}}> + <CompletarCadastroButton type="submit" >ATUALIZAR SENHA</CompletarCadastroButton> + </div> + </form> + </div> + </CardDiv> + </Paper> + </div> + </BackgroundDiv> + ) +} + +const CardDiv = styled.div` + background-color : #fff; + box-shadow : 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); + padding : 30px 60px; + margin : 50px 0; +` \ No newline at end of file diff --git a/src/Pages/PasswordRecoveryPage.js b/src/Pages/PasswordRecoveryPage.js index 010a164b..6093d37d 100644 --- a/src/Pages/PasswordRecoveryPage.js +++ b/src/Pages/PasswordRecoveryPage.js @@ -48,7 +48,7 @@ export default function PasswordRecoveryPage (props) { const payload = { "email" : formEmail.value, - "redirect_url" : "https://plataformaintegrada.mec.gov.br/recuperar-senha#/alterar-senha" + "redirect_url" : "http://localhost:4000/recuperar-senha/alterar-senha" // ### arrumar "https://plataformaintegrada.mec.gov.br/recuperar-senha/alterar-senha" } postRequest(url, payload, handleSuccessfulSubmit, (error) => {console.log(error)}) @@ -77,7 +77,7 @@ export default function PasswordRecoveryPage (props) { return ( <> <BackgroundDiv> - <div style={{minWidth:"1170px"}}> + <div> <CustomizedBreadcrumbs values={["Recuperar senha"]} /> -- GitLab From fcacdcbcf10700469b6ac1c5b8feaf9ea22ff671 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Tue, 6 Jul 2021 10:26:09 -0300 Subject: [PATCH 2/3] Finished recover pass --- src/Pages/ChangePasswordPage.js | 347 +++++++++++++++++++++++------- src/Pages/PasswordRecoveryPage.js | 2 +- 2 files changed, 276 insertions(+), 73 deletions(-) diff --git a/src/Pages/ChangePasswordPage.js b/src/Pages/ChangePasswordPage.js index a2d3a689..2ffab35e 100644 --- a/src/Pages/ChangePasswordPage.js +++ b/src/Pages/ChangePasswordPage.js @@ -1,42 +1,66 @@ -import React, {useState} from "react"; -import {BackgroundDiv} from '../Components/TabPanels/StyledComponents.js' -import Paper from '@material-ui/core/Paper'; +import React, { useState } from "react"; +import { BackgroundDiv } from '../Components/TabPanels/StyledComponents.js' +import Paper from '@material-ui/core/Paper' import styled from 'styled-components' import FormInput from "../Components/FormInput.js" -import {CompletarCadastroButton} from '../Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' +import { CompletarCadastroButton } from '../Components/TabPanels/UserPageTabs/PanelSolicitarContaProfessor.js' import ValidateUserInput from '../Components/HelperFunctions/FormValidationFunction.js' import CustomizedBreadcrumbs from '../Components/TabPanels/Breadcrumbs.js' -import {putRequest} from '../Components/HelperFunctions/getAxiosConfig' +import { putRequest } from '../Components/HelperFunctions/getAxiosConfig' +import Snackbar from '@material-ui/core/Snackbar' +import MuiAlert from '@material-ui/lab/Alert' +import Grid from '@material-ui/core/Grid' +import IconButton from '@material-ui/core/IconButton' +import VisibilityIcon from '@material-ui/icons/Visibility' +import VisibilityOffIcon from '@material-ui/icons/VisibilityOff' -export default function ChangePasswordPage (props) { +function Alert(props) { + return <MuiAlert elevation={6} variant="filled" {...props} />; +} + +export default function ChangePasswordPage(props) { + + const [error, setError] = useState(false) + const [success, setSuccess] = useState(false) + const [time, setTime] = useState(5) const [formPassword, setPassword] = useState( { - key : false, - value : "" + key: false, + hidePass: true, + value: "" } ) const [formPasswordConfirmation, setPasswordConfirmation] = useState( { - key : false, - value : "" + key: false, + hidePass: true, + value: "" } ) + const [snackInfo, setSnackInfo] = useState({ + open: false, + text: "", + severity: "", + }); + const handleChange = (e, field) => { const userInput = e.target.value; const flag = ValidateUserInput('password', userInput); if (field === "password") { - setPassword({...formPassword, - key : flag, - value : userInput + setPassword({ + ...formPassword, + key: flag, + value: userInput }) } else { - setPasswordConfirmation({...formPasswordConfirmation, - key : flag, - value : userInput + setPasswordConfirmation({ + ...formPasswordConfirmation, + key: flag, + value: userInput }) } @@ -46,8 +70,12 @@ export default function ChangePasswordPage (props) { const flag = ValidateUserInput('confirmation', formPassword.value, formPasswordConfirmation.value); if (flag === true) { - //throw error to user - ### arrumar - console.log("senha não bate"); + const snackInfo = { + open: true, + text: "As senhas inseridas não são iguais", + severity: "warning", + } + handleSnackInfo(snackInfo) } else { //console.log("senha bate"); if (!formPassword.key && !formPasswordConfirmation.key) { @@ -64,69 +92,244 @@ export default function ChangePasswordPage (props) { const url = `/auth/password` const payload = { - "password" : formPassword.value, - "password_confirmation" : formPasswordConfirmation.value, - "client" : clientId, - "config" : config, - "expiry" : expiry, - "reset_password" : resetPassword, - "access-token" : token, - "uid" : uid + "password": formPassword.value, + "password_confirmation": formPasswordConfirmation.value, + "client": clientId, + "config": config, + "expiry": expiry, + "reset_password": resetPassword, + "access-token": token, + "uid": uid } - putRequest(url, payload, () => { window.location.href="/" }, (error) => {console.log(error)}) // ### arrumar + + putRequest( + url, + payload, + () => { + setSuccess(true) + let count = 0; + const snackInfo = { + open: true, + text: "Sua senha foi atualizada!", + severity: "success", + } + handleSnackInfo(snackInfo) + const intervalId = setInterval(() => { + count++; + setTime((previousTime) => previousTime - 1) + if (count === 5) { + window.location.href = "/" + clearInterval(intervalId) + } + }, 1000) + }, + (error) => { + setError(true) + let count = 0; + const snackInfo = { + open: true, + text: "Houve um erro durante a requisição de troca de senha", + severity: "error", + } + handleSnackInfo(snackInfo) + const intervalId = setInterval(() => { + count++; + setTime((previousTime) => previousTime - 1) + if (count === 5) { + window.location.href = "/" + clearInterval(intervalId) + } + }, 1000) + } + ) } } } - return ( - <BackgroundDiv> - <div> - <CustomizedBreadcrumbs - values={["Recuperar senha", "Alterar senha"]} - /> - </div> - <div style={{justifyContent:"center", textAlign:"center", maxWidth:"600px", margin:"auto"}}> - <Paper elevation={3}> - <CardDiv> - <div style={{overflow:"hidden", display:"inline-block"}}> - <h2 style={{fontSize:"32px", fontWeight:"200", marginBottom:"20px"}}>Confirme a nova senha</h2> - <form onSubmit={(e) => { e.preventDefault(); onSubmit(e); }}> - <FormInput - inputType={"password"} - name={"senha"} - value={formPassword.value} - placeholder={"Senha"} - handleChange={e => handleChange(e, 'password')} - required={true} - error = {formPassword.key} - help = {formPassword.key ? (formPassword.value.length === 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mÃnimo 8 caracteres.") : ""} - /> - <br/> - <FormInput - inputType={"password"} - name={"confirme a senha"} - value={formPasswordConfirmation.value} - placeholder={"Confirme a senha"} - handleChange={e => handleChange(e, 'confirmation')} - required={true} - error = {formPasswordConfirmation.key} - help = {formPasswordConfirmation.key ? (formPasswordConfirmation.value.length === 0 ? "Faltou confirmar sua senha." : "A confirmação precisa ter no mÃnimo 8 caracteres e ser igual a senha.") : ""} - /> - <div style={{display:"flex", justifyContent:"center"}}> - <CompletarCadastroButton type="submit" >ATUALIZAR SENHA</CompletarCadastroButton> - </div> - </form> - </div> - </CardDiv> - </Paper> - </div> - </BackgroundDiv> - ) + const handleSnackInfo = (info) => { + setSnackInfo({ ...info }) + } + + const handleCloseSnack = () => { + const snackInfo = { + open: false, + text: "", + severity: "", + } + handleSnackInfo(snackInfo) + } + + const handleStateHideFormPass = () => { + setPassword({ + ...formPassword, + hidePass: !formPassword.hidePass + }) + } + + const handleStateHideConfFormPass = () => { + setPasswordConfirmation({ + ...formPasswordConfirmation, + hidePass: !formPasswordConfirmation.hidePass + }) + } + + if (error) + return ( + <BackgroundDiv> + <Snackbar + open={snackInfo.open} + autoHideDuration={6000} + onClose={handleCloseSnack} + anchorOrigin={{ vertical: 'top', horizontal: 'right' }} + > + <Alert onClose={handleCloseSnack} severity={snackInfo.severity}> + {snackInfo.text} + </Alert> + </Snackbar> + <div> + <CustomizedBreadcrumbs + values={["Recuperar senha", "Alterar senha"]} + /> + </div> + <div style={{ justifyContent: "center", textAlign: "center", maxWidth: "600px", margin: "auto" }}> + <Paper elevation={3}> + <CardDiv> + <div style={{ overflow: "hidden", display: "inline-block" }}> + <h2 style={{ fontSize: "32px", fontWeight: "200", marginBottom: "20px", lineHeight: '35px' }}> + Ocorreu um erro. Por favor, tente novamente mais tarde. Você será redireciona para a home em... <StyledTimer>{time}</StyledTimer> + </h2> + </div> + </CardDiv> + </Paper> + </div> + </BackgroundDiv> + ) + else if (success) + return ( + <BackgroundDiv> + <Snackbar + open={snackInfo.open} + autoHideDuration={6000} + onClose={handleCloseSnack} + anchorOrigin={{ vertical: 'top', horizontal: 'right' }} + > + <Alert onClose={handleCloseSnack} severity={snackInfo.severity}> + {snackInfo.text} + </Alert> + </Snackbar> + <div> + <CustomizedBreadcrumbs + values={["Recuperar senha", "Alterar senha"]} + /> + </div> + <div style={{ justifyContent: "center", textAlign: "center", maxWidth: "600px", margin: "auto" }}> + <Paper elevation={3}> + <CardDiv> + <div style={{ overflow: "hidden", display: "inline-block" }}> + <h2 style={{ fontSize: "32px", fontWeight: "200", marginBottom: "20px", lineHeight: '35px' }}> + Sua senha foi alterada com sucesso. Você será redireciona para a home em... <StyledTimer>{time}</StyledTimer> + </h2> + </div> + </CardDiv> + </Paper> + </div> + </BackgroundDiv> + ) + else + return ( + <BackgroundDiv> + <Snackbar + open={snackInfo.open} + autoHideDuration={6000} + onClose={handleCloseSnack} + anchorOrigin={{ vertical: 'top', horizontal: 'right' }} + > + <Alert onClose={handleCloseSnack} severity={snackInfo.severity}> + {snackInfo.text} + </Alert> + </Snackbar> + <div> + <CustomizedBreadcrumbs + values={["Recuperar senha", "Alterar senha"]} + /> + </div> + <div style={{ justifyContent: "center", textAlign: "center", maxWidth: "600px", margin: "auto" }}> + <Paper elevation={3}> + <CardDiv> + <div style={{ overflow: "hidden", display: "inline-block" }}> + <h2 style={{ fontSize: "32px", fontWeight: "200", marginBottom: "20px" }}>Confirme a nova senha</h2> + <form onSubmit={(e) => { e.preventDefault(); onSubmit(e); }}> + <Grid container direction='row' alignItems='center' spacing={1}> + <Grid item xs={10}> + <FormInput + inputType={formPassword.hidePass ? "password" : ""} + name={"senha"} + value={formPassword.value} + placeholder={"Senha"} + handleChange={e => handleChange(e, 'password')} + required={true} + error={formPassword.key} + help={formPassword.key ? (formPassword.value.length === 0 ? "Faltou digitar sua senha." : "A senha precisa ter no mÃnimo 8 caracteres.") : ""} + /> + </Grid> + <Grid item xs={2}> + { + formPassword.hidePass ? + <IconButton onClick={handleStateHideFormPass}> + <VisibilityIcon /> + </IconButton> + : + <IconButton onClick={handleStateHideFormPass}> + <VisibilityOffIcon /> + </IconButton> + } + </Grid> + </Grid> + <br /> + <Grid container direction='row' alignItems='center' spacing={1}> + <Grid item xs={10}> + <FormInput + inputType={formPasswordConfirmation.hidePass ? "password" : ""} + name={"confirme a senha"} + value={formPasswordConfirmation.value} + placeholder={"Confirme a senha"} + handleChange={e => handleChange(e, 'confirmation')} + required={true} + error={formPasswordConfirmation.key} + help={formPasswordConfirmation.key ? (formPasswordConfirmation.value.length === 0 ? "Faltou confirmar sua senha." : "A confirmação precisa ter no mÃnimo 8 caracteres e ser igual a senha.") : ""} + /> + </Grid> + <Grid item xs={2}> + { + formPasswordConfirmation.hidePass ? + <IconButton onClick={handleStateHideConfFormPass}> + <VisibilityIcon /> + </IconButton> + : + <IconButton onClick={handleStateHideConfFormPass}> + <VisibilityOffIcon /> + </IconButton> + } + </Grid> + </Grid> + <div style={{ display: "flex", justifyContent: "center" }}> + <CompletarCadastroButton type="submit" >ATUALIZAR SENHA</CompletarCadastroButton> + </div> + </form> + </div> + </CardDiv> + </Paper> + </div> + </BackgroundDiv> + ) } const CardDiv = styled.div` background-color : #fff; box-shadow : 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24); - padding : 30px 60px; + padding : 20px 30px; margin : 50px 0; +` +const StyledTimer = styled.span` + color: #00bcd4; ` \ No newline at end of file diff --git a/src/Pages/PasswordRecoveryPage.js b/src/Pages/PasswordRecoveryPage.js index 6093d37d..4a6b2572 100644 --- a/src/Pages/PasswordRecoveryPage.js +++ b/src/Pages/PasswordRecoveryPage.js @@ -42,7 +42,7 @@ export default function PasswordRecoveryPage (props) { handleChangeSwitch((data.success ? "success" : "error")) } const onSubmit = (e) => { - e.stopPropagation() + e.preventDefault() const url = `/auth/password` -- GitLab From 705bae847408469b2ab1bfd4152bfc3b15da53d6 Mon Sep 17 00:00:00 2001 From: Luis Felipe Risch <lfr20@inf.ufpr.br> Date: Tue, 6 Jul 2021 10:50:23 -0300 Subject: [PATCH 3/3] fixed "gramatica" errors --- src/Pages/ChangePasswordPage.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pages/ChangePasswordPage.js b/src/Pages/ChangePasswordPage.js index 2ffab35e..cf552c07 100644 --- a/src/Pages/ChangePasswordPage.js +++ b/src/Pages/ChangePasswordPage.js @@ -196,7 +196,7 @@ export default function ChangePasswordPage(props) { <CardDiv> <div style={{ overflow: "hidden", display: "inline-block" }}> <h2 style={{ fontSize: "32px", fontWeight: "200", marginBottom: "20px", lineHeight: '35px' }}> - Ocorreu um erro. Por favor, tente novamente mais tarde. Você será redireciona para a home em... <StyledTimer>{time}</StyledTimer> + Ocorreu um erro. Por favor, tente novamente mais tarde. Você será redirecionado para a home em... <StyledTimer>{time}</StyledTimer> </h2> </div> </CardDiv> @@ -227,7 +227,7 @@ export default function ChangePasswordPage(props) { <CardDiv> <div style={{ overflow: "hidden", display: "inline-block" }}> <h2 style={{ fontSize: "32px", fontWeight: "200", marginBottom: "20px", lineHeight: '35px' }}> - Sua senha foi alterada com sucesso. Você será redireciona para a home em... <StyledTimer>{time}</StyledTimer> + Sua senha foi alterada com sucesso. Você será redirecionado para a home em... <StyledTimer>{time}</StyledTimer> </h2> </div> </CardDiv> @@ -296,7 +296,7 @@ export default function ChangePasswordPage(props) { handleChange={e => handleChange(e, 'confirmation')} required={true} error={formPasswordConfirmation.key} - help={formPasswordConfirmation.key ? (formPasswordConfirmation.value.length === 0 ? "Faltou confirmar sua senha." : "A confirmação precisa ter no mÃnimo 8 caracteres e ser igual a senha.") : ""} + help={formPasswordConfirmation.key ? (formPasswordConfirmation.value.length === 0 ? "Faltou confirmar sua senha." : "A confirmação precisa ser igual a senha.") : ""} /> </Grid> <Grid item xs={2}> -- GitLab