Genesis
This commit is contained in:
91
server.js
Normal file
91
server.js
Normal file
@@ -0,0 +1,91 @@
|
||||
const fs = require('node:fs');
|
||||
const https = require('node:https');
|
||||
const path = require('node:path');
|
||||
|
||||
const { createStore, createJtlPosServer, createAdminServer } = require('./lib/src');
|
||||
const actions = require('./lib/src/actions');
|
||||
|
||||
const PORT = Number(process.env.PORT) || 8086;
|
||||
const ADMIN_PORT = Number(process.env.ADMIN_PORT) || 8087;
|
||||
const AUTH_TOKEN =
|
||||
process.env.AUTH_TOKEN || '9a2e3036ed9c47e389741d9dbb7590e9';
|
||||
const PAIRING_CODE = process.env.PAIRING_CODE || '307018';
|
||||
|
||||
const certsDir = path.join(__dirname, 'certs');
|
||||
const keyPath = path.join(certsDir, 'key.pem');
|
||||
const certPath = path.join(certsDir, 'cert.pem');
|
||||
|
||||
if (!fs.existsSync(keyPath) || !fs.existsSync(certPath)) {
|
||||
console.error('Missing TLS certificate. Run: npm run cert');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function serverTimestamp() {
|
||||
const d = new Date();
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||
}
|
||||
|
||||
function formatBody(buffer) {
|
||||
if (!buffer.length) {
|
||||
return '(empty)';
|
||||
}
|
||||
const text = buffer.toString('utf8');
|
||||
if (/^[\x09\x0A\x0D\x20-\x7E\u0080-\uFFFF]*$/.test(text)) {
|
||||
return text;
|
||||
}
|
||||
return `[binary ${buffer.length} bytes]\n${buffer.toString('hex')}`;
|
||||
}
|
||||
|
||||
const store = createStore();
|
||||
|
||||
// Pre-register the fixed pairing code so the POS can pair out of the box.
|
||||
store.dispatch(actions.setPairingCode(PAIRING_CODE, 'JTL-POS'));
|
||||
// Treat the fixed auth token as a pre-paired device for display in the admin UI.
|
||||
store.dispatch(actions.registerDevice(AUTH_TOKEN, 'JTL-POS'));
|
||||
|
||||
const jtlHandler = createJtlPosServer(store, { authToken: AUTH_TOKEN });
|
||||
|
||||
const loggedJtlHandler = async (req, res) => {
|
||||
const started = Date.now();
|
||||
const originalEnd = res.end.bind(res);
|
||||
|
||||
console.log('\n--- incoming POS request ---');
|
||||
console.log(`${req.method} ${req.url}`);
|
||||
console.log('remote:', req.socket.remoteAddress, req.socket.remotePort);
|
||||
console.log('headers:', JSON.stringify(req.headers, null, 2));
|
||||
|
||||
await jtlHandler(req, res);
|
||||
|
||||
// req.rawBody is attached by jtlHandler's body reader
|
||||
console.log('body:', formatBody(req.rawBody ?? Buffer.alloc(0)));
|
||||
console.log(`responded ${res.statusCode} in ${Date.now() - started}ms`);
|
||||
};
|
||||
|
||||
const httpsServer = https.createServer(
|
||||
{
|
||||
key: fs.readFileSync(keyPath),
|
||||
cert: fs.readFileSync(certPath),
|
||||
},
|
||||
loggedJtlHandler
|
||||
);
|
||||
|
||||
httpsServer.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`HTTPS POS server listening on https://0.0.0.0:${PORT}`);
|
||||
console.log(`Certificate: ${certPath}`);
|
||||
console.log('Import cert.pem into JTL POS / Windows trust store if required.');
|
||||
});
|
||||
|
||||
const { server: adminServer } = createAdminServer(store, {
|
||||
adminPort: ADMIN_PORT,
|
||||
staticDir: path.join(__dirname, 'web', 'dist'),
|
||||
});
|
||||
|
||||
function shutdown() {
|
||||
console.log('\nShutting down...');
|
||||
httpsServer.close();
|
||||
adminServer.close();
|
||||
}
|
||||
|
||||
process.on('SIGINT', shutdown);
|
||||
process.on('SIGTERM', shutdown);
|
||||
Reference in New Issue
Block a user