From aaa167fd5765360631af3b2c3af416e3f2db30e9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 17 Apr 2018 16:05:50 +0900 Subject: Refactor --- src/queue/processors/http/process-inbox.ts | 2 +- src/remote/activitypub/kernel/announce/note.ts | 2 +- src/remote/activitypub/kernel/create/image.ts | 2 +- src/remote/activitypub/kernel/create/note.ts | 2 +- src/remote/activitypub/models/image.ts | 36 ++++ src/remote/activitypub/models/note.ts | 115 +++++++++++++ src/remote/activitypub/models/person.ts | 221 +++++++++++++++++++++++++ src/remote/activitypub/objects/image.ts | 36 ---- src/remote/activitypub/objects/note.ts | 115 ------------- src/remote/activitypub/objects/person.ts | 221 ------------------------- src/remote/resolve-user.ts | 2 +- 11 files changed, 377 insertions(+), 377 deletions(-) create mode 100644 src/remote/activitypub/models/image.ts create mode 100644 src/remote/activitypub/models/note.ts create mode 100644 src/remote/activitypub/models/person.ts delete mode 100644 src/remote/activitypub/objects/image.ts delete mode 100644 src/remote/activitypub/objects/note.ts delete mode 100644 src/remote/activitypub/objects/person.ts (limited to 'src') diff --git a/src/queue/processors/http/process-inbox.ts b/src/queue/processors/http/process-inbox.ts index 2c49a67b66..75ff5918f6 100644 --- a/src/queue/processors/http/process-inbox.ts +++ b/src/queue/processors/http/process-inbox.ts @@ -5,7 +5,7 @@ const httpSignature = require('http-signature'); import parseAcct from '../../../acct/parse'; import User, { IRemoteUser } from '../../../models/user'; import perform from '../../../remote/activitypub/perform'; -import { resolvePerson } from '../../../remote/activitypub/objects/person'; +import { resolvePerson } from '../../../remote/activitypub/models/person'; const log = debug('misskey:queue:inbox'); diff --git a/src/remote/activitypub/kernel/announce/note.ts b/src/remote/activitypub/kernel/announce/note.ts index 68fb23c97f..a288dd499a 100644 --- a/src/remote/activitypub/kernel/announce/note.ts +++ b/src/remote/activitypub/kernel/announce/note.ts @@ -4,7 +4,7 @@ import Resolver from '../../resolver'; import post from '../../../../services/note/create'; import { IRemoteUser } from '../../../../models/user'; import { IAnnounce, INote } from '../../type'; -import { fetchNote, resolveNote } from '../../objects/note'; +import { fetchNote, resolveNote } from '../../models/note'; const log = debug('misskey:activitypub'); diff --git a/src/remote/activitypub/kernel/create/image.ts b/src/remote/activitypub/kernel/create/image.ts index ea36545f0c..2a55522220 100644 --- a/src/remote/activitypub/kernel/create/image.ts +++ b/src/remote/activitypub/kernel/create/image.ts @@ -1,5 +1,5 @@ import { IRemoteUser } from '../../../../models/user'; -import { createImage } from '../../objects/image'; +import { createImage } from '../../models/image'; export default async function(actor: IRemoteUser, image): Promise { await createImage(image.url, actor); diff --git a/src/remote/activitypub/kernel/create/note.ts b/src/remote/activitypub/kernel/create/note.ts index 530cf6483f..ed9fb6e54c 100644 --- a/src/remote/activitypub/kernel/create/note.ts +++ b/src/remote/activitypub/kernel/create/note.ts @@ -1,6 +1,6 @@ import Resolver from '../../resolver'; import { IRemoteUser } from '../../../../models/user'; -import { createNote, fetchNote } from '../../objects/note'; +import { createNote, fetchNote } from '../../models/note'; /** * 投稿作成アクティビティを捌きます diff --git a/src/remote/activitypub/models/image.ts b/src/remote/activitypub/models/image.ts new file mode 100644 index 0000000000..d7bc5aff2f --- /dev/null +++ b/src/remote/activitypub/models/image.ts @@ -0,0 +1,36 @@ +import * as debug from 'debug'; + +import uploadFromUrl from '../../../services/drive/upload-from-url'; +import { IRemoteUser } from '../../../models/user'; +import { IDriveFile } from '../../../models/drive-file'; +import Resolver from '../resolver'; + +const log = debug('misskey:activitypub'); + +/** + * Imageを作成します。 + */ +export async function createImage(actor: IRemoteUser, value): Promise { + const image = await new Resolver().resolve(value); + + if (image.url == null) { + throw new Error('invalid image: url not privided'); + } + + log(`Creating the Image: ${image.url}`); + + return await uploadFromUrl(image.url, actor); +} + +/** + * Imageを解決します。 + * + * Misskeyに対象のImageが登録されていればそれを返し、そうでなければ + * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 + */ +export async function resolveImage(actor: IRemoteUser, value: any): Promise { + // TODO + + // リモートサーバーからフェッチしてきて登録 + return await createImage(actor, value); +} diff --git a/src/remote/activitypub/models/note.ts b/src/remote/activitypub/models/note.ts new file mode 100644 index 0000000000..221d502f06 --- /dev/null +++ b/src/remote/activitypub/models/note.ts @@ -0,0 +1,115 @@ +import { JSDOM } from 'jsdom'; +import * as debug from 'debug'; + +import config from '../../../config'; +import Resolver from '../resolver'; +import Note, { INote } from '../../../models/note'; +import post from '../../../services/note/create'; +import { INote as INoteActivityStreamsObject, IObject } from '../type'; +import { resolvePerson, updatePerson } from './person'; +import { resolveImage } from './image'; +import { IRemoteUser } from '../../../models/user'; + +const log = debug('misskey:activitypub'); + +/** + * Noteをフェッチします。 + * + * Misskeyに対象のNoteが登録されていればそれを返します。 + */ +export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise { + const uri = typeof value == 'string' ? value : value.id; + + // URIがこのサーバーを指しているならデータベースからフェッチ + if (uri.startsWith(config.url + '/')) { + return await Note.findOne({ _id: uri.split('/').pop() }); + } + + //#region このサーバーに既に登録されていたらそれを返す + const exist = await Note.findOne({ uri }); + + if (exist) { + return exist; + } + //#endregion + + return null; +} + +/** + * Noteを作成します。 + */ +export async function createNote(value: any, resolver?: Resolver, silent = false): Promise { + if (resolver == null) resolver = new Resolver(); + + const object = await resolver.resolve(value) as any; + + if (object == null || object.type !== 'Note') { + throw new Error('invalid note'); + } + + const note: INoteActivityStreamsObject = object; + + log(`Creating the Note: ${note.id}`); + + // 投稿者をフェッチ + const actor = await resolvePerson(note.attributedTo) as IRemoteUser; + + //#region Visibility + let visibility = 'public'; + if (!note.to.includes('https://www.w3.org/ns/activitystreams#Public')) visibility = 'unlisted'; + if (note.cc.length == 0) visibility = 'private'; + // TODO + if (visibility != 'public') throw new Error('unspported visibility'); + //#endergion + + // 添付メディア + // TODO: attachmentは必ずしもImageではない + // TODO: attachmentは必ずしも配列ではない + const media = note.attachment + ? await Promise.all(note.attachment.map(x => resolveImage(actor, x))) + : []; + + // リプライ + const reply = note.inReplyTo ? await resolveNote(note.inReplyTo, resolver) : null; + + const { window } = new JSDOM(note.content); + + // ユーザーの情報が古かったらついでに更新しておく + if (actor.updatedAt && Date.now() - actor.updatedAt.getTime() > 1000 * 60 * 60 * 24) { + updatePerson(note.attributedTo); + } + + return await post(actor, { + createdAt: new Date(note.published), + media, + reply, + renote: undefined, + text: window.document.body.textContent, + viaMobile: false, + geo: undefined, + visibility, + uri: note.id + }, silent); +} + +/** + * Noteを解決します。 + * + * Misskeyに対象のNoteが登録されていればそれを返し、そうでなければ + * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 + */ +export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise { + const uri = typeof value == 'string' ? value : value.id; + + //#region このサーバーに既に登録されていたらそれを返す + const exist = await fetchNote(uri); + + if (exist) { + return exist; + } + //#endregion + + // リモートサーバーからフェッチしてきて登録 + return await createNote(value, resolver); +} diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts new file mode 100644 index 0000000000..b755b2603a --- /dev/null +++ b/src/remote/activitypub/models/person.ts @@ -0,0 +1,221 @@ +import { JSDOM } from 'jsdom'; +import { toUnicode } from 'punycode'; +import * as debug from 'debug'; + +import config from '../../../config'; +import User, { validateUsername, isValidName, IUser, IRemoteUser } from '../../../models/user'; +import webFinger from '../../webfinger'; +import Resolver from '../resolver'; +import { resolveImage } from './image'; +import { isCollectionOrOrderedCollection, IObject, IPerson } from '../type'; + +const log = debug('misskey:activitypub'); + +/** + * Personをフェッチします。 + * + * Misskeyに対象のPersonが登録されていればそれを返します。 + */ +export async function fetchPerson(value: string | IObject, resolver?: Resolver): Promise { + const uri = typeof value == 'string' ? value : value.id; + + // URIがこのサーバーを指しているならデータベースからフェッチ + if (uri.startsWith(config.url + '/')) { + return await User.findOne({ _id: uri.split('/').pop() }); + } + + //#region このサーバーに既に登録されていたらそれを返す + const exist = await User.findOne({ uri }); + + if (exist) { + return exist; + } + //#endregion + + return null; +} + +/** + * Personを作成します。 + */ +export async function createPerson(value: any, resolver?: Resolver): Promise { + if (resolver == null) resolver = new Resolver(); + + const object = await resolver.resolve(value) as any; + + if ( + object == null || + object.type !== 'Person' || + typeof object.preferredUsername !== 'string' || + !validateUsername(object.preferredUsername) || + !isValidName(object.name == '' ? null : object.name) + ) { + log(`invalid person: ${JSON.stringify(object, null, 2)}`); + throw new Error('invalid person'); + } + + const person: IPerson = object; + + log(`Creating the Person: ${person.id}`); + + const [followersCount = 0, followingCount = 0, notesCount = 0, finger] = await Promise.all([ + resolver.resolve(person.followers).then( + resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, + () => undefined + ), + resolver.resolve(person.following).then( + resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, + () => undefined + ), + resolver.resolve(person.outbox).then( + resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, + () => undefined + ), + webFinger(person.id) + ]); + + const host = toUnicode(finger.subject.replace(/^.*?@/, '')).toLowerCase(); + const summaryDOM = JSDOM.fragment(person.summary); + + // Create user + const user = await User.insert({ + avatarId: null, + bannerId: null, + createdAt: Date.parse(person.published) || null, + description: summaryDOM.textContent, + followersCount, + followingCount, + notesCount, + name: person.name, + driveCapacity: 1024 * 1024 * 8, // 8MiB + username: person.preferredUsername, + usernameLower: person.preferredUsername.toLowerCase(), + host, + publicKey: { + id: person.publicKey.id, + publicKeyPem: person.publicKey.publicKeyPem + }, + inbox: person.inbox, + uri: person.id, + url: person.url + }) as IRemoteUser; + + //#region アイコンとヘッダー画像をフェッチ + const [avatarId, bannerId] = (await Promise.all([ + person.icon, + person.image + ].map(img => + img == null + ? Promise.resolve(null) + : resolveImage(user, img) + ))).map(file => file != null ? file._id : null); + + User.update({ _id: user._id }, { $set: { avatarId, bannerId } }); + + user.avatarId = avatarId; + user.bannerId = bannerId; + //#endregion + + return user; +} + +/** + * Personの情報を更新します。 + * + * Misskeyに対象のPersonが登録されていなければ無視します。 + */ +export async function updatePerson(value: string | IObject, resolver?: Resolver): Promise { + const uri = typeof value == 'string' ? value : value.id; + + // URIがこのサーバーを指しているならスキップ + if (uri.startsWith(config.url + '/')) { + return; + } + + //#region このサーバーに既に登録されているか + const exist = await User.findOne({ uri }) as IRemoteUser; + + if (exist == null) { + return; + } + //#endregion + + if (resolver == null) resolver = new Resolver(); + + const object = await resolver.resolve(value) as any; + + if ( + object == null || + object.type !== 'Person' + ) { + log(`invalid person: ${JSON.stringify(object, null, 2)}`); + throw new Error('invalid person'); + } + + const person: IPerson = object; + + log(`Updating the Person: ${person.id}`); + + const [followersCount = 0, followingCount = 0, notesCount = 0] = await Promise.all([ + resolver.resolve(person.followers).then( + resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, + () => undefined + ), + resolver.resolve(person.following).then( + resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, + () => undefined + ), + resolver.resolve(person.outbox).then( + resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, + () => undefined + ) + ]); + + const summaryDOM = JSDOM.fragment(person.summary); + + // アイコンとヘッダー画像をフェッチ + const [avatarId, bannerId] = (await Promise.all([ + person.icon, + person.image + ].map(img => + img == null + ? Promise.resolve(null) + : resolveImage(exist, img) + ))).map(file => file != null ? file._id : null); + + // Update user + await User.update({ _id: exist._id }, { + $set: { + updatedAt: new Date(), + avatarId, + bannerId, + description: summaryDOM.textContent, + followersCount, + followingCount, + notesCount, + name: person.name, + url: person.url + } + }); +} + +/** + * Personを解決します。 + * + * Misskeyに対象のPersonが登録されていればそれを返し、そうでなければ + * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 + */ +export async function resolvePerson(value: string | IObject, verifier?: string): Promise { + const uri = typeof value == 'string' ? value : value.id; + + //#region このサーバーに既に登録されていたらそれを返す + const exist = await fetchPerson(uri); + + if (exist) { + return exist; + } + //#endregion + + // リモートサーバーからフェッチしてきて登録 + return await createPerson(value); +} diff --git a/src/remote/activitypub/objects/image.ts b/src/remote/activitypub/objects/image.ts deleted file mode 100644 index d7bc5aff2f..0000000000 --- a/src/remote/activitypub/objects/image.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as debug from 'debug'; - -import uploadFromUrl from '../../../services/drive/upload-from-url'; -import { IRemoteUser } from '../../../models/user'; -import { IDriveFile } from '../../../models/drive-file'; -import Resolver from '../resolver'; - -const log = debug('misskey:activitypub'); - -/** - * Imageを作成します。 - */ -export async function createImage(actor: IRemoteUser, value): Promise { - const image = await new Resolver().resolve(value); - - if (image.url == null) { - throw new Error('invalid image: url not privided'); - } - - log(`Creating the Image: ${image.url}`); - - return await uploadFromUrl(image.url, actor); -} - -/** - * Imageを解決します。 - * - * Misskeyに対象のImageが登録されていればそれを返し、そうでなければ - * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 - */ -export async function resolveImage(actor: IRemoteUser, value: any): Promise { - // TODO - - // リモートサーバーからフェッチしてきて登録 - return await createImage(actor, value); -} diff --git a/src/remote/activitypub/objects/note.ts b/src/remote/activitypub/objects/note.ts deleted file mode 100644 index 221d502f06..0000000000 --- a/src/remote/activitypub/objects/note.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { JSDOM } from 'jsdom'; -import * as debug from 'debug'; - -import config from '../../../config'; -import Resolver from '../resolver'; -import Note, { INote } from '../../../models/note'; -import post from '../../../services/note/create'; -import { INote as INoteActivityStreamsObject, IObject } from '../type'; -import { resolvePerson, updatePerson } from './person'; -import { resolveImage } from './image'; -import { IRemoteUser } from '../../../models/user'; - -const log = debug('misskey:activitypub'); - -/** - * Noteをフェッチします。 - * - * Misskeyに対象のNoteが登録されていればそれを返します。 - */ -export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise { - const uri = typeof value == 'string' ? value : value.id; - - // URIがこのサーバーを指しているならデータベースからフェッチ - if (uri.startsWith(config.url + '/')) { - return await Note.findOne({ _id: uri.split('/').pop() }); - } - - //#region このサーバーに既に登録されていたらそれを返す - const exist = await Note.findOne({ uri }); - - if (exist) { - return exist; - } - //#endregion - - return null; -} - -/** - * Noteを作成します。 - */ -export async function createNote(value: any, resolver?: Resolver, silent = false): Promise { - if (resolver == null) resolver = new Resolver(); - - const object = await resolver.resolve(value) as any; - - if (object == null || object.type !== 'Note') { - throw new Error('invalid note'); - } - - const note: INoteActivityStreamsObject = object; - - log(`Creating the Note: ${note.id}`); - - // 投稿者をフェッチ - const actor = await resolvePerson(note.attributedTo) as IRemoteUser; - - //#region Visibility - let visibility = 'public'; - if (!note.to.includes('https://www.w3.org/ns/activitystreams#Public')) visibility = 'unlisted'; - if (note.cc.length == 0) visibility = 'private'; - // TODO - if (visibility != 'public') throw new Error('unspported visibility'); - //#endergion - - // 添付メディア - // TODO: attachmentは必ずしもImageではない - // TODO: attachmentは必ずしも配列ではない - const media = note.attachment - ? await Promise.all(note.attachment.map(x => resolveImage(actor, x))) - : []; - - // リプライ - const reply = note.inReplyTo ? await resolveNote(note.inReplyTo, resolver) : null; - - const { window } = new JSDOM(note.content); - - // ユーザーの情報が古かったらついでに更新しておく - if (actor.updatedAt && Date.now() - actor.updatedAt.getTime() > 1000 * 60 * 60 * 24) { - updatePerson(note.attributedTo); - } - - return await post(actor, { - createdAt: new Date(note.published), - media, - reply, - renote: undefined, - text: window.document.body.textContent, - viaMobile: false, - geo: undefined, - visibility, - uri: note.id - }, silent); -} - -/** - * Noteを解決します。 - * - * Misskeyに対象のNoteが登録されていればそれを返し、そうでなければ - * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 - */ -export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise { - const uri = typeof value == 'string' ? value : value.id; - - //#region このサーバーに既に登録されていたらそれを返す - const exist = await fetchNote(uri); - - if (exist) { - return exist; - } - //#endregion - - // リモートサーバーからフェッチしてきて登録 - return await createNote(value, resolver); -} diff --git a/src/remote/activitypub/objects/person.ts b/src/remote/activitypub/objects/person.ts deleted file mode 100644 index b755b2603a..0000000000 --- a/src/remote/activitypub/objects/person.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { JSDOM } from 'jsdom'; -import { toUnicode } from 'punycode'; -import * as debug from 'debug'; - -import config from '../../../config'; -import User, { validateUsername, isValidName, IUser, IRemoteUser } from '../../../models/user'; -import webFinger from '../../webfinger'; -import Resolver from '../resolver'; -import { resolveImage } from './image'; -import { isCollectionOrOrderedCollection, IObject, IPerson } from '../type'; - -const log = debug('misskey:activitypub'); - -/** - * Personをフェッチします。 - * - * Misskeyに対象のPersonが登録されていればそれを返します。 - */ -export async function fetchPerson(value: string | IObject, resolver?: Resolver): Promise { - const uri = typeof value == 'string' ? value : value.id; - - // URIがこのサーバーを指しているならデータベースからフェッチ - if (uri.startsWith(config.url + '/')) { - return await User.findOne({ _id: uri.split('/').pop() }); - } - - //#region このサーバーに既に登録されていたらそれを返す - const exist = await User.findOne({ uri }); - - if (exist) { - return exist; - } - //#endregion - - return null; -} - -/** - * Personを作成します。 - */ -export async function createPerson(value: any, resolver?: Resolver): Promise { - if (resolver == null) resolver = new Resolver(); - - const object = await resolver.resolve(value) as any; - - if ( - object == null || - object.type !== 'Person' || - typeof object.preferredUsername !== 'string' || - !validateUsername(object.preferredUsername) || - !isValidName(object.name == '' ? null : object.name) - ) { - log(`invalid person: ${JSON.stringify(object, null, 2)}`); - throw new Error('invalid person'); - } - - const person: IPerson = object; - - log(`Creating the Person: ${person.id}`); - - const [followersCount = 0, followingCount = 0, notesCount = 0, finger] = await Promise.all([ - resolver.resolve(person.followers).then( - resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, - () => undefined - ), - resolver.resolve(person.following).then( - resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, - () => undefined - ), - resolver.resolve(person.outbox).then( - resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, - () => undefined - ), - webFinger(person.id) - ]); - - const host = toUnicode(finger.subject.replace(/^.*?@/, '')).toLowerCase(); - const summaryDOM = JSDOM.fragment(person.summary); - - // Create user - const user = await User.insert({ - avatarId: null, - bannerId: null, - createdAt: Date.parse(person.published) || null, - description: summaryDOM.textContent, - followersCount, - followingCount, - notesCount, - name: person.name, - driveCapacity: 1024 * 1024 * 8, // 8MiB - username: person.preferredUsername, - usernameLower: person.preferredUsername.toLowerCase(), - host, - publicKey: { - id: person.publicKey.id, - publicKeyPem: person.publicKey.publicKeyPem - }, - inbox: person.inbox, - uri: person.id, - url: person.url - }) as IRemoteUser; - - //#region アイコンとヘッダー画像をフェッチ - const [avatarId, bannerId] = (await Promise.all([ - person.icon, - person.image - ].map(img => - img == null - ? Promise.resolve(null) - : resolveImage(user, img) - ))).map(file => file != null ? file._id : null); - - User.update({ _id: user._id }, { $set: { avatarId, bannerId } }); - - user.avatarId = avatarId; - user.bannerId = bannerId; - //#endregion - - return user; -} - -/** - * Personの情報を更新します。 - * - * Misskeyに対象のPersonが登録されていなければ無視します。 - */ -export async function updatePerson(value: string | IObject, resolver?: Resolver): Promise { - const uri = typeof value == 'string' ? value : value.id; - - // URIがこのサーバーを指しているならスキップ - if (uri.startsWith(config.url + '/')) { - return; - } - - //#region このサーバーに既に登録されているか - const exist = await User.findOne({ uri }) as IRemoteUser; - - if (exist == null) { - return; - } - //#endregion - - if (resolver == null) resolver = new Resolver(); - - const object = await resolver.resolve(value) as any; - - if ( - object == null || - object.type !== 'Person' - ) { - log(`invalid person: ${JSON.stringify(object, null, 2)}`); - throw new Error('invalid person'); - } - - const person: IPerson = object; - - log(`Updating the Person: ${person.id}`); - - const [followersCount = 0, followingCount = 0, notesCount = 0] = await Promise.all([ - resolver.resolve(person.followers).then( - resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, - () => undefined - ), - resolver.resolve(person.following).then( - resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, - () => undefined - ), - resolver.resolve(person.outbox).then( - resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, - () => undefined - ) - ]); - - const summaryDOM = JSDOM.fragment(person.summary); - - // アイコンとヘッダー画像をフェッチ - const [avatarId, bannerId] = (await Promise.all([ - person.icon, - person.image - ].map(img => - img == null - ? Promise.resolve(null) - : resolveImage(exist, img) - ))).map(file => file != null ? file._id : null); - - // Update user - await User.update({ _id: exist._id }, { - $set: { - updatedAt: new Date(), - avatarId, - bannerId, - description: summaryDOM.textContent, - followersCount, - followingCount, - notesCount, - name: person.name, - url: person.url - } - }); -} - -/** - * Personを解決します。 - * - * Misskeyに対象のPersonが登録されていればそれを返し、そうでなければ - * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 - */ -export async function resolvePerson(value: string | IObject, verifier?: string): Promise { - const uri = typeof value == 'string' ? value : value.id; - - //#region このサーバーに既に登録されていたらそれを返す - const exist = await fetchPerson(uri); - - if (exist) { - return exist; - } - //#endregion - - // リモートサーバーからフェッチしてきて登録 - return await createPerson(value); -} diff --git a/src/remote/resolve-user.ts b/src/remote/resolve-user.ts index 5cb35cadef..b6048842bf 100644 --- a/src/remote/resolve-user.ts +++ b/src/remote/resolve-user.ts @@ -2,7 +2,7 @@ import { toUnicode, toASCII } from 'punycode'; import User from '../models/user'; import webFinger from './webfinger'; import config from '../config'; -import { createPerson } from './activitypub/objects/person'; +import { createPerson } from './activitypub/models/person'; export default async (username, _host, option) => { const usernameLower = username.toLowerCase(); -- cgit v1.2.3-freya