From 350e31d6b64e4973dfa5e9f7b46841cb09aeb1ad Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 14 Nov 2017 17:31:26 +0100 Subject: Follow works --- server/middlewares/activitypub.ts | 32 +++++++++-------- server/middlewares/validators/account.ts | 10 +++--- .../middlewares/validators/activitypub/activity.ts | 7 ++-- server/middlewares/validators/index.ts | 1 + server/middlewares/validators/webfinger.ts | 42 ++++++++++++++++++++++ 5 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 server/middlewares/validators/webfinger.ts (limited to 'server/middlewares') diff --git a/server/middlewares/activitypub.ts b/server/middlewares/activitypub.ts index 6cf8eea6f..bed2bfeab 100644 --- a/server/middlewares/activitypub.ts +++ b/server/middlewares/activitypub.ts @@ -1,12 +1,9 @@ -import { Request, Response, NextFunction } from 'express' - -import { database as db } from '../initializers' -import { - logger, - getAccountFromWebfinger, - isSignatureVerified -} from '../helpers' +import { NextFunction, Request, Response, RequestHandler } from 'express' import { ActivityPubSignature } from '../../shared' +import { isSignatureVerified, logger } from '../helpers' +import { fetchRemoteAccountAndCreatePod } from '../helpers/activitypub' +import { database as db, ACTIVITY_PUB_ACCEPT_HEADER } from '../initializers' +import { each, eachSeries, waterfall } from 'async' async function checkSignature (req: Request, res: Response, next: NextFunction) { const signatureObject: ActivityPubSignature = req.body.signature @@ -17,35 +14,40 @@ async function checkSignature (req: Request, res: Response, next: NextFunction) // We don't have this account in our database, fetch it on remote if (!account) { - account = await getAccountFromWebfinger(signatureObject.creator) + const accountResult = await fetchRemoteAccountAndCreatePod(signatureObject.creator) - if (!account) { + if (!accountResult) { return res.sendStatus(403) } // Save our new account in database + account = accountResult.account await account.save() } const verified = await isSignatureVerified(account, req.body) if (verified === false) return res.sendStatus(403) - res.locals.signature.account = account + res.locals.signature = { + account + } return next() } -function executeIfActivityPub (fun: any | any[]) { +function executeIfActivityPub (fun: RequestHandler | RequestHandler[]) { return (req: Request, res: Response, next: NextFunction) => { - if (req.header('Accept') !== 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"') { + if (req.header('Accept') !== ACTIVITY_PUB_ACCEPT_HEADER) { return next() } if (Array.isArray(fun) === true) { - fun[0](req, res, next) // FIXME: doesn't work + return eachSeries(fun as RequestHandler[], (f, cb) => { + f(req, res, cb) + }, next) } - return fun(req, res, next) + return (fun as RequestHandler)(req, res, next) } } diff --git a/server/middlewares/validators/account.ts b/server/middlewares/validators/account.ts index 3ccf2ea21..58eeed3cc 100644 --- a/server/middlewares/validators/account.ts +++ b/server/middlewares/validators/account.ts @@ -8,13 +8,13 @@ import { isUserVideoQuotaValid, logger } from '../../helpers' -import { isAccountNameWithHostValid } from '../../helpers/custom-validators/video-accounts' +import { isAccountNameValid } from '../../helpers/custom-validators/accounts' import { database as db } from '../../initializers/database' import { AccountInstance } from '../../models' import { checkErrors } from './utils' const localAccountValidator = [ - param('nameWithHost').custom(isAccountNameWithHostValid).withMessage('Should have a valid account with domain name (myuser@domain.tld)'), + param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'), (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking localAccountValidator parameters', { parameters: req.params }) @@ -33,10 +33,8 @@ export { // --------------------------------------------------------------------------- -function checkLocalAccountExists (nameWithHost: string, res: express.Response, callback: (err: Error, account: AccountInstance) => void) { - const [ name, host ] = nameWithHost.split('@') - - db.Account.loadLocalAccountByNameAndPod(name, host) +function checkLocalAccountExists (name: string, res: express.Response, callback: (err: Error, account: AccountInstance) => void) { + db.Account.loadLocalByName(name) .then(account => { if (!account) { return res.status(404) diff --git a/server/middlewares/validators/activitypub/activity.ts b/server/middlewares/validators/activitypub/activity.ts index 78a6d1444..0de8b2d85 100644 --- a/server/middlewares/validators/activitypub/activity.ts +++ b/server/middlewares/validators/activitypub/activity.ts @@ -1,11 +1,10 @@ -import { body } from 'express-validator/check' import * as express from 'express' - -import { logger, isRootActivityValid } from '../../../helpers' +import { body } from 'express-validator/check' +import { isRootActivityValid, logger } from '../../../helpers' import { checkErrors } from '../utils' const activityPubValidator = [ - body('data').custom(isRootActivityValid), + body('').custom((value, { req }) => isRootActivityValid(req.body)), (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking activity pub parameters', { parameters: req.body }) diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts index 46c00d679..92a4bad28 100644 --- a/server/middlewares/validators/index.ts +++ b/server/middlewares/validators/index.ts @@ -8,3 +8,4 @@ export * from './users' export * from './videos' export * from './video-blacklist' export * from './video-channels' +export * from './webfinger' diff --git a/server/middlewares/validators/webfinger.ts b/server/middlewares/validators/webfinger.ts new file mode 100644 index 000000000..068e03ad7 --- /dev/null +++ b/server/middlewares/validators/webfinger.ts @@ -0,0 +1,42 @@ +import { query } from 'express-validator/check' +import * as express from 'express' + +import { checkErrors } from './utils' +import { logger, isWebfingerResourceValid } from '../../helpers' +import { database as db } from '../../initializers' + +const webfingerValidator = [ + query('resource').custom(isWebfingerResourceValid).withMessage('Should have a valid webfinger resource'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + logger.debug('Checking webfinger parameters', { parameters: req.query }) + + checkErrors(req, res, () => { + // Remove 'acct:' from the beginning of the string + const nameWithHost = req.query.resource.substr(5) + const [ name, ] = nameWithHost.split('@') + + db.Account.loadLocalByName(name) + .then(account => { + if (!account) { + return res.status(404) + .send({ error: 'Account not found' }) + .end() + } + + res.locals.account = account + return next() + }) + .catch(err => { + logger.error('Error in webfinger validator.', err) + return res.sendStatus(500) + }) + }) + } +] + +// --------------------------------------------------------------------------- + +export { + webfingerValidator +} -- cgit v1.2.3