mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: added POST /api/v1/categories route
This commit is contained in:
145
openapi.yaml
145
openapi.yaml
@@ -8,11 +8,15 @@ info:
|
||||
license:
|
||||
name: MIT
|
||||
url: 'https://opensource.org/licenses/MIT'
|
||||
servers:
|
||||
- url: /api/v1
|
||||
tags:
|
||||
- name: users
|
||||
description: 'Account related calls (create, modify, delete, etc.)'
|
||||
- name: categories
|
||||
description: Administrative calls to manage categories
|
||||
paths:
|
||||
/:
|
||||
/users/:
|
||||
post:
|
||||
tags:
|
||||
- users
|
||||
@@ -94,7 +98,7 @@ paths:
|
||||
$ref: '#/components/schemas/Status'
|
||||
response:
|
||||
type: object
|
||||
'/{uid}':
|
||||
'/users/{uid}':
|
||||
put:
|
||||
tags:
|
||||
- users
|
||||
@@ -155,7 +159,7 @@ paths:
|
||||
$ref: '#/components/schemas/Status'
|
||||
response:
|
||||
type: object
|
||||
'/{uid}/password':
|
||||
'/users/{uid}/password':
|
||||
put:
|
||||
tags:
|
||||
- users
|
||||
@@ -195,7 +199,7 @@ paths:
|
||||
$ref: '#/components/schemas/Status'
|
||||
response:
|
||||
type: object
|
||||
'/{uid}/follow':
|
||||
'/users/{uid}/follow':
|
||||
post:
|
||||
tags:
|
||||
- users
|
||||
@@ -242,7 +246,7 @@ paths:
|
||||
$ref: '#/components/schemas/Status'
|
||||
response:
|
||||
type: object
|
||||
'/{uid}/ban':
|
||||
'/users/{uid}/ban':
|
||||
put:
|
||||
tags:
|
||||
- users
|
||||
@@ -302,6 +306,65 @@ paths:
|
||||
$ref: '#/components/schemas/Status'
|
||||
response:
|
||||
type: object
|
||||
/categories/:
|
||||
post:
|
||||
tags:
|
||||
- categories
|
||||
summary: creates a category
|
||||
description: This operation creates a new category
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
parentCid:
|
||||
type: number
|
||||
cloneFromCid:
|
||||
type: number
|
||||
icon:
|
||||
type: string
|
||||
description: A ForkAwesome icon without the `fa-` prefix
|
||||
bgColor:
|
||||
type: string
|
||||
color:
|
||||
type: string
|
||||
link:
|
||||
type: string
|
||||
class:
|
||||
type: string
|
||||
backgroundImage:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
example:
|
||||
name: My New Category
|
||||
description: Lorem ipsum, dolor sit amet
|
||||
parentCid: 0
|
||||
cloneFromCid: 0
|
||||
icon: bullhorn
|
||||
bgColor: '#ffffff'
|
||||
color: '#000000'
|
||||
link: 'https://example.org'
|
||||
class: 'col-md-3 col-xs-6'
|
||||
backgroundImage: '/assets/relative/path/to/image'
|
||||
responses:
|
||||
'200':
|
||||
description: category successfully created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
$ref: '#/components/schemas/Status'
|
||||
response:
|
||||
$ref: '#/components/schemas/CategoryObj'
|
||||
components:
|
||||
schemas:
|
||||
Status:
|
||||
@@ -479,6 +542,78 @@ components:
|
||||
This is a paragraph all about how my life got twist-turned upside-down
|
||||
and I'd like to take a minute and sit right here,
|
||||
to tell you all about how I because the administrator of NodeBB
|
||||
CategoryObj:
|
||||
properties:
|
||||
cid:
|
||||
type: number
|
||||
example: 1
|
||||
name:
|
||||
type: string
|
||||
example: My New Category
|
||||
description:
|
||||
type: string
|
||||
example: Lorem ipsum, dolor sit amet
|
||||
descriptionParsed:
|
||||
type: string
|
||||
example: Lorem ipsum, dolor sit amet
|
||||
icon:
|
||||
type: string
|
||||
example: bullhorn
|
||||
bgColor:
|
||||
type: string
|
||||
example: '#ffffff'
|
||||
color:
|
||||
type: string
|
||||
example: '#000000'
|
||||
slug:
|
||||
type: string
|
||||
example: 1/my-new-category
|
||||
parentCid:
|
||||
type: number
|
||||
example: 0
|
||||
topic_count:
|
||||
type: number
|
||||
example: 0
|
||||
post_count:
|
||||
type: number
|
||||
example: 0
|
||||
disabled:
|
||||
type: number
|
||||
example: 0
|
||||
order:
|
||||
type: number
|
||||
example: 5
|
||||
link:
|
||||
type: number
|
||||
example: 'https://example.org'
|
||||
numRecentReplies:
|
||||
type: number
|
||||
example: 1
|
||||
class:
|
||||
type: string
|
||||
example: col-md-3 col-xs-6
|
||||
imageClass:
|
||||
type: string
|
||||
example: cover
|
||||
isSection:
|
||||
type: number
|
||||
example: 0
|
||||
totalPostCount:
|
||||
type: number
|
||||
example: 0
|
||||
totalTopicCount:
|
||||
type: number
|
||||
example: 0
|
||||
tagWhitelist:
|
||||
type: array
|
||||
example:
|
||||
- some-tag
|
||||
- another-tag
|
||||
unread-class:
|
||||
type: string
|
||||
backgroundImage:
|
||||
type: string
|
||||
example: '/assets/images/covers/Circuit1.png'
|
||||
responses:
|
||||
'400':
|
||||
description: Bad Request
|
||||
|
||||
13
src/controllers/write/categories.js
Normal file
13
src/controllers/write/categories.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
const categories = require('../../categories');
|
||||
|
||||
const helpers = require('../helpers');
|
||||
|
||||
const Categories = module.exports;
|
||||
|
||||
Categories.create = async (req, res) => {
|
||||
const response = await categories.create(req.body);
|
||||
const categoryObjs = await categories.getCategories([response.cid]);
|
||||
helpers.formatApiResponse(200, res, categoryObjs[0]);
|
||||
};
|
||||
@@ -3,3 +3,4 @@
|
||||
const Write = module.exports;
|
||||
|
||||
Write.users = require('./users');
|
||||
Write.categories = require('./categories');
|
||||
|
||||
86
src/routes/write/categories.js
Normal file
86
src/routes/write/categories.js
Normal file
@@ -0,0 +1,86 @@
|
||||
'use strict';
|
||||
|
||||
const router = require('express').Router();
|
||||
const middleware = require('../../middleware');
|
||||
const controllers = require('../../controllers');
|
||||
const routeHelpers = require('../../routes/helpers');
|
||||
|
||||
const setupApiRoute = routeHelpers.setupApiRoute;
|
||||
|
||||
module.exports = function () {
|
||||
const middlewares = [middleware.authenticate];
|
||||
|
||||
setupApiRoute(router, '/', middleware, [...middlewares, middleware.checkRequired.bind(null, ['name'])], 'post', controllers.write.categories.create);
|
||||
|
||||
// app.post('/', apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
|
||||
// if (!utils.checkRequired(['name'], req, res)) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// Categories.create(req.body, function(err, categoryObj) {
|
||||
// return errorHandler.handle(err, res, categoryObj);
|
||||
// });
|
||||
// });
|
||||
|
||||
// app.route('/:cid')
|
||||
// .put(apiMiddleware.requireUser, apiMiddleware.requireAdmin, apiMiddleware.validateCid, function(req, res) {
|
||||
// var payload = {};
|
||||
// payload[req.params.cid] = req.body;
|
||||
|
||||
// Categories.update(payload, function(err) {
|
||||
// return errorHandler.handle(err, res);
|
||||
// });
|
||||
// })
|
||||
// .delete(apiMiddleware.requireUser, apiMiddleware.requireAdmin, apiMiddleware.validateCid, function(req, res) {
|
||||
// Categories.purge(req.params.cid, req.user.uid, function(err) {
|
||||
// return errorHandler.handle(err, res);
|
||||
// });
|
||||
// });
|
||||
|
||||
// app.route('/:cid/state')
|
||||
// .put(apiMiddleware.requireUser, apiMiddleware.requireAdmin, apiMiddleware.validateCid, function(req, res) {
|
||||
// var payload = {};
|
||||
// payload[req.params.cid] = {
|
||||
// disabled: 0
|
||||
// };
|
||||
|
||||
// Categories.update(payload, function(err) {
|
||||
// return errorHandler.handle(err, res);
|
||||
// });
|
||||
// })
|
||||
// .delete(apiMiddleware.requireUser, apiMiddleware.requireAdmin, apiMiddleware.validateCid, function(req, res) {
|
||||
// var payload = {};
|
||||
// payload[req.params.cid] = {
|
||||
// disabled: 1
|
||||
// };
|
||||
|
||||
// Categories.update(payload, function(err) {
|
||||
// return errorHandler.handle(err, res);
|
||||
// });
|
||||
// });
|
||||
|
||||
// app.route('/:cid/privileges')
|
||||
// .put(apiMiddleware.requireUser, apiMiddleware.requireAdmin, apiMiddleware.validateCidIncludingGlobal, function(req, res) {
|
||||
// changeGroupMembership(req.params.cid, req.body.privileges, req.body.groups, 'join', function(err) {
|
||||
// return errorHandler.handle(err, res);
|
||||
// });
|
||||
// })
|
||||
// .delete(apiMiddleware.requireUser, apiMiddleware.requireAdmin, apiMiddleware.validateCidIncludingGlobal, function(req, res) {
|
||||
// changeGroupMembership(req.params.cid, req.body.privileges, req.body.groups, 'leave', function(err) {
|
||||
// return errorHandler.handle(err, res);
|
||||
// });
|
||||
// });
|
||||
|
||||
// function changeGroupMembership(cid, privileges, groups, action, callback) {
|
||||
// privileges = Array.isArray(privileges) ? privileges : [privileges];
|
||||
// groups = Array.isArray(groups) ? groups : [groups];
|
||||
|
||||
// async.each(groups, function(group, groupCb) {
|
||||
// async.each(privileges, function(privilege, privilegeCb) {
|
||||
// Groups[action]('cid:' + cid + ':privileges:' + privilege, group, privilegeCb);
|
||||
// }, groupCb);
|
||||
// }, callback);
|
||||
// }
|
||||
|
||||
return router;
|
||||
};
|
||||
@@ -24,7 +24,7 @@ Write.reload = (params) => {
|
||||
// router.use('/groups', require('./groups')(coreMiddleware));
|
||||
// router.use('/posts', require('./posts')(coreMiddleware));
|
||||
// router.use('/topics', require('./topics')(coreMiddleware));
|
||||
// router.use('/categories', require('./categories')(coreMiddleware));
|
||||
router.use('/api/v1/categories', require('./categories')());
|
||||
// router.use('/util', require('./util')(coreMiddleware));
|
||||
|
||||
router.get('/api/v1/ping', function (req, res) {
|
||||
|
||||
@@ -6,12 +6,6 @@ const controllers = require('../../controllers');
|
||||
const routeHelpers = require('../helpers');
|
||||
|
||||
const setupApiRoute = routeHelpers.setupApiRoute;
|
||||
// Messaging = require.main.require('./src/messaging'),
|
||||
// apiMiddleware = require('./middleware'),
|
||||
// errorHandler = require('../../lib/errorHandler'),
|
||||
// auth = require('../../lib/auth'),
|
||||
// utils = require('./utils'),
|
||||
// async = require.main.require('async');
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function guestRoutes() {
|
||||
@@ -35,52 +29,6 @@ function authenticatedRoutes() {
|
||||
setupApiRoute(router, '/:uid/ban', middleware, [...middlewares, middleware.exposePrivileges], 'put', controllers.write.users.ban);
|
||||
setupApiRoute(router, '/:uid/ban', middleware, [...middlewares, middleware.exposePrivileges], 'delete', controllers.write.users.unban);
|
||||
|
||||
// app.route('/:uid/ban')
|
||||
// .put(apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
|
||||
// Users.bans.ban(req.params.uid, req.body.until || 0, req.body.reason || '', function(err) {
|
||||
// errorHandler.handle(err, res);
|
||||
// });
|
||||
// })
|
||||
// .delete(apiMiddleware.requireUser, apiMiddleware.requireAdmin, function(req, res) {
|
||||
// Users.bans.unban(req.params.uid, function(err) {
|
||||
// errorHandler.handle(err, res);
|
||||
// });
|
||||
// });
|
||||
|
||||
// app.route('/:uid/tokens')
|
||||
// .get(apiMiddleware.requireUser, function(req, res) {
|
||||
// if (parseInt(req.params.uid, 10) !== parseInt(req.user.uid, 10)) {
|
||||
// return errorHandler.respond(401, res);
|
||||
// }
|
||||
|
||||
// auth.getTokens(req.params.uid, function(err, tokens) {
|
||||
// return errorHandler.handle(err, res, {
|
||||
// tokens: tokens
|
||||
// });
|
||||
// });
|
||||
// })
|
||||
// .post(apiMiddleware.requireUser, function(req, res) {
|
||||
// if (parseInt(req.params.uid, 10) !== parseInt(req.user.uid)) {
|
||||
// return errorHandler.respond(401, res);
|
||||
// }
|
||||
|
||||
// auth.generateToken(req.params.uid, function(err, token) {
|
||||
// return errorHandler.handle(err, res, {
|
||||
// token: token
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// app.delete('/:uid/tokens/:token', apiMiddleware.requireUser, function(req, res) {
|
||||
// if (parseInt(req.params.uid, 10) !== req.user.uid) {
|
||||
// return errorHandler.respond(401, res);
|
||||
// }
|
||||
|
||||
// auth.revokeToken(req.params.token, 'user', function(err) {
|
||||
// errorHandler.handle(err, res);
|
||||
// });
|
||||
// });
|
||||
|
||||
/**
|
||||
* Chat routes were not migrated because chats may get refactored... also the logic is derpy
|
||||
* It also does not take into account multiple chats for a given user.
|
||||
@@ -126,6 +74,43 @@ function authenticatedRoutes() {
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
/**
|
||||
* Implement this later...
|
||||
*/
|
||||
// app.route('/:uid/tokens')
|
||||
// .get(apiMiddleware.requireUser, function(req, res) {
|
||||
// if (parseInt(req.params.uid, 10) !== parseInt(req.user.uid, 10)) {
|
||||
// return errorHandler.respond(401, res);
|
||||
// }
|
||||
|
||||
// auth.getTokens(req.params.uid, function(err, tokens) {
|
||||
// return errorHandler.handle(err, res, {
|
||||
// tokens: tokens
|
||||
// });
|
||||
// });
|
||||
// })
|
||||
// .post(apiMiddleware.requireUser, function(req, res) {
|
||||
// if (parseInt(req.params.uid, 10) !== parseInt(req.user.uid)) {
|
||||
// return errorHandler.respond(401, res);
|
||||
// }
|
||||
|
||||
// auth.generateToken(req.params.uid, function(err, token) {
|
||||
// return errorHandler.handle(err, res, {
|
||||
// token: token
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// app.delete('/:uid/tokens/:token', apiMiddleware.requireUser, function(req, res) {
|
||||
// if (parseInt(req.params.uid, 10) !== req.user.uid) {
|
||||
// return errorHandler.respond(401, res);
|
||||
// }
|
||||
|
||||
// auth.revokeToken(req.params.token, 'user', function(err) {
|
||||
// errorHandler.handle(err, res);
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
@@ -8,10 +8,13 @@ const categories = require('../../categories');
|
||||
const privileges = require('../../privileges');
|
||||
const plugins = require('../../plugins');
|
||||
const events = require('../../events');
|
||||
const sockets = require('..');
|
||||
|
||||
const Categories = module.exports;
|
||||
|
||||
Categories.create = async function (socket, data) {
|
||||
sockets.warnDeprecated(socket, 'POST /api/v1/categories');
|
||||
|
||||
if (!data) {
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user