diff --git a/backend/package-lock.json b/backend/package-lock.json index 268204e70..3635c8039 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "idurar-erp-crm", - "version": "4.0.0-beta.3", + "version": "4.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "idurar-erp-crm", - "version": "4.0.0-beta.3", + "version": "4.0.0", "license": "Fair-code License", "dependencies": { "@aws-sdk/client-s3": "^3.509.0", diff --git a/backend/src/app.js b/backend/src/app.js index 3611c5a01..fbf9170eb 100644 --- a/backend/src/app.js +++ b/backend/src/app.js @@ -36,9 +36,9 @@ app.use(compression()); // Here our API Routes -app.use('/api', coreAuthRouter); -app.use('/api', adminAuth.isValidAuthToken, coreApiRouter); -app.use('/api', adminAuth.isValidAuthToken, erpApiRouter); +app.use('/api', coreAuthRouter); // This is for common users +app.use('/api', adminAuth.isValidAuthToken, coreApiRouter); // This is for admins +app.use('/api', adminAuth.isValidAuthToken, erpApiRouter); // This is for erps app.use('/download', coreDownloadRouter); app.use('/public', corePublicRouter); diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js index bf45d7b4a..e35bc1e31 100644 --- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js +++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js @@ -1,6 +1,7 @@ const isValidAuthToken = require('./isValidAuthToken'); const login = require('./login'); const logout = require('./logout'); +const register = require('./register'); const forgetPassword = require('./forgetPassword'); const resetPassword = require('./resetPassword'); @@ -17,6 +18,11 @@ const createAuthMiddleware = (userModel) => { userModel, }); + authMethods.register = (req, res) => + register(req, res, { + userModel, + }); + authMethods.forgetPassword = (req, res) => forgetPassword(req, res, { userModel, diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js new file mode 100644 index 000000000..0f059e101 --- /dev/null +++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js @@ -0,0 +1,96 @@ +const bcrypt = require('bcryptjs'); +const jwt = require('jsonwebtoken'); +const Joi = require('joi'); + +const mongoose = require('mongoose'); +const checkAndCorrectURL = require('./checkAndCorrectURL'); +const sendMail = require('./sendMail'); +const { loadSettings } = require('@/middlewares/settings'); +const { useAppSettings } = require('@/settings'); +const AdminPassword = require('@/models/coreModels/AdminPassword'); + +const register = async (req, res, { userModel }) => { + const UserModel = new mongoose.model(userModel); + const PasswordInstance = new AdminPassword(); + + const { name, email, password, country } = req.body; + + // validate + const objectSchema = Joi.object({ + email: Joi.string() + .email({ tlds: { allow: true } }) + .required(), + name: Joi.string().required(), + country: Joi.string().required(), + password: Joi.string().required(), + }); + + const { error, value } = objectSchema.validate({ name, email, password, country }); + if (error) { + return res.status(409).json({ + success: false, + result: null, + error: error, + message: 'Invalid/Missing credentials.', + errorMessage: error.message, + }); + } + + const user = await UserModel.findOne({ email: email, removed: false }); + if (user) + return res.status(409).json({ + success: false, + result: null, + message: 'An account with this email already exists.', + }); + + const salt = await bcrypt.genSalt(10); + const hashedPassword = await PasswordInstance.generateHash(salt, password); + const newUser = { + name: name, + email: email, + country: country, + enabled: true, + }; + + const createdUser = await UserModel.create(newUser); + const newUserPassword = new AdminPassword({ + removed: false, + user: createdUser, + password: hashedPassword, + salt: salt, + emailVerified: false, + authType: 'email', + loggedSessions: [], + }); + + const newPassword = await newUserPassword.save(); + const settings = useAppSettings(); + const idurar_app_email = settings['idurar_app_email']; + const idurar_base_url = settings['idurar_base_url']; + const url = checkAndCorrectURL(idurar_base_url); + const link = url + '/verify/' + createdUser._id + '/' + newPassword.emailToken; + await sendMail({ + email, + name, + link, + idurar_app_email, + emailToken: newPassword.emailToken, + }); + + if (!createdUser || !newUserPassword) { + return res.status(500).json({ + success: false, + result: null, + message: 'Error creating your account.', + }); + } else { + const success = { + success: true, + }; + const newUser = { ...createdUser, ...success }; + return res.status(200).json(newUser); + } +}; + +module.exports = register; diff --git a/backend/src/routes/coreRoutes/coreAuth.js b/backend/src/routes/coreRoutes/coreAuth.js index 2bda27d4d..5d7eacd43 100644 --- a/backend/src/routes/coreRoutes/coreAuth.js +++ b/backend/src/routes/coreRoutes/coreAuth.js @@ -6,7 +6,7 @@ const { catchErrors } = require('@/handlers/errorHandlers'); const adminAuth = require('@/controllers/coreControllers/adminAuth'); router.route('/login').post(catchErrors(adminAuth.login)); - +router.route('/register').post(catchErrors(adminAuth.register)); router.route('/forgetpassword').post(catchErrors(adminAuth.forgetPassword)); router.route('/resetpassword').post(catchErrors(adminAuth.resetPassword)); diff --git a/frontend/src/auth/auth.service.js b/frontend/src/auth/auth.service.js index dca276a70..a0e796174 100644 --- a/frontend/src/auth/auth.service.js +++ b/frontend/src/auth/auth.service.js @@ -28,6 +28,7 @@ export const login = async ({ loginData }) => { export const register = async ({ registerData }) => { try { + const response = await axios.post(API_BASE_URL + `register`, registerData); const { status, data } = response; diff --git a/frontend/src/pages/Login.jsx b/frontend/src/pages/Login.jsx index c1f8a1f5d..1db894fe7 100644 --- a/frontend/src/pages/Login.jsx +++ b/frontend/src/pages/Login.jsx @@ -51,6 +51,16 @@ const LoginPage = () => { > {translate('Log in')} + diff --git a/frontend/src/pages/Register.jsx b/frontend/src/pages/Register.jsx new file mode 100644 index 000000000..4d332ff01 --- /dev/null +++ b/frontend/src/pages/Register.jsx @@ -0,0 +1,60 @@ +import { useEffect } from 'react'; + +import { useDispatch, useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; + +import useLanguage from '@/locale/useLanguage'; + +import { Form, Button } from 'antd'; + +import { selectAuth } from '@/redux/auth/selectors'; +import RegisterForm from '@/forms/RegisterForm'; +import Loading from '@/components/Loading'; +import AuthModule from '@/modules/AuthModule'; +import { register } from '@/redux/auth/actions'; +const RegisterPage = () => { + const translate = useLanguage(); + const { isLoading, isSuccess } = useSelector(selectAuth); + const navigate = useNavigate(); + // const size = useSize(); + + const dispatch = useDispatch(); + const onFinish = (values) => { + console.log(values); + dispatch(register({ registerData: values })); + navigate('/'); + }; + + const FormContainer = () => { + return ( + +
+ + + + + +
+ ); + }; + + return } AUTH_TITLE="Sign Up" />; +}; + +export default RegisterPage; diff --git a/frontend/src/router/AuthRouter.jsx b/frontend/src/router/AuthRouter.jsx index 2416dd984..c63b2b3d6 100644 --- a/frontend/src/router/AuthRouter.jsx +++ b/frontend/src/router/AuthRouter.jsx @@ -1,6 +1,7 @@ import { Routes, Route, Navigate } from 'react-router-dom'; import Login from '@/pages/Login'; +import Register from '@/pages/Register'; import NotFound from '@/pages/NotFound'; import ForgetPassword from '@/pages/ForgetPassword'; @@ -15,6 +16,7 @@ export default function AuthRouter() { } path="/" /> } path="/login" /> + } path="/register"/> } path="/logout" /> } path="/forgetpassword" /> } path="/resetpassword/:userId/:resetToken" /> diff --git a/frontend/src/router/routes.jsx b/frontend/src/router/routes.jsx index 80fd1dd0e..1911b3d65 100644 --- a/frontend/src/router/routes.jsx +++ b/frontend/src/router/routes.jsx @@ -4,7 +4,7 @@ import { Navigate } from 'react-router-dom'; const Logout = lazy(() => import('@/pages/Logout.jsx')); const NotFound = lazy(() => import('@/pages/NotFound.jsx')); - +const Register = lazy(()=> import('@/pages/Register.jsx')); const Dashboard = lazy(() => import('@/pages/Dashboard')); const Customer = lazy(() => import('@/pages/Customer')); const Invoice = lazy(() => import('@/pages/Invoice')); @@ -61,6 +61,10 @@ let routes = { path: '/logout', element: , }, + { + path: '/register', + element: + }, { path: '/about', element: ,