diff --git a/README.md b/README.md index 5a19824..61e976e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ UniFi Voucher Site is a web-based platform for generating and managing UniFi net - **OIDC Support**: Integrates OpenID Connect for secure user authentication and single sign-on (SSO). - **Web and API Services**: Access the service via a web interface or integrate with other systems using a REST API. - **Docker Support**: Easily deploy using Docker, with customizable environment settings. -- **Home Assistant Add-on**: Seamlessly integrate with Home Assistant for centralized management. +- **Home Assistant App**: Seamlessly integrate with Home Assistant for centralized management. - **Receipt Printing**: Supports printing vouchers with 80mm thermal printers. Via compatible PDFs and/or ESC/POS enabled network printers. - **Bulk Printing**: Export/print multiple Vouchers in one go. - **Email Functionality**: Automatically send vouchers via SMTP. @@ -124,6 +124,8 @@ services: VOUCHER_TYPES: '480,1,,,;' # Allow users to create custom vouchers types within the UI VOUCHER_CUSTOM: 'true' + # Force users to provide a note within the UI + VOUCHER_NOTE_REQUIRED: 'false' # Enable/disable the Web UI SERVICE_WEB: 'true' # Enable/disable the API @@ -212,6 +214,7 @@ The structure of the file should use lowercase versions of the environment varia "auth_disable": false, "voucher_types": "480,1,,,;", "voucher_custom": true, + "voucher_note_required": false, "service_web": true, "service_api": false, "printers": "", @@ -256,20 +259,21 @@ services: > If both environment variables and `options.json` are provided, values from `options.json` will take precedence. -### Home Assistant Add-on +### Home Assistant App -For users of Home Assistant, we provide a dedicated add-on to seamlessly integrate the UniFi Voucher Site with your Home Assistant instance. This add-on simplifies the setup process and allows you to manage UniFi vouchers directly from your Home Assistant dashboard. +For users of Home Assistant, we provide a dedicated app to seamlessly integrate the UniFi Voucher Site with your Home Assistant instance. +This app simplifies the setup process and allows you to manage UniFi vouchers directly from your Home Assistant dashboard. -[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fglenndehaan%2Fha-addons) +[![Open your Home Assistant instance and show the add app repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fglenndehaan%2Fha-addons) #### Manual Installation -To install the UniFi Voucher Site add-on for Home Assistant, follow these steps: +To install the UniFi Voucher Site app for Home Assistant, follow these steps: 1. Open the Supervisor panel in your Home Assistant instance. -2. Navigate to the "Add-on Store." +2. Navigate to the "App Store." 3. Add our repository to the list of repositories by clicking the three dots in the upper-right corner, then selecting "Repositories," and entering the URL of our repository: `https://github.com/glenndehaan/ha-addons`. -4. Once the repository is added, you will find the "UniFi Voucher Site" add-on in the add-on store. Click on it. +4. Once the repository is added, you will find the "UniFi Voucher Site" app in the app store. Click on it. 5. Click "Install" and wait for the installation to complete. --- diff --git a/controllers/voucher.js b/controllers/voucher.js index 6923af7..5f4aadd 100644 --- a/controllers/voucher.js +++ b/controllers/voucher.js @@ -72,6 +72,11 @@ module.exports = { } } + if(variables.voucherNoteRequired && req.body['voucher-note'] === '') { + res.cookie('flashMessage', JSON.stringify({type: 'error', message: 'Notes are required!'}), {httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000)}).redirect(302, `${req.headers['x-ingress-path'] ? req.headers['x-ingress-path'] : ''}/vouchers`); + return; + } + if(req.body['voucher-note'] !== '' && req.body['voucher-note'].includes('||;;||')) { res.cookie('flashMessage', JSON.stringify({type: 'error', message: 'Invalid Notes!'}), {httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000)}).redirect(302, `${req.headers['x-ingress-path'] ? req.headers['x-ingress-path'] : ''}/vouchers`); return; diff --git a/controllers/vouchers.js b/controllers/vouchers.js index 5e31d73..758ff09 100644 --- a/controllers/vouchers.js +++ b/controllers/vouchers.js @@ -80,6 +80,7 @@ module.exports = { printer_enabled: variables.printers !== '', voucher_types: types(variables.voucherTypes), voucher_custom: variables.voucherCustom, + voucher_note_required: variables.voucherNoteRequired, vouchers: cache.vouchers.filter((item) => { if(variables.authOidcRestrictVisibility && req.oidc) { return item.name && notes(item.name).auth_oidc_domain === user.email.split('@')[1].toLowerCase(); diff --git a/modules/variables.js b/modules/variables.js index c71ee7e..22f62b8 100644 --- a/modules/variables.js +++ b/modules/variables.js @@ -20,6 +20,7 @@ module.exports = { unifiSsidPassword: config('unifi_ssid_password') || process.env.UNIFI_SSID_PASSWORD || '', voucherTypes: config('voucher_types') || process.env.VOUCHER_TYPES || '480,1,,,;', voucherCustom: config('voucher_custom') !== null ? config('voucher_custom') : process.env.VOUCHER_CUSTOM ? process.env.VOUCHER_CUSTOM !== 'false' : true, + voucherNoteRequired: config('voucher_note_required') !== null ? config('voucher_note_required') : (process.env.VOUCHER_NOTE_REQUIRED === 'true') || false, serviceWeb: config('service_web') !== null ? config('service_web') : process.env.SERVICE_WEB ? process.env.SERVICE_WEB !== 'false' : true, serviceApi: config('service_api') || (process.env.SERVICE_API === 'true') || false, authInternalEnabled: config('auth_internal_enabled') !== null ? config('auth_internal_enabled') : process.env.AUTH_INTERNAL_ENABLED ? process.env.AUTH_INTERNAL_ENABLED !== 'false' : true, diff --git a/package-lock.json b/package-lock.json index e250368..b25973f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,10 +18,10 @@ "jsonwebtoken": "^9.0.3", "multer": "^2.0.2", "node-thermal-printer": "^4.6.0", - "nodemailer": "^7.0.13", + "nodemailer": "^8.0.1", "pdfkit": "^0.17.2", "qrcode": "^1.5.4", - "undici": "^7.19.2" + "undici": "^7.21.0" }, "devDependencies": { "@tailwindcss/cli": "^4.1.18", @@ -3491,9 +3491,9 @@ } }, "node_modules/nodemailer": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", - "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.1.tgz", + "integrity": "sha512-5kcldIXmaEjZcHR6F28IKGSgpmZHaF1IXLWFTG+Xh3S+Cce4MiakLtWY+PlBU69fLbRa8HlaGIrC/QolUpHkhg==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -4571,9 +4571,9 @@ } }, "node_modules/undici": { - "version": "7.19.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.19.2.tgz", - "integrity": "sha512-4VQSpGEGsWzk0VYxyB/wVX/Q7qf9t5znLRgs0dzszr9w9Fej/8RVNQ+S20vdXSAyra/bJ7ZQfGv6ZMj7UEbzSg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.21.0.tgz", + "integrity": "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg==", "license": "MIT", "engines": { "node": ">=20.18.1" diff --git a/package.json b/package.json index 59d784d..9724365 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,10 @@ "jsonwebtoken": "^9.0.3", "multer": "^2.0.2", "node-thermal-printer": "^4.6.0", - "nodemailer": "^7.0.13", + "nodemailer": "^8.0.1", "pdfkit": "^0.17.2", "qrcode": "^1.5.4", - "undici": "^7.19.2" + "undici": "^7.21.0" }, "devDependencies": { "@tailwindcss/cli": "^4.1.18", diff --git a/template/voucher.ejs b/template/voucher.ejs index 97f6d6d..8c20db7 100644 --- a/template/voucher.ejs +++ b/template/voucher.ejs @@ -282,9 +282,9 @@
- +
- + required<% } %> class="mt-2 block w-full rounded-md border-0 py-1.5 text-gray-900 dark:text-white dark:bg-white/5 ring-1 ring-inset ring-gray-300 dark:ring-white/10 focus:ring-2 focus:ring-sky-600 sm:text-sm sm:leading-6">