Files
freeplanet_serverside/src/services/UserService.js
2025-11-21 20:47:30 +01:00

467 lines
11 KiB
JavaScript

const { User } = require('../models/user');
const { MyGroup } = require('../models/mygroup');
const { Circuit } = require('../models/circuit');
const { SendNotif } = require('../models/sendnotif');
const { Province } = require('../models/province');
const tools = require('../tools/general');
const shared_consts = require('../tools/shared_nodejs');
const server_constants = require('../tools/server_constants');
const CronMod = require('../modules/CronMod');
class UserService {
/**
* Get user profile with friends
*/
async getUserProfile(idapp, username, usernameOrig, perm) {
try {
const profile = await User.getUserProfileByUsername(
idapp,
username,
usernameOrig,
false,
perm
);
const friends = await User.getFriendsByUsername(idapp, usernameOrig);
// Get extra info if viewing own profile
if (username === usernameOrig) {
const userProfile = await User.getExtraInfoByUsername(idapp, profile.username);
profile.profile = userProfile;
}
return {
user: profile,
friends
};
} catch (error) {
console.error('Error in getUserProfile:', error.message);
throw error;
}
}
/**
* Get user activities profile (public version)
*/
async getUserActivitiesProfile(idapp, username, usernameOrig, perm, isAuthenticated) {
try {
const profile = await User.getUserProfileByUsername(
idapp,
username,
usernameOrig,
false,
perm
);
const friends = await User.getFriendsByUsername(idapp, usernameOrig);
let userProfile;
if (isAuthenticated) {
userProfile = await User.getExtraInfoByUsername(idapp, profile.username);
} else {
userProfile = await User.getProfilePerActivitiesByUsername(idapp, profile.username);
// Hide sensitive data for non-authenticated users
profile.aportador_solidario = '';
profile.date_reg = '';
profile.email = '';
}
profile.profile = userProfile;
return {
user: profile,
friends
};
} catch (error) {
console.error('Error in getUserActivitiesProfile:', error.message);
throw error;
}
}
/**
* Update user balance and get notifications
*/
async updateUserBalance(idapp, username, circuitId, groupname, lastdr = '') {
try {
const userProfile = await User.getExtraInfoByUsername(idapp, username);
const arrRecNotif = await SendNotif.findAllNotifByUsernameIdAndIdApp(
username,
lastdr,
idapp,
shared_consts.LIMIT_NOTIF_FOR_USER,
shared_consts.QualiNotifs.OTHERS
);
const arrRecNotifCoins = await SendNotif.findAllNotifByUsernameIdAndIdApp(
username,
lastdr,
idapp,
shared_consts.LIMIT_NOTIFCOINS_FOR_USER,
shared_consts.QualiNotifs.CIRCUITS
);
return {
userprofile: userProfile,
arrrecnotif: arrRecNotif,
arrrecnotifcoins: arrRecNotifCoins
};
} catch (error) {
console.error('Error in updateUserBalance:', error.message);
throw error;
}
}
/**
* Get user's friends list
*/
async getUserFriends(idapp, username) {
try {
return await User.getFriendsByUsername(idapp, username);
} catch (error) {
console.error('Error in getUserFriends:', error.message);
throw error;
}
}
/**
* Get user's groups
*/
async getUserGroups(idapp, username, req) {
try {
return await MyGroup.getGroupsByUsername(idapp, username, req);
} catch (error) {
console.error('Error in getUserGroups:', error.message);
throw error;
}
}
/**
* Get user's circuits
*/
async getUserCircuits(idapp, username, user, nummovTodownload) {
try {
return await Circuit.getCircuitsByUsername(
idapp,
username,
user,
nummovTodownload
);
} catch (error) {
console.error('Error in getUserCircuits:', error.message);
throw error;
}
}
/**
* Execute friend command (add, remove, handshake, etc.)
*/
async executeFriendCommand(req, idapp, usernameOrig, usernameDest, cmd, value) {
try {
// Normalize usernames
const realUsernameOrig = await User.getRealUsernameByUsername(idapp, usernameOrig);
const realUsernameDest = await User.getRealUsernameByUsername(idapp, usernameDest);
return await User.setFriendsCmd(
req,
idapp,
realUsernameOrig,
realUsernameDest,
cmd,
value
);
} catch (error) {
console.error('Error in executeFriendCommand:', error.message);
throw error;
}
}
/**
* Execute group command
*/
async executeGroupCommand(idapp, usernameOrig, groupnameDest, cmd, value, usernameLogged) {
try {
return await User.setGroupsCmd(
idapp,
usernameOrig,
groupnameDest,
cmd,
value,
usernameLogged
);
} catch (error) {
console.error('Error in executeGroupCommand:', error.message);
throw error;
}
}
/**
* Execute circuit command
*/
async executeCircuitCommand(idapp, usernameOrig, circuitname, cmd, value, usernameLogged, extrarec) {
try {
const result = await User.setCircuitCmd(
idapp,
usernameOrig,
circuitname,
cmd,
value,
usernameLogged,
extrarec
);
// Mark notification as read if present
if (extrarec?.idnotif) {
await this.markNotificationAsRead(idapp, usernameOrig, extrarec.idnotif);
}
return result;
} catch (error) {
console.error('Error in executeCircuitCommand:', error.message);
throw error;
}
}
/**
* Mark notification as read
*/
async markNotificationAsRead(idapp, username, idnotif) {
try {
if (idnotif) {
await SendNotif.setNotifAsRead(idapp, username, idnotif);
}
} catch (error) {
console.error('Error in markNotificationAsRead:', error.message);
// Non-critical error, don't throw
}
}
/**
* Check if username exists
*/
async checkUsernameExists(idapp, username) {
try {
let user = await User.findByUsername(idapp, username, false, true);
if (!user) {
user = await User.findByUsernameTelegram(idapp, username, false, true);
}
return !!user;
} catch (error) {
console.error('Error in checkUsernameExists:', error.message);
throw error;
}
}
/**
* Set user permissions
*/
async setUserPermissions(userId, data) {
try {
await User.setPermissionsById(userId, data);
} catch (error) {
console.error('Error in setUserPermissions:', error.message);
throw error;
}
}
/**
* Execute database operation (admin only)
*/
async executeDbOperation(idapp, mydata, req, res) {
try {
const cronMod = new CronMod();
return await cronMod.eseguiDbOp(idapp, mydata, req, res);
} catch (error) {
console.error('Error in executeDbOperation:', error.message);
throw error;
}
}
/**
* Execute user-specific database operation
*/
async executeUserDbOperation(idapp, mydata, username) {
try {
let result = await User.DbOp(idapp, mydata);
// Handle specific operations
await this._handleSpecificDbOperations(mydata);
if (!result) {
result = {};
}
return await User.updateMyData(result, idapp, username);
} catch (error) {
console.error('Error in executeUserDbOperation:', error.message);
throw error;
}
}
/**
* Get map information (provinces with user counts)
*/
async getMapInformation(idapp) {
try {
const query = [
{
$lookup: {
from: 'users',
localField: 'prov',
foreignField: 'profile.resid_province',
as: 'users'
}
},
{
$addFields: {
userCount: { $size: '$users' }
}
},
{
$lookup: {
from: 'provinces',
localField: 'prov',
foreignField: 'prov',
as: 'provinceInfo'
}
},
{
$addFields: {
provinceDescr: { $arrayElemAt: ['$provinceInfo.descr', 0] }
}
},
{
$project: {
_id: 0,
province: '$prov',
descr: '$provinceDescr',
userCount: 1,
lat: 1,
long: 1
}
}
];
return await Province.aggregate(query);
} catch (error) {
console.error('Error in getMapInformation:', error.message);
throw error;
}
}
/**
* Send command to user
*/
async sendCommand(req, idapp, usernameOrig, usernameDest, cmd, value) {
try {
const realUsernameOrig = await User.getRealUsernameByUsername(idapp, usernameOrig);
const realUsernameDest = await User.getRealUsernameByUsername(idapp, usernameDest);
return await User.sendCmd(
req,
idapp,
realUsernameOrig,
realUsernameDest,
cmd,
value
);
} catch (error) {
console.error('Error in sendCommand:', error.message);
throw error;
}
}
/**
* Get user panel information (admin/manager view)
*/
async getUserPanelInfo(idapp, username) {
try {
const user = await User.findOne(
{ idapp, username },
{
username: 1,
name: 1,
surname: 1,
email: 1,
verified_by_aportador: 1,
aportador_solidario: 1,
lasttimeonline: 1,
deleted: 1,
sospeso: 1,
blocked: 1,
reported: 1,
username_who_report: 1,
date_report: 1,
profile: 1
}
).lean();
if (!user) {
throw new Error('Utente non trovato');
}
return user;
} catch (error) {
console.error('Error in getUserPanelInfo:', error.message);
throw error;
}
}
/**
* Handle specific database operations
* @private
*/
async _handleSpecificDbOperations(mydata) {
const operations = {
'saveStepTut': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.stepTutorial': mydata.value } }
),
'noNameSurname': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.noNameSurname': mydata.value } }
),
'telegram_verification_skipped': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.telegram_verification_skipped': mydata.value } }
),
'noCircuit': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.noCircuit': mydata.value } }
),
'noCircIta': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.noCircIta': mydata.value } }
),
'insert_circuito_ita': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.insert_circuito_ita': mydata.value } }
),
'noFoto': () => User.findOneAndUpdate(
{ _id: mydata._id },
{ $set: { 'profile.noFoto': mydata.value } }
),
'pwdLikeAdmin': () => User.setPwdComeQuellaDellAdmin(mydata),
'ripristinaPwdPrec': () => User.ripristinaPwdPrec(mydata)
};
const operation = operations[mydata.dbop];
if (operation) {
await operation();
}
}
}
module.exports = UserService;