diff --git a/public/openapi/components/schemas/PostsObject.yaml b/public/openapi/components/schemas/PostsObject.yaml index ed546b052ad0..5c68196b2cbf 100644 --- a/public/openapi/components/schemas/PostsObject.yaml +++ b/public/openapi/components/schemas/PostsObject.yaml @@ -1,4 +1,5 @@ PostsObject: + description: One of the objects in the array returned from `Posts.getPostSummaryByPids` type: array items: type: object diff --git a/public/openapi/write.yaml b/public/openapi/write.yaml index ccb94eccfca6..623c6a136fed 100644 --- a/public/openapi/write.yaml +++ b/public/openapi/write.yaml @@ -456,6 +456,84 @@ paths: response: type: object properties: {} + /topics: + post: + tags: + - topics + summary: Create a new topic + description: This operation creates a new topic with a post. Topic creation without a post is not allowed via the Write API as it is an internal-only method. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + cid: + type: number + title: + type: string + content: + type: string + tags: + type: array + items: + type: string + required: + - cid + - title + - content + example: + cid: 1 + title: Test topic + content: This is the test topic's content + responses: + '200': + description: topic successfully created + content: + application/json: + schema: + type: object + properties: + status: + $ref: '#/components/schemas/Status' + response: + $ref: components/schemas/TopicObject.yaml#/TopicObject + /topics/{tid}: + post: + tags: + - topics + summary: Reply to a topic + description: This operation creates a new reply to an existing topic. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + content: + type: string + timestamp: + type: number + toPid: + type: number + required: + - content + example: + content: This is a test reply + responses: + '200': + description: post successfully created + content: + application/json: + schema: + type: object + properties: + status: + $ref: '#/components/schemas/Status' + response: + $ref: components/schemas/PostsObject.yaml#/PostsObject components: schemas: Status: diff --git a/src/controllers/helpers.js b/src/controllers/helpers.js index 08419ee8970d..76dc5f6fa4cf 100644 --- a/src/controllers/helpers.js +++ b/src/controllers/helpers.js @@ -3,6 +3,7 @@ const nconf = require('nconf'); const validator = require('validator'); const querystring = require('querystring'); +const url = require('url'); const _ = require('lodash'); const user = require('../user'); @@ -413,4 +414,28 @@ helpers.generateError = (statusCode, message) => { return payload; }; +helpers.buildReqObject = (req) => { + var headers = req.headers; + var encrypted = !!req.connection.encrypted; + var host = headers.host; + var referer = headers.referer || ''; + if (!host) { + host = url.parse(referer).host || ''; + } + + return { + uid: req.uid, + params: req.params, + method: req.method, + body: req.body, + ip: req.ip, + host: host, + protocol: encrypted ? 'https' : 'http', + secure: encrypted, + url: referer, + path: referer.substr(referer.indexOf(host) + host.length), + headers: headers, + }; +}; + require('../promisify')(helpers); diff --git a/src/controllers/write/index.js b/src/controllers/write/index.js index be642c280768..693c49d2327a 100644 --- a/src/controllers/write/index.js +++ b/src/controllers/write/index.js @@ -3,4 +3,6 @@ const Write = module.exports; Write.users = require('./users'); +Write.groups = require('./groups'); Write.categories = require('./categories'); +Write.topics = require('./topics'); diff --git a/src/middleware/assert.js b/src/middleware/assert.js index 3b80c166a940..72b971eedefb 100644 --- a/src/middleware/assert.js +++ b/src/middleware/assert.js @@ -6,13 +6,23 @@ */ const groups = require('../groups'); +const topics = require('../topics'); + +const helpers = require('../controllers/helpers'); module.exports = function (middleware) { middleware.assertGroup = async (req, res, next) => { const name = await groups.getGroupNameByGroupSlug(req.params.slug); - const exists = await groups.exists(name); - if (!exists) { - throw new Error('[[error:no-group]]'); + if (!name || await groups.exists(name)) { + return helpers.formatApiResponse(404, res, new Error('[[error:no-group]]')); + } + + next(); + }; + + middleware.assertTopic = async (req, res, next) => { + if (!await topics.exists(req.params.tid)) { + return helpers.formatApiResponse(404, res, new Error('[[error:no-topic]]')); } next(); diff --git a/src/routes/write/index.js b/src/routes/write/index.js index 62de9501bee4..46cc85ca40a9 100644 --- a/src/routes/write/index.js +++ b/src/routes/write/index.js @@ -21,11 +21,11 @@ Write.reload = (params) => { }); router.use('/api/v1/users', require('./users')()); - // router.use('/groups', require('./groups')(coreMiddleware)); - // router.use('/posts', require('./posts')(coreMiddleware)); - // router.use('/topics', require('./topics')(coreMiddleware)); + router.use('/api/v1/groups', require('./groups')()); router.use('/api/v1/categories', require('./categories')()); - // router.use('/util', require('./util')(coreMiddleware)); + router.use('/api/v1/topics', require('./topics')()); + // router.use('/api/v1/posts', require('./posts')()); + // router.use('/api/v1/util', require('./util')()); router.get('/api/v1/ping', function (req, res) { helpers.formatApiResponse(200, res, { diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 83d0dfe86d33..1096f59239a2 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -13,6 +13,7 @@ const utils = require('../utils'); const apiController = require('../controllers/api'); +const sockets = require('.'); const SocketPosts = module.exports; require('./posts/edit')(SocketPosts); @@ -23,6 +24,8 @@ require('./posts/tools')(SocketPosts); require('./posts/diffs')(SocketPosts); SocketPosts.reply = async function (socket, data) { + sockets.warnDeprecated(socket, 'POST /api/v1/topics/:tid'); + if (!data || !data.tid || (meta.config.minimumPostLength !== 0 && !data.content)) { throw new Error('[[error:invalid-data]]'); } diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 6669dc8a8909..56e33266b78f 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -6,6 +6,7 @@ const user = require('../user'); const meta = require('../meta'); const apiController = require('../controllers/api'); const privileges = require('../privileges'); +const sockets = require('.'); const socketHelpers = require('./helpers'); const SocketTopics = module.exports; @@ -18,6 +19,8 @@ require('./topics/tags')(SocketTopics); require('./topics/merge')(SocketTopics); SocketTopics.post = async function (socket, data) { + sockets.warnDeprecated(socket, 'POST /api/v1/topics'); + if (!data) { throw new Error('[[error:invalid-data]]'); }