diff options
| author | taichan <40626578+tai-cha@users.noreply.github.com> | 2024-08-17 15:12:23 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-17 15:12:23 +0900 |
| commit | 9fbc1b7f7b71cf0eafadd728a6b66cb95a0c35d8 (patch) | |
| tree | b70f0a6c11c8f0ba159c877d7731cb8a38c8f5d8 | |
| parent | enhance(backend): ページ、ギャラリー、Playのモデレーション... (diff) | |
| download | sharkey-9fbc1b7f7b71cf0eafadd728a6b66cb95a0c35d8.tar.gz sharkey-9fbc1b7f7b71cf0eafadd728a6b66cb95a0c35d8.tar.bz2 sharkey-9fbc1b7f7b71cf0eafadd728a6b66cb95a0c35d8.zip | |
enhance(backend): headタグ内にrel=alternateの指定のあるlinkタグがある場合、記述されたURLを参照して照会できるように (#14371)
* signedGet時にhttpかつalternate属性のlinkがある場合に一回だけfollowして照会する
* Fix: validation position
* Fix import
* Fix tagname
* Update CHANGELOG
* Fix code style
---------
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | packages/backend/src/core/activitypub/ApRequestService.ts | 24 |
2 files changed, 23 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e98f9f193..0de0d40877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Fix: 特定の条件下でノートの削除ボタンが出ないのを修正 ### Server +- enhance: 照会時にURLがhtmlかつheadタグ内に`rel="alternate"`, `type="application/activity+json"`の`link`タグがある場合に追ってリンク先を照会できるように - Enhance: 凍結されたアカウントのフォローリクエストを表示しないように - Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374 - 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。 diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index 93ac8ce9a7..69b09ba808 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -6,6 +6,7 @@ import * as crypto from 'node:crypto'; import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; +import { Window } from 'happy-dom'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import type { MiUser } from '@/models/User.js'; @@ -180,7 +181,8 @@ export class ApRequestService { * @param url URL to fetch */ @bindThis - public async signedGet(url: string, user: { id: MiUser['id'] }): Promise<unknown> { + public async signedGet(url: string, user: { id: MiUser['id'] }, followAlternate?: boolean): Promise<unknown> { + const _followAlternate = followAlternate ?? true; const keypair = await this.userKeypairService.getUserKeypair(user.id); const req = ApRequestCreator.createSignedGet({ @@ -198,9 +200,27 @@ export class ApRequestService { headers: req.request.headers, }, { throwErrorWhenResponseNotOk: true, - validators: [validateContentTypeSetAsActivityPub], }); + //#region リクエスト先がhtmlかつactivity+jsonへのalternate linkタグがあるとき + if (res.headers.get('Content-type')?.startsWith('text/html;') && _followAlternate === true) { + const html = await res.text(); + const window = new Window(); + const document = window.document; + document.documentElement.innerHTML = html; + + const alternate = document.querySelector('head > link[rel="alternate"][type="application/activity+json"]'); + if (alternate) { + const href = alternate.getAttribute('href'); + if (href) { + return await this.signedGet(href, user, false); + } + } + } + //#endregion + + validateContentTypeSetAsActivityPub(res); + return await res.json(); } } |