diff --git a/account/server/config/passport-strategies/local.js b/account/server/config/passport-strategies/local.js
index 7af2c50..7189ce1 100644
--- a/account/server/config/passport-strategies/local.js
+++ b/account/server/config/passport-strategies/local.js
@@ -26,6 +26,10 @@ const local = new LocalStrategy({
console.error("Auth Error - user not found: " + email);
return done(null, false, { message: `Invalid email or password` })
}
+ if (!user.confirmEmail) {
+ console.error("Auth Error - user has not confirmed email: " + email);
+ return done(null, false, { message: `User's email is not confirmed` })
+ }
user.comparePassword(password, (err, isMatch) => {
if (isMatch) {
return done(null, user)
diff --git a/account/server/controllers/users.js b/account/server/controllers/users.js
index 0ab4860..6e9af9e 100644
--- a/account/server/controllers/users.js
+++ b/account/server/controllers/users.js
@@ -91,10 +91,14 @@ exports.login = function (req, res, next) {
}
if (!user.confirmEmail) {
req.logout();
- return res.json({
- success: false,
- message: "unconfirmed email",
- userId: user.id
+ req.logout(function (err) {
+ if (err) { return next(err); }
+ res.clearCookie('sessionId', { domain: cookie_domain, path: '/' });
+ return res.json({
+ success: false,
+ message: "unconfirmed email",
+ userId: user.id
+ });
});
}
//console.log("account/server/controllers/users.js - req.login() Authenicated: " + user.email);
@@ -370,20 +374,20 @@ function handleSendConfirmEmail(user) {
TextPart: "Thanks for signing up for " + site_name + ". We just wanted to check and make sure your email address was real. Copy and paste this addres in your browser to confirm your email address: " + account_server + "/confirm-email/" + user._id + "/" + token,
HTMLPart: "
Thanks for signing up for " + site_name + "
We just wanted to check and make sure your email address was real. Copy and paste this addres in your browser to confirm your email address: " + account_server + "/confirm-email/" + user._id + "/" + token + "
"
}]
- });
- }).then(result => {
- console.log("Confirm email sent to: " + user.email);
- resolve({
- success: true,
- userId: user._id
- });
- }).catch(err => {
- console.error("Admin Email: " + admin_email + " User Email: " + user.email);
- console.error("Error - Send Confirm Email - caught: " + err);
- res.status(500);
- reject({
- success: false,
- message: err
+ }).then(result => {
+ console.log("Confirm email sent to: " + user.email);
+ resolve({
+ success: true,
+ userId: user._id
+ });
+ }).catch(err => {
+ console.error("Admin Email: " + admin_email + " User Email: " + user.email);
+ console.error("Error - Send Confirm Email - caught: " + err);
+ res.status(500);
+ reject({
+ success: false,
+ message: err
+ });
});
});
}
@@ -425,10 +429,13 @@ exports.sendConfirmEmail = async function (req, res, next) {
exports.logout = function (req, res, next) {
// the logout method is added to the request object automatically by Passport
- req.logout();
- res.clearCookie('sessionId', { domain: cookie_domain, path: '/' });
- return res.json({
- success: true
+ req.logout(function (err) {
+ if (err) { return next(err); }
+
+ res.clearCookie('sessionId', { domain: cookie_domain, path: '/' });
+ return res.json({
+ success: true
+ });
});
};
@@ -542,6 +549,30 @@ exports.updateProfile = async function (req, res, next) {
});
return;
}
+
+ // Lets make sure someone else isn't using this screenName
+ screenNameUser = await User.findOne({ screenName: req.body.screenName }).catch(err => {
+ console.error(err);
+ res.status(500);
+ res.json({
+ success: false,
+ message: err
+ });
+ return;
+ });
+
+ // Did we find a user with the screeName, is it not us?
+ if (screenNameUser && (screenNameUser.userId != user.userId)) {
+ res.status(500);
+ res.json({
+ success: false,
+ message: "Screen Name already in use"
+ });
+ return;
+ }
+
+
+
// go ahead and create the new user
user.firstName = res.locals.firstName
user.lastName = res.locals.lastName
@@ -608,6 +639,24 @@ exports.register = async function (req, res, next) {
});
return;
}
+ user = await User.findOne({ screenName: req.body.screenName }).catch(err => {
+ console.error(err);
+ res.status(500);
+ res.json({
+ success: false,
+ message: err
+ });
+ return;
+ });
+ // is email address already in use?
+ if (user) {
+ res.status(500);
+ res.json({
+ success: false,
+ message: "Screen Name already in use"
+ });
+ return;
+ }
// go ahead and create the new user
user = (({
firstName,
@@ -628,12 +677,16 @@ exports.register = async function (req, res, next) {
user.password = req.body.password;
user.email = req.body.email;
- await User.create(user)
+ let savedUser = await User.create(user)
console.log("Successfully registered: " + user.email + ", now sending confirmation email.");
- // Since regiestration worked, send a confirmation email.
- handleSendConfirmEmail(user).then(function (result) {
- res.json(result);
+ // Since registration worked, send a confirmation email.
+ handleSendConfirmEmail(savedUser).then(function (result) {
+ console.log("Confirmation email sent to: " + user.email);
+ res.json({
+ success: true,
+ message: result
+ });
return;
}).catch(function (err) {
console.error("Error creating user: " + user.email + " Error: " + err);
diff --git a/account/src/App/App.js b/account/src/App/App.js
index 0f7d58c..379a1b9 100644
--- a/account/src/App/App.js
+++ b/account/src/App/App.js
@@ -15,25 +15,25 @@ import ResetPassword from "../User/ResetPassword"
import Terms from "../User/Terms"
const App = (params) => {
- const {store} = params;
- return (
-
-
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- (Miss
)} />
-
-
- )
+ const { store } = params;
+ return (
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ (Miss
)} />
+
+
+ )
};
export default App
diff --git a/account/src/App/Restricted.js b/account/src/App/Restricted.js
index 1c5db84..2c0d0bc 100644
--- a/account/src/App/Restricted.js
+++ b/account/src/App/Restricted.js
@@ -1,32 +1,31 @@
// in src/restricted.js
-import React, { useEffect} from "react";
+import React, { useEffect } from "react";
import { useSelector, useDispatch } from 'react-redux'
-import { authenticateUser } from "../features/user/userSlice";
+import { authenticateUser } from "../features/user/userSlice";
import { useNavigate } from 'react-router-dom';
/**
* Higher-order component (HOC) to wrap restricted pages
*/
-const Restricted = ({children }) => {
+const Restricted = ({ children }) => {
const { authenticated, hasAuthenticated } = useSelector((state) => state.user);
const dispatch = useDispatch();
const navigate = useNavigate();
-
+
useEffect(() => {
dispatch(authenticateUser({}));
- },[]);
+ }, []);
if (hasAuthenticated) {
if (authenticated) {
- return children;;
- }
- else {
-
- navigate("/list-systems")
- }
-}
- return
-
+ return children;
+ }
+ else {
+ navigate("/login")
+ }
+ }
+ return
+
};
export default Restricted
\ No newline at end of file
diff --git a/account/src/User/ConfirmEmail.js b/account/src/User/ConfirmEmail.js
index 42c80b2..9e143f9 100644
--- a/account/src/User/ConfirmEmail.js
+++ b/account/src/User/ConfirmEmail.js
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React, { useState, useEffect } from "react";
import {
Container,
Dimmer,
@@ -7,72 +7,65 @@ import {
Message,
Icon
} from "semantic-ui-react";
-import { Link } from "react-router-dom";
+import { Link, useParams } from "react-router-dom";
+import { confirmEmail } from "../features/user/userSlice";
+import { useDispatch } from 'react-redux'
-class ConfirmEmail extends Component {
+const ConfirmEmail = (props) => {
+ const dispatch = useDispatch();
+ const [loading, setLoading] = useState(true);
+ const [confirmMessage, setConfirmMessage] = useState({ success: false, message: "" });
+ const { userId, token } = useParams();
- state = {
- loading: true,
- confirmMessage: { success: false, message:""}
- };
- componentDidMount() {
- const { match: { params } } = this.props;
- this.props
- .confirmEmail(params.userId, params.token)
- .then(confirmMessage => {
- if (confirmMessage) {
- // report to the user is there was a problem during login
- this.setState({
- confirmMessage: confirmMessage, loading: false
- });
- }
- });
+ const checkConfirmation = async(userId, token) => {
+ const result = await dispatch(confirmEmail({ userId, token })).unwrap();
+ if (result) {
+ setConfirmMessage(result);
+ setLoading(false);
+ }
}
- render() {
- var dimmerProps = { };
- if (this.state.loading) {
- dimmerProps["active"] = true;
- }
- return (
+ useEffect(() => {
+ checkConfirmation(userId, token);
+ }, []);
-
+ const dimmerProps = { active: loading };
+
+ return (
+
- Confirming Email Address
-
-
-
- {this.state.confirmMessage.success ? (
-
-
-
-
- Success
- You have successfully confirmed you email address.
-
-
+ Confirming Email Address
+
-
-
- ) : (
-
-
+ {confirmMessage.success ? (
+
+
+
+ Success
+ You have successfully confirmed you email address.
+
+
+
+
+ ) : (
+
+
Error
- {this.state.confirmMessage.message}
+ {confirmMessage.message}
-
-
- )}
-
-
- );
- }
+
+ )}
+
+
+ );
}
export default ConfirmEmail;
+
+
diff --git a/account/src/User/Profile.js b/account/src/User/Profile.js
index b567a55..2017748 100644
--- a/account/src/User/Profile.js
+++ b/account/src/User/Profile.js
@@ -20,7 +20,7 @@ const Profile = (props) => {
if (result.success) {
console.log(result)
} else {
- setMessage = result.message;
+ setMessage(result.message);
}
}
diff --git a/account/src/User/Register.js b/account/src/User/Register.js
index b6f2f52..49ef964 100644
--- a/account/src/User/Register.js
+++ b/account/src/User/Register.js
@@ -1,6 +1,6 @@
import React, { useState } from "react";
-import { registerUser } from "../features/user/userSlice";
-import { useNavigate, useSearchParams, Link } from 'react-router-dom';
+import { registerUser } from "../features/user/userSlice";
+import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux'
import {
Container,
@@ -15,32 +15,32 @@ function Register(props) {
const [requestMessage, setRequestMessage] = useState("");
const dispatch = useDispatch();
const navigate = useNavigate();
- const onRegisterSubmit = async(user) => {
+ const onRegisterSubmit = async (user) => {
const result = await dispatch(registerUser(user)).unwrap();
if (result.success) {
- navigate("/sent-confirm-email");
- } else {
- console.error(result);
- setRequestMessage(result.message);
- }
+ navigate("/sent-confirm-email");
+ } else {
+ console.error(result);
+ setRequestMessage(result.message);
+ }
};
return (
-
+
Welcome!
- Creating an account on OpenMHz is the first step in sharing radio system recordings using Trunk Recorder.
- After creating an account, head over here to learn more about Trunk Recorder
- - Luke
+ Creating an account on OpenMHz is the first step in sharing radio system recordings using Trunk Recorder.
+ After creating an account, head over here to learn more about Trunk Recorder
+ - Luke
-
+
);
diff --git a/account/src/User/ResetPassword.js b/account/src/User/ResetPassword.js
index 5f8437e..bc6e5c5 100644
--- a/account/src/User/ResetPassword.js
+++ b/account/src/User/ResetPassword.js
@@ -43,7 +43,6 @@ const ResetPassword = (props) => {
setConfirmPasswordError(false);
}
- const { match: { params } } = props;
setCheckInputMessages(inputMessages);
if (!error) {
const result = await dispatch(resetPassword({ userId, token, password })).unwrap();
diff --git a/account/src/User/UserForm.js b/account/src/User/UserForm.js
index e65bb04..5e635f2 100644
--- a/account/src/User/UserForm.js
+++ b/account/src/User/UserForm.js
@@ -28,6 +28,7 @@ const UserForm = (props) => {
const [passwordError, setPasswordError] = useState(false);
const [confirmPasswordError, setConfirmPasswordError] = useState(false);
const [isEditing, setIsEditing] = useState(props.isEditing);
+ const [changed, setChanged] = useState(false);
const requestMessage = props.requestMessage;
useEffect(() => {
@@ -37,6 +38,7 @@ const UserForm = (props) => {
setScreenName(props.user.screenName);
setEmail(props.user.email);
setLocation(props.user.location);
+ setChanged(false);
}
}, [props.isEditing, props.user]);
@@ -120,6 +122,7 @@ const UserForm = (props) => {
if (!inputError) {
const user ={ firstName, lastName, screenName, location, email, password };
+ setChanged(false);
props.onSubmit(user);
}
}
@@ -153,6 +156,7 @@ const UserForm = (props) => {
);
}
+ const buttonDisabled = changed?{}:{disabled:true}
return (
setFirstName(e.target.value)}
+ onChange={e => {setFirstName(e.target.value); setChanged(true)}}
error={firstNameError}
value={firstName}
label="First name"
@@ -179,7 +183,7 @@ const UserForm = (props) => {
setLastName(e.target.value)}
+ onChange={e => {setLastName(e.target.value); setChanged(true)}}
error={lastNameError}
value={lastName}
label="Last name"
@@ -192,7 +196,7 @@ const UserForm = (props) => {
setEmail(e.target.value)}
+ onChange={e => {setEmail(e.target.value); setChanged(true)}}
error={emailError}
value={email}
disabled={isEditing}
@@ -205,7 +209,7 @@ const UserForm = (props) => {
setScreenName(e.target.value)}
+ onChange={e => {setScreenName(e.target.value); setChanged(true)}}
error={screenNameError}
value={screenName}
label="Screen Name"
@@ -221,7 +225,7 @@ const UserForm = (props) => {
setLocation(e.target.value)}
+ onChange={e => {setLocation(e.target.value); setChanged(true)}}
error={locationError}
value={location}
label="General Location"
@@ -235,7 +239,8 @@ const UserForm = (props) => {
setPassword(e.target.value)}
+ onChange={e => {setPassword(e.target.value); setChanged(true)}}
+ value={password}
error={passwordError}
disabled={isEditing}
label="Password"
@@ -246,7 +251,8 @@ const UserForm = (props) => {
setConfirmPassword(e.target.value)}
+ onChange={e => {setConfirmPassword(e.target.value); setChanged(true)}}
+ value={confirmPassword}
error={confirmPasswordError}
disabled={isEditing}
label="Confirm Password"
@@ -256,7 +262,7 @@ const UserForm = (props) => {
)}
-
diff --git a/account/src/features/user/userSlice.js b/account/src/features/user/userSlice.js
index 6f2b27c..c585bf3 100644
--- a/account/src/features/user/userSlice.js
+++ b/account/src/features/user/userSlice.js
@@ -90,6 +90,22 @@ export const logoutUser = createAsyncThunk(
}
)
+
+export const confirmEmail = createAsyncThunk(
+ 'user/confirmEmail',
+ async ({userId, token}) => {
+ const url = process.env.REACT_APP_ACCOUNT_SERVER + "/users/" + userId + "/confirm/" + token;
+ const res = await fetch(url, {
+ method: 'POST'
+ }).then(
+ (data) => data.json()
+ )
+ return res;
+ }
+)
+
+
+
export const sendConfirmEmail = createAsyncThunk(
'user/sendConfirmEmail',
async (userId) => {
@@ -111,7 +127,7 @@ export const resetPassword = createAsyncThunk(
'user/resetPassword',
async (data) => {
const {userId, token, password} = data;
- const url = process.env.REACT_APP_ACCOUNT_SERVER + "/users/" + userId + "/confirm/" + token
+ const url = process.env.REACT_APP_ACCOUNT_SERVER + "/users/" + userId + "/reset-password/" + token
const res = await fetch(url, {
method: 'POST',
credentials: "include",
@@ -192,19 +208,11 @@ export const userSlice = createSlice({
[updateProfile.fulfilled]: (state, data) => {
const {payload} = data;
if (payload.success) {
- state.authenticated = true;
- state.hasAuthenticated = true;
- state.userId = payload.user.userId;
- state.admin = payload.user.admin;
- state.email = payload.user.email;
state.firstName = payload.user.firstName;
state.lastName = payload.user.lastName;
state.location = payload.user.location;
state.screenName = payload.user.screenName;
- } else {
- state.authenticated = false;
- state.hasAuthenticated = true;
- }
+ }
},
[loginUser.rejected]: (state, { payload }) => {
state.authenticated = false;