Fix: AP object / actor type (#5086)
* attributedToがArrayの場合などに対応 * attachment以外で来るDocument系のObjectに対応 * Renote, Reply 対応 * 表示をいい感じに * fix type * revert as const * Fix Note / Question type * attributedToのtypeで複合配列を想定する
This commit is contained in:
parent
a8379e3bc9
commit
0141affe05
|
@ -144,8 +144,8 @@ export class NoteRepository extends Repository<Note> {
|
||||||
|
|
||||||
let text = note.text;
|
let text = note.text;
|
||||||
|
|
||||||
if (note.name) {
|
if (note.name && note.uri) {
|
||||||
text = `【${note.name}】\n${note.text}`;
|
text = `【${note.name}】\n${(note.text || '').trim()}\n${note.uri}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reactionEmojis = unique(concat([note.emojis, Object.keys(note.reactions)]));
|
const reactionEmojis = unique(concat([note.emojis, Object.keys(note.reactions)]));
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import Resolver from '../../resolver';
|
import Resolver from '../../resolver';
|
||||||
import { IRemoteUser } from '../../../../models/entities/user';
|
import { IRemoteUser } from '../../../../models/entities/user';
|
||||||
import announceNote from './note';
|
import announceNote from './note';
|
||||||
import { IAnnounce, INote } from '../../type';
|
import { IAnnounce, INote, validPost, getApId } from '../../type';
|
||||||
import { apLogger } from '../../logger';
|
import { apLogger } from '../../logger';
|
||||||
|
|
||||||
const logger = apLogger;
|
const logger = apLogger;
|
||||||
|
|
||||||
export default async (actor: IRemoteUser, activity: IAnnounce): Promise<void> => {
|
export default async (actor: IRemoteUser, activity: IAnnounce): Promise<void> => {
|
||||||
const uri = activity.id || activity;
|
const uri = getApId(activity);
|
||||||
|
|
||||||
logger.info(`Announce: ${uri}`);
|
logger.info(`Announce: ${uri}`);
|
||||||
|
|
||||||
|
@ -22,15 +22,9 @@ export default async (actor: IRemoteUser, activity: IAnnounce): Promise<void> =>
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (object.type) {
|
if (validPost.includes(object.type)) {
|
||||||
case 'Note':
|
|
||||||
case 'Question':
|
|
||||||
case 'Article':
|
|
||||||
announceNote(resolver, actor, activity, object as INote);
|
announceNote(resolver, actor, activity, object as INote);
|
||||||
break;
|
} else {
|
||||||
|
|
||||||
default:
|
|
||||||
logger.warn(`Unknown announce type: ${object.type}`);
|
logger.warn(`Unknown announce type: ${object.type}`);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Resolver from '../../resolver';
|
import Resolver from '../../resolver';
|
||||||
import post from '../../../../services/note/create';
|
import post from '../../../../services/note/create';
|
||||||
import { IRemoteUser, User } from '../../../../models/entities/user';
|
import { IRemoteUser, User } from '../../../../models/entities/user';
|
||||||
import { IAnnounce, INote } from '../../type';
|
import { IAnnounce, INote, getApId, getApIds } from '../../type';
|
||||||
import { fetchNote, resolveNote } from '../../models/note';
|
import { fetchNote, resolveNote } from '../../models/note';
|
||||||
import { resolvePerson } from '../../models/person';
|
import { resolvePerson } from '../../models/person';
|
||||||
import { apLogger } from '../../logger';
|
import { apLogger } from '../../logger';
|
||||||
|
@ -14,17 +14,13 @@ const logger = apLogger;
|
||||||
* アナウンスアクティビティを捌きます
|
* アナウンスアクティビティを捌きます
|
||||||
*/
|
*/
|
||||||
export default async function(resolver: Resolver, actor: IRemoteUser, activity: IAnnounce, note: INote): Promise<void> {
|
export default async function(resolver: Resolver, actor: IRemoteUser, activity: IAnnounce, note: INote): Promise<void> {
|
||||||
const uri = activity.id || activity;
|
const uri = getApId(activity);
|
||||||
|
|
||||||
// アナウンサーが凍結されていたらスキップ
|
// アナウンサーが凍結されていたらスキップ
|
||||||
if (actor.isSuspended) {
|
if (actor.isSuspended) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof uri !== 'string') {
|
|
||||||
throw new Error('invalid announce');
|
|
||||||
}
|
|
||||||
|
|
||||||
// アナウンス先をブロックしてたら中断
|
// アナウンス先をブロックしてたら中断
|
||||||
const meta = await fetchMeta();
|
const meta = await fetchMeta();
|
||||||
if (meta.blockedHosts.includes(extractDbHost(uri))) return;
|
if (meta.blockedHosts.includes(extractDbHost(uri))) return;
|
||||||
|
@ -52,11 +48,14 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
|
||||||
logger.info(`Creating the (Re)Note: ${uri}`);
|
logger.info(`Creating the (Re)Note: ${uri}`);
|
||||||
|
|
||||||
//#region Visibility
|
//#region Visibility
|
||||||
const visibility = getVisibility(activity.to || [], activity.cc || [], actor);
|
const to = getApIds(activity.to);
|
||||||
|
const cc = getApIds(activity.cc);
|
||||||
|
|
||||||
|
const visibility = getVisibility(to, cc, actor);
|
||||||
|
|
||||||
let visibleUsers: User[] = [];
|
let visibleUsers: User[] = [];
|
||||||
if (visibility == 'specified') {
|
if (visibility == 'specified') {
|
||||||
visibleUsers = await Promise.all((note.to || []).map(uri => resolvePerson(uri)));
|
visibleUsers = await Promise.all(to.map(uri => resolvePerson(uri)));
|
||||||
}
|
}
|
||||||
//#endergion
|
//#endergion
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
import { IRemoteUser } from '../../../../models/entities/user';
|
|
||||||
import { createImage } from '../../models/image';
|
|
||||||
|
|
||||||
export default async function(actor: IRemoteUser, image: any): Promise<void> {
|
|
||||||
await createImage(image.url, actor);
|
|
||||||
}
|
|
|
@ -1,14 +1,13 @@
|
||||||
import Resolver from '../../resolver';
|
import Resolver from '../../resolver';
|
||||||
import { IRemoteUser } from '../../../../models/entities/user';
|
import { IRemoteUser } from '../../../../models/entities/user';
|
||||||
import createImage from './image';
|
|
||||||
import createNote from './note';
|
import createNote from './note';
|
||||||
import { ICreate } from '../../type';
|
import { ICreate, getApId, validPost } from '../../type';
|
||||||
import { apLogger } from '../../logger';
|
import { apLogger } from '../../logger';
|
||||||
|
|
||||||
const logger = apLogger;
|
const logger = apLogger;
|
||||||
|
|
||||||
export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
|
export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
|
||||||
const uri = activity.id || activity;
|
const uri = getApId(activity);
|
||||||
|
|
||||||
logger.info(`Create: ${uri}`);
|
logger.info(`Create: ${uri}`);
|
||||||
|
|
||||||
|
@ -23,19 +22,9 @@ export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (object.type) {
|
if (validPost.includes(object.type)) {
|
||||||
case 'Image':
|
|
||||||
createImage(actor, object);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Note':
|
|
||||||
case 'Question':
|
|
||||||
case 'Article':
|
|
||||||
createNote(resolver, actor, object);
|
createNote(resolver, actor, object);
|
||||||
break;
|
} else {
|
||||||
|
|
||||||
default:
|
|
||||||
logger.warn(`Unknown type: ${object.type}`);
|
logger.warn(`Unknown type: ${object.type}`);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import Resolver from '../../resolver';
|
import Resolver from '../../resolver';
|
||||||
import deleteNote from './note';
|
import deleteNote from './note';
|
||||||
import { IRemoteUser } from '../../../../models/entities/user';
|
import { IRemoteUser } from '../../../../models/entities/user';
|
||||||
import { IDelete } from '../../type';
|
import { IDelete, getApId, validPost } from '../../type';
|
||||||
import { apLogger } from '../../logger';
|
import { apLogger } from '../../logger';
|
||||||
import { Notes } from '../../../../models';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 削除アクティビティを捌きます
|
* 削除アクティビティを捌きます
|
||||||
|
@ -17,24 +16,11 @@ export default async (actor: IRemoteUser, activity: IDelete): Promise<void> => {
|
||||||
|
|
||||||
const object = await resolver.resolve(activity.object);
|
const object = await resolver.resolve(activity.object);
|
||||||
|
|
||||||
const uri = (object as any).id;
|
const uri = getApId(object);
|
||||||
|
|
||||||
switch (object.type) {
|
if (validPost.includes(object.type) || object.type === 'Tombstone') {
|
||||||
case 'Note':
|
|
||||||
case 'Question':
|
|
||||||
case 'Article':
|
|
||||||
deleteNote(actor, uri);
|
deleteNote(actor, uri);
|
||||||
break;
|
} else {
|
||||||
|
|
||||||
case 'Tombstone':
|
|
||||||
const note = await Notes.findOne({ uri });
|
|
||||||
if (note != null) {
|
|
||||||
deleteNote(actor, uri);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
apLogger.warn(`Unknown type: ${object.type}`);
|
apLogger.warn(`Unknown type: ${object.type}`);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { deliverQuestionUpdate } from '../../../services/note/polls/update';
|
||||||
import { extractDbHost, toPuny } from '../../../misc/convert-host';
|
import { extractDbHost, toPuny } from '../../../misc/convert-host';
|
||||||
import { Notes, Emojis, Polls } from '../../../models';
|
import { Notes, Emojis, Polls } from '../../../models';
|
||||||
import { Note } from '../../../models/entities/note';
|
import { Note } from '../../../models/entities/note';
|
||||||
import { IObject, INote } from '../type';
|
import { IObject, INote, getApIds, getOneApId, getApId, validPost } from '../type';
|
||||||
import { Emoji } from '../../../models/entities/emoji';
|
import { Emoji } from '../../../models/entities/emoji';
|
||||||
import { genId } from '../../../misc/gen-id';
|
import { genId } from '../../../misc/gen-id';
|
||||||
import { fetchMeta } from '../../../misc/fetch-meta';
|
import { fetchMeta } from '../../../misc/fetch-meta';
|
||||||
|
@ -32,7 +32,7 @@ export function validateNote(object: any, uri: string) {
|
||||||
return new Error('invalid Note: object is null');
|
return new Error('invalid Note: object is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!['Note', 'Question', 'Article'].includes(object.type)) {
|
if (!validPost.includes(object.type)) {
|
||||||
return new Error(`invalid Note: invalied object type ${object.type}`);
|
return new Error(`invalid Note: invalied object type ${object.type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export function validateNote(object: any, uri: string) {
|
||||||
return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${extractDbHost(object.id)}`);
|
return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${extractDbHost(object.id)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object.attributedTo && extractDbHost(object.attributedTo) !== expectHost) {
|
if (object.attributedTo && extractDbHost(getOneApId(object.attributedTo)) !== expectHost) {
|
||||||
return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${extractDbHost(object.attributedTo)}`);
|
return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${extractDbHost(object.attributedTo)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,7 @@ export function validateNote(object: any, uri: string) {
|
||||||
* Misskeyに対象のNoteが登録されていればそれを返します。
|
* Misskeyに対象のNoteが登録されていればそれを返します。
|
||||||
*/
|
*/
|
||||||
export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
|
export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
|
||||||
const uri = typeof value == 'string' ? value : value.id;
|
const uri = getApId(value);
|
||||||
if (uri == null) throw new Error('missing uri');
|
|
||||||
|
|
||||||
// URIがこのサーバーを指しているならデータベースからフェッチ
|
// URIがこのサーバーを指しているならデータベースからフェッチ
|
||||||
if (uri.startsWith(config.url + '/')) {
|
if (uri.startsWith(config.url + '/')) {
|
||||||
|
@ -76,12 +75,12 @@ export async function fetchNote(value: string | IObject, resolver?: Resolver): P
|
||||||
/**
|
/**
|
||||||
* Noteを作成します。
|
* Noteを作成します。
|
||||||
*/
|
*/
|
||||||
export async function createNote(value: any, resolver?: Resolver, silent = false): Promise<Note | null> {
|
export async function createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise<Note | null> {
|
||||||
if (resolver == null) resolver = new Resolver();
|
if (resolver == null) resolver = new Resolver();
|
||||||
|
|
||||||
const object: any = await resolver.resolve(value);
|
const object: any = await resolver.resolve(value);
|
||||||
|
|
||||||
const entryUri = value.id || value;
|
const entryUri = getApId(value);
|
||||||
const err = validateNote(object, entryUri);
|
const err = validateNote(object, entryUri);
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(`${err.message}`, {
|
logger.error(`${err.message}`, {
|
||||||
|
@ -101,7 +100,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||||
logger.info(`Creating the Note: ${note.id}`);
|
logger.info(`Creating the Note: ${note.id}`);
|
||||||
|
|
||||||
// 投稿者をフェッチ
|
// 投稿者をフェッチ
|
||||||
const actor = await resolvePerson(note.attributedTo, resolver) as IRemoteUser;
|
const actor = await resolvePerson(getOneApId(note.attributedTo), resolver) as IRemoteUser;
|
||||||
|
|
||||||
// 投稿者が凍結されていたらスキップ
|
// 投稿者が凍結されていたらスキップ
|
||||||
if (actor.isSuspended) {
|
if (actor.isSuspended) {
|
||||||
|
@ -109,24 +108,24 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region Visibility
|
//#region Visibility
|
||||||
note.to = note.to == null ? [] : typeof note.to == 'string' ? [note.to] : note.to;
|
const to = getApIds(note.to);
|
||||||
note.cc = note.cc == null ? [] : typeof note.cc == 'string' ? [note.cc] : note.cc;
|
const cc = getApIds(note.cc);
|
||||||
|
|
||||||
let visibility = 'public';
|
let visibility = 'public';
|
||||||
let visibleUsers: User[] = [];
|
let visibleUsers: User[] = [];
|
||||||
if (!note.to.includes('https://www.w3.org/ns/activitystreams#Public')) {
|
if (!to.includes('https://www.w3.org/ns/activitystreams#Public')) {
|
||||||
if (note.cc.includes('https://www.w3.org/ns/activitystreams#Public')) {
|
if (cc.includes('https://www.w3.org/ns/activitystreams#Public')) {
|
||||||
visibility = 'home';
|
visibility = 'home';
|
||||||
} else if (note.to.includes(`${actor.uri}/followers`)) { // TODO: person.followerと照合するべき?
|
} else if (to.includes(`${actor.uri}/followers`)) { // TODO: person.followerと照合するべき?
|
||||||
visibility = 'followers';
|
visibility = 'followers';
|
||||||
} else {
|
} else {
|
||||||
visibility = 'specified';
|
visibility = 'specified';
|
||||||
visibleUsers = await Promise.all(note.to.map(uri => resolvePerson(uri, resolver)));
|
visibleUsers = await Promise.all(to.map(uri => resolvePerson(uri, resolver)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endergion
|
//#endergion
|
||||||
|
|
||||||
const apMentions = await extractMentionedUsers(actor, note.to, note.cc, resolver);
|
const apMentions = await extractMentionedUsers(actor, to, cc, resolver);
|
||||||
|
|
||||||
const apHashtags = await extractHashtags(note.tag);
|
const apHashtags = await extractHashtags(note.tag);
|
||||||
|
|
||||||
|
@ -217,11 +216,11 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||||
const apEmojis = emojis.map(emoji => emoji.name);
|
const apEmojis = emojis.map(emoji => emoji.name);
|
||||||
|
|
||||||
const questionUri = note._misskey_question;
|
const questionUri = note._misskey_question;
|
||||||
const poll = await extractPollFromQuestion(note._misskey_question || note).catch(() => undefined);
|
const poll = await extractPollFromQuestion(note._misskey_question || note, resolver).catch(() => undefined);
|
||||||
|
|
||||||
// ユーザーの情報が古かったらついでに更新しておく
|
// ユーザーの情報が古かったらついでに更新しておく
|
||||||
if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
|
if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
|
||||||
updatePerson(note.attributedTo);
|
if (actor.uri) updatePerson(actor.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await post(actor, {
|
return await post(actor, {
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import Resolver from '../resolver';
|
import Resolver from '../resolver';
|
||||||
import { IQuestion } from '../type';
|
import { IObject, IQuestion, isQuestion, } from '../type';
|
||||||
import { apLogger } from '../logger';
|
import { apLogger } from '../logger';
|
||||||
import { Notes, Polls } from '../../../models';
|
import { Notes, Polls } from '../../../models';
|
||||||
import { IPoll } from '../../../models/entities/poll';
|
import { IPoll } from '../../../models/entities/poll';
|
||||||
|
|
||||||
export async function extractPollFromQuestion(source: string | IQuestion): Promise<IPoll> {
|
export async function extractPollFromQuestion(source: string | IObject, resolver?: Resolver): Promise<IPoll> {
|
||||||
const question = typeof source === 'string' ? await new Resolver().resolve(source) as IQuestion : source;
|
if (resolver == null) resolver = new Resolver();
|
||||||
|
|
||||||
|
const question = await resolver.resolve(source);
|
||||||
|
|
||||||
|
if (!isQuestion(question)) {
|
||||||
|
throw new Error('invalid type');
|
||||||
|
}
|
||||||
|
|
||||||
const multiple = !question.oneOf;
|
const multiple = !question.oneOf;
|
||||||
const expiresAt = question.endTime ? new Date(question.endTime) : null;
|
const expiresAt = question.endTime ? new Date(question.endTime) : null;
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ export interface IObject {
|
||||||
id?: string;
|
id?: string;
|
||||||
summary?: string;
|
summary?: string;
|
||||||
published?: string;
|
published?: string;
|
||||||
cc?: string[];
|
cc?: IObject | string | (IObject | string)[];
|
||||||
to?: string[];
|
to?: IObject | string | (IObject | string)[];
|
||||||
attributedTo: string;
|
attributedTo: IObject | string | (IObject | string)[];
|
||||||
attachment?: any[];
|
attachment?: any[];
|
||||||
inReplyTo?: any;
|
inReplyTo?: any;
|
||||||
replies?: ICollection;
|
replies?: ICollection;
|
||||||
|
@ -23,6 +23,32 @@ export interface IObject {
|
||||||
sensitive?: boolean;
|
sensitive?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get array of ActivityStreams Objects id
|
||||||
|
*/
|
||||||
|
export function getApIds(value: IObject | string | (IObject | string)[] | undefined): string[] {
|
||||||
|
if (value == null) return [];
|
||||||
|
const array = Array.isArray(value) ? value : [value];
|
||||||
|
return array.map(x => getApId(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get first ActivityStreams Object id
|
||||||
|
*/
|
||||||
|
export function getOneApId(value: IObject | string | (IObject | string)[]): string {
|
||||||
|
const firstOne = Array.isArray(value) ? value[0] : value;
|
||||||
|
return getApId(firstOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ActivityStreams Object id
|
||||||
|
*/
|
||||||
|
export function getApId(value: string | IObject): string {
|
||||||
|
if (typeof value === 'string') return value;
|
||||||
|
if (typeof value.id === 'string') return value.id;
|
||||||
|
throw new Error(`cannot detemine id`);
|
||||||
|
}
|
||||||
|
|
||||||
export interface IActivity extends IObject {
|
export interface IActivity extends IObject {
|
||||||
//type: 'Activity';
|
//type: 'Activity';
|
||||||
actor: IObject | string;
|
actor: IObject | string;
|
||||||
|
@ -42,8 +68,10 @@ export interface IOrderedCollection extends IObject {
|
||||||
orderedItems: IObject | string | IObject[] | string[];
|
orderedItems: IObject | string | IObject[] | string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const validPost = ['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video'];
|
||||||
|
|
||||||
export interface INote extends IObject {
|
export interface INote extends IObject {
|
||||||
type: 'Note' | 'Question';
|
type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video';
|
||||||
_misskey_content?: string;
|
_misskey_content?: string;
|
||||||
_misskey_quote?: string;
|
_misskey_quote?: string;
|
||||||
_misskey_question?: string;
|
_misskey_question?: string;
|
||||||
|
@ -59,6 +87,9 @@ export interface IQuestion extends IObject {
|
||||||
endTime?: Date;
|
endTime?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isQuestion = (object: IObject): object is IQuestion =>
|
||||||
|
object.type === 'Note' || object.type === 'Question';
|
||||||
|
|
||||||
interface IQuestionChoice {
|
interface IQuestionChoice {
|
||||||
name?: string;
|
name?: string;
|
||||||
replies?: ICollection;
|
replies?: ICollection;
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Users, Notes } from '../../../../models';
|
||||||
import { Note } from '../../../../models/entities/note';
|
import { Note } from '../../../../models/entities/note';
|
||||||
import { User } from '../../../../models/entities/user';
|
import { User } from '../../../../models/entities/user';
|
||||||
import { fetchMeta } from '../../../../misc/fetch-meta';
|
import { fetchMeta } from '../../../../misc/fetch-meta';
|
||||||
import { validActor } from '../../../../remote/activitypub/type';
|
import { validActor, validPost } from '../../../../remote/activitypub/type';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['federation'],
|
tags: ['federation'],
|
||||||
|
@ -145,7 +145,7 @@ async function fetchAny(uri: string) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['Note', 'Question', 'Article'].includes(object.type)) {
|
if (validPost.includes(object.type)) {
|
||||||
const note = await createNote(object.id, undefined, true);
|
const note = await createNote(object.id, undefined, true);
|
||||||
return {
|
return {
|
||||||
type: 'Note',
|
type: 'Note',
|
||||||
|
|
Loading…
Reference in New Issue