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>
This commit is contained in:
		
							parent
							
								
									fd744f44c1
								
							
						
					
					
						commit
						9fbc1b7f7b
					
				
					 2 changed files with 23 additions and 2 deletions
				
			
		| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
- Fix: 特定の条件下でノートの削除ボタンが出ないのを修正
 | 
					- Fix: 特定の条件下でノートの削除ボタンが出ないのを修正
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Server
 | 
					### Server
 | 
				
			||||||
 | 
					- enhance: 照会時にURLがhtmlかつheadタグ内に`rel="alternate"`, `type="application/activity+json"`の`link`タグがある場合に追ってリンク先を照会できるように
 | 
				
			||||||
- Enhance: 凍結されたアカウントのフォローリクエストを表示しないように
 | 
					- Enhance: 凍結されたアカウントのフォローリクエストを表示しないように
 | 
				
			||||||
- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374
 | 
					- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374
 | 
				
			||||||
  - 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。
 | 
					  - 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
import * as crypto from 'node:crypto';
 | 
					import * as crypto from 'node:crypto';
 | 
				
			||||||
import { URL } from 'node:url';
 | 
					import { URL } from 'node:url';
 | 
				
			||||||
import { Inject, Injectable } from '@nestjs/common';
 | 
					import { Inject, Injectable } from '@nestjs/common';
 | 
				
			||||||
 | 
					import { Window } from 'happy-dom';
 | 
				
			||||||
import { DI } from '@/di-symbols.js';
 | 
					import { DI } from '@/di-symbols.js';
 | 
				
			||||||
import type { Config } from '@/config.js';
 | 
					import type { Config } from '@/config.js';
 | 
				
			||||||
import type { MiUser } from '@/models/User.js';
 | 
					import type { MiUser } from '@/models/User.js';
 | 
				
			||||||
| 
						 | 
					@ -180,7 +181,8 @@ export class ApRequestService {
 | 
				
			||||||
	 * @param url URL to fetch
 | 
						 * @param url URL to fetch
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	@bindThis
 | 
						@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 keypair = await this.userKeypairService.getUserKeypair(user.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const req = ApRequestCreator.createSignedGet({
 | 
							const req = ApRequestCreator.createSignedGet({
 | 
				
			||||||
| 
						 | 
					@ -198,9 +200,27 @@ export class ApRequestService {
 | 
				
			||||||
			headers: req.request.headers,
 | 
								headers: req.request.headers,
 | 
				
			||||||
		}, {
 | 
							}, {
 | 
				
			||||||
			throwErrorWhenResponseNotOk: true,
 | 
								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();
 | 
							return await res.json();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue