(
options: FastifyHttpOptions<RawServerDefault, FastifyBaseLogger> = {}
)
| 103 | * @returns The instantiated Fastify server, with TypeBox. |
| 104 | */ |
| 105 | export const build = async ( |
| 106 | options: FastifyHttpOptions<RawServerDefault, FastifyBaseLogger> = {} |
| 107 | ): Promise<FastifyInstanceWithTypeProvider> => { |
| 108 | // TODO: Old API returns 403s for failed validation. We now return 400 (default) from AJV. |
| 109 | // Watch when implementing in client |
| 110 | const fastify = Fastify(options).withTypeProvider<TypeBoxTypeProvider>(); |
| 111 | |
| 112 | fastify.setValidatorCompiler(({ schema }) => ajv.compile(schema)); |
| 113 | fastify.addHook('onRequest', (req, _reply, done) => { |
| 114 | const logger = fastify.log.child({ req }); |
| 115 | logger.debug({ req }, 'received request'); |
| 116 | done(); |
| 117 | }); |
| 118 | |
| 119 | fastify.addHook('onResponse', (req, reply, done) => { |
| 120 | const logger = fastify.log.child({ res: reply }); |
| 121 | logger.debug({ req, res: reply }, 'responding to request'); |
| 122 | done(); |
| 123 | }); |
| 124 | |
| 125 | void fastify.register(redirectWithMessage); |
| 126 | void fastify.register(security); |
| 127 | void fastify.register(fastifyAccepts); |
| 128 | void fastify.register(errorHandling); |
| 129 | |
| 130 | await fastify.register(cors); |
| 131 | await fastify.register(cookies); |
| 132 | await fastify.register(csrf); |
| 133 | |
| 134 | await fastify.register(growthBook, { |
| 135 | apiHost: GROWTHBOOK_FASTIFY_API_HOST, |
| 136 | clientKey: GROWTHBOOK_FASTIFY_CLIENT_KEY |
| 137 | }); |
| 138 | |
| 139 | void fastify.register(mailer, { provider: createMailProvider() }); |
| 140 | |
| 141 | // Swagger plugin |
| 142 | if (FCC_ENABLE_SWAGGER_UI ?? fastify.gb.isOn('swagger-ui')) { |
| 143 | void fastify.register(fastifySwagger, { |
| 144 | openapi: { |
| 145 | openapi: '3.1.0', |
| 146 | info: { |
| 147 | title: 'freeCodeCamp API', |
| 148 | version: '1.0.0' // API version |
| 149 | } |
| 150 | } |
| 151 | }); |
| 152 | void fastify.register(fastifySwaggerUI, { |
| 153 | uiConfig: { |
| 154 | // Convert csrf_token cookie to csrf-token header |
| 155 | requestInterceptor: req => { |
| 156 | const csrfTokenCookie = document.cookie |
| 157 | .split(';') |
| 158 | .find(str => str.includes('csrf_token')); |
| 159 | const [_key, csrfToken] = csrfTokenCookie?.split('=') ?? []; |
| 160 | |
| 161 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access |
| 162 | if (csrfToken) req.headers['csrf-token'] = csrfToken.trim(); |
no test coverage detected