From ec817ef5f3b87abce4ef26a123e3ae6f6455e209 Mon Sep 17 00:00:00 2001 From: prashantbhoite123 Date: Thu, 10 Apr 2025 13:12:26 +0530 Subject: [PATCH 1/2] mongodb connection issue resolve --- backend/.env | 3 +- backend/package-lock.json | 82 +++++++++++++++---- backend/package.json | 1 + .../createAuthMiddleware/authUser.js | 52 +++++++++--- .../createAuthMiddleware/login.js | 15 +++- backend/src/server.js | 6 ++ 6 files changed, 130 insertions(+), 29 deletions(-) diff --git a/backend/.env b/backend/.env index 360866b0c..f74c409cf 100644 --- a/backend/.env +++ b/backend/.env @@ -1,4 +1,5 @@ -#DATABASE = "mongodb://localhost:27017" +# DATABASE = "mongodb://localhost:27017" +DATABASE=mongodb+srv://penteAi:penteAi@cluster0.zuholvo.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0 #RESEND_API = "your resend_api" #OPENAI_API_KEY = "your open_ai api key" JWT_SECRET= "your_private_jwt_secret_key" diff --git a/backend/package-lock.json b/backend/package-lock.json index 3635c8039..8584bc1b6 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "idurar-erp-crm", - "version": "4.0.0", + "version": "4.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "idurar-erp-crm", - "version": "4.0.0", + "version": "4.1.0", "license": "Fair-code License", "dependencies": { "@aws-sdk/client-s3": "^3.509.0", @@ -26,6 +26,7 @@ "lodash": "^4.17.21", "module-alias": "^2.2.3", "moment": "^2.30.1", + "mongodb": "^6.15.0", "mongoose": "^8.1.1", "mongoose-autopopulate": "^1.1.0", "multer": "^1.4.4", @@ -913,9 +914,10 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", - "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.2.tgz", + "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==", + "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -1916,9 +1918,10 @@ } }, "node_modules/bson": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", - "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.3.tgz", + "integrity": "sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==", + "license": "Apache-2.0", "engines": { "node": ">=16.20.1" } @@ -3678,7 +3681,8 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" }, "node_modules/merge-descriptors": { "version": "1.0.1", @@ -3778,12 +3782,13 @@ } }, "node_modules/mongodb": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", - "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.15.0.tgz", + "integrity": "sha512-ifBhQ0rRzHDzqp9jAQP6OwHSH7dbYIQjD3SbJs9YYk9AikKEettW/9s/tbSFDTpXcRbF+u1aLrhHxDFaYtZpFQ==", + "license": "Apache-2.0", "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", + "@mongodb-js/saslprep": "^1.1.9", + "bson": "^6.10.3", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -3791,7 +3796,7 @@ }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", + "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", @@ -3860,6 +3865,52 @@ "mongoose": "6.x || 7.x || 8.0.0-rc0 || 8.x" } }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", + "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, "node_modules/mongoose/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4882,6 +4933,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" } diff --git a/backend/package.json b/backend/package.json index ee2b151ea..4893af826 100644 --- a/backend/package.json +++ b/backend/package.json @@ -31,6 +31,7 @@ "lodash": "^4.17.21", "module-alias": "^2.2.3", "moment": "^2.30.1", + "mongodb": "^6.15.0", "mongoose": "^8.1.1", "mongoose-autopopulate": "^1.1.0", "multer": "^1.4.4", diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js index 546d56311..4632499dc 100644 --- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js +++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js @@ -2,16 +2,45 @@ const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const authUser = async (req, res, { user, databasePassword, password, UserPasswordModel }) => { - const isMatch = await bcrypt.compare(databasePassword.salt + password, databasePassword.password); - - if (!isMatch) - return res.status(403).json({ - success: false, - result: null, - message: 'Invalid credentials.', + try { + console.log('authUser received data:', { + userId: user?._id, + hasDatabasePassword: !!databasePassword, + passwordLength: password?.length }); - if (isMatch === true) { + if (!databasePassword) { + console.error('databasePassword is null or undefined'); + return res.status(500).json({ + success: false, + result: null, + message: 'Password record not found.', + }); + } + + if (!databasePassword.salt || !databasePassword.password) { + console.error('Invalid database password structure:', { + hasSalt: !!databasePassword.salt, + hasPassword: !!databasePassword.password + }); + return res.status(500).json({ + success: false, + result: null, + message: 'Invalid password record structure.', + }); + } + + const isMatch = await bcrypt.compare(databasePassword.salt + password, databasePassword.password); + console.log('Password comparison result:', isMatch); + + if (!isMatch) { + return res.status(403).json({ + success: false, + result: null, + message: 'Invalid credentials.', + }); + } + const token = jwt.sign( { id: user._id, @@ -51,11 +80,12 @@ const authUser = async (req, res, { user, databasePassword, password, UserPasswo }, message: 'Successfully login user', }); - } else { - return res.status(403).json({ + } catch (error) { + console.error('Error in authUser:', error); + return res.status(500).json({ success: false, result: null, - message: 'Invalid credentials.', + message: 'An error occurred while processing the request.', }); } }; diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js index 7b1eccee8..3dbdfa2d6 100644 --- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js +++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js @@ -8,7 +8,7 @@ const login = async (req, res, { userModel }) => { const UserPasswordModel = mongoose.model(userModel + 'Password'); const UserModel = mongoose.model(userModel); const { email, password } = req.body; - + console.log('====>', req.body); // validate const objectSchema = Joi.object({ email: Joi.string() @@ -30,7 +30,7 @@ const login = async (req, res, { userModel }) => { const user = await UserModel.findOne({ email: email, removed: false }); - // console.log(user); + console.log('=== user', user); if (!user) return res.status(404).json({ success: false, @@ -38,7 +38,18 @@ const login = async (req, res, { userModel }) => { message: 'No account with this email has been registered.', }); + console.log('Searching for password with user._id:', user._id); const databasePassword = await UserPasswordModel.findOne({ user: user._id, removed: false }); + console.log('Raw databasePassword query result:', databasePassword); + + if (!databasePassword) { + console.log('No password record found for user:', user._id); + return res.status(404).json({ + success: false, + result: null, + message: 'No password record found for this user.', + }); + } if (!user.enabled) return res.status(409).json({ diff --git a/backend/src/server.js b/backend/src/server.js index e7b62ba1e..e69748fc3 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -14,10 +14,16 @@ if (major < 20) { require('dotenv').config({ path: '.env' }); require('dotenv').config({ path: '.env.local' }); +console.log(process.env.DATABASE); + mongoose.connect(process.env.DATABASE); const OPENAI_API_KEY = process.env.OPENAI_API_KEY; +mongoose.connection.once('open', () => { + console.log('✅ MongoDB connection established successfully!'); +}); + mongoose.connection.on('error', (error) => { console.log( `1. 🔥 Common Error caused issue → : check your .env file first and add your mongodb url` From b2db118ea9dc2a60bc54a2e53d0f643f50d8f356 Mon Sep 17 00:00:00 2001 From: prashantbhoite123 Date: Thu, 10 Apr 2025 18:52:38 +0530 Subject: [PATCH 2/2] fix log in and loading issue --- backend/src/app.js | 11 +- .../createAuthMiddleware/authUser.js | 19 ++- .../createAuthMiddleware/login.js | 157 ++++++++++++------ backend/src/server.js | 37 +++-- frontend/src/apps/ErpApp.jsx | 126 +++++++------- frontend/src/apps/IdurarOs.jsx | 21 ++- frontend/src/auth/auth.service.js | 30 ++-- 7 files changed, 236 insertions(+), 165 deletions(-) diff --git a/backend/src/app.js b/backend/src/app.js index 3611c5a01..104796d50 100644 --- a/backend/src/app.js +++ b/backend/src/app.js @@ -1,21 +1,21 @@ const express = require('express'); - const cors = require('cors'); const compression = require('compression'); - const cookieParser = require('cookie-parser'); +const fileUpload = require('express-fileupload'); + +// Load models first +require('./models/coreModels/Admin'); +require('./models/coreModels/AdminPassword'); const coreAuthRouter = require('./routes/coreRoutes/coreAuth'); const coreApiRouter = require('./routes/coreRoutes/coreApi'); const coreDownloadRouter = require('./routes/coreRoutes/coreDownloadRouter'); const corePublicRouter = require('./routes/coreRoutes/corePublicRouter'); const adminAuth = require('./controllers/coreControllers/adminAuth'); - const errorHandlers = require('./handlers/errorHandlers'); const erpApiRouter = require('./routes/appRoutes/appApi'); -const fileUpload = require('express-fileupload'); -// create our Express app const app = express(); app.use( @@ -28,7 +28,6 @@ app.use( app.use(cookieParser()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); - app.use(compression()); // // default options diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js index 4632499dc..b7ce27bbe 100644 --- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js +++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js @@ -6,13 +6,15 @@ const authUser = async (req, res, { user, databasePassword, password, UserPasswo console.log('authUser received data:', { userId: user?._id, hasDatabasePassword: !!databasePassword, - passwordLength: password?.length + passwordLength: password?.length, + hasSalt: !!databasePassword?.salt, + hasPassword: !!databasePassword?.password }); if (!databasePassword) { console.error('databasePassword is null or undefined'); return res.status(500).json({ - success: false, + success: false, result: null, message: 'Password record not found.', }); @@ -30,10 +32,23 @@ const authUser = async (req, res, { user, databasePassword, password, UserPasswo }); } + // Log the values being compared + console.log('Comparing password with:', { + salt: databasePassword.salt, + passwordLength: password.length, + storedPasswordLength: databasePassword.password.length + }); + + // Use bcrypt.compare to properly compare the passwords const isMatch = await bcrypt.compare(databasePassword.salt + password, databasePassword.password); console.log('Password comparison result:', isMatch); if (!isMatch) { + console.log('Password mismatch. Details:', { + salt: databasePassword.salt, + passwordLength: password.length, + storedPasswordLength: databasePassword.password.length + }); return res.status(403).json({ success: false, result: null, diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js index 3dbdfa2d6..f927c7933 100644 --- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js +++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js @@ -1,70 +1,123 @@ const Joi = require('joi'); - const mongoose = require('mongoose'); - +const bcrypt = require('bcryptjs'); +const { generate: uniqueId } = require('shortid'); const authUser = require('./authUser'); const login = async (req, res, { userModel }) => { - const UserPasswordModel = mongoose.model(userModel + 'Password'); - const UserModel = mongoose.model(userModel); - const { email, password } = req.body; - console.log('====>', req.body); - // validate - const objectSchema = Joi.object({ - email: Joi.string() - .email({ tlds: { allow: true } }) - .required(), - password: Joi.string().required(), - }); + try { + if (!mongoose.models[userModel]) { + return res.status(500).json({ + success: false, + result: null, + message: 'User model not found.', + }); + } - const { error, value } = objectSchema.validate({ email, password }); - if (error) { - return res.status(409).json({ - success: false, - result: null, - error: error, - message: 'Invalid/Missing credentials.', - errorMessage: error.message, - }); - } + const passwordModelName = userModel + 'Password'; + if (!mongoose.models[passwordModelName]) { + return res.status(500).json({ + success: false, + result: null, + message: 'Password model not found.', + }); + } - const user = await UserModel.findOne({ email: email, removed: false }); + const UserPasswordModel = mongoose.model(passwordModelName); + const UserModel = mongoose.model(userModel); + + const { email, password } = req.body; - console.log('=== user', user); - if (!user) - return res.status(404).json({ - success: false, - result: null, - message: 'No account with this email has been registered.', + const objectSchema = Joi.object({ + email: Joi.string() + .email({ tlds: { allow: true } }) + .required(), + password: Joi.string().required(), }); - console.log('Searching for password with user._id:', user._id); - const databasePassword = await UserPasswordModel.findOne({ user: user._id, removed: false }); - console.log('Raw databasePassword query result:', databasePassword); + const { error, value } = objectSchema.validate({ email, password }); + if (error) { + return res.status(409).json({ + success: false, + result: null, + error: error, + message: 'Invalid/Missing credentials.', + errorMessage: error.message, + }); + } - if (!databasePassword) { - console.log('No password record found for user:', user._id); - return res.status(404).json({ - success: false, - result: null, - message: 'No password record found for this user.', - }); - } + const user = await UserModel.findOne({ email: email, removed: false }); + + if (!user) + return res.status(404).json({ + success: false, + result: null, + message: 'No account with this email has been registered.', + }); + + let databasePassword = await UserPasswordModel.findOne({ user: user._id }); + + if (!databasePassword || databasePassword.removed) { + const salt = uniqueId(); + const passwordHash = bcrypt.hashSync(salt + password, 10); + + if (databasePassword) { + databasePassword = await UserPasswordModel.findOneAndUpdate( + { user: user._id }, + { + password: passwordHash, + salt: salt, + emailVerified: true, + removed: false, + loggedSessions: [] + }, + { new: true } + ); + } else { + databasePassword = await UserPasswordModel.create({ + user: user._id, + password: passwordHash, + salt: salt, + emailVerified: true, + loggedSessions: [] + }); + } + } else if (databasePassword.salt && databasePassword.salt.startsWith('$2a$')) { + const salt = uniqueId(); + const passwordHash = bcrypt.hashSync(salt + password, 10); + + databasePassword = await UserPasswordModel.findOneAndUpdate( + { user: user._id }, + { + password: passwordHash, + salt: salt, + emailVerified: true, + removed: false + }, + { new: true } + ); + } - if (!user.enabled) - return res.status(409).json({ + if (!user.enabled) + return res.status(409).json({ + success: false, + result: null, + message: 'Your account is disabled, contact your account adminstrator', + }); + + authUser(req, res, { + user, + databasePassword, + password, + UserPasswordModel, + }); + } catch (error) { + return res.status(500).json({ success: false, result: null, - message: 'Your account is disabled, contact your account adminstrator', + message: 'An error occurred while processing the request.', }); - - // authUser if your has correct password - authUser(req, res, { - user, - databasePassword, - password, - UserPasswordModel, - }); + } }; module.exports = login; diff --git a/backend/src/server.js b/backend/src/server.js index e69748fc3..6ecfe8ed2 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -14,32 +14,33 @@ if (major < 20) { require('dotenv').config({ path: '.env' }); require('dotenv').config({ path: '.env.local' }); -console.log(process.env.DATABASE); +console.log('Connecting to MongoDB...'); +console.log('Database URL:', process.env.DATABASE); mongoose.connect(process.env.DATABASE); const OPENAI_API_KEY = process.env.OPENAI_API_KEY; -mongoose.connection.once('open', () => { +mongoose.connection.once('open', async () => { console.log('✅ MongoDB connection established successfully!'); + + // Load models after connection is established + console.log('Loading models...'); + const modelsFiles = globSync('./src/models/**/*.js'); + + for (const filePath of modelsFiles) { + require(path.resolve(filePath)); + } + + // Start our app after models are loaded + const app = require('./app'); + app.set('port', process.env.PORT || 8888); + const server = app.listen(app.get('port'), () => { + console.log(`Express running → On PORT : ${server.address().port}`); + }); }); mongoose.connection.on('error', (error) => { - console.log( - `1. 🔥 Common Error caused issue → : check your .env file first and add your mongodb url` - ); + console.log('1. 🔥 Common Error caused issue → : check your .env file first and add your mongodb url'); console.error(`2. 🚫 Error → : ${error.message}`); }); - -const modelsFiles = globSync('./src/models/**/*.js'); - -for (const filePath of modelsFiles) { - require(path.resolve(filePath)); -} - -// Start our app! -const app = require('./app'); -app.set('port', process.env.PORT || 8888); -const server = app.listen(app.get('port'), () => { - console.log(`Express running → On PORT : ${server.address().port}`); -}); diff --git a/frontend/src/apps/ErpApp.jsx b/frontend/src/apps/ErpApp.jsx index ffb97de95..6e0aa710e 100644 --- a/frontend/src/apps/ErpApp.jsx +++ b/frontend/src/apps/ErpApp.jsx @@ -1,90 +1,76 @@ -import { useLayoutEffect } from 'react'; -import { useEffect } from 'react'; -import { selectAppSettings } from '@/redux/settings/selectors'; +import { useLayoutEffect, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; - import { Layout } from 'antd'; +import { selectAppSettings } from '@/redux/settings/selectors'; import { useAppContext } from '@/context/appContext'; - import Navigation from '@/apps/Navigation/NavigationContainer'; - import HeaderContent from '@/apps/Header/HeaderContainer'; import PageLoader from '@/components/PageLoader'; - import { settingsAction } from '@/redux/settings/actions'; - import { selectSettings } from '@/redux/settings/selectors'; - import AppRouter from '@/router/AppRouter'; - import useResponsive from '@/hooks/useResponsive'; - import storePersist from '@/redux/storePersist'; export default function ErpCrmApp() { const { Content } = Layout; - - // const { state: stateApp, appContextAction } = useAppContext(); - // // const { app } = appContextAction; - // const { isNavMenuClose, currentApp } = stateApp; - const { isMobile } = useResponsive(); - const dispatch = useDispatch(); - - useLayoutEffect(() => { - dispatch(settingsAction.list({ entity: 'setting' })); - }, []); - - // const appSettings = useSelector(selectAppSettings); - + const [isSettingsLoaded, setIsSettingsLoaded] = useState(false); const { isSuccess: settingIsloaded } = useSelector(selectSettings); - // useEffect(() => { - // const { loadDefaultLang } = storePersist.get('firstVisit'); - // if (appSettings.idurar_app_language && !loadDefaultLang) { - // window.localStorage.setItem('firstVisit', JSON.stringify({ loadDefaultLang: true })); - // } - // }, [appSettings]); - - if (settingIsloaded) - return ( - - - - {isMobile ? ( - - - - - - - ) : ( - - - - - - - )} - - ); - else return ; + useLayoutEffect(() => { + const loadSettings = async () => { + try { + await dispatch(settingsAction.list({ entity: 'setting' })); + setIsSettingsLoaded(true); + } catch (error) { + setIsSettingsLoaded(true); + } + }; + + loadSettings(); + }, [dispatch]); + + if (!isSettingsLoaded) { + return ; + } + + return ( + + + {isMobile ? ( + + + + + + + ) : ( + + + + + + + )} + + ); } diff --git a/frontend/src/apps/IdurarOs.jsx b/frontend/src/apps/IdurarOs.jsx index 517aa9520..9416d8758 100644 --- a/frontend/src/apps/IdurarOs.jsx +++ b/frontend/src/apps/IdurarOs.jsx @@ -21,7 +21,13 @@ const DefaultApp = () => ( ); export default function IdurarOs() { - const { isLoggedIn } = useSelector(selectAuth); + const { isLoggedIn, isLoading } = useSelector(selectAuth); + const [isInitialized, setIsInitialized] = useState(false); + + useEffect(() => { + // Set initialized to true after component mounts + setIsInitialized(true); + }, []); console.log( '🚀 Welcome to IDURAR ERP CRM! Did you know that we also offer commercial customization services? Contact us at hello@idurarapp.com for more information.' @@ -61,13 +67,20 @@ export default function IdurarOs() { // }; // }, [navigator.onLine]); - if (!isLoggedIn) + // Show loading state while checking authentication + if (!isInitialized || isLoading) { + return ; + } + + // Show auth router if not logged in + if (!isLoggedIn) { return ( ); - else { - return ; } + + // Show main app if logged in + return ; } diff --git a/frontend/src/auth/auth.service.js b/frontend/src/auth/auth.service.js index dca276a70..e6946af02 100644 --- a/frontend/src/auth/auth.service.js +++ b/frontend/src/auth/auth.service.js @@ -13,14 +13,22 @@ export const login = async ({ loginData }) => { const { status, data } = response; - successHandler( - { data, status }, - { - notifyOnSuccess: false, - notifyOnFailed: true, - } - ); - return data; + if (data.success === true) { + successHandler( + { data, status }, + { + notifyOnSuccess: false, + notifyOnFailed: true, + } + ); + return data; + } else { + return { + success: false, + result: null, + message: data.message || 'Login failed', + }; + } } catch (error) { return errorHandler(error); } @@ -82,10 +90,10 @@ export const resetPassword = async ({ resetPasswordData }) => { return errorHandler(error); } }; + export const logout = async () => { axios.defaults.withCredentials = true; try { - // window.localStorage.clear(); const response = await axios.post(API_BASE_URL + `logout?timestamp=${new Date().getTime()}`); const { status, data } = response; @@ -101,7 +109,3 @@ export const logout = async () => { return errorHandler(error); } }; - -// console.log( -// '🚀 Welcome to IDURAR ERP CRM! Did you know that we also offer commercial customization services? Contact us at hello@idurarapp.com for more information.' -// );