index html only on real routes otherwise redirect + better logging

pull/1/head
Antonio De Lucreziis 2 years ago
parent 5f6df46d60
commit 1452c0c143

@ -18,7 +18,5 @@ export const useUser = () => {
} }
}, []) }, [])
console.log(user)
return [user, logout] return [user, logout]
} }

@ -20,6 +20,7 @@
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"express": "^4.18.2", "express": "^4.18.2",
"katex": "^0.16.3", "katex": "^0.16.3",
"morgan": "^1.10.0",
"preact": "^10.11.2", "preact": "^10.11.2",
"preact-render-to-string": "^5.2.6", "preact-render-to-string": "^5.2.6",
"preact-router": "^4.1.0", "preact-router": "^4.1.0",

@ -9,6 +9,7 @@ specifiers:
cookie-parser: ^1.4.6 cookie-parser: ^1.4.6
express: ^4.18.2 express: ^4.18.2
katex: ^0.16.3 katex: ^0.16.3
morgan: ^1.10.0
npm-run-all: ^4.1.5 npm-run-all: ^4.1.5
preact: ^10.11.2 preact: ^10.11.2
preact-render-to-string: ^5.2.6 preact-render-to-string: ^5.2.6
@ -24,13 +25,14 @@ specifiers:
vite: ^3.2.2 vite: ^3.2.2
dependencies: dependencies:
'@preact/preset-vite': 2.4.0_itg6mj6ekxshuesvnuddqebsp4 '@preact/preset-vite': 2.4.0_preact@10.11.2+vite@3.2.2
'@preact/signals': 1.1.2_preact@10.11.2 '@preact/signals': 1.1.2_preact@10.11.2
body-parser: 1.20.1 body-parser: 1.20.1
chalk: 5.1.2 chalk: 5.1.2
cookie-parser: 1.4.6 cookie-parser: 1.4.6
express: 4.18.2 express: 4.18.2
katex: 0.16.3 katex: 0.16.3
morgan: 1.10.0
preact: 10.11.2 preact: 10.11.2
preact-render-to-string: 5.2.6_preact@10.11.2 preact-render-to-string: 5.2.6_preact@10.11.2
preact-router: 4.1.0_preact@10.11.2 preact-router: 4.1.0_preact@10.11.2
@ -227,37 +229,34 @@ packages:
'@babel/types': 7.20.2 '@babel/types': 7.20.2
dev: false dev: false
/@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.2: /@babel/plugin-syntax-jsx/7.18.6:
resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/core': 7.20.2
'@babel/helper-plugin-utils': 7.20.2 '@babel/helper-plugin-utils': 7.20.2
dev: false dev: false
/@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.2: /@babel/plugin-transform-react-jsx-development/7.18.6:
resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/core': 7.20.2 '@babel/plugin-transform-react-jsx': 7.19.0
'@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.2
dev: false dev: false
/@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.2: /@babel/plugin-transform-react-jsx/7.19.0:
resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/core': 7.20.2
'@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-annotate-as-pure': 7.18.6
'@babel/helper-module-imports': 7.18.6 '@babel/helper-module-imports': 7.18.6
'@babel/helper-plugin-utils': 7.20.2 '@babel/helper-plugin-utils': 7.20.2
'@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.2 '@babel/plugin-syntax-jsx': 7.18.6
'@babel/types': 7.20.2 '@babel/types': 7.20.2
dev: false dev: false
@ -353,18 +352,17 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14 '@jridgewell/sourcemap-codec': 1.4.14
dev: false dev: false
/@preact/preset-vite/2.4.0_itg6mj6ekxshuesvnuddqebsp4: /@preact/preset-vite/2.4.0_preact@10.11.2+vite@3.2.2:
resolution: {integrity: sha512-EiUMHuiCThuTuK+eH2r5uDg+CJbbt4aWJGePuszrHuXUpRv6WAeO4S+/DTJsEHtPtGmPRR3cLQ68N5097eOSRA==} resolution: {integrity: sha512-EiUMHuiCThuTuK+eH2r5uDg+CJbbt4aWJGePuszrHuXUpRv6WAeO4S+/DTJsEHtPtGmPRR3cLQ68N5097eOSRA==}
peerDependencies: peerDependencies:
'@babel/core': 7.x '@babel/core': 7.x
vite: 2.x || 3.x vite: 2.x || 3.x
dependencies: dependencies:
'@babel/core': 7.20.2 '@babel/plugin-transform-react-jsx': 7.19.0
'@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.2 '@babel/plugin-transform-react-jsx-development': 7.18.6
'@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.2
'@prefresh/vite': 2.2.9_preact@10.11.2+vite@3.2.2 '@prefresh/vite': 2.2.9_preact@10.11.2+vite@3.2.2
'@rollup/pluginutils': 4.2.1 '@rollup/pluginutils': 4.2.1
babel-plugin-transform-hook-names: 1.0.2_@babel+core@7.20.2 babel-plugin-transform-hook-names: 1.0.2
debug: 4.3.4 debug: 4.3.4
kolorist: 1.6.0 kolorist: 1.6.0
resolve: 1.22.1 resolve: 1.22.1
@ -500,12 +498,10 @@ packages:
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
dev: false dev: false
/babel-plugin-transform-hook-names/1.0.2_@babel+core@7.20.2: /babel-plugin-transform-hook-names/1.0.2:
resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==}
peerDependencies: peerDependencies:
'@babel/core': ^7.12.10 '@babel/core': ^7.12.10
dependencies:
'@babel/core': 7.20.2
dev: false dev: false
/bail/2.0.2: /bail/2.0.2:
@ -516,6 +512,13 @@ packages:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true dev: true
/basic-auth/2.0.1:
resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
engines: {node: '>= 0.8'}
dependencies:
safe-buffer: 5.1.2
dev: false
/binary-extensions/2.2.0: /binary-extensions/2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1870,6 +1873,19 @@ packages:
brace-expansion: 1.1.11 brace-expansion: 1.1.11
dev: true dev: true
/morgan/1.10.0:
resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==}
engines: {node: '>= 0.8.0'}
dependencies:
basic-auth: 2.0.1
debug: 2.6.9
depd: 2.0.0
on-finished: 2.3.0
on-headers: 1.0.2
transitivePeerDependencies:
- supports-color
dev: false
/mri/1.2.0: /mri/1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -1954,6 +1970,13 @@ packages:
object-keys: 1.1.1 object-keys: 1.1.1
dev: true dev: true
/on-finished/2.3.0:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
engines: {node: '>= 0.8'}
dependencies:
ee-first: 1.1.1
dev: false
/on-finished/2.4.1: /on-finished/2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@ -1961,6 +1984,11 @@ packages:
ee-first: 1.1.1 ee-first: 1.1.1
dev: false dev: false
/on-headers/1.0.2:
resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
engines: {node: '>= 0.8'}
dev: false
/parse-json/4.0.0: /parse-json/4.0.0:
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2202,6 +2230,10 @@ packages:
mri: 1.2.0 mri: 1.2.0
dev: false dev: false
/safe-buffer/5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: false
/safe-buffer/5.2.1: /safe-buffer/5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: false dev: false

@ -1,16 +1,35 @@
import path from 'path' import path from 'path'
import fs from 'fs/promises' import fs from 'fs/promises'
import { createServer as createViteServer } from 'vite'
import express from 'express' import express from 'express'
import { createApiRouter } from './server/routers.js' import morgan from 'morgan'
import { createServer as createViteServer } from 'vite'
import { createApiRouter } from './server/routes.js'
const HTML_ROUTES = ['/', '/login', '/problem/:id']
const config = { const config = {
isDevelopment: process.env.MODE === 'development', isDevelopment: process.env.MODE === 'development',
port: process.env.PORT || 3000, port: process.env.PORT || 3000,
} }
console.dir(config) if (config.isDevelopment) {
console.log(`[Config] Running in development mode`)
console.log(`[Config] PORT = ${config.port}`)
}
function mountIndexHtmlRoutes(r, serveIndexHtml) {
for (const route of HTML_ROUTES) {
console.log(`[Server] Mounted index html for "${route}"`)
r.get(route, serveIndexHtml)
}
r.use('*', (_req, res) => {
res.redirect('/')
})
}
async function createDevRouter() { async function createDevRouter() {
const r = express.Router() const r = express.Router()
@ -21,7 +40,7 @@ async function createDevRouter() {
}) })
r.use(vite.middlewares) r.use(vite.middlewares)
r.use('*', async (req, res, next) => { mountIndexHtmlRoutes(r, async (req, res, next) => {
try { try {
const indexHtml = await fs.readFile(path.resolve('./index.html'), 'utf-8') const indexHtml = await fs.readFile(path.resolve('./index.html'), 'utf-8')
const transformedTemplate = await vite.transformIndexHtml(req.originalUrl, indexHtml) const transformedTemplate = await vite.transformIndexHtml(req.originalUrl, indexHtml)
@ -48,7 +67,8 @@ async function createProductionRouter() {
const r = new express.Router() const r = new express.Router()
r.use('/', express.static('dist/client')) r.use('/', express.static('dist/client'))
r.use('*', async (req, res) => {
mountIndexHtmlRoutes(r, async (req, res) => {
const transformedTemplate = await fs.readFile( const transformedTemplate = await fs.readFile(
path.resolve('./dist/client/index.html'), path.resolve('./dist/client/index.html'),
'utf-8' 'utf-8'
@ -65,6 +85,8 @@ async function createProductionRouter() {
async function main() { async function main() {
const app = express() const app = express()
app.use(morgan('dev'))
app.use('/', await createApiRouter()) app.use('/', await createApiRouter())
if (config.isDevelopment) { if (config.isDevelopment) {

@ -8,16 +8,16 @@ async function withDatabase({ path, initialValue }, fn) {
try { try {
await access(path, constants.R_OK) await access(path, constants.R_OK)
} catch (e) { } catch (e) {
console.log(`Creating empty database into "${path}"`) console.log(`[Database] Creating empty database into "${path}"`)
await writeFile(path, JSON.stringify(initialValue, null, 2)) await writeFile(path, JSON.stringify(initialValue, null, 2))
} }
console.log(`Loading database from "${path}"`) console.log(`[Database] Loading database from "${path}"`)
const state = JSON.parse(await readFile(path, 'utf-8')) const state = JSON.parse(await readFile(path, 'utf-8'))
const result = await fn(state) const result = await fn(state)
console.log(`Saving database to "${path}"`) console.log(`[Database] Saving database to "${path}"`)
await writeFile(path, JSON.stringify(state, null, 2)) await writeFile(path, JSON.stringify(state, null, 2))
return result return result

@ -28,20 +28,6 @@ export class PingRouter extends Router {
} }
} }
export const loggingMiddleware = (req, res, next) => {
next()
const coloredStatusCode = [
chalk.gray,
chalk.green,
chalk.blueBright,
chalk.red,
chalk.redBright,
][Math.floor(res.statusCode / 100) - 1](res.statusCode)
console.log(`${toLocalISO(new Date())} | ${req.method} ${req.originalUrl} ${coloredStatusCode}`)
}
export const authMiddleware = getUserForSession => async (req, res, next) => { export const authMiddleware = getUserForSession => async (req, res, next) => {
if (req.cookies.sid) { if (req.cookies.sid) {
req.user = await getUserForSession(req.cookies.sid) req.user = await getUserForSession(req.cookies.sid)

@ -3,11 +3,11 @@ import crypto from 'crypto'
import bodyParser from 'body-parser' import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser' import cookieParser from 'cookie-parser'
import { authMiddleware, loggingMiddleware, PingRouter, StatusRouter } from './middlewares.js'
import { createDatabase, getUser, updateUser } from './db/database.js'
import express from 'express' import express from 'express'
import { authMiddleware, PingRouter, StatusRouter } from './middlewares.js'
import { createDatabase, getUser, updateUser } from './db/database.js'
import { initialDatabaseValue } from './db/example-data.js' import { initialDatabaseValue } from './db/example-data.js'
import { useId } from 'preact/hooks'
export async function createApiRouter() { export async function createApiRouter() {
const sessions = { const sessions = {
@ -29,7 +29,6 @@ export async function createApiRouter() {
r.use(bodyParser.json()) r.use(bodyParser.json())
r.use(cookieParser()) r.use(cookieParser())
r.use(loggingMiddleware)
r.use(authMiddleware(sid => sessions.getUserForSession(sid))) r.use(authMiddleware(sid => sessions.getUserForSession(sid)))
r.use('/api/status', new StatusRouter()) r.use('/api/status', new StatusRouter())
@ -78,9 +77,5 @@ export async function createApiRouter() {
res.sendStatus(200) res.sendStatus(200)
}) })
// r.all('*', (_req, res) => {
// res.sendStatus(404)
// })
return r return r
} }
Loading…
Cancel
Save