108 lines
2.1 KiB
TypeScript
108 lines
2.1 KiB
TypeScript
import cors from '@koa/cors'
|
|
import Router from '@koa/router'
|
|
import Koa from 'koa'
|
|
import { koaBody } from 'koa-body'
|
|
|
|
import {
|
|
clientId,
|
|
clientSecret,
|
|
PORT,
|
|
redirectUri,
|
|
serverUrl,
|
|
} from './config.js'
|
|
import { BodyType, sendCrispMessage } from './functions/send-crisp-message.js'
|
|
import { bree } from './jobs.js'
|
|
import { initMongodb } from './mongodb.js'
|
|
import { getAccessToken } from './oauth.js'
|
|
import { snakeToCamelCaseKeys, validateCrispBody } from './utils.js'
|
|
|
|
const mongo = await initMongodb()
|
|
|
|
type KoaState = Koa.DefaultState
|
|
type KoaContext = Koa.DefaultContext
|
|
|
|
const app = new Koa<KoaState, KoaContext>()
|
|
const router = new Router<KoaState, KoaContext>()
|
|
|
|
app.use(cors())
|
|
|
|
router.get('/connect', (ctx) => {
|
|
const { state = '' } = ctx.query
|
|
const url =
|
|
`${serverUrl}/oauth/authorize?` +
|
|
[
|
|
`client_id=${clientId}`,
|
|
`redirect_uri=${redirectUri}`,
|
|
`response_type=code`,
|
|
`state=${state?.toString()}`,
|
|
].join('&')
|
|
|
|
ctx.redirect(url)
|
|
})
|
|
|
|
router.get('/oauth', async (ctx) => {
|
|
const { code, error, state } = ctx.query
|
|
|
|
if (error) {
|
|
ctx.status = 400
|
|
ctx.body = error
|
|
|
|
return
|
|
}
|
|
if (typeof code !== 'string') {
|
|
ctx.status = 400
|
|
ctx.body = 'Bad code'
|
|
|
|
return
|
|
}
|
|
|
|
try {
|
|
const { body } = await getAccessToken({
|
|
serverUrl,
|
|
clientSecret,
|
|
clientId,
|
|
redirectUri,
|
|
code,
|
|
})
|
|
|
|
await mongo.saveOAuth(snakeToCamelCaseKeys(body))
|
|
|
|
if (
|
|
typeof state === 'string' &&
|
|
['run-all', ...bree.config.jobs.map(({ name }) => name)].includes(state)
|
|
) {
|
|
await (state === 'run-all' ? bree.run() : bree.run(state))
|
|
}
|
|
|
|
ctx.status = 200
|
|
} catch (err) {
|
|
// eslint-disable-next-line no-console
|
|
console.error(err)
|
|
|
|
ctx.status = 400
|
|
}
|
|
})
|
|
|
|
router.post('/send-crisp-message', koaBody(), async (ctx) => {
|
|
try {
|
|
const body = validateCrispBody(ctx.request.body as BodyType)
|
|
|
|
await sendCrispMessage(body)
|
|
|
|
ctx.status = 200
|
|
} catch (err) {
|
|
// eslint-disable-next-line no-console
|
|
console.error(err)
|
|
|
|
ctx.status = 400
|
|
}
|
|
})
|
|
|
|
app.use(router.routes())
|
|
app.use(router.allowedMethods())
|
|
|
|
app.listen(PORT, () => {
|
|
// eslint-disable-next-line no-console
|
|
console.log(`app listening on port ${PORT}`)
|
|
})
|