Skip to content

Commit

Permalink
feat(api): list available paths at /api/v1/admin
Browse files Browse the repository at this point in the history
  • Loading branch information
manuartero committed Mar 24, 2021
1 parent fe5e61b commit 8b95e14
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 96 deletions.
4 changes: 2 additions & 2 deletions src/log.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const Logger = require('bunyan')
const { name, version } = require('../package.json')
const { serverInfo } = require('./server-info')

const log = new Logger({
name: `${name}@${version}`,
name: serverInfo(),
// @ts-ignore
level: process.env.LOG_LEVEL || 'info'
})
Expand Down
5 changes: 5 additions & 0 deletions src/server-info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const { name, version } = require('../package.json')

module.exports = {
serverInfo: () => `${name}@${version}`
}
255 changes: 161 additions & 94 deletions src/server/restify-server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const restify = require('restify')
const { BadRequestError } = require('restify-errors')
const { log } = require('../log')
const { serverInfo } = require('../server-info')

/**
* @param {import('restify').Request} req
Expand Down Expand Up @@ -51,120 +52,186 @@ const createRestifyServer = ({
req.log.info('[<< RESPONSE]', res.toString())
})

server.get('/', (_, res, next) => {
res.send(log.fields.name)
server.get({ name: 'server info', path: '/' }, (_, res, next) => {
res.send(serverInfo())
next()
})

/** Resolves 202: Accepted */
server.post('/api/v1/messages', async (req, res, next) => {
await processMessage(req, res)
/* do not
* `res.send(202)`
* -> headers already sent to the client
* -> [ERR_HTTP_HEADERS_SENT] err
*/
next()
})

server.post('/api/v1/notify', async (req, res, next) => {
const user = req.body ? req.body.user : undefined
const message = req.body ? req.body.message : undefined
if (!user || !message) {
const err = new BadRequestError("required: 'user', 'message'")
return next(err)
}
try {
const conversationKey = await notify(user, message, {
includeMention: includeMention(req)
})
res.send(202, { conversationKey })
server.post(
{
name: 'botframework entrypoint',
path: '/api/v1/messages'
},
async (req, res, next) => {
await processMessage(req, res)
/* do not
* `res.send(202)`
* -> headers already sent to the client
* -> [ERR_HTTP_HEADERS_SENT] err
*/
next()
} catch (err) {
next(err)
}
})
)

server.post('/api/v1/broadcast', async (req, res, next) => {
const topic = req.body ? req.body.topic : undefined
const message = req.body ? req.body.message : undefined
if (!topic || !message) {
const err = new BadRequestError("required: 'topic', 'message'")
return next(err)
}
try {
const conversationKeys = await broadcast(topic, message, {
ensureTopic: ensureTopic(req)
})
res.send(202, { conversationKeys })
next()
} catch (err) {
next(err)
server.post(
{
name: 'notify',
path: '/api/v1/notify'
},
async (req, res, next) => {
const user = req.body ? req.body.user : undefined
const message = req.body ? req.body.message : undefined
if (!user || !message) {
const err = new BadRequestError("required: 'user', 'message'")
return next(err)
}
try {
const conversationKey = await notify(user, message, {
includeMention: includeMention(req)
})
res.send(202, { conversationKey })
next()
} catch (err) {
next(err)
}
}
})
)

server.get('/api/v1/admin', (_, res, next) => {
const { routes } = server.getDebugInfo()
res.send(200, routes)
})
server.post(
{
name: 'broadcast',
path: '/api/v1/broadcast'
},
async (req, res, next) => {
const topic = req.body ? req.body.topic : undefined
const message = req.body ? req.body.message : undefined
if (!topic || !message) {
const err = new BadRequestError("required: 'topic', 'message'")
return next(err)
}
try {
const conversationKeys = await broadcast(topic, message, {
ensureTopic: ensureTopic(req)
})
res.send(202, { conversationKeys })
next()
} catch (err) {
next(err)
}
}
)

server.get('/api/v1/admin/users', async (_, res, next) => {
const users = await getUsers()
res.send(200, users)
next()
})
server.get(
{
name: 'admin root',
path: '/api/v1/admin'
},
(_, res, next) => {
const { routes } = server.getDebugInfo()
// @ts-ignore
const response = routes.map(({ name, method, path }) => ({
name,
method,
path
}))
res.send(200, response)
}
)

server.get('/api/v1/admin/topics', async (_, res, next) => {
const topics = await getTopics()
res.send(200, topics)
next()
})
server.get(
{
name: 'admin: user index',
path: '/api/v1/admin/users'
},
async (_, res, next) => {
const users = await getUsers()
res.send(200, users)
next()
}
)

server.post('/api/v1/admin/topics', async (req, res, next) => {
const topic = req.body ? req.body.name : undefined
if (!topic) {
const err = new BadRequestError("required: 'name'")
return next(err)
server.get(
{
name: 'admin: topic index',
path: '/api/v1/admin/topics'
},
async (_, res, next) => {
const topics = await getTopics()
res.send(200, topics)
next()
}
const topics = await createTopic(topic)
res.send(200, topics)
next()
})
)

server.del('/api/v1/topics/:topic', async (req, res, next) => {
const topic = req.body ? req.body.name : undefined
try {
const topics = await removeTopic(topic)
server.post(
{
name: 'admin: topic creation',
path: '/api/v1/admin/topics'
},
async (req, res, next) => {
const topic = req.body ? req.body.name : undefined
if (!topic) {
const err = new BadRequestError("required: 'name'")
return next(err)
}
const topics = await createTopic(topic)
res.send(200, topics)
next()
} catch (err) {
next(err)
}
})
)

server.put('/api/v1/topics/:topic/subscribers', async (req, res, next) => {
const user = req.body ? req.body.user : undefined
if (!user) {
const err = new BadRequestError("required: 'user'")
return next(err)
server.del(
{
name: 'admin: topic delete',
path: '/api/v1/admin/topics/:topic'
},
async (req, res, next) => {
const topic = req.body ? req.body.name : undefined
try {
const topics = await removeTopic(topic)
res.send(200, topics)
next()
} catch (err) {
next(err)
}
}
const topic = req.params.topic
const subscribers = await forceSubscription(user, topic)
res.send(200, { subscribers })
next()
})
)

server.put(
{
name: 'admin: subscribe to topic',
path: '/api/v1/admin/topics/:topic/subscribers'
},
async (req, res, next) => {
const user = req.body ? req.body.user : undefined
if (!user) {
const err = new BadRequestError("required: 'user'")
return next(err)
}
const topic = req.params.topic
const subscribers = await forceSubscription(user, topic)
res.send(200, { subscribers })
next()
}
)

// server.del('/api/v1/topics/:topic', async (req, res, next) => {
// const user = req.body ? req.body.user : undefined
// if (!user) {
// const err = new BadRequestError("required: 'user'")
// return next(err)
// }
// const topic = req.params.topic
// const subscribers = await cancelSubscription(user, topic)
// res.send(200, { subscribers })
// next()
// })
server.del(
{
name: 'admin: unsubscribe from topic',
path: '/api/v1/admin/topics/:topic/subscribers'
},
async (req, res, next) => {
const user = req.body ? req.body.user : undefined
if (!user) {
const err = new BadRequestError("required: 'user'")
return next(err)
}
const topic = req.params.topic
const subscribers = await cancelSubscription(user, topic)
res.send(200, { subscribers })
next()
}
)

return {
/**
Expand Down

0 comments on commit 8b95e14

Please sign in to comment.