-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
External wallet SOCIAL NETWORKS ( METAMASK ) (#369)
### PR Description: Hello team, This PR introduces a comprehensive system for external users, specifically those utilizing Metamask wallets. With this enhancement, users can seamlessly connect their Metamask wallets to our application and link their social network accounts, including Facebook, YouTube, LinkedIn, TikTok, and Twitter. ### Changes Made: - Metamask Integration: 1- Added functionality to allow users to connect their Metamask wallets to our application. 2- Implemented a smooth authentication process for Metamask users. - Social Network Account Linking: 1-Users with connected Metamask wallets can now link their social network accounts (Facebook, YouTube, LinkedIn, TikTok, Twitter) within our application. - New Routes and Controllers for External Users: 1-Created new routes and controllers specifically designed for external users. ### Notes for Reviewers: Please review the changes made in this PR to confirm that the Metamask integration and the introduction of the external user system have been correctly implemented. Test the new routes and controllers to ensure they seamlessly handle tasks for external users, such as campaign creation and application processes. Your attention and contributions are highly appreciated. Feel free to provide any feedback or suggestions you may have. Best regards, Louay HICHRI
- Loading branch information
Showing
10 changed files
with
389 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
const { responseHandler } = require('../helpers/response-handler') | ||
const makeResponseData = responseHandler.makeResponseData | ||
const makeResponseError = responseHandler.makeResponseError | ||
const { | ||
GoogleProfile, | ||
LinkedinProfile, | ||
TwitterProfile, | ||
FbPage, | ||
TikTokProfile, | ||
UserExternalWallet | ||
} = require('../model/index') | ||
|
||
|
||
exports.createUserFromExternalWallet = async (req, res) =>{ | ||
try { | ||
const userExist = await UserExternalWallet.findOne({walletId: req.body.wallet}); | ||
if(!userExist) { | ||
const workerId = process.pid | ||
const currentDate = new Date().getTime(); | ||
const uniqueId = parseInt(workerId + currentDate); | ||
const user = new UserExternalWallet({UserId: uniqueId,walletId: req.body.wallet}); | ||
const savedUser = await user.save(); | ||
return makeResponseData(res, 200, 'User created successfully', savedUser); | ||
} else return makeResponseData(res, 200, 'User signed In successfully', userExist); | ||
|
||
} catch(err){ | ||
return makeResponseError(res, 500, err.message ? err.message : err.error); | ||
} | ||
} | ||
|
||
|
||
exports.externalSocialAccounts = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}); | ||
|
||
let UserId = user.UserId; | ||
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) => | ||
item?.pages.map((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') | ||
} | ||
return makeResponseData(res, 200, 'success', networks) | ||
} catch (err) { | ||
return makeResponseError( | ||
res, | ||
500, | ||
err.message ? err.message : err.error | ||
) | ||
} | ||
} | ||
|
||
exports.externalDeleteTiktokChannel = async (req,res) => { | ||
try { | ||
let user = await UserExternalWallet.findOne({walletId: req.address}) | ||
|
||
let tiktokProfiles = await TikTokProfile.find({ userId: user.UserId }) | ||
|
||
if (tiktokProfiles.length === 0) | ||
return makeResponseError(res, 204, 'No channel found') | ||
else { | ||
await TikTokProfile.deleteMany({ userId: user.UserId }) | ||
return makeResponseData(res, 200, 'deleted successfully') | ||
} | ||
} catch (err) { | ||
return makeResponseError( | ||
res, | ||
500, | ||
err.message ? err.message : err.error | ||
) | ||
} | ||
} | ||
|
||
exports.externalDeleteTiktokChannels = async (req, res) => { | ||
try { | ||
let user = await UserExternalWallet.findOne({walletId: req.address}) | ||
|
||
let tiktokProfiles = await TikTokProfile.find({ userId: user.UserId }) | ||
|
||
if (tiktokProfiles.length === 0) | ||
return makeResponseError(res, 204, 'No channel found') | ||
else { | ||
await TikTokProfile.deleteMany({ userId: user.UserId }) | ||
return makeResponseData(res, 200, 'deleted successfully') | ||
} | ||
} catch (err) { | ||
return makeResponseError( | ||
res, | ||
500, | ||
err.message ? err.message : err.error | ||
) | ||
} | ||
} | ||
|
||
exports.externalDeleteGoogleChannel = async (req, res) => { | ||
try { | ||
const UserId = await UserExternalWallet.findOne({walletId: req.address}) | ||
let _id = req.params.id | ||
let googleProfile = await GoogleProfile.findOne({ _id }).lean() | ||
if (googleProfile?.UserId !== 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.externalDeleteGoogleChannels = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
const result = await GoogleProfile.deleteMany({ UserId: user.UserId }) | ||
if (result.deletedCount === 0) { | ||
return makeResponseError(res, 204, 'No channel found') | ||
} else { | ||
return makeResponseData(res, 200, 'deleted successfully') | ||
} | ||
} catch (err) { | ||
console.log({err}) | ||
return makeResponseError( | ||
res, | ||
500, | ||
err.message ? err.message : err.error | ||
) | ||
} | ||
} | ||
|
||
exports.externalDeleteFacebookChannels = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
const result = await FbPage.deleteMany({ UserId: user.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.externalDeleteFacebookChannel = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
let _id = req.params.id | ||
let facebookProfile = await FbPage.findOne({ _id }) | ||
if (facebookProfile?.UserId !== user.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.externalDeleteLinkedinChannels = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
const result = await LinkedinProfile.deleteMany({ userId: user.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.externalDeleteLinkedinChannel = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
let { organization, linkedinId } = req.params | ||
let linkedinProfile = await LinkedinProfile.findOne( | ||
{ userId: user.UserId, linkedinId }, | ||
{ pages: 1 } | ||
).lean() | ||
if (!linkedinProfile) return makeResponseError(res, 401, 'unauthorized') | ||
if (linkedinProfile.pages.length === 1) { | ||
await LinkedinProfile.deleteOne({ userId: user.UserId, linkedinId }) | ||
} else { | ||
await LinkedinProfile.updateOne( | ||
{ userId: user.UserId, linkedinId }, | ||
{ $pull: { pages: { organization } } } | ||
) | ||
} | ||
return makeResponseData(res, 200, 'deleted successfully') | ||
} catch (err) { | ||
return makeResponseError( | ||
res, | ||
500, | ||
err.message ? err.message : err.error | ||
) | ||
} | ||
} | ||
|
||
|
||
exports.externalDeleteTwitterChannels = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
const result = await TwitterProfile.deleteMany({ UserId: user.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.externalDeleteTwitterChannel = async (req, res) => { | ||
try { | ||
const user = await UserExternalWallet.findOne({walletId: req.address}) | ||
let _id = req.params.id | ||
let twitterProfile = await TwitterProfile.findOne({ _id }) | ||
if (twitterProfile?.UserId !== user.UserId) | ||
return makeResponseError(res, 401, 'unauthorized') | ||
else { | ||
await TwitterProfile.deleteOne({ UserId: user.UserId }) | ||
return makeResponseData(res, 200, 'deleted successfully') | ||
} | ||
} catch (err) { | ||
return makeResponseError( | ||
res, | ||
500, | ||
err.message ? err.message : err.error | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const verifySignature = require('./../web3/verifySignature') | ||
|
||
const verifySignatureMiddleware = (req, res, next) => { | ||
const signature = req.header('X-Signature'); | ||
const address = req.header('X-Address'); | ||
const message = req.header('X-Message') | ||
if (verifySignature(message, signature, address)) { | ||
req.address = address; | ||
return next(); | ||
} else { | ||
return res.status(401).json({ message: 'Invalid signature' }); | ||
} | ||
} | ||
|
||
module.exports = verifySignatureMiddleware |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.