initial commit
This commit is contained in:
62
server.js
Normal file
62
server.js
Normal file
@@ -0,0 +1,62 @@
|
||||
// Production server for the Xpress developer docs.
|
||||
//
|
||||
// What this does:
|
||||
// 1. Reads HASURA_ADMIN_SECRET from .env.local (server-side, never bundled).
|
||||
// 2. Proxies /api/* requests to https://api.workolik.com/api/*, injecting
|
||||
// the x-hasura-admin-secret header on the way out.
|
||||
// 3. Serves the built React app from dist/ (SPA fallback to index.html).
|
||||
//
|
||||
// The browser never receives the secret. To run:
|
||||
// npm run build # builds dist/
|
||||
// npm start # starts this server on PORT (default 3000)
|
||||
|
||||
import express from 'express'
|
||||
import { createProxyMiddleware } from 'http-proxy-middleware'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'node:path'
|
||||
import 'dotenv/config'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const PORT = Number(process.env.PORT) || 3000
|
||||
const SECRET = (process.env.HASURA_ADMIN_SECRET || '').trim()
|
||||
const TARGET = 'https://api.workolik.com'
|
||||
|
||||
if (!SECRET) {
|
||||
console.warn('[xpress-docs] WARNING: HASURA_ADMIN_SECRET is not set. Proxied API calls will be sent without auth.')
|
||||
}
|
||||
|
||||
const app = express()
|
||||
|
||||
app.use('/api', createProxyMiddleware({
|
||||
target: TARGET,
|
||||
changeOrigin: true,
|
||||
secure: true,
|
||||
// The mount strips '/api' from req.url; add it back so the target URL
|
||||
// stays /api/rest/...
|
||||
pathRewrite: (p) => '/api' + p,
|
||||
on: {
|
||||
proxyReq: (proxyReq) => {
|
||||
if (SECRET) proxyReq.setHeader('x-hasura-admin-secret', SECRET)
|
||||
},
|
||||
error: (err, _req, res) => {
|
||||
console.error('[xpress-docs] proxy error:', err.message)
|
||||
if (!res.headersSent) {
|
||||
res.writeHead(502, { 'Content-Type': 'application/json' })
|
||||
}
|
||||
res.end(JSON.stringify({ error: 'proxy_error', message: err.message }))
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
// Built React app
|
||||
const distDir = path.join(__dirname, 'dist')
|
||||
app.use(express.static(distDir))
|
||||
app.get('*', (_req, res) => {
|
||||
res.sendFile(path.join(distDir, 'index.html'))
|
||||
})
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`[xpress-docs] listening on http://localhost:${PORT}`)
|
||||
console.log(`[xpress-docs] proxying /api/* -> ${TARGET}/api/*`)
|
||||
console.log(`[xpress-docs] admin secret: ${SECRET ? 'loaded' : 'NOT SET'}`)
|
||||
})
|
||||
Reference in New Issue
Block a user