Merge branch 'develop'

This commit is contained in:
syuilo 2019-04-18 01:12:21 +09:00
commit 929982117f
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
20 changed files with 209 additions and 134 deletions

View file

@ -141,7 +141,7 @@ export const mfmLanguage = P.createLanguage({
},
hashtag: () => P((input, i) => {
const text = input.substr(i);
const match = text.match(/^#([^\s\.,!\?'"#:\/\[\]]+)/i);
const match = text.match(/^#([^\s\.,!\?'"#:\/\[\]【】]+)/i);
if (!match) return P.makeFailure(i, 'not a hashtag');
let hashtag = match[1];
hashtag = removeOrphanedBrackets(hashtag);

View file

@ -182,6 +182,7 @@ export class NoteRepository extends Repository<Note> {
files: DriveFiles.packMany(note.fileIds),
replyId: note.replyId,
renoteId: note.renoteId,
mentions: note.mentions.length > 0 ? note.mentions : undefined,
uri: note.uri || undefined,
...(opts.detail ? {

View file

@ -1,6 +1,5 @@
import * as Bull from 'bull';
import * as httpSignature from 'http-signature';
import parseAcct from '../../misc/acct/parse';
import { IRemoteUser } from '../../models/entities/user';
import perform from '../../remote/activitypub/perform';
import { resolvePerson, updatePerson } from '../../remote/activitypub/models/person';
@ -12,7 +11,7 @@ import { Instances, Users, UserPublickeys } from '../../models';
import { instanceChart } from '../../services/chart';
import { UserPublickey } from '../../models/entities/user-publickey';
import fetchMeta from '../../misc/fetch-meta';
import { toPuny, toPunyNullable } from '../../misc/convert-host';
import { toPuny } from '../../misc/convert-host';
import { validActor } from '../../remote/activitypub/type';
import { ensure } from '../../prelude/ensure';
@ -35,68 +34,49 @@ export default async (job: Bull.Job): Promise<void> => {
let key: UserPublickey;
if (keyIdLower.startsWith('acct:')) {
const acct = parseAcct(keyIdLower.slice('acct:'.length));
const host = toPunyNullable(acct.host);
const username = toPuny(acct.username);
logger.warn(`Old keyId is no longer supported. ${keyIdLower}`);
return;
}
if (host === null) {
logger.warn(`request was made by local user: @${username}`);
return;
// アクティビティ内のホストの検証
const host = toPuny(new URL(signature.keyId).hostname);
try {
ValidateActivity(activity, host);
} catch (e) {
logger.warn(e.message);
return;
}
// ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
const meta = await fetchMeta();
if (meta.blockedHosts.includes(host)) {
logger.info(`Blocked request: ${host}`);
return;
}
const _key = await UserPublickeys.findOne({
keyId: signature.keyId
});
if (_key) {
// 登録済みユーザー
user = await Users.findOne(_key.userId) as IRemoteUser;
key = _key;
} else {
// 未登録ユーザーの場合はリモート解決
user = await resolvePerson(activity.actor) as IRemoteUser;
if (user == null) {
throw new Error('failed to resolve user');
}
// アクティビティ内のホストの検証
try {
ValidateActivity(activity, host);
} catch (e) {
logger.warn(e.message);
return;
}
// ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
const meta = await fetchMeta();
if (meta.blockedHosts.includes(host)) {
logger.info(`Blocked request: ${host}`);
return;
}
user = await Users.findOne({
usernameLower: username.toLowerCase(),
host: host
}) as IRemoteUser;
key = await UserPublickeys.findOne(user.id).then(ensure);
} else {
// アクティビティ内のホストの検証
const host = toPuny(new URL(signature.keyId).hostname);
try {
ValidateActivity(activity, host);
} catch (e) {
logger.warn(e.message);
return;
}
// ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
const meta = await fetchMeta();
if (meta.blockedHosts.includes(host)) {
logger.info(`Blocked request: ${host}`);
return;
}
key = await UserPublickeys.findOne({
keyId: signature.keyId
}).then(ensure);
user = await Users.findOne(key.userId) as IRemoteUser;
}
// Update Person activityの場合は、ここで署名検証/更新処理まで実施して終了
if (activity.type === 'Update') {
if (activity.object && validActor.includes(activity.object.type)) {
if (user == null) {
logger.warn('Update activity received, but user not registed.');
} else if (!httpSignature.verifySignature(signature, key.keyPem)) {
if (!httpSignature.verifySignature(signature, key.keyPem)) {
logger.warn('Update activity received, but signature verification failed.');
} else {
updatePerson(activity.actor, null, activity.object);
@ -105,15 +85,6 @@ export default async (job: Bull.Job): Promise<void> => {
}
}
// アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
if (user == null) {
user = await resolvePerson(activity.actor) as IRemoteUser;
}
if (user == null) {
throw new Error('failed to resolve user');
}
if (!httpSignature.verifySignature(signature, key.keyPem)) {
logger.error('signature verification failed');
return;

View file

@ -20,21 +20,21 @@ export default async (actor: IRemoteUser, activity: IDelete): Promise<void> => {
const uri = (object as any).id;
switch (object.type) {
case 'Note':
case 'Question':
case 'Article':
deleteNote(actor, uri);
break;
case 'Tombstone':
const note = await Notes.findOne({ uri });
if (note != null) {
case 'Note':
case 'Question':
case 'Article':
deleteNote(actor, uri);
}
break;
break;
default:
apLogger.warn(`Unknown type: ${object.type}`);
break;
case 'Tombstone':
const note = await Notes.findOne({ uri });
if (note != null) {
deleteNote(actor, uri);
}
break;
default:
apLogger.warn(`Unknown type: ${object.type}`);
break;
}
};

View file

@ -2,6 +2,7 @@ import { IRemoteUser } from '../../../models/entities/user';
import { ILike } from '../type';
import create from '../../../services/note/reaction/create';
import { Notes } from '../../../models';
import { apLogger } from '../logger';
export default async (actor: IRemoteUser, activity: ILike) => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
@ -14,7 +15,8 @@ export default async (actor: IRemoteUser, activity: ILike) => {
const note = await Notes.findOne(noteId);
if (note == null) {
throw new Error();
apLogger.warn(`Like activity recivied, but no such note: ${id}`, { id });
return;
}
await create(actor, note, activity._misskey_reaction);