Compare commits
6 Commits
f2fdeef5d1
...
7fe4a92b66
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fe4a92b66 | ||
|
|
79bce36057 | ||
|
|
26fabaa5c1 | ||
|
|
e229df97f0 | ||
|
|
9a32a554e4 | ||
|
|
c82edc8d9e |
82
eslint.config.mjs
Normal file
82
eslint.config.mjs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import security from 'eslint-plugin-security';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
files: ['**/*.js'],
|
||||||
|
ignores: ['node_modules/**', 'release/**', 'tests/**'],
|
||||||
|
plugins: { security },
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
sourceType: 'commonjs',
|
||||||
|
globals: {
|
||||||
|
require: 'readonly',
|
||||||
|
module: 'readonly',
|
||||||
|
exports: 'readonly',
|
||||||
|
__dirname: 'readonly',
|
||||||
|
__filename: 'readonly',
|
||||||
|
process: 'readonly',
|
||||||
|
console: 'readonly',
|
||||||
|
setTimeout: 'readonly',
|
||||||
|
clearTimeout: 'readonly',
|
||||||
|
setInterval: 'readonly',
|
||||||
|
clearInterval: 'readonly',
|
||||||
|
Buffer: 'readonly',
|
||||||
|
URL: 'readonly',
|
||||||
|
fetch: 'readonly',
|
||||||
|
AbortController: 'readonly',
|
||||||
|
navigator: 'readonly',
|
||||||
|
document: 'readonly',
|
||||||
|
window: 'readonly',
|
||||||
|
localStorage: 'readonly',
|
||||||
|
HTMLElement: 'readonly',
|
||||||
|
alert: 'readonly',
|
||||||
|
confirm: 'readonly',
|
||||||
|
requestAnimationFrame: 'readonly',
|
||||||
|
Intl: 'readonly',
|
||||||
|
crypto: 'readonly',
|
||||||
|
URLSearchParams: 'readonly',
|
||||||
|
EventSource: 'readonly',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// Security rules
|
||||||
|
// detect-object-injection disabled: 78 false positives from config lookups like obj[hosterName]
|
||||||
|
'security/detect-object-injection': 'off',
|
||||||
|
'security/detect-non-literal-regexp': 'warn',
|
||||||
|
'security/detect-unsafe-regex': 'warn',
|
||||||
|
'security/detect-buffer-noassert': 'warn',
|
||||||
|
'security/detect-eval-with-expression': 'error',
|
||||||
|
'security/detect-no-csrf-before-method-override': 'warn',
|
||||||
|
'security/detect-possible-timing-attacks': 'warn',
|
||||||
|
'security/detect-pseudoRandomBytes': 'warn',
|
||||||
|
// Code quality
|
||||||
|
'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
||||||
|
'no-undef': 'error',
|
||||||
|
'no-constant-condition': 'warn',
|
||||||
|
'no-debugger': 'error',
|
||||||
|
'no-duplicate-case': 'error',
|
||||||
|
'no-empty': ['warn', { allowEmptyCatch: true }],
|
||||||
|
'no-ex-assign': 'error',
|
||||||
|
'no-extra-boolean-cast': 'warn',
|
||||||
|
'no-func-assign': 'error',
|
||||||
|
'no-inner-declarations': 'error',
|
||||||
|
'no-irregular-whitespace': 'error',
|
||||||
|
'no-unreachable': 'error',
|
||||||
|
'use-isnan': 'error',
|
||||||
|
'valid-typeof': 'error',
|
||||||
|
'eqeqeq': ['warn', 'always'],
|
||||||
|
'no-caller': 'error',
|
||||||
|
'no-eval': 'error',
|
||||||
|
'no-implied-eval': 'error',
|
||||||
|
'no-new-func': 'error',
|
||||||
|
'no-throw-literal': 'warn',
|
||||||
|
'no-self-assign': 'error',
|
||||||
|
'no-self-compare': 'error',
|
||||||
|
'no-loss-of-precision': 'error',
|
||||||
|
'no-dupe-keys': 'error',
|
||||||
|
'no-unsafe-finally': 'error',
|
||||||
|
'no-unmodified-loop-condition': 'warn',
|
||||||
|
'no-template-curly-in-string': 'warn',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
@ -187,7 +187,7 @@ class VidmolyUploader {
|
|||||||
// XFS form fields
|
// XFS form fields
|
||||||
const formFields = {};
|
const formFields = {};
|
||||||
for (const [k, v] of Object.entries(params)) {
|
for (const [k, v] of Object.entries(params)) {
|
||||||
if (!/^file(?:_\d+)?$/i.test(k)) {
|
if (!/^file(?:_\d+)?$/i.test(k)) { // eslint-disable-line security/detect-unsafe-regex -- safe: no backtracking
|
||||||
formFields[k] = v;
|
formFields[k] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,7 +449,7 @@ class VidmolyUploader {
|
|||||||
let embed_url = null;
|
let embed_url = null;
|
||||||
let file_code = null;
|
let file_code = null;
|
||||||
|
|
||||||
const fnMatch = html.match(/<(?:input|textarea)[^>]*name=["']fn["'][^>]*(?:value=["']([^"']+)["'])?[^>]*>([^<]*)/i);
|
const fnMatch = html.match(/<(?:input|textarea)[^>]*name=["']fn["'][^>]*(?:value=["']([^"']+)["'])?[^>]*>([^<]*)/i); // eslint-disable-line security/detect-unsafe-regex -- parses trusted hoster HTML only
|
||||||
if (fnMatch) {
|
if (fnMatch) {
|
||||||
const codeFromFn = (fnMatch[1] || fnMatch[2] || '').trim();
|
const codeFromFn = (fnMatch[1] || fnMatch[2] || '').trim();
|
||||||
if (/^[a-z0-9]{8,16}$/i.test(codeFromFn)) {
|
if (/^[a-z0-9]{8,16}$/i.test(codeFromFn)) {
|
||||||
|
|||||||
62
package-lock.json
generated
62
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.4.2",
|
"version": "2.4.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.6.0",
|
"chokidar": "^3.6.0",
|
||||||
"undici": "^7.16.0",
|
"undici": "^7.16.0",
|
||||||
@ -75,9 +75,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@electron/asar/node_modules/minimatch": {
|
"node_modules/@electron/asar/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -381,13 +381,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@electron/universal/node_modules/minimatch": {
|
"node_modules/@electron/universal/node_modules/minimatch": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^2.0.1"
|
"brace-expansion": "^2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16 || 14 >=14.17"
|
"node": ">=16 || 14 >=14.17"
|
||||||
@ -1695,9 +1695,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cacache/node_modules/minimatch": {
|
"node_modules/cacache/node_modules/minimatch": {
|
||||||
"version": "5.1.6",
|
"version": "5.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2054,13 +2054,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/config-file-ts/node_modules/minimatch": {
|
"node_modules/config-file-ts/node_modules/minimatch": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^2.0.1"
|
"brace-expansion": "^2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16 || 14 >=14.17"
|
"node": ">=16 || 14 >=14.17"
|
||||||
@ -2376,9 +2376,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dir-compare/node_modules/minimatch": {
|
"node_modules/dir-compare/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3147,9 +3147,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/filelist/node_modules/minimatch": {
|
"node_modules/filelist/node_modules/minimatch": {
|
||||||
"version": "5.1.6",
|
"version": "5.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3462,9 +3462,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/glob/node_modules/minimatch": {
|
"node_modules/glob/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5159,9 +5159,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/readdir-glob/node_modules/minimatch": {
|
"node_modules/readdir-glob/node_modules/minimatch": {
|
||||||
"version": "5.1.6",
|
"version": "5.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
@ -5854,9 +5854,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "7.22.0",
|
"version": "7.24.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-7.24.5.tgz",
|
||||||
"integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==",
|
"integrity": "sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.18.1"
|
"node": ">=20.18.1"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "multi-hoster-uploader",
|
"name": "multi-hoster-uploader",
|
||||||
"version": "2.4.3",
|
"version": "2.4.4",
|
||||||
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -1293,6 +1293,7 @@ function getSelectedJobLinks() {
|
|||||||
async function startUpload() {
|
async function startUpload() {
|
||||||
if (uploading) return;
|
if (uploading) return;
|
||||||
// Wait for any running health check to finish (e.g. startup auto-check)
|
// Wait for any running health check to finish (e.g. startup auto-check)
|
||||||
|
// eslint-disable-next-line no-unmodified-loop-condition -- healthCheckRunning is modified externally between awaits
|
||||||
for (let _hcWait = 0; healthCheckRunning && _hcWait < 300; _hcWait++) await new Promise(r => setTimeout(r, 100)); // max 30s
|
for (let _hcWait = 0; healthCheckRunning && _hcWait < 300; _hcWait++) await new Promise(r => setTimeout(r, 100)); // max 30s
|
||||||
uploading = true; // set immediately to prevent double-click race
|
uploading = true; // set immediately to prevent double-click race
|
||||||
updateQueueActionButtons();
|
updateQueueActionButtons();
|
||||||
@ -1364,6 +1365,7 @@ async function startUpload() {
|
|||||||
|
|
||||||
async function startSelectedUpload() {
|
async function startSelectedUpload() {
|
||||||
if (uploading) return;
|
if (uploading) return;
|
||||||
|
// eslint-disable-next-line no-unmodified-loop-condition -- healthCheckRunning is modified externally between awaits
|
||||||
for (let _hcWait = 0; healthCheckRunning && _hcWait < 300; _hcWait++) await new Promise(r => setTimeout(r, 100)); // max 30s
|
for (let _hcWait = 0; healthCheckRunning && _hcWait < 300; _hcWait++) await new Promise(r => setTimeout(r, 100)); // max 30s
|
||||||
uploading = true; // set immediately to prevent double-click race
|
uploading = true; // set immediately to prevent double-click race
|
||||||
updateQueueActionButtons();
|
updateQueueActionButtons();
|
||||||
@ -1852,9 +1854,6 @@ function updateStatusBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Health Check ---
|
// --- Health Check ---
|
||||||
function setHealthCheckStatus(text) {
|
|
||||||
// Minimal inline status
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderHealthCheckResults(results) {
|
function renderHealthCheckResults(results) {
|
||||||
const container = document.getElementById('healthCheckResults');
|
const container = document.getElementById('healthCheckResults');
|
||||||
@ -1871,7 +1870,7 @@ function renderHealthCheckResults(results) {
|
|||||||
}).join('');
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeHealthCheck(hosters, mode) {
|
async function executeHealthCheck(hosters, _mode) {
|
||||||
renderHealthCheckResults([]);
|
renderHealthCheckResults([]);
|
||||||
const result = await window.api.runHealthCheck({ hosters });
|
const result = await window.api.runHealthCheck({ hosters });
|
||||||
const rows = result && Array.isArray(result.results) ? result.results : [];
|
const rows = result && Array.isArray(result.results) ? result.results : [];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user