unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
1import { completeEnvironment } from '../backendOptions.js'
2import { User } from '../../models/index.js'
3import { getUserEmojis } from '../cacheGetters/getUserEmojis.js'
4import { getUserOptions } from '../cacheGetters/getUserOptions.js'
5import { logger } from '../logger.js'
6import { redisCache } from '../redis.js'
7import { emojiToAPTag } from './emojiToAPTag.js'
8import { existsSync } from 'fs'
9
10export async function userToJSONLD(user: User) {
11 // test remove cache
12 const userCacheResult = await redisCache.get('fediverse:user:base:' + user.id)
13 let userForFediverse: any
14 if (userCacheResult) {
15 userForFediverse = JSON.parse(userCacheResult)
16 } else {
17 let emojisPromise = getUserEmojis(user.id)
18 let userOptionsPromise = getUserOptions(user.id)
19 await Promise.all([emojisPromise, userOptionsPromise])
20 const emojis = await emojisPromise
21 const userOptions = await userOptionsPromise
22 let unprocessedAttachments = userOptions.find((elem) => elem.optionName === 'fediverse.public.attachment')
23 let alsoKnownAs: any[] = []
24 let alsoKnownAsList = userOptions.find((elem) => elem.optionName === 'fediverse.public.alsoKnownAs')
25 if (alsoKnownAsList?.optionValue) {
26 try {
27 const parsedValue = alsoKnownAsList?.optionValue
28 if (typeof parsedValue === 'string') {
29 for (let elem of parsedValue.split(',')) {
30 let url = new URL(elem.replaceAll('"', ''))
31 alsoKnownAs.push(url.toString())
32 }
33 }
34 } catch (error) {
35 logger.trace({
36 message: 'Error parsing alsoknownas',
37 error: error,
38 value: alsoKnownAsList?.optionValue,
39 user: user.url
40 })
41 }
42 }
43 if (user.bskyDid) {
44 alsoKnownAs.push(`at://${user.bskyDid}`)
45 }
46 let attachments: { type: string; name: string; value: string }[] = []
47 if (unprocessedAttachments) {
48 try {
49 const attachmentsArray: { name: string; value: string }[] = JSON.parse(unprocessedAttachments.optionValue)
50 attachments = attachmentsArray.map((elem) => {
51 return { ...elem, type: 'PropertyValue' }
52 })
53 } catch (error) {
54 logger.debug({
55 message: `Error parsing attachment for user ${user.url}`,
56 error: error
57 })
58 }
59 }
60 let customCSS: string | undefined = undefined
61 if (existsSync(`uploads/themes/${user.id}.css`)) {
62 customCSS = new URL(`/api/uploads/themes/${user.id}.css`, completeEnvironment.frontendUrl).href
63 }
64 userForFediverse = {
65 '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'],
66 id: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}`,
67 type: user.isBot ? 'Service' : 'Person',
68 attachment: attachments,
69 following: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/following`,
70 followers: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/followers`,
71 featured: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/featured`,
72 inbox: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/inbox`,
73 outbox: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/outbox`,
74 preferredUsername: user.url.toLowerCase(),
75 name: user.name,
76 summary: user.description,
77 ...(!!user.userMigratedTo ? {
78 movedTo: user.userMigratedTo
79 } : {}),
80 ...(customCSS ? {
81 _wafrn_customCSS: customCSS
82 } : {}),
83 url: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}`,
84 manuallyApprovesFollowers: user.manuallyAcceptsFollows,
85 discoverable: true,
86 alsoKnownAs: alsoKnownAs,
87 published: user.createdAt,
88 tag: emojis.map((emoji: any) => emojiToAPTag(emoji)),
89 endpoints: {
90 sharedInbox: `${completeEnvironment.frontendUrl}/fediverse/sharedInbox`
91 },
92 ...(user.avatar
93 ? {
94 icon: {
95 type: 'Image',
96 mediaType: 'image/webp',
97 url: completeEnvironment.mediaUrl + user.avatar
98 }
99 }
100 : undefined),
101 ...(user.headerImage
102 ? {
103 image: {
104 type: 'Image',
105 mediaType: 'image/webp',
106 url: completeEnvironment.mediaUrl + user.headerImage
107 }
108 }
109 : undefined),
110 publicKey: {
111 id: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}#main-key`,
112 owner: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}`,
113 publicKeyPem: user.publicKey
114 }
115 }
116
117 if (user.userMigratedTo) {
118 userForFediverse.migratedTo = user.userMigratedTo
119 }
120 await redisCache.set('fediverse:user:base:' + user.id, JSON.stringify(userForFediverse), 'EX', 60)
121 }
122 return userForFediverse
123}