From d814e281a01ab8f984e7b7e0c90eaee518b39419 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 13 Apr 2023 15:22:18 -0400 Subject: [PATCH] feat: write API shorthand to query post routes by their topic index (requires tid in either query string or request body) middleware.checkRequired is also updated to check for matches in req.query as well. --- src/controllers/write/posts.js | 29 +++++++++++++++++++++++++++++ src/middleware/index.js | 2 +- src/routes/write/posts.js | 3 +++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/controllers/write/posts.js b/src/controllers/write/posts.js index 116ab5a38f..12c816e7c3 100644 --- a/src/controllers/write/posts.js +++ b/src/controllers/write/posts.js @@ -1,11 +1,40 @@ 'use strict'; +const nconf = require('nconf'); + +const db = require('../../database'); +const topics = require('../../topics'); const posts = require('../../posts'); const api = require('../../api'); const helpers = require('../helpers'); const Posts = module.exports; +Posts.redirectByIndex = async (req, res, next) => { + const { tid } = req.query || req.body; + + let { index } = req.params; + if (index < 0 || !isFinite(index)) { + index = 0; + } + index = parseInt(index, 10); + + let pid; + if (index === 0) { + pid = await topics.getTopicField(tid, 'mainPid'); + } else { + pid = await db.getSortedSetRange(`tid:${tid}:posts`, index - 1, index - 1); + } + pid = Array.isArray(pid) ? pid[0] : pid; + if (!pid) { + return next('route'); + } + + const path = req.path.split('/').slice(3).join('/'); + const urlObj = new URL(nconf.get('url') + req.url); + res.redirect(308, nconf.get('relative_path') + encodeURI(`/api/v3/posts/${pid}/${path}${urlObj.search}`)); +}; + Posts.get = async (req, res) => { const post = await api.posts.get(req, { pid: req.params.pid }); if (!post) { diff --git a/src/middleware/index.js b/src/middleware/index.js index a92501a7b9..0c44b5cfaf 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -270,7 +270,7 @@ middleware.validateAuth = helpers.try(async (req, res, next) => { middleware.checkRequired = function (fields, req, res, next) { // Used in API calls to ensure that necessary parameters/data values are present - const missing = fields.filter(field => !req.body.hasOwnProperty(field)); + const missing = fields.filter(field => !req.body.hasOwnProperty(field) && !req.query.hasOwnProperty(field)); if (!missing.length) { return next(); diff --git a/src/routes/write/posts.js b/src/routes/write/posts.js index 55c2202ac1..634ba23cdd 100644 --- a/src/routes/write/posts.js +++ b/src/routes/write/posts.js @@ -34,5 +34,8 @@ module.exports = function () { setupApiRoute(router, 'put', '/:pid/diffs/:since', middlewares, controllers.write.posts.restoreDiff); setupApiRoute(router, 'delete', '/:pid/diffs/:timestamp', middlewares, controllers.write.posts.deleteDiff); + // Shorthand route to access post routes by topic index + router.all('/+byIndex/:index*?', [middleware.checkRequired.bind(null, ['tid'])], controllers.write.posts.redirectByIndex); + return router; };