From 388a9c2b18ef71b1530927d5e310d1daeb2351ec Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 1 Apr 2018 14:12:07 +0900 Subject: [PATCH] Implement WebFinger --- src/server/index.ts | 2 ++ src/server/webfinger.ts | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/server/webfinger.ts diff --git a/src/server/index.ts b/src/server/index.ts index 92d46d46a..187479011 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -10,6 +10,7 @@ import * as morgan from 'morgan'; import Accesses from 'accesses'; import activityPub from './activitypub'; +import webFinger from './webfinger'; import log from './log-request'; import config from '../conf'; @@ -55,6 +56,7 @@ app.use((req, res, next) => { app.use('/api', require('./api')); app.use('/files', require('./file')); app.use(activityPub); +app.use(webFinger); app.use(require('./web')); function createServer() { diff --git a/src/server/webfinger.ts b/src/server/webfinger.ts new file mode 100644 index 000000000..864bb4af5 --- /dev/null +++ b/src/server/webfinger.ts @@ -0,0 +1,47 @@ +import config from '../conf'; +import parseAcct from '../common/user/parse-acct'; +import User from '../models/user'; +const express = require('express'); + +const app = express(); + +app.get('/.well-known/webfinger', async (req, res) => { + if (typeof req.query.resource !== 'string') { + return res.sendStatus(400); + } + + const resourceLower = req.query.resource.toLowerCase(); + const webPrefix = config.url.toLowerCase() + '/@'; + let acctLower; + + if (resourceLower.startsWith(webPrefix)) { + acctLower = resourceLower.slice(webPrefix.length); + } else if (resourceLower.startsWith('acct:')) { + acctLower = resourceLower.slice('acct:'.length); + } else { + acctLower = resourceLower; + } + + const parsedAcctLower = parseAcct(acctLower); + if (![null, config.host.toLowerCase()].includes(parsedAcctLower.host)) { + return res.sendStatus(422); + } + + const user = await User.findOne({ usernameLower: parsedAcctLower.username, host: null }); + if (user === null) { + return res.sendStatus(404); + } + + return res.json({ + subject: `acct:${user.username}@${config.host}`, + links: [ + { + rel: 'self', + type: 'application/activity+json', + href: `${config.url}/@${user.username}` + } + ] + }); +}); + +export default app;