From 35115607bc7eb1ff974c7f7c4d9f14bc8377ee6e Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 1 Jun 2018 00:42:37 +0900 Subject: [PATCH] wip --- src/models/user.ts | 13 ++++++- src/remote/activitypub/kernel/accept/index.ts | 2 +- src/remote/activitypub/kernel/index.ts | 8 ++++- .../activitypub/kernel/reject/follow.ts | 27 ++++++++++++++ src/remote/activitypub/kernel/reject/index.ts | 35 +++++++++++++++++++ src/remote/activitypub/renderer/reject.ts | 4 +++ src/remote/activitypub/type.ts | 5 +++ .../api/endpoints/users/recommendation.ts | 1 + src/services/user/reject-follow-request.ts | 18 ++++++++++ 9 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 src/remote/activitypub/kernel/reject/follow.ts create mode 100644 src/remote/activitypub/kernel/reject/index.ts create mode 100644 src/remote/activitypub/renderer/reject.ts create mode 100644 src/services/user/reject-follow-request.ts diff --git a/src/models/user.ts b/src/models/user.ts index aa051517f1..4186241a59 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -416,7 +416,7 @@ export const pack = ( } if (meId && !meId.equals(_user.id)) { - const [following1, following2, mute] = await Promise.all([ + const [following1, following2, followReq1, followReq2, mute] = await Promise.all([ Following.findOne({ followerId: meId, followeeId: _user.id @@ -425,6 +425,14 @@ export const pack = ( followerId: _user.id, followeeId: meId }), + _user.isLocked ? FollowRequest.findOne({ + followerId: meId, + followeeId: _user.id + }) : Promise.resolve(null), + FollowRequest.findOne({ + followerId: _user.id, + followeeId: meId + }), Mute.findOne({ muterId: meId, muteeId: _user.id @@ -435,6 +443,9 @@ export const pack = ( _user.isFollowing = following1 !== null; _user.isStalking = following1 && following1.stalk; + _user.hasPendingFollowRequestFromYou = followReq1 !== null; + _user.hasPendingFollowRequestToYou = followReq2 !== null; + // Whether the user is followed _user.isFollowed = following2 !== null; diff --git a/src/remote/activitypub/kernel/accept/index.ts b/src/remote/activitypub/kernel/accept/index.ts index b647df022e..2f9d646d14 100644 --- a/src/remote/activitypub/kernel/accept/index.ts +++ b/src/remote/activitypub/kernel/accept/index.ts @@ -25,7 +25,7 @@ export default async (actor: IRemoteUser, activity: IAccept): Promise => { switch (object.type) { case 'Follow': - acceptFollow(resolver, actor, activity, object); + acceptFollow(actor, object); break; default: diff --git a/src/remote/activitypub/kernel/index.ts b/src/remote/activitypub/kernel/index.ts index 15ea9494ae..752a9bd2e2 100644 --- a/src/remote/activitypub/kernel/index.ts +++ b/src/remote/activitypub/kernel/index.ts @@ -6,6 +6,8 @@ import follow from './follow'; import undo from './undo'; import like from './like'; import announce from './announce'; +import accept from './accept'; +import reject from './reject'; const self = async (actor: IRemoteUser, activity: Object): Promise => { switch (activity.type) { @@ -22,7 +24,11 @@ const self = async (actor: IRemoteUser, activity: Object): Promise => { break; case 'Accept': - // noop + await accept(actor, activity); + break; + + case 'Reject': + await reject(actor, activity); break; case 'Announce': diff --git a/src/remote/activitypub/kernel/reject/follow.ts b/src/remote/activitypub/kernel/reject/follow.ts new file mode 100644 index 0000000000..862f3def3b --- /dev/null +++ b/src/remote/activitypub/kernel/reject/follow.ts @@ -0,0 +1,27 @@ +import * as mongo from 'mongodb'; +import User, { IRemoteUser } from '../../../../models/user'; +import config from '../../../../config'; +import reject from '../../../../services/user/reject-follow-request'; +import { IFollow } from '../../type'; + +export default async (actor: IRemoteUser, activity: IFollow): Promise => { + const id = typeof activity.object == 'string' ? activity.object : activity.object.id; + + if (!id.startsWith(config.url + '/')) { + return null; + } + + const follower = await User.findOne({ + _id: new mongo.ObjectID(id.split('/').pop()) + }); + + if (follower === null) { + throw new Error('follower not found'); + } + + if (follower.host != null) { + throw new Error('フォローリクエストしたユーザーはローカルユーザーではありません'); + } + + await reject(actor, follower); +}; diff --git a/src/remote/activitypub/kernel/reject/index.ts b/src/remote/activitypub/kernel/reject/index.ts new file mode 100644 index 0000000000..a82c3fd61e --- /dev/null +++ b/src/remote/activitypub/kernel/reject/index.ts @@ -0,0 +1,35 @@ +import * as debug from 'debug'; + +import Resolver from '../../resolver'; +import { IRemoteUser } from '../../../../models/user'; +import rejectFollow from './follow'; +import { IReject } from '../../type'; + +const log = debug('misskey:activitypub'); + +export default async (actor: IRemoteUser, activity: IReject): Promise => { + const uri = activity.id || activity; + + log(`Reject: ${uri}`); + + const resolver = new Resolver(); + + let object; + + try { + object = await resolver.resolve(activity.object); + } catch (e) { + log(`Resolution failed: ${e}`); + throw e; + } + + switch (object.type) { + case 'Follow': + rejectFollow(actor, object); + break; + + default: + console.warn(`Unknown reject type: ${object.type}`); + break; + } +}; diff --git a/src/remote/activitypub/renderer/reject.ts b/src/remote/activitypub/renderer/reject.ts new file mode 100644 index 0000000000..29c998a6b4 --- /dev/null +++ b/src/remote/activitypub/renderer/reject.ts @@ -0,0 +1,4 @@ +export default object => ({ + type: 'Reject', + object +}); diff --git a/src/remote/activitypub/type.ts b/src/remote/activitypub/type.ts index 77e6bc3045..13e1969b4e 100644 --- a/src/remote/activitypub/type.ts +++ b/src/remote/activitypub/type.ts @@ -83,6 +83,10 @@ export interface IAccept extends IActivity { type: 'Accept'; } +export interface IReject extends IActivity { + type: 'Reject'; +} + export interface ILike extends IActivity { type: 'Like'; _misskey_reaction: string; @@ -100,5 +104,6 @@ export type Object = IUndo | IFollow | IAccept | + IReject | ILike | IAnnounce; diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts index 620ae17ca2..23821a552f 100644 --- a/src/server/api/endpoints/users/recommendation.ts +++ b/src/server/api/endpoints/users/recommendation.ts @@ -36,6 +36,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => { _id: { $nin: followingIds.concat(mutedUserIds) }, + isLocked: false, $or: [{ lastUsedAt: { $gte: new Date(Date.now() - ms('7days')) diff --git a/src/services/user/reject-follow-request.ts b/src/services/user/reject-follow-request.ts new file mode 100644 index 0000000000..32965a1556 --- /dev/null +++ b/src/services/user/reject-follow-request.ts @@ -0,0 +1,18 @@ +import User, { IUser, isRemoteUser, ILocalUser } from "../../models/user"; +import FollowRequest from "../../models/follow-request"; +import pack from '../../remote/activitypub/renderer'; +import renderFollow from '../../remote/activitypub/renderer/follow'; +import renderReject from '../../remote/activitypub/renderer/reject'; +import { deliver } from '../../queue'; + +export default async function(followee: IUser, follower: IUser) { + if (isRemoteUser(follower)) { + const content = pack(renderReject(renderFollow(follower, followee))); + deliver(followee as ILocalUser, content, follower.inbox); + } + + FollowRequest.remove({ + followeeId: followee._id, + followerId: follower._id + }); +}