summaryrefslogtreecommitdiff
path: root/src/remote/activitypub
diff options
context:
space:
mode:
Diffstat (limited to 'src/remote/activitypub')
-rw-r--r--src/remote/activitypub/kernel/accept/follow.ts27
-rw-r--r--src/remote/activitypub/kernel/accept/index.ts35
-rw-r--r--src/remote/activitypub/kernel/follow.ts2
-rw-r--r--src/remote/activitypub/kernel/index.ts8
-rw-r--r--src/remote/activitypub/kernel/reject/follow.ts27
-rw-r--r--src/remote/activitypub/kernel/reject/index.ts35
-rw-r--r--src/remote/activitypub/kernel/undo/follow.ts13
-rw-r--r--src/remote/activitypub/models/person.ts1
-rw-r--r--src/remote/activitypub/renderer/follow.ts8
-rw-r--r--src/remote/activitypub/renderer/person.ts4
-rw-r--r--src/remote/activitypub/renderer/reject.ts4
-rw-r--r--src/remote/activitypub/type.ts6
12 files changed, 162 insertions, 8 deletions
diff --git a/src/remote/activitypub/kernel/accept/follow.ts b/src/remote/activitypub/kernel/accept/follow.ts
new file mode 100644
index 0000000000..0f414ba321
--- /dev/null
+++ b/src/remote/activitypub/kernel/accept/follow.ts
@@ -0,0 +1,27 @@
+import * as mongo from 'mongodb';
+import User, { IRemoteUser } from '../../../../models/user';
+import config from '../../../../config';
+import accept from '../../../../services/following/requests/accept';
+import { IFollow } from '../../type';
+
+export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
+ 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 accept(actor, follower);
+};
diff --git a/src/remote/activitypub/kernel/accept/index.ts b/src/remote/activitypub/kernel/accept/index.ts
new file mode 100644
index 0000000000..2f9d646d14
--- /dev/null
+++ b/src/remote/activitypub/kernel/accept/index.ts
@@ -0,0 +1,35 @@
+import * as debug from 'debug';
+
+import Resolver from '../../resolver';
+import { IRemoteUser } from '../../../../models/user';
+import acceptFollow from './follow';
+import { IAccept } from '../../type';
+
+const log = debug('misskey:activitypub');
+
+export default async (actor: IRemoteUser, activity: IAccept): Promise<void> => {
+ const uri = activity.id || activity;
+
+ log(`Accept: ${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':
+ acceptFollow(actor, object);
+ break;
+
+ default:
+ console.warn(`Unknown accept type: ${object.type}`);
+ break;
+ }
+};
diff --git a/src/remote/activitypub/kernel/follow.ts b/src/remote/activitypub/kernel/follow.ts
index 7e31eb32ea..464f8582b7 100644
--- a/src/remote/activitypub/kernel/follow.ts
+++ b/src/remote/activitypub/kernel/follow.ts
@@ -23,5 +23,5 @@ export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
throw new Error('フォローしようとしているユーザーはローカルユーザーではありません');
}
- await follow(actor, followee, activity);
+ await follow(actor, followee);
};
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<void> => {
switch (activity.type) {
@@ -22,7 +24,11 @@ const self = async (actor: IRemoteUser, activity: Object): Promise<void> => {
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..c139865d0e
--- /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/following/requests/reject';
+import { IFollow } from '../../type';
+
+export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
+ 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<void> => {
+ 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/kernel/undo/follow.ts b/src/remote/activitypub/kernel/undo/follow.ts
index c0b10c1898..7377984616 100644
--- a/src/remote/activitypub/kernel/undo/follow.ts
+++ b/src/remote/activitypub/kernel/undo/follow.ts
@@ -2,7 +2,9 @@ import * as mongo from 'mongodb';
import User, { IRemoteUser } from '../../../../models/user';
import config from '../../../../config';
import unfollow from '../../../../services/following/delete';
+import cancelRequest from '../../../../services/following/requests/cancel';
import { IFollow } from '../../type';
+import FollowRequest from '../../../../models/follow-request';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
@@ -23,5 +25,14 @@ export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
throw new Error('フォロー解除しようとしているユーザーはローカルユーザーではありません');
}
- await unfollow(actor, followee, activity);
+ const req = await FollowRequest.findOne({
+ followerId: actor._id,
+ followeeId: followee._id
+ });
+
+ if (req) {
+ await cancelRequest(actor, followee);
+ } else {
+ await unfollow(actor, followee);
+ }
};
diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts
index 33280f3d89..b720c445c6 100644
--- a/src/remote/activitypub/models/person.ts
+++ b/src/remote/activitypub/models/person.ts
@@ -93,6 +93,7 @@ export async function createPerson(value: any, resolver?: Resolver): Promise<IUs
notesCount,
name: person.name,
driveCapacity: 1024 * 1024 * 8, // 8MiB
+ isLocked: person.manuallyApprovesFollowers,
username: person.preferredUsername,
usernameLower: person.preferredUsername.toLowerCase(),
host,
diff --git a/src/remote/activitypub/renderer/follow.ts b/src/remote/activitypub/renderer/follow.ts
index bf8eeff06b..522422bcff 100644
--- a/src/remote/activitypub/renderer/follow.ts
+++ b/src/remote/activitypub/renderer/follow.ts
@@ -1,8 +1,8 @@
import config from '../../../config';
-import { IRemoteUser, ILocalUser } from '../../../models/user';
+import { IUser, isLocalUser } from '../../../models/user';
-export default (follower: ILocalUser, followee: IRemoteUser) => ({
+export default (follower: IUser, followee: IUser) => ({
type: 'Follow',
- actor: `${config.url}/users/${follower._id}`,
- object: followee.uri
+ actor: isLocalUser(follower) ? `${config.url}/users/${follower._id}` : follower.uri,
+ object: isLocalUser(followee) ? `${config.url}/users/${followee._id}` : followee.uri
});
diff --git a/src/remote/activitypub/renderer/person.ts b/src/remote/activitypub/renderer/person.ts
index 424305f8d3..b2ac885f46 100644
--- a/src/remote/activitypub/renderer/person.ts
+++ b/src/remote/activitypub/renderer/person.ts
@@ -1,8 +1,9 @@
import renderImage from './image';
import renderKey from './key';
import config from '../../../config';
+import { ILocalUser } from '../../../models/user';
-export default user => {
+export default (user: ILocalUser) => {
const id = `${config.url}/users/${user._id}`;
return {
@@ -17,6 +18,7 @@ export default user => {
summary: user.description,
icon: user.avatarId && renderImage({ _id: user.avatarId }),
image: user.bannerId && renderImage({ _id: user.bannerId }),
+ manuallyApprovesFollowers: user.isLocked,
publicKey: renderKey(user)
};
};
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 ca38ec2227..13e1969b4e 100644
--- a/src/remote/activitypub/type.ts
+++ b/src/remote/activitypub/type.ts
@@ -45,6 +45,7 @@ export interface IPerson extends IObject {
type: 'Person';
name: string;
preferredUsername: string;
+ manuallyApprovesFollowers: boolean;
inbox: string;
publicKey: any;
followers: any;
@@ -82,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;
@@ -99,5 +104,6 @@ export type Object =
IUndo |
IFollow |
IAccept |
+ IReject |
ILike |
IAnnounce;