added login, first preparation for menu
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
};
|
||||
|
||||
208
backend/controllers/navigationController.js
Normal file
208
backend/controllers/navigationController.js
Normal file
@@ -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 });
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
7
backend/routers/navigationRouter.js
Normal file
7
backend/routers/navigationRouter.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Router } from 'express';
|
||||
import { menu } from '../controllers/navigationController.js';
|
||||
|
||||
const router = Router();
|
||||
router.get('/:userid', menu);
|
||||
|
||||
export default router;
|
||||
78
backend/services/authService.js
Normal file
78
backend/services/authService.js
Normal file
@@ -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' };
|
||||
};
|
||||
Reference in New Issue
Block a user