1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-03 09:49:20 +02:00

Prefer handle param name

This commit is contained in:
Chocobozzz 2025-04-10 09:55:55 +02:00
parent 6f68db1be9
commit e7753c1b62
No known key found for this signature in database
GPG key ID: 583A612D890159BE
16 changed files with 63 additions and 80 deletions

View file

@ -92,7 +92,7 @@ activityPubClientRouter.get(
asyncMiddleware(accountPlaylistsController) asyncMiddleware(accountPlaylistsController)
) )
activityPubClientRouter.get( activityPubClientRouter.get(
'/accounts?/:name/likes/:videoId', '/accounts?/:accountName/likes/:videoId',
executeIfActivityPub, executeIfActivityPub,
activityPubRateLimiter, activityPubRateLimiter,
cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS), cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS),
@ -100,7 +100,7 @@ activityPubClientRouter.get(
asyncMiddleware(getAccountVideoRateFactory('like')) asyncMiddleware(getAccountVideoRateFactory('like'))
) )
activityPubClientRouter.get( activityPubClientRouter.get(
'/accounts?/:name/dislikes/:videoId', '/accounts?/:accountName/dislikes/:videoId',
executeIfActivityPub, executeIfActivityPub,
activityPubRateLimiter, activityPubRateLimiter,
cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS), cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS),

View file

@ -30,7 +30,8 @@ import {
import { ActorFollowModel } from '../../../models/actor/actor-follow.js' import { ActorFollowModel } from '../../../models/actor/actor-follow.js'
const serverFollowsRouter = express.Router() const serverFollowsRouter = express.Router()
serverFollowsRouter.get('/following', serverFollowsRouter.get(
'/following',
listFollowsValidator, listFollowsValidator,
paginationValidator, paginationValidator,
instanceFollowingSortValidator, instanceFollowingSortValidator,
@ -39,7 +40,8 @@ serverFollowsRouter.get('/following',
asyncMiddleware(listFollowing) asyncMiddleware(listFollowing)
) )
serverFollowsRouter.post('/following', serverFollowsRouter.post(
'/following',
authenticate, authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
followValidator, followValidator,
@ -47,14 +49,16 @@ serverFollowsRouter.post('/following',
asyncMiddleware(addFollow) asyncMiddleware(addFollow)
) )
serverFollowsRouter.delete('/following/:hostOrHandle', serverFollowsRouter.delete(
'/following/:hostOrHandle',
authenticate, authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(removeFollowingValidator), asyncMiddleware(removeFollowingValidator),
asyncMiddleware(removeFollowing) asyncMiddleware(removeFollowing)
) )
serverFollowsRouter.get('/followers', serverFollowsRouter.get(
'/followers',
listFollowsValidator, listFollowsValidator,
paginationValidator, paginationValidator,
instanceFollowersSortValidator, instanceFollowersSortValidator,
@ -63,14 +67,16 @@ serverFollowsRouter.get('/followers',
asyncMiddleware(listFollowers) asyncMiddleware(listFollowers)
) )
serverFollowsRouter.delete('/followers/:nameWithHost', serverFollowsRouter.delete(
'/followers/:handle',
authenticate, authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(getFollowerValidator), asyncMiddleware(getFollowerValidator),
asyncMiddleware(removeFollower) asyncMiddleware(removeFollower)
) )
serverFollowsRouter.post('/followers/:nameWithHost/reject', serverFollowsRouter.post(
'/followers/:handle/reject',
authenticate, authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(getFollowerValidator), asyncMiddleware(getFollowerValidator),
@ -78,7 +84,8 @@ serverFollowsRouter.post('/followers/:nameWithHost/reject',
asyncMiddleware(rejectFollower) asyncMiddleware(rejectFollower)
) )
serverFollowsRouter.post('/followers/:nameWithHost/accept', serverFollowsRouter.post(
'/followers/:handle/accept',
authenticate, authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(getFollowerValidator), asyncMiddleware(getFollowerValidator),

View file

@ -24,30 +24,15 @@ const testEmbedPath = join(distPath, 'standalone', 'videos', 'test-embed.html')
// Special route that add OpenGraph and oEmbed tags // Special route that add OpenGraph and oEmbed tags
// Do not use a template engine for a so little thing // Do not use a template engine for a so little thing
clientsRouter.use([ '/w/p/:id', '/videos/watch/playlist/:id' ], clientsRouter.use([ '/w/p/:id', '/videos/watch/playlist/:id' ], clientsRateLimiter, asyncMiddleware(generateWatchPlaylistHtmlPage))
clientsRateLimiter,
asyncMiddleware(generateWatchPlaylistHtmlPage)
)
clientsRouter.use([ '/w/:id', '/videos/watch/:id' ], clientsRouter.use([ '/w/:id', '/videos/watch/:id' ], clientsRateLimiter, asyncMiddleware(generateWatchHtmlPage))
clientsRateLimiter,
asyncMiddleware(generateWatchHtmlPage)
)
clientsRouter.use([ '/accounts/:nameWithHost', '/a/:nameWithHost' ], clientsRouter.use([ '/accounts/:handle', '/a/:handle' ], clientsRateLimiter, asyncMiddleware(generateAccountHtmlPage))
clientsRateLimiter,
asyncMiddleware(generateAccountHtmlPage)
)
clientsRouter.use([ '/video-channels/:nameWithHost', '/c/:nameWithHost' ], clientsRouter.use([ '/video-channels/:handle', '/c/:handle' ], clientsRateLimiter, asyncMiddleware(generateVideoChannelHtmlPage))
clientsRateLimiter,
asyncMiddleware(generateVideoChannelHtmlPage)
)
clientsRouter.use('/@:nameWithHost', clientsRouter.use('/@:handle', clientsRateLimiter, asyncMiddleware(generateActorHtmlPage))
clientsRateLimiter,
asyncMiddleware(generateActorHtmlPage)
)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -118,10 +103,7 @@ clientsRouter.use('/client/*', (req: express.Request, res: express.Response) =>
// Always serve index client page (the client is a single page application, let it handle routing) // Always serve index client page (the client is a single page application, let it handle routing)
// Try to provide the right language index.html // Try to provide the right language index.html
clientsRouter.use('/(:language)?', clientsRouter.use('/(:language)?', clientsRateLimiter, asyncMiddleware(serveIndexHTML))
clientsRateLimiter,
asyncMiddleware(serveIndexHTML)
)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -206,19 +188,19 @@ async function generateWatchPlaylistHtmlPage (req: express.Request, res: express
} }
async function generateAccountHtmlPage (req: express.Request, res: express.Response) { async function generateAccountHtmlPage (req: express.Request, res: express.Response) {
const html = await ClientHtml.getAccountHTMLPage(req.params.nameWithHost, req, res) const html = await ClientHtml.getAccountHTMLPage(req.params.handle, req, res)
return sendHTML(html, res, true) return sendHTML(html, res, true)
} }
async function generateVideoChannelHtmlPage (req: express.Request, res: express.Response) { async function generateVideoChannelHtmlPage (req: express.Request, res: express.Response) {
const html = await ClientHtml.getVideoChannelHTMLPage(req.params.nameWithHost, req, res) const html = await ClientHtml.getVideoChannelHTMLPage(req.params.handle, req, res)
return sendHTML(html, res, true) return sendHTML(html, res, true)
} }
async function generateActorHtmlPage (req: express.Request, res: express.Response) { async function generateActorHtmlPage (req: express.Request, res: express.Response) {
const html = await ClientHtml.getActorHTMLPage(req.params.nameWithHost, req, res) const html = await ClientHtml.getActorHTMLPage(req.params.handle, req, res)
return sendHTML(html, res, true) return sendHTML(html, res, true)
} }

View file

@ -56,9 +56,9 @@ function getLinkOrThrow (webfingerData: WebFingerData) {
return selfLink.href return selfLink.href
} }
function webfingerLookup (nameWithHost: string) { function webfingerLookup (handle: string) {
return new Promise<WebFingerData>((res, rej) => { return new Promise<WebFingerData>((res, rej) => {
webfinger.lookup(nameWithHost, (err, p) => { webfinger.lookup(handle, (err, p) => {
if (err) return rej(err) if (err) return rej(err)
return res(p.object) return res(p.object)

View file

@ -8,7 +8,6 @@ import { ActorHtml } from './shared/actor-html.js'
import { PageHtml } from './shared/page-html.js' import { PageHtml } from './shared/page-html.js'
class ClientHtml { class ClientHtml {
static invalidateCache () { static invalidateCache () {
PageHtml.invalidateCache() PageHtml.invalidateCache()
} }
@ -39,16 +38,16 @@ class ClientHtml {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
static getAccountHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { static getAccountHTMLPage (handle: string, req: express.Request, res: express.Response) {
return ActorHtml.getAccountHTMLPage(nameWithHost, req, res) return ActorHtml.getAccountHTMLPage(handle, req, res)
} }
static getVideoChannelHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { static getVideoChannelHTMLPage (handle: string, req: express.Request, res: express.Response) {
return ActorHtml.getVideoChannelHTMLPage(nameWithHost, req, res) return ActorHtml.getVideoChannelHTMLPage(handle, req, res)
} }
static getActorHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { static getActorHTMLPage (handle: string, req: express.Request, res: express.Response) {
return ActorHtml.getActorHTMLPage(nameWithHost, req, res) return ActorHtml.getActorHTMLPage(handle, req, res)
} }
} }

View file

@ -11,8 +11,8 @@ import { PageHtml } from './page-html.js'
import { TagsHtml, TagsOptions } from './tags-html.js' import { TagsHtml, TagsOptions } from './tags-html.js'
export class ActorHtml { export class ActorHtml {
static async getAccountHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { static async getAccountHTMLPage (handle: string, req: express.Request, res: express.Response) {
const accountModelPromise = AccountModel.loadByNameWithHost(nameWithHost) const accountModelPromise = AccountModel.loadByHandle(handle)
return this.getAccountOrChannelHTMLPage({ return this.getAccountOrChannelHTMLPage({
loader: () => accountModelPromise, loader: () => accountModelPromise,
@ -22,8 +22,8 @@ export class ActorHtml {
}) })
} }
static async getVideoChannelHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { static async getVideoChannelHTMLPage (handle: string, req: express.Request, res: express.Response) {
const videoChannel = await VideoChannelModel.loadByHandleAndPopulateAccount(nameWithHost) const videoChannel = await VideoChannelModel.loadByHandleAndPopulateAccount(handle)
return this.getAccountOrChannelHTMLPage({ return this.getAccountOrChannelHTMLPage({
loader: () => Promise.resolve(videoChannel), loader: () => Promise.resolve(videoChannel),
@ -33,10 +33,10 @@ export class ActorHtml {
}) })
} }
static async getActorHTMLPage (nameWithHost: string, req: express.Request, res: express.Response) { static async getActorHTMLPage (handle: string, req: express.Request, res: express.Response) {
const [ account, channel ] = await Promise.all([ const [ account, channel ] = await Promise.all([
AccountModel.loadByNameWithHost(nameWithHost), AccountModel.loadByHandle(handle),
VideoChannelModel.loadByHandleAndPopulateAccount(nameWithHost) VideoChannelModel.loadByHandleAndPopulateAccount(handle)
]) ])
return this.getAccountOrChannelHTMLPage({ return this.getAccountOrChannelHTMLPage({

View file

@ -177,7 +177,7 @@ function buildModerationHelpers () {
}, },
blockAccount: async (options: { byAccountId: number, handleToBlock: string }) => { blockAccount: async (options: { byAccountId: number, handleToBlock: string }) => {
const accountToBlock = await AccountModel.loadByNameWithHost(options.handleToBlock) const accountToBlock = await AccountModel.loadByHandle(options.handleToBlock)
if (!accountToBlock) return if (!accountToBlock) return
const user = await UserModel.loadByAccountId(options.byAccountId) const user = await UserModel.loadByAccountId(options.byAccountId)
@ -190,7 +190,7 @@ function buildModerationHelpers () {
}, },
unblockAccount: async (options: { byAccountId: number, handleToUnblock: string }) => { unblockAccount: async (options: { byAccountId: number, handleToUnblock: string }) => {
const targetAccount = await AccountModel.loadByNameWithHost(options.handleToUnblock) const targetAccount = await AccountModel.loadByHandle(options.handleToUnblock)
if (!targetAccount) return if (!targetAccount) return
const accountBlock = await AccountBlocklistModel.loadByAccountAndTarget(options.byAccountId, targetAccount.id) const accountBlock = await AccountBlocklistModel.loadByAccountAndTarget(options.byAccountId, targetAccount.id)

View file

@ -12,8 +12,7 @@ const lTags = loggerTagsFactory('user-import')
type ImportObject = { handle: string | null, host: string | null, archiveFiles?: never } type ImportObject = { handle: string | null, host: string | null, archiveFiles?: never }
export class BlocklistImporter extends AbstractUserImporter <BlocklistExportJSON, ImportObject, ImportObject> { export class BlocklistImporter extends AbstractUserImporter<BlocklistExportJSON, ImportObject, ImportObject> {
protected getImportObjects (json: BlocklistExportJSON) { protected getImportObjects (json: BlocklistExportJSON) {
return [ return [
...json.actors.map(o => ({ handle: o.handle, host: null })), ...json.actors.map(o => ({ handle: o.handle, host: null })),
@ -38,7 +37,7 @@ export class BlocklistImporter extends AbstractUserImporter <BlocklistExportJSON
} }
private async importAccountBlock (handle: string) { private async importAccountBlock (handle: string) {
const accountToBlock = await AccountModel.loadByNameWithHost(handle) const accountToBlock = await AccountModel.loadByHandle(handle)
if (!accountToBlock) { if (!accountToBlock) {
logger.info('Account %s was not blocked on user import because it cannot be found in the database.', handle, lTags()) logger.info('Account %s was not blocked on user import because it cannot be found in the database.', handle, lTags())
return return

View file

@ -15,7 +15,7 @@ export const accountHandleGetValidatorFactory = (options: {
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
if (!await doesAccountHandleExist({ handle: req.params.accountName, res, checkIsLocal, checkManage })) return if (!await doesAccountHandleExist({ handle: req.params.handle, res, checkIsLocal, checkManage })) return
if (options.checkManage) { if (options.checkManage) {
const user = res.locals.oauth.token.User const user = res.locals.oauth.token.User

View file

@ -53,7 +53,6 @@ const followValidator = [
const body: ServerFollowCreate = req.body const body: ServerFollowCreate = req.body
if (body.hosts.length === 0 && body.handles.length === 0) { if (body.hosts.length === 0 && body.handles.length === 0) {
return res return res
.status(HttpStatusCode.BAD_REQUEST_400) .status(HttpStatusCode.BAD_REQUEST_400)
.json({ .json({
@ -94,7 +93,7 @@ const removeFollowingValidator = [
] ]
const getFollowerValidator = [ const getFollowerValidator = [
param('nameWithHost') param('handle')
.custom(isValidActorHandle), .custom(isValidActorHandle),
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
@ -102,19 +101,19 @@ const getFollowerValidator = [
let follow: MActorFollowActorsDefault let follow: MActorFollowActorsDefault
try { try {
const actorUrl = await loadActorUrlOrGetFromWebfinger(req.params.nameWithHost) const actorUrl = await loadActorUrlOrGetFromWebfinger(req.params.handle)
const actor = await ActorModel.loadByUrl(actorUrl) const actor = await ActorModel.loadByUrl(actorUrl)
const serverActor = await getServerActor() const serverActor = await getServerActor()
follow = await ActorFollowModel.loadByActorAndTarget(actor.id, serverActor.id) follow = await ActorFollowModel.loadByActorAndTarget(actor.id, serverActor.id)
} catch (err) { } catch (err) {
logger.warn('Cannot get actor from handle.', { handle: req.params.nameWithHost, err }) logger.warn('Cannot get actor from handle.', { handle: req.params.handle, err })
} }
if (!follow) { if (!follow) {
return res.fail({ return res.fail({
status: HttpStatusCode.NOT_FOUND_404, status: HttpStatusCode.NOT_FOUND_404,
message: `Follower ${req.params.nameWithHost} not found.` message: `Follower ${req.params.handle} not found.`
}) })
} }

View file

@ -26,7 +26,7 @@ export async function doesAccountHandleExist (options: {
}) { }) {
const { handle, res, checkIsLocal, checkManage } = options const { handle, res, checkIsLocal, checkManage } = options
const account = await AccountModel.loadByNameWithHost(handle) const account = await AccountModel.loadByHandle(handle)
return doesAccountExist({ account, res, checkIsLocal, checkManage }) return doesAccountExist({ account, res, checkIsLocal, checkManage })
} }

View file

@ -51,9 +51,6 @@ export const videoChannelsAddValidator = [
] ]
export const videoChannelsUpdateValidator = [ export const videoChannelsUpdateValidator = [
param('nameWithHost')
.exists(),
body('displayName') body('displayName')
.optional() .optional()
.custom(isVideoChannelDisplayNameValid), .custom(isVideoChannelDisplayNameValid),
@ -95,7 +92,7 @@ export const videoChannelsHandleValidatorFactory = (options: {
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
if (!await doesChannelHandleExist({ handle: req.params.nameWithHost, checkManage, checkIsLocal, res })) return if (!await doesChannelHandleExist({ handle: req.params.handle, checkManage, checkIsLocal, res })) return
return next() return next()
} }

View file

@ -28,7 +28,7 @@ const videoUpdateRateValidator = [
const getAccountVideoRateValidatorFactory = function (rateType: VideoRateType) { const getAccountVideoRateValidatorFactory = function (rateType: VideoRateType) {
return [ return [
param('name') param('accountName')
.custom(isAccountNameValid), .custom(isAccountNameValid),
param('videoId') param('videoId')
.custom(isIdValid), .custom(isIdValid),
@ -36,7 +36,7 @@ const getAccountVideoRateValidatorFactory = function (rateType: VideoRateType) {
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
const rate = await AccountVideoRateModel.loadLocalAndPopulateVideo(rateType, req.params.name, +req.params.videoId) const rate = await AccountVideoRateModel.loadLocalAndPopulateVideo(rateType, req.params.accountName, +req.params.videoId)
if (!rate) { if (!rate) {
return res.fail({ return res.fail({
status: HttpStatusCode.NOT_FOUND_404, status: HttpStatusCode.NOT_FOUND_404,

View file

@ -14,8 +14,8 @@ const webfingerValidator = [
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
// Remove 'acct:' from the beginning of the string // Remove 'acct:' from the beginning of the string
const nameWithHost = getHostWithPort(req.query.resource.substr(5)) const handle = getHostWithPort(req.query.resource.substr(5))
const [ name ] = nameWithHost.split('@') const [ name ] = handle.split('@')
const actor = await ActorModel.loadLocalUrlByName(name) const actor = await ActorModel.loadLocalUrlByName(name)
if (!actor) { if (!actor) {

View file

@ -302,8 +302,8 @@ export class AccountModel extends SequelizeModel<AccountModel> {
return AccountModel.findByPk(id, { transaction }) return AccountModel.findByPk(id, { transaction })
} }
static loadByNameWithHost (nameWithHost: string): Promise<MAccountDefault> { static loadByHandle (handle: string): Promise<MAccountDefault> {
const [ accountName, host ] = nameWithHost.split('@') const [ accountName, host ] = handle.split('@')
if (!host || host === WEBSERVER.HOST) return AccountModel.loadLocalByName(accountName) if (!host || host === WEBSERVER.HOST) return AccountModel.loadLocalByName(accountName)

View file

@ -1202,7 +1202,7 @@ paths:
items: items:
$ref: '#/components/schemas/Follow' $ref: '#/components/schemas/Follow'
'/api/v1/server/followers/{nameWithHost}': '/api/v1/server/followers/{handle}':
delete: delete:
summary: Remove or reject a follower to your server summary: Remove or reject a follower to your server
security: security:
@ -1211,7 +1211,7 @@ paths:
tags: tags:
- Instance Follows - Instance Follows
parameters: parameters:
- name: nameWithHost - name: handle
in: path in: path
required: true required: true
description: The remote actor handle to remove from your followers description: The remote actor handle to remove from your followers
@ -1224,7 +1224,7 @@ paths:
'404': '404':
description: follower not found description: follower not found
'/api/v1/server/followers/{nameWithHost}/reject': '/api/v1/server/followers/{handle}/reject':
post: post:
summary: Reject a pending follower to your server summary: Reject a pending follower to your server
security: security:
@ -1233,7 +1233,7 @@ paths:
tags: tags:
- Instance Follows - Instance Follows
parameters: parameters:
- name: nameWithHost - name: handle
in: path in: path
required: true required: true
description: The remote actor handle to remove from your followers description: The remote actor handle to remove from your followers
@ -1246,7 +1246,7 @@ paths:
'404': '404':
description: follower not found description: follower not found
'/api/v1/server/followers/{nameWithHost}/accept': '/api/v1/server/followers/{handle}/accept':
post: post:
summary: Accept a pending follower to your server summary: Accept a pending follower to your server
security: security:
@ -1255,7 +1255,7 @@ paths:
tags: tags:
- Instance Follows - Instance Follows
parameters: parameters:
- name: nameWithHost - name: handle
in: path in: path
required: true required: true
description: The remote actor handle to remove from your followers description: The remote actor handle to remove from your followers