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