import { CosmosClient } from '@azure/cosmos' import { Plugin } from 'fastify' import trim from 'lodash/trim' import { Server, IncomingMessage, ServerResponse } from 'http' import { JWT } from '../../lib/crypto' import { tokenFromHeader } from '../../lib/http' import apps from './apps' import authentication from './authentication' import groups from './groups' import media from './media' import posts from './posts' import users from './users' import { PluginOptions, HttpError } from '../../types' interface Database { client: CosmosClient } interface UserInfo { id: string } declare module "fastify" { interface FastifyInstance { database?: Database } interface FastifyRequest{ viewer?: UserInfo } } const plugin: Plugin = async server => { const database: Database = { client: new CosmosClient({ endpoint: process.env.DATABASE_ENDPOINT!, key: process.env.DATABASE_PRIMARY_KEY, }), } server.decorate('database', database) server.decorateRequest('viewer', null) server.addHook('preHandler', async req => { const token = tokenFromHeader(req.headers.authorization) if (!token) return try { const data: JWT.JWTData = await JWT.verify(token) if (!data.sub) throw new Error('Invalid token') req.viewer = { id: data.sub } } catch (err) { req.log.error('Unable to decode token') req.log.error(err) } }) server.setErrorHandler(function(error, request, reply) { request.log.error(error) const response: HttpError = { message: error.message, } if (error.validation) { response.errors = error.validation.map(e => { return { field: trim(e.dataPath, '.'), message: e.message, } }) } reply.send(response) }) server.register(apps) server.register(authentication) server.register(groups) server.register(media) server.register(posts) server.register(users) server.get('/', {}, async () => { return { app: 'flexor', version: process.env.NPM_PACKAGE_VERSION, } }) } export default plugin