ActivityPubオブジェクト採番API (#2832)
* Show ActivityPub object API * Add missing return
This commit is contained in:
		
							
								
								
									
										116
									
								
								src/server/api/endpoints/ap/show.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/server/api/endpoints/ap/show.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | import $ from 'cafy'; | ||||||
|  | import getParams from '../../get-params'; | ||||||
|  | import config from '../../../../config'; | ||||||
|  | import * as mongo from 'mongodb'; | ||||||
|  | import User, { pack as packUser, IUser } from '../../../../models/user'; | ||||||
|  | import { createPerson } from '../../../../remote/activitypub/models/person'; | ||||||
|  | import Note, { pack as packNote, INote } from '../../../../models/note'; | ||||||
|  | import { createNote } from '../../../../remote/activitypub/models/note'; | ||||||
|  | import Resolver from '../../../../remote/activitypub/resolver'; | ||||||
|  |  | ||||||
|  | export const meta = { | ||||||
|  | 	desc: { | ||||||
|  | 		'ja-JP': 'URIを指定してActivityPubオブジェクトを参照します。' | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	requireCredential: false, | ||||||
|  |  | ||||||
|  | 	params: { | ||||||
|  | 		uri: $.str.note({ | ||||||
|  | 			desc: { | ||||||
|  | 				'ja-JP': 'ActivityPubオブジェクトのURI' | ||||||
|  | 			} | ||||||
|  | 		}), | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default (params: any) => new Promise(async (res, rej) => { | ||||||
|  | 	const [ps, psErr] = getParams(meta, params); | ||||||
|  | 	if (psErr) return rej(psErr); | ||||||
|  |  | ||||||
|  | 	const object = await fetchAny(ps.uri); | ||||||
|  | 	if (object !== null) return res(object); | ||||||
|  |  | ||||||
|  | 	return rej('object not found'); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | /*** | ||||||
|  |  * URIからUserかNoteを解決する | ||||||
|  |  */ | ||||||
|  | async function fetchAny(uri: string) { | ||||||
|  | 	// URIがこのサーバーを指しているなら、ローカルユーザーIDとしてDBからフェッチ | ||||||
|  | 	if (uri.startsWith(config.url + '/')) { | ||||||
|  | 		const id = new mongo.ObjectID(uri.split('/').pop()); | ||||||
|  | 		const [ user, note ] = await Promise.all([ | ||||||
|  | 			User.findOne({ _id: id }), | ||||||
|  | 			Note.findOne({ _id: id }) | ||||||
|  | 		]); | ||||||
|  |  | ||||||
|  | 		const packed = await mergePack(user, note); | ||||||
|  | 		if (packed !== null) return packed; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// URI(AP Object id)としてDB検索 | ||||||
|  | 	{ | ||||||
|  | 		const [ user, note ] = await Promise.all([ | ||||||
|  | 			User.findOne({ uri: uri }), | ||||||
|  | 			Note.findOne({ uri: uri }) | ||||||
|  | 		]); | ||||||
|  |  | ||||||
|  | 		const packed = await mergePack(user, note); | ||||||
|  | 		if (packed !== null) return packed; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// リモートから一旦オブジェクトフェッチ | ||||||
|  | 	const resolver = new Resolver(); | ||||||
|  | 	const object = await resolver.resolve(uri) as any; | ||||||
|  |  | ||||||
|  | 	// /@user のような正規id以外で取得できるURIが指定されていた場合、ここで初めて正規URIが確定する | ||||||
|  | 	// これはDBに存在する可能性があるため再度DB検索 | ||||||
|  | 	if (uri !== object.id) { | ||||||
|  | 		const [ user, note ] = await Promise.all([ | ||||||
|  | 			User.findOne({ uri: object.id }), | ||||||
|  | 			Note.findOne({ uri: object.id }) | ||||||
|  | 		]); | ||||||
|  |  | ||||||
|  | 		const packed = await mergePack(user, note); | ||||||
|  | 		if (packed !== null) return packed; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// それでもみつからなければ新規であるため登録 | ||||||
|  | 	if (object.type === 'Person') { | ||||||
|  | 		const user = await createPerson(object.id); | ||||||
|  | 		return { | ||||||
|  | 			type: 'User', | ||||||
|  | 			object: user | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (object.type === 'Note') { | ||||||
|  | 		const note = await createNote(object.id); | ||||||
|  | 		return { | ||||||
|  | 			type: 'Note', | ||||||
|  | 			object: note | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function mergePack(user: IUser, note: INote) { | ||||||
|  | 	if (user !== null) { | ||||||
|  | 		return { | ||||||
|  | 			type: 'User', | ||||||
|  | 			object: await packUser(user, null, { detail: true }) | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (note !== null) { | ||||||
|  | 		return { | ||||||
|  | 			type: 'Note', | ||||||
|  | 			object: await packNote(note, null, { detail: true }) | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return null; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 MeiMei
					MeiMei