diff --git a/server/extensions.py b/server/extensions.py
index 1ef41774..cbf82369 100644
--- a/server/extensions.py
+++ b/server/extensions.py
@@ -35,12 +35,12 @@
Base = declarative_base()
Base.metadata.reflect(engine)
else:
- logging.warning("Testing mode, using local sqlite db.")
+ logging.warning("Testing mode, using local sqlite test db.")
engine = create_engine(
- "sqlite:///" + os.path.join(basedir, "openml.db"),
+ "sqlite:///" + os.path.join(basedir, "openml.test.db"),
echo=False,
)
- Config.SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "openml.db")
+ Config.SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "openml.test.db")
Base = declarative_base()
Base.metadata.reflect(engine)
diff --git a/server/openml.test.db b/server/openml.test.db
new file mode 100644
index 00000000..aa20b071
Binary files /dev/null and b/server/openml.test.db differ
diff --git a/server/public/views.py b/server/public/views.py
index e9e6dd48..50088464 100644
--- a/server/public/views.py
+++ b/server/public/views.py
@@ -22,8 +22,8 @@
CORS(blueprint)
-DO_SEND_EMAIL = strtobool(os.environ.get("SEND_EMAIL", "True"))
-
+def email_enabled():
+ return strtobool(os.getenv("SEND_EMAIL", "True"))
@blueprint.route("/signup", methods=["POST"])
def signupfunc():
@@ -45,7 +45,7 @@ def signupfunc():
user.remember_code = "0000"
user.created_on = "0000"
user.last_login = "0000"
- user.active = "0" if DO_SEND_EMAIL else "1"
+ user.active = "0" if email_enabled() else "1"
user.first_name = register_obj["first_name"]
user.last_name = register_obj["last_name"]
user.company = "0000"
@@ -59,7 +59,7 @@ def signupfunc():
user.password_hash = "0000"
token = secrets.token_hex()
user.update_activation_code(token)
- if DO_SEND_EMAIL:
+ if email_enabled():
confirmation_email(user.email, token)
session.add(user)
session.commit()
@@ -81,7 +81,7 @@ def password():
token = secrets.token_hex()
user.update_forgotten_code(token)
# user.update_forgotten_time(timestamp)
- if DO_SEND_EMAIL:
+ if email_enabled():
forgot_password_email(user.email, token)
session.merge(user)
session.commit()
@@ -100,7 +100,7 @@ def confirmation_token():
return jsonify({"msg": "User confirmation token sent"}), 200
token = secrets.token_hex()
user.update_activation_code(token)
- if DO_SEND_EMAIL:
+ if email_enabled():
confirmation_email(user.email, token)
# updating user groups here
user_group = UserGroups(user_id=user.id, group_id=2)
diff --git a/server/src/client/app/src/pages/auth/APIKey.js b/server/src/client/app/src/pages/auth/APIKey.js
index ac65cdde..e799c7db 100644
--- a/server/src/client/app/src/pages/auth/APIKey.js
+++ b/server/src/client/app/src/pages/auth/APIKey.js
@@ -46,8 +46,8 @@ function APIKey() {
const [apikey, setApikey] = useState('');
const yourConfig = {
headers: {
- Authorization: "Bearer " + localStorage.getItem("token"),
- },
+ Authorization: "Bearer " + localStorage.getItem("token")
+ }
};
useEffect(() => {
@@ -66,7 +66,7 @@ function APIKey() {
axios
.post(
process.env.REACT_APP_URL_SITE_BACKEND + "api-key",
- { resetapikey: true },
+ {}, // no form data required
yourConfig
)
.then((response) => {
diff --git a/server/src/client/app/src/pages/auth/ProfilePage.js b/server/src/client/app/src/pages/auth/ProfilePage.js
index 713e7ab0..a050d3f3 100755
--- a/server/src/client/app/src/pages/auth/ProfilePage.js
+++ b/server/src/client/app/src/pages/auth/ProfilePage.js
@@ -92,14 +92,16 @@ function Public() {
setFname(response.data.first_name);
setLname(response.data.last_name);
setId(response.data.id);
- if (id !== false) {
+ if (id) {
fetch(`${ELASTICSEARCH_SERVER}user/user/` + id.toString())
.then(response => response.json())
.then(data => {
- setDataset(data._source.datasets_uploaded);
- setRun(data._source.runs_uploaded);
- setTask(data._source.tasks_uploaded);
- setFlow(data._source.flows_uploaded);
+ if (data._source) {
+ setDataset(data._source.datasets_uploaded);
+ setRun(data._source.runs_uploaded);
+ setTask(data._source.tasks_uploaded);
+ setFlow(data._source.flows_uploaded);
+ }
});
}
})
diff --git a/server/src/client/app/src/pages/auth/SignIn.js b/server/src/client/app/src/pages/auth/SignIn.js
index 7f5f17ea..fa5a8221 100755
--- a/server/src/client/app/src/pages/auth/SignIn.js
+++ b/server/src/client/app/src/pages/auth/SignIn.js
@@ -33,8 +33,7 @@ function SignIn() {
const [errorlog, setError] = useState(false);
const [confirmflag, setConfirm] = useState(false);
const [errormsg, setErrorMsg] = useState(false);
- const [notexist, setNotExist] = useState(false);
- const [wrongpass, setWrongPass] = useState(false);
+ const [incorrectCredentials, setIncorrectCredentials] = useState(false);
const context = useContext(MainContext);
function sendtoflask(event) {
@@ -46,12 +45,10 @@ function SignIn() {
})
.then(response => {
console.log(response.data);
- if (response.data.msg === "NotConfirmed") {
+ if (response.data.msg === "UserNotConfirmed") {
setConfirm(true);
- } else if (response.data.msg === "Wrong username or password") {
- setNotExist(true);
- } else if (response.data.msg === "wrong password") {
- setWrongPass(true);
+ } else if (response.data.msg === "WrongUsernameOrPassword") {
+ setIncorrectCredentials(true);
} else {
localStorage.setItem("token", response.data.access_token);
context.checkLogIn();
@@ -75,12 +72,15 @@ function SignIn() {
)}
+ {/** Header **/}
Welcome back!
Sign in to continue
+
+ {/** Start Error Banner **/}
{errorlog && (
)}
- {wrongpass && (
+ {/* User with this email & password could not be found */}
+ {(incorrectCredentials) && (
)}
+ {/* User's account not yet confirmed */}
{confirmflag && (
(resend activation token)
)}
- {notexist && (
-
-
- Wrong username or password
-
- )}
+ {/** End Error Banner **/}
+
+ {/** Start Entry Fields **/}
+ {/** End Entry Fields **/}
diff --git a/server/src/client/app/src/pages/auth/SignUp.js b/server/src/client/app/src/pages/auth/SignUp.js
index 56d596ab..4454c1db 100755
--- a/server/src/client/app/src/pages/auth/SignUp.js
+++ b/server/src/client/app/src/pages/auth/SignUp.js
@@ -7,12 +7,18 @@ import { useState } from "react";
import {
FormControl,
+ IconButton,
Input,
InputLabel,
+ InputAdornment,
Button as MuiButton,
Paper,
Typography
} from "@mui/material";
+import {
+ Visibility,
+ VisibilityOff
+} from '@mui/icons-material';
import { spacing } from "@mui/system";
import axios from "axios";
@@ -30,53 +36,84 @@ const RedIcon = styled(FontAwesomeIcon)({
color: red[500]
});
+const MIN_PASSWORD_LENGTH = 15;
+
function SignUp() {
const [register, setRegister] = useState(false);
const [duplicateUser, setDuplicateUser] = useState(false);
const [error, setError] = useState(false);
const [errormessage, setErrorMessage] = useState(false);
- function sendflask(event) {
+
+ const [firstName, setFirstName] = useState("");
+ const [lastName, setLastName] = useState("");
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+
+ const [showPassword, setShowPassword] = useState(false);
+
+ function handleSubmit(event) {
event.preventDefault();
- console.log(event.target.email.value);
- console.log(event.target.password.value);
- if (event.target.password.value.length < 8) {
+ var registrationData = {
+ email: email,
+ firstName: firstName,
+ lastName: lastName,
+ password: password
+ };
+
+ if (password.length < MIN_PASSWORD_LENGTH) {
+ // Password must meet minimum length
+ // Using NIST recommendation
setError(true);
- setErrorMessage("Password too weak. Use at least 8 characters, with numbers, digits, and special characters.");
- } else if (
- /[a-zA-Z0-9]+@(?:[a-zA-Z0-9-]+\.)+[A-Za-z]+$/.test(
- event.target.email.value
- ) !== true
- ) {
+ setErrorMessage(`Password too weak. Use at least ${MIN_PASSWORD_LENGTH} characters.`);
+ } else if ( (/[a-zA-Z0-9]+@(?:[a-zA-Z0-9-]+\.)+[A-Za-z]+$/.test(email)) === false) {
+ // Email must be in valid format
setError(true);
setErrorMessage("Please enter valid email");
} else {
- axios
- .post(process.env.REACT_APP_URL_SITE_BACKEND + "signup", {
- first_name: event.target.fname.value,
- last_name: event.target.lname.value,
- email: event.target.email.value,
- password: event.target.password.value
- })
- .then(function(response) {
- if (response.data.msg === "User created") {
- console.log(response.data);
- setRegister(true);
- } else if (response.data.msg === "User already exists") {
- setDuplicateUser(true);
- }
- })
- .catch(function(error) {
- console.log(error.data);
- });
+ sendflask(registrationData);
}
+
return false;
}
+
+ function handleMouseDownPassword(event) {
+ event.preventDefault(); // Prevents focus loss
+ }
+
+ function handleClickShowPassword() {
+ setShowPassword(function(prev) {
+ return !prev;
+ });
+ }
+
+ function sendflask(registrationData) {
+ axios
+ .post(process.env.REACT_APP_URL_SITE_BACKEND + "signup", {
+ first_name: registrationData.firstName,
+ last_name: registrationData.lastName,
+ email: registrationData.email,
+ password: registrationData.password
+ })
+ .then(function(response) {
+ if (response.data.msg === "User created") {
+ console.log(response.data);
+ setRegister(true);
+ } else if (response.data.msg === "User alredy exists") {
+ setDuplicateUser(true);
+ }
+ })
+ .catch(function(error) {
+ console.log(error.data);
+ })
+ }
+
return (
Almost there
-