unoffical wafrn mirror wafrn.net
atproto social-network activitypub
fork

Configure Feed

Select the types of activity you want to include in your feed.

at angular21 139 lines 4.6 kB view raw
1import { Application, Response } from 'express' 2import { authenticateToken } from '../utils/authenticateToken.js' 3 4import { Notification, Post, User, UserLikesPostRelations } from '../models/index.js' 5import { logger } from '../utils/logger.js' 6import { likePostRemote } from '../utils/activitypub/likePost.js' 7import AuthorizedRequest from '../interfaces/authorizedRequest.js' 8import { getUserOptions } from '../utils/cacheGetters/getUserOptions.js' 9import { getAtProtoSession } from '../atproto/utils/getAtProtoSession.js' 10import { Model } from 'sequelize' 11import { forceUpdateLastActive } from '../utils/forceUpdateLastActive.js' 12import { createNotification } from '../utils/pushNotifications.js' 13 14export default function likeRoutes(app: Application) { 15 app.post('/api/like', authenticateToken, forceUpdateLastActive, async (req: AuthorizedRequest, res: Response) => { 16 let success = false 17 const userId = req.jwtData?.userId 18 const postId = req.body.postId 19 let bskyUri = undefined 20 const userPromise = User.findOne({ 21 where: { 22 id: userId 23 } 24 }) 25 const postPromise = Post.findOne({ 26 where: { 27 id: postId 28 } 29 }) 30 const likePromise = UserLikesPostRelations.findOne({ 31 where: { 32 userId: userId, 33 postId: postId 34 } 35 }) 36 try { 37 await Promise.all([userPromise, postPromise, likePromise]) 38 const user = await userPromise 39 const post = await postPromise 40 const like = await likePromise 41 if (userId && user && post && !like) { 42 const options = await getUserOptions(user.id) 43 const userFederatesWithThreads = options.filter( 44 (elem) => elem.optionName === 'wafrn.federateWithThreads' && elem.optionValue === 'true' 45 ) 46 if (userFederatesWithThreads.length === 0) { 47 const userPosterOfPostToBeLiked = await User.findByPk(post.userId) 48 if (userPosterOfPostToBeLiked?.url.toLowerCase().endsWith('.threads.net')) { 49 res.status(403) 50 res.send({ error: true, message: 'You do not have threads federation enabled' }) 51 return 52 } 53 } 54 if (!user.enableBsky && post.bskyUri) { 55 const userPosterOfPostToBeLiked = (await User.findByPk(post.userId)) as User 56 if (userPosterOfPostToBeLiked.isRemoteUser) { 57 res.status(403) 58 res.send({ error: true, message: 'You do not have bluesky federation enabled' }) 59 return 60 } 61 } else { 62 if (user.enableBsky && post.bskyUri) { 63 try { 64 const agent = await getAtProtoSession(user) 65 const { uri } = await agent.like(post.bskyUri, post.bskyCid as string) 66 bskyUri = uri 67 } catch (error) { 68 logger.debug({ 69 message: `Error while sending a bluesky post`, 70 postId: post.id, 71 user: user.url, 72 error: error 73 }) 74 } 75 } 76 } 77 const likedPost = await UserLikesPostRelations.create({ 78 userId: userId, 79 postId: postId, 80 bskyPath: bskyUri 81 }) 82 await likedPost.save() 83 await createNotification( 84 { 85 notificationType: 'LIKE', 86 notifiedUserId: post.userId, 87 userId: userId, 88 postId: postId 89 }, 90 { 91 postContent: post?.content, 92 userUrl: user.url 93 } 94 ) 95 success = true 96 likePostRemote(likedPost) 97 } 98 if (like) { 99 success = true 100 } 101 } catch (error) { 102 logger.debug(error) 103 } 104 res.send({ success: success }) 105 }) 106 107 app.post('/api/unlike', authenticateToken, forceUpdateLastActive, async (req: AuthorizedRequest, res: Response) => { 108 let success = false 109 const userId = req.jwtData?.userId 110 const postId = req.body.postId 111 const like = await UserLikesPostRelations.findOne({ 112 where: { 113 userId: userId, 114 postId: postId 115 } 116 }) 117 await Notification.destroy({ 118 where: { 119 notificationType: 'LIKE', 120 userId: userId, 121 postId: postId 122 } 123 }) 124 if (like && like.bskyPath) { 125 const user = await User.findByPk(userId) 126 if (user && user.enableBsky) { 127 const agent = await getAtProtoSession(user) 128 await agent.deleteLike(like.bskyPath) 129 } 130 } 131 if (like) { 132 likePostRemote(like, true) 133 await like.destroy() 134 success = true 135 } 136 137 res.send({ success: success }) 138 }) 139}