diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f92a7009..77e82be6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,10 +8,14 @@ "customizations": { "vscode": { "extensions": [ - "junstyle.php-cs-fixer", "stylelint.vscode-stylelint", "jetmartin.bats", - "recca0120.vscode-phpunit" + "ms-azuretools.vscode-containers", + "github.vscode-github-actions", + "ms-vscode.makefile-tools", + "ms-vscode-remote.remote-containers", + "DEVSENSE.phptools-vscode", + "redhat.vscode-yaml" ] } }, diff --git a/Makefile b/Makefile index 6ebbb1c0..4ba00d24 100644 --- a/Makefile +++ b/Makefile @@ -101,6 +101,7 @@ local: build docker stop nextcloud-container || true docker container rm nextcloud-container || true docker run --rm -d -p 8080:80 --name nextcloud-container -e SERVER_BRANCH="v31.0.8" -v .:/var/www/html/apps-extra/gdatavaas ghcr.io/juliusknorr/nextcloud-dev-php84:latest + composer install # Builds the app for production and prepares it for the appstore under ./build/artifacts .PHONY: appstore diff --git a/appinfo/routes.php b/appinfo/routes.php index 0d0741d2..ffaaf294 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -27,6 +27,8 @@ => '/getSendMailSummaryOfMaliciousFiles', 'verb' => 'GET'], ['name' => 'settings#setSendMailSummaryOfMaliciousFiles', 'url' => '/setSendMailSummaryOfMaliciousFiles', 'verb' => 'POST'], - ['name' => 'settings#testsettings', 'url' => '/testsettings', 'verb' => 'POST'] + ['name' => 'settings#testsettings', 'url' => '/testsettings', 'verb' => 'POST'], + ['name' => 'settings#getCache', 'url' => '/getCache', 'verb' => 'GET'], + ['name' => 'settings#getHashlookup', 'url' => '/getHashlookup', 'verb' => 'GET'] ] ]; diff --git a/css/style.css b/css/style.css index 98e73ef9..4099cff2 100644 --- a/css/style.css +++ b/css/style.css @@ -25,6 +25,10 @@ select { box-sizing: border-box; } +.basic_settings_table .input_field input[type=checkbox] { + margin: 8px 0 8px 50px; +} + input.toggle-round { display: none; } diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 6ed5d532..651a40dc 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -51,6 +51,9 @@ public function setconfig( $doNotScanThis, $notifyMails, $maxScanSize, + $timeout, + bool $cache, + bool $hashlookup, ): JSONResponse { if (!empty($notifyMails)) { $mails = explode(',', preg_replace('/\s+/', '', $notifyMails)); @@ -63,6 +66,9 @@ public function setconfig( if ((int)$maxScanSize < 1) { return new JSONResponse(['status' => 'error', 'message' => 'Invalid max scan size: ' . $maxScanSize]); } + if ((int)$timeout < 1) { + return new JSONResponse(['status' => 'error', 'message' => 'Invalid timeout: ' . $timeout]); + } $this->config->setValueString($this->appName, 'username', $username); $this->config->setValueString($this->appName, 'password', $password); $this->config->setValueString($this->appName, 'clientId', $clientId); @@ -73,6 +79,9 @@ public function setconfig( $this->config->setValueString($this->appName, 'doNotScanThis', $doNotScanThis); $this->config->setValueString($this->appName, 'notifyMails', $notifyMails); $this->config->setValueInt($this->appName, 'maxScanSizeInMB', (int)$maxScanSize); + $this->config->setValueInt($this->appName, 'timeout', (int)$timeout); + $this->config->setValueBool($this->appName, 'cache', $cache); + $this->config->setValueBool($this->appName, 'hashlookup', $hashlookup); return new JSONResponse(['status' => 'success']); } @@ -186,4 +195,12 @@ public function testSettings(string $tokenEndpoint, string $vaasUrl): JSONRespon return new JSONResponse(['status' => 'error', 'message' => $e->getMessage()]); } } + + public function getCache(): JSONResponse { + return new JSONResponse(['status' => $this->config->getValueBool($this->appName, 'cache', true)]); + } + + public function getHashlookup(): JSONResponse { + return new JSONResponse(['status' => $this->config->getValueBool($this->appName, 'hashlookup', true)]); + } } diff --git a/lib/Service/VerdictService.php b/lib/Service/VerdictService.php index 5a14dd1a..7e9f12c9 100644 --- a/lib/Service/VerdictService.php +++ b/lib/Service/VerdictService.php @@ -210,7 +210,12 @@ public function createAndConnectVaas(): Vaas { $this->vaasUrl = 'https://' . substr($this->vaasUrl, 6); } } - $options = new VaasOptions(true, true, $this->vaasUrl); + $options = new VaasOptions( + useHashLookup: $this->appConfig->getValueBool(Application::APP_ID, 'hashlookup', true), + useCache: $this->appConfig->getValueBool(Application::APP_ID, 'cache', true), + vaasUrl: $this->vaasUrl, + timeout: $this->appConfig->getValueInt(Application::APP_ID, 'timeout', 300) + ); return Vaas::builder() ->withAuthenticator($this->getAuthenticator($this->authMethod, $this->tokenEndpoint)) ->withOptions($options) diff --git a/lib/Settings/VaasAdmin.php b/lib/Settings/VaasAdmin.php index 4e8b92b1..4e3e050f 100644 --- a/lib/Settings/VaasAdmin.php +++ b/lib/Settings/VaasAdmin.php @@ -57,7 +57,10 @@ public function getForm(): TemplateResponse { => $this->config->getValueBool(Application::APP_ID, 'sendMailOnVirusUpload'), 'notifyAdminEnabled' => $this->config->getValueBool(Application::APP_ID, 'notifyAdminEnabled'), 'maxScanSizeInMB' - => $this->config->getValueInt(Application::APP_ID, 'maxScanSizeInMB', 256) + => $this->config->getValueInt(Application::APP_ID, 'maxScanSizeInMB', 256), + 'timeout' => $this->config->getValueInt(Application::APP_ID, 'timeout', 300), + 'cache' => $this->config->getValueBool(Application::APP_ID, 'cache', true), + 'hashlookup' => $this->config->getValueBool(Application::APP_ID, 'hashlookup', true), ]; return new TemplateResponse(Application::APP_ID, 'admin', $params); diff --git a/src/admin-settings.js b/src/admin-settings.js index 56a0a494..305ea4eb 100644 --- a/src/admin-settings.js +++ b/src/admin-settings.js @@ -66,6 +66,9 @@ document.addEventListener('DOMContentLoaded', async () => { const doNotScanThis = document.querySelector('#doNotScanThis').value; const notifyMails = document.querySelector('#notify_mails').value; const maxScanSize = document.querySelector('#max-scan-size').value; + const timeout = document.querySelector('#timeout').value; + const cache = document.querySelector('#cache').checked; + const hashlookup = document.querySelector('#hashlookup').checked; const response = await postData(OC.generateUrl('apps/gdatavaas/setconfig'), { username: username, @@ -77,7 +80,10 @@ document.addEventListener('DOMContentLoaded', async () => { scanOnlyThis, doNotScanThis, notifyMails, - maxScanSize + maxScanSize, + timeout, + cache, + hashlookup }); const msgElement = document.querySelector('#auth_save_msg'); @@ -203,4 +209,7 @@ document.addEventListener('DOMContentLoaded', async () => { scanCounter.textContent = ' N/A'; console.log('Error getting files counter:', filesCounter['message']); } + + document.querySelector('#cache').checked = (await getData(OC.generateUrl('apps/gdatavaas/getCache'))).status; + document.querySelector('#hashlookup').checked = (await getData(OC.generateUrl('apps/gdatavaas/getHashlookup'))).status; }); diff --git a/src/files-action.js b/src/files-action.js index 347cf0ab..cd6f8482 100644 --- a/src/files-action.js +++ b/src/files-action.js @@ -15,37 +15,42 @@ registerFileAction(new FileAction({ }, iconSvgInline: () => Magnifier, async exec(file) { - const fileId = file.fileid; - let response = await fetch(OC.generateUrl('/apps/gdatavaas/scan'), { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'requesttoken': oc_requesttoken - }, - body: JSON.stringify({ - fileId: fileId - }) - }); - let vaasVerdict = await response.json(); - if (response.status === 200) { - switch (vaasVerdict['verdict']) { - case 'Malicious': - showError(t('gdatavaas', 'The file "' + file.basename + '" has been scanned with G DATA as verdict Malicious')); - break; - case 'Clean': - showSuccess(t('gdatavaas', 'The file "' + file.basename + '" has been scanned with G DATA as verdict Clean')); - break; - case 'Pup': - showWarning(t('gdatavaas', 'The file "' + file.basename + '" has been scanned with G DATA as ' + - 'verdict PUP (Potentially unwanted program)')); - break; - } - } else { - try { - showError(t('gdatavaas', vaasVerdict.error)); - } catch (e) { - showError(t('gdatavaas', 'An unknown error occurred while scanning the file')); + try { + const fileId = file.fileid; + let response = await fetch(OC.generateUrl('/apps/gdatavaas/scan'), { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'requesttoken': oc_requesttoken + }, + body: JSON.stringify({ + fileId: fileId + }) + }); + let vaasVerdict = await response.json(); + if (response.status === 200) { + switch (vaasVerdict['verdict']) { + case 'Malicious': + showError(t('gdatavaas', 'The file "' + file.basename + '" has been scanned with G DATA as verdict Malicious')); + break; + case 'Clean': + showSuccess(t('gdatavaas', 'The file "' + file.basename + '" has been scanned with G DATA as verdict Clean')); + break; + case 'Pup': + showWarning(t('gdatavaas', 'The file "' + file.basename + '" has been scanned with G DATA as ' + + 'verdict PUP (Potentially unwanted program)')); + break; + } + } else { + try { + showError(t('gdatavaas', vaasVerdict.error)); + } catch (e) { + showError(t('gdatavaas', 'An unknown error occurred while scanning the file')); + } } } + catch (e) { + showError(t('gdatavaas', 'An error occurred while trying to scan the file: ') + e); + } }, })) diff --git a/templates/admin.php b/templates/admin.php index 095bb5e2..3825c674 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -19,7 +19,7 @@
" class="visible"> |
+ " class="visible"> |
||
| + | + | ||
| + | /> | +||
| + | /> | +