mirror of https://github.com/requarks/wiki
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.
79 lines
2.7 KiB
79 lines
2.7 KiB
import { whoAmI } from './users.ts'
|
|
import type { FastifyInstance } from 'fastify'
|
|
|
|
/**
|
|
* Bootstrap API Route
|
|
*
|
|
* The three things the app has to know before it can draw anything: which site it is on, which system
|
|
* flags are set, and who is asking. Each has an endpoint of its own — the admin area reads the flags,
|
|
* the login flow asks who is logged in once that has changed — but a full load needs all three at
|
|
* once, and asking for them one at a time is three round trips before the first pixel.
|
|
*
|
|
* None of them touches the database: the site configurations and the flags are in memory, and the
|
|
* session carries the user. So what this saves is the round trips, which is the whole cost.
|
|
*/
|
|
async function routes(app: FastifyInstance) {
|
|
app.get<{ Querystring: { hostname?: string } }>(
|
|
'/',
|
|
{
|
|
config: {
|
|
publicAccess: true
|
|
},
|
|
schema: {
|
|
summary: 'Everything the app needs to start',
|
|
description:
|
|
'The site for the hostname, the system flags, and the current session — the same answers `sites/{hostname}`, `system/flags` and `users/whoami` give, in one request.\n\nCarries the session, so it is never cached.',
|
|
tags: ['System'],
|
|
querystring: {
|
|
type: 'object',
|
|
properties: {
|
|
hostname: {
|
|
type: 'string',
|
|
maxLength: 255,
|
|
description: "The host the browser is on. The request's own hostname when absent."
|
|
}
|
|
}
|
|
},
|
|
response: {
|
|
200: {
|
|
description: 'Site, flags and session',
|
|
type: 'object',
|
|
properties: {
|
|
site: { $ref: 'Site#' },
|
|
flags: { $ref: 'SystemFlags#' },
|
|
user: {
|
|
type: 'object',
|
|
description:
|
|
'As `users/whoami` answers it: `authenticated: false` alone for a guest, otherwise the account and its group-wide permissions.',
|
|
additionalProperties: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
async (req, reply) => {
|
|
// -> The session decides part of the answer, so no shared cache may hold on to it
|
|
reply.preventCache()
|
|
const site = await WIKI.models.sites.getSiteByHostname({
|
|
hostname: req.query.hostname ?? req.hostname
|
|
})
|
|
if (!site) {
|
|
return reply.notFound('There is no wiki site at this hostname.')
|
|
}
|
|
return {
|
|
site: {
|
|
...site.config,
|
|
id: site.id,
|
|
hostname: site.hostname,
|
|
isEnabled: site.isEnabled
|
|
},
|
|
flags: WIKI.models.flags.getFlags(),
|
|
user: whoAmI(req)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
export default routes
|