You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.4 KiB
98 lines
2.4 KiB
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<Server, IncomingMessage, ServerResponse, PluginOptions> = 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
|