mirror of
https://github.com/glenndehaan/unifi-voucher-site.git
synced 2026-04-05 08:53:53 -04:00
Refactored unifi.js to separate logic. Updated application header. Fixed incorrect screen-reader text. Updated sync button text. Implemented last sync date/time. Implemented cache util. Fixed missing vouchers check to prevent 'headers are already send' error. Fixed missing cache sync on api voucher creation. Implemented auto sync every 15 minutes
This commit is contained in:
@@ -25,12 +25,16 @@ const config = {
|
||||
/**
|
||||
* Exports the UniFi voucher functions
|
||||
*
|
||||
* @param type
|
||||
* @param create
|
||||
* @returns {Promise<unknown>}
|
||||
* @type {{create: (function(*): Promise<*>), list: (function(): Promise<*>)}}
|
||||
*/
|
||||
module.exports = (type, create = true) => {
|
||||
if(create) {
|
||||
module.exports = {
|
||||
/**
|
||||
* Creates a new UniFi Voucher
|
||||
*
|
||||
* @param type
|
||||
* @return {Promise<unknown>}
|
||||
*/
|
||||
create: (type) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
/**
|
||||
* Create new UniFi controller object
|
||||
@@ -69,7 +73,14 @@ module.exports = (type, create = true) => {
|
||||
reject('[UniFi] Error while logging in!');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a list with all UniFi Vouchers
|
||||
*
|
||||
* @return {Promise<unknown>}
|
||||
*/
|
||||
list: () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
/**
|
||||
* Create new UniFi controller object
|
||||
@@ -102,4 +113,4 @@ module.exports = (type, create = true) => {
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
38
server.js
38
server.js
@@ -24,6 +24,11 @@ const unifi = require('./modules/unifi');
|
||||
const authorization = require('./middlewares/authorization');
|
||||
const flashMessage = require('./middlewares/flashMessage');
|
||||
|
||||
/**
|
||||
* Import own utils
|
||||
*/
|
||||
const {updateCache} = require('./utils/cache');
|
||||
|
||||
/**
|
||||
* Setup Express app
|
||||
*/
|
||||
@@ -184,13 +189,13 @@ if(webService) {
|
||||
}
|
||||
|
||||
// Create voucher code
|
||||
const voucherCode = await unifi(types(req.body['voucher-type'], true)).catch((e) => {
|
||||
const voucherCode = await unifi.create(types(req.body['voucher-type'], true)).catch((e) => {
|
||||
res.cookie('flashMessage', JSON.stringify({type: 'error', message: e}), {httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000)}).redirect(302, `${req.headers['x-ingress-path'] ? req.headers['x-ingress-path'] : ''}/vouchers`);
|
||||
});
|
||||
|
||||
log.info('[Cache] Requesting UniFi Vouchers...');
|
||||
|
||||
const vouchers = await unifi('', false).catch((e) => {
|
||||
const vouchers = await unifi.list().catch((e) => {
|
||||
log.error('[Cache] Error requesting vouchers!');
|
||||
log.error(e);
|
||||
res.cookie('flashMessage', JSON.stringify({type: 'error', message: e}), {httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000)}).redirect(302, `${req.headers['x-ingress-path'] ? req.headers['x-ingress-path'] : ''}/vouchers`);
|
||||
@@ -202,7 +207,7 @@ if(webService) {
|
||||
log.info(`[Cache] Saved ${vouchers.length} voucher(s)`);
|
||||
}
|
||||
|
||||
if(voucherCode) {
|
||||
if(vouchers && voucherCode) {
|
||||
res.cookie('flashMessage', JSON.stringify({type: 'info', message: `Voucher Created: ${voucherCode}`}), {httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000)}).redirect(302, `${req.headers['x-ingress-path'] ? req.headers['x-ingress-path'] : ''}/vouchers`);
|
||||
}
|
||||
});
|
||||
@@ -210,7 +215,7 @@ if(webService) {
|
||||
if(req.query.refresh) {
|
||||
log.info('[Cache] Requesting UniFi Vouchers...');
|
||||
|
||||
const vouchers = await unifi('', false).catch((e) => {
|
||||
const vouchers = await unifi.list().catch((e) => {
|
||||
log.error('[Cache] Error requesting vouchers!');
|
||||
log.error(e);
|
||||
res.cookie('flashMessage', JSON.stringify({type: 'error', message: e}), {httpOnly: true, expires: new Date(Date.now() + 24 * 60 * 60 * 1000)}).redirect(302, `${req.headers['x-ingress-path'] ? req.headers['x-ingress-path'] : ''}/vouchers`);
|
||||
@@ -235,7 +240,8 @@ if(webService) {
|
||||
error_text: req.flashMessage.message || '',
|
||||
timeConvert: time,
|
||||
voucher_types: voucherTypes,
|
||||
vouchers: cache.vouchers
|
||||
vouchers: cache.vouchers,
|
||||
updated: cache.updated
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -275,13 +281,15 @@ if(apiService) {
|
||||
}
|
||||
|
||||
// Create voucher code
|
||||
const voucherCode = await unifi(types(req.params.type, true)).catch((e) => {
|
||||
const voucherCode = await unifi.create(types(req.params.type, true)).catch((e) => {
|
||||
res.json({
|
||||
error: e,
|
||||
data: {}
|
||||
});
|
||||
});
|
||||
|
||||
await updateCache();
|
||||
|
||||
if(voucherCode) {
|
||||
res.json({
|
||||
error: null,
|
||||
@@ -314,17 +322,11 @@ app.disable('x-powered-by');
|
||||
*/
|
||||
app.listen(3000, '0.0.0.0', async () => {
|
||||
log.info(`[App] Running on: 0.0.0.0:3000`);
|
||||
await updateCache();
|
||||
|
||||
log.info('[Cache] Requesting UniFi Vouchers...');
|
||||
|
||||
const vouchers = await unifi('', false).catch((e) => {
|
||||
log.error('[Cache] Error requesting vouchers!');
|
||||
log.error(e);
|
||||
});
|
||||
|
||||
if(vouchers) {
|
||||
cache.vouchers = vouchers;
|
||||
cache.updated = new Date().getTime();
|
||||
log.info(`[Cache] Saved ${vouchers.length} voucher(s)`);
|
||||
}
|
||||
// Run auto sync every 15 minutes
|
||||
setInterval(async () => {
|
||||
log.info('[Auto Sync] Starting Sync...');
|
||||
await updateCache();
|
||||
}, 900000);
|
||||
});
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
<div class="flex">
|
||||
<div class="flex flex-shrink-0 items-center">
|
||||
<img class="h-12 w-auto" alt="UniFi Voucher Site Logo" src="<%= baseUrl %>/images/logo.png">
|
||||
<div class="hidden sm:block ml-4 text-2xl font-semibold leading-7 text-gray-900 dark:text-white">
|
||||
UniFi Voucher
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
@@ -47,7 +50,7 @@
|
||||
<div class="ml-4 flex flex-shrink-0 items-center">
|
||||
<a href="https://github.com/glenndehaan/unifi-voucher-site" aria-label="GitHub Project Link" target="_blank" rel="noreferrer noopener" type="button" class="relative rounded-full p-1 text-gray-500 dark:text-gray-400 hover:text-black dark:hover:text-white">
|
||||
<span class="absolute -inset-1.5"></span>
|
||||
<span class="sr-only">View notifications</span>
|
||||
<span class="sr-only">GitHub Project Link</span>
|
||||
<svg class="h-6 w-6" viewBox="0 0 42 42" fill="currentColor">
|
||||
<path d="M21,0.5c-11.6,0-21,9.4-21,21c0,9.3,6,17.1,14.4,19.9c1.1,0.2,1.4-0.5,1.4-1c0-0.5,0-1.8,0-3.6C9.9,38.1,8.7,34,8.7,34c-1-2.4-2.3-3.1-2.3-3.1c-1.9-1.3,0.1-1.3,0.1-1.3c2.1,0.1,3.2,2.2,3.2,2.2c1.9,3.2,4.9,2.3,6.1,1.7c0.2-1.4,0.7-2.3,1.3-2.8c-4.7-0.5-9.6-2.3-9.6-10.4c0-2.3,0.8-4.2,2.2-5.6c-0.2-0.5-0.9-2.7,0.2-5.6c0,0,1.8-0.6,5.8,2.2c1.7-0.5,3.5-0.7,5.3-0.7c1.8,0,3.6,0.2,5.3,0.7c4-2.7,5.8-2.2,5.8-2.2c1.1,2.9,0.4,5,0.2,5.6c1.3,1.5,2.2,3.3,2.2,5.6c0,8.1-4.9,9.8-9.6,10.4c0.8,0.6,1.4,1.9,1.4,3.9c0,2.8,0,5.1,0,5.8c0,0.6,0.4,1.2,1.4,1C36,38.7,42,30.8,42,21.5C42,9.9,32.6,0.5,21,0.5z"></path>
|
||||
</svg>
|
||||
@@ -94,14 +97,21 @@
|
||||
|
||||
<main class="mx-auto max-w-7xl">
|
||||
<header class="flex items-center justify-between border-b border-black/5 dark:border-white/5 px-4 py-4 sm:px-6 sm:py-6 lg:px-8">
|
||||
<h1 class="text-xl font-semibold leading-7 text-gray-900 dark:text-white">Vouchers</h1>
|
||||
<h1 class="text-2xl font-semibold leading-7 text-gray-900 dark:text-white">
|
||||
Vouchers
|
||||
</h1>
|
||||
|
||||
<div class="grid">
|
||||
<a href="<%= baseUrl %>/vouchers?refresh=true" id="reload-vouchers" type="button" class="relative inline-flex items-center gap-x-1.5 rounded-md bg-sky-700 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-sky-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-700">
|
||||
<svg class="-ml-0.5 h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M15.312 11.424a5.5 5.5 0 0 1-9.201 2.466l-.312-.311h2.433a.75.75 0 0 0 0-1.5H3.989a.75.75 0 0 0-.75.75v4.242a.75.75 0 0 0 1.5 0v-2.43l.31.31a7 7 0 0 0 11.712-3.138.75.75 0 0 0-1.449-.39Zm1.23-3.723a.75.75 0 0 0 .219-.53V2.929a.75.75 0 0 0-1.5 0V5.36l-.31-.31A7 7 0 0 0 3.239 8.188a.75.75 0 1 0 1.448.389A5.5 5.5 0 0 1 13.89 6.11l.311.31h-2.432a.75.75 0 0 0 0 1.5h4.243a.75.75 0 0 0 .53-.219Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
Reload Vouchers
|
||||
Sync Vouchers
|
||||
</a>
|
||||
<span class="mt-2 text-xs text-center italic text-gray-900 dark:text-white">
|
||||
Last Sync: <%= new Intl.DateTimeFormat('en-US', {dateStyle: 'short', timeStyle: 'short', hour12: false}).format(new Date(updated)) %>
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<% if(vouchers.length < 1) { %>
|
||||
|
||||
37
utils/cache.js
Normal file
37
utils/cache.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Import own modules
|
||||
*/
|
||||
const log = require('../modules/log');
|
||||
const unifi = require('../modules/unifi');
|
||||
const cache = require('../modules/cache');
|
||||
|
||||
/**
|
||||
* Exports all cache utils
|
||||
*
|
||||
* @type {{updateCache: (function(): Promise<*>)}}
|
||||
*/
|
||||
module.exports = {
|
||||
/**
|
||||
* Update the cache
|
||||
*
|
||||
* @return {Promise<*>}
|
||||
*/
|
||||
updateCache: () => {
|
||||
return new Promise(async (resolve) => {
|
||||
log.info('[Cache] Requesting UniFi Vouchers...');
|
||||
|
||||
const vouchers = await unifi.list().catch((e) => {
|
||||
log.error('[Cache] Error requesting vouchers!');
|
||||
log.error(e);
|
||||
});
|
||||
|
||||
if(vouchers) {
|
||||
cache.vouchers = vouchers;
|
||||
cache.updated = new Date().getTime();
|
||||
log.info(`[Cache] Saved ${vouchers.length} voucher(s)`);
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user