From 0ac8658becae958e54b2a28b3c5eab5198bdb993 Mon Sep 17 00:00:00 2001 From: HamdiBenK Date: Wed, 14 Jun 2023 15:25:00 +0100 Subject: [PATCH 1/4] refactor getPromApplyStats in oracles.js & social media functions in profile --- conf/config.js | 4 + controllers/profile.controller.js | 244 ++++++++++-------------------- manager/oracles.js | 29 +++- model/index.js | 2 +- web3/campaigns.js | 2 +- 5 files changed, 113 insertions(+), 168 deletions(-) diff --git a/conf/config.js b/conf/config.js index 8cd20278d..80b4a0719 100644 --- a/conf/config.js +++ b/conf/config.js @@ -1,5 +1,9 @@ +require('dotenv').config({ + path: `.env.${process.env.NODE_ENV}` + }); + exports.mongoConnection = () => process.env.MONGOURI exports.payementRequest = async (payment) => { return { diff --git a/controllers/profile.controller.js b/controllers/profile.controller.js index 0cd95decf..3259b8fd8 100644 --- a/controllers/profile.controller.js +++ b/controllers/profile.controller.js @@ -12,7 +12,6 @@ const { FbPage, TikTokProfile, } = require('../model/index') -const axios = require('axios') const contentDisposition = require('content-disposition') @@ -107,6 +106,17 @@ module.exports.uploadImageProfile = multer({ module.exports.uploadUserLegal = multer({ storage: storageUserLegal }).single( 'file' ) +const findTwitterProfile= (queryField,projection={}) => { + return new Promise((resolve, reject) => { + try { + const profile = TwitterProfile.findOne(queryField,projection).lean(); + resolve(profile); + } catch (err) { + reject({ message: err.message }); + } + }); + }; + exports.account = async (req, res) => { try { @@ -301,137 +311,84 @@ exports.FindUserLegalProfile = async (req, res) => { ) } } -exports.deleteTwitterChannels = async (req, res) => { +const deleteChannel = async (model, condition, res) => { try { - const UserId = req.user._id - const result = await TwitterProfile.deleteMany({ UserId }) - if (result.deletedCount === 0) { - return makeResponseError(res, 204, 'No channel found') - } else { - return makeResponseData(res, 200, 'deleted successfully') - } + const result = await model.deleteMany(condition); + if (result.deletedCount === 0) { + return makeResponseError(res, 204, 'No channel found'); + } else { + return makeResponseData(res, 200, 'deleted successfully'); + } } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) + return makeResponseError(res, 500, err.message ? err.message : err.error); } + }; + + exports.deleteTwitterChannels = async (req, res) => { + const UserId = req.user._id; + return deleteChannel(TwitterProfile, { UserId }, res); + }; + + exports.deleteGoogleChannels = async (req, res) => { + const UserId = req.user._id; + return deleteChannel(GoogleProfile, { UserId }, res); + }; + + exports.deleteFacebookChannels = async (req, res) => { + const UserId = req.user._id; + return deleteChannel(FbPage, { UserId }, res); + }; + + exports.deleteLinkedinChannels = async (req, res) => { + const userId = req.user._id + return deleteChannel(LinkedinProfile, { userId }, res); } -exports.deleteTwitterChannel = async (req, res) => { - try { - let UserId = req.user._id - let _id = req.params.id - let twitterProfile = await TwitterProfile.findOne({ _id }) - if (twitterProfile?.UserId !== UserId) - return makeResponseError(res, 401, 'unauthorized') - else { - await TwitterProfile.deleteOne({ UserId }) - return makeResponseData(res, 200, 'deleted successfully') - } - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } +exports.deleteTiktokChannels = async (req, res) => { + let userId = req.user._id + return deleteChannel(TikTokProfile, { userId }, res); } + -exports.deleteGoogleChannels = async (req, res) => { +const deleteChannelById = async (model, condition, unauthorizedErrorMessage, res,UserId) => { try { - const UserId = req.user._id - const result = await GoogleProfile.deleteMany({ UserId }) - if (result.deletedCount === 0) { - return makeResponseError(res, 204, 'No channel found') - } else { - return makeResponseData(res, 200, 'deleted successfully') - } + const channel = await model.findOne(condition,{UserId:1}).lean(); + if (!channel) { + return makeResponseError(res, 204, 'No channel found'); + } else if (channel.UserId !== UserId) { + return makeResponseError(res, 401, unauthorizedErrorMessage); + } else { + await model.deleteOne(condition); + return makeResponseData(res, 200, 'deleted successfully'); + } } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) + return makeResponseError(res, 500, err.message ? err.message : err.error); } -} + }; -exports.deleteGoogleChannel = async (req, res) => { - try { - let UserId = req.user._id - let _id = req.params.id - let googleProfile = await GoogleProfile.findOne({ _id }).lean() - if (googleProfile?.UserId !== UserId) - return makeResponseError(res, 401, 'unauthorized') - else { - await GoogleProfile.deleteOne({ _id }) - return makeResponseData(res, 200, 'deleted successfully') - } - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } -} + exports.deleteTwitterChannel = async (req, res) => { + const _id = req.params.id; + return deleteChannelById(TwitterProfile, {_id}, 'unauthorized', res,req.user._id); + }; + -exports.deleteFacebookChannels = async (req, res) => { - try { - const UserId = req.user._id - const result = await FbPage.deleteMany({ UserId }) - if (result.deletedCount === 0) { - return makeResponseError(res, 204, 'No channel found') - } else { - return makeResponseData(res, 200, 'deleted successfully') - } - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } -} + exports.deleteGoogleChannel = async (req, res) => { + const _id = req.params.id; + return deleteChannelById(GoogleProfile, {_id}, 'unauthorized', res,req.user._id); + }; -exports.deleteFacebookChannel = async (req, res) => { - try { - let UserId = req.user._id - let _id = req.params.id - let facebookProfile = await FbPage.findOne({ _id }) - if (facebookProfile?.UserId !== UserId) - return makeResponseError(res, 401, 'unauthorized') - else { - await FbPage.deleteOne({ _id }) - return makeResponseData(res, 200, 'deleted successfully') - } - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } -} -exports.deleteLinkedinChannels = async (req, res) => { - try { - const userId = req.user._id - const result = await LinkedinProfile.deleteMany({ userId }) - if (result.deletedCount === 0) { - return makeResponseError(res, 204, 'No channel found') - } else { - return makeResponseData(res, 200, 'deleted successfully') - } - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } + exports.deleteFacebookChannel = async (req, res) => { + const _id = req.params.id; + return deleteChannelById(FbPage, { _id}, 'unauthorized', res,req.user._id); + } + + exports.deleteTiktokChannel = async (req, res) => { + let userId = +req.user._id + return deleteChannelById(TikTokProfile, { userId}, 'unauthorized',res, userId); } + + exports.deleteLinkedinChannel = async (req, res) => { try { let userId = req.user._id @@ -459,57 +416,19 @@ exports.deleteLinkedinChannel = async (req, res) => { } } -exports.deleteTiktokChannel = async (req, res) => { - try { - let userId = +req.user._id - let tiktokProfile = await TikTokProfile.findOneAndDelete({ userId }) - if (!tiktokProfile) return makeResponseError(res, 401, 'unauthorized') - return makeResponseData(res, 200, 'deleted successfully') - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } -} - -exports.deleteTiktokChannels = async (req, res) => { - try { - let userId = req.user._id - let tiktokProfiles = await TikTokProfile.find({ userId }) - if (tiktokProfiles.length === 0) - return makeResponseError(res, 204, 'No channel found') - else { - await TikTokProfile.deleteMany({ userId }) - return makeResponseData(res, 200, 'deleted successfully') - } - } catch (err) { - return makeResponseError( - res, - 500, - err.message ? err.message : err.error - ) - } -} exports.UserInterstes = async (req, res) => { try { - const userId = req.user._id - let allInterests = [] + const {_id :userId} = req.user const result = await Interests.find({ userId }) if (!result.length) { return makeResponseError(res, 204, 'No interest found') - } else if (result.length >= 2) { - result.forEach((item, index) => { - allInterests = [...allInterests, ...item.interests] - }) - } else { - allInterests = [...result[0].interests] - } + } + + const allInterests = results.flatMap(result => result.interests); return makeResponseData(res, 200, 'success', allInterests) } catch (err) { @@ -961,12 +880,7 @@ module.exports.verifyLink = async (req, response) => { break case '4': - var twitterProfile = await TwitterProfile.findOne( - { - UserId: userId, - }, - { access_token_key: 1, access_token_secret: 1 } - ).lean() + var twitterProfile =await findTwitterProfile({UserId: userId},{access_token_key: 1, access_token_secret: 1}) if (twitterProfile) { linked = true res = await verifyTwitter(twitterProfile, userId, idPost) diff --git a/manager/oracles.js b/manager/oracles.js index ec1bf1971..bf8615b57 100644 --- a/manager/oracles.js +++ b/manager/oracles.js @@ -492,7 +492,7 @@ exports.tiktokAbos = async (userId, access_token = null) => { console.error('tiktokAbos', err.message ? err.message : err.error) } } - +/* exports.getPromApplyStats = async ( oracles, link, @@ -526,8 +526,35 @@ exports.getPromApplyStats = async ( } catch (err) { console.error('getPromApplyStats', err) } +}*/ + +const socialNetworkStrategies = { + facebook: async ({ link }) => await facebook(link.idUser, link.idPost), + twitter: async ({ link }) => await twitter(link.idUser, link.idPost), + youtube: async ({ link }) => await youtube(link.idPost), + instagram: async ({ link, id }) => await instagram(id, link), + linkedin: async ({ link, linkedinProfile }) => await linkedin(link.idUser, link.idPost, link.typeURL, linkedinProfile), + tiktok: async ({ link, tiktokProfile }) => await tiktok(tiktokProfile, link.idPost), } +exports.getPromApplyStats = async ( + oracles, + link, + id, + linkedinProfile = null, + tiktokProfile = null +) => { + try { + let socialOracle = await socialNetworkStrategies[oracles]({ link, id, linkedinProfile, tiktokProfile }); + + delete socialOracle?.date; + return socialOracle; + } catch (err) { + console.error('getPromApplyStats', err); + } +}; + + const facebook = async (pageName, idPost) => { try { var page = await FbPage.findOne({ username: pageName }) diff --git a/model/index.js b/model/index.js index 267b35c00..0736dfd36 100644 --- a/model/index.js +++ b/model/index.js @@ -36,5 +36,5 @@ module.exports = { FbPage, Wallet, CustomToken, - WalletUserNode + WalletUserNode, } \ No newline at end of file diff --git a/web3/campaigns.js b/web3/campaigns.js index 773adcf4a..90e7bfc4b 100644 --- a/web3/campaigns.js +++ b/web3/campaigns.js @@ -1104,7 +1104,7 @@ exports.getGains = async (idProm, credentials, tronWeb, token = false) => { exports.filterLinks = (req, id_wallet) => { - let {oracles,status,campaign} = req.query; + let {oracles,status,campaign,state} = req.query; var query = { id_wallet } if (campaign && state === 'part') { From ea901878bf48803a2c248a9bc8cfd7625391c9ed Mon Sep 17 00:00:00 2001 From: HamdiBenK Date: Wed, 14 Jun 2023 15:29:19 +0100 Subject: [PATCH 2/4] refactor getPromApplyStats in oracles.js & social media functions in profile --- manager/oracles.js | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/manager/oracles.js b/manager/oracles.js index bf8615b57..caa4bd411 100644 --- a/manager/oracles.js +++ b/manager/oracles.js @@ -492,41 +492,6 @@ exports.tiktokAbos = async (userId, access_token = null) => { console.error('tiktokAbos', err.message ? err.message : err.error) } } -/* -exports.getPromApplyStats = async ( - oracles, - link, - id, - linkedinProfile = null, - tiktokProfile = null -) => { - try { - let socialOracle = {} - if (oracles === 'facebook') - socialOracle = await facebook(link.idUser, link.idPost) - else if (oracles === 'twitter') - socialOracle = await twitter(link.idUser, link.idPost) - else if (oracles === 'youtube') - socialOracle = await youtube(link.idPost) - else if (oracles === 'instagram') - socialOracle = await instagram(id, link) - else if (oracles === 'linkedin') { - socialOracle = await linkedin( - link.idUser, - link.idPost, - link.typeURL, - linkedinProfile - ) - } else if (oracles === 'tiktok') { - socialOracle = await tiktok(tiktokProfile, link.idPost) - } - - delete socialOracle?.date - return socialOracle - } catch (err) { - console.error('getPromApplyStats', err) - } -}*/ const socialNetworkStrategies = { facebook: async ({ link }) => await facebook(link.idUser, link.idPost), From 612874f52a3bb9258bed32dbbbb7923a58da3298 Mon Sep 17 00:00:00 2001 From: HamdiBenK Date: Wed, 14 Jun 2023 16:39:12 +0100 Subject: [PATCH 3/4] optimize async call & refactor socialAccounts --- controllers/profile.controller.js | 99 +++++++++++++++++++------------ 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/controllers/profile.controller.js b/controllers/profile.controller.js index 3259b8fd8..1146ce7a4 100644 --- a/controllers/profile.controller.js +++ b/controllers/profile.controller.js @@ -106,7 +106,7 @@ module.exports.uploadImageProfile = multer({ module.exports.uploadUserLegal = multer({ storage: storageUserLegal }).single( 'file' ) -const findTwitterProfile= (queryField,projection={}) => { +/*const TwitterProfile.findOne= (queryField,projection={}) => { return new Promise((resolve, reject) => { try { const profile = TwitterProfile.findOne(queryField,projection).lean(); @@ -115,7 +115,7 @@ const findTwitterProfile= (queryField,projection={}) => { reject({ message: err.message }); } }); - }; + };*/ exports.account = async (req, res) => { @@ -478,53 +478,74 @@ exports.tiktokApiAbos = async (req, res) => { } } + +const networkModelMap = { + google: { + model: GoogleProfile, + excludeFields: { accessToken: 0, refreshToken: 0 } + }, + twitter: { + model: TwitterProfile, + excludeFields: { _raw: 0, access_token_key: 0, access_token_secret: 0 } + }, + facebook: { + model: FbPage, + excludeFields: { token: 0 } + }, + linkedin: { + model: LinkedinProfile, + excludeFields: {accessToken : 0 , refreshToken : 0} + }, + tikTok: { + model: TikTokProfile, + excludeFields: { accessToken: 0, refreshToken: 0 } + } +}; + exports.socialAccounts = async (req, res) => { try { - let UserId = req.user._id - let networks = {} - let [channelsGoogle, channelsTwitter] = await Promise.all([ - GoogleProfile.find({ UserId }, { accessToken: 0, refreshToken: 0 }), - TwitterProfile.find( - { UserId }, - { _raw: 0, access_token_key: 0, access_token_secret: 0 } - ), - ]) - let channelsFacebook = await FbPage.find({ UserId }, { token: 0 }) - let channelsLinkedin = await LinkedinProfile.find({ userId: UserId }) - let channelsTiktok = await TikTokProfile.find( - { userId: UserId }, - { accessToken: 0, refreshToken: 0 } - ) - networks.google = channelsGoogle - networks.twitter = channelsTwitter - networks.facebook = channelsFacebook - networks.linkedin = channelsLinkedin?.flatMap((item) => + const UserId = req.user._id; + let networks = {}; + + // Generate the database queries. + const queries = Object.keys(networkModelMap).map(network => { + const { model, excludeFields } = networkModelMap[network]; + + const query = network === 'linkedin' || network === 'tikTok' && { userId: UserId } || { UserId }; + + return model.find(query, excludeFields); + }); + + // Run the queries concurrently. + const channels = await Promise.all(queries); + + // Assign the results to the appropriate properties in the networks object. + Object.keys(networkModelMap).forEach((network, i) => { + networks[network] = channels[i]; + }); + + // Process the LinkedIn channels separately. + networks.linkedin = networks.linkedin?.flatMap((item) => item?.pages.map((elem) => { - elem = elem.toJSON() - elem.linkedinId = item.linkedinId - return elem + elem = elem.toJSON(); + elem.linkedinId = item.linkedinId; + return elem; }) - ) + ); - networks.tikTok = channelsTiktok || [] - if ( - !channelsGoogle?.length && - !channelsLinkedin?.length && - !channelsTwitter?.length && - !channelsFacebook?.length && - !channelsTiktok?.length - ) { - return makeResponseError(res, 204, 'No channel found') + // Check if all network channels are empty. + if (Object.values(networks).every(networkChannels => !networkChannels?.length)) { + return makeResponseError(res, 204, 'No channel found'); } - return makeResponseData(res, 200, 'success', networks) + return makeResponseData(res, 200, 'success', networks); } catch (err) { return makeResponseError( res, 500, err.message ? err.message : err.error - ) + ); } -} +}; module.exports.checkOnBoarding = async (req, res) => { try { @@ -871,7 +892,7 @@ module.exports.verifyLink = async (req, response) => { { UserId: userId }, { instagram_id: { $exists: true } }, ], - }) + }).lean() if (page) { linked = true res = await verifyInsta(userId, idPost) @@ -880,7 +901,7 @@ module.exports.verifyLink = async (req, response) => { break case '4': - var twitterProfile =await findTwitterProfile({UserId: userId},{access_token_key: 1, access_token_secret: 1}) + var twitterProfile =await TwitterProfile.findOne({UserId: userId},{access_token_key: 1, access_token_secret: 1}).lean() if (twitterProfile) { linked = true res = await verifyTwitter(twitterProfile, userId, idPost) From af1a5d2e3613b1795df22f949e950a3ed5d553cd Mon Sep 17 00:00:00 2001 From: HamdiBenK Date: Wed, 14 Jun 2023 17:25:56 +0100 Subject: [PATCH 4/4] optimize async call & refactor checkOnBoarding --- controllers/profile.controller.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/controllers/profile.controller.js b/controllers/profile.controller.js index 1146ce7a4..eeac74ab0 100644 --- a/controllers/profile.controller.js +++ b/controllers/profile.controller.js @@ -549,25 +549,18 @@ exports.socialAccounts = async (req, res) => { module.exports.checkOnBoarding = async (req, res) => { try { - const _id = req.user._id + const {_id} = req.user; const userUpdated = User.updateOne( { _id }, { $set: { onBoarding: true } } ) - const firstNotif = notificationManager(_id, 'buy_some_gas', { - action: 'buy_some_gas', - }) - const secondNotif = notificationManager(_id, 'invite_friends', { - action: 'Invite your friends', - }) - const thirdNotif = notificationManager(_id, 'join_on_social', { - action: 'Join us on social', - }) + + const notifications = ['buy_some_gas', 'invite_friends', 'join_on_social'].map(notifType => + notificationManager(_id, notifType, { action: notifType !=='buy_some_gas' && notifType.replace(/_/g, ' ') || notifType})); + await Promise.allSettled([ userUpdated, - firstNotif, - secondNotif, - thirdNotif, + ...notifications ]) return makeResponseData(res, 201, 'onBoarding updated', true) } catch (err) {