From 51548b31815c6f96f314ae96588a9adca150519d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 15 Nov 2017 10:10:41 +0100 Subject: Add follow tabs Following Follow Followers --- server/controllers/activitypub/client.ts | 4 +- server/controllers/activitypub/index.ts | 5 +- server/controllers/api/application/follows.ts | 127 ++++++++++++++++++++++++++ server/controllers/api/application/index.ts | 12 +++ server/controllers/api/index.ts | 4 +- server/controllers/api/pods.ts | 127 -------------------------- server/controllers/webfinger.ts | 2 +- 7 files changed, 145 insertions(+), 136 deletions(-) create mode 100644 server/controllers/api/application/follows.ts create mode 100644 server/controllers/api/application/index.ts delete mode 100644 server/controllers/api/pods.ts (limited to 'server/controllers') diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 56a4054fa..49dd24e79 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts @@ -46,7 +46,7 @@ async function accountFollowersController (req: express.Request, res: express.Re const page = req.params.page || 1 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) - const result = await db.Account.listAcceptedFollowerUrlsForApi(account.id, start, count) + const result = await db.AccountFollow.listAcceptedFollowerUrlsForApi(account.id, start, count) const activityPubResult = activityPubCollectionPagination(req.url, page, result) return res.json(activityPubResult) @@ -58,7 +58,7 @@ async function accountFollowingController (req: express.Request, res: express.Re const page = req.params.page || 1 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) - const result = await db.Account.listAcceptedFollowingUrlsForApi(account.id, start, count) + const result = await db.AccountFollow.listAcceptedFollowingUrlsForApi(account.id, start, count) const activityPubResult = activityPubCollectionPagination(req.url, page, result) return res.json(activityPubResult) diff --git a/server/controllers/activitypub/index.ts b/server/controllers/activitypub/index.ts index 0c8574ef7..c5bec6448 100644 --- a/server/controllers/activitypub/index.ts +++ b/server/controllers/activitypub/index.ts @@ -1,14 +1,11 @@ import * as express from 'express' - -import { badRequest } from '../../helpers' -import { inboxRouter } from './inbox' import { activityPubClientRouter } from './client' +import { inboxRouter } from './inbox' const activityPubRouter = express.Router() activityPubRouter.use('/', inboxRouter) activityPubRouter.use('/', activityPubClientRouter) -activityPubRouter.use('/*', badRequest) // --------------------------------------------------------------------------- diff --git a/server/controllers/api/application/follows.ts b/server/controllers/api/application/follows.ts new file mode 100644 index 000000000..000bbd23e --- /dev/null +++ b/server/controllers/api/application/follows.ts @@ -0,0 +1,127 @@ +import * as express from 'express' +import { UserRight } from '../../../../shared/models/users/user-right.enum' +import { getFormattedObjects } from '../../../helpers' +import { logger } from '../../../helpers/logger' +import { getApplicationAccount } from '../../../helpers/utils' +import { getAccountFromWebfinger } from '../../../helpers/webfinger' +import { SERVER_ACCOUNT_NAME } from '../../../initializers/constants' +import { database as db } from '../../../initializers/database' +import { sendFollow } from '../../../lib/activitypub/send-request' +import { asyncMiddleware, paginationValidator, setFollowersSort, setPagination } from '../../../middlewares' +import { authenticate } from '../../../middlewares/oauth' +import { setBodyHostsPort } from '../../../middlewares/pods' +import { setFollowingSort } from '../../../middlewares/sort' +import { ensureUserHasRight } from '../../../middlewares/user-right' +import { followValidator } from '../../../middlewares/validators/pods' +import { followersSortValidator, followingSortValidator } from '../../../middlewares/validators/sort' + +const applicationFollowsRouter = express.Router() + +applicationFollowsRouter.get('/following', + paginationValidator, + followingSortValidator, + setFollowingSort, + setPagination, + asyncMiddleware(listFollowing) +) + +applicationFollowsRouter.post('/follow', + authenticate, + ensureUserHasRight(UserRight.MANAGE_APPLICATION_FOLLOW), + followValidator, + setBodyHostsPort, + asyncMiddleware(follow) +) + +applicationFollowsRouter.get('/followers', + paginationValidator, + followersSortValidator, + setFollowersSort, + setPagination, + asyncMiddleware(listFollowers) +) + +// --------------------------------------------------------------------------- + +export { + applicationFollowsRouter +} + +// --------------------------------------------------------------------------- + +async function listFollowing (req: express.Request, res: express.Response, next: express.NextFunction) { + const applicationAccount = await getApplicationAccount() + const resultList = await db.AccountFollow.listFollowingForApi(applicationAccount.id, req.query.start, req.query.count, req.query.sort) + + return res.json(getFormattedObjects(resultList.data, resultList.total)) +} + +async function listFollowers (req: express.Request, res: express.Response, next: express.NextFunction) { + const applicationAccount = await getApplicationAccount() + const resultList = await db.AccountFollow.listFollowersForApi(applicationAccount.id, req.query.start, req.query.count, req.query.sort) + + return res.json(getFormattedObjects(resultList.data, resultList.total)) +} + +async function follow (req: express.Request, res: express.Response, next: express.NextFunction) { + const hosts = req.body.hosts as string[] + const fromAccount = await getApplicationAccount() + + const tasks: Promise[] = [] + const accountName = SERVER_ACCOUNT_NAME + + for (const host of hosts) { + + // We process each host in a specific transaction + // First, we add the follow request in the database + // Then we send the follow request to other account + const p = loadLocalOrGetAccountFromWebfinger(accountName, host) + .then(accountResult => { + let targetAccount = accountResult.account + + return db.sequelize.transaction(async t => { + if (accountResult.loadedFromDB === false) { + targetAccount = await targetAccount.save({ transaction: t }) + } + + const [ accountFollow ] = await db.AccountFollow.findOrCreate({ + where: { + accountId: fromAccount.id, + targetAccountId: targetAccount.id + }, + defaults: { + state: 'pending', + accountId: fromAccount.id, + targetAccountId: targetAccount.id + }, + transaction: t + }) + + // Send a notification to remote server + if (accountFollow.state === 'pending') { + await sendFollow(fromAccount, targetAccount, t) + } + }) + }) + .catch(err => logger.warn('Cannot follow server %s.', `${accountName}@${host}`, err)) + + tasks.push(p) + } + + await Promise.all(tasks) + + return res.status(204).end() +} + +async function loadLocalOrGetAccountFromWebfinger (name: string, host: string) { + let loadedFromDB = true + let account = await db.Account.loadByNameAndHost(name, host) + + if (!account) { + const nameWithDomain = name + '@' + host + account = await getAccountFromWebfinger(nameWithDomain) + loadedFromDB = false + } + + return { account, loadedFromDB } +} diff --git a/server/controllers/api/application/index.ts b/server/controllers/api/application/index.ts new file mode 100644 index 000000000..011b971ed --- /dev/null +++ b/server/controllers/api/application/index.ts @@ -0,0 +1,12 @@ +import * as express from 'express' +import { applicationFollowsRouter } from './follows' + +const applicationRouter = express.Router() + +applicationRouter.use('/', applicationFollowsRouter) + +// --------------------------------------------------------------------------- + +export { + applicationRouter +} diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts index 2e949d531..a22c78cce 100644 --- a/server/controllers/api/index.ts +++ b/server/controllers/api/index.ts @@ -4,15 +4,15 @@ import { badRequest } from '../../helpers' import { oauthClientsRouter } from './oauth-clients' import { configRouter } from './config' -import { podsRouter } from './pods' +import { applicationRouter } from './application' import { usersRouter } from './users' import { videosRouter } from './videos' const apiRouter = express.Router() +apiRouter.use('/application', applicationRouter) apiRouter.use('/oauth-clients', oauthClientsRouter) apiRouter.use('/config', configRouter) -apiRouter.use('/pods', podsRouter) apiRouter.use('/users', usersRouter) apiRouter.use('/videos', videosRouter) apiRouter.use('/ping', pong) diff --git a/server/controllers/api/pods.ts b/server/controllers/api/pods.ts deleted file mode 100644 index 0bd6971bb..000000000 --- a/server/controllers/api/pods.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as express from 'express' -import { UserRight } from '../../../shared/models/users/user-right.enum' -import { getFormattedObjects } from '../../helpers' -import { logger } from '../../helpers/logger' -import { getApplicationAccount } from '../../helpers/utils' -import { getAccountFromWebfinger } from '../../helpers/webfinger' -import { SERVER_ACCOUNT_NAME } from '../../initializers/constants' -import { database as db } from '../../initializers/database' -import { sendFollow } from '../../lib/activitypub/send-request' -import { asyncMiddleware, paginationValidator, setFollowersSort, setPagination } from '../../middlewares' -import { authenticate } from '../../middlewares/oauth' -import { setBodyHostsPort } from '../../middlewares/pods' -import { setFollowingSort } from '../../middlewares/sort' -import { ensureUserHasRight } from '../../middlewares/user-right' -import { followValidator } from '../../middlewares/validators/pods' -import { followersSortValidator, followingSortValidator } from '../../middlewares/validators/sort' - -const podsRouter = express.Router() - -podsRouter.get('/following', - paginationValidator, - followingSortValidator, - setFollowingSort, - setPagination, - asyncMiddleware(listFollowing) -) - -podsRouter.post('/follow', - authenticate, - ensureUserHasRight(UserRight.MANAGE_PEERTUBE_FOLLOW), - followValidator, - setBodyHostsPort, - asyncMiddleware(follow) -) - -podsRouter.get('/followers', - paginationValidator, - followersSortValidator, - setFollowersSort, - setPagination, - asyncMiddleware(listFollowers) -) - -// --------------------------------------------------------------------------- - -export { - podsRouter -} - -// --------------------------------------------------------------------------- - -async function listFollowing (req: express.Request, res: express.Response, next: express.NextFunction) { - const applicationAccount = await getApplicationAccount() - const resultList = await db.Account.listFollowingForApi(applicationAccount.id, req.query.start, req.query.count, req.query.sort) - - return res.json(getFormattedObjects(resultList.data, resultList.total)) -} - -async function listFollowers (req: express.Request, res: express.Response, next: express.NextFunction) { - const applicationAccount = await getApplicationAccount() - const resultList = await db.Account.listFollowersForApi(applicationAccount.id, req.query.start, req.query.count, req.query.sort) - - return res.json(getFormattedObjects(resultList.data, resultList.total)) -} - -async function follow (req: express.Request, res: express.Response, next: express.NextFunction) { - const hosts = req.body.hosts as string[] - const fromAccount = await getApplicationAccount() - - const tasks: Promise[] = [] - const accountName = SERVER_ACCOUNT_NAME - - for (const host of hosts) { - - // We process each host in a specific transaction - // First, we add the follow request in the database - // Then we send the follow request to other account - const p = loadLocalOrGetAccountFromWebfinger(accountName, host) - .then(accountResult => { - let targetAccount = accountResult.account - - return db.sequelize.transaction(async t => { - if (accountResult.loadedFromDB === false) { - targetAccount = await targetAccount.save({ transaction: t }) - } - - const [ accountFollow ] = await db.AccountFollow.findOrCreate({ - where: { - accountId: fromAccount.id, - targetAccountId: targetAccount.id - }, - defaults: { - state: 'pending', - accountId: fromAccount.id, - targetAccountId: targetAccount.id - }, - transaction: t - }) - - // Send a notification to remote server - if (accountFollow.state === 'pending') { - await sendFollow(fromAccount, targetAccount, t) - } - }) - }) - .catch(err => logger.warn('Cannot follow server %s.', `${accountName}@${host}`, err)) - - tasks.push(p) - } - - await Promise.all(tasks) - - return res.status(204).end() -} - -async function loadLocalOrGetAccountFromWebfinger (name: string, host: string) { - let loadedFromDB = true - let account = await db.Account.loadByNameAndHost(name, host) - - if (!account) { - const nameWithDomain = name + '@' + host - account = await getAccountFromWebfinger(nameWithDomain) - loadedFromDB = false - } - - return { account, loadedFromDB } -} diff --git a/server/controllers/webfinger.ts b/server/controllers/webfinger.ts index 1c726f0cb..102ac0937 100644 --- a/server/controllers/webfinger.ts +++ b/server/controllers/webfinger.ts @@ -8,7 +8,7 @@ import { AccountInstance } from '../models/account/account-interface' const webfingerRouter = express.Router() -webfingerRouter.use('/.well-known/webfinger', +webfingerRouter.get('/.well-known/webfinger', webfingerValidator, webfingerController ) -- cgit v1.2.3