unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
fork
Configure Feed
Select the types of activity you want to include in your feed.
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}