- sistemazioni Email : registrazione, invio invito, email di benvenuto
- fix circuito - profilo
This commit is contained in:
533
src/controllers/UserController.js
Normal file
533
src/controllers/UserController.js
Normal file
@@ -0,0 +1,533 @@
|
||||
const UserService = require('../services/UserService');
|
||||
const AuthService = require('../services/AuthService');
|
||||
const RegistrationService = require('../services/RegistrationService');
|
||||
const { validateRegistration, validateLogin } = require('../validators/userValidators');
|
||||
const telegrambot = require('../telegram/telegrambot');
|
||||
const tools = require('../tools/general');
|
||||
const server_constants = require('../tools/server_constants');
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
class UserController {
|
||||
constructor() {
|
||||
this.userService = new UserService();
|
||||
this.authService = new AuthService();
|
||||
this.registrationService = new RegistrationService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new user
|
||||
* POST /users
|
||||
*/
|
||||
async register(req, res) {
|
||||
try {
|
||||
tools.mylog('POST /users - Registration');
|
||||
|
||||
// Validate input
|
||||
const validationError = validateRegistration(req.body);
|
||||
if (validationError) {
|
||||
await tools.snooze(5000);
|
||||
return res.status(400).send({
|
||||
code: validationError.code,
|
||||
msg: validationError.message
|
||||
});
|
||||
}
|
||||
|
||||
const userData = this._extractUserData(req.body);
|
||||
userData.ipaddr = tools.getiPAddressUser(req);
|
||||
|
||||
// Check security (IP bans, block words, etc.)
|
||||
const securityCheck = await this._performSecurityChecks(userData, req);
|
||||
if (securityCheck.blocked) {
|
||||
return res.status(securityCheck.status).send({
|
||||
code: securityCheck.code,
|
||||
msg: securityCheck.message
|
||||
});
|
||||
}
|
||||
|
||||
// Process registration
|
||||
const result = await this.registrationService.registerUser(userData, req);
|
||||
|
||||
if (result.error) {
|
||||
return res.status(400).send({
|
||||
code: result.code,
|
||||
msg: result.message
|
||||
});
|
||||
}
|
||||
|
||||
// Send response with tokens
|
||||
res
|
||||
.header('x-auth', result.token)
|
||||
.header('x-refrtok', result.refreshToken)
|
||||
.send(result.user);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in registration:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User login
|
||||
* POST /users/login
|
||||
*/
|
||||
async login(req, res) {
|
||||
try {
|
||||
const { username, password, idapp, keyappid } = req.body;
|
||||
|
||||
// Validate API key
|
||||
if (keyappid !== process.env.KEY_APP_ID) {
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR });
|
||||
}
|
||||
|
||||
// Validate input
|
||||
const validationError = validateLogin(req.body);
|
||||
if (validationError) {
|
||||
return res.status(400).send({
|
||||
code: validationError.code,
|
||||
msg: validationError.message
|
||||
});
|
||||
}
|
||||
|
||||
// Attempt login
|
||||
const result = await this.authService.authenticate(
|
||||
idapp,
|
||||
username,
|
||||
password,
|
||||
req
|
||||
);
|
||||
|
||||
if (result.error) {
|
||||
return res.status(result.status).send({
|
||||
code: result.code,
|
||||
msg: result.message
|
||||
});
|
||||
}
|
||||
|
||||
// Send response with tokens
|
||||
res
|
||||
.header('x-auth', result.token)
|
||||
.header('x-refrtok', result.refreshToken)
|
||||
.send({
|
||||
usertosend: result.user,
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
subsExistonDb: result.subsExistonDb
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in login:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC,
|
||||
msgerr: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user profile
|
||||
* POST /users/profile
|
||||
*/
|
||||
async getProfile(req, res) {
|
||||
try {
|
||||
const usernameOrig = req.user?.username || '';
|
||||
const perm = req.user?.perm || tools.Perm.PERM_NONE;
|
||||
const { username, idapp, idnotif } = req.body;
|
||||
|
||||
// Mark notification as read if present
|
||||
if (idnotif) {
|
||||
await this.userService.markNotificationAsRead(idapp, usernameOrig, idnotif);
|
||||
}
|
||||
|
||||
// Get user profile
|
||||
const profile = await this.userService.getUserProfile(
|
||||
idapp,
|
||||
username,
|
||||
usernameOrig,
|
||||
perm
|
||||
);
|
||||
|
||||
res.send(profile);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in getProfile:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user saldo (balance)
|
||||
* POST /users/updatesaldo
|
||||
*/
|
||||
async updateSaldo(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp, circuitId, groupname, lastdr } = req.body;
|
||||
|
||||
const result = await this.userService.updateUserBalance(
|
||||
idapp,
|
||||
username,
|
||||
circuitId,
|
||||
groupname,
|
||||
lastdr
|
||||
);
|
||||
|
||||
res.send({ ris: result });
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in updateSaldo:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's friends
|
||||
* POST /users/friends
|
||||
*/
|
||||
async getFriends(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp } = req.body;
|
||||
|
||||
const friends = await this.userService.getUserFriends(idapp, username);
|
||||
|
||||
res.send(friends);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in getFriends:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute friend command (add, remove, etc.)
|
||||
* POST /users/friends/cmd
|
||||
*/
|
||||
async executeFriendCommand(req, res) {
|
||||
try {
|
||||
const usernameLogged = req.user.username;
|
||||
const { idapp, usernameOrig, usernameDest, cmd, value } = req.body;
|
||||
|
||||
// Security check
|
||||
if (!this._canExecuteFriendCommand(req.user, usernameOrig, usernameDest, cmd)) {
|
||||
return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({
|
||||
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||
msg: ''
|
||||
});
|
||||
}
|
||||
|
||||
const result = await this.userService.executeFriendCommand(
|
||||
req,
|
||||
idapp,
|
||||
usernameOrig,
|
||||
usernameDest,
|
||||
cmd,
|
||||
value
|
||||
);
|
||||
|
||||
res.send(result);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in executeFriendCommand:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's groups
|
||||
* POST /users/groups
|
||||
*/
|
||||
async getGroups(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp } = req.body;
|
||||
|
||||
const groups = await this.userService.getUserGroups(idapp, username, req);
|
||||
|
||||
res.send(groups);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in getGroups:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's circuits
|
||||
* POST /users/circuits
|
||||
*/
|
||||
async getCircuits(req, res) {
|
||||
try {
|
||||
const username = req.user.username;
|
||||
const { idapp, nummovTodownload } = req.body;
|
||||
|
||||
const circuits = await this.userService.getUserCircuits(
|
||||
idapp,
|
||||
username,
|
||||
req.user,
|
||||
nummovTodownload
|
||||
);
|
||||
|
||||
res.send(circuits);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in getCircuits:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh authentication token
|
||||
* POST /users/newtok
|
||||
*/
|
||||
async refreshToken(req, res) {
|
||||
try {
|
||||
const { refreshToken } = req.body;
|
||||
|
||||
if (!refreshToken) {
|
||||
return res.status(400).send({ error: 'Refresh token mancante' });
|
||||
}
|
||||
|
||||
const result = await this.authService.refreshToken(refreshToken, req);
|
||||
|
||||
if (result.error) {
|
||||
return res.status(result.status).send({ error: result.message });
|
||||
}
|
||||
|
||||
res.status(200).send({
|
||||
token: result.token,
|
||||
refreshToken: result.refreshToken
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in refreshToken:', error.message);
|
||||
res.status(500).send({ error: 'Errore interno del server' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout user (remove token)
|
||||
* DELETE /users/me/token
|
||||
*/
|
||||
async logout(req, res) {
|
||||
try {
|
||||
await this.authService.removeToken(req.user, req.token);
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
console.error('Error in logout:', error.message);
|
||||
res.status(400).send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if username exists
|
||||
* GET /users/:idapp/:username
|
||||
*/
|
||||
async checkUsername(req, res) {
|
||||
try {
|
||||
const { username, idapp } = req.params;
|
||||
|
||||
const exists = await this.userService.checkUsernameExists(idapp, username);
|
||||
|
||||
if (!exists) {
|
||||
return res.status(404).send();
|
||||
}
|
||||
|
||||
res.status(200).send();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in checkUsername:', error.message);
|
||||
res.status(400).send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user permissions
|
||||
* POST /users/setperm
|
||||
*/
|
||||
async setPermissions(req, res) {
|
||||
try {
|
||||
const { idapp, username, perm } = req.body;
|
||||
|
||||
await this.userService.setUserPermissions(req.user._id, {
|
||||
idapp,
|
||||
username,
|
||||
perm
|
||||
});
|
||||
|
||||
res.status(200).send();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in setPermissions:', error.message);
|
||||
res.status(400).send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Database operations (admin only)
|
||||
* POST /users/dbop
|
||||
*/
|
||||
async executeDbOperation(req, res) {
|
||||
try {
|
||||
const { mydata, idapp } = req.body;
|
||||
|
||||
// Check permissions
|
||||
if (!this._hasAdminPermissions(req.user)) {
|
||||
return res.status(404).send({
|
||||
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED
|
||||
});
|
||||
}
|
||||
|
||||
const result = await this.userService.executeDbOperation(
|
||||
idapp,
|
||||
mydata,
|
||||
req,
|
||||
res
|
||||
);
|
||||
|
||||
res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
data: result
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in executeDbOperation:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get map information
|
||||
* POST /users/infomap
|
||||
*/
|
||||
async getMapInfo(req, res) {
|
||||
try {
|
||||
const { idapp } = req.body;
|
||||
|
||||
const mapData = await this.userService.getMapInformation(idapp);
|
||||
|
||||
res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
ris: mapData
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in getMapInfo:', error.message);
|
||||
res.status(400).send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
msg: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ===== PRIVATE HELPER METHODS =====
|
||||
|
||||
_extractUserData(body) {
|
||||
const fields = [
|
||||
'email', 'password', 'username', 'group', 'name',
|
||||
'surname', 'idapp', 'keyappid', 'lang', 'profile',
|
||||
'aportador_solidario'
|
||||
];
|
||||
|
||||
const userData = {};
|
||||
fields.forEach(field => {
|
||||
if (body[field] !== undefined) {
|
||||
userData[field] = body[field];
|
||||
}
|
||||
});
|
||||
|
||||
// Normalize data
|
||||
if (userData.email) userData.email = userData.email.toLowerCase().trim();
|
||||
if (userData.username) userData.username = userData.username.trim();
|
||||
if (userData.name) userData.name = userData.name.trim();
|
||||
if (userData.surname) userData.surname = userData.surname.trim();
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
async _performSecurityChecks(userData, req) {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
// Check for blocked words
|
||||
if (tools.blockwords(userData.username) ||
|
||||
tools.blockwords(userData.name) ||
|
||||
tools.blockwords(userData.surname)) {
|
||||
await tools.snooze(5000);
|
||||
return {
|
||||
blocked: true,
|
||||
status: 404,
|
||||
code: server_constants.RIS_CODE_ERR
|
||||
};
|
||||
}
|
||||
|
||||
// Check IP ban
|
||||
const lastRecord = await User.getLastRec(userData.idapp);
|
||||
if (lastRecord && process.env.LOCALE !== '1') {
|
||||
if (lastRecord.ipaddr === userData.ipaddr && lastRecord.date_reg) {
|
||||
const isTooRecent = tools.isdiffSecDateLess(lastRecord.date_reg, 3);
|
||||
if (isTooRecent) {
|
||||
const msg = `${userData.ipaddr}: [${userData.username}] ${userData.name} ${userData.surname}`;
|
||||
tools.writeIPToBan(msg);
|
||||
await telegrambot.sendMsgTelegramToTheAdmin(userData.idapp, '‼️ BAN: ' + msg, true);
|
||||
await tools.snooze(5000);
|
||||
|
||||
return {
|
||||
blocked: true,
|
||||
status: 400,
|
||||
code: server_constants.RIS_CODE_BANIP
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { blocked: false };
|
||||
}
|
||||
|
||||
_canExecuteFriendCommand(user, usernameOrig, usernameDest, cmd) {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
if (User.isAdmin(user.perm) || User.isManager(user.perm)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const allowedCommands = [
|
||||
shared_consts.FRIENDSCMD.SETFRIEND,
|
||||
shared_consts.FRIENDSCMD.SETHANDSHAKE
|
||||
];
|
||||
|
||||
if (allowedCommands.includes(cmd)) {
|
||||
return usernameOrig === user.username || usernameDest === user.username;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_hasAdminPermissions(user) {
|
||||
const { User } = require('../models/user');
|
||||
return User.isCollaboratore(user.perm);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserController;
|
||||
Reference in New Issue
Block a user