Skip to content

Commit 7064189

Browse files
author
Krzysiek_QM
committed
v.3.4.0
- added new user field to keep email address - implemented password reset for user
1 parent 343da73 commit 7064189

39 files changed

Lines changed: 1056 additions & 57 deletions

build.gradle

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = 'pl.databucket'
9-
version = '3.3.3'
9+
version = '3.4.0'
1010
targetCompatibility = 8
1111
sourceCompatibility = 8
1212

@@ -34,6 +34,7 @@ dependencies {
3434
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.5.7'
3535
implementation 'org.springframework.boot:spring-boot-starter-security:2.5.7'
3636
implementation 'org.springframework.boot:spring-boot-starter-actuator:2.5.7'
37+
implementation 'org.springframework.boot:spring-boot-starter-mail:2.5.7'
3738
implementation 'org.springframework:spring-tx:5.3.9'
3839
implementation 'org.postgresql:postgresql:42.2.23.jre7'
3940
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.1'
@@ -50,17 +51,17 @@ dependencies {
5051
compileOnly 'org.projectlombok:lombok:1.18.20'
5152
annotationProcessor 'org.projectlombok:lombok'
5253

53-
testImplementation('org.springframework.boot:spring-boot-starter-test:2.5.4') {exclude group: 'junit', module: 'junit'}
54+
// testImplementation('org.springframework.boot:spring-boot-starter-test:2.5.4') {exclude group: 'junit', module: 'junit'}
5455

5556
// JUnit dependencies
56-
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
57-
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.7.2'
58-
testRuntimeOnly 'org.junit.platform:junit-platform-commons:1.7.2'
57+
// testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
58+
// testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.7.2'
59+
// testRuntimeOnly 'org.junit.platform:junit-platform-commons:1.7.2'
5960

6061
// Spock - Mandatory dependencies
61-
testImplementation 'org.codehaus.groovy:groovy-all:3.0.8'
62-
testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0'
63-
testImplementation 'org.spockframework:spock-spring:2.0-groovy-3.0'
62+
// testImplementation 'org.codehaus.groovy:groovy-all:3.0.8'
63+
// testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0'
64+
// testImplementation 'org.spockframework:spock-spring:2.0-groovy-3.0'
6465
}
6566

6667
test {

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"homepage": ".",
33
"name": "databucket",
4-
"version": "3.3.3",
4+
"version": "3.4.0",
55
"private": true,
66
"dependencies": {
77
"@material-ui/core": "4.12.4",

frontend/src/components/dialogs/InfoDialog.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default function InfoDialog() {
6262
>
6363
<img style={{marginLeft: '100px', marginTop: '20px'}} src={DatabucketLogo} alt='' width='399' height='65'/>
6464
<div style={{margin: '20px'}}>
65-
<Typography color='secondary'>Version: <b>3.3.3</b></Typography>
65+
<Typography color='secondary'>Version: <b>3.4.0</b></Typography>
6666
<Link target='_blank' href='https://www.databucket.pl' color="primary">www.databucket.pl</Link><br/>
6767
<Link target='_blank' href='https://github.com/databucket/databucket-server' color="textSecondary">Source code</Link><br/>
6868
<Link target='_blank' href='https://github.com/databucket/databucket-server/wiki' color="textSecondary">Documentation</Link><br/>

frontend/src/components/login/ChangePasswordPage.jsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {fetchHelper, handleErrors} from "../../utils/FetchHelper";
1313
import {Redirect} from "react-router-dom";
1414
import {getProjectDataPath} from "../../route/AppRouter";
1515
import {getBaseUrl} from "../../utils/UrlBuilder";
16+
import Link from "@material-ui/core/Link";
1617

1718
const initialState = {
1819
password: "",
@@ -21,6 +22,7 @@ const initialState = {
2122
};
2223

2324
export default function ChangePasswordPage() {
25+
const [back, setBack] = useState(false);
2426
const [{password, newPassword, newPasswordConfirmation}, setState] = useState(initialState);
2527
const [messageBox, setMessageBox] = useState({open: false, severity: 'error', title: '', message: ''});
2628
const [redirect, setRedirect] = useState(false);
@@ -82,6 +84,9 @@ export default function ChangePasswordPage() {
8284
getPasswordStrength(value);
8385
};
8486

87+
if (back)
88+
return (<Redirect to="/login"/>);
89+
else
8590
return (
8691
redirect === true ? (
8792
<Redirect to={getProjectDataPath()}/>
@@ -91,6 +96,16 @@ export default function ChangePasswordPage() {
9196
<Typography className="Title" variant="h5">
9297
Change password
9398
</Typography>
99+
{/*// additional control to block setting default password by Chrome*/}
100+
<FormControl disabled={true} style={{height: '0px', width: '0px'}}>
101+
<Input
102+
name="pass"
103+
type='password'
104+
value={null}
105+
disabled={true}
106+
// visible={false}
107+
/>
108+
</FormControl>
94109
<FormControl className="LoginInputText">
95110
<InputLabel htmlFor="standard-adornment-password">Current password</InputLabel>
96111
<Input
@@ -120,6 +135,7 @@ export default function ChangePasswordPage() {
120135
</FormControl>
121136
<div className="Button">
122137
<Button
138+
fullWidth={true}
123139
variant="contained"
124140
color="primary"
125141
disabled={
@@ -132,6 +148,17 @@ export default function ChangePasswordPage() {
132148
Submit
133149
</Button>
134150
</div>
151+
<div className="BackLink">
152+
<Link
153+
component="button"
154+
color="inherit"
155+
onClick={() => {
156+
setBack(true);
157+
}}
158+
>
159+
Back
160+
</Link>
161+
</div>
135162
</Paper>
136163
<MessageBox
137164
config={messageBox}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React, {useEffect, useState} from "react";
2+
import "./SignUpPage.css";
3+
import Logo from "../../images/databucket-logo.png";
4+
import {Paper} from "@material-ui/core";
5+
import Typography from "@material-ui/core/Typography";
6+
import {MessageBox} from "../utils/MessageBox";
7+
import {Redirect, useParams} from "react-router-dom";
8+
import {getConfirmationUrl} from "../../utils/UrlBuilder";
9+
import {handleErrors} from "../../utils/FetchHelper";
10+
import {getGetOptions} from "../../utils/MaterialTableHelper";
11+
12+
export default function ConfirmationPage() {
13+
14+
const inputParams = useParams();
15+
const [messageBox, setMessageBox] = useState({open: false, severity: 'error', title: '', message: ''});
16+
const [done, setDone] = useState(false);
17+
const [redirect, setRedirect] = useState(false);
18+
19+
useEffect(() => {
20+
let resultOk = true;
21+
fetch(getConfirmationUrl(inputParams[0]), getGetOptions())
22+
.then(handleErrors)
23+
.catch(error => {
24+
setMessageBox({open: true, severity: 'error', title: 'Error', message: error});
25+
resultOk = false;
26+
})
27+
.then(response => {
28+
if (resultOk) {
29+
setDone(true);
30+
setTimeout(() => {
31+
setRedirect(true);
32+
}, 6000)
33+
}
34+
});
35+
}, [inputParams]);
36+
37+
if (redirect)
38+
return (<Redirect to="/login"/>);
39+
else
40+
return (
41+
<div className="ContainerClass">
42+
{<img src={Logo} alt=''/>}
43+
<Paper className="PaperClass" elevation={3}>
44+
<Typography className="Title" variant="h5">
45+
Confirmation
46+
</Typography>
47+
<div style={{height: '100px'}}/>
48+
<Typography className="Description">
49+
{!done ? "Processing..." : "Check your email inbox."}
50+
</Typography>
51+
</Paper>
52+
<MessageBox
53+
config={messageBox}
54+
onClose={() => setMessageBox({...messageBox, open: false})}
55+
/>
56+
</div>
57+
);
58+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
.ContainerClass {
2+
display: flex;
3+
flex-direction: column;
4+
align-items: center;
5+
justify-content: center;
6+
padding: 10vh;
7+
}
8+
9+
.PaperClass {
10+
margin-top: 40px;
11+
display: flex;
12+
min-width: 370px;
13+
max-width: 370px;
14+
min-height: 500px;
15+
max-height: 700px;
16+
flex-direction: column;
17+
align-items: center;
18+
justify-content: flex-start;
19+
padding: 20px 0px 0px 0px;
20+
}
21+
22+
.Title {
23+
padding: 30px;
24+
}
25+
26+
.Description {
27+
padding: 30px;
28+
}
29+
30+
.TitleGrid {
31+
padding: 30px;
32+
width: 100%;
33+
/*overflow: auto;*/
34+
}
35+
36+
.Button {
37+
width: 100%;
38+
margin-top: 10px;
39+
padding: 20px;
40+
}
41+
42+
.EmailInputText {
43+
height: 70px;
44+
width: 85%;
45+
overflow: auto;
46+
}
47+
48+
.BackLink {
49+
width: 100%;
50+
margin-top: 50px;
51+
margin-left: 40px;
52+
margin-bottom: 10px;
53+
display: flex;
54+
flex-direction: column;
55+
align-items: flex-start;
56+
justify-content: flex-start;
57+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import React, {useState} from "react";
2+
import "./ForgotPasswordPage.css";
3+
import Button from "@material-ui/core/Button";
4+
import Logo from "../../images/databucket-logo.png";
5+
import {Input, InputLabel, Paper} from "@material-ui/core";
6+
import Typography from "@material-ui/core/Typography";
7+
import FormControl from "@material-ui/core/FormControl";
8+
import {MessageBox} from "../utils/MessageBox";
9+
import Link from "@material-ui/core/Link";
10+
import {Redirect} from "react-router-dom";
11+
import {getBaseUrl, getContextPath} from "../../utils/UrlBuilder";
12+
import {handleLoginErrors} from "../../utils/FetchHelper";
13+
import {validateEmail} from "../../utils/Misc";
14+
15+
export default function ForgotPasswordPage() {
16+
17+
const [back, setBack] = useState(false);
18+
const [email, setEmail] = useState("");
19+
const [messageBox, setMessageBox] = useState({open: false, severity: 'error', title: '', message: ''});
20+
21+
const onChange = e => {
22+
setEmail(e.target.value);
23+
};
24+
25+
const handleReset = () => {
26+
fetch(getBaseUrl('public/forgot-password'), {
27+
method: 'POST',
28+
body: JSON.stringify({email: email, url: window.location.origin + getContextPath() + "/confirmation/forgot-password/"}),
29+
headers: {'Content-Type': 'application/json'}
30+
})
31+
.then(handleLoginErrors)
32+
.then(response => {
33+
setMessageBox({open: true, severity: 'info', title: 'Send confirmation email', message: null});
34+
}).catch(error => {
35+
setMessageBox({open: true, severity: 'error', title: 'Sending confirmation password failed', message: error});
36+
}
37+
);
38+
}
39+
40+
const handleKeypress = e => {
41+
if (e.key === 'Enter')
42+
handleReset();
43+
};
44+
45+
if (back)
46+
return (<Redirect to="/login"/>);
47+
else
48+
return (
49+
<div className="ContainerClass">
50+
{<img src={Logo} alt=''/>}
51+
<Paper className="PaperClass" elevation={3}>
52+
<Typography className="Title" variant="h5">
53+
Forgot your password?
54+
</Typography>
55+
<Typography className="Description">
56+
Please enter the email address for your account.
57+
A verification link will be sent to you.
58+
Once you have received the verification link,
59+
you will be able to choose a new password for your account.
60+
</Typography>
61+
<FormControl className="EmailInputText">
62+
<InputLabel htmlFor="standard-adornment-email">Email</InputLabel>
63+
<Input
64+
id="standard-adornment-email"
65+
name="email"
66+
type='email'
67+
value={email}
68+
onChange={onChange}
69+
onKeyPress={(event) => handleKeypress(event)}
70+
/>
71+
</FormControl>
72+
<div className="Button">
73+
<Button
74+
fullWidth={true}
75+
variant="contained"
76+
color="primary"
77+
size={'large'}
78+
disabled={!(validateEmail(email))}
79+
onClick={() => {
80+
handleReset();
81+
}}
82+
>
83+
Submit
84+
</Button>
85+
</div>
86+
<div className="BackLink">
87+
<Link
88+
component="button"
89+
color="inherit"
90+
onClick={() => {
91+
setBack(true);
92+
}}
93+
>
94+
Back
95+
</Link>
96+
</div>
97+
</Paper>
98+
<MessageBox
99+
config={messageBox}
100+
onClose={() => setMessageBox({...messageBox, open: false})}
101+
/>
102+
</div>
103+
);
104+
}

0 commit comments

Comments
 (0)