summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/notify.ts (renamed from src/server/api/common/notify.ts)8
-rw-r--r--src/common/remote/activitypub/act/create.ts2
-rw-r--r--src/common/remote/activitypub/act/index.ts6
-rw-r--r--src/common/remote/activitypub/create.ts11
-rw-r--r--src/common/remote/activitypub/renderer/follow.ts8
-rw-r--r--src/common/remote/activitypub/renderer/key.ts1
-rw-r--r--src/common/remote/activitypub/resolve-person.ts7
-rw-r--r--src/common/remote/activitypub/resolver.ts100
-rw-r--r--src/common/remote/activitypub/type.ts2
-rw-r--r--src/common/remote/resolve-user.ts2
-rw-r--r--src/common/remote/webfinger.ts8
-rw-r--r--src/models/drive-folder.ts2
-rw-r--r--src/models/user.ts1
-rw-r--r--src/processor/http/follow.ts89
-rw-r--r--src/processor/http/index.ts2
-rw-r--r--src/server/activitypub/index.ts2
-rw-r--r--src/server/activitypub/outbox.ts30
-rw-r--r--src/server/activitypub/publickey.ts19
-rw-r--r--src/server/activitypub/user.ts39
-rw-r--r--src/server/activitypub/with-user.ts23
-rw-r--r--src/server/api/endpoints/following/create.ts29
-rw-r--r--src/server/api/endpoints/posts/create.ts2
-rw-r--r--src/server/api/endpoints/posts/polls/vote.ts2
-rw-r--r--src/server/api/endpoints/posts/reactions/create.ts2
24 files changed, 247 insertions, 150 deletions
diff --git a/src/server/api/common/notify.ts b/src/common/notify.ts
index 69bf8480b0..fc65820d3b 100644
--- a/src/server/api/common/notify.ts
+++ b/src/common/notify.ts
@@ -1,8 +1,8 @@
import * as mongo from 'mongodb';
-import Notification from '../../../models/notification';
-import Mute from '../../../models/mute';
-import event from '../../../common/event';
-import { pack } from '../../../models/notification';
+import Notification from '../models/notification';
+import Mute from '../models/mute';
+import event from './event';
+import { pack } from '../models/notification';
export default (
notifiee: mongo.ObjectID,
diff --git a/src/common/remote/activitypub/act/create.ts b/src/common/remote/activitypub/act/create.ts
index 6c62f7ab9e..9eb74800ea 100644
--- a/src/common/remote/activitypub/act/create.ts
+++ b/src/common/remote/activitypub/act/create.ts
@@ -2,7 +2,7 @@ import create from '../create';
export default (resolver, actor, activity) => {
if ('actor' in activity && actor.account.uri !== activity.actor) {
- throw new Error;
+ throw new Error();
}
return create(resolver, actor, activity.object);
diff --git a/src/common/remote/activitypub/act/index.ts b/src/common/remote/activitypub/act/index.ts
index 0f4084a61e..a76983638f 100644
--- a/src/common/remote/activitypub/act/index.ts
+++ b/src/common/remote/activitypub/act/index.ts
@@ -3,8 +3,8 @@ import createObject from '../create';
import Resolver from '../resolver';
export default (actor, value) => {
- return (new Resolver).resolve(value).then(resolved => Promise.all(resolved.map(async asyncResult => {
- const { resolver, object } = await asyncResult;
+ return new Resolver().resolve(value).then(resolved => Promise.all(resolved.map(async promisedResult => {
+ const { resolver, object } = await promisedResult;
const created = await (await createObject(resolver, actor, [object]))[0];
if (created !== null) {
@@ -19,4 +19,4 @@ export default (actor, value) => {
return null;
}
})));
-}
+};
diff --git a/src/common/remote/activitypub/create.ts b/src/common/remote/activitypub/create.ts
index 4aaaeb3060..ea780f01ea 100644
--- a/src/common/remote/activitypub/create.ts
+++ b/src/common/remote/activitypub/create.ts
@@ -3,6 +3,7 @@ import config from '../../../conf';
import Post from '../../../models/post';
import RemoteUserObject, { IRemoteUserObject } from '../../../models/remote-user-object';
import uploadFromUrl from '../../drive/upload_from_url';
+import Resolver from './resolver';
const createDOMPurify = require('dompurify');
function createRemoteUserObject($ref, $id, { id }) {
@@ -17,7 +18,7 @@ function createRemoteUserObject($ref, $id, { id }) {
async function createImage(actor, object) {
if ('attributedTo' in object && actor.account.uri !== object.attributedTo) {
- throw new Error;
+ throw new Error();
}
const { _id } = await uploadFromUrl(object.url, actor);
@@ -26,7 +27,7 @@ async function createImage(actor, object) {
async function createNote(resolver, actor, object) {
if ('attributedTo' in object && actor.account.uri !== object.attributedTo) {
- throw new Error;
+ throw new Error();
}
const mediaIds = 'attachment' in object &&
@@ -69,10 +70,10 @@ async function createNote(resolver, actor, object) {
return createRemoteUserObject('posts', _id, object);
}
-export default async function create(parentResolver, actor, value): Promise<Promise<IRemoteUserObject>[]> {
+export default async function create(parentResolver: Resolver, actor, value): Promise<Array<Promise<IRemoteUserObject>>> {
const results = await parentResolver.resolveRemoteUserObjects(value);
- return results.map(asyncResult => asyncResult.then(({ resolver, object }) => {
+ return results.map(promisedResult => promisedResult.then(({ resolver, object }) => {
switch (object.type) {
case 'Image':
return createImage(actor, object);
@@ -83,4 +84,4 @@ export default async function create(parentResolver, actor, value): Promise<Prom
return null;
}));
-};
+}
diff --git a/src/common/remote/activitypub/renderer/follow.ts b/src/common/remote/activitypub/renderer/follow.ts
new file mode 100644
index 0000000000..05c0ecca06
--- /dev/null
+++ b/src/common/remote/activitypub/renderer/follow.ts
@@ -0,0 +1,8 @@
+import config from '../../../../conf';
+import { IRemoteAccount } from '../../../../models/user';
+
+export default ({ username }, { account }) => ({
+ type: 'Follow',
+ actor: `${config.url}/@${username}`,
+ object: (account as IRemoteAccount).uri
+});
diff --git a/src/common/remote/activitypub/renderer/key.ts b/src/common/remote/activitypub/renderer/key.ts
index 7148c59745..692c71f88e 100644
--- a/src/common/remote/activitypub/renderer/key.ts
+++ b/src/common/remote/activitypub/renderer/key.ts
@@ -3,6 +3,7 @@ import { extractPublic } from '../../../../crypto_key';
import { ILocalAccount } from '../../../../models/user';
export default ({ username, account }) => ({
+ id: `${config.url}/@${username}/publickey`,
type: 'Key',
owner: `${config.url}/@${username}`,
publicKeyPem: extractPublic((account as ILocalAccount).keypair)
diff --git a/src/common/remote/activitypub/resolve-person.ts b/src/common/remote/activitypub/resolve-person.ts
index 999a37eea1..73584946e5 100644
--- a/src/common/remote/activitypub/resolve-person.ts
+++ b/src/common/remote/activitypub/resolve-person.ts
@@ -12,10 +12,10 @@ async function isCollection(collection) {
export default async (value, usernameLower, hostLower, acctLower) => {
if (!validateUsername(usernameLower)) {
- throw new Error;
+ throw new Error();
}
- const { resolver, object } = await (new Resolver).resolveOne(value);
+ const { resolver, object } = await new Resolver().resolveOne(value);
if (
object === null ||
@@ -25,7 +25,7 @@ export default async (value, usernameLower, hostLower, acctLower) => {
!isValidName(object.name) ||
!isValidDescription(object.summary)
) {
- throw new Error;
+ throw new Error();
}
const [followers, following, outbox, finger] = await Promise.all([
@@ -66,6 +66,7 @@ export default async (value, usernameLower, hostLower, acctLower) => {
id: object.publicKey.id,
publicKeyPem: object.publicKey.publicKeyPem
},
+ inbox: object.inbox,
uri: object.id,
},
});
diff --git a/src/common/remote/activitypub/resolver.ts b/src/common/remote/activitypub/resolver.ts
index 50ac1b0b19..a167fa1339 100644
--- a/src/common/remote/activitypub/resolver.ts
+++ b/src/common/remote/activitypub/resolver.ts
@@ -7,80 +7,80 @@ type IResult = {
object: IObject;
};
-async function resolveUnrequestedOne(this: Resolver, value) {
- if (typeof value !== 'string') {
- return { resolver: this, object: value };
+export default class Resolver {
+ private requesting: Set<string>;
+
+ constructor(iterable?: Iterable<string>) {
+ this.requesting = new Set(iterable);
}
- const resolver = new Resolver(this.requesting);
+ private async resolveUnrequestedOne(value) {
+ if (typeof value !== 'string') {
+ return { resolver: this, object: value };
+ }
- resolver.requesting.add(value);
+ const resolver = new Resolver(this.requesting);
- const object = await request({
- url: value,
- headers: {
- Accept: 'application/activity+json, application/ld+json'
- },
- json: true
- });
+ resolver.requesting.add(value);
- if (object === null || (
- Array.isArray(object['@context']) ?
- !object['@context'].includes('https://www.w3.org/ns/activitystreams') :
- object['@context'] !== 'https://www.w3.org/ns/activitystreams'
- )) {
- throw new Error;
- }
+ const object = await request({
+ url: value,
+ headers: {
+ Accept: 'application/activity+json, application/ld+json'
+ },
+ json: true
+ });
- return { resolver, object };
-}
+ if (object === null || (
+ Array.isArray(object['@context']) ?
+ !object['@context'].includes('https://www.w3.org/ns/activitystreams') :
+ object['@context'] !== 'https://www.w3.org/ns/activitystreams'
+ )) {
+ throw new Error();
+ }
-async function resolveCollection(this: Resolver, value) {
- if (Array.isArray(value)) {
- return value;
+ return { resolver, object };
}
- const resolved = typeof value === 'string' ?
- await resolveUnrequestedOne.call(this, value) :
- value;
-
- switch (resolved.type) {
- case 'Collection':
- return resolved.items;
+ private async resolveCollection(value) {
+ if (Array.isArray(value)) {
+ return value;
+ }
- case 'OrderedCollection':
- return resolved.orderedItems;
+ const resolved = typeof value === 'string' ?
+ await this.resolveUnrequestedOne(value) :
+ value;
- default:
- return [resolved];
- }
-}
+ switch (resolved.type) {
+ case 'Collection':
+ return resolved.items;
-export default class Resolver {
- requesting: Set<string>;
+ case 'OrderedCollection':
+ return resolved.orderedItems;
- constructor(iterable?: Iterable<string>) {
- this.requesting = new Set(iterable);
+ default:
+ return [resolved];
+ }
}
- async resolve(value): Promise<Promise<IResult>[]> {
- const collection = await resolveCollection.call(this, value);
+ public async resolve(value): Promise<Array<Promise<IResult>>> {
+ const collection = await this.resolveCollection(value);
return collection
.filter(element => !this.requesting.has(element))
- .map(resolveUnrequestedOne.bind(this));
+ .map(this.resolveUnrequestedOne.bind(this));
}
- resolveOne(value) {
+ public resolveOne(value) {
if (this.requesting.has(value)) {
- throw new Error;
+ throw new Error();
}
- return resolveUnrequestedOne.call(this, value);
+ return this.resolveUnrequestedOne(value);
}
- async resolveRemoteUserObjects(value) {
- const collection = await resolveCollection.call(this, value);
+ public async resolveRemoteUserObjects(value) {
+ const collection = await this.resolveCollection(value);
return collection.filter(element => !this.requesting.has(element)).map(element => {
if (typeof element === 'string') {
@@ -91,7 +91,7 @@ export default class Resolver {
}
}
- return resolveUnrequestedOne.call(this, element);
+ return this.resolveUnrequestedOne(element);
});
}
}
diff --git a/src/common/remote/activitypub/type.ts b/src/common/remote/activitypub/type.ts
index 5c4750e140..94e2c350a2 100644
--- a/src/common/remote/activitypub/type.ts
+++ b/src/common/remote/activitypub/type.ts
@@ -1,3 +1,3 @@
export type IObject = {
type: string;
-}
+};
diff --git a/src/common/remote/resolve-user.ts b/src/common/remote/resolve-user.ts
index 13d155830e..4959539da6 100644
--- a/src/common/remote/resolve-user.ts
+++ b/src/common/remote/resolve-user.ts
@@ -16,7 +16,7 @@ export default async (username, host, option) => {
const finger = await webFinger(acctLower, acctLower);
const self = finger.links.find(link => link.rel && link.rel.toLowerCase() === 'self');
if (!self) {
- throw new Error;
+ throw new Error();
}
user = await resolvePerson(self.href, usernameLower, hostLower, acctLower);
diff --git a/src/common/remote/webfinger.ts b/src/common/remote/webfinger.ts
index 23f0aaa55f..fec5da689c 100644
--- a/src/common/remote/webfinger.ts
+++ b/src/common/remote/webfinger.ts
@@ -1,16 +1,16 @@
const WebFinger = require('webfinger.js');
-const webFinger = new WebFinger({});
+const webFinger = new WebFinger({ });
type ILink = {
href: string;
rel: string;
-}
+};
type IWebFinger = {
- links: Array<ILink>;
+ links: ILink[];
subject: string;
-}
+};
export default (query, verifier): Promise<IWebFinger> => new Promise((res, rej) => webFinger.lookup(query, (error, result) => {
if (error) {
diff --git a/src/models/drive-folder.ts b/src/models/drive-folder.ts
index ad27b151b1..45cc9c9649 100644
--- a/src/models/drive-folder.ts
+++ b/src/models/drive-folder.ts
@@ -3,7 +3,7 @@ import deepcopy = require('deepcopy');
import db from '../db/mongodb';
import DriveFile from './drive-file';
-const DriveFolder = db.get<IDriveFolder>('drive_folders');
+const DriveFolder = db.get<IDriveFolder>('driveFolders');
export default DriveFolder;
export type IDriveFolder = {
diff --git a/src/models/user.ts b/src/models/user.ts
index 9588c45153..d9ac72b88f 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -70,6 +70,7 @@ export type ILocalAccount = {
};
export type IRemoteAccount = {
+ inbox: string;
uri: string;
publicKey: {
id: string;
diff --git a/src/processor/http/follow.ts b/src/processor/http/follow.ts
new file mode 100644
index 0000000000..adaa2f3f65
--- /dev/null
+++ b/src/processor/http/follow.ts
@@ -0,0 +1,89 @@
+import { request } from 'https';
+import { sign } from 'http-signature';
+import { URL } from 'url';
+import User, { ILocalAccount, IRemoteAccount, pack as packUser } from '../../models/user';
+import Following from '../../models/following';
+import event from '../../common/event';
+import notify from '../../common/notify';
+import context from '../../common/remote/activitypub/renderer/context';
+import render from '../../common/remote/activitypub/renderer/follow';
+import config from '../../conf';
+
+export default ({ data }, done) => Following.findOne({ _id: data.following }).then(({ followerId, followeeId }) => {
+ const promisedFollower = User.findOne({ _id: followerId });
+ const promisedFollowee = User.findOne({ _id: followeeId });
+
+ return Promise.all([
+ // Increment following count
+ User.update(followerId, {
+ $inc: {
+ followingCount: 1
+ }
+ }),
+
+ // Increment followers count
+ User.update({ _id: followeeId }, {
+ $inc: {
+ followersCount: 1
+ }
+ }),
+
+ // Notify
+ promisedFollowee.then(followee => followee.host === null ?
+ notify(followeeId, followerId, 'follow') : null),
+
+ // Publish follow event
+ Promise.all([promisedFollower, promisedFollowee]).then(([follower, followee]) => {
+ const followerEvent = packUser(followee, follower)
+ .then(packed => event(follower._id, 'follow', packed));
+ let followeeEvent;
+
+ if (followee.host === null) {
+ followeeEvent = packUser(follower, followee)
+ .then(packed => event(followee._id, 'followed', packed));
+ } else {
+ followeeEvent = new Promise((resolve, reject) => {
+ const {
+ protocol,
+ hostname,
+ port,
+ pathname,
+ search
+ } = new URL(followee.account as IRemoteAccount).inbox);
+
+ const req = request({
+ protocol,
+ hostname,
+ port,
+ method: 'POST',
+ path: pathname + search,
+ }, res => {
+ res.on('close', () => {
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ resolve();
+ } else {
+ reject(res);
+ }
+ });
+
+ res.on('data', () => {});
+ res.on('error', reject);
+ });
+
+ sign(req, {
+ authorizationHeaderName: 'Signature',
+ key: (follower.account as ILocalAccount).keypair,
+ keyId: `acct:${follower.username}@${config.host}`
+ });
+
+ const rendered = render(follower, followee);
+ rendered['@context'] = context;
+
+ req.end(JSON.stringify(rendered));
+ });
+ }
+
+ return Promise.all([followerEvent, followeeEvent]);
+ })
+ ]);
+}).then(done, done);
diff --git a/src/processor/http/index.ts b/src/processor/http/index.ts
index da942ad2a1..a001cf11f7 100644
--- a/src/processor/http/index.ts
+++ b/src/processor/http/index.ts
@@ -1,7 +1,9 @@
+import follow from './follow';
import performActivityPub from './perform-activitypub';
import reportGitHubFailure from './report-github-failure';
const handlers = {
+ follow,
performActivityPub,
reportGitHubFailure,
};
diff --git a/src/server/activitypub/index.ts b/src/server/activitypub/index.ts
index c81024d15f..ac7a184f2a 100644
--- a/src/server/activitypub/index.ts
+++ b/src/server/activitypub/index.ts
@@ -3,6 +3,7 @@ import * as express from 'express';
import user from './user';
import inbox from './inbox';
import outbox from './outbox';
+import publicKey from './publickey';
import post from './post';
const app = express();
@@ -11,6 +12,7 @@ app.disable('x-powered-by');
app.use(user);
app.use(inbox);
app.use(outbox);
+app.use(publicKey);
app.use(post);
export default app;
diff --git a/src/server/activitypub/outbox.ts b/src/server/activitypub/outbox.ts
index c5a42ae0a9..c26c4df75d 100644
--- a/src/server/activitypub/outbox.ts
+++ b/src/server/activitypub/outbox.ts
@@ -2,44 +2,26 @@ import * as express from 'express';
import context from '../../common/remote/activitypub/renderer/context';
import renderNote from '../../common/remote/activitypub/renderer/note';
import renderOrderedCollection from '../../common/remote/activitypub/renderer/ordered-collection';
-import parseAcct from '../../common/user/parse-acct';
import config from '../../conf';
import Post from '../../models/post';
-import User from '../../models/user';
+import withUser from './with-user';
const app = express();
app.disable('x-powered-by');
-app.get('/@:user/outbox', async (req, res) => {
- const { username, host } = parseAcct(req.params.user);
- if (host !== null) {
- return res.sendStatus(422);
- }
-
- const user = await User.findOne({
- usernameLower: username.toLowerCase(),
- host: null
- });
- if (user === null) {
- return res.sendStatus(404);
- }
-
- const id = `${config.url}/@${user.username}/inbox`;
-
- if (username !== user.username) {
- return res.redirect(id);
- }
-
+app.get('/@:user/outbox', withUser(username => {
+ return `${config.url}/@${username}/inbox`;
+}, async (user, req, res) => {
const posts = await Post.find({ userId: user._id }, {
limit: 20,
sort: { _id: -1 }
});
const renderedPosts = await Promise.all(posts.map(post => renderNote(user, post)));
- const rendered = renderOrderedCollection(id, user.postsCount, renderedPosts);
+ const rendered = renderOrderedCollection(`${config.url}/@${user.username}/inbox`, user.postsCount, renderedPosts);
rendered['@context'] = context;
res.json(rendered);
-});
+}));
export default app;
diff --git a/src/server/activitypub/publickey.ts b/src/server/activitypub/publickey.ts
new file mode 100644
index 0000000000..e380309dc4
--- /dev/null
+++ b/src/server/activitypub/publickey.ts
@@ -0,0 +1,19 @@
+import * as express from 'express';
+import context from '../../common/remote/activitypub/renderer/context';
+import render from '../../common/remote/activitypub/renderer/key';
+import config from '../../conf';
+import withUser from './with-user';
+
+const app = express();
+app.disable('x-powered-by');
+
+app.get('/@:user/publickey', withUser(username => {
+ return `${config.url}/@${username}/publickey`;
+}, (user, req, res) => {
+ const rendered = render(user);
+ rendered['@context'] = context;
+
+ res.json(rendered);
+}));
+
+export default app;
diff --git a/src/server/activitypub/user.ts b/src/server/activitypub/user.ts
index d43a9793d4..cfda409e2c 100644
--- a/src/server/activitypub/user.ts
+++ b/src/server/activitypub/user.ts
@@ -2,39 +2,26 @@ import * as express from 'express';
import config from '../../conf';
import context from '../../common/remote/activitypub/renderer/context';
import render from '../../common/remote/activitypub/renderer/person';
-import parseAcct from '../../common/user/parse-acct';
-import User from '../../models/user';
+import withUser from './with-user';
+
+const respond = withUser(username => `${config.url}/@${username}`, (user, req, res) => {
+ const rendered = render(user);
+ rendered['@context'] = context;
+
+ res.json(rendered);
+});
const app = express();
app.disable('x-powered-by');
-app.get('/@:user', async (req, res, next) => {
+app.get('/@:user', (req, res, next) => {
const accepted = req.accepts(['html', 'application/activity+json', 'application/ld+json']);
- if (!(['application/activity+json', 'application/ld+json'] as Array<any>).includes(accepted)) {
- return next();
- }
-
- const { username, host } = parseAcct(req.params.user);
- if (host !== null) {
- return res.sendStatus(422);
- }
-
- const user = await User.findOne({
- usernameLower: username.toLowerCase(),
- host: null
- });
- if (user === null) {
- return res.sendStatus(404);
- }
- if (username !== user.username) {
- return res.redirect(`${config.url}/@${user.username}`);
+ if ((['application/activity+json', 'application/ld+json'] as any[]).includes(accepted)) {
+ respond(req, res, next);
+ } else {
+ next();
}
-
- const rendered = render(user);
- rendered['@context'] = context;
-
- res.json(rendered);
});
export default app;
diff --git a/src/server/activitypub/with-user.ts b/src/server/activitypub/with-user.ts
new file mode 100644
index 0000000000..ed289b641b
--- /dev/null
+++ b/src/server/activitypub/with-user.ts
@@ -0,0 +1,23 @@
+import parseAcct from '../../common/user/parse-acct';
+import User from '../../models/user';
+
+export default (redirect, respond) => async (req, res, next) => {
+ const { username, host } = parseAcct(req.params.user);
+ if (host !== null) {
+ return res.sendStatus(422);
+ }
+
+ const user = await User.findOne({
+ usernameLower: username.toLowerCase(),
+ host: null
+ });
+ if (user === null) {
+ return res.sendStatus(404);
+ }
+
+ if (username !== user.username) {
+ return res.redirect(redirect(user.username));
+ }
+
+ return respond(user, req, res, next);
+};
diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts
index a689250e35..03c13ab7fc 100644
--- a/src/server/api/endpoints/following/create.ts
+++ b/src/server/api/endpoints/following/create.ts
@@ -2,10 +2,9 @@
* Module dependencies
*/
import $ from 'cafy';
-import User, { pack as packUser } from '../../../../models/user';
+import User from '../../../../models/user';
import Following from '../../../../models/following';
-import notify from '../../common/notify';
-import event from '../../../../common/event';
+import queue from '../../../../queue';
/**
* Follow a user
@@ -52,33 +51,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}
// Create following
- await Following.insert({
+ const { _id } = await Following.insert({
createdAt: new Date(),
followerId: follower._id,
followeeId: followee._id
});
+ queue.create('http', { type: 'follow', following: _id }).save();
+
// Send response
res();
- // Increment following count
- User.update(follower._id, {
- $inc: {
- followingCount: 1
- }
- });
-
- // Increment followers count
- User.update({ _id: followee._id }, {
- $inc: {
- followersCount: 1
- }
- });
-
- // Publish follow event
- event(follower._id, 'follow', await packUser(followee, follower));
- event(followee._id, 'followed', await packUser(follower, followee));
-
- // Notify
- notify(followee._id, follower._id, 'follow');
});
diff --git a/src/server/api/endpoints/posts/create.ts b/src/server/api/endpoints/posts/create.ts
index 42901ebcbf..6e7d2329a7 100644
--- a/src/server/api/endpoints/posts/create.ts
+++ b/src/server/api/endpoints/posts/create.ts
@@ -14,9 +14,9 @@ import DriveFile from '../../../../models/drive-file';
import Watching from '../../../../models/post-watching';
import ChannelWatching from '../../../../models/channel-watching';
import { pack } from '../../../../models/post';
-import notify from '../../common/notify';
import watch from '../../common/watch-post';
import event, { pushSw, publishChannelStream } from '../../../../common/event';
+import notify from '../../../../common/notify';
import getAcct from '../../../../common/user/get-acct';
import parseAcct from '../../../../common/user/parse-acct';
import config from '../../../../conf';
diff --git a/src/server/api/endpoints/posts/polls/vote.ts b/src/server/api/endpoints/posts/polls/vote.ts
index 98df074e5d..59b1f099fb 100644
--- a/src/server/api/endpoints/posts/polls/vote.ts
+++ b/src/server/api/endpoints/posts/polls/vote.ts
@@ -5,9 +5,9 @@ import $ from 'cafy';
import Vote from '../../../../../models/poll-vote';
import Post from '../../../../../models/post';
import Watching from '../../../../../models/post-watching';
-import notify from '../../../common/notify';
import watch from '../../../common/watch-post';
import { publishPostStream } from '../../../../../common/event';
+import notify from '../../../../../common/notify';
/**
* Vote poll of a post
diff --git a/src/server/api/endpoints/posts/reactions/create.ts b/src/server/api/endpoints/posts/reactions/create.ts
index 8db76d6436..441d563835 100644
--- a/src/server/api/endpoints/posts/reactions/create.ts
+++ b/src/server/api/endpoints/posts/reactions/create.ts
@@ -6,9 +6,9 @@ import Reaction from '../../../../../models/post-reaction';
import Post, { pack as packPost } from '../../../../../models/post';
import { pack as packUser } from '../../../../../models/user';
import Watching from '../../../../../models/post-watching';
-import notify from '../../../common/notify';
import watch from '../../../common/watch-post';
import { publishPostStream, pushSw } from '../../../../../common/event';
+import notify from '../../../../../common/notify';
/**
* React to a post