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() const router = new Router() 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}`) })