From 677a79026c405456ea6ec18a07a9c765b1b02ea9 Mon Sep 17 00:00:00 2001 From: Jan Christoph Uhde Date: Thu, 25 Apr 2019 09:56:29 +0200 Subject: [PATCH] Foxx Security (#8845) --- CHANGELOG | 66 +- .../Appendix/JavaScriptModules/FileSystem.md | 12 +- .../Manual/ReleaseNotes/NewFeatures35.md | 52 +- Documentation/Books/Manual/SUMMARY.md | 1 + Documentation/Books/Manual/Security/README.md | 1 + .../Books/Manual/Security/SecurityOptions.md | 160 ++++ README_maintainers.md | 21 + UnitTests/OskarTestSuitesBlackList | 2 - arangod/Actions/ActionFeature.cpp | 4 +- arangod/Actions/actions.h | 7 +- arangod/Aql/Expression.cpp | 6 +- arangod/Aql/Functions.cpp | 6 +- arangod/Aql/ModificationExecutor.cpp | 5 +- arangod/Aql/Query.cpp | 4 +- arangod/CMakeLists.txt | 1 + .../GeneralServer/ServerSecurityFeature.cpp | 84 ++ arangod/GeneralServer/ServerSecurityFeature.h | 49 + .../RestHandler/RestAdminExecuteHandler.cpp | 62 +- arangod/RestHandler/RestAdminLogHandler.cpp | 13 +- .../RestAdminStatisticsHandler.cpp | 12 + arangod/RestHandler/RestCollectionHandler.cpp | 2 +- arangod/RestHandler/RestEngineHandler.cpp | 30 +- arangod/RestHandler/RestStatusHandler.cpp | 12 + arangod/RestHandler/RestTasksHandler.cpp | 64 +- .../RestHandler/RestTransactionHandler.cpp | 6 +- arangod/RestHandler/RestVersionHandler.cpp | 61 +- arangod/RestServer/CheckVersionFeature.cpp | 4 +- arangod/RestServer/ConsoleThread.cpp | 20 +- arangod/RestServer/ConsoleThread.h | 4 +- arangod/RestServer/ScriptFeature.cpp | 15 +- arangod/RestServer/UpgradeFeature.cpp | 4 +- arangod/RestServer/arangod.cpp | 6 +- arangod/RocksDBEngine/RocksDBCollection.cpp | 64 +- arangod/Transaction/Manager.cpp | 122 +-- arangod/V8Server/FoxxQueuesFeature.h | 11 +- arangod/V8Server/V8Context.cpp | 20 +- arangod/V8Server/V8Context.h | 27 - arangod/V8Server/V8DealerFeature.cpp | 154 ++- arangod/V8Server/V8DealerFeature.h | 43 +- arangod/V8Server/v8-actions.cpp | 159 +++- arangod/V8Server/v8-actions.h | 4 +- arangod/V8Server/v8-dispatcher.cpp | 5 + arangod/V8Server/v8-query.cpp | 8 +- arangod/V8Server/v8-statistics.cpp | 31 + arangod/V8Server/v8-vocbase.cpp | 209 +---- arangod/VocBase/Methods/AqlUserFunctions.cpp | 6 +- arangod/VocBase/Methods/Collections.cpp | 11 +- arangod/VocBase/Methods/Databases.cpp | 70 +- arangod/VocBase/Methods/Tasks.cpp | 16 +- arangosh/Export/ExportFeature.cpp | 5 +- arangosh/Import/ImportFeature.cpp | 5 +- arangosh/Shell/ClientFeature.cpp | 14 + arangosh/Shell/ClientFeature.h | 9 + arangosh/Shell/V8ClientConnection.cpp | 24 +- arangosh/Shell/V8ShellFeature.cpp | 30 +- arangosh/Shell/arangosh.cpp | 2 + arangosh/Utils/ClientManager.cpp | 5 + etc/jenkins/arangosh.conf | 2 + etc/relative/arangosh.conf | 2 + etc/testing/arangosh.conf | 4 + js/actions/_admin/app.js | 1 + js/actions/_admin/foxx/app.js | 18 + js/actions/api-cluster.js | 15 + js/actions/api-simple.js | 10 + js/actions/api-system.js | 1 + js/actions/api-traversal.js | 1 + .../system/_admin/aardvark/APP/aardvark.js | 3 +- js/apps/system/_admin/aardvark/APP/foxxes.js | 22 +- .../aardvark/APP/frontend/build/app.min.js | 2 +- .../aardvark/APP/frontend/build/app.min.js.gz | Bin 139294 -> 139427 bytes .../APP/frontend/build/index-min.html | 8 +- .../APP/frontend/build/index-min.html.gz | Bin 43308 -> 43241 bytes .../aardvark/APP/frontend/build/libs.min.js | 5 +- .../APP/frontend/build/libs.min.js.gz | Bin 1103410 -> 1095392 bytes .../APP/frontend/build/style-minified.css | 2 +- .../APP/frontend/build/style-minified.css.gz | Bin 54014 -> 53712 bytes .../aardvark/APP/frontend/build/style.css.gz | Bin 63538 -> 63244 bytes .../js/collections/arangoCollections.js | 6 +- .../APP/frontend/js/templates/indicesView.ejs | 8 +- .../js/templates/modalCollectionInfo.ejs | 11 + .../APP/frontend/js/views/collectionsView.js | 40 +- .../APP/frontend/js/views/dashboardView.js | 2 +- .../APP/frontend/js/views/footerView.js | 3 + .../frontend/js/views/installServiceView.js | 15 +- .../system/_admin/aardvark/APP/package.json | 47 + js/apps/system/_api/foxx/APP/index.js | 3 + js/client/modules/@arangodb/process-utils.js | 296 +++--- js/client/modules/@arangodb/test-utils.js | 1 + .../modules/@arangodb/testsuites/arangosh.js | 44 +- .../@arangodb/testsuites/permissions.js | 122 +++ .../@arangodb/testsuites/resilience.js | 14 +- js/common/bootstrap/errors.js | 38 + js/common/bootstrap/modules/fs.js | 9 + js/common/bootstrap/modules/internal.js | 64 +- js/common/modules/@arangodb/common.js | 9 +- js/common/modules/@arangodb/foxx/store.js | 9 +- .../modules/@arangodb/graph/traversal.js | 31 +- js/common/modules/jsunity.js | 2 +- js/server/bootstrap/autoload.js | 6 +- js/server/bootstrap/modules/internal.js | 57 +- js/server/bootstrap/routing.js | 14 +- js/server/initialize.js | 4 +- js/server/modules/@arangodb/actions.js | 20 +- js/server/modules/@arangodb/foxx/manager.js | 6 +- .../modules/@arangodb/foxx/queues/manager.js | 11 +- js/server/server.js | 13 +- lib/ApplicationFeatures/ApplicationServer.cpp | 9 +- lib/ApplicationFeatures/ApplicationServer.h | 6 +- lib/ApplicationFeatures/DaemonFeature.cpp | 8 +- lib/ApplicationFeatures/TempFeature.cpp | 1 - lib/ApplicationFeatures/V8Phase.cpp | 4 +- lib/ApplicationFeatures/V8SecurityFeature.cpp | 402 ++++++++ lib/ApplicationFeatures/V8SecurityFeature.h | 136 +++ lib/ApplicationFeatures/V8ShellPhase.cpp | 2 + lib/Basics/FileUtils.cpp | 9 +- lib/Basics/files.cpp | 217 +++-- lib/Basics/files.h | 17 +- lib/CMakeLists.txt | 2 + lib/ProgramOptions/ProgramOptions.cpp | 13 +- lib/ProgramOptions/ProgramOptions.h | 7 +- lib/V8/JSLoader.cpp | 42 - lib/V8/JSLoader.h | 8 - lib/V8/JavaScriptSecurityContext.cpp | 88 ++ lib/V8/JavaScriptSecurityContext.h | 104 +++ lib/V8/v8-environment.cpp | 46 +- lib/V8/v8-globals.cpp | 4 +- lib/V8/v8-globals.h | 14 +- lib/V8/v8-shell.cpp | 21 + lib/V8/v8-utils.cpp | 627 ++++++++++++- scripts/unittest | 1 + tests/Basics/files-test.cpp | 21 +- tests/js/client/permissions/endpoints.js | 59 ++ tests/js/client/permissions/environment.js | 84 ++ tests/js/client/permissions/execute.js | 108 +++ tests/js/client/permissions/filesystem.js | 875 ++++++++++++++++++ tests/js/client/permissions/harden.js | 76 ++ tests/js/client/permissions/options.js | 83 ++ tests/js/client/permissions/ports.js | 99 ++ .../js/client/shell/shell-require-canceled.js | 86 -- .../test-data/apps/server-security/index.js | 85 ++ .../apps/server-security/manifest.json | 6 + .../permissions/test-admin-execute-allowed.js | 54 ++ .../test-admin-execute-disallowed.js | 55 ++ .../test-api-transaction-hardened.js | 119 +++ .../test-api-transaction-restricted.js | 121 +++ .../test-api-transaction-unrestricted.js | 103 +++ .../server/permissions/test-foxx-apis-off.js | 128 +++ .../server/permissions/test-foxx-apis-on.js | 130 +++ .../test-foxx-service-access-denied.js | 177 ++++ .../permissions/test-hardened-rest-apis.js | 155 ++++ tests/js/server/permissions/test-tasks.js | 172 ++++ .../replication/sync/replication-sync.js | 2 +- utils/jslint.sh | 3 + 153 files changed, 6078 insertions(+), 1362 deletions(-) create mode 100644 Documentation/Books/Manual/Security/SecurityOptions.md create mode 100644 arangod/GeneralServer/ServerSecurityFeature.cpp create mode 100644 arangod/GeneralServer/ServerSecurityFeature.h create mode 100644 js/apps/system/_admin/aardvark/APP/package.json create mode 100644 js/client/modules/@arangodb/testsuites/permissions.js create mode 100644 lib/ApplicationFeatures/V8SecurityFeature.cpp create mode 100644 lib/ApplicationFeatures/V8SecurityFeature.h create mode 100644 lib/V8/JavaScriptSecurityContext.cpp create mode 100644 lib/V8/JavaScriptSecurityContext.h create mode 100644 tests/js/client/permissions/endpoints.js create mode 100644 tests/js/client/permissions/environment.js create mode 100644 tests/js/client/permissions/execute.js create mode 100644 tests/js/client/permissions/filesystem.js create mode 100644 tests/js/client/permissions/harden.js create mode 100644 tests/js/client/permissions/options.js create mode 100644 tests/js/client/permissions/ports.js delete mode 100644 tests/js/client/shell/shell-require-canceled.js create mode 100644 tests/js/common/test-data/apps/server-security/index.js create mode 100644 tests/js/common/test-data/apps/server-security/manifest.json create mode 100644 tests/js/server/permissions/test-admin-execute-allowed.js create mode 100644 tests/js/server/permissions/test-admin-execute-disallowed.js create mode 100644 tests/js/server/permissions/test-api-transaction-hardened.js create mode 100644 tests/js/server/permissions/test-api-transaction-restricted.js create mode 100644 tests/js/server/permissions/test-api-transaction-unrestricted.js create mode 100644 tests/js/server/permissions/test-foxx-apis-off.js create mode 100644 tests/js/server/permissions/test-foxx-apis-on.js create mode 100644 tests/js/server/permissions/test-foxx-service-access-denied.js create mode 100644 tests/js/server/permissions/test-hardened-rest-apis.js create mode 100644 tests/js/server/permissions/test-tasks.js diff --git a/CHANGELOG b/CHANGELOG index 5bcc06c93b..f8a81d39b6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,30 @@ devel ----- +* added options to make server more secure: + + - `--server.harden`: denies access to certain REST APIs that return server internals + - `--foxx.api`: set to false disables Foxx management API + - `--foxx.store`: set to false disables Foxx UI + - `--javascript.allow-port-testing`: enables internal.testPort() + - `--javascript.allow-external-process-control`: enables external process control + - `--javascript.harden`: disables getPid(), processStatistics() and logLevel() + - `--javascript.startup-options-whitelist`: control startup options visible in JavaScript + - `--javascript.environment-variables-whitelist`: control environment variables visible in JavaScript + - `--javascript.endpoints-whitelist`: control accessible endpoints in JavaScript + - `--javascript.files-whitelist`: control file access in JavaScript + + Note: There is a [detailed description of all options](https://github.com/arangodb-helper/arangodb/blob/master/Documentation/Books/Manual/Security/SecurityOptions.md). + +* prevent arangod from making a call to www.arangodb.com at startup + + This call was done to check for available updates, but it could have contributed + to small startup delays in case outgoing connections were blocked. + +* removed support for undocumented HTTP header `x-arango-v8-context`, which + allowed controlling in which particular V8 context number a JavaScript-based + action was executed. This header was only used internally for testing. + * db._query now handles additional arguments correctly when passing an AQL query object instead of a query string and separate bindVars @@ -25,7 +49,7 @@ devel * updated bundled version of jemalloc memory allocator to 5.2.0. * don't create per-database system collection `_frontend` automatically. - This collection is only needed by the web UI, and it can be created lazily + This collection is only needed by the web UI, and it can be created lazily when needed. * added logging option `--log.time-format` to configure the time format used @@ -37,22 +61,22 @@ devel - uptime: seconds since server start - uptime-millis: seconds since server start, with millisecond precision - uptime-micros: seconds since server start, with microsecond precision - - utc-datestring: UTC-based date and time in format YYYY-MM-DDTHH:MM:SSZ - - utc-datestring-millis: UTC-based date and time in format YYYY-MM-DDTHH:MM:SS.FFFZ + - utc-datestring: UTC-based date and time in format YYYY-MM-DDTHH:MM:SSZ + - utc-datestring-millis: UTC-based date and time in format YYYY-MM-DDTHH:MM:SS.FFFZ - local-datestring: local date and time in format YYYY-MM-DDTHH:MM:SS - This change deprecates the existing options `--log.use-microtime` and + This change deprecates the existing options `--log.use-microtime` and `--log.use-localtime`, because the functionality provided by these options is covered by `--log.time-format` too. * added "smart joins" to the ArangoDB Enterprise Edition that allows running cluster - joins between two certain sharded collections with performance close to that of a - local join operation. + joins between two certain sharded collections with performance close to that of a + local join operation. * fixed internal issue #3815: fixed the removal of connected edges when removing a vertex graph node in a smart graph environment. -* show startup warning in case kernel setting `vm.overcommit_memory` is set +* show startup warning in case kernel setting `vm.overcommit_memory` is set to a value of 2 and the jemalloc memory allocator is in use. This combination does not play well together. @@ -68,7 +92,7 @@ devel executables with the `--version` command. It also changes the attribute name in the detailed response of the `/_api/version` REST API. -* internal issue #2276: fixed the sorting of the databases in the database +* internal issue #2276: fixed the sorting of the databases in the database selection dropdown in the web ui. The sort order differed based on whether authentication was enabled or disabled. @@ -77,7 +101,7 @@ devel * fixed internal issue #3789: restricted the allowed query names for user defined custom queries within the web ui. - + * upgraded bundled RocksDB version to 6.0 * added "--log.ids" option to arangod @@ -94,7 +118,7 @@ devel * fixed internal issue #528: ArangoSearch range query sometimes doesn't work correctly with numeric values -* changed type of the startup option `--rocksdb.recycle-log-file-num` from +* changed type of the startup option `--rocksdb.recycle-log-file-num` from numeric to boolean, as this is also the type the options has in the RocksDB library. @@ -102,22 +126,22 @@ devel consistent `--rocksdb.delayed-write-rate`. When the old option name is used, the arangod startup will be aborted with a descriptive error message. -* if not explicitly configured, make agency nodes start removing their unused +* if not explicitly configured, make agency nodes start removing their unused WAL files a few seconds after the completed server startup already. This is because on agency nodes, unused WAL files do not need to be retained for - potential replication clients to read them. + potential replication clients to read them. * added option `--all-databases` to arangodump and arangorestore When set to true, this makes arangodump dump all available databases the current user has access to. The option `--all-databases` cannot be - used in combination with the option `--server.database`. + used in combination with the option `--server.database`. When `--all-databases` is used, arangodump will create a subdirectory - with the data of each dumped database. Databases will be dumped one + with the data of each dumped database. Databases will be dumped one after the other. However, inside each database, the collections of the database can be dumped in parallel using multiple threads. - + For arangorestore, this makes it restore all databases from inside the subdirectories of the specified dump directory. Using the option for arangorestore only makes sense for dumps created with arangodump and @@ -125,12 +149,12 @@ devel be invoked with the options `--all-databases` and `--server.database` at the same time. Additionally, the option `--force-same-database` cannot be used together with `--all-databases`. - + If the to-be-restored databases do not exist on the target server, then restoring data into them will fail unless the option `--create-database` is also specified. Please note that in this case a database user must be used that has access to the `_system` database, in order to create - the databases on restore. + the databases on restore. * added index hints feature to AQL @@ -138,12 +162,12 @@ devel If a name is not specified on index creation, one will be auto-generated. -* Under normal circumstances there should be no need to connect to a - database server in a cluster with one of the client tools, and it is +* Under normal circumstances there should be no need to connect to a + database server in a cluster with one of the client tools, and it is likely that any user operations carried out there with one of the client - tools may cause trouble. + tools may cause trouble. - The client tools arangosh, arangodump and arangorestore will now emit + The client tools arangosh, arangodump and arangorestore will now emit a warning when connecting with them to a database server node in a cluster. * fix compation behavior of followers diff --git a/Documentation/Books/Manual/Appendix/JavaScriptModules/FileSystem.md b/Documentation/Books/Manual/Appendix/JavaScriptModules/FileSystem.md index d3b27489f5..b90d2e7de8 100644 --- a/Documentation/Books/Manual/Appendix/JavaScriptModules/FileSystem.md +++ b/Documentation/Books/Manual/Appendix/JavaScriptModules/FileSystem.md @@ -113,7 +113,10 @@ absolute path to the same location is returned. sets file permissions of specified files (non windows only) -`fs.exists(path)` +`fs.chmod(path, mode)` + +where `mode` is a string with a leading zero matching the `OCTAL-MODE` as explained +in *nix `man chmod`. Returns true on success. @@ -288,6 +291,13 @@ the specified filename. +### linkFile + +creates a symbolic link from a target in the place of linkpath. +`fs.linkFile(target, linkpath)` + +In `linkpath` a symbolic link to `target` will be created. + ### move diff --git a/Documentation/Books/Manual/ReleaseNotes/NewFeatures35.md b/Documentation/Books/Manual/ReleaseNotes/NewFeatures35.md index 3ef4f94ad0..a1e2396b9f 100644 --- a/Documentation/Books/Manual/ReleaseNotes/NewFeatures35.md +++ b/Documentation/Books/Manual/ReleaseNotes/NewFeatures35.md @@ -303,6 +303,41 @@ Mon Apr 01 2019 02:00:00 GMT+0200 (Central European Summer Time) > new Date("2019-04-01T00:00:00Z"); Mon Apr 01 2019 02:00:00 GMT+0200 (Central European Summer Time) ``` + +### JavaScript security options + +ArangoDB 3.5 provides several new options for restricting the functionality of +JavaScript application code running in the server, with the intent to make a setup +more secure. + +There now exist startup options for restricting which environment variables and +values of which configuration options JavaScript code is allowed to read. These +options can be set to prevent leaking of confidential information from the +environment or the setup into the JavaScript application code. +Additionally there are options to restrict outbound HTTP connections from JavaScript +applications to certain endpoints and to restrict filesystem access from JavaScript +applications to certain directories only. + +Finally there are startup options to turn off the REST APIs for managing Foxx +services, which can be used to prevent installation and uninstallation of Foxx +applications on a server. A separate option is provided to turn off access and +connections to the central Foxx app store via the web interface. + +A complete overview of the security options can be found in [Security Options](../Security/SecurityOptions.md). + +### Foxx + +Request credentials are now exposed via the `auth` property: + +```js +const tokens = context.collection("tokens"); +router.get("/authorized", (req, res) => { + if (!req.auth || !req.auth.bearer || !tokens.exists(req.auth.bearer)) { + res.throw(403, "Not authenticated"); + } + // ... +}); +``` ### API improvements @@ -381,6 +416,7 @@ Client configurations that use this configuration variable should adjust their configuration and set this variable to a boolean value instead of to a numeric value. + Miscellaneous ------------- @@ -455,19 +491,3 @@ The bundled JEMalloc memory allocator used in ArangoDB release packages has been upgraded from version 5.0.1 to version 5.2.0. The bundled version of the RocksDB library has been upgraded from 5.16 to 6.0. - - -Foxx ----- - -Request credentials are now exposed via the `auth` property: - -```js -const tokens = context.collection("tokens"); -router.get("/authorized", (req, res) => { - if (!req.auth || !req.auth.bearer || !tokens.exists(req.auth.bearer)) { - res.throw(403, "Not authenticated"); - } - // ... -}); -``` diff --git a/Documentation/Books/Manual/SUMMARY.md b/Documentation/Books/Manual/SUMMARY.md index d370e7eb23..f2a2ff103b 100644 --- a/Documentation/Books/Manual/SUMMARY.md +++ b/Documentation/Books/Manual/SUMMARY.md @@ -359,6 +359,7 @@ * [Removal Procedure](Administration/Starter/Removal.md) * [Recovery Procedure](Administration/Starter/Recovery.md) * [Security](Security/README.md) + * [Security Options](Security/SecurityOptions.md) * [Change Root Password](Security/ChangeRootPassword.md) * [Encryption at Rest](Security/Encryption/README.md) * [Auditing](Security/Auditing/README.md) diff --git a/Documentation/Books/Manual/Security/README.md b/Documentation/Books/Manual/Security/README.md index e865629be4..cf003bc06f 100644 --- a/Documentation/Books/Manual/Security/README.md +++ b/Documentation/Books/Manual/Security/README.md @@ -1,5 +1,6 @@ # Security +- [Security Options](SecurityOptions.md) - [Change Root Password](ChangeRootPassword.md) - [Encryption at Rest](Encryption/README.md) - [Auditing](Auditing/README.md) diff --git a/Documentation/Books/Manual/Security/SecurityOptions.md b/Documentation/Books/Manual/Security/SecurityOptions.md new file mode 100644 index 0000000000..d762bc808b --- /dev/null +++ b/Documentation/Books/Manual/Security/SecurityOptions.md @@ -0,0 +1,160 @@ +# Server security options + +_arangod_ provides a variety of options to make a setup more secure. +Administrators can use these options to limit access to certain ArangoDB +server functionality as well as providing the leakage of information about +the environment that a server is running in. + +## General security options + +The following security options are available: + +- `--server.harden` + If this option is set to `true` and authentication is enabled, non-admin users + will be denied access to the following REST APIs: + + * `/_admin/log` + * `/_admin/log/level` + * `/_admin/status` + * `/_admin/statistics` + * `/_admin/statistics-description` + * `/_api/engine/stats` + + Additionally, no version details will be revealed by the version REST API at + `/_api/version`. + ` + The default value for this option is `false`. + +## JavaScript security options + +`arangod` has several options that allow you to make your installation more +secure when it comes to running application code in it. Below you will find +an overview of the relevant options. + +### Blacklist and whitelists + +Several options exists to restrict JavaScript application code functionality +to just certain allowed subsets. Which subset of functionality is available +can be controlled via blacklisting and whitelisting access to individual +components. Blacklists can be used to disallow access to dedicated functionality, +whereas whitelists can be used to explicitly allow access to certain functionality. + +If an item is covered by both a blacklist and a whitelist, the whitelist will +overrule and access to the functionality will be allowed. + +Values for blacklist and whitelist options need to be specified as ECMAScript +regular expressions. Each option can be used multiple times. In this case, +the individual values for each option will be combined with a _logical or_. + +For example, the following combination of startup options + + --javascript.startup-options-whitelist "^server\." + --javascript.startup-options-whitelist "^log\." + --javascript.startup-options-blacklist "^javascript\." + --javascript.startup-options-blacklist "endpoint" + +will resolve internally to the following regular expressions: + +``` +--javascript.startup-options-whitelist = "^server\.|^log\." +--javascript.startup-options-blacklist = "^javascript\.|endpoint" +``` + +Access to directories and files from JavaScript operations is only +controlled via a whitelist, which can be specified via the startup +option `--javascript.files-whitelist`. + +For example, when using the following startup options + + --javascript.startup-options-whitelist "^/etc/required/" + --javascript.startup-options-whitelist "^/etc/mtab/" + +all files in the directories `/etc/required` and `/etc/mtab` plus their +subdirectories will be accessible, while access to files in any other directories +will be disallowed from JavaScript operations, with the following exceptions: + +- ArangoDB's temporary directory: JavaScript code is given access to this + directory for storing temporary files. The temporary directory location + can be specified explicitly via the `--temp.path` option at startup. + If the option is not specified, ArangoDB will automatically use a subdirectory + of the system's temporary directory). +- ArangoDB's own JavaScript code, shipped with the ArangoDB release packages. + Files in this directory and its subdirectories will be readable for JavaScript + code running in ArangoDB. The exact path can be specified by the startup option + `--javascript.startup-directory`. + +### Options for blacklisting and whitelisting + +The following options are available for blacklisting and whitelisting access +to dedicated functionality for application code: + +- `--javascript.startup-options-whitelist` and `--javascript.startup-options-blacklist`: + These options control which startup options will be exposed to JavaScript code, + following above rules for blacklists and whitelists. + +- `--javascript.environment-variables-whitelist` and `--javascript.environment-variables-blacklist`: + These options control which environment variables will be exposed to JavaScript + code, following above rules for blacklists and whitelists. + +- `--javascript.endpoints-whitelist` and `--javascript.endpoints-blacklist`: + These options control which endpoints can be used from within the `@arangodb/request` + JavaScript module. + Endpoint values are passed into the filter in a normalized format starting + with either of the prefixes `tcp://`, `ssl://`, `unix://` or `srv://`. + Note that for HTTP/SSL-based endpoints the port number will be included too, + and that the endpoint can be specified either as an IP address or host name + from application code. + +- `--javascript.files-whitelist`: + This option controls which filesystem paths can be accessed from JavaScript code. + +### Additional JavaScript security options + +In addition to the blacklisting and whitelisting security options, the following +extra options are available for locking down JavaScript access to server functionality: + +- `--javascript.allow-port-testing`: + If set to `true`, this option enables the `testPort` JavaScript function in the + `internal` module. The default value is `false`. + +- `--javascript.allow-external-process-control`: + If set to `true`, this option allows the execution and control of external processes + from JavaScript code via the functions from the `internal` module: + + - executeExternal + - executeExternalAndWait + - getExternalSpawned + - killExternal + - suspendExternal + - continueExternal + - statusExternal + +- `--javascript.harden`: + If set to `true`, this setting will deactivate the following JavaScript functions + which may leak information about the environment: + + - `internal.clientStatistics()` + - `internal.httpStatistics()` + - `internal.processStatistics()` + - `internal.getPid()` + - `internal.logLevel()`. + + The default value is `false`. + +## Security options for managing Foxx applications + +The following options are available for controlling the installation of Foxx applications +in an ArangoDB server: + +- `--foxx.api`: + If set to `false`, this option disables the Foxx management API, which will make it + impossible to install and uninstall Foxx applications. Setting the option to `false` + will also deactivate the "Services" section in the web interface. + The default value is `true`, meaning that Foxx apps can be installed and uninstalled. + +- `--foxx.store`: + If set to `false`, this option disables the Foxx app store in ArangoDB's web interface, + which will also prevent ArangoDB and its web interface from making calls to the main Foxx + application Github repository at https://github.com/arangodb/foxx-apps. + The default value is `true`. + diff --git a/README_maintainers.md b/README_maintainers.md index 40585674f2..78f3ece0de 100644 --- a/README_maintainers.md +++ b/README_maintainers.md @@ -798,3 +798,24 @@ for `mocha`) match the versions required by the updated module and delete any duplicated nested dependencies if necessary (e.g. `mocha/node_modules/glob`) to make sure the global (mocked) version is used instead. +Changing the FrontEnd +===================== + +Change to `js/apps/system/_admin/aardvark/APP/` and open +`manifest.json`. Then apply the following change: + +``` + "/app.js": { + - "path": "frontend/build/app.min.js", + - "gzip": true + + "path": "frontend/build/app.js", + + "gzip": false + }, +``` + +Then run `grunt`, `grunt deploy` and `grunt watch`. This +should make every change in the code available after a +reload for the browser. + +Note: You might need to do the same for other files. Usually +the change for `app` should suffice. diff --git a/UnitTests/OskarTestSuitesBlackList b/UnitTests/OskarTestSuitesBlackList index c777febee5..510680e91b 100644 --- a/UnitTests/OskarTestSuitesBlackList +++ b/UnitTests/OskarTestSuitesBlackList @@ -1,5 +1,3 @@ upgrade_data_3.2.* upgrade_data_3.3.* -permissions -permissions_server audit diff --git a/arangod/Actions/ActionFeature.cpp b/arangod/Actions/ActionFeature.cpp index f6c162b2d7..c2a417f18e 100644 --- a/arangod/Actions/ActionFeature.cpp +++ b/arangod/Actions/ActionFeature.cpp @@ -58,8 +58,8 @@ void ActionFeature::start() { V8DealerFeature* dealer = ApplicationServer::getFeature("V8Dealer"); - dealer->defineContextUpdate([](v8::Isolate* isolate, v8::Handle context, - size_t) { TRI_InitV8Actions(isolate, context); }, + dealer->defineContextUpdate([](v8::Isolate* isolate, v8::Handle /*context*/, + size_t) { TRI_InitV8Actions(isolate); }, nullptr); } diff --git a/arangod/Actions/actions.h b/arangod/Actions/actions.h index 5a5f372a1f..d9c013a942 100644 --- a/arangod/Actions/actions.h +++ b/arangod/Actions/actions.h @@ -46,7 +46,11 @@ class TRI_action_result_t { /// @brief action descriptor class TRI_action_t { public: - TRI_action_t() : _urlParts(0), _isPrefix(false), _allowUseDatabase(false) {} + TRI_action_t() : + _urlParts(0), + _isPrefix(false), + _allowUseDatabase(false), + _isSystem(false) {} virtual ~TRI_action_t() {} @@ -69,6 +73,7 @@ class TRI_action_t { bool _isPrefix; bool _allowUseDatabase; + bool _isSystem; }; /// @brief fake action class used only inside /_admin/execute RestHandler diff --git a/arangod/Aql/Expression.cpp b/arangod/Aql/Expression.cpp index 112d2268ea..ca2a064096 100644 --- a/arangod/Aql/Expression.cpp +++ b/arangod/Aql/Expression.cpp @@ -882,13 +882,9 @@ AqlValue Expression::executeSimpleExpressionFCallJS(AstNode const* node, { ISOLATE; TRI_ASSERT(isolate != nullptr); - TRI_V8_CURRENT_GLOBALS_AND_SCOPE; + v8::HandleScope scope(isolate); \ _ast->query()->prepareV8Context(); - auto old = v8g->_query; - v8g->_query = static_cast(_ast->query()); - TRI_DEFER(v8g->_query = old); - std::string jsName; size_t const n = static_cast(member->numMembers()); size_t callArgs = (node->type == NODE_TYPE_FCALL_USER ? 2 : n); diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 17213e081a..77d7380ca6 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -1086,16 +1086,12 @@ AqlValue callApplyBackend(ExpressionContext* expressionContext, transaction::Met // JavaScript function (this includes user-defined functions) { ISOLATE; - TRI_V8_CURRENT_GLOBALS_AND_SCOPE; + v8::HandleScope scope(isolate); \ Query* query = expressionContext->query(); TRI_ASSERT(query != nullptr); query->prepareV8Context(); - auto old = v8g->_query; - v8g->_query = query; - TRI_DEFER(v8g->_query = old); - std::string jsName; int const n = static_cast(invokeParams.size()); int const callArgs = (func == nullptr ? 3 : n); diff --git a/arangod/Aql/ModificationExecutor.cpp b/arangod/Aql/ModificationExecutor.cpp index 0d659c0dbe..3342d47c9d 100644 --- a/arangod/Aql/ModificationExecutor.cpp +++ b/arangod/Aql/ModificationExecutor.cpp @@ -46,14 +46,13 @@ std::string toString(SingleBlockFetcher&) { template ModificationExecutorBase::ModificationExecutorBase(Fetcher& fetcher, Infos& infos) - : _infos(infos), _fetcher(fetcher), _prepared(false){}; + : _infos(infos), _fetcher(fetcher), _prepared(false) {} template ModificationExecutor::ModificationExecutor(Fetcher& fetcher, Infos& infos) : ModificationExecutorBase(fetcher, infos), _modifier() { this->_infos._trx->pinData(this->_infos._aqlCollection->id()); // important for mmfiles - // LOG_DEVEL << toString(_modifier) << " " << toString(this->_fetcher); // <-- enable this first when debugging modification problems -}; +} template ModificationExecutor::~ModificationExecutor() = default; diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index 686ac1718d..e5b0a7d408 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -51,6 +51,7 @@ #include "Transaction/V8Context.h" #include "Utils/CollectionNameResolver.h" #include "Utils/ExecContext.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-conv.h" #include "V8/v8-vpack.h" #include "V8Server/V8DealerFeature.h" @@ -1176,7 +1177,8 @@ void Query::enterContext() { "V8 engine is disabled"); } TRI_ASSERT(V8DealerFeature::DEALER != nullptr); - _context = V8DealerFeature::DEALER->enterContext(&_vocbase, false); + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createQueryContext(); + _context = V8DealerFeature::DEALER->enterContext(&_vocbase, securityContext); if (_context == nullptr) { THROW_ARANGO_EXCEPTION_MESSAGE( diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index cb270f515c..819a171119 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -365,6 +365,7 @@ SET(ARANGOD_SOURCES GeneralServer/ListenTask.cpp GeneralServer/RestHandler.cpp GeneralServer/RestHandlerFactory.cpp + GeneralServer/ServerSecurityFeature.cpp GeneralServer/SocketSslTcp.cpp GeneralServer/SocketTask.cpp GeneralServer/Task.cpp diff --git a/arangod/GeneralServer/ServerSecurityFeature.cpp b/arangod/GeneralServer/ServerSecurityFeature.cpp new file mode 100644 index 0000000000..2010b92880 --- /dev/null +++ b/arangod/GeneralServer/ServerSecurityFeature.cpp @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2016 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Jan Steemann +//////////////////////////////////////////////////////////////////////////////// + +#include "GeneralServer/ServerSecurityFeature.h" +#include "Logger/Logger.h" +#include "ProgramOptions/ProgramOptions.h" +#include "ProgramOptions/Section.h" +#include "Utils/ExecContext.h" + +using namespace arangodb; +using namespace arangodb::basics; +using namespace arangodb::options; + +ServerSecurityFeature::ServerSecurityFeature(application_features::ApplicationServer& server) + : ApplicationFeature(server, "ServerSecurity"), + _enableFoxxApi(true), + _enableFoxxStore(true), + _hardenedRestApi(false) { + setOptional(false); + startsAfter("ServerPlatform"); +} + +void ServerSecurityFeature::collectOptions(std::shared_ptr options) { + options->addSection("server", "Server features"); + options->addOption("--server.harden", + "lock down REST APIs that reveal version information or server " + "internals for non-admin users", + new BooleanParameter(&_hardenedRestApi)) + .setIntroducedIn(30500); + + options->addSection("foxx", "Configure Foxx"); + options->addOption("--foxx.api", "enables Foxx management REST APIs", + new BooleanParameter(&_enableFoxxApi)) + .setIntroducedIn(30500); + options->addOption("--foxx.store", "enables Foxx store in web interface", + new BooleanParameter(&_enableFoxxStore)) + .setIntroducedIn(30500); + +} + +bool ServerSecurityFeature::isFoxxApiDisabled() const { + return !_enableFoxxApi; +} + +bool ServerSecurityFeature::isFoxxStoreDisabled() const { + return !_enableFoxxStore || !_enableFoxxApi; +} + +bool ServerSecurityFeature::isRestApiHardened() const { + return _hardenedRestApi; +} + +bool ServerSecurityFeature::canAccessHardenedApi() const { + bool allowAccess = !isRestApiHardened(); + + if (!allowAccess) { + ExecContext const* exec = ExecContext::CURRENT; + if (exec == nullptr || exec->isAdminUser()) { + // also allow access if there is not authentication + // enabled or when the user is an administrator + allowAccess = true; + } + } + return allowAccess; +} diff --git a/arangod/GeneralServer/ServerSecurityFeature.h b/arangod/GeneralServer/ServerSecurityFeature.h new file mode 100644 index 0000000000..f77f73e138 --- /dev/null +++ b/arangod/GeneralServer/ServerSecurityFeature.h @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2016 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Jan Steemann +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ARANGODB_APPLICATION_FEATURES_SERVER_SECURITY_FEATURE_H +#define ARANGODB_APPLICATION_FEATURES_SERVER_SECURITY_FEATURE_H 1 + +#include "ApplicationFeatures/ApplicationFeature.h" + +namespace arangodb { + +class ServerSecurityFeature final : public application_features::ApplicationFeature { + public: + explicit ServerSecurityFeature(application_features::ApplicationServer& server); + + void collectOptions(std::shared_ptr) override final; + + bool isRestApiHardened() const; + bool isFoxxApiDisabled() const; + bool isFoxxStoreDisabled() const; + bool canAccessHardenedApi() const; + + private: + bool _enableFoxxApi; + bool _enableFoxxStore; + bool _hardenedRestApi; +}; + +} // namespace arangodb + +#endif diff --git a/arangod/RestHandler/RestAdminExecuteHandler.cpp b/arangod/RestHandler/RestAdminExecuteHandler.cpp index 81348bdec2..81bc74a61e 100644 --- a/arangod/RestHandler/RestAdminExecuteHandler.cpp +++ b/arangod/RestHandler/RestAdminExecuteHandler.cpp @@ -29,6 +29,7 @@ #include "Basics/StaticStrings.h" #include "Basics/StringUtils.h" #include "Logger/Logger.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-globals.h" #include "V8/v8-vpack.h" #include "V8Server/v8-actions.h" @@ -53,11 +54,11 @@ RestStatus RestAdminExecuteHandler::execute() { } TRI_ASSERT(V8DealerFeature::DEALER->allowAdminExecute()); - + arangodb::velocypack::StringRef bodyStr = _request->rawPayload(); char const* body = bodyStr.data(); size_t bodySize = bodyStr.size(); - + if (bodySize == 0) { // nothing to execute. return an empty response VPackBuilder result; @@ -72,29 +73,14 @@ RestStatus RestAdminExecuteHandler::execute() { try { LOG_TOPIC("c838e", WARN, Logger::FIXME) << "about to execute: '" << Logger::CHARS(body, bodySize) << "'"; - - ssize_t forceContext = -1; - bool found; - std::string const& c = _request->header("x-arango-v8-context", found); - if (found && !c.empty()) { - forceContext = basics::StringUtils::int32(c); - } - // get a V8 context bool const allowUseDatabase = ActionFeature::ACTION->allowUseDatabase(); - V8Context* context = V8DealerFeature::DEALER->enterContext(&_vocbase, allowUseDatabase, forceContext); + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createRestAdminScriptActionContext(allowUseDatabase); + V8ContextGuard guard(&_vocbase, securityContext); - // note: the context might be nullptr in case of shut-down - if (context == nullptr) { - THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_RESOURCE_LIMIT, - "unable to acquire V8 context in time"); - } - - TRI_DEFER(V8DealerFeature::DEALER->exitContext(context)); - - { - v8::Isolate* isolate = context->_isolate; + { + v8::Isolate* isolate = guard.isolate(); v8::HandleScope scope(isolate); v8::Handle current = isolate->GetCurrentContext()->Global(); @@ -106,9 +92,9 @@ RestStatus RestAdminExecuteHandler::execute() { v8::Handle args[1] = {TRI_V8_PAIR_STRING(isolate, body, bodySize)}; v8::Local function = ctor->NewInstance(TRI_IGETC, 1, args).FromMaybe(v8::Local()); v8::Handle action = v8::Local::Cast(function); - + v8::Handle rv; - + if (!action.IsEmpty()) { action->SetName(TRI_V8_ASCII_STRING(isolate, "source")); @@ -116,18 +102,18 @@ RestStatus RestAdminExecuteHandler::execute() { TRI_fake_action_t adminExecuteAction("_admin/execute", 2); - v8g->_currentRequest = TRI_RequestCppToV8(isolate, v8g, _request.get(), &adminExecuteAction); + v8g->_currentRequest = TRI_RequestCppToV8(isolate, v8g, _request.get(), &adminExecuteAction); v8g->_currentResponse = v8::Object::New(isolate); - + auto guard = scopeGuard([&v8g, &isolate]() { v8g->_currentRequest = v8::Undefined(isolate); v8g->_currentResponse = v8::Undefined(isolate); }); - + v8::Handle args[] = {v8::Null(isolate)}; rv = action->Call(current, 0, args); } - + if (tryCatch.HasCaught()) { // got an error std::string errorMessage; @@ -142,7 +128,7 @@ RestStatus RestAdminExecuteHandler::execute() { errorMessage = *tryCatchMessage; } } - + _response->setResponseCode(rest::ResponseCode::SERVER_ERROR); switch (_response->transportType()) { case Endpoint::TransportType::HTTP: { @@ -153,7 +139,7 @@ RestStatus RestAdminExecuteHandler::execute() { _response->setContentType(rest::ContentType::TEXT); httpResponse->body().appendText(errorMessage.data(), errorMessage.size()); break; - } + } case Endpoint::TransportType::VST: { VPackBuffer buffer; VPackBuilder builder(buffer); @@ -168,11 +154,11 @@ RestStatus RestAdminExecuteHandler::execute() { bool returnAsJSON = _request->parsedValue("returnAsJSON", false); if (returnAsJSON) { // if the result is one of the following type, we return it as is - returnAsJSON &= (rv->IsString() || rv->IsStringObject() || - rv->IsNumber() || rv->IsNumberObject() || + returnAsJSON &= (rv->IsString() || rv->IsStringObject() || + rv->IsNumber() || rv->IsNumberObject() || rv->IsBoolean()); } - + VPackBuilder result; bool handled = false; int res = TRI_ERROR_FAILED; @@ -182,7 +168,7 @@ RestStatus RestAdminExecuteHandler::execute() { result.add(StaticStrings::Error, VPackValue(false)); result.add(StaticStrings::Code, VPackValue(static_cast(rest::ResponseCode::OK))); if (rv->IsObject()) { - res = TRI_V8ToVPack(isolate, result, rv, false); + res = TRI_V8ToVPack(isolate, result, rv, false); handled = true; } result.close(); @@ -190,16 +176,16 @@ RestStatus RestAdminExecuteHandler::execute() { if (!handled) { result.clear(); - + VPackBuilder temp; - res = TRI_V8ToVPack(isolate, temp, rv, false); + res = TRI_V8ToVPack(isolate, temp, rv, false); result.add(temp.slice()); - } - + } + if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } - + generateResult(rest::ResponseCode::OK, result.slice()); } } diff --git a/arangod/RestHandler/RestAdminLogHandler.cpp b/arangod/RestHandler/RestAdminLogHandler.cpp index 8c2fa4e573..fc3d020ebd 100644 --- a/arangod/RestHandler/RestAdminLogHandler.cpp +++ b/arangod/RestHandler/RestAdminLogHandler.cpp @@ -28,6 +28,7 @@ #include #include "Basics/StringUtils.h" +#include "GeneralServer/ServerSecurityFeature.h" #include "Logger/LogBuffer.h" #include "Logger/Logger.h" #include "Rest/HttpRequest.h" @@ -40,13 +41,23 @@ RestAdminLogHandler::RestAdminLogHandler(GeneralRequest* request, GeneralRespons : RestBaseHandler(request, response) {} RestStatus RestAdminLogHandler::execute() { - size_t const len = _request->suffixes().size(); + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + if (!security->canAccessHardenedApi()) { + generateError(rest::ResponseCode::FORBIDDEN, TRI_ERROR_FORBIDDEN); + return RestStatus::DONE; + } + + size_t const len = _request->suffixes().size(); if (len == 0) { reportLogs(); } else { setLogLevel(); } + return RestStatus::DONE; } diff --git a/arangod/RestHandler/RestAdminStatisticsHandler.cpp b/arangod/RestHandler/RestAdminStatisticsHandler.cpp index 75c16e0046..3702de9018 100644 --- a/arangod/RestHandler/RestAdminStatisticsHandler.cpp +++ b/arangod/RestHandler/RestAdminStatisticsHandler.cpp @@ -21,6 +21,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "RestAdminStatisticsHandler.h" +#include "GeneralServer/ServerSecurityFeature.h" #include "Statistics/Descriptions.h" #include "Statistics/StatisticsFeature.h" @@ -37,6 +38,17 @@ RestStatus RestAdminStatisticsHandler::execute() { generateError(rest::ResponseCode::METHOD_NOT_ALLOWED, TRI_ERROR_HTTP_METHOD_NOT_ALLOWED); return RestStatus::DONE; } + + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + + if (!security->canAccessHardenedApi()) { + // dont leak information about server internals here + generateError(rest::ResponseCode::FORBIDDEN, TRI_ERROR_FORBIDDEN); + return RestStatus::DONE; + } if (_request->requestPath() == "/_admin/statistics") { getStatistics(); diff --git a/arangod/RestHandler/RestCollectionHandler.cpp b/arangod/RestHandler/RestCollectionHandler.cpp index ed5577a0c5..eeff705c02 100644 --- a/arangod/RestHandler/RestCollectionHandler.cpp +++ b/arangod/RestHandler/RestCollectionHandler.cpp @@ -297,7 +297,7 @@ void RestCollectionHandler::handleCommandPost() { type = TRI_col_type_e::TRI_COL_TYPE_EDGE; } - // for some "security" a white-list of allowed parameters + // for some "security" a whitelist of allowed parameters VPackBuilder filtered = VPackCollection::keep( body, std::unordered_set{ "doCompact", StaticStrings::DataSourceSystem, diff --git a/arangod/RestHandler/RestEngineHandler.cpp b/arangod/RestHandler/RestEngineHandler.cpp index 87e2cae68d..3944f0567e 100644 --- a/arangod/RestHandler/RestEngineHandler.cpp +++ b/arangod/RestHandler/RestEngineHandler.cpp @@ -21,6 +21,7 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// +#include "GeneralServer/ServerSecurityFeature.h" #include "RestEngineHandler.h" #include "Rest/HttpRequest.h" #include "StorageEngine/EngineSelectorFeature.h" @@ -39,13 +40,13 @@ RestEngineHandler::RestEngineHandler(GeneralRequest* request, GeneralResponse* r RestStatus RestEngineHandler::execute() { // extract the sub-request type auto const type = _request->requestType(); - - if (type == rest::RequestType::GET) { - handleGet(); + + if (type != rest::RequestType::GET) { + generateError(rest::ResponseCode::METHOD_NOT_ALLOWED, TRI_ERROR_HTTP_METHOD_NOT_ALLOWED); return RestStatus::DONE; } - - generateError(rest::ResponseCode::METHOD_NOT_ALLOWED, TRI_ERROR_HTTP_METHOD_NOT_ALLOWED); + + handleGet(); return RestStatus::DONE; } @@ -58,11 +59,24 @@ void RestEngineHandler::handleGet() { return; } - if (suffixes.size() == 0) { + if (suffixes.empty()) { getCapabilities(); - } else { - getStats(); + return; } + + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + + if (!security->canAccessHardenedApi()) { + // dont leak information about server internals here + generateError(rest::ResponseCode::FORBIDDEN, TRI_ERROR_FORBIDDEN); + return; + } + + // access to engine stats is disallowed in hardened mode + getStats(); } void RestEngineHandler::getCapabilities() { diff --git a/arangod/RestHandler/RestStatusHandler.cpp b/arangod/RestHandler/RestStatusHandler.cpp index 9d8614ac2b..255b4b0811 100644 --- a/arangod/RestHandler/RestStatusHandler.cpp +++ b/arangod/RestHandler/RestStatusHandler.cpp @@ -28,6 +28,7 @@ #include "Agency/Agent.h" #include "ApplicationFeatures/ApplicationServer.h" #include "Cluster/ServerState.h" +#include "GeneralServer/ServerSecurityFeature.h" #include "Rest/HttpRequest.h" #include "Rest/Version.h" #include "RestServer/ServerFeature.h" @@ -51,6 +52,17 @@ RestStatusHandler::RestStatusHandler(GeneralRequest* request, GeneralResponse* r : RestBaseHandler(request, response) {} RestStatus RestStatusHandler::execute() { + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + + if (!security->canAccessHardenedApi()) { + // dont leak information about server internals here + generateError(rest::ResponseCode::FORBIDDEN, TRI_ERROR_FORBIDDEN); + return RestStatus::DONE; + } + VPackBuilder result; result.add(VPackValue(VPackValueType::Object)); result.add("server", VPackValue("arango")); diff --git a/arangod/RestHandler/RestTasksHandler.cpp b/arangod/RestHandler/RestTasksHandler.cpp index d837b17d92..b2e5445e63 100644 --- a/arangod/RestHandler/RestTasksHandler.cpp +++ b/arangod/RestHandler/RestTasksHandler.cpp @@ -27,8 +27,7 @@ #include "Basics/VelocyPackHelper.h" #include "Cluster/ServerState.h" #include "Rest/HttpRequest.h" -#include "Scheduler/Scheduler.h" -#include "Scheduler/SchedulerFeature.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-globals.h" #include "V8/v8-vpack.h" #include "V8Server/V8DealerFeature.h" @@ -140,12 +139,6 @@ void RestTasksHandler::registerTask(bool byId) { } } - if (SchedulerFeature::SCHEDULER == nullptr) { - generateError(rest::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL, - "no scheduler found"); - return; - } - ExecContext const* exec = ExecContext::CURRENT; if (exec != nullptr) { if (exec->databaseAuthLevel() != auth::Level::RW) { @@ -206,40 +199,35 @@ void RestTasksHandler::registerTask(bool byId) { return; } - { - Result res; - v8::Isolate* isolate = nullptr; - try { - V8ContextDealerGuard dealerGuard(res, isolate, &_vocbase, true); - if (res.fail()) { - generateError(res); - return; - } - v8::HandleScope scope(isolate); - v8::Handle bv8 = TRI_VPackToV8(isolate, body).As(); + try { + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createRestrictedContext(); + V8ContextGuard guard(&_vocbase, securityContext); + + v8::Isolate* isolate = guard.isolate(); + v8::HandleScope scope(isolate); + v8::Handle bv8 = TRI_VPackToV8(isolate, body).As(); - if (bv8->Get(TRI_V8_ASCII_STRING(isolate, "command"))->IsFunction()) { - // need to add ( and ) around function because call will otherwise break - command = "(" + cmdSlice.copyString() + ")(params)"; - } else { - command = cmdSlice.copyString(); - } + if (bv8->Get(TRI_V8_ASCII_STRING(isolate, "command"))->IsFunction()) { + // need to add ( and ) around function because call will otherwise break + command = "(" + cmdSlice.copyString() + ")(params)"; + } else { + command = cmdSlice.copyString(); + } - if (!Task::tryCompile(isolate, command)) { - generateError(rest::ResponseCode::BAD, TRI_ERROR_BAD_PARAMETER, - "cannot compile command"); - return; - } - } catch (arangodb::basics::Exception const& ex) { - generateError(Result{ex.code(), ex.what()}); - return; - } catch (std::exception const& ex) { - generateError(Result{TRI_ERROR_INTERNAL, ex.what()}); - return; - } catch (...) { - generateError(TRI_ERROR_INTERNAL); + if (!Task::tryCompile(isolate, command)) { + generateError(rest::ResponseCode::BAD, TRI_ERROR_BAD_PARAMETER, + "cannot compile command"); return; } + } catch (arangodb::basics::Exception const& ex) { + generateError(Result{ex.code(), ex.what()}); + return; + } catch (std::exception const& ex) { + generateError(Result{TRI_ERROR_INTERNAL, ex.what()}); + return; + } catch (...) { + generateError(TRI_ERROR_INTERNAL); + return; } // extract the parameters diff --git a/arangod/RestHandler/RestTransactionHandler.cpp b/arangod/RestHandler/RestTransactionHandler.cpp index 65c0a9f042..2929690312 100644 --- a/arangod/RestHandler/RestTransactionHandler.cpp +++ b/arangod/RestHandler/RestTransactionHandler.cpp @@ -23,6 +23,7 @@ #include "RestTransactionHandler.h" +#include "Actions/ActionFeature.h" #include "ApplicationFeatures/ApplicationServer.h" #include "Basics/ReadLocker.h" #include "Basics/WriteLocker.h" @@ -33,6 +34,7 @@ #include "Transaction/ManagerFeature.h" #include "Transaction/Helpers.h" #include "Transaction/Status.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8Server/V8Context.h" #include "V8Server/V8DealerFeature.h" #include "VocBase/Methods/Transactions.h" @@ -239,7 +241,9 @@ void RestTransactionHandler::executeJSTransaction() { std::string portType = _request->connectionInfo().portType(); - _v8Context = V8DealerFeature::DEALER->enterContext(&_vocbase, true /*allow use database*/); + bool allowUseDatabase = ActionFeature::ACTION->allowUseDatabase(); + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createRestActionContext(allowUseDatabase); + _v8Context = V8DealerFeature::DEALER->enterContext(&_vocbase, securityContext); if (!_v8Context) { generateError(Result(TRI_ERROR_INTERNAL, "could not acquire v8 context")); diff --git a/arangod/RestHandler/RestVersionHandler.cpp b/arangod/RestHandler/RestVersionHandler.cpp index 31f3c800b4..f2b8dcc253 100644 --- a/arangod/RestHandler/RestVersionHandler.cpp +++ b/arangod/RestHandler/RestVersionHandler.cpp @@ -21,12 +21,13 @@ /// @author Achim Brandt //////////////////////////////////////////////////////////////////////////////// -#include "RestVersionHandler.h" #include "ApplicationFeatures/ApplicationServer.h" #include "Cluster/ServerState.h" +#include "GeneralServer/ServerSecurityFeature.h" #include "Rest/HttpRequest.h" #include "Rest/Version.h" #include "RestServer/ServerFeature.h" +#include "RestVersionHandler.h" #include #include @@ -44,42 +45,48 @@ RestVersionHandler::RestVersionHandler(GeneralRequest* request, GeneralResponse* RestStatus RestVersionHandler::execute() { VPackBuilder result; + + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + + bool const allowInfo = security->canAccessHardenedApi(); + result.add(VPackValue(VPackValueType::Object)); result.add("server", VPackValue("arango")); - result.add("version", VPackValue(ARANGODB_VERSION)); - #ifdef USE_ENTERPRISE - result.add("license", VPackValue("enterprise")); + result.add("license", VPackValue("enterprise")); #else - result.add("license", VPackValue("community")); + result.add("license", VPackValue("community")); #endif - bool found; - std::string const& detailsStr = _request->value("details", found); + if (allowInfo) { + result.add("version", VPackValue(ARANGODB_VERSION)); - if (found && StringUtils::boolean(detailsStr)) { - result.add("details", VPackValue(VPackValueType::Object)); + bool found; + std::string const& detailsStr = _request->value("details", found); + if (found && StringUtils::boolean(detailsStr)) { + result.add("details", VPackValue(VPackValueType::Object)); + Version::getVPack(result); - Version::getVPack(result); - - if (application_features::ApplicationServer::server != nullptr) { - auto server = application_features::ApplicationServer::server->getFeature( - "Server"); - result.add("mode", VPackValue(server->operationModeString())); - auto serverState = ServerState::instance(); - if (serverState != nullptr) { - result.add("role", VPackValue(ServerState::roleToString(serverState->getRole()))); + if (application_features::ApplicationServer::server != nullptr) { + auto server = application_features::ApplicationServer::server->getFeature( + "Server"); + result.add("mode", VPackValue(server->operationModeString())); + auto serverState = ServerState::instance(); + if (serverState != nullptr) { + result.add("role", VPackValue(ServerState::roleToString(serverState->getRole()))); + } } - } - std::string host = ServerState::instance()->getHost(); - - if (!host.empty()) { - result.add("host", VPackValue(host)); - } - - result.close(); - } + std::string host = ServerState::instance()->getHost(); + if (!host.empty()) { + result.add("host", VPackValue(host)); + } + result.close(); + } // found + } // allowInfo result.close(); generateResult(rest::ResponseCode::OK, result.slice()); return RestStatus::DONE; diff --git a/arangod/RestServer/CheckVersionFeature.cpp b/arangod/RestServer/CheckVersionFeature.cpp index 2550c59575..97ed67744f 100644 --- a/arangod/RestServer/CheckVersionFeature.cpp +++ b/arangod/RestServer/CheckVersionFeature.cpp @@ -138,7 +138,9 @@ void CheckVersionFeature::checkVersion() { bool ignoreDatafileErrors = false; { - VPackBuilder options = server()->options(std::unordered_set()); + VPackBuilder options = server()->options([](std::string const& name) { + return (name.find("database.ignore-datafile-errors") != std::string::npos); + }); VPackSlice s = options.slice(); if (s.get("database.ignore-datafile-errors").isBoolean()) { ignoreDatafileErrors = s.get("database.ignore-datafile-errors").getBool(); diff --git a/arangod/RestServer/ConsoleThread.cpp b/arangod/RestServer/ConsoleThread.cpp index d715ce7414..e732cc78b5 100644 --- a/arangod/RestServer/ConsoleThread.cpp +++ b/arangod/RestServer/ConsoleThread.cpp @@ -31,6 +31,7 @@ #include "Basics/tri-strings.h" #include "Logger/Logger.h" #include "Rest/Version.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/V8LineEditor.h" #include "V8/v8-conv.h" #include "V8/v8-utils.h" @@ -48,7 +49,6 @@ Mutex ConsoleThread::serverConsoleMutex; ConsoleThread::ConsoleThread(ApplicationServer* applicationServer, TRI_vocbase_t* vocbase) : Thread("Console"), _applicationServer(applicationServer), - _context(nullptr), _vocbase(vocbase), _userAborted(false) {} @@ -66,18 +66,12 @@ void ConsoleThread::run() { } // enter V8 context - _context = V8DealerFeature::DEALER->enterContext(_vocbase, true); - - if (_context == nullptr) { - LOG_TOPIC("921b8", FATAL, arangodb::Logger::FIXME) << "cannot acquire V8 context"; - FATAL_ERROR_EXIT(); - } - - TRI_DEFER(V8DealerFeature::DEALER->exitContext(_context)); + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createAdminScriptContext(); + V8ContextGuard guard(_vocbase, securityContext); // work try { - inner(); + inner(guard); } catch (char const* error) { if (strcmp(error, USER_ABORTED) != 0) { LOG_TOPIC("6e7fd", ERR, arangodb::Logger::FIXME) << error; @@ -91,11 +85,11 @@ void ConsoleThread::run() { _applicationServer->beginShutdown(); } -void ConsoleThread::inner() { +void ConsoleThread::inner(V8ContextGuard const& guard) { // flush all log output before we print the console prompt Logger::flush(); - v8::Isolate* isolate = _context->_isolate; + v8::Isolate* isolate = guard.isolate(); v8::HandleScope globalScope(isolate); // run the shell @@ -105,7 +99,7 @@ void ConsoleThread::inner() { v8::Local name(TRI_V8_ASCII_STRING(isolate, TRI_V8_SHELL_COMMAND_NAME)); - auto localContext = v8::Local::New(isolate, _context->_context); + auto localContext = v8::Local::New(isolate, guard.context()->_context); localContext->Enter(); { v8::Context::Scope contextScope(localContext); diff --git a/arangod/RestServer/ConsoleThread.h b/arangod/RestServer/ConsoleThread.h index 90477ddc67..35c2990e1e 100644 --- a/arangod/RestServer/ConsoleThread.h +++ b/arangod/RestServer/ConsoleThread.h @@ -30,6 +30,7 @@ struct TRI_vocbase_t; namespace arangodb { +class V8ContextGuard; class V8LineEditor; } @@ -59,11 +60,10 @@ class ConsoleThread final : public Thread { void userAbort() { _userAborted.store(true); } private: - void inner(); + void inner(V8ContextGuard const&); private: application_features::ApplicationServer* _applicationServer; - V8Context* _context; TRI_vocbase_t* _vocbase; std::atomic _userAborted; }; diff --git a/arangod/RestServer/ScriptFeature.cpp b/arangod/RestServer/ScriptFeature.cpp index dace57315e..d6656882b1 100644 --- a/arangod/RestServer/ScriptFeature.cpp +++ b/arangod/RestServer/ScriptFeature.cpp @@ -27,6 +27,7 @@ #include "ProgramOptions/Section.h" #include "RestServer/ServerFeature.h" #include "RestServer/SystemDatabaseFeature.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-conv.h" #include "V8/v8-globals.h" #include "V8/v8-utils.h" @@ -68,21 +69,15 @@ int ScriptFeature::runScript(std::vector const& scripts) { auto* sysDbFeature = arangodb::application_features::ApplicationServer::lookupFeature(); auto database = sysDbFeature->use(); - V8Context* context = V8DealerFeature::DEALER->enterContext(database.get(), true); - if (context == nullptr) { - LOG_TOPIC("d01d3", FATAL, arangodb::Logger::FIXME) << "cannot acquire V8 context"; - FATAL_ERROR_EXIT(); - } - - TRI_DEFER(V8DealerFeature::DEALER->exitContext(context)); - - auto isolate = context->_isolate; + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createAdminScriptContext(); + V8ContextGuard guard(database.get(), securityContext); + auto isolate = guard.isolate(); { v8::HandleScope globalScope(isolate); - auto localContext = v8::Local::New(isolate, context->_context); + auto localContext = v8::Local::New(isolate, guard.context()->_context); localContext->Enter(); { v8::Context::Scope contextScope(localContext); diff --git a/arangod/RestServer/UpgradeFeature.cpp b/arangod/RestServer/UpgradeFeature.cpp index 38d3b722a0..2ab04e3bd0 100644 --- a/arangod/RestServer/UpgradeFeature.cpp +++ b/arangod/RestServer/UpgradeFeature.cpp @@ -180,7 +180,9 @@ void UpgradeFeature::upgradeDatabase() { bool ignoreDatafileErrors = false; { - VPackBuilder options = server()->options(std::unordered_set()); + VPackBuilder options = server()->options([](std::string const& name) { + return (name.find("database.ignore-datafile-errors") != std::string::npos); + }); VPackSlice s = options.slice(); if (s.get("database.ignore-datafile-errors").isBoolean()) { ignoreDatafileErrors = s.get("database.ignore-datafile-errors").getBool(); diff --git a/arangod/RestServer/arangod.cpp b/arangod/RestServer/arangod.cpp index e60e8502a8..3620e37519 100644 --- a/arangod/RestServer/arangod.cpp +++ b/arangod/RestServer/arangod.cpp @@ -54,6 +54,7 @@ #include "ApplicationFeatures/TempFeature.h" #include "ApplicationFeatures/V8Phase.h" #include "ApplicationFeatures/V8PlatformFeature.h" +#include "ApplicationFeatures/V8SecurityFeature.h" #include "ApplicationFeatures/VersionFeature.h" #include "Aql/AqlFunctionFeature.h" #include "Aql/OptimizerRulesFeature.h" @@ -64,6 +65,7 @@ #include "Cluster/ReplicationTimeoutFeature.h" #include "GeneralServer/AuthenticationFeature.h" #include "GeneralServer/GeneralServerFeature.h" +#include "GeneralServer/ServerSecurityFeature.h" #include "Logger/LoggerBufferFeature.h" #include "Logger/LoggerFeature.h" #include "Pregel/PregelFeature.h" @@ -203,6 +205,7 @@ static int runServer(int argc, char** argv, ArangoGlobalContext& context) { server.addFeature(new ScriptFeature(server, &ret)); server.addFeature(new ServerFeature(server, &ret)); server.addFeature(new ServerIdFeature(server)); + server.addFeature(new ServerSecurityFeature(server)); server.addFeature(new ShardingFeature(server)); server.addFeature(new ShellColorsFeature(server)); server.addFeature(new ShutdownFeature(server, {"Script"})); @@ -211,12 +214,13 @@ static int runServer(int argc, char** argv, ArangoGlobalContext& context) { server.addFeature(new StorageEngineFeature(server)); server.addFeature(new SystemDatabaseFeature(server)); server.addFeature(new TempFeature(server, name)); - server.addFeature(new transaction::ManagerFeature(server)); server.addFeature(new TraverserEngineRegistryFeature(server)); server.addFeature(new TtlFeature(server)); server.addFeature(new UpgradeFeature(server, &ret, nonServerFeatures)); server.addFeature(new V8DealerFeature(server)); server.addFeature(new V8PlatformFeature(server)); + server.addFeature(new V8SecurityFeature(server)); + server.addFeature(new transaction::ManagerFeature(server)); server.addFeature(new VersionFeature(server)); server.addFeature(new ViewTypesFeature(server)); server.addFeature(new aql::AqlFunctionFeature(server)); diff --git a/arangod/RocksDBEngine/RocksDBCollection.cpp b/arangod/RocksDBEngine/RocksDBCollection.cpp index 61442073ef..18e53bb5c1 100644 --- a/arangod/RocksDBEngine/RocksDBCollection.cpp +++ b/arangod/RocksDBEngine/RocksDBCollection.cpp @@ -315,7 +315,7 @@ std::shared_ptr RocksDBCollection::createIndex(VPackSlice const& info, TRI_vocbase_t& vocbase = _logicalCollection.vocbase(); TRI_vocbase_col_status_e status; Result res = vocbase.useCollection(&_logicalCollection, status); - + if (res.fail()) { THROW_ARANGO_EXCEPTION(res); } @@ -381,9 +381,9 @@ std::shared_ptr RocksDBCollection::createIndex(VPackSlice const& info, } } } - + do { - + // Step 3. add index to collection entry (for removal after a crash) auto buildIdx = std::make_shared(std::static_pointer_cast(idx)); @@ -400,7 +400,7 @@ std::shared_ptr RocksDBCollection::createIndex(VPackSlice const& info, res.reset(rocksutils::convertStatus(s)); break; } - + VPackBuilder builder; builder.openObject(); for (auto const& pair : VPackObjectIterator(VPackSlice(ps.data()))) { @@ -421,7 +421,7 @@ std::shared_ptr RocksDBCollection::createIndex(VPackSlice const& info, break; } } - + // Step 4. fill index const bool inBackground = basics::VelocyPackHelper::getBooleanValue(info, StaticStrings::IndexInBackground, false); @@ -435,7 +435,7 @@ std::shared_ptr RocksDBCollection::createIndex(VPackSlice const& info, break; } locker.lock(); // always lock to avoid inconsistencies - + // Step 5. register in index list WRITE_LOCKER(guard, _indexesLock); if (inBackground) { // swap in actual index @@ -452,7 +452,7 @@ std::shared_ptr RocksDBCollection::createIndex(VPackSlice const& info, #if USE_PLAN_CACHE arangodb::aql::PlanCache::instance()->invalidate(_logicalCollection.vocbase()); #endif - + // inBackground index might not recover selectivity estimate w/o sync if (inBackground && !idx->unique() && idx->hasSelectivityEstimate()) { engine->settingsManager()->sync(false); @@ -703,7 +703,7 @@ Result RocksDBCollection::truncate(transaction::Methods& trx, OperationOptions& TRI_ASSERT(_objectId == RocksDBKey::objectId(iter->key())); VPackSlice document(iter->value().data()); TRI_ASSERT(document.isObject()); - + // tmp may contain a pointer into rocksdb::WriteBuffer::_rep. This is // a 'std::string' which might be realloc'ed on any Put/Delete operation docBuffer.clear(); @@ -720,7 +720,7 @@ Result RocksDBCollection::truncate(transaction::Methods& trx, OperationOptions& state->prepareOperation(_logicalCollection.id(), rid, // actual revision ID!! TRI_VOC_DOCUMENT_OPERATION_REMOVE); - + LocalDocumentId const docId = RocksDBKey::documentId(iter->key()); auto res = removeDocument(&trx, docId, docBuffer.slice(), options); @@ -738,7 +738,7 @@ Result RocksDBCollection::truncate(transaction::Methods& trx, OperationOptions& guard.finish(hasPerformedIntermediateCommit); trackWaitForSync(&trx, options); - + } // reset to previous value after truncate is finished @@ -762,7 +762,7 @@ Result RocksDBCollection::truncate(transaction::Methods& trx, OperationOptions& } return Result{}; } - + LocalDocumentId RocksDBCollection::lookupKey(transaction::Methods* trx, VPackSlice const& key) const { TRI_ASSERT(key.isString()); @@ -800,7 +800,7 @@ Result RocksDBCollection::read(transaction::Methods* trx, if (!documentId.isSet()) { return TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND; } // found - + std::string* buffer = result.setManaged(); rocksdb::PinnableSlice ps(buffer); Result res = lookupDocumentVPack(trx, documentId, ps, /*readCache*/true, /*fillCache*/true); @@ -810,7 +810,7 @@ Result RocksDBCollection::read(transaction::Methods* trx, } // else value is already assigned result.setRevisionId(); // extracts id from buffer } - + return res; } @@ -848,7 +848,7 @@ Result RocksDBCollection::insert(arangodb::transaction::Methods* trx, OperationOptions& options, bool /*lock*/, KeyLockInfo* /*keyLockInfo*/, std::function const& cbDuringLock) { - + bool const isEdgeCollection = (TRI_COL_TYPE_EDGE == _logicalCollection.type()); transaction::BuilderLeaser builder(trx); @@ -888,7 +888,7 @@ Result RocksDBCollection::insert(arangodb::transaction::Methods* trx, } } } - + LocalDocumentId const documentId = LocalDocumentId::create(); RocksDBSavePoint guard(trx, TRI_VOC_DOCUMENT_OPERATION_INSERT); @@ -900,7 +900,7 @@ Result RocksDBCollection::insert(arangodb::transaction::Methods* trx, if (res.ok()) { trackWaitForSync(trx, options); - + if (options.returnNew) { resultMdr.setManaged(newSlice.begin()); TRI_ASSERT(resultMdr.revisionId() == revisionId); @@ -913,7 +913,7 @@ Result RocksDBCollection::insert(arangodb::transaction::Methods* trx, keyBuilder->size()); resultMdr.setRevisionId(revisionId); } - + bool hasPerformedIntermediateCommit = false; res = state->addOperation(_logicalCollection.id(), revisionId, TRI_VOC_DOCUMENT_OPERATION_INSERT, @@ -933,14 +933,14 @@ Result RocksDBCollection::update(arangodb::transaction::Methods* trx, arangodb::velocypack::Slice const newSlice, ManagedDocumentResult& resultMdr, OperationOptions& options, bool /*lock*/, ManagedDocumentResult& previousMdr) { - + VPackSlice keySlice = newSlice.get(StaticStrings::KeyString); if (keySlice.isNone()) { return TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD; } else if (!keySlice.isString()) { return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } - + auto const oldDocumentId = primaryIndex()->lookupKey(trx, VPackStringRef(keySlice)); if (!oldDocumentId.isSet()) { return TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND; @@ -980,7 +980,7 @@ Result RocksDBCollection::update(arangodb::transaction::Methods* trx, TRI_voc_rid_t revisionId; LocalDocumentId const newDocumentId = LocalDocumentId::create(); auto isEdgeCollection = (TRI_COL_TYPE_EDGE == _logicalCollection.type()); - + transaction::BuilderLeaser builder(trx); res = mergeObjectsForUpdate(trx, oldDoc, newSlice, isEdgeCollection, options.mergeObjects, options.keepNull, @@ -1043,14 +1043,14 @@ Result RocksDBCollection::replace(transaction::Methods* trx, arangodb::velocypack::Slice const newSlice, ManagedDocumentResult& resultMdr, OperationOptions& options, bool /*lock*/, ManagedDocumentResult& previousMdr) { - + VPackSlice keySlice = newSlice.get(StaticStrings::KeyString); if (keySlice.isNone()) { return TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD; } else if (!keySlice.isString()) { return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } - + auto const oldDocumentId = primaryIndex()->lookupKey(trx, VPackStringRef(keySlice)); if (!oldDocumentId.isSet()) { return TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND; @@ -1063,7 +1063,7 @@ Result RocksDBCollection::replace(transaction::Methods* trx, if (res.fail()) { return res; } - + TRI_ASSERT(previousPS.size() > 0); VPackSlice const oldDoc(previousPS.data()); previousMdr.setRevisionId(transaction::helpers::extractRevFromDocument(oldDoc)); @@ -1076,7 +1076,7 @@ Result RocksDBCollection::replace(transaction::Methods* trx, return res; } } - + // merge old and new values TRI_voc_rid_t revisionId; LocalDocumentId const newDocumentId = LocalDocumentId::create(); @@ -1155,7 +1155,7 @@ Result RocksDBCollection::remove(transaction::Methods& trx, velocypack::Slice sl if (!keySlice.isString()) { return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } - + auto const documentId = primaryIndex()->lookupKey(&trx, VPackStringRef(keySlice)); if (!documentId.isSet()) { return TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND; @@ -1168,7 +1168,7 @@ Result RocksDBCollection::remove(transaction::Methods& trx, velocypack::Slice sl if (res.fail()) { return res; } - + TRI_ASSERT(previousPS.size() > 0); VPackSlice const oldDoc(previousPS.data()); previousMdr.setRevisionId(transaction::helpers::extractRevFromDocument(oldDoc)); @@ -1203,7 +1203,7 @@ Result RocksDBCollection::remove(transaction::Methods& trx, velocypack::Slice sl } else { previousMdr.clearData(); } - + bool hasPerformedIntermediateCommit = false; res = state->addOperation(_logicalCollection.id(), newRevisionId(), TRI_VOC_DOCUMENT_OPERATION_REMOVE, hasPerformedIntermediateCommit); @@ -1429,17 +1429,17 @@ arangodb::Result RocksDBCollection::lookupDocumentVPack(transaction::Methods* tr lockTimeout = true; // we skip the insert in this case } } - + RocksDBMethods* mthd = RocksDBTransactionState::toMethods(trx); rocksdb::Status s = mthd->Get(RocksDBColumnFamily::documents(), key->string(), &ps); - + if (!s.ok()) { LOG_TOPIC("f63dd", DEBUG, Logger::ENGINES) << "NOT FOUND rev: " << documentId.id() << " trx: " << trx->state()->id() << " objectID " << _objectId << " name: " << _logicalCollection.name(); return res.reset(rocksutils::convertStatus(s, rocksutils::document)); } - + if (fillCache && useCache() && !lockTimeout) { TRI_ASSERT(_cache != nullptr); // write entry back to cache @@ -1459,7 +1459,7 @@ arangodb::Result RocksDBCollection::lookupDocumentVPack(transaction::Methods* tr } } } - + return res; } @@ -1480,7 +1480,7 @@ bool RocksDBCollection::lookupDocumentVPack(transaction::Methods* trx, return true; } } - + transaction::StringLeaser buffer(trx); rocksdb::PinnableSlice ps(buffer.get()); Result res = lookupDocumentVPack(trx, documentId, ps, /*readCache*/false, withCache); diff --git a/arangod/Transaction/Manager.cpp b/arangod/Transaction/Manager.cpp index 5c5f50fd92..0eb050d2b6 100644 --- a/arangod/Transaction/Manager.cpp +++ b/arangod/Transaction/Manager.cpp @@ -40,7 +40,7 @@ namespace arangodb { namespace transaction { - + namespace { struct MGMethods final : arangodb::transaction::Methods { MGMethods(std::shared_ptr const& ctx, @@ -50,7 +50,7 @@ namespace { } }; } - + // register a list of failed transactions void Manager::registerFailedTransactions(std::unordered_set const& failedTransactions) { TRI_ASSERT(_keepTransactionData); @@ -83,7 +83,7 @@ void Manager::registerTransaction(TRI_voc_tid_t transactionId, const size_t bucket = getBucket(transactionId); READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); - + try { // insert into currently running list of transactions _transactions[bucket]._activeTransactions.emplace(transactionId, std::move(data)); @@ -178,7 +178,7 @@ Manager::ManagedTrx::~ManagedTrx() { // but we are in a destructor and must never throw from here } } - + using namespace arangodb; /// @brief register a transaction shard @@ -189,25 +189,25 @@ void Manager::registerAQLTrx(TransactionState* state) { const size_t bucket = getBucket(state->id()); READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); - + auto& buck = _transactions[bucket]; auto it = buck._managed.find(state->id()); if (it != buck._managed.end()) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_TRANSACTION_INTERNAL, "transaction ID already used"); } - + buck._managed.emplace(std::piecewise_construct, std::forward_as_tuple(state->id()), std::forward_as_tuple(MetaType::StandaloneAQL, state, (defaultTTL + TRI_microtime()))); } - + void Manager::unregisterAQLTrx(TRI_voc_tid_t tid) noexcept { const size_t bucket = getBucket(tid); READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); - + auto& buck = _transactions[bucket]; auto it = buck._managed.find(tid); if (it == buck._managed.end()) { @@ -216,7 +216,7 @@ void Manager::unregisterAQLTrx(TRI_voc_tid_t tid) noexcept { return; } TRI_ASSERT(it->second.type == MetaType::StandaloneAQL); - + /// we need to make sure no-one else is still using the TransactionState if (!it->second.rwlock.writeLock(/*maxAttempts*/256)) { LOG_TOPIC("9f7d7", ERR, Logger::TRANSACTIONS) << "a transaction is still in use"; @@ -225,16 +225,16 @@ void Manager::unregisterAQLTrx(TRI_voc_tid_t tid) noexcept { } buck._managed.erase(it); // unlocking not necessary } - + Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, VPackSlice const trxOpts) { Result res; - + // parse the collections to register if (!trxOpts.isObject() || !trxOpts.get("collections").isObject()) { return res.reset(TRI_ERROR_BAD_PARAMETER, "missing 'collections'"); } - + // extract the properties from the object transaction::Options options; options.fromVelocyPack(trxOpts); @@ -242,7 +242,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, return res.reset(TRI_ERROR_BAD_PARAMETER, " needs to be positive"); } - + auto fillColls = [](VPackSlice const& slice, std::vector& cols) { if (slice.isNone()) { // ignore nonexistant keys return true; @@ -250,7 +250,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, cols.emplace_back(slice.copyString()); return true; } - + if (slice.isArray()) { for (VPackSlice val : VPackArrayIterator(slice)) { if (!val.isString() || val.getStringLength() == 0) { @@ -270,10 +270,10 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, if (!isValid) { return res.reset(TRI_ERROR_BAD_PARAMETER, "invalid 'collections' attribute"); } - + return createManagedTrx(vocbase, tid, reads, writes, exclusives, options); } - + /// @brief create managed transaction Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, std::vector const& readCollections, @@ -283,7 +283,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, Result res; const size_t bucket = getBucket(tid); - + { // quick check whether ID exists READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); @@ -293,7 +293,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, return res.reset(TRI_ERROR_TRANSACTION_INTERNAL, "transaction ID already used"); } } - + std::unique_ptr state; try { // now start our own transaction @@ -304,7 +304,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, } TRI_ASSERT(state != nullptr); TRI_ASSERT(state->id() == tid); - + // lock collections CollectionNameResolver resolver(vocbase); auto lockCols = [&](std::vector cols, AccessMode::Type mode) { @@ -315,10 +315,10 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, } else { // only support local collections / shards cid = resolver.getCollectionIdLocal(cname); } - + if (cid == 0) { // not found - res.reset(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, + res.reset(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, std::string(TRI_errno_string(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND)) + ":" + cname); } else { res.reset(state->addCollection(cid, cname, mode, /*nestingLevel*/0, false)); @@ -340,7 +340,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, // no error set. so it must be "data source not found" return res.reset(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND); } - + // start the transaction transaction::Hints hints; hints.set(transaction::Hints::Hint::LOCK_ENTIRELY); @@ -349,7 +349,7 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, if (res.fail()) { return res; } - + { // add transaction to bucket READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); @@ -365,9 +365,9 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, std::forward_as_tuple(MetaType::Managed, state.release(), expires)); } - + LOG_TOPIC("d6806", DEBUG, Logger::TRANSACTIONS) << "created managed trx '" << tid << "'"; - + return res; } @@ -375,23 +375,23 @@ Result Manager::createManagedTrx(TRI_vocbase_t& vocbase, TRI_voc_tid_t tid, std::shared_ptr Manager::leaseManagedTrx(TRI_voc_tid_t tid, AccessMode::Type mode) { const size_t bucket = getBucket(tid); - + int i = 0; TransactionState* state = nullptr; do { READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); - + auto it = _transactions[bucket]._managed.find(tid); if (it == _transactions[bucket]._managed.end()) { return nullptr; } - + ManagedTrx& mtrx = it->second; if (mtrx.type == MetaType::Tombstone) { return nullptr; // already committet this trx } - + if (AccessMode::isWriteOrExclusive(mode)) { if (mtrx.type == MetaType::StandaloneAQL) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_TRANSACTION_DISALLOWED_OPERATION, @@ -411,11 +411,11 @@ std::shared_ptr Manager::leaseManagedTrx(TRI_voc_tid_t tid THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_TRANSACTION_DISALLOWED_OPERATION, "transaction is already in use"); } - + writeLocker.unlock(); // failure; allTransactionsLocker.unlock(); std::this_thread::yield(); - + if (i++ > 32) { LOG_TOPIC("9e972", DEBUG, Logger::TRANSACTIONS) << "waiting on trx lock " << tid; i = 0; @@ -424,7 +424,7 @@ std::shared_ptr Manager::leaseManagedTrx(TRI_voc_tid_t tid } } } while (true); - + if (state) { state->increaseNesting(); return std::make_shared(tid, state, mode); @@ -432,7 +432,7 @@ std::shared_ptr Manager::leaseManagedTrx(TRI_voc_tid_t tid TRI_ASSERT(false); // should be unreachable return nullptr; } - + void Manager::returnManagedTrx(TRI_voc_tid_t tid, AccessMode::Type mode) noexcept { const size_t bucket = getBucket(tid); READ_LOCKER(allTransactionsLocker, _allTransactionsLock); @@ -444,11 +444,11 @@ void Manager::returnManagedTrx(TRI_voc_tid_t tid, AccessMode::Type mode) noexcep TRI_ASSERT(false); return; } - + TRI_ASSERT(it->second.state != nullptr); TRI_ASSERT(it->second.state->isEmbeddedTransaction()); it->second.state->decreaseNesting(); - + // garbageCollection might soft abort used transactions const bool isSoftAborted = it->second.expires == 0; if (!isSoftAborted) { @@ -461,7 +461,7 @@ void Manager::returnManagedTrx(TRI_voc_tid_t tid, AccessMode::Type mode) noexcep } else { TRI_ASSERT(false); } - + if (isSoftAborted) { abortManagedTrx(tid); } @@ -472,14 +472,14 @@ transaction::Status Manager::getManagedTrxStatus(TRI_voc_tid_t tid) const { size_t bucket = getBucket(tid); READ_LOCKER(allTransactionsLocker, _allTransactionsLock); READ_LOCKER(writeLocker, _transactions[bucket]._lock); - + auto it = _transactions[bucket]._managed.find(tid); if (it == _transactions[bucket]._managed.end()) { return transaction::Status::UNDEFINED; } - - auto const& mtrx = it->second; - + + auto const& mtrx = it->second; + if (mtrx.type == MetaType::Tombstone) { return mtrx.finalStatus; } else if (mtrx.expires > TRI_microtime() && mtrx.state != nullptr) { @@ -492,7 +492,7 @@ transaction::Status Manager::getManagedTrxStatus(TRI_voc_tid_t tid) const { return transaction::Status::ABORTED; } } - + Result Manager::commitManagedTrx(TRI_voc_tid_t tid) { return updateTransaction(tid, transaction::Status::COMMITTED, false); } @@ -506,32 +506,32 @@ Result Manager::updateTransaction(TRI_voc_tid_t tid, bool clearServers) { TRI_ASSERT(status == transaction::Status::COMMITTED || status == transaction::Status::ABORTED); - - LOG_TOPIC("7ad2f", DEBUG, Logger::TRANSACTIONS) << "managed trx '" << tid + + LOG_TOPIC("7bd2f", DEBUG, Logger::TRANSACTIONS) << "managed trx '" << tid << " updating to '" << status << "'"; - + Result res; const size_t bucket = getBucket(tid); bool wasExpired = false; - + std::unique_ptr state; { READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); - + auto& buck = _transactions[bucket]; auto it = buck._managed.find(tid); if (it == buck._managed.end()) { return res.reset(TRI_ERROR_TRANSACTION_NOT_FOUND); } - + ManagedTrx& mtrx = it->second; TRY_WRITE_LOCKER(tryGuard, mtrx.rwlock); if (!tryGuard.isLocked()) { return res.reset(TRI_ERROR_TRANSACTION_DISALLOWED_OPERATION, "transaction is in use"); } - + if (mtrx.type == MetaType::StandaloneAQL) { return res.reset(TRI_ERROR_TRANSACTION_DISALLOWED_OPERATION, "not allowed to change an AQL transaction"); @@ -547,13 +547,13 @@ Result Manager::updateTransaction(TRI_voc_tid_t tid, return res.reset(TRI_ERROR_TRANSACTION_DISALLOWED_OPERATION, msg); } } - + double now = TRI_microtime(); if (mtrx.expires < now) { status = transaction::Status::ABORTED; wasExpired = true; } - + state.reset(mtrx.state); mtrx.state = nullptr; mtrx.type = MetaType::Tombstone; @@ -561,12 +561,12 @@ Result Manager::updateTransaction(TRI_voc_tid_t tid, mtrx.finalStatus = status; // it is sufficient to pretend that the operation already succeeded } - + TRI_ASSERT(state); if (!state) { // this should never happen return res.reset(TRI_ERROR_INTERNAL, "managed trx in an invalid state"); } - + auto abortTombstone = [&] { // set tombstone entry to aborted READ_LOCKER(allTransactionsLocker, _allTransactionsLock); WRITE_LOCKER(writeLocker, _transactions[bucket]._lock); @@ -580,10 +580,10 @@ Result Manager::updateTransaction(TRI_voc_tid_t tid, abortTombstone(); return res.reset(TRI_ERROR_TRANSACTION_ABORTED, "transaction was not running"); } - + auto ctx = std::make_shared(tid, state.get(), AccessMode::Type::NONE); state.release(); // now owned by ctx - + transaction::Options trxOpts; MGMethods trx(ctx, trxOpts); TRI_ASSERT(trx.state()->isRunning()); @@ -605,7 +605,7 @@ Result Manager::updateTransaction(TRI_voc_tid_t tid, } TRI_ASSERT(!trx.state()->isRunning()); } - + return res; } @@ -677,17 +677,17 @@ bool Manager::garbageCollect(bool abortAll) { /// @brief abort all transactions matching bool Manager::abortManagedTrx(std::function cb) { - + SmallVector::allocator_type::arena_type arena; SmallVector toAbort{arena}; - + READ_LOCKER(allTransactionsLocker, _allTransactionsLock); for (size_t bucket = 0; bucket < numBuckets; ++bucket) { READ_LOCKER(locker, _transactions[bucket]._lock); - + auto it = _transactions[bucket]._managed.begin(); while (it != _transactions[bucket]._managed.end()) { - + ManagedTrx& mtrx = it->second; if (mtrx.type == MetaType::Managed) { TRI_ASSERT(mtrx.state != nullptr); @@ -696,11 +696,11 @@ bool Manager::abortManagedTrx(std::function cb) { toAbort.emplace_back(it->first); } } - + ++it; // next } } - + for (TRI_voc_tid_t tid : toAbort) { Result res = updateTransaction(tid, Status::ABORTED, /*clearSrvs*/true); if (res.fail()) { diff --git a/arangod/V8Server/FoxxQueuesFeature.h b/arangod/V8Server/FoxxQueuesFeature.h index 312de0f618..9e3fa6818a 100644 --- a/arangod/V8Server/FoxxQueuesFeature.h +++ b/arangod/V8Server/FoxxQueuesFeature.h @@ -34,6 +34,15 @@ class FoxxQueuesFeature final : public application_features::ApplicationFeature void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; + /// @brief return poll interval for foxx queues. returns a negative number if + /// foxx queues are turned off + double pollInterval() const { + if (!_enabled) { + return -1.0; + } + return _pollInterval; + } + private: double _pollInterval; bool _enabled; @@ -41,4 +50,4 @@ class FoxxQueuesFeature final : public application_features::ApplicationFeature } // namespace arangodb -#endif \ No newline at end of file +#endif diff --git a/arangod/V8Server/V8Context.cpp b/arangod/V8Server/V8Context.cpp index ecac6a6557..eb96669ba3 100644 --- a/arangod/V8Server/V8Context.cpp +++ b/arangod/V8Server/V8Context.cpp @@ -37,16 +37,6 @@ std::string const GlobalContextMethods::CodeReloadRouting = std::string const GlobalContextMethods::CodeReloadAql = "try { require(\"@arangodb/aql\").reload(); } catch (err) { }"; -std::string const GlobalContextMethods::CodeCollectGarbage = - "require(\"internal\").wait(0.01, true);"; - -std::string const GlobalContextMethods::CodeBootstrapCoordinator = - "require('internal').loadStartup('server/bootstrap/autoload.js').startup();" - "require('internal').loadStartup('server/bootstrap/routing.js').startup();"; - -std::string const GlobalContextMethods::CodeWarmupExports = - "require(\"@arangodb/actions\").warmupExports()"; - V8Context::V8Context(size_t id, v8::Isolate* isolate) : _id(id), _isolate(isolate), @@ -158,8 +148,11 @@ void V8Context::handleGlobalContextMethods() { << "executing global context method '" << func << "' for context " << _id; TRI_GET_GLOBALS2(_isolate); - bool allowUseDatabase = v8g->_allowUseDatabase; - v8g->_allowUseDatabase = true; + + // save old security context settings + JavaScriptSecurityContext old(v8g->_securityContext); + + v8g->_securityContext = JavaScriptSecurityContext::createInternalContext(); try { v8::TryCatch tryCatch(_isolate); @@ -180,7 +173,8 @@ void V8Context::handleGlobalContextMethods() { << "caught exception during global context method '" << func << "'"; } - v8g->_allowUseDatabase = allowUseDatabase; + // restore old security settings + v8g->_securityContext = old; } } diff --git a/arangod/V8Server/V8Context.h b/arangod/V8Server/V8Context.h index bd3888d0d0..d9464c116b 100644 --- a/arangod/V8Server/V8Context.h +++ b/arangod/V8Server/V8Context.h @@ -38,9 +38,6 @@ class GlobalContextMethods { UNKNOWN = 0, RELOAD_ROUTING, RELOAD_AQL, - COLLECT_GARBAGE, - BOOTSTRAP_COORDINATOR, - WARMUP_EXPORTS }; public: @@ -51,15 +48,6 @@ class GlobalContextMethods { if (type == "reloadAql") { return MethodType::RELOAD_AQL; } - if (type == "collectGarbage") { - return MethodType::COLLECT_GARBAGE; - } - if (type == "bootstrapCoordinator") { - return MethodType::BOOTSTRAP_COORDINATOR; - } - if (type == "warmupExports") { - return MethodType::WARMUP_EXPORTS; - } return MethodType::UNKNOWN; } @@ -70,12 +58,6 @@ class GlobalContextMethods { return "reloadRouting"; case MethodType::RELOAD_AQL: return "reloadAql"; - case MethodType::COLLECT_GARBAGE: - return "collectGarbage"; - case MethodType::BOOTSTRAP_COORDINATOR: - return "bootstrapCoordinator"; - case MethodType::WARMUP_EXPORTS: - return "warmupExports"; case MethodType::UNKNOWN: default: return "unknown"; @@ -88,12 +70,6 @@ class GlobalContextMethods { return CodeReloadRouting; case MethodType::RELOAD_AQL: return CodeReloadAql; - case MethodType::COLLECT_GARBAGE: - return CodeCollectGarbage; - case MethodType::BOOTSTRAP_COORDINATOR: - return CodeBootstrapCoordinator; - case MethodType::WARMUP_EXPORTS: - return CodeWarmupExports; case MethodType::UNKNOWN: default: return StaticStrings::Empty; @@ -103,9 +79,6 @@ class GlobalContextMethods { public: static std::string const CodeReloadRouting; static std::string const CodeReloadAql; - static std::string const CodeCollectGarbage; - static std::string const CodeBootstrapCoordinator; - static std::string const CodeWarmupExports; }; class V8Context { diff --git a/arangod/V8Server/V8DealerFeature.cpp b/arangod/V8Server/V8DealerFeature.cpp index 3c4e859c8f..a342d8f02d 100644 --- a/arangod/V8Server/V8DealerFeature.cpp +++ b/arangod/V8Server/V8DealerFeature.cpp @@ -27,6 +27,7 @@ #include "Actions/actions.h" #include "ApplicationFeatures/V8PlatformFeature.h" +#include "ApplicationFeatures/V8SecurityFeature.h" #include "Basics/ArangoGlobalContext.h" #include "Basics/ConditionLocker.h" #include "Basics/FileUtils.h" @@ -43,6 +44,7 @@ #include "RestServer/SystemDatabaseFeature.h" #include "Scheduler/SchedulerFeature.h" #include "Transaction/V8Context.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-buffer.h" #include "V8/v8-conv.h" #include "V8/v8-globals.h" @@ -110,6 +112,7 @@ V8DealerFeature::V8DealerFeature(application_features::ApplicationServer& server startsAfter("Action"); startsAfter("V8Platform"); + startsAfter("V8Security"); } void V8DealerFeature::collectOptions(std::shared_ptr options) { @@ -181,6 +184,11 @@ void V8DealerFeature::collectOptions(std::shared_ptr options) { void V8DealerFeature::validateOptions(std::shared_ptr options) { ProgramOptions::ProcessingResult const& result = options->processingResult(); + V8SecurityFeature* v8security = + application_features::ApplicationServer::getFeature( + "V8Security"); + TRI_ASSERT(v8security != nullptr); + // DBServer and Agent don't need JS. Agent role handled in AgencyFeature if (ServerState::instance()->getRole() == ServerState::RoleEnum::ROLE_DBSERVER && (!result.touched("console") || @@ -213,6 +221,8 @@ void V8DealerFeature::validateOptions(std::shared_ptr options) { } ctx->normalizePath(_startupDirectory, "javascript.startup-directory", true); + v8security->addToInternalWhitelist(_startupDirectory, FSAccessType::READ); + ctx->normalizePath(_moduleDirectories, "javascript.module-directory", false); // try to append the current version name to the startup directory, @@ -241,6 +251,7 @@ void V8DealerFeature::validateOptions(std::shared_ptr options) { // version-specific js path exists! it = versionedPath; } + v8security->addToInternalWhitelist(it, FSAccessType::READ); } // check whether app-path was specified @@ -253,6 +264,8 @@ void V8DealerFeature::validateOptions(std::shared_ptr options) { // Tests if this path is either a directory (ok) or does not exist (we create // it in ::start) If it is something else this will throw an error. ctx->normalizePath(_appPath, "javascript.app-path", false); + v8security->addToInternalWhitelist(_appPath, FSAccessType::READ); + v8security->addToInternalWhitelist(_appPath, FSAccessType::WRITE); // use a minimum of 1 second for GC if (_gcFrequency < 1) { @@ -759,7 +772,7 @@ void V8DealerFeature::loadJavaScriptFileInAllContexts(TRI_vocbase_t* vocbase, TRI_DEFER(unblockDynamicContextCreation()); LOG_TOPIC("1364d", TRACE, Logger::V8) << "loading JavaScript file '" << file << "' in all (" - << contexts.size() << ") V8 context"; + << contexts.size() << ") V8 contexts"; // now safely scan the local copy of the contexts for (auto& context : contexts) { @@ -825,7 +838,7 @@ void V8DealerFeature::startGarbageCollection() { } void V8DealerFeature::prepareLockedContext(TRI_vocbase_t* vocbase, V8Context* context, - bool allowUseDatabase) { + JavaScriptSecurityContext const& securityContext) { TRI_ASSERT(vocbase != nullptr); // when we get here, we should have a context and an isolate @@ -845,9 +858,8 @@ void V8DealerFeature::prepareLockedContext(TRI_vocbase_t* vocbase, V8Context* co TRI_GET_GLOBALS(); // initialize the context data - v8g->_query = nullptr; v8g->_vocbase = vocbase; - v8g->_allowUseDatabase = allowUseDatabase; + v8g->_securityContext = securityContext; try { LOG_TOPIC("94226", TRACE, arangodb::Logger::V8) @@ -860,16 +872,9 @@ void V8DealerFeature::prepareLockedContext(TRI_vocbase_t* vocbase, V8Context* co } } -/// @brief forceContext == -1 means that any free context may be -/// picked, or a new one will be created if we have not exceeded -/// the maximum number of contexts -/// forceContext == -2 means that any free context may be picked, -/// or a new one will be created if we have not exceeded or exactly -/// reached the maximum number of contexts. this can be used to -/// force the creation of another context for high priority tasks -/// forceContext >= 0 means picking the context with that exact id -V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase, bool allowUseDatabase, - ssize_t forceContext) { +/// @brief enter a V8 context +/// currently returns a nullptr if no context can be acquired in time +V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase, JavaScriptSecurityContext const& securityContext) { TRI_ASSERT(vocbase != nullptr); if (_stopping) { @@ -890,75 +895,8 @@ V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase, bool allowUseDa V8Context* context = nullptr; - // this is for TESTING / DEBUGGING / INIT only - if (forceContext >= 0) { - size_t id = static_cast(forceContext); - - while (!_stopping) { - { - CONDITION_LOCKER(guard, _contextCondition); - - if (_stopping) { - break; - } - - for (auto it = _idleContexts.begin(); it != _idleContexts.end(); ++it) { - if ((*it)->id() == id) { - context = (*it); - _idleContexts.erase(it); - _busyContexts.emplace(context); - break; - } - } - - if (context == nullptr) { - // still not found - for (auto it = _dirtyContexts.begin(); it != _dirtyContexts.end(); ++it) { - if ((*it)->id() == id) { - context = (*it); - _dirtyContexts.erase(it); - _busyContexts.emplace(context); - break; - } - } - } - - if (context != nullptr) { - // found the context - TRI_ASSERT(guard.isLocked()); - break; - } - - // check if such context exists at all - bool found = false; - for (auto& it : _contexts) { - if (it->id() == id) { - found = true; - break; - } - } - - if (!found) { - vocbase->release(); - LOG_TOPIC("ba767", WARN, arangodb::Logger::V8) - << "specified V8 context #" << id << " not found"; - return nullptr; - } - } - - LOG_TOPIC("603d8", DEBUG, arangodb::Logger::V8) - << "waiting for V8 context #" << id << " to become available"; - std::this_thread::sleep_for(std::chrono::microseconds(50 * 1000)); - } - - if (context == nullptr) { - vocbase->release(); - return nullptr; - } - } - // look for a free context - else { + { CONDITION_LOCKER(guard, _contextCondition); while (_idleContexts.empty() && !_stopping) { @@ -1059,7 +997,7 @@ V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase, bool allowUseDa context->lockAndEnter(); context->assertLocked(); - prepareLockedContext(vocbase, context, allowUseDatabase); + prepareLockedContext(vocbase, context, securityContext); return context; } @@ -1139,9 +1077,8 @@ void V8DealerFeature::cleanupLockedContext(V8Context* context) { TRI_GET_GLOBALS(); // reset the context data; gc should be able to run without it - v8g->_query = nullptr; v8g->_vocbase = nullptr; - v8g->_allowUseDatabase = false; + v8g->_securityContext.reset(); // now really exit auto localContext = v8::Local::New(isolate, context->_context); @@ -1246,8 +1183,10 @@ void V8DealerFeature::applyContextUpdate(V8Context* context) { continue; } + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createInternalContext(); + context->lockAndEnter(); - prepareLockedContext(vocbase, context, true); + prepareLockedContext(vocbase, context, securityContext); TRI_DEFER(exitContextInternal(context)); { @@ -1474,7 +1413,7 @@ V8Context* V8DealerFeature::buildContext(size_t id) { TRI_InitV8UserStructures(isolate, localContext); TRI_InitV8Buffer(isolate); TRI_InitV8Utils(isolate, localContext, _startupDirectory, modules); - TRI_InitV8DebugUtils(isolate, localContext); + TRI_InitV8ServerUtils(isolate); TRI_InitV8Shell(isolate); TRI_InitV8Ttl(isolate); @@ -1553,8 +1492,10 @@ bool V8DealerFeature::loadJavaScriptFileInContext(TRI_vocbase_t* vocbase, return false; } + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createInternalContext(); + context->lockAndEnter(); - prepareLockedContext(vocbase, context, true); + prepareLockedContext(vocbase, context, securityContext); TRI_DEFER(exitContextInternal(context)); try { @@ -1650,26 +1591,49 @@ void V8DealerFeature::shutdownContext(V8Context* context) { delete context; } -V8ContextDealerGuard::V8ContextDealerGuard(Result& res, v8::Isolate*& isolate, - TRI_vocbase_t* vocbase, bool allowModification) - : _isolate(isolate), _context(nullptr), _active(isolate ? false : true) { +V8ContextGuard::V8ContextGuard(TRI_vocbase_t* vocbase, + JavaScriptSecurityContext const& securityContext) + : _isolate(nullptr), _context(nullptr) { + _context = V8DealerFeature::DEALER->enterContext(vocbase, securityContext); + if (_context == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_RESOURCE_LIMIT, + "unable to acquire V8 context in time"); + } + _isolate = _context->_isolate; +} + +V8ContextGuard::~V8ContextGuard() { + if (_context) { + try { + V8DealerFeature::DEALER->exitContext(_context); + } catch (...) { + } + } +} + +V8ConditionalContextGuard::V8ConditionalContextGuard(Result& res, v8::Isolate*& isolate, + TRI_vocbase_t* vocbase, + JavaScriptSecurityContext const& securityContext) + : _isolate(isolate), + _context(nullptr), + _active(isolate ? false : true) { if (_active) { if (!vocbase) { res.reset(TRI_ERROR_INTERNAL, - "V8ContextDealerGuard - no vocbase provided"); + "V8ConditionalContextGuard - no vocbase provided"); return; } - _context = V8DealerFeature::DEALER->enterContext(vocbase, allowModification); + _context = V8DealerFeature::DEALER->enterContext(vocbase, securityContext); if (!_context) { res.reset(TRI_ERROR_INTERNAL, - "V8ContextDealerGuard - could not acquire context"); + "V8ConditionalContextGuard - could not acquire context"); return; } isolate = _context->_isolate; } } -V8ContextDealerGuard::~V8ContextDealerGuard() { +V8ConditionalContextGuard::~V8ConditionalContextGuard() { if (_active && _context) { try { V8DealerFeature::DEALER->exitContext(_context); diff --git a/arangod/V8Server/V8DealerFeature.h b/arangod/V8Server/V8DealerFeature.h index ec4777ff19..6c32d64a29 100644 --- a/arangod/V8Server/V8DealerFeature.h +++ b/arangod/V8Server/V8DealerFeature.h @@ -35,7 +35,7 @@ struct TRI_vocbase_t; namespace arangodb { - +class JavaScriptSecurityContext; class Thread; class V8Context; @@ -87,15 +87,9 @@ class V8DealerFeature final : public application_features::ApplicationFeature { void loadJavaScriptFileInAllContexts(TRI_vocbase_t*, std::string const& file, VPackBuilder* builder); - /// @brief forceContext == -1 means that any free context may be - /// picked, or a new one will be created if we have not exceeded - /// the maximum number of contexts - /// forceContext == -2 means that any free context may be picked, - /// or a new one will be created if we have not exceeded or exactly - /// reached the maximum number of contexts. this can be used to - /// force the creation of another context for high priority tasks - /// forceContext >= 0 means picking the context with that exact id - V8Context* enterContext(TRI_vocbase_t*, bool allowUseDatabase, ssize_t forceContext = -1); + /// @brief enter a V8 context + /// currently returns a nullptr if no context can be acquired in time + V8Context* enterContext(TRI_vocbase_t*, JavaScriptSecurityContext const& securityContext); void exitContext(V8Context*); void defineContextUpdate(std::function, size_t)>, @@ -136,7 +130,7 @@ class V8DealerFeature final : public application_features::ApplicationFeature { VPackBuilder* builder); bool loadJavaScriptFileInContext(TRI_vocbase_t*, std::string const& file, V8Context* context, VPackBuilder* builder); - void prepareLockedContext(TRI_vocbase_t*, V8Context*, bool allowUseDatabase); + void prepareLockedContext(TRI_vocbase_t*, V8Context*, JavaScriptSecurityContext const&); void exitContextInternal(V8Context*); void cleanupLockedContext(V8Context*); void applyContextUpdate(V8Context* context); @@ -164,14 +158,31 @@ class V8DealerFeature final : public application_features::ApplicationFeature { std::vector, size_t)>, TRI_vocbase_t*>> _contextUpdates; }; +/// @brief enters and exits a context and provides an isolate +/// throws an exception when no context can be provided +class V8ContextGuard { + public: + explicit V8ContextGuard(TRI_vocbase_t*, JavaScriptSecurityContext const&); + V8ContextGuard(V8ContextGuard const&) = delete; + V8ContextGuard& operator=(V8ContextGuard const&) = delete; + ~V8ContextGuard(); + + v8::Isolate* isolate() const { return _isolate; } + V8Context* context() const { return _context; } + + private: + v8::Isolate* _isolate; + V8Context* _context; +}; + // enters and exits a context and provides an isolate // in case the passed in isolate is a nullptr -class V8ContextDealerGuard { +class V8ConditionalContextGuard { public: - explicit V8ContextDealerGuard(Result&, v8::Isolate*&, TRI_vocbase_t*, bool allowModification); - V8ContextDealerGuard(V8ContextDealerGuard const&) = delete; - V8ContextDealerGuard& operator=(V8ContextDealerGuard const&) = delete; - ~V8ContextDealerGuard(); + explicit V8ConditionalContextGuard(Result&, v8::Isolate*&, TRI_vocbase_t*, JavaScriptSecurityContext const&); + V8ConditionalContextGuard(V8ConditionalContextGuard const&) = delete; + V8ConditionalContextGuard& operator=(V8ConditionalContextGuard const&) = delete; + ~V8ConditionalContextGuard(); private: v8::Isolate*& _isolate; diff --git a/arangod/V8Server/v8-actions.cpp b/arangod/V8Server/v8-actions.cpp index d394ee5529..c3f879a2a8 100644 --- a/arangod/V8Server/v8-actions.cpp +++ b/arangod/V8Server/v8-actions.cpp @@ -24,6 +24,8 @@ #include "v8-actions.h" #include "Actions/ActionFeature.h" #include "Actions/actions.h" +#include "ApplicationFeatures/ApplicationServer.h" +#include "ApplicationFeatures/V8SecurityFeature.h" #include "Basics/MutexLocker.h" #include "Basics/ReadLocker.h" #include "Basics/StringUtils.h" @@ -34,15 +36,18 @@ #include "Cluster/ClusterComm.h" #include "Cluster/ServerState.h" #include "GeneralServer/GeneralServer.h" +#include "GeneralServer/ServerSecurityFeature.h" #include "Logger/Logger.h" #include "Rest/GeneralRequest.h" #include "Rest/HttpRequest.h" #include "Rest/HttpResponse.h" #include "Utils/ExecContext.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-buffer.h" #include "V8/v8-conv.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" +#include "V8Server/FoxxQueuesFeature.h" #include "V8Server/V8Context.h" #include "V8Server/V8DealerFeature.h" #include "V8Server/v8-vocbase.h" @@ -105,40 +110,19 @@ class v8_action_t final : public TRI_action_t { void** data) override { TRI_action_result_t result; - // allow use database execution in rest calls - bool allowUseDatabaseInRestActions = ActionFeature::ACTION->allowUseDatabase(); - - if (_allowUseDatabase) { - allowUseDatabaseInRestActions = true; - } - - // this is for TESTING / DEBUGGING only - do not document this feature - ssize_t forceContext = -1; - bool found; - - std::string const& c = request->header("x-arango-v8-context", found); - - if (found && !c.empty()) { - forceContext = StringUtils::int32(c); - } + // allow use database execution in rest calls? + bool allowUseDatabase = _allowUseDatabase || ActionFeature::ACTION->allowUseDatabase(); // get a V8 context - V8Context* context = V8DealerFeature::DEALER->enterContext(vocbase, allowUseDatabaseInRestActions, - forceContext); - - // note: the context might be nullptr in case of shut-down - if (context == nullptr) { - THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_RESOURCE_LIMIT, - "unable to acquire V8 context in time"); - } - - TRI_DEFER(V8DealerFeature::DEALER->exitContext(context)); + V8ContextGuard guard(vocbase, _isSystem ? + JavaScriptSecurityContext::createInternalContext() : + JavaScriptSecurityContext::createRestActionContext(allowUseDatabase)); // locate the callback READ_LOCKER(readLocker, _callbacksLock); { - auto it = _callbacks.find(context->_isolate); + auto it = _callbacks.find(guard.isolate()); if (it == _callbacks.end()) { LOG_TOPIC("94556", WARN, arangodb::Logger::FIXME) @@ -159,17 +143,17 @@ class v8_action_t final : public TRI_action_t { return result; } - *data = (void*)context->_isolate; + *data = (void*)guard.isolate(); } - v8::HandleScope scope(context->_isolate); - auto localFunction = v8::Local::New(context->_isolate, it->second); + v8::HandleScope scope(guard.isolate()); + auto localFunction = v8::Local::New(guard.isolate(), it->second); // we can release the lock here already as no other threads will // work in our isolate at this time readLocker.unlock(); try { - result = ExecuteActionVocbase(vocbase, context->_isolate, this, + result = ExecuteActionVocbase(vocbase, guard.isolate(), this, localFunction, request, response); } catch (...) { result.isValid = false; @@ -241,6 +225,14 @@ static void ParseActionOptions(v8::Isolate* isolate, TRI_v8_global_t* v8g, } else { action->_allowUseDatabase = false; } + + TRI_GET_GLOBAL_STRING(IsSystemKey); + if (TRI_HasProperty(context, isolate, options, IsSystemKey)) { + action->_isSystem = + TRI_ObjectToBoolean(isolate, options->Get(IsSystemKey)); + } else { + action->_isSystem = false; + } } //////////////////////////////////////////////////////////////////////////////// @@ -506,7 +498,7 @@ v8::Handle TRI_RequestCppToV8(v8::Isolate* isolate, req->Set(RequestTypeKey, HeadConstant); break; } - case rest::RequestType::GET: + case rest::RequestType::GET: default: { TRI_GET_GLOBAL_STRING(GetConstant); req->Set(RequestTypeKey, GetConstant); @@ -562,7 +554,7 @@ v8::Handle TRI_RequestCppToV8(v8::Isolate* isolate, TRI_GET_GLOBAL_STRING(CookiesKey); req->Set(CookiesKey, cookiesObject); } - + // copy suffix, which comes from the action: std::vector const& suffixes = request->decodedSuffixes(); std::vector const& rawSuffixes = request->suffixes(); @@ -823,7 +815,7 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g, HttpResponse* httpResponse = dynamic_cast(response); httpResponse->body().appendText(content, length); TRI_FreeString(content); - } + } break; case Endpoint::TransportType::VST: { @@ -835,7 +827,7 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g, // create vpack from file response->setContentType(rest::ContentType::TEXT); response->setPayload(std::move(buffer), true); - } + } break; default: @@ -1020,6 +1012,15 @@ static void JS_DefineAction(v8::FunctionCallbackInfo const& args) { "defineAction(, , )"); } + V8SecurityFeature* v8security = + application_features::ApplicationServer::getFeature( + "V8Security"); + TRI_ASSERT(v8security != nullptr); + + if (!v8security->isAllowedToDefineHttpAction(isolate)) { + TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, "operation only allowed for internal scripts"); + } + // extract the action name TRI_Utf8ValueNFC utf8name(isolate, args[0]); @@ -1376,7 +1377,7 @@ static void JS_GetCurrentResponse(v8::FunctionCallbackInfo const& arg /// @brief stores the V8 actions function inside the global variable //////////////////////////////////////////////////////////////////////////////// -void TRI_InitV8Actions(v8::Isolate* isolate, v8::Handle context) { +void TRI_InitV8Actions(v8::Isolate* isolate) { v8::HandleScope scope(isolate); // ............................................................................. @@ -1388,7 +1389,7 @@ void TRI_InitV8Actions(v8::Isolate* isolate, v8::Handle context) { TRI_AddGlobalFunctionVocbase( isolate, TRI_V8_ASCII_STRING(isolate, "SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION"), - JS_ExecuteGlobalContextFunction); + JS_ExecuteGlobalContextFunction, true); TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "SYS_GET_CURRENT_REQUEST"), @@ -1644,12 +1645,83 @@ static void JS_DebugClearFailAt(v8::FunctionCallbackInfo const& args) TRI_V8_TRY_CATCH_END } -void TRI_InitV8DebugUtils(v8::Isolate* isolate, v8::Handle context) { +static void JS_IsFoxxApiDisabled(v8::FunctionCallbackInfo const& args) { + TRI_V8_TRY_CATCH_BEGIN(isolate) + v8::HandleScope scope(isolate); + + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + TRI_V8_RETURN_BOOL(security->isFoxxApiDisabled()); + + TRI_V8_TRY_CATCH_END +} + +static void JS_IsFoxxStoreDisabled(v8::FunctionCallbackInfo const& args) { + TRI_V8_TRY_CATCH_BEGIN(isolate) + v8::HandleScope scope(isolate); + + ServerSecurityFeature* security = + application_features::ApplicationServer::getFeature( + "ServerSecurity"); + TRI_ASSERT(security != nullptr); + TRI_V8_RETURN_BOOL(security->isFoxxStoreDisabled()); + + TRI_V8_TRY_CATCH_END +} + +static void JS_RunInRestrictedContext(v8::FunctionCallbackInfo const& args) { + TRI_V8_TRY_CATCH_BEGIN(isolate) + v8::HandleScope scope(isolate); + + if (args.Length() != 1 || !args[0]->IsFunction()) { + TRI_V8_THROW_EXCEPTION_USAGE( + "runInRestrictedContext()"); + } + + v8::Handle action = v8::Local::Cast(args[0]); + if (action.IsEmpty()) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "cannot cannot function instance for runInRestrictedContext"); + } + + TRI_GET_GLOBALS(); + + { + // take a copy of the previous security context + auto oldContext = v8g->_securityContext; + + // patch security context + v8g->_securityContext = JavaScriptSecurityContext::createRestrictedContext(); + + // make sure the old context will be restored + auto guard = scopeGuard([&oldContext, &v8g]() { + v8g->_securityContext = oldContext; + }); + + v8::Handle current = isolate->GetCurrentContext()->Global(); + v8::Handle callArgs[] = {v8::Null(isolate)}; + v8::Handle rv = action->Call(current, 0, callArgs); + TRI_V8_RETURN(rv); + } + + TRI_V8_TRY_CATCH_END +} + +void TRI_InitV8ServerUtils(v8::Isolate* isolate) { + TRI_AddGlobalFunctionVocbase(isolate, + TRI_V8_ASCII_STRING(isolate, "SYS_IS_FOXX_API_DISABLED"), JS_IsFoxxApiDisabled, true); + TRI_AddGlobalFunctionVocbase(isolate, + TRI_V8_ASCII_STRING(isolate, "SYS_IS_FOXX_STORE_DISABLED"), JS_IsFoxxStoreDisabled, true); + TRI_AddGlobalFunctionVocbase(isolate, + TRI_V8_ASCII_STRING(isolate, "SYS_RUN_IN_RESTRICTED_CONTEXT"), JS_RunInRestrictedContext, true); + // debugging functions TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "SYS_DEBUG_CLEAR_FAILAT"), JS_DebugClearFailAt); + #ifdef ARANGODB_ENABLE_FAILURE_TESTS TRI_AddGlobalFunctionVocbase( isolate, TRI_V8_ASCII_STRING(isolate, "SYS_DEBUG_SEGFAULT"), JS_DebugSegfault); @@ -1666,4 +1738,15 @@ void TRI_InitV8DebugUtils(v8::Isolate* isolate, v8::Handle context) "SYS_DEBUG_SHOULD_FAILAT"), JS_DebugShouldFailAt); #endif + + // poll interval for Foxx queues + FoxxQueuesFeature* foxxQueuesFeature = + application_features::ApplicationServer::getFeature( + "FoxxQueues"); + + isolate->GetCurrentContext()->Global() + ->DefineOwnProperty(TRI_IGETC, + TRI_V8_ASCII_STRING(isolate, "FOXX_QUEUES_POLL_INTERVAL"), + v8::Number::New(isolate, foxxQueuesFeature->pollInterval()), v8::ReadOnly) + .FromMaybe(false); // ignore result } diff --git a/arangod/V8Server/v8-actions.h b/arangod/V8Server/v8-actions.h index 2926814e5c..cf0ad24a5f 100644 --- a/arangod/V8Server/v8-actions.h +++ b/arangod/V8Server/v8-actions.h @@ -40,8 +40,8 @@ v8::Handle TRI_RequestCppToV8(v8::Isolate* isolate, arangodb::GeneralRequest* request, TRI_action_t const* action); -void TRI_InitV8Actions(v8::Isolate* isolate, v8::Handle context); +void TRI_InitV8Actions(v8::Isolate* isolate); -void TRI_InitV8DebugUtils(v8::Isolate* isolate, v8::Handle context); +void TRI_InitV8ServerUtils(v8::Isolate* isolate); #endif diff --git a/arangod/V8Server/v8-dispatcher.cpp b/arangod/V8Server/v8-dispatcher.cpp index 2eed252f88..b7df3139ef 100644 --- a/arangod/V8Server/v8-dispatcher.cpp +++ b/arangod/V8Server/v8-dispatcher.cpp @@ -140,6 +140,11 @@ static void JS_RegisterTask(v8::FunctionCallbackInfo const& args) { .FromMaybe(v8::Local())); } + if(isSystem && !v8g->_securityContext.isInternal()) { + TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, "Only Internal Context may create System Tasks"); + + } + // offset in seconds into period or from now on if no period double offset = 0.0; diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 15dbba8c19..de57d251b0 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -27,6 +27,7 @@ #include "Basics/StaticStrings.h" #include "Basics/VelocyPackHelper.h" #include "Indexes/Index.h" +#include "RestServer/QueryRegistryFeature.h" #include "StorageEngine/PhysicalCollection.h" #include "Transaction/Helpers.h" #include "Transaction/V8Context.h" @@ -58,9 +59,10 @@ using namespace arangodb::basics; aql::QueryResultV8 AqlQuery(v8::Isolate* isolate, arangodb::LogicalCollection const* col, std::string const& aql, std::shared_ptr bindVars) { TRI_ASSERT(col != nullptr); + + auto queryRegistry = QueryRegistryFeature::registry(); + TRI_ASSERT(queryRegistry != nullptr); - TRI_GET_GLOBALS(); - // If we execute an AQL query from V8 we need to unset the nolock headers arangodb::aql::Query query(true, col->vocbase(), arangodb::aql::QueryString(aql), bindVars, nullptr, arangodb::aql::PART_MAIN); @@ -70,7 +72,7 @@ aql::QueryResultV8 AqlQuery(v8::Isolate* isolate, arangodb::LogicalCollection co aql::QueryResultV8 queryResult; while (true) { auto state = - query.executeV8(isolate, static_cast(v8g->_queryRegistry), + query.executeV8(isolate, static_cast(queryRegistry), queryResult); if (state != aql::ExecutionState::WAITING) { break; diff --git a/arangod/V8Server/v8-statistics.cpp b/arangod/V8Server/v8-statistics.cpp index ca73b0677b..f47f7c3a93 100644 --- a/arangod/V8Server/v8-statistics.cpp +++ b/arangod/V8Server/v8-statistics.cpp @@ -24,6 +24,7 @@ #include "v8-statistics.h" #include "ApplicationFeatures/ApplicationServer.h" +#include "ApplicationFeatures/V8SecurityFeature.h" #include "Basics/Exceptions.h" #include "Basics/StringUtils.h" #include "Basics/process-utils.h" @@ -97,6 +98,16 @@ static void FillDistribution(v8::Isolate* isolate, v8::Handle list, static void JS_ServerStatistics(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate) v8::HandleScope scope(isolate); + + V8SecurityFeature* v8security = + application_features::ApplicationServer::getFeature( + "V8Security"); + TRI_ASSERT(v8security != nullptr); + + if (v8security->isInternalModuleHardened(isolate)) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, + "not allowed to provide this information"); + } ServerStatistics info = ServerStatistics::statistics(); @@ -164,6 +175,16 @@ static void JS_EnabledStatistics(v8::FunctionCallbackInfo const& args static void JS_ClientStatistics(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate) v8::HandleScope scope(isolate); + + V8SecurityFeature* v8security = + application_features::ApplicationServer::getFeature( + "V8Security"); + TRI_ASSERT(v8security != nullptr); + + if (v8security->isInternalModuleHardened(isolate)) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, + "not allowed to provide this information"); + } v8::Handle result = v8::Object::New(isolate); @@ -209,6 +230,16 @@ static void JS_ClientStatistics(v8::FunctionCallbackInfo const& args) static void JS_HttpStatistics(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); + + V8SecurityFeature* v8security = + application_features::ApplicationServer::getFeature( + "V8Security"); + TRI_ASSERT(v8security != nullptr); + + if (v8security->isInternalModuleHardened(isolate)) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, + "not allowed to provide this information"); + } v8::Handle result = v8::Object::New(isolate); diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 193f90c480..6d9b9f6cef 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -57,7 +57,7 @@ #include "Rest/Version.h" #include "RestServer/ConsoleThread.h" #include "RestServer/DatabaseFeature.h" -#include "RocksDBEngine/RocksDBEngine.h" +#include "RestServer/QueryRegistryFeature.h" #include "Statistics/StatisticsFeature.h" #include "StorageEngine/EngineSelectorFeature.h" #include "StorageEngine/StorageEngine.h" @@ -65,7 +65,6 @@ #include "Utils/Events.h" #include "Utils/ExecContext.h" #include "V8/JSLoader.h" -#include "V8/V8LineEditor.h" #include "V8/v8-conv.h" #include "V8/v8-helper.h" #include "V8/v8-utils.h" @@ -193,60 +192,6 @@ static void JS_EnableNativeBacktraces(v8::FunctionCallbackInfo const& TRI_V8_TRY_CATCH_END } -extern V8LineEditor* theConsole; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief starts a debugging console -//////////////////////////////////////////////////////////////////////////////// - -static void JS_Debug(v8::FunctionCallbackInfo const& args) { - TRI_V8_TRY_CATCH_BEGIN(isolate); - - v8::Local name(TRI_V8_ASCII_STRING(isolate, "debug loop")); - v8::Local debug(TRI_V8_ASCII_STRING(isolate, "debug")); - - v8::Local callerScope; - if (args.Length() >= 1) { - TRI_AddGlobalVariableVocbase(isolate, debug, args[0]); - } - - MUTEX_LOCKER(mutexLocker, ConsoleThread::serverConsoleMutex); - V8LineEditor* console = ConsoleThread::serverConsole; - - if (console != nullptr) { - while (true) { - ShellBase::EofType eof; - std::string input = console->prompt("debug> ", "debug>", eof); - - if (eof == ShellBase::EOF_FORCE_ABORT) { - break; - } - - if (input.empty()) { - continue; - } - - console->addHistory(input); - - { - v8::HandleScope scope(isolate); - v8::TryCatch tryCatch(isolate); - ; - - TRI_ExecuteJavaScriptString(isolate, isolate->GetCurrentContext(), - TRI_V8_STD_STRING(isolate, input), name, true); - - if (tryCatch.HasCaught()) { - std::cout << TRI_StringifyV8Exception(isolate, &tryCatch); - } - } - } - } - - TRI_V8_RETURN_UNDEFINED(); - TRI_V8_TRY_CATCH_END -} - //////////////////////////////////////////////////////////////////////////////// /// @brief compare two UTF 16 strings //////////////////////////////////////////////////////////////////////////////// @@ -529,41 +474,6 @@ static void JS_ParseAql(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_END } -//////////////////////////////////////////////////////////////////////////////// -/// @brief registers a warning for the currently running AQL query -/// this function is called from aql.js -//////////////////////////////////////////////////////////////////////////////// - -static void JS_WarningAql(v8::FunctionCallbackInfo const& args) { - TRI_V8_TRY_CATCH_BEGIN(isolate); - v8::HandleScope scope(isolate); - - if (args.Length() != 2) { - TRI_V8_THROW_EXCEPTION_USAGE("AQL_WARNING(, )"); - } - - // get the query string - if (!args[1]->IsString()) { - TRI_V8_THROW_TYPE_ERROR("expecting string for "); - } - - TRI_GET_GLOBALS(); - - if (v8g->_query != nullptr) { - // only register the error if we have a query... - // note: we may not have a query if the AQL functions are called without - // a query, e.g. during tests - int code = static_cast(TRI_ObjectToInt64(isolate, args[0])); - std::string const message = TRI_ObjectToString(isolate, args[1]); - - auto query = static_cast(v8g->_query); - query->registerWarning(code, message.c_str()); - } - - TRI_V8_RETURN_UNDEFINED(); - TRI_V8_TRY_CATCH_END -} - //////////////////////////////////////////////////////////////////////////////// /// @brief explains an AQL query //////////////////////////////////////////////////////////////////////////////// @@ -706,10 +616,12 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo const& args) { } } - TRI_GET_GLOBALS(); + auto queryRegistry = QueryRegistryFeature::registry(); + TRI_ASSERT(queryRegistry != nullptr); + arangodb::aql::Query query(true, vocbase, queryBuilder, options, arangodb::aql::PART_MAIN); aql::QueryResult queryResult = - query.executeSync(static_cast(v8g->_queryRegistry)); + query.executeSync(static_cast(queryRegistry)); if (queryResult.result.fail()) { events::QueryDocument(vocbase.name(), queryBuilder->slice(), queryResult.result.errorNumber()); @@ -812,8 +724,10 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo const& args) { } } + auto queryRegistry = QueryRegistryFeature::registry(); + TRI_ASSERT(queryRegistry != nullptr); + // bind parameters will be freed by the query later - TRI_GET_GLOBALS(); arangodb::aql::Query query(true, vocbase, aql::QueryString(queryString), bindVars, options, arangodb::aql::PART_MAIN); @@ -823,7 +737,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo const& args) { aql::QueryResultV8 queryResult; while (true) { auto state = - query.executeV8(isolate, static_cast(v8g->_queryRegistry), + query.executeV8(isolate, static_cast(queryRegistry), queryResult); if (state != aql::ExecutionState::WAITING) { break; @@ -1100,23 +1014,6 @@ static void JS_QueriesKillAql(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_END } -//////////////////////////////////////////////////////////////////////////////// -/// @brief whether or not a query is killed -//////////////////////////////////////////////////////////////////////////////// - -static void JS_QueryIsKilledAql(v8::FunctionCallbackInfo const& args) { - TRI_V8_TRY_CATCH_BEGIN(isolate); - v8::HandleScope scope(isolate); - - TRI_GET_GLOBALS(); - if (v8g->_query != nullptr && static_cast(v8g->_query)->killed()) { - TRI_V8_RETURN_TRUE(); - } - - TRI_V8_RETURN_FALSE(); - TRI_V8_TRY_CATCH_END -} - //////////////////////////////////////////////////////////////////////////////// /// @brief configures the AQL query cache //////////////////////////////////////////////////////////////////////////////// @@ -1209,71 +1106,6 @@ static void JS_ThrowCollectionNotLoaded(v8::FunctionCallbackInfo cons TRI_V8_TRY_CATCH_END } -//////////////////////////////////////////////////////////////////////////////// -/// @brief sleeps and checks for query abortion in between -//////////////////////////////////////////////////////////////////////////////// - -static void JS_QuerySleepAql(v8::FunctionCallbackInfo const& args) { - TRI_V8_TRY_CATCH_BEGIN(isolate); - v8::HandleScope scope(isolate); - - // extract arguments - if (args.Length() != 1) { - TRI_V8_THROW_EXCEPTION_USAGE("sleep()"); - } - - TRI_GET_GLOBALS(); - arangodb::aql::Query* query = static_cast(v8g->_query); - - if (query == nullptr) { - TRI_V8_THROW_EXCEPTION(TRI_ERROR_QUERY_NOT_FOUND); - } - - double n = TRI_ObjectToDouble(isolate, args[0]); - double const until = TRI_microtime() + n; - - while (TRI_microtime() < until) { - std::this_thread::sleep_for(std::chrono::microseconds(10000)); - - if (query != nullptr) { - if (query->killed()) { - TRI_V8_THROW_EXCEPTION(TRI_ERROR_QUERY_KILLED); - } - } - } - - TRI_V8_RETURN_UNDEFINED(); - TRI_V8_TRY_CATCH_END -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief hashes a V8 object -//////////////////////////////////////////////////////////////////////////////// - -static void JS_ObjectHash(v8::FunctionCallbackInfo const& args) { - TRI_V8_TRY_CATCH_BEGIN(isolate); - v8::HandleScope scope(isolate); - - // extract arguments - if (args.Length() != 1) { - TRI_V8_THROW_EXCEPTION_USAGE("hash()"); - } - - VPackBuilder builder; - int res = TRI_V8ToVPack(isolate, builder, args[0], false); - - if (res != TRI_ERROR_NO_ERROR) { - TRI_V8_THROW_EXCEPTION(res); - } - - // throw away the top bytes so the hash value can safely be used - // without precision loss when storing in JavaScript etc. - uint64_t hash = builder.slice().normalizedHash() & 0x0007ffffffffffffULL; - - TRI_V8_RETURN(v8::Number::New(isolate, static_cast(hash))); - TRI_V8_TRY_CATCH_END -} - //////////////////////////////////////////////////////////////////////////////// /// @brief wraps a TRI_vocbase_t //////////////////////////////////////////////////////////////////////////////// @@ -1600,7 +1432,7 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo const& args) { TRI_GET_GLOBALS(); - if (!v8g->_allowUseDatabase) { + if (!v8g->_securityContext.canUseDatabase()) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_FORBIDDEN); } @@ -1995,10 +1827,6 @@ void TRI_InitV8VocBridge(v8::Isolate* isolate, v8::Handle context, v8g->_transactionContext = new transaction::V8Context(vocbase, true); static_cast(v8g->_transactionContext)->makeGlobal(); - // register the query registry - TRI_ASSERT(queryRegistry != nullptr); - v8g->_queryRegistry = queryRegistry; - // register the database v8g->_vocbase = &vocbase; @@ -2082,9 +1910,6 @@ void TRI_InitV8VocBridge(v8::Isolate* isolate, v8::Handle context, TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "AQL_PARSE"), JS_ParseAql, true); - TRI_AddGlobalFunctionVocbase(isolate, - TRI_V8_ASCII_STRING(isolate, "AQL_WARNING"), - JS_WarningAql, true); TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "AQL_QUERIES_PROPERTIES"), @@ -2099,13 +1924,6 @@ void TRI_InitV8VocBridge(v8::Isolate* isolate, v8::Handle context, TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "AQL_QUERIES_KILL"), JS_QueriesKillAql, true); - TRI_AddGlobalFunctionVocbase(isolate, - TRI_V8_ASCII_STRING(isolate, "AQL_QUERY_SLEEP"), - JS_QuerySleepAql, true); - TRI_AddGlobalFunctionVocbase(isolate, - TRI_V8_ASCII_STRING(isolate, - "AQL_QUERY_IS_KILLED"), - JS_QueryIsKilledAql, true); TRI_AddGlobalFunctionVocbase( isolate, TRI_V8_ASCII_STRING(isolate, "AQL_QUERY_CACHE_PROPERTIES"), JS_QueryCachePropertiesAql, true); @@ -2117,10 +1935,6 @@ void TRI_InitV8VocBridge(v8::Isolate* isolate, v8::Handle context, isolate, TRI_V8_ASCII_STRING(isolate, "AQL_QUERY_CACHE_INVALIDATE"), JS_QueryCacheInvalidateAql, true); - TRI_AddGlobalFunctionVocbase(isolate, - TRI_V8_ASCII_STRING(isolate, "OBJECT_HASH"), - JS_ObjectHash, true); - TRI_AddGlobalFunctionVocbase( isolate, TRI_V8_ASCII_STRING(isolate, "THROW_COLLECTION_NOT_LOADED"), JS_ThrowCollectionNotLoaded, true); @@ -2155,9 +1969,6 @@ void TRI_InitV8VocBridge(v8::Isolate* isolate, v8::Handle context, "ENABLE_NATIVE_BACKTRACES"), JS_EnableNativeBacktraces, true); - TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "Debug"), - JS_Debug, true); - TRI_AddGlobalFunctionVocbase(isolate, TRI_V8_ASCII_STRING(isolate, "AUTHENTICATION_ENABLED"), diff --git a/arangod/VocBase/Methods/AqlUserFunctions.cpp b/arangod/VocBase/Methods/AqlUserFunctions.cpp index 46a0857961..873fe3a13f 100644 --- a/arangod/VocBase/Methods/AqlUserFunctions.cpp +++ b/arangod/VocBase/Methods/AqlUserFunctions.cpp @@ -34,6 +34,7 @@ #include "Transaction/V8Context.h" #include "Utils/OperationOptions.h" #include "Utils/SingleCollectionTransaction.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-globals.h" #include "V8/v8-utils.h" #include "V8Server/V8DealerFeature.h" @@ -232,8 +233,9 @@ Result arangodb::registerUserFunction(TRI_vocbase_t& vocbase, velocypack::Slice { ISOLATE; bool throwV8Exception = (isolate != nullptr); - V8ContextDealerGuard dealerGuard(res, isolate, &vocbase, true /*allowModification*/ - ); + + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createRestrictedContext(); + V8ConditionalContextGuard contextGuard(res, isolate, &vocbase, securityContext); if (res.fail()) { return res; diff --git a/arangod/VocBase/Methods/Collections.cpp b/arangod/VocBase/Methods/Collections.cpp index 7d6f5563f7..b2456c4824 100644 --- a/arangod/VocBase/Methods/Collections.cpp +++ b/arangod/VocBase/Methods/Collections.cpp @@ -46,6 +46,7 @@ #include "Utils/ExecContext.h" #include "Utils/OperationCursor.h" #include "Utils/SingleCollectionTransaction.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-conv.h" #include "V8/v8-utils.h" #include "V8Server/V8Context.h" @@ -514,14 +515,10 @@ static int RenameGraphCollections(TRI_vocbase_t* vocbase, std::string const& old buffer.appendJsonEncoded(newName.c_str(), newName.size()); buffer.appendText(");"); - V8Context* context = dealer->enterContext(vocbase, false); - if (context == nullptr) { - LOG_TOPIC("8f0aa", WARN, Logger::FIXME) << "RenameGraphCollections: no V8 context"; - return TRI_ERROR_OUT_OF_MEMORY; - } - TRI_DEFER(dealer->exitContext(context)); + JavaScriptSecurityContext securityContext = JavaScriptSecurityContext::createInternalContext(); + V8ContextGuard guard(vocbase, securityContext); - auto isolate = context->_isolate; + auto isolate = guard.isolate(); v8::HandleScope scope(isolate); TRI_ExecuteJavaScriptString(isolate, isolate->GetCurrentContext(), TRI_V8_ASCII_PAIR_STRING(isolate, buffer.c_str(), diff --git a/arangod/VocBase/Methods/Databases.cpp b/arangod/VocBase/Methods/Databases.cpp index 94df56b649..0e8646118b 100644 --- a/arangod/VocBase/Methods/Databases.cpp +++ b/arangod/VocBase/Methods/Databases.cpp @@ -20,8 +20,8 @@ /// @author Simon Grätzer //////////////////////////////////////////////////////////////////////////////// -#include "Basics/Common.h" #include "Databases.h" +#include "Basics/Common.h" #include "Agency/AgencyComm.h" #include "Basics/StringUtils.h" @@ -34,6 +34,7 @@ #include "RestServer/SystemDatabaseFeature.h" #include "Utils/Events.h" #include "Utils/ExecContext.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" #include "V8Server/V8Context.h" @@ -356,6 +357,8 @@ int dropDBCoordinator(std::string const& dbName) { } return TRI_ERROR_NO_ERROR; } + +const std::string dropError = "Error when dropping Datbase"; } // namespace arangodb::Result Databases::drop(TRI_vocbase_t* systemVocbase, std::string const& dbName) { @@ -371,40 +374,44 @@ arangodb::Result Databases::drop(TRI_vocbase_t* systemVocbase, std::string const int res; V8DealerFeature* dealer = V8DealerFeature::DEALER; if (dealer != nullptr && dealer->isEnabled()) { - V8Context* v8ctx = V8DealerFeature::DEALER->enterContext(systemVocbase, true); - if (v8ctx == nullptr) { - events::DropDatabase(dbName, TRI_ERROR_INTERNAL); - return Result(TRI_ERROR_INTERNAL, "Could not get v8 context"); - } - TRI_DEFER(V8DealerFeature::DEALER->exitContext(v8ctx)); - v8::Isolate* isolate = v8ctx->_isolate; - v8::HandleScope scope(isolate); + try { + JavaScriptSecurityContext securityContext = + JavaScriptSecurityContext::createInternalContext(); - // clear collections in cache object - TRI_ClearObjectCacheV8(isolate); + V8ContextGuard guard(systemVocbase, securityContext); + v8::Isolate* isolate = guard.isolate(); - if (ServerState::instance()->isCoordinator()) { - // If we are a coordinator in a cluster, we have to behave differently: - res = ::dropDBCoordinator(dbName); - } else { - res = DatabaseFeature::DATABASE->dropDatabase(dbName, false, true); + v8::HandleScope scope(isolate); - if (res != TRI_ERROR_NO_ERROR) { - events::DropDatabase(dbName, res); - return Result(res); + // clear collections in cache object + TRI_ClearObjectCacheV8(isolate); + + if (ServerState::instance()->isCoordinator()) { + // If we are a coordinator in a cluster, we have to behave differently: + res = ::dropDBCoordinator(dbName); + } else { + res = DatabaseFeature::DATABASE->dropDatabase(dbName, false, true); + + if (res != TRI_ERROR_NO_ERROR) { + events::DropDatabase(dbName, res); + return Result(res); + } + + TRI_RemoveDatabaseTasksV8Dispatcher(dbName); + // run the garbage collection in case the database held some objects + // which can now be freed + TRI_RunGarbageCollectionV8(isolate, 0.25); + V8DealerFeature::DEALER->addGlobalContextMethod("reloadRouting"); } - - TRI_RemoveDatabaseTasksV8Dispatcher(dbName); - // run the garbage collection in case the database held some objects which - // can now be freed - TRI_RunGarbageCollectionV8(isolate, 0.25); - TRI_ExecuteJavaScriptString( - isolate, isolate->GetCurrentContext(), - TRI_V8_ASCII_STRING( - isolate, - "require('internal').executeGlobalContextFunction('" - "reloadRouting')"), - TRI_V8_ASCII_STRING(isolate, "reload routing"), false); + } catch (arangodb::basics::Exception const& ex) { + events::DropDatabase(dbName, TRI_ERROR_INTERNAL); + return Result(ex.code(), dropError + ex.message()); + } catch (std::exception const& ex) { + events::DropDatabase(dbName, TRI_ERROR_INTERNAL); + return Result(TRI_ERROR_INTERNAL, dropError + ex.what()); + } catch (...) { + events::DropDatabase(dbName, TRI_ERROR_INTERNAL); + return Result(TRI_ERROR_INTERNAL, dropError); } } else { if (ServerState::instance()->isCoordinator()) { @@ -412,7 +419,6 @@ arangodb::Result Databases::drop(TRI_vocbase_t* systemVocbase, std::string const res = ::dropDBCoordinator(dbName); } else { res = DatabaseFeature::DATABASE->dropDatabase(dbName, false, true); - ; } } diff --git a/arangod/VocBase/Methods/Tasks.cpp b/arangod/VocBase/Methods/Tasks.cpp index 6da2265a7c..49fd4ff600 100644 --- a/arangod/VocBase/Methods/Tasks.cpp +++ b/arangod/VocBase/Methods/Tasks.cpp @@ -41,6 +41,7 @@ #include "Utils/ExecContext.h" #include "Utils/OperationOptions.h" #include "Utils/SingleCollectionTransaction.h" +#include "V8/JavaScriptSecurityContext.h" #include "V8/v8-conv.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" @@ -376,18 +377,15 @@ void Task::toVelocyPack(VPackBuilder& builder) const { } void Task::work(ExecContext const* exec) { - auto context = V8DealerFeature::DEALER->enterContext(&(_dbGuard->database()), _allowUseDatabase); - - // note: the context might be 0 in case of shut-down - if (context == nullptr) { - return; - } - - TRI_DEFER(V8DealerFeature::DEALER->exitContext(context)); + JavaScriptSecurityContext securityContext = + _allowUseDatabase + ? JavaScriptSecurityContext::createInternalContext() // internal context that may access internal data + : JavaScriptSecurityContext::createTaskContext(false /*_allowUseDatabase*/); // task context that has no access to dbs + V8ContextGuard guard(&(_dbGuard->database()), securityContext); // now execute the function within this context { - auto isolate = context->_isolate; + auto isolate = guard.isolate(); v8::HandleScope scope(isolate); // get built-in Function constructor (see ECMA-262 5th edition 15.3.2) diff --git a/arangosh/Export/ExportFeature.cpp b/arangosh/Export/ExportFeature.cpp index d1edce37f9..a160f3609b 100644 --- a/arangosh/Export/ExportFeature.cpp +++ b/arangosh/Export/ExportFeature.cpp @@ -237,10 +237,7 @@ void ExportFeature::start() { } // successfully connected - std::cout << "Connected to ArangoDB '" << httpClient->getEndpointSpecification() - << "', version " << httpClient->getServerVersion() - << ", database: '" << client->databaseName() << "', username: '" - << client->username() << "'" << std::endl; + std::cout << ClientFeature::buildConnectedMessage(httpClient->getEndpointSpecification(), httpClient->getServerVersion(), /*role*/ "", /*mode*/ "", client->databaseName(), client->username()) << std::endl; uint64_t exportedSize = 0; diff --git a/arangosh/Import/ImportFeature.cpp b/arangosh/Import/ImportFeature.cpp index 4a7d3c38b5..6c0fcbccd5 100644 --- a/arangosh/Import/ImportFeature.cpp +++ b/arangosh/Import/ImportFeature.cpp @@ -292,10 +292,7 @@ void ImportFeature::start() { bool createdDatabase = false; auto successfulConnection = [&]() { - std::cout << "Connected to ArangoDB '" - << _httpClient->getEndpointSpecification() << "', version " - << versionString << ", database: '" << client->databaseName() - << "', username: '" << client->username() << "'" << std::endl; + std::cout << ClientFeature::buildConnectedMessage(_httpClient->getEndpointSpecification(), versionString, /*role*/ "", /*mode*/ "", client->databaseName(), client->username()) << std::endl; std::cout << "----------------------------------------" << std::endl; std::cout << "database: " << client->databaseName() << std::endl; diff --git a/arangosh/Shell/ClientFeature.cpp b/arangosh/Shell/ClientFeature.cpp index da989405a1..b2085c455c 100644 --- a/arangosh/Shell/ClientFeature.cpp +++ b/arangosh/Shell/ClientFeature.cpp @@ -329,6 +329,20 @@ void ClientFeature::stop() { #endif } +std::string ClientFeature::buildConnectedMessage( + std::string const& endpointSpecification, + std::string const& version, + std::string const& role, + std::string const& mode, + std::string const& databaseName, + std::string const& user +) { + return std::string("Connected to ArangoDB '") + endpointSpecification + + ((version.empty() || version == "arango") ? "" : ", version: " + version) + + (role.empty() ? "" : " [" + role + ", " + mode + "]") + + ", database: '" + databaseName + "', username: '" + user + "'"; +} + int ClientFeature::runMain(int argc, char* argv[], std::function const& mainFunc) { try { diff --git a/arangosh/Shell/ClientFeature.h b/arangosh/Shell/ClientFeature.h index 168fc6ca3a..198cfbb6f4 100644 --- a/arangosh/Shell/ClientFeature.h +++ b/arangosh/Shell/ClientFeature.h @@ -93,6 +93,15 @@ class ClientFeature final : public application_features::ApplicationFeature, bool getWarnConnect() { return _warnConnect; } + static std::string buildConnectedMessage( + std::string const& endpointSpecification, + std::string const& version, + std::string const& role, + std::string const& mode, + std::string const& databaseName, + std::string const& user + ); + static int runMain(int argc, char* argv[], std::function const& mainFunc); diff --git a/arangosh/Shell/V8ClientConnection.cpp b/arangosh/Shell/V8ClientConnection.cpp index 6571f10e02..3b02b5416c 100644 --- a/arangosh/Shell/V8ClientConnection.cpp +++ b/arangosh/Shell/V8ClientConnection.cpp @@ -48,7 +48,7 @@ #include "V8/v8-vpack.h" #include - + using namespace arangodb; using namespace arangodb::application_features; using namespace arangodb::basics; @@ -133,6 +133,11 @@ void V8ClientConnection::createConnection() { _role = role.copyString(); } } + if (!body.hasKey("version")) { + // if we don't get a version number in return, the server is + // probably running in hardened mode + return; + } std::string const versionString = VelocyPackHelper::getStringValue(body, "version", ""); std::pair version = rest::Version::parseVersionString(versionString); @@ -233,11 +238,7 @@ void V8ClientConnection::reconnect(ClientFeature* client) { if (isConnected() && _lastHttpReturnCode == static_cast(rest::ResponseCode::OK)) { LOG_TOPIC("2d416", INFO, arangodb::Logger::FIXME) - << "Connected to ArangoDB " - << "'" << endpointSpecification() << "', " - << "version " << _version << " [" << _role << ", " << _mode << "], " - << "database '" << _databaseName << "', " - << "username: '" << client->username() << "'"; + << ClientFeature::buildConnectedMessage(endpointSpecification(), _version, _role, _mode, _databaseName, client->username()); } else { if (client->getWarnConnect()) { LOG_TOPIC("9d7ea", ERR, arangodb::Logger::FIXME) @@ -359,18 +360,15 @@ static void ClientConnection_ConstructorCallback(v8::FunctionCallbackInfoisConnected() && v8connection->lastHttpReturnCode() == (int)rest::ResponseCode::OK) { LOG_TOPIC("9c8b4", INFO, arangodb::Logger::FIXME) - << "Connected to ArangoDB " - << "'" << v8connection->endpointSpecification() << "', " - << "version " << v8connection->version() << " [" << v8connection->role() << ", " << v8connection->mode() << "], " - << "database '" << v8connection->databaseName() << "', " - << "username: '" << v8connection->username() << "'"; - + << ClientFeature::buildConnectedMessage(v8connection->endpointSpecification(), v8connection->version(), + v8connection->role(), v8connection->mode(), v8connection->databaseName(), + v8connection->username()); } else { std::string errorMessage = "Could not connect. Error message: " + v8connection->lastErrorMessage(); TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_SIMPLE_CLIENT_COULD_NOT_CONNECT, - errorMessage.c_str()); + errorMessage); } TRI_V8_RETURN(WrapV8ClientConnection(isolate, v8connection.release())); diff --git a/arangosh/Shell/V8ShellFeature.cpp b/arangosh/Shell/V8ShellFeature.cpp index 354725dcdc..2ac32a027c 100644 --- a/arangosh/Shell/V8ShellFeature.cpp +++ b/arangosh/Shell/V8ShellFeature.cpp @@ -24,6 +24,7 @@ #include "ApplicationFeatures/ShellColorsFeature.h" #include "ApplicationFeatures/V8PlatformFeature.h" +#include "ApplicationFeatures/V8SecurityFeature.h" #include "Basics/ArangoGlobalContext.h" #include "Basics/FileUtils.h" #include "Basics/StringUtils.h" @@ -42,6 +43,7 @@ #include "V8/V8LineEditor.h" #include "V8/v8-buffer.h" #include "V8/v8-conv.h" +#include "V8/v8-globals.h" #include "V8/v8-shell.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" @@ -78,6 +80,7 @@ V8ShellFeature::V8ShellFeature(application_features::ApplicationServer& server, startsAfter("BasicsPhase"); startsAfter("Console"); startsAfter("V8Platform"); + startsAfter("V8Security"); startsAfter("Random"); } @@ -95,7 +98,7 @@ void V8ShellFeature::collectOptions(std::shared_ptr options) { options->addOption( "--javascript.copy-directory", - "target directory to copy files from 'javascript.startup-directory' into" + "target directory to copy files from 'javascript.startup-directory' into " "(only used when `--javascript.copy-installation` is enabled)", new StringParameter(&_copyDirectory)); @@ -151,6 +154,11 @@ void V8ShellFeature::start() { v8::Isolate::Scope isolate_scope(_isolate); v8::HandleScope handle_scope(_isolate); + auto* isolate = _isolate; + TRI_GET_GLOBALS(); + v8g = TRI_CreateV8Globals(isolate); + v8g->_securityContext = arangodb::JavaScriptSecurityContext::createAdminScriptContext(); + // create the global template v8::Local global = v8::ObjectTemplate::New(_isolate); @@ -340,14 +348,11 @@ bool V8ShellFeature::printHello(V8ClientConnection* v8connection) { if (v8connection != nullptr) { if (v8connection->isConnected() && v8connection->lastHttpReturnCode() == (int)rest::ResponseCode::OK) { - std::ostringstream is; - - is << "Connected to ArangoDB '" << v8connection->endpointSpecification() - << "' version: " << v8connection->version() << " [" << v8connection->role() << ", " - << v8connection->mode() << "], database: '" << v8connection->databaseName() - << "', username: '" << v8connection->username() << "'"; - - _console->printLine(is.str()); + std::string msg = ClientFeature::buildConnectedMessage( + v8connection->endpointSpecification(), v8connection->version(), + v8connection->role(), v8connection->mode(), v8connection->databaseName(), + v8connection->username()); + _console->printLine(msg); if (v8connection->role() == "PRIMARY" || v8connection->role() == "DBSERVER") { std::string msg("WARNING: You connected to a DBServer node, but operations in a cluster should be carried out via a Coordinator"); @@ -998,6 +1003,10 @@ void V8ShellFeature::initGlobals() { ctx->normalizePath(_startupDirectory, "javascript.startup-directory", true); ctx->normalizePath(_moduleDirectories, "javascript.module-directory", false); + V8SecurityFeature* v8security = + application_features::ApplicationServer::getFeature( + "V8Security"); + // try to append the current version name to the startup directory, // so instead of "/path/to/js" we will get "/path/to/js/3.4.0" std::string const versionAppendix = @@ -1013,6 +1022,7 @@ void V8ShellFeature::initGlobals() { // version-specific js path exists! _startupDirectory = versionedPath; } + v8security->addToInternalWhitelist(_startupDirectory, FSAccessType::READ); for (auto& it : _moduleDirectories) { versionedPath = basics::FileUtils::buildFilename(it, versionAppendix); @@ -1024,6 +1034,7 @@ void V8ShellFeature::initGlobals() { // version-specific js path exists! it = versionedPath; } + v8security->addToInternalWhitelist(it, FSAccessType::READ); //expand } LOG_TOPIC("930d9", DEBUG, Logger::V8) @@ -1053,6 +1064,7 @@ void V8ShellFeature::initGlobals() { if (_currentModuleDirectory) { modules += sep + FileUtils::currentDirectory().result(); + v8security->addToInternalWhitelist(FileUtils::currentDirectory().result(), FSAccessType::READ); } // we take the last entry in _startupDirectory as global path; diff --git a/arangosh/Shell/arangosh.cpp b/arangosh/Shell/arangosh.cpp index 8958f44f15..2d035f57e0 100644 --- a/arangosh/Shell/arangosh.cpp +++ b/arangosh/Shell/arangosh.cpp @@ -33,6 +33,7 @@ #include "ApplicationFeatures/ShutdownFeature.h" #include "ApplicationFeatures/TempFeature.h" #include "ApplicationFeatures/V8PlatformFeature.h" +#include "ApplicationFeatures/V8SecurityFeature.h" #include "ApplicationFeatures/V8ShellPhase.h" #include "ApplicationFeatures/VersionFeature.h" #include "Basics/ArangoGlobalContext.h" @@ -80,6 +81,7 @@ int main(int argc, char* argv[]) { // server.addFeature(new SslFeature(server)); server.addFeature(new TempFeature(server, name)); server.addFeature(new V8PlatformFeature(server)); + server.addFeature(new V8SecurityFeature(server)); server.addFeature(new V8ShellFeature(server, name)); server.addFeature(new VersionFeature(server)); diff --git a/arangosh/Utils/ClientManager.cpp b/arangosh/Utils/ClientManager.cpp index 84a305650e..765469fb30 100644 --- a/arangosh/Utils/ClientManager.cpp +++ b/arangosh/Utils/ClientManager.cpp @@ -110,6 +110,11 @@ Result ClientManager::getConnectedClient(std::unique_ptr'+t+""),e.disabled||$("#subNavigationBar .bottom").children().last().bind("click",function(){window.App.navigate(e.route,{trigger:!0})})})},buildUserSubNav:function(e,t){var i={General:{route:"#user/"+encodeURIComponent(e)},Permissions:{route:"#user/"+encodeURIComponent(e)+"/permission"}};i[t].active=!0,this.buildSubNavBar(i)},buildGraphSubNav:function(e,t){var i={Content:{route:"#graph/"+encodeURIComponent(e)},Settings:{route:"#graph/"+encodeURIComponent(e)+"/settings"}};i[t].active=!0,this.buildSubNavBar(i)},buildNodeSubNav:function(e,t,i){var n={Dashboard:{route:"#node/"+encodeURIComponent(e)}};n[t].active=!0,n[i].disabled=!0,this.buildSubNavBar(n)},buildNodesSubNav:function(e,t){var i={Overview:{route:"#nodes"},Shards:{route:"#shards"}};i[e].active=!0,t&&(i[t].disabled=!0),this.buildSubNavBar(i)},buildServicesSubNav:function(e,t){var i={Store:{route:"#services/install"},Upload:{route:"#services/install/upload"},New:{route:"#services/install/new"},GitHub:{route:"#services/install/github"},Remote:{route:"#services/install/remote"}};i[e].active=!0,t&&(i[t].disabled=!0),this.buildSubNavBar(i)},scaleability:void 0,buildCollectionSubNav:function(e,t){var i={Content:{route:"#collection/"+encodeURIComponent(e)+"/documents/1"},Indexes:{route:"#cIndices/"+encodeURIComponent(e)},Info:{route:"#cInfo/"+encodeURIComponent(e)},Settings:{route:"#cSettings/"+encodeURIComponent(e)}};i[t].active=!0,this.buildSubNavBar(i)},enableKeyboardHotkeys:function(e){var t=window.arangoHelper.hotkeysFunctions;!0===e&&($(document).on("keydown",null,"j",t.scrollDown),$(document).on("keydown",null,"k",t.scrollUp))},databaseAllowed:function(i){var e=function(e,t){e?arangoHelper.arangoError("",""):$.ajax({type:"GET",cache:!1,url:this.databaseUrl("/_api/database/",t),contentType:"application/json",processData:!1,success:function(){i(!1,!0)},error:function(){i(!0,!1)}})}.bind(this);this.currentDatabase(e)},arangoNotification:function(e,t,i){window.App.notificationList.add({title:e,content:t,info:i,type:"success"})},arangoError:function(e,t,i){$("#offlinePlaceholder").is(":visible")||window.App.notificationList.add({title:e,content:t,info:i,type:"error"})},arangoWarning:function(e,t,i){window.App.notificationList.add({title:e,content:t,info:i,type:"warning"})},arangoMessage:function(e,t,i){window.App.notificationList.add({title:e,content:t,info:i,type:"message"})},hideArangoNotifications:function(){$.noty.clearQueue(),$.noty.closeAll()},openDocEditor:function(e,t,i){var n=e.split("/"),o=this,a=new window.DocumentView({collection:window.App.arangoDocumentStore});a.breadcrumb=function(){},a.colid=n[0],a.docid=n[1],a.el=".arangoFrame .innerDiv",a.render(),a.setType(t),$(".arangoFrame .headerBar").remove(),$(".arangoFrame .outerDiv").prepend(''),$(".arangoFrame .outerDiv").click(function(){o.closeDocEditor()}),$(".arangoFrame .innerDiv").click(function(e){e.stopPropagation()}),$(".fa-times").click(function(){o.closeDocEditor()}),$(".arangoFrame").show(),a.customView=!0,a.customDeleteFunction=function(){window.modalView.hide(),$(".arangoFrame").hide()},a.customSaveFunction=function(e){o.closeDocEditor(),i&&i(e)},$(".arangoFrame #deleteDocumentButton").click(function(){a.deleteDocumentModal()}),$(".arangoFrame #saveDocumentButton").click(function(){a.saveDocument()}),$(".arangoFrame #deleteDocumentButton").css("display","none")},closeDocEditor:function(){$(".arangoFrame .outerDiv .fa-times").remove(),$(".arangoFrame").hide()},addAardvarkJob:function(e,t){$.ajax({cache:!1,type:"POST",url:this.databaseUrl("/_admin/aardvark/job"),data:JSON.stringify(e),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},deleteAardvarkJob:function(e,t){$.ajax({cache:!1,type:"DELETE",url:this.databaseUrl("/_admin/aardvark/job/"+encodeURIComponent(e)),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},deleteAllAardvarkJobs:function(t){$.ajax({cache:!1,type:"DELETE",url:this.databaseUrl("/_admin/aardvark/job"),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},getAardvarkJobs:function(t){$.ajax({cache:!1,type:"GET",url:this.databaseUrl("/_admin/aardvark/job"),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},getPendingJobs:function(t){$.ajax({cache:!1,type:"GET",url:this.databaseUrl("/_api/job/pending"),contentType:"application/json",processData:!1,success:function(e){t(!1,e)},error:function(e){t(!0,e)}})},syncAndReturnUnfinishedAardvarkJobs:function(a,r){var e=function(e,t){if(e)r(!0);else{var i=function(e,n){if(e)arangoHelper.arangoError("","");else{var o=[];0/g,">").replace(/"/g,""").replace(/'/g,"'")},backendUrl:function(e){return frontendConfig.basePath+e},databaseUrl:function(e,t){if("/_db/"===e.substr(0,5))throw new Error("Calling databaseUrl with a databased url ("+e+") doesn't make any sense");return t||(t="_system",frontendConfig.db&&(t=frontendConfig.db)),this.backendUrl("/_db/"+encodeURIComponent(t)+e)},showAuthDialog:function(){var e=!0;return"false"===localStorage.getItem("authenticationNotification")&&(e=!1),e},doNotShowAgain:function(){localStorage.setItem("authenticationNotification",!1)},renderEmpty:function(e,t){t?$("#content").html(''):$("#content").html('")},initSigma:function(){try{sigma.classes.graph.addMethod("neighbors",function(e){var t,i={},n=this.allNeighborsIndex[e]||{};for(t in n)i[t]=this.nodesIndex[t];return i}),sigma.classes.graph.addMethod("getNodeEdges",function(t){var e=this.edges(),i=[];return _.each(e,function(e){e.source!==t&&e.target!==t||i.push(e.id)}),i}),sigma.classes.graph.addMethod("getNodeEdgesCount",function(e){return this.allNeighborsCount[e]}),sigma.classes.graph.addMethod("getNodesCount",function(){return this.nodesArray.length})}catch(e){}},downloadLocalBlob:function(e,t){var i;if("csv"===t&&(i="text/csv; charset=utf-8"),"json"===t&&(i="application/json; charset=utf-8"),i){var n=new Blob([e],{type:i}),o=window.URL.createObjectURL(n),a=document.createElement("a");document.body.appendChild(a),a.style="display: none",a.href=o,a.download="results-"+window.frontendConfig.db+"."+t,a.click(),window.setTimeout(function(){window.URL.revokeObjectURL(o),document.body.removeChild(a)},500)}},download:function(e,r){$.ajax(e).success(function(e,t,i){if(r)r(e);else{var n=new Blob([JSON.stringify(e)],{type:i.getResponseHeader("Content-Type")||"application/octet-stream"}),o=window.URL.createObjectURL(n),a=document.createElement("a");document.body.appendChild(a),a.style="display: none",a.href=o,a.download=i.getResponseHeader("Content-Disposition").replace(/.* filename="([^")]*)"/,"$1"),a.click(),window.setTimeout(function(){window.URL.revokeObjectURL(o),document.body.removeChild(a)},500)}})},downloadPost:function(e,t,i,n){var o=new XMLHttpRequest;o.onreadystatechange=function(){if(4===this.readyState&&200===this.status){i&&i();var e=document.createElement("a");e.download=this.getResponseHeader("Content-Disposition").replace(/.* filename="([^")]*)"/,"$1"),document.body.appendChild(e);var t=window.URL.createObjectURL(this.response);e.href=t,e.click(),window.setTimeout(function(){window.URL.revokeObjectURL(t),document.body.removeChild(e)},500)}else 4===this.readyState&&void 0!==n&&n(this.status,this.statusText)},o.open("POST",e),window.arangoHelper.getCurrentJwt()&&o.setRequestHeader("Authorization","bearer "+window.arangoHelper.getCurrentJwt()),o.responseType="blob",o.send(t)},checkCollectionPermissions:function(e,t){var i=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(window.App.userCollection.activeUser)+"/database/"+encodeURIComponent(frontendConfig.db)+"/"+encodeURIComponent(e));$.ajax({type:"GET",url:i,contentType:"application/json",success:function(e){"ro"===e.result&&t()},error:function(e){arangoHelper.arangoError("User","Could not fetch collection permissions.")}})},checkDatabasePermissions:function(t,i){var e=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(window.App.userCollection.activeUser)+"/database/"+encodeURIComponent(frontendConfig.db));$.ajax({type:"GET",url:e,contentType:"application/json",success:function(e){"ro"===e.result?t&&t(!0):"rw"===e.result?i&&i(!1):"none"===e.result&&(frontendConfig.authenticationEnabled||i&&i(!1))},error:function(e){arangoHelper.arangoError("User","Could not fetch collection permissions.")}})},getFoxxFlag:function(){var e;return $("#new-app-replace").prop("checked")?e=!0:$("#new-app-teardown").prop("checked")&&(e=!1),e},createMountPointModal:function(e,t,i){var n,o=[],a=[];window.App.replaceApp&&(n=(n=window.App.replaceAppData.mount).substr(1,n.length)),a.push(window.modalView.createTextEntry("new-app-mount","Mount point",n,"The path the app will be mounted. Is not allowed to start with _","mountpoint",!1,[{rule:Joi.string().required(),msg:""}])),a.push(window.modalView.createCheckboxEntry("new-app-teardown","Run setup?",!0,"Should this app's setup script be executed after installing the app?",!0)),window.App.replaceApp?(a.push(window.modalView.createCheckboxEntry("new-app-replace","Keep configuration and dependency files?",!0,"Should this app's configuration be saved before replacing the app?",!1)),o.push(window.modalView.createSuccessButton("Replace",e))):o.push(window.modalView.createSuccessButton("Install",e));var r="Create Foxx Service";window.App.replaceApp&&(r="Replace Foxx Service ("+window.App.replaceAppData.mount+")"),window.modalView.show("modalTable.ejs",r,o,a),window.App.replaceApp?($("#new-app-mount").attr("disabled","true"),$("#new-app-replace").attr("checked",!1),$("#new-app-replace").on("click",function(){$("#new-app-replace").prop("checked")?$("#new-app-teardown").attr("disabled",!0):$("#new-app-teardown").attr("disabled",!1)})):window.modalView.modalBindValidation({id:"new-app-mount",validateInput:function(){return[{rule:Joi.string().regex(/(\/|^)APP(\/|$)/i,{invert:!0}),msg:"May not contain APP"},{rule:Joi.string().regex(/^([a-zA-Z0-9_\-/]+)+$/),msg:"Can only contain [a-zA-Z0-9_-/]"},{rule:Joi.string().regex(/([^_]|_open\/)/),msg:"Mountpoints with _ are reserved for internal use"},{rule:Joi.string().regex(/[^/]$/),msg:"May not end with /"},{rule:Joi.string().required().min(1),msg:"Has to be non-empty"}]}})}}}(),function(){"use strict";if(!window.hasOwnProperty("TEST_BUILD")){window.templateEngine=new function(){var e={createTemplate:function(e){var i=$("#"+e.replace(".","\\.")).html();return{render:function(e){var t=_.template(i);return t=t(e)}}}};return e}}}(),function(){"use strict";window.dygraphConfig={defaultFrame:12e5,zeropad:function(e){return e<10?"0"+e:e},xAxisFormat:function(e){if(-1===e)return"";var t=new Date(e);return this.zeropad(t.getHours())+":"+this.zeropad(t.getMinutes())+":"+this.zeropad(t.getSeconds())},mergeObjects:function(n,o,e){e||(e=[]);var t,a={};return e.forEach(function(e){var t=n[e],i=o[e];void 0===t&&(t={}),void 0===i&&(i={}),a[e]=_.extend(t,i)}),t=_.extend(n,o),Object.keys(a).forEach(function(e){t[e]=a[e]}),t},mapStatToFigure:{pageFaults:["times","majorPageFaultsPerSecond","minorPageFaultsPerSecond"],systemUserTime:["times","systemTimePerSecond","userTimePerSecond"],totalTime:["times","avgQueueTime","avgRequestTime","avgIoTime"],dataTransfer:["times","bytesSentPerSecond","bytesReceivedPerSecond"],requests:["times","getsPerSecond","putsPerSecond","postsPerSecond","deletesPerSecond","patchesPerSecond","headsPerSecond","optionsPerSecond","othersPerSecond"]},colors:["rgb(95, 194, 135)","rgb(238, 190, 77)","#81ccd8","#7ca530","#3c3c3c","#aa90bd","#e1811d","#c7d4b2","#d0b2d4"],figureDependedOptions:{clusterRequestsPerSecond:{showLabelsOnHighlight:!0,title:"",header:"Cluster Requests per Second",stackedGraph:!0,div:"lineGraphLegend",labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}},pageFaults:{header:"Page Faults",visibility:[!0,!1],labels:["datetime","Major Page","Minor Page"],div:"pageFaultsChart",labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}},systemUserTime:{div:"systemUserTimeChart",header:"System and User Time",labels:["datetime","System Time","User Time"],stackedGraph:!0,labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}},totalTime:{div:"totalTimeChart",header:"Total Time",labels:["datetime","Queue","Computation","I/O"],labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}},stackedGraph:!0},dataTransfer:{header:"Data Transfer",labels:["datetime","Bytes sent","Bytes received"],stackedGraph:!0,div:"dataTransferChart"},requests:{header:"Requests",labels:["datetime","Reads","Writes"],stackedGraph:!0,div:"requestsChart",axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}}},getDashBoardFigures:function(t){var i=[],n=this;return Object.keys(this.figureDependedOptions).forEach(function(e){"clusterRequestsPerSecond"!==e&&(n.figureDependedOptions[e].div||t)&&i.push(e)}),i},getDefaultConfig:function(e){var t=this,i={digitsAfterDecimal:1,drawGapPoints:!0,fillGraph:!0,fillAlpha:.85,showLabelsOnHighlight:!1,strokeWidth:0,lineWidth:0,strokeBorderWidth:0,includeZero:!0,highlightCircleSize:2.5,labelsSeparateLines:!0,strokeBorderColor:"rgba(0,0,0,0)",interactionModel:{},maxNumberWidth:10,colors:[this.colors[0]],xAxisLabelWidth:"50",rightGap:15,showRangeSelector:!1,rangeSelectorHeight:50,rangeSelectorPlotStrokeColor:"#365300",rangeSelectorPlotFillColor:"",pixelsPerLabel:50,labelsKMG2:!0,dateWindow:[(new Date).getTime()-this.defaultFrame,(new Date).getTime()],axes:{x:{valueFormatter:function(e){return t.xAxisFormat(e)}},y:{ticker:Dygraph.numericLinearTicks}}};return this.figureDependedOptions[e]&&(i=this.mergeObjects(i,this.figureDependedOptions[e],["axes"])).div&&i.labels&&(i.colors=this.getColors(i.labels),i.labelsDiv=document.getElementById(i.div+"Legend"),i.legend="always",i.showLabelsOnHighlight=!0),i},getDetailChartConfig:function(e){var t=_.extend(this.getDefaultConfig(e),{showRangeSelector:!0,interactionModel:null,showLabelsOnHighlight:!0,highlightCircleSize:2.5,legend:"always",labelsDiv:"div#detailLegend.dashboard-legend-inner"});return"pageFaults"===e&&(t.visibility=[!0,!0]),t.labels||(t.labels=["datetime",t.header],t.colors=this.getColors(t.labels)),t},getColors:function(e){return this.colors.concat([]).slice(0,e.length-1)}}}(),function(){"use strict";window.arangoCollectionModel=Backbone.Model.extend({idAttribute:"name",urlRoot:arangoHelper.databaseUrl("/_api/collection"),defaults:{id:"",name:"",status:"",type:"",isSystem:!1,picture:"",locked:!1,desc:void 0},getProperties:function(t){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/collection/"+encodeURIComponent(this.get("id"))+"/properties"),contentType:"application/json",processData:!1,success:function(e){t(!1,e)},error:function(e){t(!0,e)}})},getFigures:function(t){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/figures"),contentType:"application/json",processData:!1,success:function(e){t(!1,e)},error:function(){t(!0)}})},getRevision:function(t,i){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/revision"),contentType:"application/json",processData:!1,success:function(e){t(!1,e,i)},error:function(){t(!0)}})},getIndex:function(t){var i=this;$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/index/?collection="+this.get("id")),contentType:"application/json",processData:!1,success:function(e){t(!1,e,i.get("id"))},error:function(e){t(!0,e,i.get("id"))}})},createIndex:function(e,n){var o=this;$.ajax({cache:!1,type:"POST",url:arangoHelper.databaseUrl("/_api/index?collection="+o.get("id")),headers:{"x-arango-async":"store"},data:JSON.stringify(e),contentType:"application/json",processData:!1,success:function(e,t,i){i.getResponseHeader("x-arango-async-id")?(window.arangoHelper.addAardvarkJob({id:i.getResponseHeader("x-arango-async-id"),type:"index",desc:"Creating Index",collection:o.get("id")}),n(!1,e)):n(!0,e)},error:function(e){n(!0,e)}})},deleteIndex:function(e,n){var o=this;$.ajax({cache:!1,type:"DELETE",url:arangoHelper.databaseUrl("/_api/index/"+this.get("name")+"/"+encodeURIComponent(e)),headers:{"x-arango-async":"store"},success:function(e,t,i){i.getResponseHeader("x-arango-async-id")?(window.arangoHelper.addAardvarkJob({id:i.getResponseHeader("x-arango-async-id"),type:"index",desc:"Removing Index",collection:o.get("id")}),n(!1,e)):n(!0,e)},error:function(e){n(!0,e)}}),n()},truncateCollection:function(){var e=this;$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/truncate"),success:function(){arangoHelper.arangoNotification("Collection truncated."),$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_admin/wal/flush?waitForSync=true&waitForCollector=true"),success:function(){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+e.get("id")+"/rotate"),success:function(){},error:function(){}})},error:function(){}})},error:function(e){arangoHelper.arangoError("Collection error: "+e.responseJSON.errorMessage)}})},warmupCollection:function(){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/loadIndexesIntoMemory"),success:function(){arangoHelper.arangoNotification("Loading indexes into memory.")},error:function(e){arangoHelper.arangoError("Collection error: "+e.responseJSON.errorMessage)}})},loadCollection:function(e){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/load"),success:function(){e(!1)},error:function(){e(!0)}}),e()},unloadCollection:function(e){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/unload?flush=true"),success:function(){e(!1)},error:function(){e(!0)}}),e()},renameCollection:function(e,t){var i=this;$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/rename"),data:JSON.stringify({name:e}),contentType:"application/json",processData:!1,success:function(){i.set("name",e),t(!1)},error:function(e){t(!0,e)}})},changeCollection:function(e,t,i,n,o){"true"===e?e=!0:"false"===e&&(e=!1);var a={waitForSync:e,journalSize:parseInt(t,10),indexBuckets:parseInt(i,10)};return n&&(a.replicationFactor=parseInt(n,10)),$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/properties"),data:JSON.stringify(a),contentType:"application/json",processData:!1,success:function(){o(!1)},error:function(e){o(!0,e)}}),!1}})}(),window.DatabaseModel=Backbone.Model.extend({idAttribute:"name",initialize:function(){},isNew:function(){"use strict";return!1},sync:function(e,t,i){"use strict";return"update"===e&&(e="create"),Backbone.sync(e,t,i)},url:arangoHelper.databaseUrl("/_api/database"),defaults:{}}),window.arangoDocumentModel=Backbone.Model.extend({initialize:function(){},urlRoot:arangoHelper.databaseUrl("/_api/document"),defaults:{_id:"",_rev:"",_key:""},getSorted:function(){"use strict";var t=this,e=Object.keys(t.attributes).sort(function(e,t){var i=arangoHelper.isSystemAttribute(e);return i!==arangoHelper.isSystemAttribute(t)?i?-1:1:e=this.getLastPageNumber()&&null!==this.totalAmount?this.page=this.getLastPageNumber()-1:this.page=e<1?0:e-1},getLastPageNumber:function(){return Math.max(Math.ceil(this.totalAmount/this.pagesize),1)},getOffset:function(){return this.page*this.pagesize},getPageSize:function(){return this.pagesize},setPageSize:function(e){if("all"===e)this.pagesize="all";else try{e=parseInt(e,10),this.pagesize=e}catch(e){}},setToFirst:function(){this.page=0},setToLast:function(){this.setPage(this.getLastPageNumber())},setToPrev:function(){this.setPage(this.getPage()-1)},setToNext:function(){this.setPage(this.getPage()+1)},setTotal:function(e){this.totalAmount=e},getTotal:function(){return this.totalAmount},setTotalMinusOne:function(){this.totalAmount--}})}(),window.ClusterStatisticsCollection=Backbone.Collection.extend({model:window.Statistics,url:"/_admin/statistics",updateUrl:function(){this.url=window.App.getNewRoute(this.host)+this.url},initialize:function(e,t){this.host=t.host,window.App.registerForUpdate(this)}}),function(){"use strict";window.ArangoCollections=Backbone.Collection.extend({url:arangoHelper.databaseUrl("/_api/collection"),model:arangoCollectionModel,searchOptions:{searchPhrase:null,includeSystem:!1,includeDocument:!0,includeEdge:!0,includeLoaded:!0,includeUnloaded:!0,sortBy:"name",sortOrder:1},translateStatus:function(e){switch(e){case 0:return"corrupted";case 1:return"new born collection";case 2:return"unloaded";case 3:return"loaded";case 4:return"unloading";case 5:return"deleted";case 6:return"loading";default:return"unknown"}},translateTypePicture:function(e){var t="";switch(e){case"document":t+="fa-file-text-o";break;case"edge":t+="fa-share-alt";break;case"unknown":t+="fa-question";break;default:t+="fa-cogs"}return t},parse:function(e){var t=this;return _.each(e.result,function(e){e.isSystem=arangoHelper.isSystemCollection(e),e.type=arangoHelper.collectionType(e),e.status=t.translateStatus(e.status),e.picture=t.translateTypePicture(e.type)}),e.result},getPosition:function(e){var t,i=this.getFiltered(this.searchOptions),n=null,o=null;for(t=0;t
  • '),$(this.paginationDiv).append('
    ')}})}(),function(){"use strict";window.ApplicationDetailView=Backbone.View.extend({el:"#content",divs:["#readme","#swagger","#app-info","#sideinformation","#information","#settings"],navs:["#service-info","#service-api","#service-readme","#service-settings"],template:templateEngine.createTemplate("serviceDetailView.ejs"),remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click .open":"openApp","click .delete":"deleteApp","click #app-deps":"showDepsDialog","click #app-switch-mode":"toggleDevelopment","click #app-scripts [data-script]":"runScript","click #app-tests":"runTests","click #app-replace":"replaceApp","click #download-app":"downloadApp","click .subMenuEntries li":"changeSubview","click #jsonLink":"toggleSwagger","mouseenter #app-scripts":"showDropdown","mouseleave #app-scripts":"hideDropdown"},resize:function(e){e?$(".innerContent").css("height","auto"):($(".innerContent").height($(".centralRow").height()-150),$("#swagger iframe").height($(".centralRow").height()-150),$("#swagger #swaggerJsonContent").height($(".centralRow").height()-150))},toggleSwagger:function(){var e=function(e){$("#jsonLink").html("JSON"),this.jsonEditor.setValue(JSON.stringify(e,null,"\t"),1),$("#swaggerJsonContent").show(),$("#swagger iframe").hide()}.bind(this);if("Swagger"===$("#jsonLink").html()){var t=arangoHelper.databaseUrl("/_admin/aardvark/foxxes/docs/swagger.json?mount="+encodeURIComponent(this.model.get("mount")));arangoHelper.download(t,e)}else $("#swaggerJsonContent").hide(),$("#swagger iframe").show(),$("#jsonLink").html("Swagger")},changeSubview:function(e){if(_.each(this.navs,function(e){$(e).removeClass("active")}),$(e.currentTarget).addClass("active"),_.each(this.divs,function(e){$(".headerButtonBar").hide(),$(e).hide()}),"service-readme"===e.currentTarget.id)this.resize(!0),$("#readme").show();else if("service-api"===e.currentTarget.id){this.resize(),$("#swagger").show(),$("#swaggerIframe").remove();var t=window.location.pathname.split("/"),i=window.location.protocol+"//"+window.location.hostname+":"+window.location.port+"/"+t[1]+"/"+t[2]+"/_admin/aardvark/foxxes/docs/index.html?mount="+this.model.get("mount"),n=$("')},toggleViews:function(e){var t=this,i=e.currentTarget.id.split("-")[0];_.each(["community","documentation","swagger"],function(e){i!==e?$("#"+e).hide():("swagger"===i?(t.renderSwagger(),$("#swagger iframe").css("height","100%"),$("#swagger iframe").css("width","100%"),$("#swagger iframe").css("margin-top","-13px"),t.resize()):t.resize(!0),$("#"+e).show())}),$(".subMenuEntries").children().removeClass("active"),$("#"+i+"-support").addClass("active")}})}(),function(){"use strict";window.TableView=Backbone.View.extend({template:templateEngine.createTemplate("tableView.ejs"),loading:templateEngine.createTemplate("loadingTableView.ejs"),initialize:function(e){this.rowClickCallback=e.rowClick},events:{"click .pure-table-body .pure-table-row":"rowClick","click .deleteButton":"removeClick"},rowClick:function(e){this.hasOwnProperty("rowClickCallback")&&this.rowClickCallback(e)},removeClick:function(e){this.hasOwnProperty("removeClickCallback")&&(this.removeClickCallback(e),e.stopPropagation())},setRowClick:function(e){this.rowClickCallback=e},setRemoveClick:function(e){this.removeClickCallback=e},render:function(){$(this.el).html(this.template.render({docs:this.collection}))},drawLoading:function(){$(this.el).html(this.loading.render({}))}})}(),function(){"use strict";window.UserBarView=Backbone.View.extend({events:{"change #userBarSelect":"navigateBySelect","click .tab":"navigateByTab","mouseenter .dropdown":"showDropdown","mouseleave .dropdown":"hideDropdown","click #userLogoutIcon":"userLogout","click #userLogout":"userLogout"},initialize:function(e){arangoHelper.checkDatabasePermissions(this.setUserCollectionMode.bind(this)),this.userCollection=e.userCollection,this.userCollection.fetch({cache:!1,async:!0}),this.userCollection.bind("change:extra",this.render.bind(this))},setUserCollectionMode:function(e){e&&(this.userCollection.authOptions.ro=!0)},template:templateEngine.createTemplate("userBarView.ejs"),navigateBySelect:function(){var e=$("#arangoCollectionSelect").find("option:selected").val();window.App.navigate(e,{trigger:!0})},navigateByTab:function(e){var t=e.target||e.srcElement,i=(t=$(t).closest("a")).attr("id");if("user"===i)return $("#user_dropdown").slideToggle(200),void e.preventDefault();window.App.navigate(i,{trigger:!0}),e.preventDefault()},toggleUserMenu:function(){$("#userBar .subBarDropdown").toggle()},showDropdown:function(){$("#user_dropdown").fadeIn(1)},hideDropdown:function(){$("#user_dropdown").fadeOut(1)},render:function(){if(!1!==frontendConfig.authenticationEnabled){var s=this;$("#userBar").on("click",function(){s.toggleUserMenu()}),this.userCollection.whoAmI(function(e,t){if(e)arangoHelper.arangoErro("User","Could not fetch user.");else{var i=null,n=null,o=!1,a=null;if(!1!==t){var r=function(){return frontendConfig.ldapEnabled&&s.userCollection.add({name:window.App.currentUser,user:window.App.currentUser,username:window.App.currentUser,active:!0,img:void 0}),(a=s.userCollection.findWhere({user:t})).set({loggedIn:!0}),n=a.get("extra").name,i=a.get("extra").img,o=a.get("active"),i=i?"https://s.gravatar.com/avatar/"+i+"?s=80":"img/default_user.png",n||(n=""),s.$el=$("#userBar"),s.$el.html(s.template.render({img:i,name:n,username:t,active:o})),s.delegateEvents(),s.$el};0===s.userCollection.models.length?s.userCollection.fetch({success:function(){r()}}):r()}}})}},userLogout:function(){var e=function(e){e?arangoHelper.arangoError("User","Logout error"):this.userCollection.logout()}.bind(this);this.userCollection.whoAmI(e)}})}(),function(){"use strict";window.UserManagementView=Backbone.View.extend({el:"#content",el2:"#userManagementThumbnailsIn",template:templateEngine.createTemplate("userManagementView.ejs"),remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click #createUser":"createUser","click #submitCreateUser":"submitCreateUser","click #userManagementThumbnailsIn .tile":"editUser","click #submitEditUser":"submitEditUser","click #userManagementToggle":"toggleView","keyup #userManagementSearchInput":"search","click #userManagementSearchSubmit":"search","click #callEditUserPassword":"editUserPassword","click #submitEditUserPassword":"submitEditUserPassword","click #submitEditCurrentUserProfile":"submitEditCurrentUserProfile","click .css-label":"checkBoxes","change #userSortDesc":"sorting"},dropdownVisible:!1,initialize:function(){var e=this,t=function(e,t){!0===frontendConfig.authenticationEnabled&&(e||null===t?arangoHelper.arangoError("User","Could not fetch user data"):this.currentUser=this.collection.findWhere({user:t}))}.bind(this);this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){e.collection.whoAmI(t)}})},checkBoxes:function(e){var t=e.currentTarget.id;$("#"+t).click()},sorting:function(){$("#userSortDesc").is(":checked")?this.collection.setSortingDesc(!0):this.collection.setSortingDesc(!1),$("#userManagementDropdown").is(":visible")?this.dropdownVisible=!0:this.dropdownVisible=!1,this.render()},render:function(e){var t=!1;$("#userManagementDropdown").is(":visible")&&(t=!0);var i=function(){this.collection.sort(),$(this.el).html(this.template.render({collection:this.collection,searchString:""})),!0===t&&($("#userManagementDropdown2").show(),$("#userSortDesc").attr("checked",this.collection.sortOptions.desc),$("#userManagementToggle").toggleClass("activated"),$("#userManagementDropdown").show()),e&&this.editCurrentUser(),arangoHelper.setCheckboxStatus("#userManagementDropdown")}.bind(this);return this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){i()}}),this},search:function(){var e,t,i,n;e=$("#userManagementSearchInput"),t=arangoHelper.escapeHtml($("#userManagementSearchInput").val()),n=this.collection.filter(function(e){return-1!==e.get("user").indexOf(t)}),$(this.el).html(this.template.render({collection:n,searchString:t})),i=(e=$("#userManagementSearchInput")).val().length,e.focus(),e[0].setSelectionRange(i,i)},createUser:function(e){e.preventDefault(),this.createCreateUserModal()},submitCreateUser:function(){var e=this,t=$("#newUsername").val(),i=$("#newName").val(),n=$("#newPassword").val(),o=$("#newStatus").is(":checked");if(this.validateUserInfo(i,t,n,o)){var a={user:t,passwd:n,active:o,extra:{name:i}};frontendConfig.isEnterprise&&$("#newRole").is(":checked")&&(a.user=":role:"+t,delete a.passwd),this.collection.create(a,{wait:!0,error:function(e,t){arangoHelper.parseError("User",t,e)},success:function(){e.updateUserManagement(),window.modalView.hide()}})}},validateUserInfo:function(e,t,i,n){return""!==t||(arangoHelper.arangoError("You have to define an username"),$("#newUsername").closest("th").css("backgroundColor","red"),!1)},updateUserManagement:function(){var e=this;this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){e.render()}})},editUser:function(e){if("createUser"!==$(e.currentTarget).find("a").attr("id")){$(e.currentTarget).hasClass("tile")&&(e.currentTarget=$(e.currentTarget).find(".fa")),this.collection.fetch({fetchAllUsers:!0,cache:!1});var t=this.evaluateUserName($(e.currentTarget).attr("id"),"_edit-user");""===t&&(t=$(e.currentTarget).attr("id")),window.App.navigate("user/"+encodeURIComponent(t),{trigger:!0})}},toggleView:function(){$("#userSortDesc").attr("checked",this.collection.sortOptions.desc),$("#userManagementToggle").toggleClass("activated"),$("#userManagementDropdown2").slideToggle(200)},createCreateUserModal:function(){var e=[],t=[];t.push(window.modalView.createTextEntry("newUsername","Username","",!1,"Username",!0,[{rule:Joi.string().regex(/^[a-zA-Z0-9\-_]*$/),msg:'Only symbols, "_" and "-" are allowed.'},{rule:Joi.string().required(),msg:"No username given."}])),t.push(window.modalView.createTextEntry("newName","Name","",!1,"Name",!1)),t.push(window.modalView.createPasswordEntry("newPassword","Password","",!1,"",!1)),frontendConfig.isEnterprise&&t.push(window.modalView.createCheckboxEntry("newRole","Role",!1,!1,!1)),t.push(window.modalView.createCheckboxEntry("newStatus","Active","active",!1,!0)),e.push(window.modalView.createSuccessButton("Create",this.submitCreateUser.bind(this))),window.modalView.show("modalTable.ejs","Create New User",e,t),frontendConfig.isEnterprise&&$("#newRole").on("change",function(){$("#newRole").is(":checked")?$("#newPassword").attr("disabled",!0):$("#newPassword").attr("disabled",!1)})},evaluateUserName:function(e,t){if(e){var i=e.lastIndexOf(t);return e.substring(0,i)}},updateUserProfile:function(){var e=this;this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){e.render()}})}})}(),function(){"use strict";window.UserPermissionView=Backbone.View.extend({el:"#content",template:templateEngine.createTemplate("userPermissionView.ejs"),initialize:function(e){this.username=e.username},remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click #userPermissionView .dbCheckbox":"setDBPermission","click #userPermissionView .collCheckbox":"setCollPermission","click .db-row":"toggleAccordion"},render:function(e,t){var i=this;this.collection.fetch({fetchAllUsers:!0,success:function(){i.continueRender(e,t)}})},toggleAccordion:function(e){if(!($(e.target).attr("type")||$(e.target).parent().hasClass("noAction")||$(e.target).hasClass("inner")||$(e.target).is("span"))){var t=$(e.currentTarget).find(".collection-row").is(":visible"),i=$(e.currentTarget).attr("id").split("-")[0];$(".collection-row").hide(),$(".db-label").css("font-weight",200),$(".db-label").css("color","#8a969f"),4<$(e.currentTarget).find(".collection-row").children().length?($(".db-row .fa-caret-down").hide(),$(".db-row .fa-caret-right").show(),t?$(e.currentTarget).find(".collection-row").hide():($(e.currentTarget).find(".collection-row").fadeIn("fast"),$(e.currentTarget).find(".db-label").css("font-weight",600),$(e.currentTarget).find(".db-label").css("color","rgba(64, 74, 83, 1)"),$(e.currentTarget).find(".fa-caret-down").show(),$(e.currentTarget).find(".fa-caret-right").hide())):($(".db-row .fa-caret-down").hide(),$(".db-row .fa-caret-right").show(),arangoHelper.arangoNotification("Permissions",'No collections in "'+i+'" available.'))}},setCollPermission:function(e){var t,i=$(e.currentTarget).attr("db"),n=$(e.currentTarget).attr("collection");t=$(e.currentTarget).hasClass("readOnly")?"ro":$(e.currentTarget).hasClass("readWrite")?"rw":$(e.currentTarget).hasClass("noAccess")?"none":"undefined",this.sendCollPermission(this.currentUser.get("user"),i,n,t)},setDBPermission:function(e){var t,i=$(e.currentTarget).attr("name");if(t=$(e.currentTarget).hasClass("readOnly")?"ro":$(e.currentTarget).hasClass("readWrite")?"rw":$(e.currentTarget).hasClass("noAccess")?"none":"undefined","_system"===i){var n=[],o=[];o.push(window.modalView.createReadOnlyEntry("db-system-revoke-button","Caution","You are changing the _system database permission. Really continue?",void 0,void 0,!1)),n.push(window.modalView.createSuccessButton("Ok",this.sendDBPermission.bind(this,this.currentUser.get("user"),i,t))),n.push(window.modalView.createCloseButton("Cancel",this.rollbackInputButton.bind(this,i))),window.modalView.show("modalTable.ejs","Change _system Database Permission",n,o)}else this.sendDBPermission(this.currentUser.get("user"),i,t)},rollbackInputButton:function(e,t){var i;_.each($(".collection-row"),function(e,t){$(e).is(":visible")&&(i=$(e).parent().attr("id"))}),i?this.render(i,t):this.render(),window.modalView.hide()},sendCollPermission:function(e,t,i,n){var o=this;"undefined"===n?this.revokeCollPermission(e,t,i):$.ajax({type:"PUT",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)+"/"+encodeURIComponent(i)),contentType:"application/json",data:JSON.stringify({grant:n})}).success(function(e){o.styleDefaultRadios(null,!0)}).error(function(e){o.rollbackInputButton(null,e)})},revokeCollPermission:function(e,t,i){var n=this;$.ajax({type:"DELETE",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)+"/"+encodeURIComponent(i)),contentType:"application/json"}).success(function(e){n.styleDefaultRadios(null,!0)}).error(function(e){n.rollbackInputButton(null,e)})},sendDBPermission:function(e,t,i){var n=this;"undefined"===i?this.revokeDBPermission(e,t):$.ajax({type:"PUT",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)),contentType:"application/json",data:JSON.stringify({grant:i})}).success(function(e){n.styleDefaultRadios(null,!0)}).error(function(e){n.rollbackInputButton(null,e)})},revokeDBPermission:function(e,t){var i=this;$.ajax({type:"DELETE",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)),contentType:"application/json"}).success(function(e){i.styleDefaultRadios(null,!0)}).error(function(e){i.rollbackInputButton(null,e)})},continueRender:function(t,i){var n=this;this.currentUser=this.collection.findWhere({user:this.username});var e=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(n.currentUser.get("user"))+"/database?full=true");$.ajax({type:"GET",url:e,contentType:"application/json",success:function(e){n.finishRender(e.result,t,i)},error:function(e){arangoHelper.arangoError("User","Could not fetch user permissions")}})},finishRender:function(e,t,i){var n=_.pairs(e);n.sort(),n=_.object(n),$(this.el).html(this.template.render({permissions:n})),$(".noAction").first().appendTo(".pure-table-body"),$(".pure-table-body").height(window.innerHeight-200),t&&$("#"+t).click(),i&&i.responseJSON&&i.responseJSON.errorMessage&&arangoHelper.arangoError("User",i.responseJSON.errorMessage),this.styleDefaultRadios(e),arangoHelper.createTooltips(),this.checkRoot(),this.breadcrumb()},checkRoot:function(){"root"===this.currentUser.get("user")&&$("#_system-db #___-collection input").attr("disabled","true")},styleDefaultRadios:function(e,t){var i=function(e){$(".db-row input").css("box-shadow","none");var o="rgba(0, 0, 0, 0.3) 0px 1px 4px 4px";_.each(e,function(e,i){if(e.collections){var n=e.collections["*"];_.each(e.collections,function(e,t){"_"!==t.charAt(0)&&"*"!==t.charAt(0)&&"undefined"===e&&("rw"===n?$("#"+i+"-db #"+t+"-collection .readWrite").css("box-shadow",o):"ro"===n?$("#"+i+"-db #"+t+"-collection .readOnly").css("box-shadow",o):"none"===n&&$("#"+i+"-db #"+t+"-collection .noAccess").css("box-shadow",o))})}})};if(t){var n=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(this.currentUser.get("user"))+"/database?full=true");$.ajax({type:"GET",url:n,contentType:"application/json",success:function(e){i(e.result)},error:function(e){arangoHelper.arangoError("User","Could not fetch user permissions")}})}else i(e);window.modalView.hide()},breadcrumb:function(){var e=this;window.App.naviView?($("#subNavigationBar .breadcrumb").html("User: "+arangoHelper.escapeHtml(this.currentUser.get("user"))),arangoHelper.buildUserSubNav(e.currentUser.get("user"),"Permissions")):window.setTimeout(function(){e.breadcrumb()},100)}})}(),function(){"use strict";window.UserView=Backbone.View.extend({el:"#content",initialize:function(e){this.username=e.username},render:function(){var e=this;this.collection.fetch({fetchAllUsers:!0,success:function(){e.continueRender()}})},editCurrentUser:function(){this.createEditCurrentUserModal(this.currentUser.get("user"),this.currentUser.get("extra").name,this.currentUser.get("extra").img)},continueRender:function(){this.currentUser=this.collection.findWhere({user:this.username}),this.breadcrumb(),this.currentUser.get("loggedIn")?this.editCurrentUser():this.createEditUserModal(this.currentUser.get("user"),this.currentUser.get("extra").name,this.currentUser.get("active"))},createEditUserPasswordModal:function(){var e=[],t=[];t.push(window.modalView.createPasswordEntry("newCurrentPassword","New Password","",!1,"new password",!1)),t.push(window.modalView.createPasswordEntry("confirmCurrentPassword","Confirm New Password","",!1,"confirm new password",!1)),e.push(window.modalView.createSuccessButton("Save",this.submitEditUserPassword.bind(this))),window.modalView.show("modalTable.ejs","Edit User Password",e,t)},createEditCurrentUserModal:function(e,t,i){var n=[],o=[];o.push(window.modalView.createReadOnlyEntry("id_username","Username",e)),o.push(window.modalView.createTextEntry("editCurrentName","Name",t,!1,"Name",!1)),o.push(window.modalView.createTextEntry("editCurrentUserProfileImg","Gravatar account (Mail)",i,"Mailaddress or its md5 representation of your gravatar account.The address will be converted into a md5 string. Only the md5 string will be stored, not the mailaddress.","myAccount(at)gravatar.com")),":role:"===this.username.substring(0,6)?n.push(window.modalView.createDisabledButton("Change Password")):n.push(window.modalView.createNotificationButton("Change Password",this.editUserPassword.bind(this))),n.push(window.modalView.createSuccessButton("Save",this.submitEditCurrentUserProfile.bind(this))),window.modalView.show("modalTable.ejs","Edit User Profile",n,o,null,null,this.events,null,null,"content")},parseImgString:function(e){return-1===e.indexOf("@")?e:CryptoJS.MD5(e).toString()},createEditUserModal:function(e,t,i){var n,o;o=[{type:window.modalView.tables.READONLY,label:"Username",value:_.escape(e)},{type:window.modalView.tables.TEXT,label:"Name",value:_.escape(t),id:"editName",placeholder:"Name"},{type:window.modalView.tables.CHECKBOX,label:"Active",value:"active",checked:i,id:"editStatus"}],(n=[]).push({title:"Delete",type:window.modalView.buttons.DELETE,callback:this.submitDeleteUser.bind(this,e)}),":role:"===this.username.substring(0,6)?n.push({title:"Change Password",type:window.modalView.buttons.DISABLED,callback:this.createEditUserPasswordModal.bind(this,e)}):n.push({title:"Change Password",type:window.modalView.buttons.NOTIFICATION,callback:this.createEditUserPasswordModal.bind(this,e)}),n.push({title:"Save",type:window.modalView.buttons.SUCCESS,callback:this.submitEditUser.bind(this,e)}),window.modalView.show("modalTable.ejs","Edit User",n,o,null,null,this.events,null,null,"content")},validateStatus:function(e){return""!==e},submitDeleteUser:function(e){this.collection.findWhere({user:e}).destroy({wait:!0}),window.App.navigate("#users",{trigger:!0})},submitEditCurrentUserProfile:function(){var e=$("#editCurrentName").val(),t=$("#editCurrentUserProfileImg").val();t=this.parseImgString(t);var i=function(e){e?arangoHelper.arangoError("User","Could not edit user settings"):(arangoHelper.arangoNotification("User","Changes confirmed."),this.updateUserProfile())}.bind(this);this.currentUser.setExtras(e,t,i),window.modalView.hide()},submitEditUserPassword:function(){var e=$("#newCurrentPassword").val(),t=$("#confirmCurrentPassword").val();$("#newCurrentPassword").val(""),$("#confirmCurrentPassword").val(""),$("#newCurrentPassword").closest("th").css("backgroundColor","white"),$("#confirmCurrentPassword").closest("th").css("backgroundColor","white");var i=!1;e!==t&&(arangoHelper.arangoError("User","New passwords do not match."),i=!0),i||(this.currentUser.setPassword(e),arangoHelper.arangoNotification("User","Password changed."),window.modalView.hide())},editUserPassword:function(){window.modalView.hide(),this.createEditUserPasswordModal()},submitEditUser:function(e){var t=$("#editName").val(),i=$("#editStatus").is(":checked");if(this.validateStatus(i)){var n=this.collection.findWhere({user:e});n.save({extra:{name:t},active:i},{type:"PATCH",success:function(){arangoHelper.arangoNotification("User",n.get("user")+" updated.")},error:function(){arangoHelper.arangoError("User","Could not update "+n.get("user")+".")}})}else $("#editStatus").closest("th").css("backgroundColor","red")},breadcrumb:function(){var e=this;window.App.naviView?($("#subNavigationBar .breadcrumb").html("User: "+_.escape(this.username)),arangoHelper.buildUserSubNav(e.currentUser.get("user"),"General")):window.setTimeout(function(){e.breadcrumb()},100)}})}(),function(){"use strict";window.ViewsView=Backbone.View.extend({el:"#content",readOnly:!1,template:templateEngine.createTemplate("viewsView.ejs"),initialize:function(){},refreshRate:1e4,sortOptions:{desc:!1},searchString:"",remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click #createView":"createView","click #viewsToggle":"toggleSettingsDropdown","click .tile-view":"gotoView","keyup #viewsSearchInput":"search","click #viewsSearchSubmit":"search","click #viewsSortDesc":"sorting"},checkVisibility:function(){$("#viewsDropdown").is(":visible")?this.dropdownVisible=!0:this.dropdownVisible=!1,arangoHelper.setCheckboxStatus("#viewsDropdown")},checkIfInProgress:function(){if(-1&'"]/)),e.push(window.modalView.createDeleteButton("Delete",this.deleteViewTrue.bind(this))),window.modalView.show("modalTable.ejs","Delete View",e,t)},deleteViewTrue:function(){this.model.deleteView(function(e,t){e?arangoHelper.arangoError("View","Could not delete the view."):(window.modalView.hide(),window.App.navigate("#views",{trigger:!0}))})},renameView:function(){var e=[],t=[];t.push(window.modalView.createTextEntry("editCurrentName","Name",this.name,!1,"Name",!1)),e.push(window.modalView.createSuccessButton("Rename",this.renameViewTrue.bind(this))),window.modalView.show("modalTable.ejs","Rename View",e,t)},renameViewTrue:function(){var t=this;$("#editCurrentName").val()?$.ajax({type:"PUT",cache:!1,url:arangoHelper.databaseUrl("/_api/view/"+encodeURIComponent(t.name)+"/rename"),contentType:"application/json",processData:!1,data:JSON.stringify({name:$("#editCurrentName").val()}),success:function(e){t.name=e.name,t.model.set("name",e.name),t.breadcrumb(),window.modalView.hide()},error:function(e){window.modalView.hide(),arangoHelper.arangoError("View",e.responseJSON.errorMessage)}}):arangoHelper.arangoError("View","Please fill in a view name.")},breadcrumb:function(){var e=this;window.App.naviView?($("#subNavigationBar .breadcrumb").html("View: "+arangoHelper.escapeHtml(e.name)),window.setTimeout(function(){$("#subNavigationBar .breadcrumb").html("View: "+arangoHelper.escapeHtml(e.name)),e.checkIfInProgress()},100)):window.setTimeout(function(){e.breadcrumb()},100)}})}(),function(){"use strict";window.Router=Backbone.Router.extend({toUpdate:[],dbServers:[],isCluster:void 0,lastRoute:void 0,routes:{"":"cluster",dashboard:"dashboard",replication:"replication","replication/applier/:endpoint/:database":"applier",collections:"collections",new:"newCollection",login:"login","collection/:colid/documents/:pageid":"documents","cIndices/:colname":"cIndices","cSettings/:colname":"cSettings","cInfo/:colname":"cInfo","collection/:colid/:docid":"document",shell:"shell",queries:"query",databases:"databases",settings:"databases",services:"applications","services/install":"installService","services/install/new":"installNewService","services/install/github":"installGitHubService","services/install/upload":"installUploadService","services/install/remote":"installUrlService","service/:mount":"applicationDetail","store/:name":"storeDetail",graphs:"graphManagement","graphs/:name":"showGraph",users:"userManagement","user/:name":"userView","user/:name/permission":"userPermission",userProfile:"userProfile",cluster:"cluster",nodes:"nodes",shards:"shards","node/:name":"node","nodeInfo/:id":"nodeInfo",logs:"logger",helpus:"helpUs",views:"views","view/:name":"view","graph/:name":"graph","graph/:name/settings":"graphSettings",support:"support"},execute:function(e,t){if("#queries"===this.lastRoute&&(this.queryView.removeInputEditors(),this.queryView.cleanupGraphs(),this.queryView.removeResults()),this.lastRoute){var i=this.lastRoute.split("/")[0],n=this.lastRoute.split("/")[1],o=this.lastRoute.split("/")[2];"#service"!==i&&(window.App.replaceApp?"install"!==n&&o&&(window.App.replaceApp=!1):window.App.replaceApp=!1),"#collection"===this.lastRoute.substr(0,11)&&3===this.lastRoute.split("/").length&&this.documentView.cleanupEditor(),"#dasboard"!==this.lastRoute&&"#node"!==window.location.hash.substr(0,5)||d3.selectAll("svg > *").remove(),"#logger"===this.lastRoute&&(this.loggerView.logLevelView&&this.loggerView.logLevelView.remove(),this.loggerView.logTopicView&&this.loggerView.logTopicView.remove())}this.lastRoute=window.location.hash,$("#subNavigationBar .breadcrumb").html(""),$("#subNavigationBar .bottom").html(""),$("#loadingScreen").hide(),$("#content").show(),e&&e.apply(this,t),"#services"===this.lastRoute&&(window.App.replaceApp=!1),this.graphViewer&&this.graphViewer.graphSettingsView&&this.graphViewer.graphSettingsView.hide(),this.queryView&&this.queryView.graphViewer&&this.queryView.graphViewer.graphSettingsView&&this.queryView.graphViewer.graphSettingsView.hide()},listenerFunctions:{},listener:function(i){_.each(window.App.listenerFunctions,function(e,t){e(i)})},checkUser:function(){var i=this;if("#login"!==window.location.hash){var n=function(){this.initOnce(),$(".bodyWrapper").show(),$(".navbar").show()}.bind(this),e=function(e,t){frontendConfig.authenticationEnabled?(i.currentUser=t,e||null===t?"#login"!==window.location.hash&&this.navigate("login",{trigger:!0}):n()):n()}.bind(this);frontendConfig.authenticationEnabled?this.userCollection.whoAmI(e):(this.initOnce(),$(".bodyWrapper").show(),$(".navbar").show())}},waitForInit:function(e,t,i){this.initFinished?(t||e(!0),t&&!i&&e(t,!0),t&&i&&e(t,i,!0)):setTimeout(function(){t||e(!1),t&&!i&&e(t,!1),t&&i&&e(t,i,!1)},350)},initFinished:!1,initialize:function(){!0===frontendConfig.isCluster&&(this.isCluster=!0),document.addEventListener("keyup",this.listener,!1),window.modalView=new window.ModalView,this.foxxList=new window.FoxxCollection,window.foxxInstallView=new window.FoxxInstallView({collection:this.foxxList}),this.foxxRepo=new window.FoxxRepository,this.foxxRepo.fetch({success:function(){i.serviceInstallView&&(i.serviceInstallView.collection=i.foxxRepo)}}),window.progressView=new window.ProgressView;var i=this;this.userCollection=new window.ArangoUsers,this.initOnce=function(){this.initOnce=function(){};var e=function(e,t){i=this,!0===t&&i.coordinatorCollection.fetch({success:function(){i.fetchDBS()}}),e&&console.log(e)}.bind(this);window.isCoordinator(e),!1===frontendConfig.isCluster&&(this.initFinished=!0),this.arangoDatabase=new window.ArangoDatabase,this.currentDB=new window.CurrentDatabase,this.arangoCollectionsStore=new window.ArangoCollections,this.arangoDocumentStore=new window.ArangoDocument,this.arangoViewsStore=new window.ArangoViews,this.coordinatorCollection=new window.ClusterCoordinators,window.spotlightView=new window.SpotlightView({collection:this.arangoCollectionsStore}),arangoHelper.setDocumentStore(this.arangoDocumentStore),this.arangoCollectionsStore.fetch({cache:!1}),this.footerView=new window.FooterView({collection:i.coordinatorCollection}),this.notificationList=new window.NotificationCollection,this.currentDB.fetch({cache:!1,success:function(){i.naviView=new window.NavigationView({database:i.arangoDatabase,currentDB:i.currentDB,notificationCollection:i.notificationList,userCollection:i.userCollection,isCluster:i.isCluster}),i.naviView.render()}}),this.queryCollection=new window.ArangoQueries,this.footerView.render(),window.checkVersion(),this.userConfig=new window.UserConfig({ldapEnabled:frontendConfig.ldapEnabled}),this.userConfig.fetch(),this.documentsView=new window.DocumentsView({collection:new window.ArangoDocuments,documentStore:this.arangoDocumentStore,collectionsStore:this.arangoCollectionsStore}),arangoHelper.initSigma()}.bind(this),$(window).resize(function(){i.handleResize()}),$(window).scroll(function(){})},handleScroll:function(){50<$(window).scrollTop()?($(".navbar > .secondary").css("top",$(window).scrollTop()),$(".navbar > .secondary").css("position","absolute"),$(".navbar > .secondary").css("z-index","10"),$(".navbar > .secondary").css("width",$(window).width())):($(".navbar > .secondary").css("top","0"),$(".navbar > .secondary").css("position","relative"),$(".navbar > .secondary").css("width",""))},cluster:function(e){this.checkUser(),e?!1!==this.isCluster&&void 0!==this.isCluster?(this.clusterView||(this.clusterView=new window.ClusterView({coordinators:this.coordinatorCollection,dbServers:this.dbServers})),this.clusterView.render()):"_system"===this.currentDB.get("name")?(this.routes[""]="dashboard",this.navigate("#dashboard",{trigger:!0})):(this.routes[""]="collections",this.navigate("#collections",{trigger:!0})):this.waitForInit(this.cluster.bind(this))},node:function(e,t){if(this.checkUser(),t&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.nodeView&&this.nodeView.remove(),this.nodeView=new window.NodeView({coordid:e,coordinators:this.coordinatorCollection,dbServers:this.dbServers}),this.nodeView.render()}else this.waitForInit(this.node.bind(this),e)},shards:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.shardsView&&this.shardsView.remove(),this.shardsView=new window.ShardsView({dbServers:this.dbServers}),this.shardsView.render()}else this.waitForInit(this.shards.bind(this))},nodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.nodesView&&this.nodesView.remove(),this.nodesView=new window.NodesView({}),this.nodesView.render()}else this.waitForInit(this.nodes.bind(this))},cNodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.nodesView=new window.NodesView({coordinators:this.coordinatorCollection,dbServers:this.dbServers[0],toRender:"coordinator"}),this.nodesView.render()}else this.waitForInit(this.cNodes.bind(this))},dNodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster)return!1===this.isCluster?(this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0})):void(0!==this.dbServers.length?(this.nodesView=new window.NodesView({coordinators:this.coordinatorCollection,dbServers:this.dbServers[0],toRender:"dbserver"}),this.nodesView.render()):this.navigate("#cNodes",{trigger:!0}));this.waitForInit(this.dNodes.bind(this))},sNodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.scaleView=new window.ScaleView({coordinators:this.coordinatorCollection,dbServers:this.dbServers[0]}),this.scaleView.render()}else this.waitForInit(this.sNodes.bind(this))},addAuth:function(e){var t=this.clusterPlan.get("user");if(!t)return e.abort(),void(this.isCheckingUser||this.requestAuth());var i=t.name,n=t.passwd,o=i.concat(":",n);e.setRequestHeader("Authorization","Basic "+btoa(o))},logger:function(e){if(this.checkUser(),e){if(!this.loggerView){var t=new window.ArangoLogs({upto:!0,loglevel:4});this.loggerView=new window.LoggerView({collection:t})}this.loggerView.render()}else this.waitForInit(this.logger.bind(this))},applicationDetail:function(e,t){if(this.checkUser(),t){var i=function(){this.hasOwnProperty("applicationDetailView")&&this.applicationDetailView.remove(),this.applicationDetailView=new window.ApplicationDetailView({model:this.foxxList.get(decodeURIComponent(e))}),this.applicationDetailView.model=this.foxxList.get(decodeURIComponent(e)),this.applicationDetailView.render("swagger")}.bind(this);0===this.foxxList.length?this.foxxList.fetch({cache:!1,success:function(){i()}}):i()}else this.waitForInit(this.applicationDetail.bind(this),e)},storeDetail:function(e,t){if(this.checkUser(),t){var i=function(){this.hasOwnProperty("storeDetailView")&&this.storeDetailView.remove(),this.storeDetailView=new window.StoreDetailView({model:this.foxxRepo.get(decodeURIComponent(e)),collection:this.foxxList}),this.storeDetailView.model=this.foxxRepo.get(decodeURIComponent(e)),this.storeDetailView.render()}.bind(this);0===this.foxxRepo.length?this.foxxRepo.fetch({cache:!1,success:function(){i()}}):i()}else this.waitForInit(this.storeDetail.bind(this),e)},login:function(){var e=function(e,t){this.loginView||(this.loginView=new window.LoginView({collection:this.userCollection})),e||null===t?this.loginView.render():this.loginView.render(!0)}.bind(this);this.userCollection.whoAmI(e)},collections:function(e){if(this.checkUser(),e){var t=this;this.collectionsView&&this.collectionsView.remove(),this.collectionsView=new window.CollectionsView({collection:this.arangoCollectionsStore}),this.arangoCollectionsStore.fetch({cache:!1,success:function(){t.collectionsView.render()}})}else this.waitForInit(this.collections.bind(this))},cIndices:function(e,t){var i=this;this.checkUser(),t?this.arangoCollectionsStore.fetch({cache:!1,success:function(){i.indicesView&&i.indicesView.remove(),i.indicesView=new window.IndicesView({collectionName:e,collection:i.arangoCollectionsStore.findWhere({name:e})}),i.indicesView.render()}}):this.waitForInit(this.cIndices.bind(this),e)},cSettings:function(e,t){var i=this;this.checkUser(),t?this.arangoCollectionsStore.fetch({cache:!1,success:function(){i.settingsView=new window.SettingsView({collectionName:e,collection:i.arangoCollectionsStore.findWhere({name:e})}),i.settingsView.render()}}):this.waitForInit(this.cSettings.bind(this),e)},cInfo:function(e,t){var i=this;this.checkUser(),t?this.arangoCollectionsStore.fetch({cache:!1,success:function(){i.infoView=new window.InfoView({collectionName:e,collection:i.arangoCollectionsStore.findWhere({name:e})}),i.infoView.render()}}):this.waitForInit(this.cInfo.bind(this),e)},documents:function(e,t,i){this.checkUser(),i?(this.documentsView&&this.documentsView.unbindEvents(),this.documentsView||(this.documentsView=new window.DocumentsView({collection:new window.ArangoDocuments,documentStore:this.arangoDocumentStore,collectionsStore:this.arangoCollectionsStore})),this.documentsView.setCollectionId(e,t),this.documentsView.render(),this.documentsView.delegateEvents()):this.waitForInit(this.documents.bind(this),e,t)},document:function(e,t,i){if(this.checkUser(),i){var n;this.documentView&&(this.documentView.defaultMode&&(n=this.documentView.defaultMode),this.documentView.remove()),this.documentView=new window.DocumentView({collection:this.arangoDocumentStore}),this.documentView.colid=e,this.documentView.defaultMode=n;var o=window.location.hash.split("/")[2],a=(o.split("%").length-1)%3;decodeURI(o)!==o&&0!=a&&(o=decodeURIComponent(o)),this.documentView.docid=o,this.documentView.render();var r=function(e,t){e?console.log("Error","Could not fetch collection type"):this.documentView.setType()}.bind(this);arangoHelper.collectionApiType(e,null,r)}else this.waitForInit(this.document.bind(this),e,t)},query:function(e){this.checkUser(),e?(this.queryView||(this.queryView=new window.QueryView({collection:this.queryCollection})),this.queryView.render()):this.waitForInit(this.query.bind(this))},graph:function(e,t){this.checkUser(),t?(this.graphViewer&&(this.graphViewer.graphSettingsView&&this.graphViewer.graphSettingsView.remove(),this.graphViewer.killCurrentGraph(),this.graphViewer.unbind(),this.graphViewer.remove()),this.graphViewer=new window.GraphViewer({name:e,documentStore:this.arangoDocumentStore,collection:new window.GraphCollection,userConfig:this.userConfig}),this.graphViewer.render()):this.waitForInit(this.graph.bind(this),e)},graphSettings:function(e,t){this.checkUser(),t?(this.graphSettingsView&&this.graphSettingsView.remove(),this.graphSettingsView=new window.GraphSettingsView({name:e,userConfig:this.userConfig}),this.graphSettingsView.render()):this.waitForInit(this.graphSettings.bind(this),e)},helpUs:function(e){this.checkUser(),e?(this.testView||(this.helpUsView=new window.HelpUsView({})),this.helpUsView.render()):this.waitForInit(this.helpUs.bind(this))},support:function(e){this.checkUser(),e?(this.testView||(this.supportView=new window.SupportView({})),this.supportView.render()):this.waitForInit(this.support.bind(this))},queryManagement:function(e){this.checkUser(),e?(this.queryManagementView&&this.queryManagementView.remove(),this.queryManagementView=new window.QueryManagementView({collection:void 0}),this.queryManagementView.render()):this.waitForInit(this.queryManagement.bind(this))},databases:function(e){if(this.checkUser(),e){var t=function(e){e?(arangoHelper.arangoError("DB","Could not get list of allowed databases"),this.navigate("#",{trigger:!0}),$("#databaseNavi").css("display","none"),$("#databaseNaviSelect").css("display","none")):(this.databaseView&&this.databaseView.remove(),this.databaseView=new window.DatabaseView({users:this.userCollection,collection:this.arangoDatabase}),this.databaseView.render())}.bind(this);arangoHelper.databaseAllowed(t)}else this.waitForInit(this.databases.bind(this))},dashboard:function(e){this.checkUser(),e?(void 0===this.dashboardView&&(this.dashboardView=new window.DashboardView({dygraphConfig:window.dygraphConfig,database:this.arangoDatabase})),this.dashboardView.render()):this.waitForInit(this.dashboard.bind(this))},replication:function(e){this.checkUser(),e?(this.replicationView||(this.replicationView=new window.ReplicationView({})),this.replicationView.render()):this.waitForInit(this.replication.bind(this))},applier:function(e,t,i){this.checkUser(),i?(void 0===this.applierView&&(this.applierView=new window.ApplierView({})),this.applierView.endpoint=atob(e),this.applierView.database=atob(t),this.applierView.render()):this.waitForInit(this.applier.bind(this),e,t)},graphManagement:function(e){this.checkUser(),e?(this.graphManagementView&&this.graphManagementView.undelegateEvents(),this.graphManagementView=new window.GraphManagementView({collection:new window.GraphCollection,collectionCollection:this.arangoCollectionsStore}),this.graphManagementView.render()):this.waitForInit(this.graphManagement.bind(this))},showGraph:function(e,t){this.checkUser(),t?this.graphManagementView?this.graphManagementView.loadGraphViewer(e):(this.graphManagementView=new window.GraphManagementView({collection:new window.GraphCollection,collectionCollection:this.arangoCollectionsStore}),this.graphManagementView.render(e,!0)):this.waitForInit(this.showGraph.bind(this),e)},applications:function(e){this.checkUser(),e?(void 0===this.applicationsView&&(this.applicationsView=new window.ApplicationsView({collection:this.foxxList})),this.applicationsView.reload()):this.waitForInit(this.applications.bind(this))},installService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceInstallView&&this.serviceInstallView.remove(),this.serviceInstallView=new window.ServiceInstallView({collection:this.foxxRepo,functionsCollection:this.foxxList}),this.serviceInstallView.render()):this.waitForInit(this.installService.bind(this))},installNewService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceNewView&&this.serviceNewView.remove(),this.serviceNewView=new window.ServiceInstallNewView({collection:this.foxxList}),this.serviceNewView.render()):this.waitForInit(this.installNewService.bind(this))},installGitHubService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceGitHubView&&this.serviceGitHubView.remove(),this.serviceGitHubView=new window.ServiceInstallGitHubView({collection:this.foxxList}),this.serviceGitHubView.render()):this.waitForInit(this.installGitHubService.bind(this))},installUrlService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceUrlView&&this.serviceUrlView.remove(),this.serviceUrlView=new window.ServiceInstallUrlView({collection:this.foxxList}),this.serviceUrlView.render()):this.waitForInit(this.installUrlService.bind(this))},installUploadService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceUploadView&&this.serviceUploadView.remove(),this.serviceUploadView=new window.ServiceInstallUploadView({collection:this.foxxList}),this.serviceUploadView.render()):this.waitForInit(this.installUploadService.bind(this))},handleSelectDatabase:function(e){this.checkUser(),e?this.naviView.handleSelectDatabase():this.waitForInit(this.handleSelectDatabase.bind(this))},handleResize:function(){this.dashboardView&&this.dashboardView.resize(),this.graphManagementView&&"graphs"===Backbone.history.getFragment()&&this.graphManagementView.handleResize($("#content").width()),this.queryView&&"queries"===Backbone.history.getFragment()&&this.queryView.resize(),this.naviView&&this.naviView.resize(),this.graphViewer&&-1'),window.parseVersions=function(e){_.isEmpty(e)?$("#currentVersion").addClass("up-to-date"):($("#currentVersion").addClass("out-of-date"),$("#currentVersion .fa").removeClass("fa-check-circle").addClass("fa-exclamation-circle"),$("#currentVersion").click(function(){!function(e,t){var i=[];i.push(window.modalView.createSuccessButton("Download Page",function(){window.open("https://www.arangodb.com/download","_blank"),window.modalView.hide()}));var n=[],o=window.modalView.createReadOnlyEntry.bind(window.modalView);n.push(o("current","Current",e.toString())),t.major&&n.push(o("major","Major",t.major.version)),t.minor&&n.push(o("minor","Minor",t.minor.version)),t.bugfix&&n.push(o("bugfix","Bugfix",t.bugfix.version)),window.modalView.show("modalTable.ejs","New Version Available",i,n)}(t,e)}))},$.ajax({type:"GET",async:!0,crossDomain:!0,timeout:3e3,dataType:"jsonp",url:"https://www.arangodb.com/repositories/versions.php?jsonp=parseVersions&version="+encodeURIComponent(t.toString()),error:function(e){200===e.status?window.activeInternetConnection=!0:window.activeInternetConnection=!1},success:function(e){window.activeInternetConnection=!0}})}})}}(),function(){"use strict";window.hasOwnProperty("TEST_BUILD")||($(document).ajaxSend(function(e,t,i){t.setRequestHeader("X-Arango-Frontend","true");var n=window.arangoHelper.getCurrentJwt();n&&t.setRequestHeader("Authorization","bearer "+n)}),$.ajaxSetup({error:function(e,t,i){401===e.status&&arangoHelper.checkJwt()}}),$(document).ready(function(){window.App=new window.Router,Backbone.history.start(),window.App.handleResize()}),$(document).click(function(e){e.stopPropagation(),$(e.target).hasClass("subBarDropdown")||$(e.target).hasClass("dropdown-header")||$(e.target).hasClass("dropdown-footer")||$(e.target).hasClass("toggle")||$("#userInfo").is(":visible")&&$(".subBarDropdown").hide()}),$("body").on("keyup",function(e){27===e.keyCode&&window.modalView&&window.modalView.hide()}))}(); \ No newline at end of file +!function(){"use strict";var i=null;window.isCoordinator=function(t){null===i?$.ajax("cluster/amICoordinator",{async:!0,success:function(e){t(!1,i=e)},error:function(e){t(!0,i=e)}}):t(!1,i)},window.versionHelper={fromString:function(e){var t=e.replace(/-[a-zA-Z0-9_-]*$/g,"").split(".");return{major:parseInt(t[0],10)||0,minor:parseInt(t[1],10)||0,patch:parseInt(t[2],10)||0,toString:function(){return this.major+"."+this.minor+"."+this.patch}}},toString:function(e){return e.major+"."+e.minor+"."+e.patch},toDocuVersion:function(e){return 0<=e.toLowerCase().indexOf("devel")||0<=e.toLowerCase().indexOf("rc")?"devel":e.substring(0,3)}},window.arangoHelper={alphabetColors:{a:"rgb(0,0,180)",b:"rgb(175,13,102)",c:"rgb(146,248,70)",d:"rgb(255,200,47)",e:"rgb(255,118,0)",f:"rgb(185,185,185)",g:"rgb(235,235,222)",h:"rgb(100,100,100)",i:"rgb(255,255,0)",j:"rgb(55,19,112)",k:"rgb(255,255,150)",l:"rgb(202,62,94)",m:"rgb(205,145,63)",n:"rgb(12,75,100)",o:"rgb(255,0,0)",p:"rgb(175,155,50)",q:"rgb(0,0,0)",r:"rgb(37,70,25)",s:"rgb(121,33,135)",t:"rgb(83,140,208)",u:"rgb(0,154,37)",v:"rgb(178,220,205)",w:"rgb(255,152,213)",x:"rgb(0,0,74)",y:"rgb(175,200,74)",z:"rgb(63,25,12)"},statusColors:{fatal:"#ad5148",info:"rgb(88, 214, 141)",error:"rgb(236, 112, 99)",warning:"#ffb075",debug:"rgb(64, 74, 83)"},getCurrentJwt:function(){return sessionStorage.getItem("jwt")},getCurrentJwtUsername:function(){return sessionStorage.getItem("jwtUser")},setCurrentJwt:function(e,t){sessionStorage.setItem("jwt",e),sessionStorage.setItem("jwtUser",t)},checkJwt:function(){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/version"),contentType:"application/json",processData:!1,async:!0,error:function(e){401===e.status&&window.App.navigate("login",{trigger:!0})}})},getCoordinatorShortName:function(i){var n;return window.clusterHealth&&_.each(window.clusterHealth,function(e,t){i===t&&(n=e.ShortName)}),arangoHelper.escapeHtml(n)},getDatabaseShortName:function(e){return this.getCoordinatorShortName(e)},getDatabaseServerId:function(i){var n;return window.clusterHealth&&_.each(window.clusterHealth,function(e,t){i===e.ShortName&&(n=t)}),n},lastNotificationMessage:null,CollectionTypes:{},systemAttributes:function(){return{_id:!0,_rev:!0,_key:!0,_bidirectional:!0,_vertices:!0,_from:!0,_to:!0,$id:!0}},getCurrentSub:function(){return window.App.naviView.activeSubMenu},parseError:function(e,t){var i;try{i=JSON.parse(t.responseText).errorMessage}catch(e){i=e}this.arangoError(e,i)},setCheckboxStatus:function(e){_.each($(e).find("ul").find("li"),function(e){$(e).hasClass("nav-header")||($(e).find("input").attr("checked")?$(e).find("i").hasClass("css-round-label")?($(e).find("i").removeClass("fa-circle-o"),$(e).find("i").addClass("fa-dot-circle-o")):($(e).find("i").removeClass("fa-square-o"),$(e).find("i").addClass("fa-check-square-o")):$(e).find("i").hasClass("css-round-label")?($(e).find("i").removeClass("fa-dot-circle-o"),$(e).find("i").addClass("fa-circle-o")):($(e).find("i").removeClass("fa-check-square-o"),$(e).find("i").addClass("fa-square-o")))})},parseInput:function(e){var t,i=$(e).val();try{t=JSON.parse(i)}catch(e){t=i}return t},calculateCenterDivHeight:function(){var e=$(".navbar").height(),t=$(".footer").height();return $(window).height()-t-e-110},createTooltips:function(e,t){var i=this,n={arrow:!0,animation:"fade",animateFill:!1,multiple:!1,hideDuration:1};if(t&&(n.position=t),e||(e=".tippy"),"object"==typeof e)_.each(e,function(e){i.lastTooltips=new Tippy(e,n)});else{if(-1'+t+""),e.disabled||$("#subNavigationBar .bottom").children().last().bind("click",function(){window.App.navigate(e.route,{trigger:!0})})})},buildUserSubNav:function(e,t){var i={General:{route:"#user/"+encodeURIComponent(e)},Permissions:{route:"#user/"+encodeURIComponent(e)+"/permission"}};i[t].active=!0,this.buildSubNavBar(i)},buildGraphSubNav:function(e,t){var i={Content:{route:"#graph/"+encodeURIComponent(e)},Settings:{route:"#graph/"+encodeURIComponent(e)+"/settings"}};i[t].active=!0,this.buildSubNavBar(i)},buildNodeSubNav:function(e,t,i){var n={Dashboard:{route:"#node/"+encodeURIComponent(e)}};n[t].active=!0,n[i].disabled=!0,this.buildSubNavBar(n)},buildNodesSubNav:function(e,t){var i={Overview:{route:"#nodes"},Shards:{route:"#shards"}};i[e].active=!0,t&&(i[t].disabled=!0),this.buildSubNavBar(i)},buildServicesSubNav:function(e,t){var i={Store:{route:"#services/install"},Upload:{route:"#services/install/upload"},New:{route:"#services/install/new"},GitHub:{route:"#services/install/github"},Remote:{route:"#services/install/remote"}};i[e].active=!0,t&&(i[t].disabled=!0),this.buildSubNavBar(i)},scaleability:void 0,buildCollectionSubNav:function(e,t){var i={Content:{route:"#collection/"+encodeURIComponent(e)+"/documents/1"},Indexes:{route:"#cIndices/"+encodeURIComponent(e)},Info:{route:"#cInfo/"+encodeURIComponent(e)},Settings:{route:"#cSettings/"+encodeURIComponent(e)}};i[t].active=!0,this.buildSubNavBar(i)},enableKeyboardHotkeys:function(e){var t=window.arangoHelper.hotkeysFunctions;!0===e&&($(document).on("keydown",null,"j",t.scrollDown),$(document).on("keydown",null,"k",t.scrollUp))},databaseAllowed:function(i){var e=function(e,t){e?arangoHelper.arangoError("",""):$.ajax({type:"GET",cache:!1,url:this.databaseUrl("/_api/database/",t),contentType:"application/json",processData:!1,success:function(){i(!1,!0)},error:function(){i(!0,!1)}})}.bind(this);this.currentDatabase(e)},arangoNotification:function(e,t,i){window.App.notificationList.add({title:e,content:t,info:i,type:"success"})},arangoError:function(e,t,i){$("#offlinePlaceholder").is(":visible")||window.App.notificationList.add({title:e,content:t,info:i,type:"error"})},arangoWarning:function(e,t,i){window.App.notificationList.add({title:e,content:t,info:i,type:"warning"})},arangoMessage:function(e,t,i){window.App.notificationList.add({title:e,content:t,info:i,type:"message"})},hideArangoNotifications:function(){$.noty.clearQueue(),$.noty.closeAll()},openDocEditor:function(e,t,i){var n=e.split("/"),o=this,a=new window.DocumentView({collection:window.App.arangoDocumentStore});a.breadcrumb=function(){},a.colid=n[0],a.docid=n[1],a.el=".arangoFrame .innerDiv",a.render(),a.setType(t),$(".arangoFrame .headerBar").remove(),$(".arangoFrame .outerDiv").prepend(''),$(".arangoFrame .outerDiv").click(function(){o.closeDocEditor()}),$(".arangoFrame .innerDiv").click(function(e){e.stopPropagation()}),$(".fa-times").click(function(){o.closeDocEditor()}),$(".arangoFrame").show(),a.customView=!0,a.customDeleteFunction=function(){window.modalView.hide(),$(".arangoFrame").hide()},a.customSaveFunction=function(e){o.closeDocEditor(),i&&i(e)},$(".arangoFrame #deleteDocumentButton").click(function(){a.deleteDocumentModal()}),$(".arangoFrame #saveDocumentButton").click(function(){a.saveDocument()}),$(".arangoFrame #deleteDocumentButton").css("display","none")},closeDocEditor:function(){$(".arangoFrame .outerDiv .fa-times").remove(),$(".arangoFrame").hide()},addAardvarkJob:function(e,t){$.ajax({cache:!1,type:"POST",url:this.databaseUrl("/_admin/aardvark/job"),data:JSON.stringify(e),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},deleteAardvarkJob:function(e,t){$.ajax({cache:!1,type:"DELETE",url:this.databaseUrl("/_admin/aardvark/job/"+encodeURIComponent(e)),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},deleteAllAardvarkJobs:function(t){$.ajax({cache:!1,type:"DELETE",url:this.databaseUrl("/_admin/aardvark/job"),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},getAardvarkJobs:function(t){$.ajax({cache:!1,type:"GET",url:this.databaseUrl("/_admin/aardvark/job"),contentType:"application/json",processData:!1,success:function(e){t&&t(!1,e)},error:function(e){t&&t(!0,e)}})},getPendingJobs:function(t){$.ajax({cache:!1,type:"GET",url:this.databaseUrl("/_api/job/pending"),contentType:"application/json",processData:!1,success:function(e){t(!1,e)},error:function(e){t(!0,e)}})},syncAndReturnUnfinishedAardvarkJobs:function(a,r){var e=function(e,t){if(e)r(!0);else{var i=function(e,n){if(e)arangoHelper.arangoError("","");else{var o=[];0/g,">").replace(/"/g,""").replace(/'/g,"'")},backendUrl:function(e){return frontendConfig.basePath+e},databaseUrl:function(e,t){if("/_db/"===e.substr(0,5))throw new Error("Calling databaseUrl with a databased url ("+e+") doesn't make any sense");return t||(t="_system",frontendConfig.db&&(t=frontendConfig.db)),this.backendUrl("/_db/"+encodeURIComponent(t)+e)},showAuthDialog:function(){var e=!0;return"false"===localStorage.getItem("authenticationNotification")&&(e=!1),e},doNotShowAgain:function(){localStorage.setItem("authenticationNotification",!1)},renderEmpty:function(e,t){t?$("#content").html(''):$("#content").html('")},initSigma:function(){try{sigma.classes.graph.addMethod("neighbors",function(e){var t,i={},n=this.allNeighborsIndex[e]||{};for(t in n)i[t]=this.nodesIndex[t];return i}),sigma.classes.graph.addMethod("getNodeEdges",function(t){var e=this.edges(),i=[];return _.each(e,function(e){e.source!==t&&e.target!==t||i.push(e.id)}),i}),sigma.classes.graph.addMethod("getNodeEdgesCount",function(e){return this.allNeighborsCount[e]}),sigma.classes.graph.addMethod("getNodesCount",function(){return this.nodesArray.length})}catch(e){}},downloadLocalBlob:function(e,t){var i;if("csv"===t&&(i="text/csv; charset=utf-8"),"json"===t&&(i="application/json; charset=utf-8"),i){var n=new Blob([e],{type:i}),o=window.URL.createObjectURL(n),a=document.createElement("a");document.body.appendChild(a),a.style="display: none",a.href=o,a.download="results-"+window.frontendConfig.db+"."+t,a.click(),window.setTimeout(function(){window.URL.revokeObjectURL(o),document.body.removeChild(a)},500)}},download:function(e,r){$.ajax(e).success(function(e,t,i){if(r)r(e);else{var n=new Blob([JSON.stringify(e)],{type:i.getResponseHeader("Content-Type")||"application/octet-stream"}),o=window.URL.createObjectURL(n),a=document.createElement("a");document.body.appendChild(a),a.style="display: none",a.href=o,a.download=i.getResponseHeader("Content-Disposition").replace(/.* filename="([^")]*)"/,"$1"),a.click(),window.setTimeout(function(){window.URL.revokeObjectURL(o),document.body.removeChild(a)},500)}})},downloadPost:function(e,t,i,n){var o=new XMLHttpRequest;o.onreadystatechange=function(){if(4===this.readyState&&200===this.status){i&&i();var e=document.createElement("a");e.download=this.getResponseHeader("Content-Disposition").replace(/.* filename="([^")]*)"/,"$1"),document.body.appendChild(e);var t=window.URL.createObjectURL(this.response);e.href=t,e.click(),window.setTimeout(function(){window.URL.revokeObjectURL(t),document.body.removeChild(e)},500)}else 4===this.readyState&&void 0!==n&&n(this.status,this.statusText)},o.open("POST",e),window.arangoHelper.getCurrentJwt()&&o.setRequestHeader("Authorization","bearer "+window.arangoHelper.getCurrentJwt()),o.responseType="blob",o.send(t)},checkCollectionPermissions:function(e,t){var i=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(window.App.userCollection.activeUser)+"/database/"+encodeURIComponent(frontendConfig.db)+"/"+encodeURIComponent(e));$.ajax({type:"GET",url:i,contentType:"application/json",success:function(e){"ro"===e.result&&t()},error:function(e){arangoHelper.arangoError("User","Could not fetch collection permissions.")}})},checkDatabasePermissions:function(t,i){var e=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(window.App.userCollection.activeUser)+"/database/"+encodeURIComponent(frontendConfig.db));$.ajax({type:"GET",url:e,contentType:"application/json",success:function(e){"ro"===e.result?t&&t(!0):"rw"===e.result?i&&i(!1):"none"===e.result&&(frontendConfig.authenticationEnabled||i&&i(!1))},error:function(e){arangoHelper.arangoError("User","Could not fetch collection permissions.")}})},getFoxxFlag:function(){var e;return $("#new-app-replace").prop("checked")?e=!0:$("#new-app-teardown").prop("checked")&&(e=!1),e},createMountPointModal:function(e,t,i){var n,o=[],a=[];window.App.replaceApp&&(n=(n=window.App.replaceAppData.mount).substr(1,n.length)),a.push(window.modalView.createTextEntry("new-app-mount","Mount point",n,"The path the app will be mounted. Is not allowed to start with _","mountpoint",!1,[{rule:Joi.string().required(),msg:""}])),a.push(window.modalView.createCheckboxEntry("new-app-teardown","Run setup?",!0,"Should this app's setup script be executed after installing the app?",!0)),window.App.replaceApp?(a.push(window.modalView.createCheckboxEntry("new-app-replace","Keep configuration and dependency files?",!0,"Should this app's configuration be saved before replacing the app?",!1)),o.push(window.modalView.createSuccessButton("Replace",e))):o.push(window.modalView.createSuccessButton("Install",e));var r="Create Foxx Service";window.App.replaceApp&&(r="Replace Foxx Service ("+window.App.replaceAppData.mount+")"),window.modalView.show("modalTable.ejs",r,o,a),window.App.replaceApp?($("#new-app-mount").attr("disabled","true"),$("#new-app-replace").attr("checked",!1),$("#new-app-replace").on("click",function(){$("#new-app-replace").prop("checked")?$("#new-app-teardown").attr("disabled",!0):$("#new-app-teardown").attr("disabled",!1)})):window.modalView.modalBindValidation({id:"new-app-mount",validateInput:function(){return[{rule:Joi.string().regex(/(\/|^)APP(\/|$)/i,{invert:!0}),msg:"May not contain APP"},{rule:Joi.string().regex(/^([a-zA-Z0-9_\-/]+)+$/),msg:"Can only contain [a-zA-Z0-9_-/]"},{rule:Joi.string().regex(/([^_]|_open\/)/),msg:"Mountpoints with _ are reserved for internal use"},{rule:Joi.string().regex(/[^/]$/),msg:"May not end with /"},{rule:Joi.string().required().min(1),msg:"Has to be non-empty"}]}})}}}(),function(){"use strict";if(!window.hasOwnProperty("TEST_BUILD")){window.templateEngine=new function(){var e={createTemplate:function(e){var i=$("#"+e.replace(".","\\.")).html();return{render:function(e){var t=_.template(i);return t=t(e)}}}};return e}}}(),function(){"use strict";window.dygraphConfig={defaultFrame:12e5,zeropad:function(e){return e<10?"0"+e:e},xAxisFormat:function(e){if(-1===e)return"";var t=new Date(e);return this.zeropad(t.getHours())+":"+this.zeropad(t.getMinutes())+":"+this.zeropad(t.getSeconds())},mergeObjects:function(n,o,e){e||(e=[]);var t,a={};return e.forEach(function(e){var t=n[e],i=o[e];void 0===t&&(t={}),void 0===i&&(i={}),a[e]=_.extend(t,i)}),t=_.extend(n,o),Object.keys(a).forEach(function(e){t[e]=a[e]}),t},mapStatToFigure:{pageFaults:["times","majorPageFaultsPerSecond","minorPageFaultsPerSecond"],systemUserTime:["times","systemTimePerSecond","userTimePerSecond"],totalTime:["times","avgQueueTime","avgRequestTime","avgIoTime"],dataTransfer:["times","bytesSentPerSecond","bytesReceivedPerSecond"],requests:["times","getsPerSecond","putsPerSecond","postsPerSecond","deletesPerSecond","patchesPerSecond","headsPerSecond","optionsPerSecond","othersPerSecond"]},colors:["rgb(95, 194, 135)","rgb(238, 190, 77)","#81ccd8","#7ca530","#3c3c3c","#aa90bd","#e1811d","#c7d4b2","#d0b2d4"],figureDependedOptions:{clusterRequestsPerSecond:{showLabelsOnHighlight:!0,title:"",header:"Cluster Requests per Second",stackedGraph:!0,div:"lineGraphLegend",labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}},pageFaults:{header:"Page Faults",visibility:[!0,!1],labels:["datetime","Major Page","Minor Page"],div:"pageFaultsChart",labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}},systemUserTime:{div:"systemUserTimeChart",header:"System and User Time",labels:["datetime","System Time","User Time"],stackedGraph:!0,labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}},totalTime:{div:"totalTimeChart",header:"Total Time",labels:["datetime","Queue","Computation","I/O"],labelsKMG2:!1,axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}},stackedGraph:!0},dataTransfer:{header:"Data Transfer",labels:["datetime","Bytes sent","Bytes received"],stackedGraph:!0,div:"dataTransferChart"},requests:{header:"Requests",labels:["datetime","Reads","Writes"],stackedGraph:!0,div:"requestsChart",axes:{y:{valueFormatter:function(e){return parseFloat(e.toPrecision(3))},axisLabelFormatter:function(e){return 0===e?0:parseFloat(e.toPrecision(3))}}}}},getDashBoardFigures:function(t){var i=[],n=this;return Object.keys(this.figureDependedOptions).forEach(function(e){"clusterRequestsPerSecond"!==e&&(n.figureDependedOptions[e].div||t)&&i.push(e)}),i},getDefaultConfig:function(e){var t=this,i={digitsAfterDecimal:1,drawGapPoints:!0,fillGraph:!0,fillAlpha:.85,showLabelsOnHighlight:!1,strokeWidth:0,lineWidth:0,strokeBorderWidth:0,includeZero:!0,highlightCircleSize:2.5,labelsSeparateLines:!0,strokeBorderColor:"rgba(0,0,0,0)",interactionModel:{},maxNumberWidth:10,colors:[this.colors[0]],xAxisLabelWidth:"50",rightGap:15,showRangeSelector:!1,rangeSelectorHeight:50,rangeSelectorPlotStrokeColor:"#365300",rangeSelectorPlotFillColor:"",pixelsPerLabel:50,labelsKMG2:!0,dateWindow:[(new Date).getTime()-this.defaultFrame,(new Date).getTime()],axes:{x:{valueFormatter:function(e){return t.xAxisFormat(e)}},y:{ticker:Dygraph.numericLinearTicks}}};return this.figureDependedOptions[e]&&(i=this.mergeObjects(i,this.figureDependedOptions[e],["axes"])).div&&i.labels&&(i.colors=this.getColors(i.labels),i.labelsDiv=document.getElementById(i.div+"Legend"),i.legend="always",i.showLabelsOnHighlight=!0),i},getDetailChartConfig:function(e){var t=_.extend(this.getDefaultConfig(e),{showRangeSelector:!0,interactionModel:null,showLabelsOnHighlight:!0,highlightCircleSize:2.5,legend:"always",labelsDiv:"div#detailLegend.dashboard-legend-inner"});return"pageFaults"===e&&(t.visibility=[!0,!0]),t.labels||(t.labels=["datetime",t.header],t.colors=this.getColors(t.labels)),t},getColors:function(e){return this.colors.concat([]).slice(0,e.length-1)}}}(),function(){"use strict";window.arangoCollectionModel=Backbone.Model.extend({idAttribute:"name",urlRoot:arangoHelper.databaseUrl("/_api/collection"),defaults:{id:"",name:"",status:"",type:"",isSystem:!1,picture:"",locked:!1,desc:void 0},getProperties:function(t){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/collection/"+encodeURIComponent(this.get("id"))+"/properties"),contentType:"application/json",processData:!1,success:function(e){t(!1,e)},error:function(e){t(!0,e)}})},getFigures:function(t){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/figures"),contentType:"application/json",processData:!1,success:function(e){t(!1,e)},error:function(){t(!0)}})},getRevision:function(t,i){$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/revision"),contentType:"application/json",processData:!1,success:function(e){t(!1,e,i)},error:function(){t(!0)}})},getIndex:function(t){var i=this;$.ajax({type:"GET",cache:!1,url:arangoHelper.databaseUrl("/_api/index/?collection="+this.get("id")),contentType:"application/json",processData:!1,success:function(e){t(!1,e,i.get("id"))},error:function(e){t(!0,e,i.get("id"))}})},createIndex:function(e,n){var o=this;$.ajax({cache:!1,type:"POST",url:arangoHelper.databaseUrl("/_api/index?collection="+o.get("id")),headers:{"x-arango-async":"store"},data:JSON.stringify(e),contentType:"application/json",processData:!1,success:function(e,t,i){i.getResponseHeader("x-arango-async-id")?(window.arangoHelper.addAardvarkJob({id:i.getResponseHeader("x-arango-async-id"),type:"index",desc:"Creating Index",collection:o.get("id")}),n(!1,e)):n(!0,e)},error:function(e){n(!0,e)}})},deleteIndex:function(e,n){var o=this;$.ajax({cache:!1,type:"DELETE",url:arangoHelper.databaseUrl("/_api/index/"+this.get("name")+"/"+encodeURIComponent(e)),headers:{"x-arango-async":"store"},success:function(e,t,i){i.getResponseHeader("x-arango-async-id")?(window.arangoHelper.addAardvarkJob({id:i.getResponseHeader("x-arango-async-id"),type:"index",desc:"Removing Index",collection:o.get("id")}),n(!1,e)):n(!0,e)},error:function(e){n(!0,e)}}),n()},truncateCollection:function(){var e=this;$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/truncate"),success:function(){arangoHelper.arangoNotification("Collection truncated."),$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_admin/wal/flush?waitForSync=true&waitForCollector=true"),success:function(){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+e.get("id")+"/rotate"),success:function(){},error:function(){}})},error:function(){}})},error:function(e){arangoHelper.arangoError("Collection error: "+e.responseJSON.errorMessage)}})},warmupCollection:function(){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/loadIndexesIntoMemory"),success:function(){arangoHelper.arangoNotification("Loading indexes into memory.")},error:function(e){arangoHelper.arangoError("Collection error: "+e.responseJSON.errorMessage)}})},loadCollection:function(e){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/load"),success:function(){e(!1)},error:function(){e(!0)}}),e()},unloadCollection:function(e){$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/unload?flush=true"),success:function(){e(!1)},error:function(){e(!0)}}),e()},renameCollection:function(e,t){var i=this;$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/rename"),data:JSON.stringify({name:e}),contentType:"application/json",processData:!1,success:function(){i.set("name",e),t(!1)},error:function(e){t(!0,e)}})},changeCollection:function(e,t,i,n,o){"true"===e?e=!0:"false"===e&&(e=!1);var a={waitForSync:e,journalSize:parseInt(t,10),indexBuckets:parseInt(i,10)};return n&&(a.replicationFactor=parseInt(n,10)),$.ajax({cache:!1,type:"PUT",url:arangoHelper.databaseUrl("/_api/collection/"+this.get("id")+"/properties"),data:JSON.stringify(a),contentType:"application/json",processData:!1,success:function(){o(!1)},error:function(e){o(!0,e)}}),!1}})}(),window.DatabaseModel=Backbone.Model.extend({idAttribute:"name",initialize:function(){},isNew:function(){"use strict";return!1},sync:function(e,t,i){"use strict";return"update"===e&&(e="create"),Backbone.sync(e,t,i)},url:arangoHelper.databaseUrl("/_api/database"),defaults:{}}),window.arangoDocumentModel=Backbone.Model.extend({initialize:function(){},urlRoot:arangoHelper.databaseUrl("/_api/document"),defaults:{_id:"",_rev:"",_key:""},getSorted:function(){"use strict";var t=this,e=Object.keys(t.attributes).sort(function(e,t){var i=arangoHelper.isSystemAttribute(e);return i!==arangoHelper.isSystemAttribute(t)?i?-1:1:e=this.getLastPageNumber()&&null!==this.totalAmount?this.page=this.getLastPageNumber()-1:this.page=e<1?0:e-1},getLastPageNumber:function(){return Math.max(Math.ceil(this.totalAmount/this.pagesize),1)},getOffset:function(){return this.page*this.pagesize},getPageSize:function(){return this.pagesize},setPageSize:function(e){if("all"===e)this.pagesize="all";else try{e=parseInt(e,10),this.pagesize=e}catch(e){}},setToFirst:function(){this.page=0},setToLast:function(){this.setPage(this.getLastPageNumber())},setToPrev:function(){this.setPage(this.getPage()-1)},setToNext:function(){this.setPage(this.getPage()+1)},setTotal:function(e){this.totalAmount=e},getTotal:function(){return this.totalAmount},setTotalMinusOne:function(){this.totalAmount--}})}(),window.ClusterStatisticsCollection=Backbone.Collection.extend({model:window.Statistics,url:"/_admin/statistics",updateUrl:function(){this.url=window.App.getNewRoute(this.host)+this.url},initialize:function(e,t){this.host=t.host,window.App.registerForUpdate(this)}}),function(){"use strict";window.ArangoCollections=Backbone.Collection.extend({url:arangoHelper.databaseUrl("/_api/collection"),model:arangoCollectionModel,searchOptions:{searchPhrase:null,includeSystem:!1,includeDocument:!0,includeEdge:!0,includeLoaded:!0,includeUnloaded:!0,sortBy:"name",sortOrder:1},translateStatus:function(e){switch(e){case 0:return"corrupted";case 1:return"new born collection";case 2:return"unloaded";case 3:return"loaded";case 4:return"unloading";case 5:return"deleted";case 6:return"loading";default:return"unknown"}},translateTypePicture:function(e){var t="";switch(e){case"document":t+="fa-file-text-o";break;case"edge":t+="fa-share-alt";break;case"unknown":t+="fa-question";break;default:t+="fa-cogs"}return t},parse:function(e){var t=this;return _.each(e.result,function(e){e.isSystem=arangoHelper.isSystemCollection(e),e.type=arangoHelper.collectionType(e),e.status=t.translateStatus(e.status),e.picture=t.translateTypePicture(e.type)}),e.result},getPosition:function(e){var t,i=this.getFiltered(this.searchOptions),n=null,o=null;for(t=0;t
  • '),$(this.paginationDiv).append('
    ')}})}(),function(){"use strict";window.ApplicationDetailView=Backbone.View.extend({el:"#content",divs:["#readme","#swagger","#app-info","#sideinformation","#information","#settings"],navs:["#service-info","#service-api","#service-readme","#service-settings"],template:templateEngine.createTemplate("serviceDetailView.ejs"),remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click .open":"openApp","click .delete":"deleteApp","click #app-deps":"showDepsDialog","click #app-switch-mode":"toggleDevelopment","click #app-scripts [data-script]":"runScript","click #app-tests":"runTests","click #app-replace":"replaceApp","click #download-app":"downloadApp","click .subMenuEntries li":"changeSubview","click #jsonLink":"toggleSwagger","mouseenter #app-scripts":"showDropdown","mouseleave #app-scripts":"hideDropdown"},resize:function(e){e?$(".innerContent").css("height","auto"):($(".innerContent").height($(".centralRow").height()-150),$("#swagger iframe").height($(".centralRow").height()-150),$("#swagger #swaggerJsonContent").height($(".centralRow").height()-150))},toggleSwagger:function(){var e=function(e){$("#jsonLink").html("JSON"),this.jsonEditor.setValue(JSON.stringify(e,null,"\t"),1),$("#swaggerJsonContent").show(),$("#swagger iframe").hide()}.bind(this);if("Swagger"===$("#jsonLink").html()){var t=arangoHelper.databaseUrl("/_admin/aardvark/foxxes/docs/swagger.json?mount="+encodeURIComponent(this.model.get("mount")));arangoHelper.download(t,e)}else $("#swaggerJsonContent").hide(),$("#swagger iframe").show(),$("#jsonLink").html("Swagger")},changeSubview:function(e){if(_.each(this.navs,function(e){$(e).removeClass("active")}),$(e.currentTarget).addClass("active"),_.each(this.divs,function(e){$(".headerButtonBar").hide(),$(e).hide()}),"service-readme"===e.currentTarget.id)this.resize(!0),$("#readme").show();else if("service-api"===e.currentTarget.id){this.resize(),$("#swagger").show(),$("#swaggerIframe").remove();var t=window.location.pathname.split("/"),i=window.location.protocol+"//"+window.location.hostname+":"+window.location.port+"/"+t[1]+"/"+t[2]+"/_admin/aardvark/foxxes/docs/index.html?mount="+this.model.get("mount"),n=$("')},toggleViews:function(e){var t=this,i=e.currentTarget.id.split("-")[0];_.each(["community","documentation","swagger"],function(e){i!==e?$("#"+e).hide():("swagger"===i?(t.renderSwagger(),$("#swagger iframe").css("height","100%"),$("#swagger iframe").css("width","100%"),$("#swagger iframe").css("margin-top","-13px"),t.resize()):t.resize(!0),$("#"+e).show())}),$(".subMenuEntries").children().removeClass("active"),$("#"+i+"-support").addClass("active")}})}(),function(){"use strict";window.TableView=Backbone.View.extend({template:templateEngine.createTemplate("tableView.ejs"),loading:templateEngine.createTemplate("loadingTableView.ejs"),initialize:function(e){this.rowClickCallback=e.rowClick},events:{"click .pure-table-body .pure-table-row":"rowClick","click .deleteButton":"removeClick"},rowClick:function(e){this.hasOwnProperty("rowClickCallback")&&this.rowClickCallback(e)},removeClick:function(e){this.hasOwnProperty("removeClickCallback")&&(this.removeClickCallback(e),e.stopPropagation())},setRowClick:function(e){this.rowClickCallback=e},setRemoveClick:function(e){this.removeClickCallback=e},render:function(){$(this.el).html(this.template.render({docs:this.collection}))},drawLoading:function(){$(this.el).html(this.loading.render({}))}})}(),function(){"use strict";window.UserBarView=Backbone.View.extend({events:{"change #userBarSelect":"navigateBySelect","click .tab":"navigateByTab","mouseenter .dropdown":"showDropdown","mouseleave .dropdown":"hideDropdown","click #userLogoutIcon":"userLogout","click #userLogout":"userLogout"},initialize:function(e){arangoHelper.checkDatabasePermissions(this.setUserCollectionMode.bind(this)),this.userCollection=e.userCollection,this.userCollection.fetch({cache:!1,async:!0}),this.userCollection.bind("change:extra",this.render.bind(this))},setUserCollectionMode:function(e){e&&(this.userCollection.authOptions.ro=!0)},template:templateEngine.createTemplate("userBarView.ejs"),navigateBySelect:function(){var e=$("#arangoCollectionSelect").find("option:selected").val();window.App.navigate(e,{trigger:!0})},navigateByTab:function(e){var t=e.target||e.srcElement,i=(t=$(t).closest("a")).attr("id");if("user"===i)return $("#user_dropdown").slideToggle(200),void e.preventDefault();window.App.navigate(i,{trigger:!0}),e.preventDefault()},toggleUserMenu:function(){$("#userBar .subBarDropdown").toggle()},showDropdown:function(){$("#user_dropdown").fadeIn(1)},hideDropdown:function(){$("#user_dropdown").fadeOut(1)},render:function(){if(!1!==frontendConfig.authenticationEnabled){var s=this;$("#userBar").on("click",function(){s.toggleUserMenu()}),this.userCollection.whoAmI(function(e,t){if(e)arangoHelper.arangoErro("User","Could not fetch user.");else{var i=null,n=null,o=!1,a=null;if(!1!==t){var r=function(){return frontendConfig.ldapEnabled&&s.userCollection.add({name:window.App.currentUser,user:window.App.currentUser,username:window.App.currentUser,active:!0,img:void 0}),(a=s.userCollection.findWhere({user:t})).set({loggedIn:!0}),n=a.get("extra").name,i=a.get("extra").img,o=a.get("active"),i=i?"https://s.gravatar.com/avatar/"+i+"?s=80":"img/default_user.png",n||(n=""),s.$el=$("#userBar"),s.$el.html(s.template.render({img:i,name:n,username:t,active:o})),s.delegateEvents(),s.$el};0===s.userCollection.models.length?s.userCollection.fetch({success:function(){r()}}):r()}}})}},userLogout:function(){var e=function(e){e?arangoHelper.arangoError("User","Logout error"):this.userCollection.logout()}.bind(this);this.userCollection.whoAmI(e)}})}(),function(){"use strict";window.UserManagementView=Backbone.View.extend({el:"#content",el2:"#userManagementThumbnailsIn",template:templateEngine.createTemplate("userManagementView.ejs"),remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click #createUser":"createUser","click #submitCreateUser":"submitCreateUser","click #userManagementThumbnailsIn .tile":"editUser","click #submitEditUser":"submitEditUser","click #userManagementToggle":"toggleView","keyup #userManagementSearchInput":"search","click #userManagementSearchSubmit":"search","click #callEditUserPassword":"editUserPassword","click #submitEditUserPassword":"submitEditUserPassword","click #submitEditCurrentUserProfile":"submitEditCurrentUserProfile","click .css-label":"checkBoxes","change #userSortDesc":"sorting"},dropdownVisible:!1,initialize:function(){var e=this,t=function(e,t){!0===frontendConfig.authenticationEnabled&&(e||null===t?arangoHelper.arangoError("User","Could not fetch user data"):this.currentUser=this.collection.findWhere({user:t}))}.bind(this);this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){e.collection.whoAmI(t)}})},checkBoxes:function(e){var t=e.currentTarget.id;$("#"+t).click()},sorting:function(){$("#userSortDesc").is(":checked")?this.collection.setSortingDesc(!0):this.collection.setSortingDesc(!1),$("#userManagementDropdown").is(":visible")?this.dropdownVisible=!0:this.dropdownVisible=!1,this.render()},render:function(e){var t=!1;$("#userManagementDropdown").is(":visible")&&(t=!0);var i=function(){this.collection.sort(),$(this.el).html(this.template.render({collection:this.collection,searchString:""})),!0===t&&($("#userManagementDropdown2").show(),$("#userSortDesc").attr("checked",this.collection.sortOptions.desc),$("#userManagementToggle").toggleClass("activated"),$("#userManagementDropdown").show()),e&&this.editCurrentUser(),arangoHelper.setCheckboxStatus("#userManagementDropdown")}.bind(this);return this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){i()}}),this},search:function(){var e,t,i,n;e=$("#userManagementSearchInput"),t=arangoHelper.escapeHtml($("#userManagementSearchInput").val()),n=this.collection.filter(function(e){return-1!==e.get("user").indexOf(t)}),$(this.el).html(this.template.render({collection:n,searchString:t})),i=(e=$("#userManagementSearchInput")).val().length,e.focus(),e[0].setSelectionRange(i,i)},createUser:function(e){e.preventDefault(),this.createCreateUserModal()},submitCreateUser:function(){var e=this,t=$("#newUsername").val(),i=$("#newName").val(),n=$("#newPassword").val(),o=$("#newStatus").is(":checked");if(this.validateUserInfo(i,t,n,o)){var a={user:t,passwd:n,active:o,extra:{name:i}};frontendConfig.isEnterprise&&$("#newRole").is(":checked")&&(a.user=":role:"+t,delete a.passwd),this.collection.create(a,{wait:!0,error:function(e,t){arangoHelper.parseError("User",t,e)},success:function(){e.updateUserManagement(),window.modalView.hide()}})}},validateUserInfo:function(e,t,i,n){return""!==t||(arangoHelper.arangoError("You have to define an username"),$("#newUsername").closest("th").css("backgroundColor","red"),!1)},updateUserManagement:function(){var e=this;this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){e.render()}})},editUser:function(e){if("createUser"!==$(e.currentTarget).find("a").attr("id")){$(e.currentTarget).hasClass("tile")&&(e.currentTarget=$(e.currentTarget).find(".fa")),this.collection.fetch({fetchAllUsers:!0,cache:!1});var t=this.evaluateUserName($(e.currentTarget).attr("id"),"_edit-user");""===t&&(t=$(e.currentTarget).attr("id")),window.App.navigate("user/"+encodeURIComponent(t),{trigger:!0})}},toggleView:function(){$("#userSortDesc").attr("checked",this.collection.sortOptions.desc),$("#userManagementToggle").toggleClass("activated"),$("#userManagementDropdown2").slideToggle(200)},createCreateUserModal:function(){var e=[],t=[];t.push(window.modalView.createTextEntry("newUsername","Username","",!1,"Username",!0,[{rule:Joi.string().regex(/^[a-zA-Z0-9\-_]*$/),msg:'Only symbols, "_" and "-" are allowed.'},{rule:Joi.string().required(),msg:"No username given."}])),t.push(window.modalView.createTextEntry("newName","Name","",!1,"Name",!1)),t.push(window.modalView.createPasswordEntry("newPassword","Password","",!1,"",!1)),frontendConfig.isEnterprise&&t.push(window.modalView.createCheckboxEntry("newRole","Role",!1,!1,!1)),t.push(window.modalView.createCheckboxEntry("newStatus","Active","active",!1,!0)),e.push(window.modalView.createSuccessButton("Create",this.submitCreateUser.bind(this))),window.modalView.show("modalTable.ejs","Create New User",e,t),frontendConfig.isEnterprise&&$("#newRole").on("change",function(){$("#newRole").is(":checked")?$("#newPassword").attr("disabled",!0):$("#newPassword").attr("disabled",!1)})},evaluateUserName:function(e,t){if(e){var i=e.lastIndexOf(t);return e.substring(0,i)}},updateUserProfile:function(){var e=this;this.collection.fetch({fetchAllUsers:!0,cache:!1,success:function(){e.render()}})}})}(),function(){"use strict";window.UserPermissionView=Backbone.View.extend({el:"#content",template:templateEngine.createTemplate("userPermissionView.ejs"),initialize:function(e){this.username=e.username},remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click #userPermissionView .dbCheckbox":"setDBPermission","click #userPermissionView .collCheckbox":"setCollPermission","click .db-row":"toggleAccordion"},render:function(e,t){var i=this;this.collection.fetch({fetchAllUsers:!0,success:function(){i.continueRender(e,t)}})},toggleAccordion:function(e){if(!($(e.target).attr("type")||$(e.target).parent().hasClass("noAction")||$(e.target).hasClass("inner")||$(e.target).is("span"))){var t=$(e.currentTarget).find(".collection-row").is(":visible"),i=$(e.currentTarget).attr("id").split("-")[0];$(".collection-row").hide(),$(".db-label").css("font-weight",200),$(".db-label").css("color","#8a969f"),4<$(e.currentTarget).find(".collection-row").children().length?($(".db-row .fa-caret-down").hide(),$(".db-row .fa-caret-right").show(),t?$(e.currentTarget).find(".collection-row").hide():($(e.currentTarget).find(".collection-row").fadeIn("fast"),$(e.currentTarget).find(".db-label").css("font-weight",600),$(e.currentTarget).find(".db-label").css("color","rgba(64, 74, 83, 1)"),$(e.currentTarget).find(".fa-caret-down").show(),$(e.currentTarget).find(".fa-caret-right").hide())):($(".db-row .fa-caret-down").hide(),$(".db-row .fa-caret-right").show(),arangoHelper.arangoNotification("Permissions",'No collections in "'+i+'" available.'))}},setCollPermission:function(e){var t,i=$(e.currentTarget).attr("db"),n=$(e.currentTarget).attr("collection");t=$(e.currentTarget).hasClass("readOnly")?"ro":$(e.currentTarget).hasClass("readWrite")?"rw":$(e.currentTarget).hasClass("noAccess")?"none":"undefined",this.sendCollPermission(this.currentUser.get("user"),i,n,t)},setDBPermission:function(e){var t,i=$(e.currentTarget).attr("name");if(t=$(e.currentTarget).hasClass("readOnly")?"ro":$(e.currentTarget).hasClass("readWrite")?"rw":$(e.currentTarget).hasClass("noAccess")?"none":"undefined","_system"===i){var n=[],o=[];o.push(window.modalView.createReadOnlyEntry("db-system-revoke-button","Caution","You are changing the _system database permission. Really continue?",void 0,void 0,!1)),n.push(window.modalView.createSuccessButton("Ok",this.sendDBPermission.bind(this,this.currentUser.get("user"),i,t))),n.push(window.modalView.createCloseButton("Cancel",this.rollbackInputButton.bind(this,i))),window.modalView.show("modalTable.ejs","Change _system Database Permission",n,o)}else this.sendDBPermission(this.currentUser.get("user"),i,t)},rollbackInputButton:function(e,t){var i;_.each($(".collection-row"),function(e,t){$(e).is(":visible")&&(i=$(e).parent().attr("id"))}),i?this.render(i,t):this.render(),window.modalView.hide()},sendCollPermission:function(e,t,i,n){var o=this;"undefined"===n?this.revokeCollPermission(e,t,i):$.ajax({type:"PUT",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)+"/"+encodeURIComponent(i)),contentType:"application/json",data:JSON.stringify({grant:n})}).success(function(e){o.styleDefaultRadios(null,!0)}).error(function(e){o.rollbackInputButton(null,e)})},revokeCollPermission:function(e,t,i){var n=this;$.ajax({type:"DELETE",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)+"/"+encodeURIComponent(i)),contentType:"application/json"}).success(function(e){n.styleDefaultRadios(null,!0)}).error(function(e){n.rollbackInputButton(null,e)})},sendDBPermission:function(e,t,i){var n=this;"undefined"===i?this.revokeDBPermission(e,t):$.ajax({type:"PUT",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)),contentType:"application/json",data:JSON.stringify({grant:i})}).success(function(e){n.styleDefaultRadios(null,!0)}).error(function(e){n.rollbackInputButton(null,e)})},revokeDBPermission:function(e,t){var i=this;$.ajax({type:"DELETE",url:arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(e)+"/database/"+encodeURIComponent(t)),contentType:"application/json"}).success(function(e){i.styleDefaultRadios(null,!0)}).error(function(e){i.rollbackInputButton(null,e)})},continueRender:function(t,i){var n=this;this.currentUser=this.collection.findWhere({user:this.username});var e=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(n.currentUser.get("user"))+"/database?full=true");$.ajax({type:"GET",url:e,contentType:"application/json",success:function(e){n.finishRender(e.result,t,i)},error:function(e){arangoHelper.arangoError("User","Could not fetch user permissions")}})},finishRender:function(e,t,i){var n=_.pairs(e);n.sort(),n=_.object(n),$(this.el).html(this.template.render({permissions:n})),$(".noAction").first().appendTo(".pure-table-body"),$(".pure-table-body").height(window.innerHeight-200),t&&$("#"+t).click(),i&&i.responseJSON&&i.responseJSON.errorMessage&&arangoHelper.arangoError("User",i.responseJSON.errorMessage),this.styleDefaultRadios(e),arangoHelper.createTooltips(),this.checkRoot(),this.breadcrumb()},checkRoot:function(){"root"===this.currentUser.get("user")&&$("#_system-db #___-collection input").attr("disabled","true")},styleDefaultRadios:function(e,t){var i=function(e){$(".db-row input").css("box-shadow","none");var o="rgba(0, 0, 0, 0.3) 0px 1px 4px 4px";_.each(e,function(e,i){if(e.collections){var n=e.collections["*"];_.each(e.collections,function(e,t){"_"!==t.charAt(0)&&"*"!==t.charAt(0)&&"undefined"===e&&("rw"===n?$("#"+i+"-db #"+t+"-collection .readWrite").css("box-shadow",o):"ro"===n?$("#"+i+"-db #"+t+"-collection .readOnly").css("box-shadow",o):"none"===n&&$("#"+i+"-db #"+t+"-collection .noAccess").css("box-shadow",o))})}})};if(t){var n=arangoHelper.databaseUrl("/_api/user/"+encodeURIComponent(this.currentUser.get("user"))+"/database?full=true");$.ajax({type:"GET",url:n,contentType:"application/json",success:function(e){i(e.result)},error:function(e){arangoHelper.arangoError("User","Could not fetch user permissions")}})}else i(e);window.modalView.hide()},breadcrumb:function(){var e=this;window.App.naviView?($("#subNavigationBar .breadcrumb").html("User: "+arangoHelper.escapeHtml(this.currentUser.get("user"))),arangoHelper.buildUserSubNav(e.currentUser.get("user"),"Permissions")):window.setTimeout(function(){e.breadcrumb()},100)}})}(),function(){"use strict";window.UserView=Backbone.View.extend({el:"#content",initialize:function(e){this.username=e.username},render:function(){var e=this;this.collection.fetch({fetchAllUsers:!0,success:function(){e.continueRender()}})},editCurrentUser:function(){this.createEditCurrentUserModal(this.currentUser.get("user"),this.currentUser.get("extra").name,this.currentUser.get("extra").img)},continueRender:function(){this.currentUser=this.collection.findWhere({user:this.username}),this.breadcrumb(),this.currentUser.get("loggedIn")?this.editCurrentUser():this.createEditUserModal(this.currentUser.get("user"),this.currentUser.get("extra").name,this.currentUser.get("active"))},createEditUserPasswordModal:function(){var e=[],t=[];t.push(window.modalView.createPasswordEntry("newCurrentPassword","New Password","",!1,"new password",!1)),t.push(window.modalView.createPasswordEntry("confirmCurrentPassword","Confirm New Password","",!1,"confirm new password",!1)),e.push(window.modalView.createSuccessButton("Save",this.submitEditUserPassword.bind(this))),window.modalView.show("modalTable.ejs","Edit User Password",e,t)},createEditCurrentUserModal:function(e,t,i){var n=[],o=[];o.push(window.modalView.createReadOnlyEntry("id_username","Username",e)),o.push(window.modalView.createTextEntry("editCurrentName","Name",t,!1,"Name",!1)),o.push(window.modalView.createTextEntry("editCurrentUserProfileImg","Gravatar account (Mail)",i,"Mailaddress or its md5 representation of your gravatar account.The address will be converted into a md5 string. Only the md5 string will be stored, not the mailaddress.","myAccount(at)gravatar.com")),":role:"===this.username.substring(0,6)?n.push(window.modalView.createDisabledButton("Change Password")):n.push(window.modalView.createNotificationButton("Change Password",this.editUserPassword.bind(this))),n.push(window.modalView.createSuccessButton("Save",this.submitEditCurrentUserProfile.bind(this))),window.modalView.show("modalTable.ejs","Edit User Profile",n,o,null,null,this.events,null,null,"content")},parseImgString:function(e){return-1===e.indexOf("@")?e:CryptoJS.MD5(e).toString()},createEditUserModal:function(e,t,i){var n,o;o=[{type:window.modalView.tables.READONLY,label:"Username",value:_.escape(e)},{type:window.modalView.tables.TEXT,label:"Name",value:_.escape(t),id:"editName",placeholder:"Name"},{type:window.modalView.tables.CHECKBOX,label:"Active",value:"active",checked:i,id:"editStatus"}],(n=[]).push({title:"Delete",type:window.modalView.buttons.DELETE,callback:this.submitDeleteUser.bind(this,e)}),":role:"===this.username.substring(0,6)?n.push({title:"Change Password",type:window.modalView.buttons.DISABLED,callback:this.createEditUserPasswordModal.bind(this,e)}):n.push({title:"Change Password",type:window.modalView.buttons.NOTIFICATION,callback:this.createEditUserPasswordModal.bind(this,e)}),n.push({title:"Save",type:window.modalView.buttons.SUCCESS,callback:this.submitEditUser.bind(this,e)}),window.modalView.show("modalTable.ejs","Edit User",n,o,null,null,this.events,null,null,"content")},validateStatus:function(e){return""!==e},submitDeleteUser:function(e){this.collection.findWhere({user:e}).destroy({wait:!0}),window.App.navigate("#users",{trigger:!0})},submitEditCurrentUserProfile:function(){var e=$("#editCurrentName").val(),t=$("#editCurrentUserProfileImg").val();t=this.parseImgString(t);var i=function(e){e?arangoHelper.arangoError("User","Could not edit user settings"):(arangoHelper.arangoNotification("User","Changes confirmed."),this.updateUserProfile())}.bind(this);this.currentUser.setExtras(e,t,i),window.modalView.hide()},submitEditUserPassword:function(){var e=$("#newCurrentPassword").val(),t=$("#confirmCurrentPassword").val();$("#newCurrentPassword").val(""),$("#confirmCurrentPassword").val(""),$("#newCurrentPassword").closest("th").css("backgroundColor","white"),$("#confirmCurrentPassword").closest("th").css("backgroundColor","white");var i=!1;e!==t&&(arangoHelper.arangoError("User","New passwords do not match."),i=!0),i||(this.currentUser.setPassword(e),arangoHelper.arangoNotification("User","Password changed."),window.modalView.hide())},editUserPassword:function(){window.modalView.hide(),this.createEditUserPasswordModal()},submitEditUser:function(e){var t=$("#editName").val(),i=$("#editStatus").is(":checked");if(this.validateStatus(i)){var n=this.collection.findWhere({user:e});n.save({extra:{name:t},active:i},{type:"PATCH",success:function(){arangoHelper.arangoNotification("User",n.get("user")+" updated.")},error:function(){arangoHelper.arangoError("User","Could not update "+n.get("user")+".")}})}else $("#editStatus").closest("th").css("backgroundColor","red")},breadcrumb:function(){var e=this;window.App.naviView?($("#subNavigationBar .breadcrumb").html("User: "+_.escape(this.username)),arangoHelper.buildUserSubNav(e.currentUser.get("user"),"General")):window.setTimeout(function(){e.breadcrumb()},100)}})}(),function(){"use strict";window.ViewsView=Backbone.View.extend({el:"#content",readOnly:!1,template:templateEngine.createTemplate("viewsView.ejs"),initialize:function(){},refreshRate:1e4,sortOptions:{desc:!1},searchString:"",remove:function(){return this.$el.empty().off(),this.stopListening(),this.unbind(),delete this.el,this},events:{"click #createView":"createView","click #viewsToggle":"toggleSettingsDropdown","click .tile-view":"gotoView","keyup #viewsSearchInput":"search","click #viewsSearchSubmit":"search","click #viewsSortDesc":"sorting"},checkVisibility:function(){$("#viewsDropdown").is(":visible")?this.dropdownVisible=!0:this.dropdownVisible=!1,arangoHelper.setCheckboxStatus("#viewsDropdown")},checkIfInProgress:function(){if(-1&'"]/)),e.push(window.modalView.createDeleteButton("Delete",this.deleteViewTrue.bind(this))),window.modalView.show("modalTable.ejs","Delete View",e,t)},deleteViewTrue:function(){this.model.deleteView(function(e,t){e?arangoHelper.arangoError("View","Could not delete the view."):(window.modalView.hide(),window.App.navigate("#views",{trigger:!0}))})},renameView:function(){var e=[],t=[];t.push(window.modalView.createTextEntry("editCurrentName","Name",this.name,!1,"Name",!1)),e.push(window.modalView.createSuccessButton("Rename",this.renameViewTrue.bind(this))),window.modalView.show("modalTable.ejs","Rename View",e,t)},renameViewTrue:function(){var t=this;$("#editCurrentName").val()?$.ajax({type:"PUT",cache:!1,url:arangoHelper.databaseUrl("/_api/view/"+encodeURIComponent(t.name)+"/rename"),contentType:"application/json",processData:!1,data:JSON.stringify({name:$("#editCurrentName").val()}),success:function(e){t.name=e.name,t.model.set("name",e.name),t.breadcrumb(),window.modalView.hide()},error:function(e){window.modalView.hide(),arangoHelper.arangoError("View",e.responseJSON.errorMessage)}}):arangoHelper.arangoError("View","Please fill in a view name.")},breadcrumb:function(){var e=this;window.App.naviView?($("#subNavigationBar .breadcrumb").html("View: "+arangoHelper.escapeHtml(e.name)),window.setTimeout(function(){$("#subNavigationBar .breadcrumb").html("View: "+arangoHelper.escapeHtml(e.name)),e.checkIfInProgress()},100)):window.setTimeout(function(){e.breadcrumb()},100)}})}(),function(){"use strict";window.Router=Backbone.Router.extend({toUpdate:[],dbServers:[],isCluster:void 0,lastRoute:void 0,routes:{"":"cluster",dashboard:"dashboard",replication:"replication","replication/applier/:endpoint/:database":"applier",collections:"collections",new:"newCollection",login:"login","collection/:colid/documents/:pageid":"documents","cIndices/:colname":"cIndices","cSettings/:colname":"cSettings","cInfo/:colname":"cInfo","collection/:colid/:docid":"document",shell:"shell",queries:"query",databases:"databases",settings:"databases",services:"applications","services/install":"installService","services/install/new":"installNewService","services/install/github":"installGitHubService","services/install/upload":"installUploadService","services/install/remote":"installUrlService","service/:mount":"applicationDetail","store/:name":"storeDetail",graphs:"graphManagement","graphs/:name":"showGraph",users:"userManagement","user/:name":"userView","user/:name/permission":"userPermission",userProfile:"userProfile",cluster:"cluster",nodes:"nodes",shards:"shards","node/:name":"node","nodeInfo/:id":"nodeInfo",logs:"logger",helpus:"helpUs",views:"views","view/:name":"view","graph/:name":"graph","graph/:name/settings":"graphSettings",support:"support"},execute:function(e,t){if("#queries"===this.lastRoute&&(this.queryView.removeInputEditors(),this.queryView.cleanupGraphs(),this.queryView.removeResults()),this.lastRoute){var i=this.lastRoute.split("/")[0],n=this.lastRoute.split("/")[1],o=this.lastRoute.split("/")[2];"#service"!==i&&(window.App.replaceApp?"install"!==n&&o&&(window.App.replaceApp=!1):window.App.replaceApp=!1),"#collection"===this.lastRoute.substr(0,11)&&3===this.lastRoute.split("/").length&&this.documentView.cleanupEditor(),"#dasboard"!==this.lastRoute&&"#node"!==window.location.hash.substr(0,5)||d3.selectAll("svg > *").remove(),"#logger"===this.lastRoute&&(this.loggerView.logLevelView&&this.loggerView.logLevelView.remove(),this.loggerView.logTopicView&&this.loggerView.logTopicView.remove())}this.lastRoute=window.location.hash,$("#subNavigationBar .breadcrumb").html(""),$("#subNavigationBar .bottom").html(""),$("#loadingScreen").hide(),$("#content").show(),e&&e.apply(this,t),"#services"===this.lastRoute&&(window.App.replaceApp=!1),this.graphViewer&&this.graphViewer.graphSettingsView&&this.graphViewer.graphSettingsView.hide(),this.queryView&&this.queryView.graphViewer&&this.queryView.graphViewer.graphSettingsView&&this.queryView.graphViewer.graphSettingsView.hide()},listenerFunctions:{},listener:function(i){_.each(window.App.listenerFunctions,function(e,t){e(i)})},checkUser:function(){var i=this;if("#login"!==window.location.hash){var n=function(){this.initOnce(),$(".bodyWrapper").show(),$(".navbar").show()}.bind(this),e=function(e,t){frontendConfig.authenticationEnabled?(i.currentUser=t,e||null===t?"#login"!==window.location.hash&&this.navigate("login",{trigger:!0}):n()):n()}.bind(this);frontendConfig.authenticationEnabled?this.userCollection.whoAmI(e):(this.initOnce(),$(".bodyWrapper").show(),$(".navbar").show())}},waitForInit:function(e,t,i){this.initFinished?(t||e(!0),t&&!i&&e(t,!0),t&&i&&e(t,i,!0)):setTimeout(function(){t||e(!1),t&&!i&&e(t,!1),t&&i&&e(t,i,!1)},350)},initFinished:!1,initialize:function(){!0===frontendConfig.isCluster&&(this.isCluster=!0),document.addEventListener("keyup",this.listener,!1),window.modalView=new window.ModalView,this.foxxList=new window.FoxxCollection,window.foxxInstallView=new window.FoxxInstallView({collection:this.foxxList}),this.foxxRepo=new window.FoxxRepository,this.foxxRepo.fetch({success:function(){i.serviceInstallView&&(i.serviceInstallView.collection=i.foxxRepo)}}),window.progressView=new window.ProgressView;var i=this;this.userCollection=new window.ArangoUsers,this.initOnce=function(){this.initOnce=function(){};var e=function(e,t){i=this,!0===t&&i.coordinatorCollection.fetch({success:function(){i.fetchDBS()}}),e&&console.log(e)}.bind(this);window.isCoordinator(e),!1===frontendConfig.isCluster&&(this.initFinished=!0),this.arangoDatabase=new window.ArangoDatabase,this.currentDB=new window.CurrentDatabase,this.arangoCollectionsStore=new window.ArangoCollections,this.arangoDocumentStore=new window.ArangoDocument,this.arangoViewsStore=new window.ArangoViews,this.coordinatorCollection=new window.ClusterCoordinators,window.spotlightView=new window.SpotlightView({collection:this.arangoCollectionsStore}),arangoHelper.setDocumentStore(this.arangoDocumentStore),this.arangoCollectionsStore.fetch({cache:!1}),this.footerView=new window.FooterView({collection:i.coordinatorCollection}),this.notificationList=new window.NotificationCollection,this.currentDB.fetch({cache:!1,success:function(){i.naviView=new window.NavigationView({database:i.arangoDatabase,currentDB:i.currentDB,notificationCollection:i.notificationList,userCollection:i.userCollection,isCluster:i.isCluster}),i.naviView.render()}}),this.queryCollection=new window.ArangoQueries,this.footerView.render(),window.checkVersion(),this.userConfig=new window.UserConfig({ldapEnabled:frontendConfig.ldapEnabled}),this.userConfig.fetch(),this.documentsView=new window.DocumentsView({collection:new window.ArangoDocuments,documentStore:this.arangoDocumentStore,collectionsStore:this.arangoCollectionsStore}),arangoHelper.initSigma()}.bind(this),$(window).resize(function(){i.handleResize()}),$(window).scroll(function(){})},handleScroll:function(){50<$(window).scrollTop()?($(".navbar > .secondary").css("top",$(window).scrollTop()),$(".navbar > .secondary").css("position","absolute"),$(".navbar > .secondary").css("z-index","10"),$(".navbar > .secondary").css("width",$(window).width())):($(".navbar > .secondary").css("top","0"),$(".navbar > .secondary").css("position","relative"),$(".navbar > .secondary").css("width",""))},cluster:function(e){this.checkUser(),e?!1!==this.isCluster&&void 0!==this.isCluster?(this.clusterView||(this.clusterView=new window.ClusterView({coordinators:this.coordinatorCollection,dbServers:this.dbServers})),this.clusterView.render()):"_system"===this.currentDB.get("name")?(this.routes[""]="dashboard",this.navigate("#dashboard",{trigger:!0})):(this.routes[""]="collections",this.navigate("#collections",{trigger:!0})):this.waitForInit(this.cluster.bind(this))},node:function(e,t){if(this.checkUser(),t&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.nodeView&&this.nodeView.remove(),this.nodeView=new window.NodeView({coordid:e,coordinators:this.coordinatorCollection,dbServers:this.dbServers}),this.nodeView.render()}else this.waitForInit(this.node.bind(this),e)},shards:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.shardsView&&this.shardsView.remove(),this.shardsView=new window.ShardsView({dbServers:this.dbServers}),this.shardsView.render()}else this.waitForInit(this.shards.bind(this))},nodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.nodesView&&this.nodesView.remove(),this.nodesView=new window.NodesView({}),this.nodesView.render()}else this.waitForInit(this.nodes.bind(this))},cNodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.nodesView=new window.NodesView({coordinators:this.coordinatorCollection,dbServers:this.dbServers[0],toRender:"coordinator"}),this.nodesView.render()}else this.waitForInit(this.cNodes.bind(this))},dNodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster)return!1===this.isCluster?(this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0})):void(0!==this.dbServers.length?(this.nodesView=new window.NodesView({coordinators:this.coordinatorCollection,dbServers:this.dbServers[0],toRender:"dbserver"}),this.nodesView.render()):this.navigate("#cNodes",{trigger:!0}));this.waitForInit(this.dNodes.bind(this))},sNodes:function(e){if(this.checkUser(),e&&void 0!==this.isCluster){if(!1===this.isCluster)return this.routes[""]="dashboard",void this.navigate("#dashboard",{trigger:!0});this.scaleView=new window.ScaleView({coordinators:this.coordinatorCollection,dbServers:this.dbServers[0]}),this.scaleView.render()}else this.waitForInit(this.sNodes.bind(this))},addAuth:function(e){var t=this.clusterPlan.get("user");if(!t)return e.abort(),void(this.isCheckingUser||this.requestAuth());var i=t.name,n=t.passwd,o=i.concat(":",n);e.setRequestHeader("Authorization","Basic "+btoa(o))},logger:function(e){if(this.checkUser(),e){if(!this.loggerView){var t=new window.ArangoLogs({upto:!0,loglevel:4});this.loggerView=new window.LoggerView({collection:t})}this.loggerView.render()}else this.waitForInit(this.logger.bind(this))},applicationDetail:function(e,t){if(this.checkUser(),t){var i=function(){this.hasOwnProperty("applicationDetailView")&&this.applicationDetailView.remove(),this.applicationDetailView=new window.ApplicationDetailView({model:this.foxxList.get(decodeURIComponent(e))}),this.applicationDetailView.model=this.foxxList.get(decodeURIComponent(e)),this.applicationDetailView.render("swagger")}.bind(this);0===this.foxxList.length?this.foxxList.fetch({cache:!1,success:function(){i()}}):i()}else this.waitForInit(this.applicationDetail.bind(this),e)},storeDetail:function(e,t){if(this.checkUser(),t){var i=function(){this.hasOwnProperty("storeDetailView")&&this.storeDetailView.remove(),this.storeDetailView=new window.StoreDetailView({model:this.foxxRepo.get(decodeURIComponent(e)),collection:this.foxxList}),this.storeDetailView.model=this.foxxRepo.get(decodeURIComponent(e)),this.storeDetailView.render()}.bind(this);0===this.foxxRepo.length?this.foxxRepo.fetch({cache:!1,success:function(){i()}}):i()}else this.waitForInit(this.storeDetail.bind(this),e)},login:function(){var e=function(e,t){this.loginView||(this.loginView=new window.LoginView({collection:this.userCollection})),e||null===t?this.loginView.render():this.loginView.render(!0)}.bind(this);this.userCollection.whoAmI(e)},collections:function(e){if(this.checkUser(),e){var t=this;this.collectionsView&&this.collectionsView.remove(),this.collectionsView=new window.CollectionsView({collection:this.arangoCollectionsStore}),this.arangoCollectionsStore.fetch({cache:!1,success:function(){t.collectionsView.render()}})}else this.waitForInit(this.collections.bind(this))},cIndices:function(e,t){var i=this;this.checkUser(),t?this.arangoCollectionsStore.fetch({cache:!1,success:function(){i.indicesView&&i.indicesView.remove(),i.indicesView=new window.IndicesView({collectionName:e,collection:i.arangoCollectionsStore.findWhere({name:e})}),i.indicesView.render()}}):this.waitForInit(this.cIndices.bind(this),e)},cSettings:function(e,t){var i=this;this.checkUser(),t?this.arangoCollectionsStore.fetch({cache:!1,success:function(){i.settingsView=new window.SettingsView({collectionName:e,collection:i.arangoCollectionsStore.findWhere({name:e})}),i.settingsView.render()}}):this.waitForInit(this.cSettings.bind(this),e)},cInfo:function(e,t){var i=this;this.checkUser(),t?this.arangoCollectionsStore.fetch({cache:!1,success:function(){i.infoView=new window.InfoView({collectionName:e,collection:i.arangoCollectionsStore.findWhere({name:e})}),i.infoView.render()}}):this.waitForInit(this.cInfo.bind(this),e)},documents:function(e,t,i){this.checkUser(),i?(this.documentsView&&this.documentsView.unbindEvents(),this.documentsView||(this.documentsView=new window.DocumentsView({collection:new window.ArangoDocuments,documentStore:this.arangoDocumentStore,collectionsStore:this.arangoCollectionsStore})),this.documentsView.setCollectionId(e,t),this.documentsView.render(),this.documentsView.delegateEvents()):this.waitForInit(this.documents.bind(this),e,t)},document:function(e,t,i){if(this.checkUser(),i){var n;this.documentView&&(this.documentView.defaultMode&&(n=this.documentView.defaultMode),this.documentView.remove()),this.documentView=new window.DocumentView({collection:this.arangoDocumentStore}),this.documentView.colid=e,this.documentView.defaultMode=n;var o=window.location.hash.split("/")[2],a=(o.split("%").length-1)%3;decodeURI(o)!==o&&0!=a&&(o=decodeURIComponent(o)),this.documentView.docid=o,this.documentView.render();var r=function(e,t){e?console.log("Error","Could not fetch collection type"):this.documentView.setType()}.bind(this);arangoHelper.collectionApiType(e,null,r)}else this.waitForInit(this.document.bind(this),e,t)},query:function(e){this.checkUser(),e?(this.queryView||(this.queryView=new window.QueryView({collection:this.queryCollection})),this.queryView.render()):this.waitForInit(this.query.bind(this))},graph:function(e,t){this.checkUser(),t?(this.graphViewer&&(this.graphViewer.graphSettingsView&&this.graphViewer.graphSettingsView.remove(),this.graphViewer.killCurrentGraph(),this.graphViewer.unbind(),this.graphViewer.remove()),this.graphViewer=new window.GraphViewer({name:e,documentStore:this.arangoDocumentStore,collection:new window.GraphCollection,userConfig:this.userConfig}),this.graphViewer.render()):this.waitForInit(this.graph.bind(this),e)},graphSettings:function(e,t){this.checkUser(),t?(this.graphSettingsView&&this.graphSettingsView.remove(),this.graphSettingsView=new window.GraphSettingsView({name:e,userConfig:this.userConfig}),this.graphSettingsView.render()):this.waitForInit(this.graphSettings.bind(this),e)},helpUs:function(e){this.checkUser(),e?(this.testView||(this.helpUsView=new window.HelpUsView({})),this.helpUsView.render()):this.waitForInit(this.helpUs.bind(this))},support:function(e){this.checkUser(),e?(this.testView||(this.supportView=new window.SupportView({})),this.supportView.render()):this.waitForInit(this.support.bind(this))},queryManagement:function(e){this.checkUser(),e?(this.queryManagementView&&this.queryManagementView.remove(),this.queryManagementView=new window.QueryManagementView({collection:void 0}),this.queryManagementView.render()):this.waitForInit(this.queryManagement.bind(this))},databases:function(e){if(this.checkUser(),e){var t=function(e){e?(arangoHelper.arangoError("DB","Could not get list of allowed databases"),this.navigate("#",{trigger:!0}),$("#databaseNavi").css("display","none"),$("#databaseNaviSelect").css("display","none")):(this.databaseView&&this.databaseView.remove(),this.databaseView=new window.DatabaseView({users:this.userCollection,collection:this.arangoDatabase}),this.databaseView.render())}.bind(this);arangoHelper.databaseAllowed(t)}else this.waitForInit(this.databases.bind(this))},dashboard:function(e){this.checkUser(),e?(void 0===this.dashboardView&&(this.dashboardView=new window.DashboardView({dygraphConfig:window.dygraphConfig,database:this.arangoDatabase})),this.dashboardView.render()):this.waitForInit(this.dashboard.bind(this))},replication:function(e){this.checkUser(),e?(this.replicationView||(this.replicationView=new window.ReplicationView({})),this.replicationView.render()):this.waitForInit(this.replication.bind(this))},applier:function(e,t,i){this.checkUser(),i?(void 0===this.applierView&&(this.applierView=new window.ApplierView({})),this.applierView.endpoint=atob(e),this.applierView.database=atob(t),this.applierView.render()):this.waitForInit(this.applier.bind(this),e,t)},graphManagement:function(e){this.checkUser(),e?(this.graphManagementView&&this.graphManagementView.undelegateEvents(),this.graphManagementView=new window.GraphManagementView({collection:new window.GraphCollection,collectionCollection:this.arangoCollectionsStore}),this.graphManagementView.render()):this.waitForInit(this.graphManagement.bind(this))},showGraph:function(e,t){this.checkUser(),t?this.graphManagementView?this.graphManagementView.loadGraphViewer(e):(this.graphManagementView=new window.GraphManagementView({collection:new window.GraphCollection,collectionCollection:this.arangoCollectionsStore}),this.graphManagementView.render(e,!0)):this.waitForInit(this.showGraph.bind(this),e)},applications:function(e){this.checkUser(),e?(void 0===this.applicationsView&&(this.applicationsView=new window.ApplicationsView({collection:this.foxxList})),this.applicationsView.reload()):this.waitForInit(this.applications.bind(this))},installService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceInstallView&&this.serviceInstallView.remove(),this.serviceInstallView=new window.ServiceInstallView({collection:this.foxxRepo,functionsCollection:this.foxxList}),this.serviceInstallView.render()):this.waitForInit(this.installService.bind(this))},installNewService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceNewView&&this.serviceNewView.remove(),this.serviceNewView=new window.ServiceInstallNewView({collection:this.foxxList}),this.serviceNewView.render()):this.waitForInit(this.installNewService.bind(this))},installGitHubService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceGitHubView&&this.serviceGitHubView.remove(),this.serviceGitHubView=new window.ServiceInstallGitHubView({collection:this.foxxList}),this.serviceGitHubView.render()):this.waitForInit(this.installGitHubService.bind(this))},installUrlService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceUrlView&&this.serviceUrlView.remove(),this.serviceUrlView=new window.ServiceInstallUrlView({collection:this.foxxList}),this.serviceUrlView.render()):this.waitForInit(this.installUrlService.bind(this))},installUploadService:function(e){this.checkUser(),e?(window.modalView.clearValidators(),this.serviceUploadView&&this.serviceUploadView.remove(),this.serviceUploadView=new window.ServiceInstallUploadView({collection:this.foxxList}),this.serviceUploadView.render()):this.waitForInit(this.installUploadService.bind(this))},handleSelectDatabase:function(e){this.checkUser(),e?this.naviView.handleSelectDatabase():this.waitForInit(this.handleSelectDatabase.bind(this))},handleResize:function(){this.dashboardView&&this.dashboardView.resize(),this.graphManagementView&&"graphs"===Backbone.history.getFragment()&&this.graphManagementView.handleResize($("#content").width()),this.queryView&&"queries"===Backbone.history.getFragment()&&this.queryView.resize(),this.naviView&&this.naviView.resize(),this.graphViewer&&-1'),window.parseVersions=function(e){_.isEmpty(e)?$("#currentVersion").addClass("up-to-date"):($("#currentVersion").addClass("out-of-date"),$("#currentVersion .fa").removeClass("fa-check-circle").addClass("fa-exclamation-circle"),$("#currentVersion").click(function(){!function(e,t){var i=[];i.push(window.modalView.createSuccessButton("Download Page",function(){window.open("https://www.arangodb.com/download","_blank"),window.modalView.hide()}));var n=[],o=window.modalView.createReadOnlyEntry.bind(window.modalView);n.push(o("current","Current",e.toString())),t.major&&n.push(o("major","Major",t.major.version)),t.minor&&n.push(o("minor","Minor",t.minor.version)),t.bugfix&&n.push(o("bugfix","Bugfix",t.bugfix.version)),window.modalView.show("modalTable.ejs","New Version Available",i,n)}(t,e)}))},$.ajax({type:"GET",async:!0,crossDomain:!0,timeout:3e3,dataType:"jsonp",url:"https://www.arangodb.com/repositories/versions.php?jsonp=parseVersions&version="+encodeURIComponent(t.toString()),error:function(e){200===e.status?window.activeInternetConnection=!0:window.activeInternetConnection=!1},success:function(e){window.activeInternetConnection=!0}})}})}}(),function(){"use strict";window.hasOwnProperty("TEST_BUILD")||($(document).ajaxSend(function(e,t,i){t.setRequestHeader("X-Arango-Frontend","true");var n=window.arangoHelper.getCurrentJwt();n&&t.setRequestHeader("Authorization","bearer "+n)}),$.ajaxSetup({error:function(e,t,i){401===e.status&&arangoHelper.checkJwt()}}),$(document).ready(function(){window.App=new window.Router,Backbone.history.start(),window.App.handleResize()}),$(document).click(function(e){e.stopPropagation(),$(e.target).hasClass("subBarDropdown")||$(e.target).hasClass("dropdown-header")||$(e.target).hasClass("dropdown-footer")||$(e.target).hasClass("toggle")||$("#userInfo").is(":visible")&&$(".subBarDropdown").hide()}),$("body").on("keyup",function(e){27===e.keyCode&&window.modalView&&window.modalView.hide()}))}(); \ No newline at end of file diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/app.min.js.gz b/js/apps/system/_admin/aardvark/APP/frontend/build/app.min.js.gz index 5ad1c8d77bf3e78d0b41068f8e7099bd5a032586..0c6de86bed935df75871942493311c5238ac9151 100644 GIT binary patch delta 99723 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μ=|LK9JTlrlIL0nV|;sosm2jES&n1x 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

    P3V51;wYL8XiAh|KU?=HTOPwq+4kSe}B(dbm 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 IY`{qe0PSGsm;e9( diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/index-min.html b/js/apps/system/_admin/aardvark/APP/frontend/build/index-min.html index 10f8063bd9..0ecc8938ab 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/build/index-min.html +++ b/js/apps/system/_admin/aardvark/APP/frontend/build/index-min.html @@ -3135,12 +3135,6 @@ Upload a Foxx service bundle. The Foxx service bundle should be a zip archive co <% counter++; %> <% }); %> <% } %> <% }); %>

    <% if (frontendConfig.db === '_system') { %> <% } %>
    -
    \ No newline at end of file + <% } %>
    \ No newline at end of file diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/index-min.html.gz b/js/apps/system/_admin/aardvark/APP/frontend/build/index-min.html.gz index 52c0fd4dc1416d6fb44cd0878751d73302dcb1c1..c27216060eb58a61f1e6a4c1e042b34bd5048573 100644 GIT binary patch delta 12595 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 Vc2x=3Wzn*|{{}RQ`SOtt0|5Ec9diHx delta 12662 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 k&u%0AHl|db#N;Cg^|ij)RV84TMa%a88~)}%2%--I0PHfcLjV8( diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/libs.min.js b/js/apps/system/_admin/aardvark/APP/frontend/build/libs.min.js index 3a9b14be5c..6642e6fc2b 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/build/libs.min.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/build/libs.min.js @@ -7458,7 +7458,6 @@ b){return g(a,b,c)}};var k=["getTime","getTimezoneOffset","getDay","getDate","ge !function(){function n(t,r,e){function u(n){var u=t(n),i=e>u,c=d3.extent(t.range()),o=c[0],a=c[1],f=i?e-o:a-e;return 0==f&&(f=a-o),(i?-1:1)*f*(r+1)/(r+f/Math.abs(u-e))+e}return u.distortion=function(n){return arguments.length?(r=+n,u):r},u.focus=function(n){return arguments.length?(e=+n,u):e},u.copy=function(){return n(t.copy(),r,e)},u.nice=t.nice,u.ticks=t.ticks,u.tickFormat=t.tickFormat,d3.rebind(u,t,"domain","range")}d3.fisheye={scale:function(t){return n(t(),3,0)},circular:function(){function n(n){var t=n.x-c[0],i=n.y-c[1],o=Math.sqrt(t*t+i*i);if(!o||o>=u)return{x:n.x,y:n.y,z:1};var a=r*(1-Math.exp(-o*e))/o*.75+.25;return{x:c[0]+t*a,y:c[1]+i*a,z:Math.min(a,10)}}function t(){return r=Math.exp(i),r=r/(r-1)*u,e=i/u,n}var r,e,u=200,i=2,c=[0,0];return n.radius=function(n){return arguments.length?(u=+n,t()):u},n.distortion=function(n){return arguments.length?(i=+n,t()):i},n.focus=function(t){return arguments.length?(c=t,n):c},t()}}}(); !function(a){"use strict";function n(a){}function e(a){a.stopPropagation()}a.fn.pagination=function(i){function t(n,i){var t=i>=1&&i<=l.lastPage,s=a("").append(n),r=a("
  • ").append(s);return t?(s.click(function(){l.click(i)}),a(".arango-pagination").next().children().first().removeClass("disabledPag"),a(".arango-pagination").prev().children().first().removeClass("disabledPag")):(r.addClass("disabledPag"),setTimeout(function(){a(r).find("i").hasClass("fa-angle-right")?a(".arango-pagination").next().children().first().addClass("disabledPag"):a(r).find("i").hasClass("fa-angle-left")&&a(".arango-pagination").prev().children().first().addClass("disabledPag")},50)),s.click(e),i===l.page&&r.addClass("active active-arango-pagination-button"),r}function s(){var n,e=a('
      ');for(e.append(t(l.prev,l.page-1)),n=g;p>=n;n+=1)e.append(t(n,n));return e.append(t(l.next,l.page+1))}var l=a.extend({prev:'',next:'',left:3,right:3,page:1,lastPage:1,click:n},i||{}),r=l.left+l.right,g=Math.max(1,l.page-l.left),p=g+r;return l.lastPage";_="
      ";f=":empty";L="\n";u=">>> ";l="... ";a=2;i=""+p+"ansi-";d="";$=/\[(\d*)(?:;(\d*))*m/;e=function(){t.prototype.COLORS=["black","red","green","yellow","blue","magenta","cyan","white"];function t(){this.stylize=R(this.stylize,this);this._closeSpan=R(this._closeSpan,this);this._openSpan=R(this._openSpan,this);this.getClasses=R(this.getClasses,this);this._style=R(this._style,this);this._color=R(this._color,this);this._remove=R(this._remove,this);this._append=R(this._append,this);this.klasses=[]}t.prototype._append=function(t){t=""+i+t;if(this.klasses.indexOf(t)===-1){return this.klasses.push(t)}};t.prototype._remove=function(){var t,e,s,r,o,n;s=1<=arguments.length?U.call(arguments,0):[];n=[];for(r=0,o=s.length;r'+t};t.prototype._closeSpan=function(t){return""+t+""};t.prototype.stylize=function(t){var e,i,s,r,o,n;t=this._openSpan(t);s=0;while((s=t.indexOf(d,s))&&s!==-1){if(i=t.slice(s).match($)){n=i.slice(1);for(r=0,o=n.length;r'+(e||"")+""};v=function(){function i(i,s,r,n){this._HideComposition=R(this._HideComposition,this);this._ShowComposition=R(this._ShowComposition,this);this._UpdateComposition=R(this._UpdateComposition,this);this._EndComposition=R(this._EndComposition,this);this._StartComposition=R(this._StartComposition,this);this._CheckComposition=R(this._CheckComposition,this);this._ProcessMatch=R(this._ProcessMatch,this);this._HandleKey=R(this._HandleKey,this);this._HandleChar=R(this._HandleChar,this);this.isMobile=!!navigator.userAgent.match(/iPhone|iPad|iPod|Android/i);this.isIos=!!navigator.userAgent.match(/iPhone|iPad|iPod/i);this.isAndroid=!!navigator.userAgent.match(/Android/i);this.$window=t(window);this.header=s||"";this.prompt_label_main=typeof r==="string"?r:u;this.prompt_label_continue=n||l;this.indent_width=a;this.state=W;this.input_queue=[];this.input_callback=null;this.multiline_callback=null;this.history=[];this.history_index=0;this.history_new="";this.history_active=false;this.shortcuts={};this.$container=t("
      ").appendTo(i);this.$container.css({top:0,left:0,right:0,bottom:0,position:"absolute",overflow:"auto"});this.$console=t('
      ').appendTo(this.$container);this.$console.css({margin:0,position:"relative","min-height":"100%","box-sizing":"border-box","-moz-box-sizing":"border-box","-webkit-box-sizing":"border-box"});this.$console_focused=true;this.$input_container=t(_).appendTo(this.$container);this.$input_container.css({position:"absolute",width:1,height:0,overflow:"hidden"});this.$input_source=this.isAndroid?t(""):t("