From 80badf493afca026bc542260f353210e605a1715 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 6 Dec 2021 16:53:00 +0100 Subject: Add mute status in account and channel pages --- server/controllers/api/blocklist.ts | 108 +++++++++++++++++++++++ server/controllers/api/index.ts | 2 + server/controllers/api/users/my-subscriptions.ts | 21 ++--- 3 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 server/controllers/api/blocklist.ts (limited to 'server/controllers/api') diff --git a/server/controllers/api/blocklist.ts b/server/controllers/api/blocklist.ts new file mode 100644 index 000000000..1e936ad10 --- /dev/null +++ b/server/controllers/api/blocklist.ts @@ -0,0 +1,108 @@ +import express from 'express' +import { handleToNameAndHost } from '@server/helpers/actors' +import { AccountBlocklistModel } from '@server/models/account/account-blocklist' +import { getServerActor } from '@server/models/application/application' +import { ServerBlocklistModel } from '@server/models/server/server-blocklist' +import { MActorAccountId, MUserAccountId } from '@server/types/models' +import { BlockStatus } from '@shared/models' +import { asyncMiddleware, blocklistStatusValidator, optionalAuthenticate } from '../../middlewares' +import { logger } from '@server/helpers/logger' + +const blocklistRouter = express.Router() + +blocklistRouter.get('/status', + optionalAuthenticate, + blocklistStatusValidator, + asyncMiddleware(getBlocklistStatus) +) + +// --------------------------------------------------------------------------- + +export { + blocklistRouter +} + +// --------------------------------------------------------------------------- + +async function getBlocklistStatus (req: express.Request, res: express.Response) { + const hosts = req.query.hosts as string[] + const accounts = req.query.accounts as string[] + const user = res.locals.oauth?.token.User + + const serverActor = await getServerActor() + + const byAccountIds = [ serverActor.Account.id ] + if (user) byAccountIds.push(user.Account.id) + + const status: BlockStatus = { + accounts: {}, + hosts: {} + } + + const baseOptions = { + byAccountIds, + user, + serverActor, + status + } + + await Promise.all([ + populateServerBlocklistStatus({ ...baseOptions, hosts }), + populateAccountBlocklistStatus({ ...baseOptions, accounts }) + ]) + + return res.json(status) +} + +async function populateServerBlocklistStatus (options: { + byAccountIds: number[] + user?: MUserAccountId + serverActor: MActorAccountId + hosts: string[] + status: BlockStatus +}) { + const { byAccountIds, user, serverActor, hosts, status } = options + + if (!hosts || hosts.length === 0) return + + const serverBlocklistStatus = await ServerBlocklistModel.getBlockStatus(byAccountIds, hosts) + + logger.debug('Got server blocklist status.', { serverBlocklistStatus, byAccountIds, hosts }) + + for (const host of hosts) { + const block = serverBlocklistStatus.find(b => b.host === host) + + status.hosts[host] = getStatus(block, serverActor, user) + } +} + +async function populateAccountBlocklistStatus (options: { + byAccountIds: number[] + user?: MUserAccountId + serverActor: MActorAccountId + accounts: string[] + status: BlockStatus +}) { + const { byAccountIds, user, serverActor, accounts, status } = options + + if (!accounts || accounts.length === 0) return + + const accountBlocklistStatus = await AccountBlocklistModel.getBlockStatus(byAccountIds, accounts) + + logger.debug('Got account blocklist status.', { accountBlocklistStatus, byAccountIds, accounts }) + + for (const account of accounts) { + const sanitizedHandle = handleToNameAndHost(account) + + const block = accountBlocklistStatus.find(b => b.name === sanitizedHandle.name && b.host === sanitizedHandle.host) + + status.accounts[sanitizedHandle.handle] = getStatus(block, serverActor, user) + } +} + +function getStatus (block: { accountId: number }, serverActor: MActorAccountId, user?: MUserAccountId) { + return { + blockedByServer: !!(block && block.accountId === serverActor.Account.id), + blockedByUser: !!(block && user && block.accountId === user.Account.id) + } +} diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts index 9949b378a..5f49336b1 100644 --- a/server/controllers/api/index.ts +++ b/server/controllers/api/index.ts @@ -6,6 +6,7 @@ import { badRequest } from '../../helpers/express-utils' import { CONFIG } from '../../initializers/config' import { abuseRouter } from './abuse' import { accountsRouter } from './accounts' +import { blocklistRouter } from './blocklist' import { bulkRouter } from './bulk' import { configRouter } from './config' import { customPageRouter } from './custom-page' @@ -49,6 +50,7 @@ apiRouter.use('/search', searchRouter) apiRouter.use('/overviews', overviewsRouter) apiRouter.use('/plugins', pluginRouter) apiRouter.use('/custom-pages', customPageRouter) +apiRouter.use('/blocklist', blocklistRouter) apiRouter.use('/ping', pong) apiRouter.use('/*', badRequest) diff --git a/server/controllers/api/users/my-subscriptions.ts b/server/controllers/api/users/my-subscriptions.ts index 6799ca8c5..fb1f68635 100644 --- a/server/controllers/api/users/my-subscriptions.ts +++ b/server/controllers/api/users/my-subscriptions.ts @@ -1,5 +1,6 @@ import 'multer' import express from 'express' +import { handlesToNameAndHost } from '@server/helpers/actors' import { pickCommonVideoQuery } from '@server/helpers/query' import { sendUndoFollow } from '@server/lib/activitypub/send' import { guessAdditionalAttributesFromQuery } from '@server/models/video/formatter/video-format-utils' @@ -7,7 +8,6 @@ import { VideoChannelModel } from '@server/models/video/video-channel' import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes' import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils' import { getFormattedObjects } from '../../../helpers/utils' -import { WEBSERVER } from '../../../initializers/constants' import { sequelizeTypescript } from '../../../initializers/database' import { JobQueue } from '../../../lib/job-queue' import { @@ -89,28 +89,23 @@ async function areSubscriptionsExist (req: express.Request, res: express.Respons const uris = req.query.uris as string[] const user = res.locals.oauth.token.User - const handles = uris.map(u => { - let [ name, host ] = u.split('@') - if (host === WEBSERVER.HOST) host = null + const sanitizedHandles = handlesToNameAndHost(uris) - return { name, host, uri: u } - }) - - const results = await ActorFollowModel.listSubscriptionsOf(user.Account.Actor.id, handles) + const results = await ActorFollowModel.listSubscriptionsOf(user.Account.Actor.id, sanitizedHandles) const existObject: { [id: string ]: boolean } = {} - for (const handle of handles) { + for (const sanitizedHandle of sanitizedHandles) { const obj = results.find(r => { const server = r.ActorFollowing.Server - return r.ActorFollowing.preferredUsername === handle.name && + return r.ActorFollowing.preferredUsername === sanitizedHandle.name && ( - (!server && !handle.host) || - (server.host === handle.host) + (!server && !sanitizedHandle.host) || + (server.host === sanitizedHandle.host) ) }) - existObject[handle.uri] = obj !== undefined + existObject[sanitizedHandle.handle] = obj !== undefined } return res.json(existObject) -- cgit v1.2.3