refactor: simplify ap/show with DbResolver (#8838)
Using the existing code in DbResolver we can avoid separate code for parsing the URIs in this endpoint. Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
		
							parent
							
								
									ecdaeea94f
								
							
						
					
					
						commit
						4f4d2b7c53
					
				
					 1 changed files with 33 additions and 99 deletions
				
			
		|  | @ -2,12 +2,13 @@ import define from '../../define.js'; | |||
| import config from '@/config/index.js'; | ||||
| import { createPerson } from '@/remote/activitypub/models/person.js'; | ||||
| import { createNote } from '@/remote/activitypub/models/note.js'; | ||||
| import DbResolver from '@/remote/activitypub/db-resolver.js'; | ||||
| import Resolver from '@/remote/activitypub/resolver.js'; | ||||
| import { ApiError } from '../../error.js'; | ||||
| import { extractDbHost } from '@/misc/convert-host.js'; | ||||
| import { Users, Notes } from '@/models/index.js'; | ||||
| import { Note } from '@/models/entities/note.js'; | ||||
| import { User } from '@/models/entities/user.js'; | ||||
| import { CacheableLocalUser, User } from '@/models/entities/user.js'; | ||||
| import { fetchMeta } from '@/misc/fetch-meta.js'; | ||||
| import { isActor, isPost, getApId } from '@/remote/activitypub/type.js'; | ||||
| import ms from 'ms'; | ||||
|  | @ -77,8 +78,8 @@ export const paramDef = { | |||
| } as const; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, paramDef, async (ps) => { | ||||
| 	const object = await fetchAny(ps.uri); | ||||
| export default define(meta, paramDef, async (ps, me) => { | ||||
| 	const object = await fetchAny(ps.uri, me); | ||||
| 	if (object) { | ||||
| 		return object; | ||||
| 	} else { | ||||
|  | @ -89,48 +90,18 @@ export default define(meta, paramDef, async (ps) => { | |||
| /*** | ||||
|  * URIからUserかNoteを解決する | ||||
|  */ | ||||
| async function fetchAny(uri: string): Promise<SchemaType<typeof meta['res']> | null> { | ||||
| 	// URIがこのサーバーを指しているなら、ローカルユーザーIDとしてDBからフェッチ
 | ||||
| 	if (uri.startsWith(config.url + '/')) { | ||||
| 		const parts = uri.split('/'); | ||||
| 		const id = parts.pop(); | ||||
| 		const type = parts.pop(); | ||||
| 
 | ||||
| 		if (type === 'notes') { | ||||
| 			const note = await Notes.findOneBy({ id }); | ||||
| 
 | ||||
| 			if (note) { | ||||
| 				return { | ||||
| 					type: 'Note', | ||||
| 					object: await Notes.pack(note, null, { detail: true }), | ||||
| 				}; | ||||
| 			} | ||||
| 		} else if (type === 'users') { | ||||
| 			const user = await Users.findOneBy({ id }); | ||||
| 
 | ||||
| 			if (user) { | ||||
| 				return { | ||||
| 					type: 'User', | ||||
| 					object: await Users.pack(user, null, { detail: true }), | ||||
| 				}; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| async function fetchAny(uri: string, me: CacheableLocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> { | ||||
| 	// ブロックしてたら中断
 | ||||
| 	const fetchedMeta = await fetchMeta(); | ||||
| 	if (fetchedMeta.blockedHosts.includes(extractDbHost(uri))) return null; | ||||
| 
 | ||||
| 	// URI(AP Object id)としてDB検索
 | ||||
| 	{ | ||||
| 		const [user, note] = await Promise.all([ | ||||
| 			Users.findOneBy({ uri: uri }), | ||||
| 			Notes.findOneBy({ uri: uri }), | ||||
| 		]); | ||||
| 	const dbResolver = new DbResolver(); | ||||
| 
 | ||||
| 		const packed = await mergePack(user, note); | ||||
| 		if (packed !== null) return packed; | ||||
| 	} | ||||
| 	let local = await mergePack(me, ...await Promise.all([ | ||||
| 		dbResolver.getUserFromApId(uri), | ||||
| 		dbResolver.getNoteFromApId(uri), | ||||
| 	])); | ||||
| 	if (local != null) return local; | ||||
| 
 | ||||
| 	// リモートから一旦オブジェクトフェッチ
 | ||||
| 	const resolver = new Resolver(); | ||||
|  | @ -139,74 +110,37 @@ async function fetchAny(uri: string): Promise<SchemaType<typeof meta['res']> | n | |||
| 	// /@user のような正規id以外で取得できるURIが指定されていた場合、ここで初めて正規URIが確定する
 | ||||
| 	// これはDBに存在する可能性があるため再度DB検索
 | ||||
| 	if (uri !== object.id) { | ||||
| 		if (object.id.startsWith(config.url + '/')) { | ||||
| 			const parts = object.id.split('/'); | ||||
| 			const id = parts.pop(); | ||||
| 			const type = parts.pop(); | ||||
| 
 | ||||
| 			if (type === 'notes') { | ||||
| 				const note = await Notes.findOneBy({ id }); | ||||
| 
 | ||||
| 				if (note) { | ||||
| 					return { | ||||
| 						type: 'Note', | ||||
| 						object: await Notes.pack(note, null, { detail: true }), | ||||
| 					}; | ||||
| 				} | ||||
| 			} else if (type === 'users') { | ||||
| 				const user = await Users.findOneBy({ id }); | ||||
| 
 | ||||
| 				if (user) { | ||||
| 					return { | ||||
| 						type: 'User', | ||||
| 						object: await Users.pack(user, null, { detail: true }), | ||||
| 					}; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		const [user, note] = await Promise.all([ | ||||
| 			Users.findOneBy({ uri: object.id }), | ||||
| 			Notes.findOneBy({ uri: object.id }), | ||||
| 		]); | ||||
| 
 | ||||
| 		const packed = await mergePack(user, note); | ||||
| 		if (packed !== null) return packed; | ||||
| 		local = await mergePack(me, ...await Promise.all([ | ||||
| 			dbResolver.getUserFromApId(object.id), | ||||
| 			dbResolver.getNoteFromApId(object.id), | ||||
| 		])); | ||||
| 		if (local != null) return local; | ||||
| 	} | ||||
| 
 | ||||
| 	// それでもみつからなければ新規であるため登録
 | ||||
| 	if (isActor(object)) { | ||||
| 		const user = await createPerson(getApId(object)); | ||||
| 		return { | ||||
| 			type: 'User', | ||||
| 			object: await Users.pack(user, null, { detail: true }), | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	if (isPost(object)) { | ||||
| 		const note = await createNote(getApId(object), undefined, true); | ||||
| 		return { | ||||
| 			type: 'Note', | ||||
| 			object: await Notes.pack(note!, null, { detail: true }), | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	return null; | ||||
| 	return await mergePack( | ||||
| 		me, | ||||
| 		isActor(object) ? await createPerson(getApId(object)) : null, | ||||
| 		isPost(object) ? await createNote(getApId(object), undefined, true) : null, | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| async function mergePack(user: User | null | undefined, note: Note | null | undefined): Promise<SchemaType<typeof meta.res> | null> { | ||||
| async function mergePack(me: CacheableLocalUser | null | undefined, user: User | null | undefined, note: Note | null | undefined): Promise<SchemaType<typeof meta.res> | null> { | ||||
| 	if (user != null) { | ||||
| 		return { | ||||
| 			type: 'User', | ||||
| 			object: await Users.pack(user, null, { detail: true }), | ||||
| 			object: await Users.pack(user, me, { detail: true }), | ||||
| 		}; | ||||
| 	} | ||||
| 	} else if (note != null) { | ||||
| 		try { | ||||
| 			const object = await Notes.pack(note, me, { detail: true }); | ||||
| 
 | ||||
| 	if (note != null) { | ||||
| 		return { | ||||
| 			type: 'Note', | ||||
| 			object: await Notes.pack(note, null, { detail: true }), | ||||
| 		}; | ||||
| 			return { | ||||
| 				type: 'Note', | ||||
| 				object, | ||||
| 			}; | ||||
| 		} catch (e) { | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return null; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue