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'
8
9export async function userToJSONLD(user: User) {
10 const userCacheResult = await redisCache.get('fediverse:user:base:' + user.id)
11 let userForFediverse: any
12 if (userCacheResult) {
13 userForFediverse = JSON.parse(userCacheResult)
14 } else {
15 const emojis = await getUserEmojis(user.id)
16 const userOptions = await getUserOptions(user.id)
17 let unprocessedAttachments = userOptions.find((elem) => elem.optionName === 'fediverse.public.attachment')
18 let alsoKnownAs: any[] = []
19 let alsoKnownAsList = userOptions.find((elem) => elem.optionName === 'fediverse.public.alsoKnownAs')
20 if (alsoKnownAsList?.optionValue) {
21 try {
22 const parsedValue = JSON.parse(alsoKnownAsList?.optionValue)
23 if (typeof parsedValue === 'string') {
24 for (let elem of parsedValue.split(',')) {
25 let url = new URL(elem)
26 alsoKnownAs.push(url.toString())
27 }
28 }
29 } catch (_) {}
30 }
31 if (user.bskyDid) {
32 alsoKnownAs.push(`at://${user.bskyDid}`)
33 }
34 let attachments: { type: string; name: string; value: string }[] = []
35 if (unprocessedAttachments) {
36 try {
37 const attachmentsArray: { name: string; value: string }[] = JSON.parse(unprocessedAttachments.optionValue)
38 attachments = attachmentsArray.map((elem) => {
39 return { ...elem, type: 'PropertyValue' }
40 })
41 } catch (error) {
42 logger.debug({
43 message: `Error parsing attachment for user ${user.url}`,
44 error: error
45 })
46 }
47 }
48 userForFediverse = {
49 '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'],
50 id: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}`,
51 type: 'Person',
52 attachment: attachments,
53 following: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/following`,
54 followers: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/followers`,
55 featured: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/featured`,
56 inbox: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/inbox`,
57 outbox: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}/outbox`,
58 preferredUsername: user.url.toLowerCase(),
59 name: user.name,
60 summary: user.description,
61 url: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}`,
62 manuallyApprovesFollowers: user.manuallyAcceptsFollows,
63 discoverable: true,
64 alsoKnownAs: alsoKnownAs,
65 published: user.createdAt,
66 tag: emojis.map((emoji: any) => emojiToAPTag(emoji)),
67 endpoints: {
68 sharedInbox: `${completeEnvironment.frontendUrl}/fediverse/sharedInbox`
69 },
70 ...(user.avatar
71 ? {
72 icon: {
73 type: 'Image',
74 mediaType: 'image/webp',
75 url: completeEnvironment.mediaUrl + user.avatar
76 }
77 }
78 : undefined),
79 ...(user.headerImage
80 ? {
81 image: {
82 type: 'Image',
83 mediaType: 'image/webp',
84 url: completeEnvironment.mediaUrl + user.headerImage
85 }
86 }
87 : undefined),
88 publicKey: {
89 id: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}#main-key`,
90 owner: `${completeEnvironment.frontendUrl}/fediverse/blog/${user.url.toLowerCase()}`,
91 publicKeyPem: user.publicKey
92 }
93 }
94
95 if (user.userMigratedTo) {
96 userForFediverse.migratedTo = user.userMigratedTo
97 }
98 redisCache.set('fediverse:user:base:' + user.id, JSON.stringify(userForFediverse), 'EX', 300)
99 }
100 return userForFediverse
101}