From 1e26ffcf9dd968543fe7d0a023fbd46b6024932d Mon Sep 17 00:00:00 2001 From: zefie Date: Fri, 11 Jul 2025 14:47:48 -0400 Subject: [PATCH] initial scrapbook implementation --- zefie_wtvp_minisrv/app.js | 4 + .../ServiceVault/wtv-author/scrapbook.js | 17 +- .../wtv-tricks/add-to-scrapbook.js | 89 +++ .../wtv-tricks/view-scrapbook-image.js | 35 ++ .../includes/classes/WTVAuthor.js | 105 +++- .../includes/classes/WTVShared.js | 1 - zefie_wtvp_minisrv/package-lock.json | 534 +++++++++++++++++- zefie_wtvp_minisrv/package.json | 1 + 8 files changed, 773 insertions(+), 13 deletions(-) create mode 100644 zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js create mode 100644 zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 3ac7644a..4c0da521 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -12,9 +12,11 @@ const {spawn} = require('child_process'); const http = require('follow-redirects').http const https = require('follow-redirects').https const httpx = require(classPath + "/HTTPX.js"); +const { URL } = require('url'); const net = require('net'); const crypto = require('crypto') const CryptoJS = require('crypto-js'); +const sharp = require('sharp') const process = require('process'); const WTVSec = require(classPath + "/WTVSec.js"); const WTVLzpf = require(classPath + "/WTVLzpf.js"); @@ -238,6 +240,8 @@ var runScriptInVM = function (script_data, user_contextObj = {}, privileged = fa "wtvmime": wtvmime, "http": http, "https": https, + "URL": URL, + "sharp": sharp, "wtvshared": wtvshared, "zlib": zlib, "clientShowAlert": clientShowAlert, diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js index aab3991a..4a463e99 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook.js @@ -2,7 +2,7 @@ var minisrv_service_file = true; var files = session_data.pagestore.listScrapbook(); var dir = session_data.pagestore.scrapbookDir() -var start = 12; +var start = 0; headers = `200 OK Connection: Keep-Alive @@ -158,14 +158,21 @@ Choose one of your saved images to view it full size. ` -for (let i = 0; i < 12; i++) { +if (files.length === 0) { + data += ``; +} else { + for (let i = start; i < Math.min(files.length, start + 12); i++) { data += ` ` + +${i % 4 === 1 ? '' : ''}` +} } data += `
+ Your scrapbook is empty. + - +"wtv-tricks:/view-scrapbook-image?id=${files[i]}" transition=light> + -
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js new file mode 100644 index 00000000..f94497b4 --- /dev/null +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/add-to-scrapbook.js @@ -0,0 +1,89 @@ +var minisrv_service_file = true; +var request_is_async = true; + + +function handleError(reason) { + var errpage = wtvshared.doErrorPage(400, reason); + sendToClient(socket, errpage[0], errpage[1]); +} + +if (!request_headers.query.url) { + handleError('No URL provided'); +} else { + var url = request_headers.query.url; + function isValidImageType(contentType, url) { + // Check content-type header or file extension + if (contentType) { + return contentType === 'image/jpeg' || contentType == 'image/jpg' || contentType === 'image/gif'; + } + return url.endsWith('.jpg') || url.endsWith('.jpeg') || url.endsWith('.gif'); + } + + try { + const parsedUrl = new URL(url); + const protocol = parsedUrl.protocol === 'https:' ? https : http; + + protocol.get(url, (res) => { + if (res.statusCode !== 200) { + handleError('URL does not exist or returned status ' + res.statusCode); + res.resume(); + return; + } + + const contentType = res.headers['content-type']; + const contentLength = parseInt(res.headers['content-length'], 10); + + if (!isValidImageType(contentType, url)) { + handleError('URL is not a JPEG or GIF image'); + res.resume(); + return; + } + + if (contentLength && contentLength > 1024 * 1024) { + handleError('Image is larger than 1MB'); + res.resume(); + return; + } + + let data = []; + let totalLength = 0; + res.on('data', (chunk) => { + totalLength += chunk.length; + if (totalLength > 1024 * 1024) { + handleError('Image is larger than 1MB'); + res.destroy(); + return; + } + data.push(chunk); + }); + + res.on('end', () => { + if (totalLength > 1024 * 1024) return; + data = Buffer.concat(data); + var id = session_data.pagestore.getFreeScrapbookID(); + var result = session_data.pagestore.addToScrapbook(id, contentType, data); + if (result) { + var successScrapbook = new clientShowAlert({ + 'image': minisrv_config.config.service_logo, + 'message': "The image has been added to your scrapbook. Would you like to view your scrapbook now?", + 'buttonlabel1': "No", + 'buttonaction1': "client:donothing", + 'buttonlabel2': "Yes", + 'buttonaction2': "wtv-author:/scrapbook", + }).getURL(); + sendToClient(socket, {'Status': 302, 'Location': successScrapbook, 'wtv-visit': successScrapbook}, ''); + } else { + handleError('Failed to add image to scrapbook'); + } + }); + + res.on('error', (err) => { + handleError('Error downloading image'); + }); + }).on('error', (err) => { + handleError('Failed to fetch URL'); + }); + } catch (e) { + handleError(e.message); + } +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js new file mode 100644 index 00000000..6e1ece60 --- /dev/null +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/view-scrapbook-image.js @@ -0,0 +1,35 @@ +var minisrv_service_file = true; +var request_is_async = true; + +function handleError(reason) { + var errpage = wtvshared.doErrorPage(400, reason); + sendToClient(socket, errpage[0], errpage[1]); +} + +async function handleImage() { + if (!request_headers.query.id) { + handleError('No image ID specified'); + } else { + data = session_data.pagestore.getScrapbookImage(request_headers.query.id); + if (!data) { + handleError('Image not found'); + } else { + try { + if (request_headers.query.width) { + // Scale the image to the specified width without losing aspect ratio, without using wtvshared + const width = parseInt(request_headers.query.width, 10); + data = await sharp(data).resize({ width, withoutEnlargement: true }).toBuffer(); + } + headers = `200 OK +Content-Type: ${session_data.pagestore.getScrapbookImageType(request_headers.query.id)} +Content-Length: ${data.length}` + sendToClient(socket, headers, data); + } catch (error) { + handleError('Error processing image'); + console.error('Image processing error:', error); + } + } + } +} + +handleImage(); \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js b/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js index ab37eacd..fca96eb5 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js @@ -10,6 +10,7 @@ class WTVAuthor { wtvclient = null; pageFileExt = ".page"; pagestore_dir = null; + scrapbook_dir = null; pageArr = []; blockArr = []; header = null; @@ -59,16 +60,26 @@ class WTVAuthor { if (this.pagestore_dir === null) { // set pagestore directory local var so we don't call the function every time var userstore_dir = this.wtvclient.getUserStoreDirectory(); - this.debug("pagestoreExists", "userstore_dir", userstore_dir) - // PageStore var store_dir = "PageStore" + this.path.sep; - this.pagestore_dir = userstore_dir + store_dir; + this.pagestore_dir = userstore_dir + store_dir; } return this.fs.existsSync(this.pagestore_dir); } return true; } + + scrapbookExists() { + if (!this.isguest) { + if (this.scrapbook_dir === null) { + var userstore_dir = this.wtvclient.getUserStoreDirectory(); + var store_dir = "Scrapbook" + this.path.sep; + this.scrapbook_dir = userstore_dir + store_dir; + } + } + return this.fs.existsSync(this.scrapbook_dir); + } + createPagestore() { if (this.pagestoreExists() === false) { @@ -79,7 +90,93 @@ class WTVAuthor { } return false; } - + + createScrapbook() { + if (this.scrapbookExists() === false) { + try { + if (!this.fs.existsSync(this.scrapbook_dir)) this.fs.mkdirSync(this.scrapbook_dir, { recursive: true }); + return true; + } catch { } + } + return false + } + + scrapbookDir() { + if (this.scrapbookExists() === false) { + this.createScrapbook(); + } + return this.scrapbook_dir; + } + + listScrapbook() { + if (this.scrapbookExists() === false) { + this.createScrapbook(); + } + const files = this.fs.readdirSync(this.scrapbook_dir); + const filteredFiles = files.filter(file => !file.endsWith('.meta')); + return filteredFiles; + } + + getFreeScrapbookID() { + if (this.scrapbookExists() === false) { + this.createScrapbook(); + } + var id = 1; + var files = this.fs.readdirSync(this.scrapbook_dir); + if (files.length == 0) { + return id; + } + files = files.map(file => parseInt(file.substr(0, file.indexOf('.')))); + while (files.includes(id)) { + id++; + } + return id; + } + + getScrapbookImage(id) { + if (this.scrapbookExists() === false) { + this.createScrapbook(); + } + var file = this.scrapbook_dir + id; + if (this.fs.existsSync(file)) { + return this.fs.readFileSync(file); + } + return null; + } + + getScrapbookImageType(id) { + if (this.scrapbookExists() === false) { + this.createScrapbook(); + } + var file = this.scrapbook_dir + id + ".meta"; + if (this.fs.existsSync(file)) { + var meta = this.fs.readFileSync(file, 'utf8'); + try { + var metaData = JSON.parse(meta); + return metaData.contentType; + } catch (e) { + this.debug("getScrapbookImageType", "Error parsing metadata for image ID", id, e); + } + } + return null; + } + + addToScrapbook(filename, contentType, data) { + try { + if (this.scrapbookExists() === false) { + this.createScrapbook(); + } + var fileout = this.scrapbook_dir + filename; + var fileout_meta = this.scrapbook_dir + filename + ".meta"; + this.fs.writeFileSync(fileout, data); + this.fs.writeFileSync(fileout_meta, JSON.stringify({ + "contentType": contentType + })); + return true; + } catch {} + return false; + } + createPage(style) { this.pagestoreExists() var pagestorepath = this.pagestore_dir; diff --git a/zefie_wtvp_minisrv/includes/classes/WTVShared.js b/zefie_wtvp_minisrv/includes/classes/WTVShared.js index f3943b18..61474cc7 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVShared.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVShared.js @@ -703,7 +703,6 @@ class WTVShared { return encoded.toUpperCase(); } - /** * Decodes a urlencoded string into a binary buffer * @param {string} encoded urlencoded string diff --git a/zefie_wtvp_minisrv/package-lock.json b/zefie_wtvp_minisrv/package-lock.json index d6d8444d..8767f855 100644 --- a/zefie_wtvp_minisrv/package-lock.json +++ b/zefie_wtvp_minisrv/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "zefie_wtvp_minisrv", - "version": "0.9.60-pre", + "version": "0.9.61-pre", "license": "GPL3", "dependencies": { "adm-zip": "^0.5.12", @@ -25,6 +25,7 @@ "proxy-agent": "^6.4.0", "rc4-crypto": "^1.5.0", "sanitize-html": "^2.13.0", + "sharp": "^0.34.3", "starttls": "^1.0.1", "strftime": "^0.10.2", "uuid": "^8.3.2" @@ -37,6 +38,16 @@ "url": "https://www.patreon.com/zefie" } }, + "node_modules/@emnapi/runtime": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", + "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -138,6 +149,424 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz", + "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz", + "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz", + "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz", + "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz", + "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz", + "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz", + "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz", + "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz", + "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz", + "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz", + "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz", + "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz", + "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.0" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz", + "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz", + "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz", + "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz", + "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz", + "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz", + "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.4" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz", + "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz", + "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz", + "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -454,11 +883,23 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -471,9 +912,18 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -639,6 +1089,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1555,6 +2014,12 @@ "node": ">= 0.10" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2311,6 +2776,18 @@ "postcss": "^8.3.11" } }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -2395,6 +2872,48 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/sharp": { + "version": "0.34.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz", + "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.3", + "@img/sharp-darwin-x64": "0.34.3", + "@img/sharp-libvips-darwin-arm64": "1.2.0", + "@img/sharp-libvips-darwin-x64": "1.2.0", + "@img/sharp-libvips-linux-arm": "1.2.0", + "@img/sharp-libvips-linux-arm64": "1.2.0", + "@img/sharp-libvips-linux-ppc64": "1.2.0", + "@img/sharp-libvips-linux-s390x": "1.2.0", + "@img/sharp-libvips-linux-x64": "1.2.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", + "@img/sharp-libvips-linuxmusl-x64": "1.2.0", + "@img/sharp-linux-arm": "0.34.3", + "@img/sharp-linux-arm64": "0.34.3", + "@img/sharp-linux-ppc64": "0.34.3", + "@img/sharp-linux-s390x": "0.34.3", + "@img/sharp-linux-x64": "0.34.3", + "@img/sharp-linuxmusl-arm64": "0.34.3", + "@img/sharp-linuxmusl-x64": "0.34.3", + "@img/sharp-wasm32": "0.34.3", + "@img/sharp-win32-arm64": "0.34.3", + "@img/sharp-win32-ia32": "0.34.3", + "@img/sharp-win32-x64": "0.34.3" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2488,6 +3007,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", diff --git a/zefie_wtvp_minisrv/package.json b/zefie_wtvp_minisrv/package.json index f0f90b65..9664ecdf 100644 --- a/zefie_wtvp_minisrv/package.json +++ b/zefie_wtvp_minisrv/package.json @@ -43,6 +43,7 @@ "proxy-agent": "^6.4.0", "rc4-crypto": "^1.5.0", "sanitize-html": "^2.13.0", + "sharp": "^0.34.3", "starttls": "^1.0.1", "strftime": "^0.10.2", "uuid": "^8.3.2"