From efe3794eeeea9b8f5d05583f498b89b0383eecfe Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sun, 2 Apr 2023 22:27:36 -0400 Subject: [PATCH] Seems to be all working!! --- .../config/passport-strategies/local.js | 4 + account/server/controllers/users.js | 105 +++++++++++++----- account/src/App/App.js | 38 +++---- account/src/App/Restricted.js | 27 +++-- account/src/User/ConfirmEmail.js | 105 ++++++++---------- account/src/User/Profile.js | 2 +- account/src/User/Register.js | 26 ++--- account/src/User/ResetPassword.js | 1 - account/src/User/UserForm.js | 22 ++-- account/src/features/user/userSlice.js | 28 +++-- 10 files changed, 210 insertions(+), 148 deletions(-) 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.

- -
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;