Updated info.js to reflect auto kiosk print status. Implemented KIOSK_PRINTER environment variable. Updated docker-compose.yml. Dependency updates. Updated README.md. Implemented voucher auto-print within kiosk in server.js

This commit is contained in:
Glenn de Haan
2025-07-22 19:20:22 +02:00
parent 09d2fe6e31
commit 95cbad4fd8
7 changed files with 77 additions and 20 deletions

View File

@@ -137,6 +137,8 @@ services:
KIOSK_VOUCHER_TYPES: '480,1,,,;'
# Enable/disable the requirement for a guest to enter their name before generating a voucher
KIOSK_NAME_REQUIRED: 'false'
# Enable/disable a printer for Kiosk Vouchers (this automatically prints vouchers), currently supported: escpos ip (Example: 192.168.1.10)
KIOSK_PRINTER: ''
# Sets the application Log Level (Valid Options: error|warn|info|debug|trace)
LOG_LEVEL: 'info'
# Sets the default translation for dropdowns
@@ -619,6 +621,16 @@ KIOSK_VOUCHER_TYPES: '480,1,,,;'
- Set to `'true'` to enable the requirement for a guest to enter their name before generating a voucher.
- Set to `'false'` to disable to allow generation of vouchers without a name.
* **`KIOSK_PRINTER`**:
* Set this to the IP address of an ESC/POS-compatible network printer to enable automatic voucher printing.
* Leave this value empty to disable printing.
* Example:
```text
KIOSK_PRINTER=192.168.1.50
```
### Custom Branding (Logo and Background)
You can customize the appearance of the kiosk page by providing your own `logo.png` and `bg.jpg` images.

View File

@@ -34,5 +34,6 @@ services:
KIOSK_ENABLED: 'false'
KIOSK_VOUCHER_TYPES: '480,1,,,;'
KIOSK_NAME_REQUIRED: 'false'
KIOSK_PRINTER: ''
LOG_LEVEL: 'info'
TRANSLATION_DEBUG: 'false'

View File

@@ -114,6 +114,9 @@ module.exports = () => {
types(variables.kioskVoucherTypes).forEach((type, key) => {
log.info(`[Kiosk][Type][${key}] ${time(type.expiration)}, ${type.usage === '1' ? 'single-use' : type.usage === '0' ? 'multi-use (unlimited)' : `multi-use (${type.usage}x)`}${typeof type.upload === "undefined" && typeof type.download === "undefined" && typeof type.megabytes === "undefined" ? ', no limits' : `${typeof type.upload !== "undefined" ? `, upload bandwidth limit: ${type.upload} kb/s` : ''}${typeof type.download !== "undefined" ? `, download bandwidth limit: ${type.download} kb/s` : ''}${typeof type.megabytes !== "undefined" ? `, quota limit: ${type.megabytes} mb` : ''}`}`);
});
if(variables.kioskPrinter !== '') {
log.info(`[Kiosk] Auto-printing enabled! Printer: ${variables.kioskPrinter}`);
}
}
/**

View File

@@ -42,6 +42,7 @@ module.exports = {
kioskEnabled: config('kiosk_enabled') || (process.env.KIOSK_ENABLED === 'true') || false,
kioskVoucherTypes: config('kiosk_voucher_types') || process.env.KIOSK_VOUCHER_TYPES || '480,1,,,;',
kioskNameRequired: config('kiosk_name_required') || (process.env.KIOSK_NAME_REQUIRED === 'true') || false,
kioskPrinter: config('kiosk_printer') || process.env.KIOSK_PRINTER || '',
logLevel: config('log_level') || process.env.LOG_LEVEL || 'info',
translationDefault: config('translation_default') || process.env.TRANSLATION_DEFAULT || 'en',
translationDebug: config('translation_debug') || (process.env.TRANSLATION_DEBUG === 'true') || false,

65
package-lock.json generated
View File

@@ -16,7 +16,7 @@
"express-openid-connect": "^2.18.1",
"js-logger": "^1.6.1",
"jsonwebtoken": "^9.0.2",
"multer": "^2.0.1",
"multer": "^2.0.2",
"node-thermal-printer": "^4.5.0",
"node-unifi": "^2.5.1",
"nodemailer": "^7.0.5",
@@ -922,9 +922,9 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz",
"integrity": "sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
"integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -1591,6 +1591,21 @@
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -1886,12 +1901,15 @@
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
@@ -2057,6 +2075,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -2831,9 +2864,9 @@
"license": "MIT"
},
"node_modules/multer": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.1.tgz",
"integrity": "sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
"integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
"license": "MIT",
"dependencies": {
"append-field": "^1.0.0",
@@ -2955,9 +2988,9 @@
}
},
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -3631,9 +3664,9 @@
}
},
"node_modules/tough-cookie": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.1.tgz",
"integrity": "sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
"integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
"license": "BSD-3-Clause",
"dependencies": {
"tldts": "^6.1.32"

View File

@@ -16,9 +16,10 @@
"license": "MIT",
"overrides": {
"node-unifi@^2.5.1": {
"axios": "1.8.3",
"tough-cookie": "5.1.1"
}
"axios": "1.10.0",
"tough-cookie": "5.1.2"
},
"form-data": "4.0.4"
},
"dependencies": {
"cookie-parser": "^1.4.7",
@@ -28,7 +29,7 @@
"express-openid-connect": "^2.18.1",
"js-logger": "^1.6.1",
"jsonwebtoken": "^9.0.2",
"multer": "^2.0.1",
"multer": "^2.0.2",
"node-thermal-printer": "^4.5.0",
"node-unifi": "^2.5.1",
"nodemailer": "^7.0.5",

View File

@@ -250,6 +250,12 @@ if(variables.serviceWeb) {
return;
}
// Auto print voucher if enabled
await print.escpos(voucherData, req.locale.language, variables.kioskPrinter).catch((e) => {
log.error(`[Kiosk] Unable to auto-print voucher on printer: ${variables.kioskPrinter}!`);
log.error(e);
});
res.render('kiosk', {
t: translation('kiosk', req.locale.language),
languages,