summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAkihiko Odaki <nekomanma@pixiv.co.jp>2018-04-02 18:36:47 +0900
committerAkihiko Odaki <nekomanma@pixiv.co.jp>2018-04-02 18:36:47 +0900
commit69763ac32b4e79e84d8338ba8e20b83add9d8560 (patch)
treea3ac499dac06decbc8c47a3d393336f5fbedc56a /src
parentDistribute posts from remote (diff)
downloadmisskey-69763ac32b4e79e84d8338ba8e20b83add9d8560.tar.gz
misskey-69763ac32b4e79e84d8338ba8e20b83add9d8560.tar.bz2
misskey-69763ac32b4e79e84d8338ba8e20b83add9d8560.zip
Resolve account by signature in inbox
Diffstat (limited to 'src')
-rw-r--r--src/processor/http/index.ts2
-rw-r--r--src/processor/http/perform-activitypub.ts2
-rw-r--r--src/processor/http/process-inbox.ts38
-rw-r--r--src/remote/activitypub/resolve-person.ts16
-rw-r--r--src/remote/resolve-user.ts2
-rw-r--r--src/remote/webfinger.ts24
-rw-r--r--src/server/activitypub/inbox.ts42
7 files changed, 71 insertions, 55 deletions
diff --git a/src/processor/http/index.ts b/src/processor/http/index.ts
index a001cf11f7..b3161cb992 100644
--- a/src/processor/http/index.ts
+++ b/src/processor/http/index.ts
@@ -1,10 +1,12 @@
import follow from './follow';
import performActivityPub from './perform-activitypub';
+import processInbox from './process-inbox';
import reportGitHubFailure from './report-github-failure';
const handlers = {
follow,
performActivityPub,
+ processInbox,
reportGitHubFailure,
};
diff --git a/src/processor/http/perform-activitypub.ts b/src/processor/http/perform-activitypub.ts
index d8981ea126..420ed9ec75 100644
--- a/src/processor/http/perform-activitypub.ts
+++ b/src/processor/http/perform-activitypub.ts
@@ -2,5 +2,5 @@ import User from '../../models/user';
import act from '../../remote/activitypub/act';
export default ({ data }, done) => User.findOne({ _id: data.actor })
- .then(actor => act(actor, data.outbox, data.distribute))
+ .then(actor => act(actor, data.outbox, false))
.then(() => done(), done);
diff --git a/src/processor/http/process-inbox.ts b/src/processor/http/process-inbox.ts
new file mode 100644
index 0000000000..78c20f8a7e
--- /dev/null
+++ b/src/processor/http/process-inbox.ts
@@ -0,0 +1,38 @@
+import { verifySignature } from 'http-signature';
+import parseAcct from '../../acct/parse';
+import User, { IRemoteUser } from '../../models/user';
+import act from '../../remote/activitypub/act';
+import resolvePerson from '../../remote/activitypub/resolve-person';
+
+export default ({ data }, done) => (async () => {
+ const keyIdLower = data.signature.keyId.toLowerCase();
+ let user;
+
+ if (keyIdLower.startsWith('acct:')) {
+ const { username, host } = parseAcct(keyIdLower.slice('acct:'.length));
+ if (host === null) {
+ throw 'request was made by local user';
+ }
+
+ user = await User.findOne({ usernameLower: username, hostLower: host }) as IRemoteUser;
+ } else {
+ user = await User.findOne({
+ host: { $ne: null },
+ 'account.publicKey.id': data.signature.keyId
+ }) as IRemoteUser;
+
+ if (user === null) {
+ user = await resolvePerson(data.signature.keyId);
+ }
+ }
+
+ if (user === null) {
+ throw 'failed to resolve user';
+ }
+
+ if (!verifySignature(data.signature, user.account.publicKey.publicKeyPem)) {
+ throw 'signature verification failed';
+ }
+
+ await act(user, data.inbox, true);
+})().then(done, done);
diff --git a/src/remote/activitypub/resolve-person.ts b/src/remote/activitypub/resolve-person.ts
index 4a2636b2f7..59be65908e 100644
--- a/src/remote/activitypub/resolve-person.ts
+++ b/src/remote/activitypub/resolve-person.ts
@@ -10,18 +10,14 @@ async function isCollection(collection) {
return ['Collection', 'OrderedCollection'].includes(collection.type);
}
-export default async (value, usernameLower, hostLower, acctLower) => {
- if (!validateUsername(usernameLower)) {
- throw new Error();
- }
-
+export default async (value, verifier?: string) => {
const { resolver, object } = await new Resolver().resolveOne(value);
if (
object === null ||
object.type !== 'Person' ||
typeof object.preferredUsername !== 'string' ||
- object.preferredUsername.toLowerCase() !== usernameLower ||
+ !validateUsername(object.preferredUsername) ||
!isValidName(object.name) ||
!isValidDescription(object.summary)
) {
@@ -41,9 +37,11 @@ export default async (value, usernameLower, hostLower, acctLower) => {
resolved => isCollection(resolved.object) ? resolved.object : null,
() => null
),
- webFinger(object.id, acctLower),
+ webFinger(object.id, verifier),
]);
+ const host = toUnicode(finger.subject.replace(/^.*?@/, ''));
+ const hostLower = host.replace(/[A-Z]+/, matched => matched.toLowerCase());
const summaryDOM = JSDOM.fragment(object.summary);
// Create user
@@ -58,8 +56,8 @@ export default async (value, usernameLower, hostLower, acctLower) => {
postsCount: outbox ? outbox.totalItem || 0 : 0,
driveCapacity: 1024 * 1024 * 8, // 8MiB
username: object.preferredUsername,
- usernameLower,
- host: toUnicode(finger.subject.replace(/^.*?@/, '')),
+ usernameLower: object.preferredUsername.toLowerCase(),
+ host,
hostLower,
account: {
publicKey: {
diff --git a/src/remote/resolve-user.ts b/src/remote/resolve-user.ts
index a393092839..48219e8cb3 100644
--- a/src/remote/resolve-user.ts
+++ b/src/remote/resolve-user.ts
@@ -19,7 +19,7 @@ export default async (username, host, option) => {
throw new Error();
}
- user = await resolvePerson(self.href, usernameLower, hostLower, acctLower);
+ user = await resolvePerson(self.href, acctLower);
}
return user;
diff --git a/src/remote/webfinger.ts b/src/remote/webfinger.ts
index fec5da689c..4c0304e3f1 100644
--- a/src/remote/webfinger.ts
+++ b/src/remote/webfinger.ts
@@ -12,14 +12,22 @@ type IWebFinger = {
subject: string;
};
-export default (query, verifier): Promise<IWebFinger> => new Promise((res, rej) => webFinger.lookup(query, (error, result) => {
- if (error) {
- return rej(error);
- }
+export default async function resolve(query, verifier?: string): Promise<IWebFinger> {
+ const finger = await new Promise((res, rej) => webFinger.lookup(query, (error, result) => {
+ if (error) {
+ return rej(error);
+ }
+
+ res(result.object);
+ })) as IWebFinger;
+
+ if (verifier) {
+ if (finger.subject.toLowerCase().replace(/^acct:/, '') !== verifier) {
+ throw 'WebFinger verfification failed';
+ }
- if (result.object.subject.toLowerCase().replace(/^acct:/, '') !== verifier) {
- return rej('WebFinger verfification failed');
+ return finger;
}
- res(result.object);
-}));
+ return resolve(finger.subject, finger.subject.toLowerCase());
+}
diff --git a/src/server/activitypub/inbox.ts b/src/server/activitypub/inbox.ts
index 2de2bd9646..5de8433850 100644
--- a/src/server/activitypub/inbox.ts
+++ b/src/server/activitypub/inbox.ts
@@ -1,9 +1,7 @@
import * as bodyParser from 'body-parser';
import * as express from 'express';
-import { parseRequest, verifySignature } from 'http-signature';
-import User, { IRemoteUser } from '../../models/user';
+import { parseRequest } from 'http-signature';
import queue from '../../queue';
-import parseAcct from '../../acct/parse';
const app = express();
@@ -14,48 +12,20 @@ app.post('/@:user/inbox', bodyParser.json({
return true;
}
}), async (req, res) => {
- let parsed;
+ let signature;
req.headers.authorization = 'Signature ' + req.headers.signature;
try {
- parsed = parseRequest(req);
+ signature = parseRequest(req);
} catch (exception) {
return res.sendStatus(401);
}
- const keyIdLower = parsed.keyId.toLowerCase();
- let query;
-
- if (keyIdLower.startsWith('acct:')) {
- const { username, host } = parseAcct(keyIdLower.slice('acct:'.length));
- if (host === null) {
- return res.sendStatus(401);
- }
-
- query = { usernameLower: username, hostLower: host };
- } else {
- query = {
- host: { $ne: null },
- 'account.publicKey.id': parsed.keyId
- };
- }
-
- const user = await User.findOne(query) as IRemoteUser;
-
- if (user === null) {
- return res.sendStatus(401);
- }
-
- if (!verifySignature(parsed, user.account.publicKey.publicKeyPem)) {
- return res.sendStatus(401);
- }
-
queue.create('http', {
- type: 'performActivityPub',
- actor: user._id,
- outbox: req.body,
- distribute: true,
+ type: 'processInbox',
+ inbox: req.body,
+ signature,
}).save();
return res.status(202).end();