This PR contains the work done to provide optimizations to the current service, such as a health-check endpoint, pre-renders static HTML pages, and hardens the error page's CSP. To provide further details about the work: * Added the `HealthController` controller serving GET `/health` with a static JSON payload. * Added the `CachedHTMLResponse` response, which renders a static HTMLDocument to bytes once and reuses them per request (no Content-Length, so responses stay compressible). * Integrated the response into the `RootController` and the `NotFoundMiddleware` middleware to avoid re-rendering on hot paths. * Added a `RouterMethods.addRoutes(_:)` extension and switched the router in App+build to use it. * Moved the inline style from the `ErrorPage` page into a dedicated style file so the CSP needs no inline-style escape hatch. * Fixed the `IndexPage` page path inconsistencies. * Written the `README` file. Reviewed-on: rock-n-code/loud-amsterdam#9 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
34 lines
1.9 KiB
Swift
34 lines
1.9 KiB
Swift
extension String {
|
|
/// A namespace for well-known path string constants.
|
|
public enum Path {
|
|
/// The directory, relative to the working directory, that the website's static files are served from.
|
|
public static let staticResources = "Resources/Static"
|
|
}
|
|
/// A namespace for the security headers' default configuration values.
|
|
///
|
|
/// `Strict-Transport-Security` is intentionally absent: it is only safe over HTTPS and is
|
|
/// "sticky" in browsers, so it stays off unless explicitly configured in production.
|
|
public enum Security {
|
|
/// The default `Content-Security-Policy`.
|
|
///
|
|
/// Restricts every resource to the site's own origin (`default-src 'self'`), blocks plugins
|
|
/// (`object-src 'none'`), pins the document base URL (`base-uri 'self'`), and forbids framing
|
|
/// (`frame-ancestors 'none'`). Both pages link external stylesheets, so no inline-style
|
|
/// exception is required.
|
|
public static let contentSecurityPolicy = "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'"
|
|
/// The default `X-Content-Type-Options` (disables MIME sniffing).
|
|
public static let contentTypeOptions = "nosniff"
|
|
/// The default `X-Frame-Options` (forbids framing the page).
|
|
public static let frameOptions = "DENY"
|
|
/// The default `Referrer-Policy`.
|
|
public static let referrerPolicy = "strict-origin-when-cross-origin"
|
|
/// The default `Permissions-Policy` (denies access to powerful browser features the site does not use).
|
|
public static let permissionsPolicy = "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"
|
|
}
|
|
/// A namespace for the server string constants.
|
|
public enum Server {
|
|
/// The website server's name.
|
|
public static let name = "LoudWebsite"
|
|
}
|
|
}
|