summaryrefslogtreecommitdiff
path: root/src/models
diff options
context:
space:
mode:
Diffstat (limited to 'src/models')
-rw-r--r--src/models/follow-request.ts87
-rw-r--r--src/models/notification.ts1
-rw-r--r--src/models/user.ts39
3 files changed, 126 insertions, 1 deletions
diff --git a/src/models/follow-request.ts b/src/models/follow-request.ts
new file mode 100644
index 0000000000..eea5d1c535
--- /dev/null
+++ b/src/models/follow-request.ts
@@ -0,0 +1,87 @@
+import * as mongo from 'mongodb';
+import * as deepcopy from 'deepcopy';
+import db from '../db/mongodb';
+import { pack as packUser } from './user';
+
+const FollowRequest = db.get<IFollowRequest>('followRequests');
+FollowRequest.createIndex(['followerId', 'followeeId'], { unique: true });
+export default FollowRequest;
+
+export type IFollowRequest = {
+ _id: mongo.ObjectID;
+ createdAt: Date;
+ followeeId: mongo.ObjectID;
+ followerId: mongo.ObjectID;
+
+ // 非正規化
+ _followee: {
+ host: string;
+ inbox?: string;
+ },
+ _follower: {
+ host: string;
+ inbox?: string;
+ }
+};
+
+/**
+ * FollowRequestを物理削除します
+ */
+export async function deleteFollowRequest(followRequest: string | mongo.ObjectID | IFollowRequest) {
+ let f: IFollowRequest;
+
+ // Populate
+ if (mongo.ObjectID.prototype.isPrototypeOf(followRequest)) {
+ f = await FollowRequest.findOne({
+ _id: followRequest
+ });
+ } else if (typeof followRequest === 'string') {
+ f = await FollowRequest.findOne({
+ _id: new mongo.ObjectID(followRequest)
+ });
+ } else {
+ f = followRequest as IFollowRequest;
+ }
+
+ if (f == null) return;
+
+ // このFollowingを削除
+ await FollowRequest.remove({
+ _id: f._id
+ });
+}
+
+/**
+ * Pack a request for API response
+ */
+export const pack = (
+ request: any,
+ me?: any
+) => new Promise<any>(async (resolve, reject) => {
+ let _request: any;
+
+ // Populate the request if 'request' is ID
+ if (mongo.ObjectID.prototype.isPrototypeOf(request)) {
+ _request = await FollowRequest.findOne({
+ _id: request
+ });
+ } else if (typeof request === 'string') {
+ _request = await FollowRequest.findOne({
+ _id: new mongo.ObjectID(request)
+ });
+ } else {
+ _request = deepcopy(request);
+ }
+
+ // Rename _id to id
+ _request.id = _request._id;
+ delete _request._id;
+
+ // Populate follower
+ _request.follower = await packUser(_request.followerId, me);
+
+ // Populate followee
+ _request.followee = await packUser(_request.followeeId, me);
+
+ resolve(_request);
+});
diff --git a/src/models/notification.ts b/src/models/notification.ts
index c4cf1e4efd..875c6952b5 100644
--- a/src/models/notification.ts
+++ b/src/models/notification.ts
@@ -111,6 +111,7 @@ export const pack = (notification: any) => new Promise<any>(async (resolve, reje
switch (_notification.type) {
case 'follow':
+ case 'receiveFollowRequest':
// nope
break;
case 'mention':
diff --git a/src/models/user.ts b/src/models/user.ts
index 11eafe05ea..0e06512dae 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -22,6 +22,7 @@ import FollowedLog, { deleteFollowedLog } from './followed-log';
import SwSubscription, { deleteSwSubscription } from './sw-subscription';
import Notification, { deleteNotification } from './notification';
import UserList, { deleteUserList } from './user-list';
+import FollowRequest, { deleteFollowRequest } from './follow-request';
const User = db.get<IUser>('users');
@@ -50,7 +51,22 @@ type IUserBase = {
data: any;
description: string;
pinnedNoteId: mongo.ObjectID;
+
+ /**
+ * 凍結されているか否か
+ */
isSuspended: boolean;
+
+ /**
+ * 鍵アカウントか否か
+ */
+ isLocked: boolean;
+
+ /**
+ * このアカウントに届いているフォローリクエストの数
+ */
+ pendingReceivedFollowRequestsCount: number;
+
host: string;
};
@@ -240,6 +256,16 @@ export async function deleteUser(user: string | mongo.ObjectID | IUser) {
await Following.find({ followeeId: u._id })
).map(x => deleteFollowing(x)));
+ // このユーザーのFollowRequestをすべて削除
+ await Promise.all((
+ await FollowRequest.find({ followerId: u._id })
+ ).map(x => deleteFollowRequest(x)));
+
+ // このユーザーへのFollowRequestをすべて削除
+ await Promise.all((
+ await FollowRequest.find({ followeeId: u._id })
+ ).map(x => deleteFollowRequest(x)));
+
// このユーザーのFollowingLogをすべて削除
await Promise.all((
await FollowingLog.find({ userId: u._id })
@@ -395,7 +421,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
@@ -404,6 +430,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
@@ -414,6 +448,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;