diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-05-05 09:07:26 -0400 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-05-08 11:05:14 -0400 |
| commit | ab65f4b8b2d0cc15c8279467b6150b4f0e51f704 (patch) | |
| tree | 49760b137c6aad27643005c7fa8e50c305e5c293 /packages/backend/src/server/web | |
| parent | fix eslint warning in UrlPreviewService.ts (diff) | |
| download | sharkey-ab65f4b8b2d0cc15c8279467b6150b4f0e51f704.tar.gz sharkey-ab65f4b8b2d0cc15c8279467b6150b4f0e51f704.tar.bz2 sharkey-ab65f4b8b2d0cc15c8279467b6150b4f0e51f704.zip | |
infer ActivityPub links from local DB
Diffstat (limited to 'packages/backend/src/server/web')
| -rw-r--r-- | packages/backend/src/server/web/UrlPreviewService.ts | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index 8c1776568b..a38454fafc 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -20,6 +20,9 @@ import { RedisKVCache } from '@/misc/cache.js'; import { UtilityService } from '@/core/UtilityService.js'; import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js'; import type { FastifyRequest, FastifyReply } from 'fastify'; +import type { NotesRepository } from '@/models/_.js'; +import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js'; +import { IsNull, Not } from 'typeorm'; export type LocalSummalyResult = SummalyResult & { haveNoteLocally?: boolean; @@ -40,9 +43,13 @@ export class UrlPreviewService { @Inject(DI.meta) private readonly meta: MiMeta, + @Inject(DI.notesRepository) + private readonly notesRepository: NotesRepository, + private httpRequestService: HttpRequestService, private loggerService: LoggerService, private readonly utilityService: UtilityService, + private readonly apUtilityService: ApUtilityService, private readonly apDbResolverService: ApDbResolverService, ) { this.logger = this.loggerService.getLogger('url-preview'); @@ -143,6 +150,9 @@ export class UrlPreviewService { if (summary.activityPub) { summary.haveNoteLocally = !!await this.apDbResolverService.getNoteFromApId(summary.activityPub); + } else { + // Summaly cannot always detect links to a fedi post, so check if it matches anything we already have + await this.inferActivityPubLink(summary); } this.previewCache.set(key, summary); @@ -198,4 +208,33 @@ export class UrlPreviewService { return this.httpRequestService.getJson<LocalSummalyResult>(`${proxy}?${queryStr}`, 'application/json, */*', undefined, true); } + + private async inferActivityPubLink(summary: LocalSummalyResult) { + // Match canonical URI first. + // This covers local and remote links. + const isCanonicalUri = !!await this.apDbResolverService.getNoteFromApId(summary.url); + if (isCanonicalUri) { + summary.activityPub = summary.url; + summary.haveNoteLocally = true; + } + + // Try public URL next. + // This is necessary for Mastodon and other software with a different public URL. + const urlMatches = await this.notesRepository.find({ + select: { + uri: true, + }, + where: { + url: summary.url, + uri: Not(IsNull()), + }, + }) as { uri: string }[]; + + // Older versions did not validate URL, so do it now to avoid impersonation. + const matchByUrl = urlMatches.find(({ uri }) => this.apUtilityService.haveSameAuthority(uri, summary.url)); + if (matchByUrl) { + summary.activityPub = matchByUrl.uri; + summary.haveNoteLocally = true; + } + } } |