diff --git a/backend/app.js b/backend/app.js
index 2ceb25b..e746827 100644
--- a/backend/app.js
+++ b/backend/app.js
@@ -3,6 +3,7 @@ import path from 'path';
import { fileURLToPath } from 'url';
import chatRouter from './routers/chatRouter.js';
import authRouter from './routers/authRouter.js';
+import navigationRouter from './routers/navigationRouter.js'
import cors from 'cors';
const __filename = fileURLToPath(import.meta.url);
@@ -15,10 +16,11 @@ app.use(express.json()); // To handle JSON request bodies
app.use('/api/chat', chatRouter);
app.use('/api/auth', authRouter);
+app.use('/api/navigation', navigationRouter);
app.use('/images', express.static(path.join(__dirname, '../frontend/public/images')));
-app.get('*', (req, res) => {
- res.sendFile(path.join(__dirname, '../frontend/dist/index.html'));
+app.use((req, res) => {
+ res.status(404).send('404 Not Found');
});
export default app;
diff --git a/backend/controllers/authController.js b/backend/controllers/authController.js
index bb305f0..f40f57b 100644
--- a/backend/controllers/authController.js
+++ b/backend/controllers/authController.js
@@ -1,40 +1,11 @@
-import bcrypt from 'bcrypt';
-import { v4 as uuidv4 } from 'uuid';
-import User from '../models/community/user.js';
-import UserParam from '../models/community/user_param.js';
-import UserParamType from '../models/type/user_param.js';
-import { sendAccountActivationEmail, sendPasswordResetEmail } from '../services/emailService.js';
-import i18n from '../utils/i18n.js';
-
-const saltRounds = 10;
+import * as userService from '../services/authService.js';
export const register = async (req, res) => {
const { email, username, password, language } = req.body;
try {
- const hashedPassword = await bcrypt.hash(password, saltRounds);
- const resetToken = uuidv4();
- const user = await User.create({
- email,
- username,
- password: hashedPassword,
- resetToken: resetToken,
- active: false,
- registration_date: new Date()
- });
- const languageType = await UserParamType.findOne({ where: { description: 'language' } });
- if (!languageType) {
- return res.status(500).json({ error: 'Language type not found' });
- }
- console.log(user.id, languageType.id);
- await UserParam.create({
- userId: user.id,
- paramTypeId: languageType.id,
- value: language
- });
- const activationLink = `${process.env.FRONTEND_URL}/activate?token=${resetToken}`;
- await sendAccountActivationEmail(email, activationLink, username, resetToken, language);
- res.status(201).json({ id: user.hashedId, username: user.username, active: user.active });
+ const result = await userService.registerUser({ email, username, password, language });
+ res.status(201).json(result);
} catch (error) {
console.log(error);
res.status(500).json({ error: error.message });
@@ -42,56 +13,33 @@ export const register = async (req, res) => {
};
export const login = async (req, res) => {
- const { email, password } = req.body;
+ const { username, password } = req.body;
try {
- const user = await User.findOne({ where: { email } });
- if (!user) {
- return res.status(401).json({ error: 'Invalid email or password' });
- }
- if (!user.active) {
- return res.status(403).json({ error: 'Account not activated' });
- }
- const match = await bcrypt.compare(password, user.password);
- if (!match) {
- return res.status(401).json({ error: 'Invalid email or password' });
- }
- res.status(200).json({ id: user.hashed_id, username: user.username });
+ const result = await userService.loginUser({ username, password });
+ res.status(200).json(result);
} catch (error) {
- res.status(500).json({ error: 'Error logging in' });
+ res.status(500).json({ error: error.message });
}
};
export const forgotPassword = async (req, res) => {
const { email } = req.body;
+
try {
- const user = await User.findOne({ where: { email } });
- if (!user) {
- return res.status(404).json({ error: 'Email not found' });
- }
- const resetToken = uuidv4();
- const resetLink = `${process.env.FRONTEND_URL}/reset-password?token=${resetToken}`;
- await user.update({ reset_token: resetToken });
-
- const languageParam = await UserParam.findOne({ where: { user_id: user.id, param_type_id: languageType.id } });
- const userLanguage = languageParam ? languageParam.value : 'en';
-
- await sendPasswordResetEmail(email, resetLink, userLanguage);
- res.status(200).json({ message: 'Password reset email sent' });
+ const result = await userService.handleForgotPassword({ email });
+ res.status(200).json(result);
} catch (error) {
- res.status(500).json({ error: 'Error processing forgot password' });
+ res.status(500).json({ error: error.message });
}
};
export const activateAccount = async (req, res) => {
const { token } = req.body;
+
try {
- const user = await User.findOne({ where: { reset_token: token } });
- if (!user) {
- return res.status(404).json({ error: 'Invalid token' });
- }
- await user.update({ active: true, reset_token: null });
- res.status(200).json({ message: 'Account activated' });
+ const result = await userService.activateUserAccount({ token });
+ res.status(200).json(result);
} catch (error) {
- res.status(500).json({ error: 'Error activating account' });
+ res.status(500).json({ error: error.message });
}
};
diff --git a/backend/controllers/navigationController.js b/backend/controllers/navigationController.js
new file mode 100644
index 0000000..a8f7006
--- /dev/null
+++ b/backend/controllers/navigationController.js
@@ -0,0 +1,208 @@
+const menuStructure = {
+ home: {
+ visible: ["all"],
+ children: {},
+ path: "/"
+ },
+ friends: {
+ visible: ["all"],
+ children: {
+ manageFriends : {
+ visible: ["all"],
+ path: "/socialnetwork/friends"
+ }
+ },
+ showLoggedinFriends: 1
+ },
+ socialnetwork: {
+ visible: ["all"],
+ children: {
+ guestbook: {
+ visible: ["all"],
+ path: "/socialnetwork/guestbook"
+ },
+ usersearch: {
+ visible: ["all"],
+ path: "/socialnetwork/search"
+ },
+ forum: {
+ visible: ["all"],
+ path: "/socialnetwork/forum",
+ showForums: 1
+ },
+ gallery: {
+ visible: ["all"],
+ path: "/socialnetwork/gallery"
+ },
+ blockedUsers: {
+ visible: ["all"],
+ path: "/socialnetwork/blocked"
+ },
+ oneTimeInvitation: {
+ visible: ["all"],
+ path: "/socialnetwork/onetimeinvitation"
+ },
+ diary: {
+ visible: ["all"],
+ path: "/socialnetwork/diary"
+ }
+ }
+ },
+ chats: {
+ visible: ["all"],
+ children: {
+ multiChat: {
+ visible: ["over12"],
+ action: "openMultiChat"
+ },
+ randomChat: {
+ visible: ["over12"],
+ action: "openRanomChat"
+ }
+ }
+ },
+ falukant: {
+ visible: ["all"],
+ children: {
+ create: {
+ visible: ["nofalukantaccount"],
+ path: "/falukant/create"
+ },
+ overview: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/home"
+ },
+ towns: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/towns"
+ },
+ directors: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/directors"
+ },
+ factory: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/factory"
+ },
+ family: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/family"
+ },
+ house: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/house"
+ },
+ nobility: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/nobility"
+ },
+ politics: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/politics"
+ },
+ education: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/education"
+ },
+ bank: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/bank"
+ },
+ darknet: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/darknet"
+ },
+ reputation: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/reputation"
+ },
+ moneyhistory: {
+ visible: ["hasfalukantaccount"],
+ path: "/falukant/moneyhistory"
+ }
+ }
+ },
+ minigames: {
+ visible: ["all"],
+ },
+ settings: {
+ visible: ["all"],
+ children: {
+ homepage: {
+ visible: ["all"],
+ path: "/settings/homepage"
+ },
+ account: {
+ visible: ["all"],
+ path: "/settings/account"
+ },
+ personal: {
+ visible: ["all"],
+ path: "/settings/account"
+ },
+ view: {
+ visible: ["all"],
+ path: "/settings/account"
+ },
+ interrests: {
+ visible: ["all"],
+ path: "/settings/interrests"
+ },
+ sexuality: {
+ visible: ["over14"],
+ path: "/setting/sexuality"
+ },
+ notifications: {
+ visible: ["all"],
+ path: "/settings/notifications"
+ }
+ }
+ },
+ administration: {
+ visible: ["anyadmin"],
+ children: {
+ contactrequests: {
+ visible: ["mainadmin", "contactrequests"],
+ path: "/admin/contacts"
+ },
+ useradministration: {
+ visible: ["mainadmin", "useradministration"],
+ path: "/admin/users"
+ },
+ forum: {
+ visible: ["mainadmin", "forum"],
+ path: "/admin/forum"
+ },
+ userrights: {
+ visible: ["mainadmin", "rights"],
+ path: "/admin/rights"
+ },
+ interrests: {
+ visible: ["mainadmin", "interrests"],
+ path: "/admin/interrests"
+ },
+ falukant: {
+ visible: ["mainadmin", "falukant"],
+ children: {
+ logentries: {
+ visible: ["mainadmin", "falukant"],
+ path: "/admin/falukant/logentries"
+ },
+ edituser: {
+ visible: ["mainadmin", "falukant"],
+ path: "/admin/falukant/edituser"
+ },
+ database: {
+ visible: ["mainadmin", "falukant"],
+ path: "/admin/falukant/database"
+ },
+ }
+ }
+ }
+ }
+};
+
+export const menu = async (req, res) => {
+ const { userid } = req.params;
+ res.status(200).json({ userId: userid });
+}
diff --git a/backend/models/community/user.js b/backend/models/community/user.js
index c999d2c..ecde458 100644
--- a/backend/models/community/user.js
+++ b/backend/models/community/user.js
@@ -19,9 +19,6 @@ const User = sequelize.define('user', {
password: {
type: DataTypes.STRING,
allowNull: false,
- set(value) {
- this.setDataValue('password', bcrypt.hashSync(value, 10));
- }
},
registrationDate: {
type: DataTypes.DATE,
diff --git a/backend/routers/navigationRouter.js b/backend/routers/navigationRouter.js
new file mode 100644
index 0000000..7cd50b2
--- /dev/null
+++ b/backend/routers/navigationRouter.js
@@ -0,0 +1,7 @@
+import { Router } from 'express';
+import { menu } from '../controllers/navigationController.js';
+
+const router = Router();
+router.get('/:userid', menu);
+
+export default router;
\ No newline at end of file
diff --git a/backend/services/authService.js b/backend/services/authService.js
new file mode 100644
index 0000000..0d0937b
--- /dev/null
+++ b/backend/services/authService.js
@@ -0,0 +1,78 @@
+import bcrypt from 'bcrypt';
+import { v4 as uuidv4 } from 'uuid';
+import User from '../models/community/user.js';
+import UserParam from '../models/community/user_param.js';
+import UserParamType from '../models/type/user_param.js';
+import { sendAccountActivationEmail, sendPasswordResetEmail } from './emailService.js';
+
+const saltRounds = 10;
+
+export const registerUser = async ({ email, username, password, language }) => {
+ const hashedPassword = await bcrypt.hash(password, saltRounds);
+ const resetToken = uuidv4();
+ const user = await User.create({
+ email,
+ username,
+ password: hashedPassword,
+ resetToken: resetToken,
+ active: false,
+ registration_date: new Date()
+ });
+
+ const languageType = await UserParamType.findOne({ where: { description: 'language' } });
+ if (!languageType) {
+ throw new Error('Language type not found');
+ }
+
+ await UserParam.create({
+ userId: user.id,
+ paramTypeId: languageType.id,
+ value: language
+ });
+
+ const activationLink = `${process.env.FRONTEND_URL}/activate?token=${resetToken}`;
+ await sendAccountActivationEmail(email, activationLink, username, resetToken, language);
+
+ return { id: user.hashedId, username: user.username, active: user.active };
+};
+
+export const loginUser = async ({ username, password }) => {
+ console.log('check login');
+ const user = await User.findOne({ where: { username } });
+ if (!user) {
+ throw new Error('credentialsinvalid');
+ }
+ const match = await bcrypt.compare(password, user.password);
+ if (!match) {
+ throw new Error('credentialsinvalid');
+ }
+ return { id: user.hashedId, username: user.username, active: user.active };
+};
+
+export const handleForgotPassword = async ({ email }) => {
+ const user = await User.findOne({ where: { email } });
+ if (!user) {
+ throw new Error('Email not found');
+ }
+
+ const resetToken = uuidv4();
+ const resetLink = `${process.env.FRONTEND_URL}/reset-password?token=${resetToken}`;
+ await user.update({ reset_token: resetToken });
+
+ const languageParam = await UserParam.findOne({ where: { user_id: user.id, param_type_id: languageType.id } });
+ const userLanguage = languageParam ? languageParam.value : 'en';
+
+ await sendPasswordResetEmail(email, resetLink, userLanguage);
+
+ return { message: 'Password reset email sent' };
+};
+
+export const activateUserAccount = async ({ token }) => {
+ const user = await User.findOne({ where: { reset_token: token } });
+ if (!user) {
+ throw new Error('Invalid token');
+ }
+
+ await user.update({ active: true, reset_token: null });
+ return { message: 'Account activated' };
+};
diff --git a/frontend/src/components/AppNavigation.vue b/frontend/src/components/AppNavigation.vue
index b2235bf..55f3d5e 100644
--- a/frontend/src/components/AppNavigation.vue
+++ b/frontend/src/components/AppNavigation.vue
@@ -1,7 +1,7 @@