summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorMeiMei <30769358+mei23@users.noreply.github.com>2018-10-07 20:20:55 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2018-10-07 20:20:55 +0900
commitb9f5fca3333283cda2ccbd7843f7496dd9eae574 (patch)
treea220edf1c3a53397fd3732bffb1f8d195c33852f /src/server
parent投稿の削除イベントを受け取るように (diff)
downloadsharkey-b9f5fca3333283cda2ccbd7843f7496dd9eae574.tar.gz
sharkey-b9f5fca3333283cda2ccbd7843f7496dd9eae574.tar.bz2
sharkey-b9f5fca3333283cda2ccbd7843f7496dd9eae574.zip
ActivityPubオブジェクト採番API (#2832)
* Show ActivityPub object API * Add missing return
Diffstat (limited to 'src/server')
-rw-r--r--src/server/api/endpoints/ap/show.ts116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts
new file mode 100644
index 0000000000..1f390d01aa
--- /dev/null
+++ b/src/server/api/endpoints/ap/show.ts
@@ -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;
+}