u
This commit is contained in:
9
src/v1/index.js
Normal file
9
src/v1/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Router } from 'express';
|
||||
import { handleClient } from './routes/client.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
// POS discovery and pairing
|
||||
router.get('/client', handleClient);
|
||||
|
||||
export default router;
|
||||
126
src/v1/routes/client.js
Normal file
126
src/v1/routes/client.js
Normal file
@@ -0,0 +1,126 @@
|
||||
import crypto from 'node:crypto';
|
||||
import * as db from '../../db/posterminal.js';
|
||||
import { getCompanyById } from '../../db/company.js';
|
||||
import { getCertMetadata } from '../../util/cert.js';
|
||||
|
||||
export 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())}`;
|
||||
}
|
||||
|
||||
export function buildClientStep1(config) {
|
||||
const {
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
serverFingerprint,
|
||||
} = config;
|
||||
|
||||
return {
|
||||
authCode: null,
|
||||
authToken: null,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
mandantName: null,
|
||||
mandantDatabase: null,
|
||||
serverFingerprint,
|
||||
name: null,
|
||||
serverTimestamp: serverTimestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildClientStep2(authCode, config) {
|
||||
const {
|
||||
authToken,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
mandantName,
|
||||
mandantDatabase,
|
||||
} = config;
|
||||
|
||||
return {
|
||||
authCode,
|
||||
authToken,
|
||||
certificateFingerprint,
|
||||
certificateSerialNumber,
|
||||
mandantId,
|
||||
mandantName,
|
||||
mandantDatabase,
|
||||
serverFingerprint: null,
|
||||
name: null,
|
||||
serverTimestamp: serverTimestamp(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles GET /v1/client
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
export async function handleClient(req, res) {
|
||||
const authCode = String(req.query.authCode || '').trim();
|
||||
const name = String(req.query.name || 'JTL-POS').trim();
|
||||
|
||||
try {
|
||||
const certMeta = await getCertMetadata();
|
||||
|
||||
if (authCode.length <= 4 && authCode.length > 0) {
|
||||
const config = {
|
||||
...certMeta,
|
||||
mandantId: process.env.MANDANT_ID || '1',
|
||||
};
|
||||
return res.status(200).json(buildClientStep1(config));
|
||||
}
|
||||
|
||||
if (authCode.length === 6) {
|
||||
const terminal = await db.findByPairingpin(authCode);
|
||||
if (terminal) {
|
||||
const token = terminal.token;
|
||||
const strToken = String(token || crypto.randomBytes(16).toString('hex')).trim();
|
||||
const pairedAt = serverTimestamp();
|
||||
|
||||
await db.pair(terminal.id, {
|
||||
token: strToken,
|
||||
clientserial: name,
|
||||
pairedAt,
|
||||
});
|
||||
|
||||
let mandantName = process.env.MANDANT_NAME || 'eB-Standard';
|
||||
let mandantDatabase = process.env.MANDANT_DATABASE || 'eazybusiness';
|
||||
let mandantId = String(terminal.companyId || process.env.MANDANT_ID || '1');
|
||||
|
||||
if (terminal.companyId) {
|
||||
try {
|
||||
const company = await getCompanyById(terminal.companyId);
|
||||
if (company) {
|
||||
mandantName = company.name;
|
||||
mandantDatabase = company.name;
|
||||
}
|
||||
} catch {
|
||||
// ignore lookup error and fallback to defaults
|
||||
}
|
||||
}
|
||||
|
||||
const config = {
|
||||
...certMeta,
|
||||
authToken: strToken,
|
||||
mandantId,
|
||||
mandantName,
|
||||
mandantDatabase,
|
||||
};
|
||||
|
||||
return res.status(200).json(buildClientStep2(authCode, config));
|
||||
}
|
||||
|
||||
return res.status(400).json({ Message: 'Der Authentifizierungscode ist falsch.' });
|
||||
}
|
||||
|
||||
return res.status(400).json({ Message: 'Keinen passenden Authentifizierungscode gefunden.' });
|
||||
} catch (err) {
|
||||
console.error('POS /v1/client error:', err);
|
||||
return res.status(500).json({ Message: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user