mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge branch 'dev' into staging
This commit is contained in:
commit
05db940e05
106 changed files with 1890 additions and 1109 deletions
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
|
|
@ -35,12 +35,12 @@ jobs:
|
|||
python -m pip install --no-cache-dir --require-hashes -r src/common/db/requirements.txt
|
||||
echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0
|
||||
uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql.yml
|
||||
setup-python-dependencies: false
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0
|
||||
uses: github/codeql-action/analyze@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
|
|
|||
2
.github/workflows/doc-to-pdf.yml
vendored
2
.github/workflows/doc-to-pdf.yml
vendored
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
run: mkdocs serve & sleep 10
|
||||
- name: Run pdf script
|
||||
run: node docs/misc/pdf.js http://localhost:8000/print_page/ BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf 'BunkerWeb documentation v${{ inputs.VERSION }}'
|
||||
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
- uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
path: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
|
|
|
|||
2
.github/workflows/linux-build.yml
vendored
2
.github/workflows/linux-build.yml
vendored
|
|
@ -129,7 +129,7 @@ jobs:
|
|||
scp -r root@arm:/root/package-${{ inputs.LINUX }} ./package-${{ inputs.LINUX }}
|
||||
env:
|
||||
LARCH: ${{ env.LARCH }}
|
||||
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
- uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
with:
|
||||
name: package-${{ inputs.LINUX }}-${{ env.LARCH }}
|
||||
path: package-${{ inputs.LINUX }}/*.${{ inputs.PACKAGE }}
|
||||
|
|
|
|||
2
.github/workflows/push-github.yml
vendored
2
.github/workflows/push-github.yml
vendored
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
# Get PDF doc
|
||||
- name: Get documentation
|
||||
if: inputs.VERSION != 'testing'
|
||||
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5
|
||||
with:
|
||||
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
# Create tag
|
||||
|
|
|
|||
6
.github/workflows/push-packagecloud.yml
vendored
6
.github/workflows/push-packagecloud.yml
vendored
|
|
@ -42,18 +42,18 @@ jobs:
|
|||
- name: Check out repository code
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- name: Install ruby
|
||||
uses: ruby/setup-ruby@5f19ec79cedfadb78ab837f95b87734d0003c899 # v1.173.0
|
||||
uses: ruby/setup-ruby@6bd3d993c602f6b675728ebaecb2b569ff86e99b # v1.174.0
|
||||
with:
|
||||
ruby-version: "3.0"
|
||||
- name: Install packagecloud
|
||||
run: gem install package_cloud
|
||||
# Download packages
|
||||
- uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
- uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5
|
||||
if: inputs.LINUX != 'el' && inputs.LINUX != 'el9'
|
||||
with:
|
||||
name: package-${{ inputs.LINUX }}-${{ inputs.PACKAGE_ARCH }}
|
||||
path: /tmp/${{ inputs.LINUX }}
|
||||
- uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
- uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5
|
||||
if: inputs.LINUX == 'el' || inputs.LINUX == 'el9'
|
||||
with:
|
||||
name: package-rh${{ inputs.LINUX }}-${{ inputs.PACKAGE_ARCH }}
|
||||
|
|
|
|||
2
.github/workflows/scorecards-analysis.yml
vendored
2
.github/workflows/scorecards-analysis.yml
vendored
|
|
@ -25,6 +25,6 @@ jobs:
|
|||
results_format: sarif
|
||||
publish_results: true
|
||||
- name: "Upload SARIF results to code scanning"
|
||||
uses: github/codeql-action/upload-sarif@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0
|
||||
uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
2
.github/workflows/staging-create-infra.yml
vendored
2
.github/workflows/staging-create-infra.yml
vendored
|
|
@ -52,7 +52,7 @@ jobs:
|
|||
if: always()
|
||||
env:
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
- uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||
if: always()
|
||||
with:
|
||||
name: tf-${{ inputs.TYPE }}
|
||||
|
|
|
|||
2
.github/workflows/staging-delete-infra.yml
vendored
2
.github/workflows/staging-delete-infra.yml
vendored
|
|
@ -23,7 +23,7 @@ jobs:
|
|||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- name: Install terraform
|
||||
uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
|
||||
- uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
- uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5
|
||||
with:
|
||||
name: tf-${{ inputs.TYPE }}
|
||||
path: /tmp
|
||||
|
|
|
|||
2
.github/workflows/staging-tests.yml
vendored
2
.github/workflows/staging-tests.yml
vendored
|
|
@ -43,7 +43,7 @@ jobs:
|
|||
if: inputs.TYPE == 'swarm'
|
||||
- name: Install test dependencies
|
||||
run: PIP_BREAK_SYSTEM_PACKAGES=1 pip3 install --no-cache-dir --require-hashes --no-deps -r tests/requirements.txt
|
||||
- uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
|
||||
- uses: actions/download-artifact@8caf195ad4b1dee92908e23f56eeb0696f1dd42d # v4.1.5
|
||||
with:
|
||||
name: tf-k8s
|
||||
path: /tmp
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ src/ui/templates/settings_plugins.html:hashicorp-tf-password:87
|
|||
src/ui/templates/settings_plugins.html:hashicorp-tf-password:297
|
||||
src/ui/templates/settings_plugins.html:hashicorp-tf-password:106
|
||||
src/ui/templates/account.html:hashicorp-tf-password:154
|
||||
src/ui/templates/account.html:hashicorp-tf-password:162
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
exclude: (^LICENSE.md$|^src/VERSION$|^env/|^src/(bw/misc/root-ca.pem$|deps/src/|common/core/modsecurity/files|ui/static/(js/(editor/|utils/purify/|tsparticles\.bundle\.min\.js)|css/dashboard\.css))|\.(svg|drawio|patch\d?|ascii|tf|tftpl|key)$)
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: c4a0b883114b00d8d76b479c820ce7950211c99b # frozen: v4.5.0
|
||||
rev: 2c9f875913ee60ca25ce70243dc24d5b6415598c # frozen: v4.6.0
|
||||
hooks:
|
||||
- id: requirements-txt-fixer
|
||||
name: Fix requirements.txt and requirements.in files
|
||||
|
|
@ -17,7 +17,7 @@ repos:
|
|||
- id: check-case-conflict
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 552baf822992936134cbd31a38f69c8cfe7c0f05 # frozen: 24.3.0
|
||||
rev: 8fe627072f15ff2e3d380887b92f7868efaf6d05 # frozen: 24.4.0
|
||||
hooks:
|
||||
- id: black
|
||||
name: Black Python Formatter
|
||||
|
|
|
|||
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -10,6 +10,17 @@
|
|||
- [FEATURE] Add backup plugin to backup and restore easily the database
|
||||
- [FEATURE] Add LETS_ENCRYPT_CLEAR_OLD_CERTS setting to control if old certificates should be removed when generating Let's Encrypt certificates (default is no)
|
||||
- [FEATURE] Add DISABLE_DEFAULT_SERVER_STRICT_SNI setting to allow/block requests when SNI is unknown or unset (default is no)
|
||||
- [UI] General : fix tooltip crop because of overflow
|
||||
- [UI] General : fix select setting crop because of overflow and check if select is out of viewport to determine visible position
|
||||
- [UI] General : show logs on UI when pre rendering issue
|
||||
- [UI] Global config : fix script error while fragment relate to a missing plugin
|
||||
- [UI] Global config / services page : filtering settings now open plugin select to highlight remaining plugin
|
||||
- [UI] Global config / services page : add combobox on plugin select open to search a plugin quick
|
||||
- [UI] Global config / services page : add combobox on plugin select open to search a plugin quick
|
||||
- [UI] Reporting page : fix missing data and add new ones
|
||||
- [UI] Account page : keep license key form even if pro register to easy update
|
||||
|
||||
|
||||
- [DOCUMENTATION] Add upgrade procedure for 1.5.7+
|
||||
- [MISC] Support custom bwcli commands using plugins
|
||||
- [DEPS] Updated LuaJIT version to v2.1-20240314
|
||||
|
|
|
|||
BIN
docs/assets/img/crowdity1.png
Normal file
BIN
docs/assets/img/crowdity1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
docs/assets/img/crowdity2.png
Normal file
BIN
docs/assets/img/crowdity2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
BIN
docs/assets/img/crowdity3.png
Normal file
BIN
docs/assets/img/crowdity3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/assets/img/crowdity4.png
Normal file
BIN
docs/assets/img/crowdity4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -979,6 +979,10 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
|
|||
!!! warning "Testing/dev version"
|
||||
If you use the `testing` or `dev` version, you will need to add the `force-bad-version` directive to your `/etc/dpkg/dpkg.cfg` file before installing BunkerWeb.
|
||||
|
||||
```shell
|
||||
echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg
|
||||
```
|
||||
|
||||
Optional step : if you want to automatically enable the [setup wizard](web-ui.md#setup-wizard) when BunkerWeb is installed, export the following variable :
|
||||
|
||||
```shell
|
||||
|
|
@ -1022,6 +1026,10 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
|
|||
!!! warning "Testing/dev version"
|
||||
If you use the `testing` or `dev` version, you will need to add the `force-bad-version` directive to your `/etc/dpkg/dpkg.cfg` file before installing BunkerWeb.
|
||||
|
||||
```shell
|
||||
echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg
|
||||
```
|
||||
|
||||
Optional step : if you want to automatically enable the [setup wizard](web-ui.md#setup-wizard) when BunkerWeb is installed, export the following variable :
|
||||
|
||||
```shell
|
||||
|
|
@ -1110,7 +1118,7 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
|
|||
And finally install BunkerWeb 1.5.7 :
|
||||
|
||||
```shell
|
||||
dnf install -y epel-release && \
|
||||
sudo dnf install -y epel-release && \
|
||||
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \
|
||||
sudo dnf check-update && \
|
||||
sudo -E dnf install -y bunkerweb-1.5.7
|
||||
|
|
|
|||
|
|
@ -510,100 +510,100 @@ pyyaml-env-tag==0.1 \
|
|||
--hash=sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb \
|
||||
--hash=sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069
|
||||
# via mkdocs
|
||||
regex==2023.12.25 \
|
||||
--hash=sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5 \
|
||||
--hash=sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770 \
|
||||
--hash=sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc \
|
||||
--hash=sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105 \
|
||||
--hash=sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d \
|
||||
--hash=sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b \
|
||||
--hash=sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9 \
|
||||
--hash=sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630 \
|
||||
--hash=sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6 \
|
||||
--hash=sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c \
|
||||
--hash=sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482 \
|
||||
--hash=sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6 \
|
||||
--hash=sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a \
|
||||
--hash=sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80 \
|
||||
--hash=sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5 \
|
||||
--hash=sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1 \
|
||||
--hash=sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f \
|
||||
--hash=sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf \
|
||||
--hash=sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb \
|
||||
--hash=sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2 \
|
||||
--hash=sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347 \
|
||||
--hash=sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20 \
|
||||
--hash=sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060 \
|
||||
--hash=sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5 \
|
||||
--hash=sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73 \
|
||||
--hash=sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f \
|
||||
--hash=sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d \
|
||||
--hash=sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3 \
|
||||
--hash=sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae \
|
||||
--hash=sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4 \
|
||||
--hash=sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2 \
|
||||
--hash=sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457 \
|
||||
--hash=sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c \
|
||||
--hash=sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4 \
|
||||
--hash=sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87 \
|
||||
--hash=sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0 \
|
||||
--hash=sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704 \
|
||||
--hash=sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f \
|
||||
--hash=sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f \
|
||||
--hash=sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b \
|
||||
--hash=sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5 \
|
||||
--hash=sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923 \
|
||||
--hash=sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715 \
|
||||
--hash=sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c \
|
||||
--hash=sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca \
|
||||
--hash=sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1 \
|
||||
--hash=sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756 \
|
||||
--hash=sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360 \
|
||||
--hash=sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc \
|
||||
--hash=sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445 \
|
||||
--hash=sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e \
|
||||
--hash=sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4 \
|
||||
--hash=sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a \
|
||||
--hash=sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8 \
|
||||
--hash=sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53 \
|
||||
--hash=sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697 \
|
||||
--hash=sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf \
|
||||
--hash=sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a \
|
||||
--hash=sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415 \
|
||||
--hash=sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f \
|
||||
--hash=sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9 \
|
||||
--hash=sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400 \
|
||||
--hash=sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d \
|
||||
--hash=sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392 \
|
||||
--hash=sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb \
|
||||
--hash=sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd \
|
||||
--hash=sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861 \
|
||||
--hash=sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232 \
|
||||
--hash=sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95 \
|
||||
--hash=sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7 \
|
||||
--hash=sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39 \
|
||||
--hash=sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887 \
|
||||
--hash=sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5 \
|
||||
--hash=sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39 \
|
||||
--hash=sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb \
|
||||
--hash=sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586 \
|
||||
--hash=sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97 \
|
||||
--hash=sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423 \
|
||||
--hash=sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69 \
|
||||
--hash=sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7 \
|
||||
--hash=sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1 \
|
||||
--hash=sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7 \
|
||||
--hash=sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5 \
|
||||
--hash=sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8 \
|
||||
--hash=sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91 \
|
||||
--hash=sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590 \
|
||||
--hash=sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe \
|
||||
--hash=sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c \
|
||||
--hash=sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64 \
|
||||
--hash=sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd \
|
||||
--hash=sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa \
|
||||
--hash=sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31 \
|
||||
--hash=sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988
|
||||
regex==2024.4.16 \
|
||||
--hash=sha256:00169caa125f35d1bca6045d65a662af0202704489fada95346cfa092ec23f39 \
|
||||
--hash=sha256:03576e3a423d19dda13e55598f0fd507b5d660d42c51b02df4e0d97824fdcae3 \
|
||||
--hash=sha256:03e68f44340528111067cecf12721c3df4811c67268b897fbe695c95f860ac42 \
|
||||
--hash=sha256:0534b034fba6101611968fae8e856c1698da97ce2efb5c2b895fc8b9e23a5834 \
|
||||
--hash=sha256:08dea89f859c3df48a440dbdcd7b7155bc675f2fa2ec8c521d02dc69e877db70 \
|
||||
--hash=sha256:0a38d151e2cdd66d16dab550c22f9521ba79761423b87c01dae0a6e9add79c0d \
|
||||
--hash=sha256:0c8290b44d8b0af4e77048646c10c6e3aa583c1ca67f3b5ffb6e06cf0c6f0f89 \
|
||||
--hash=sha256:10188fe732dec829c7acca7422cdd1bf57d853c7199d5a9e96bb4d40db239c73 \
|
||||
--hash=sha256:1210365faba7c2150451eb78ec5687871c796b0f1fa701bfd2a4a25420482d26 \
|
||||
--hash=sha256:12f6a3f2f58bb7344751919a1876ee1b976fe08b9ffccb4bbea66f26af6017b9 \
|
||||
--hash=sha256:159dc4e59a159cb8e4e8f8961eb1fa5d58f93cb1acd1701d8aff38d45e1a84a6 \
|
||||
--hash=sha256:20b7a68444f536365af42a75ccecb7ab41a896a04acf58432db9e206f4e525d6 \
|
||||
--hash=sha256:23cff1b267038501b179ccbbd74a821ac4a7192a1852d1d558e562b507d46013 \
|
||||
--hash=sha256:2c72608e70f053643437bd2be0608f7f1c46d4022e4104d76826f0839199347a \
|
||||
--hash=sha256:3399dd8a7495bbb2bacd59b84840eef9057826c664472e86c91d675d007137f5 \
|
||||
--hash=sha256:34422d5a69a60b7e9a07a690094e824b66f5ddc662a5fc600d65b7c174a05f04 \
|
||||
--hash=sha256:370c68dc5570b394cbaadff50e64d705f64debed30573e5c313c360689b6aadc \
|
||||
--hash=sha256:3a1018e97aeb24e4f939afcd88211ace472ba566efc5bdf53fd8fd7f41fa7170 \
|
||||
--hash=sha256:3d5ac5234fb5053850d79dd8eb1015cb0d7d9ed951fa37aa9e6249a19aa4f336 \
|
||||
--hash=sha256:4313ab9bf6a81206c8ac28fdfcddc0435299dc88cad12cc6305fd0e78b81f9e4 \
|
||||
--hash=sha256:445ca8d3c5a01309633a0c9db57150312a181146315693273e35d936472df912 \
|
||||
--hash=sha256:479595a4fbe9ed8f8f72c59717e8cf222da2e4c07b6ae5b65411e6302af9708e \
|
||||
--hash=sha256:4918fd5f8b43aa7ec031e0fef1ee02deb80b6afd49c85f0790be1dc4ce34cb50 \
|
||||
--hash=sha256:4aba818dcc7263852aabb172ec27b71d2abca02a593b95fa79351b2774eb1d2b \
|
||||
--hash=sha256:4e819a806420bc010489f4e741b3036071aba209f2e0989d4750b08b12a9343f \
|
||||
--hash=sha256:4facc913e10bdba42ec0aee76d029aedda628161a7ce4116b16680a0413f658a \
|
||||
--hash=sha256:549c3584993772e25f02d0656ac48abdda73169fe347263948cf2b1cead622f3 \
|
||||
--hash=sha256:5c02fcd2bf45162280613d2e4a1ca3ac558ff921ae4e308ecb307650d3a6ee51 \
|
||||
--hash=sha256:5f580c651a72b75c39e311343fe6875d6f58cf51c471a97f15a938d9fe4e0d37 \
|
||||
--hash=sha256:62120ed0de69b3649cc68e2965376048793f466c5a6c4370fb27c16c1beac22d \
|
||||
--hash=sha256:6295004b2dd37b0835ea5c14a33e00e8cfa3c4add4d587b77287825f3418d310 \
|
||||
--hash=sha256:65436dce9fdc0aeeb0a0effe0839cb3d6a05f45aa45a4d9f9c60989beca78b9c \
|
||||
--hash=sha256:684008ec44ad275832a5a152f6e764bbe1914bea10968017b6feaecdad5736e0 \
|
||||
--hash=sha256:684e52023aec43bdf0250e843e1fdd6febbe831bd9d52da72333fa201aaa2335 \
|
||||
--hash=sha256:6cc38067209354e16c5609b66285af17a2863a47585bcf75285cab33d4c3b8df \
|
||||
--hash=sha256:6f2f017c5be19984fbbf55f8af6caba25e62c71293213f044da3ada7091a4455 \
|
||||
--hash=sha256:743deffdf3b3481da32e8a96887e2aa945ec6685af1cfe2bcc292638c9ba2f48 \
|
||||
--hash=sha256:7571f19f4a3fd00af9341c7801d1ad1967fc9c3f5e62402683047e7166b9f2b4 \
|
||||
--hash=sha256:7731728b6568fc286d86745f27f07266de49603a6fdc4d19c87e8c247be452af \
|
||||
--hash=sha256:785c071c982dce54d44ea0b79cd6dfafddeccdd98cfa5f7b86ef69b381b457d9 \
|
||||
--hash=sha256:78fddb22b9ef810b63ef341c9fcf6455232d97cfe03938cbc29e2672c436670e \
|
||||
--hash=sha256:7bb966fdd9217e53abf824f437a5a2d643a38d4fd5fd0ca711b9da683d452969 \
|
||||
--hash=sha256:7cbc5d9e8a1781e7be17da67b92580d6ce4dcef5819c1b1b89f49d9678cc278c \
|
||||
--hash=sha256:803b8905b52de78b173d3c1e83df0efb929621e7b7c5766c0843704d5332682f \
|
||||
--hash=sha256:80b696e8972b81edf0af2a259e1b2a4a661f818fae22e5fa4fa1a995fb4a40fd \
|
||||
--hash=sha256:81500ed5af2090b4a9157a59dbc89873a25c33db1bb9a8cf123837dcc9765047 \
|
||||
--hash=sha256:89ec7f2c08937421bbbb8b48c54096fa4f88347946d4747021ad85f1b3021b3c \
|
||||
--hash=sha256:8ba6745440b9a27336443b0c285d705ce73adb9ec90e2f2004c64d95ab5a7598 \
|
||||
--hash=sha256:8c91e1763696c0eb66340c4df98623c2d4e77d0746b8f8f2bee2c6883fd1fe18 \
|
||||
--hash=sha256:8d015604ee6204e76569d2f44e5a210728fa917115bef0d102f4107e622b08d5 \
|
||||
--hash=sha256:8d1f86f3f4e2388aa3310b50694ac44daefbd1681def26b4519bd050a398dc5a \
|
||||
--hash=sha256:8f83b6fd3dc3ba94d2b22717f9c8b8512354fd95221ac661784df2769ea9bba9 \
|
||||
--hash=sha256:8fc6976a3395fe4d1fbeb984adaa8ec652a1e12f36b56ec8c236e5117b585427 \
|
||||
--hash=sha256:904c883cf10a975b02ab3478bce652f0f5346a2c28d0a8521d97bb23c323cc8b \
|
||||
--hash=sha256:911742856ce98d879acbea33fcc03c1d8dc1106234c5e7d068932c945db209c0 \
|
||||
--hash=sha256:91797b98f5e34b6a49f54be33f72e2fb658018ae532be2f79f7c63b4ae225145 \
|
||||
--hash=sha256:95399831a206211d6bc40224af1c635cb8790ddd5c7493e0bd03b85711076a53 \
|
||||
--hash=sha256:956b58d692f235cfbf5b4f3abd6d99bf102f161ccfe20d2fd0904f51c72c4c66 \
|
||||
--hash=sha256:98c1165f3809ce7774f05cb74e5408cd3aa93ee8573ae959a97a53db3ca3180d \
|
||||
--hash=sha256:9ab40412f8cd6f615bfedea40c8bf0407d41bf83b96f6fc9ff34976d6b7037fd \
|
||||
--hash=sha256:9df1bfef97db938469ef0a7354b2d591a2d438bc497b2c489471bec0e6baf7c4 \
|
||||
--hash=sha256:a01fe2305e6232ef3e8f40bfc0f0f3a04def9aab514910fa4203bafbc0bb4682 \
|
||||
--hash=sha256:a70b51f55fd954d1f194271695821dd62054d949efd6368d8be64edd37f55c86 \
|
||||
--hash=sha256:a7ccdd1c4a3472a7533b0a7aa9ee34c9a2bef859ba86deec07aff2ad7e0c3b94 \
|
||||
--hash=sha256:b340cccad138ecb363324aa26893963dcabb02bb25e440ebdf42e30963f1a4e0 \
|
||||
--hash=sha256:b74586dd0b039c62416034f811d7ee62810174bb70dffcca6439f5236249eb09 \
|
||||
--hash=sha256:b9d320b3bf82a39f248769fc7f188e00f93526cc0fe739cfa197868633d44701 \
|
||||
--hash=sha256:ba2336d6548dee3117520545cfe44dc28a250aa091f8281d28804aa8d707d93d \
|
||||
--hash=sha256:ba8122e3bb94ecda29a8de4cf889f600171424ea586847aa92c334772d200331 \
|
||||
--hash=sha256:bd727ad276bb91928879f3aa6396c9a1d34e5e180dce40578421a691eeb77f47 \
|
||||
--hash=sha256:c21fc21a4c7480479d12fd8e679b699f744f76bb05f53a1d14182b31f55aac76 \
|
||||
--hash=sha256:c2d0e7cbb6341e830adcbfa2479fdeebbfbb328f11edd6b5675674e7a1e37730 \
|
||||
--hash=sha256:c2ef6f7990b6e8758fe48ad08f7e2f66c8f11dc66e24093304b87cae9037bb4a \
|
||||
--hash=sha256:c4ed75ea6892a56896d78f11006161eea52c45a14994794bcfa1654430984b22 \
|
||||
--hash=sha256:cccc79a9be9b64c881f18305a7c715ba199e471a3973faeb7ba84172abb3f317 \
|
||||
--hash=sha256:d0800631e565c47520aaa04ae38b96abc5196fe8b4aa9bd864445bd2b5848a7a \
|
||||
--hash=sha256:d2da13568eff02b30fd54fccd1e042a70fe920d816616fda4bf54ec705668d81 \
|
||||
--hash=sha256:d61ae114d2a2311f61d90c2ef1358518e8f05eafda76eaf9c772a077e0b465ec \
|
||||
--hash=sha256:d83c2bc678453646f1a18f8db1e927a2d3f4935031b9ad8a76e56760461105dd \
|
||||
--hash=sha256:dd5acc0a7d38fdc7a3a6fd3ad14c880819008ecb3379626e56b163165162cc46 \
|
||||
--hash=sha256:df79012ebf6f4efb8d307b1328226aef24ca446b3ff8d0e30202d7ebcb977a8c \
|
||||
--hash=sha256:e0a2df336d1135a0b3a67f3bbf78a75f69562c1199ed9935372b82215cddd6e2 \
|
||||
--hash=sha256:e2f142b45c6fed48166faeb4303b4b58c9fcd827da63f4cf0a123c3480ae11fb \
|
||||
--hash=sha256:e697e1c0238133589e00c244a8b676bc2cfc3ab4961318d902040d099fec7483 \
|
||||
--hash=sha256:e757d475953269fbf4b441207bb7dbdd1c43180711b6208e129b637792ac0b93 \
|
||||
--hash=sha256:e87ab229332ceb127a165612d839ab87795972102cb9830e5f12b8c9a5c1b508 \
|
||||
--hash=sha256:ea355eb43b11764cf799dda62c658c4d2fdb16af41f59bb1ccfec517b60bcb07 \
|
||||
--hash=sha256:ec7e0043b91115f427998febaa2beb82c82df708168b35ece3accb610b91fac1 \
|
||||
--hash=sha256:eeaa0b5328b785abc344acc6241cffde50dc394a0644a968add75fcefe15b9d4 \
|
||||
--hash=sha256:f2d80a6749724b37853ece57988b39c4e79d2b5fe2869a86e8aeae3bbeef9eb0 \
|
||||
--hash=sha256:fa454d26f2e87ad661c4f0c5a5fe4cf6aab1e307d1b94f16ffdfcb089ba685c0 \
|
||||
--hash=sha256:fb83cc090eac63c006871fd24db5e30a1f282faa46328572661c0a24a2323a08 \
|
||||
--hash=sha256:fd80d1280d473500d8086d104962a82d77bfbf2b118053824b7be28cd5a79ea5
|
||||
# via mkdocs-material
|
||||
requests==2.31.0 \
|
||||
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
||||
|
|
|
|||
|
|
@ -442,10 +442,72 @@ BunkerNet is a crowdsourced database of malicious requests shared between all Bu
|
|||
|
||||
If you enable BunkerNet, malicious requests will be sent to a remote server and will be analyzed by our systems. By doing so, we can extract malicious data from everyone's reports and give back the results to each BunkerWeb instances participating into BunkerNet.
|
||||
|
||||
At the moment, that feature should be considered in "beta". We only extract malicious IP and we are very strict about how we do it to avoid any "poisoning". We strongly recommend activating it (which is the default) because the more instances participate, the more data we have to improve the algorithm.
|
||||
Besides the enhanced security, enabling BunkerNet will let you benefit from extra features such as the integration with CrowdSec Console.
|
||||
|
||||
The setting used to enable or disable BunkerNet is `USE_BUNKERNET` (default : `yes`).
|
||||
|
||||
### CrowdSec Console integration
|
||||
|
||||
If you don't already know about it, [CrowdSec](https://www.crowdsec.net/?utm_campaign=bunkerweb&utm_source=doc) is an open-source cybersecurity solution leveraging crowdsourced intelligence to mitigate cyber threats. Think of it like Waze but applied to cybersecurity : when a specific server is attacked, other systems around the globe will be informed and protected from the same attackers. You will find more information on their website [here](https://www.crowdsec.net/about?utm_campaign=bunkerweb&utm_source=blog).
|
||||
|
||||
Thanks to a partnership with CrowdSec, you can enroll your BunkerWeb instances to your [CrowdSec Console](https://app.crowdsec.net/signup?utm_source=external-blog&utm_medium=cta&utm_campaign=bunker-web-integration). In other words, the attacks blocked by BunkerWeb will be visible the same way it does for attacks blocked by CrowdSec Security Engines.
|
||||
|
||||
Please note that CrowdSec doesn't need to be installed at all (even if we recommend you to try it with the [CrowdSec plugin for BunkerWeb](https://github.com/bunkerity/bunkerweb-plugins/tree/main/crowdsec) to enhance the security of your web services) and you can still enroll your Security Engines into the same Console account.
|
||||
|
||||
**Step #1 : create your CrowdSec Console account**
|
||||
|
||||
Go to the [CrowdSec Console](https://app.crowdsec.net/signup?utm_source=external-blog&utm_medium=cta&utm_campaign=bunker-web-integration) and register your account if you don't already have one. Once it's done, write down your enroll key by going to "Security Engines", then "Engines" and click on "Add Security Engine" :
|
||||
|
||||
<figure markdown>
|
||||
{ align=center }
|
||||
<figcaption>Get your Crowdsec Console enroll key</figcaption>
|
||||
</figure>
|
||||
|
||||
**Step #2 : get your BunkerNet ID**
|
||||
|
||||
Activating the BunkerNet feature (which is the case by default) is mandatory if you want to enroll your BunkerWeb instance(s) into your CrowdSec console. You can do it by setting `USE_BUNKERNET` to `yes`.
|
||||
|
||||
Get your BunkerNet ID on Docker :
|
||||
|
||||
```shell
|
||||
docker exec my-bw-scheduler cat /var/cache/bunkerweb/bunkernet/instance.id
|
||||
```
|
||||
|
||||
Get your BunkerNet ID on Linux :
|
||||
|
||||
```shell
|
||||
cat /var/cache/bunkerweb/bunkernet/instance.id
|
||||
```
|
||||
|
||||
**Step #3 : enroll your instance using the Panel**
|
||||
|
||||
Once you have noted your BunkerNet ID and CrowdSec Console enroll key, you can [order the free product "BunkerNet / CrowdSec" on the Panel](https://panel.bunkerweb.io/order/bunkernet/11?utm_campaign=self&utm_source=doc). Please note that you will need to create an account if you don't already have one.
|
||||
|
||||
You can now select the "BunkerNet / CrowdSec" service and fill out the form by pasting your BunkerNet ID and CrowdSec Console enroll key :
|
||||
|
||||
<figure markdown>
|
||||
{ align=center }
|
||||
<figcaption>Enroll your BunkerWeb instance into the CrowdSec Console</figcaption>
|
||||
</figure>
|
||||
|
||||
**Step #4 : accept new security engine on the Console**
|
||||
|
||||
Last but not least, you need to go back to your CrowdSec Console and accept the new Security Engine :
|
||||
|
||||
<figure markdown>
|
||||
{ align=center }
|
||||
<figcaption>Accept enroll into the CrowdSec Console</figcaption>
|
||||
</figure>
|
||||
|
||||
**Congratulations, your BunkerWeb instance is now enrolled into your CrowdSec Console !**
|
||||
|
||||
Pro tip : when viewing your alerts, click on "columns" and tick the "context" checkbox to get access to BunkerWeb specific data.
|
||||
|
||||
<figure markdown>
|
||||
{ align=center }
|
||||
<figcaption>BunkerWeb data shown in the context column</figcaption>
|
||||
</figure>
|
||||
|
||||
## DNSBL
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
|
@ -640,9 +702,11 @@ The Reporting plugin provides a comprehensive solution for regular reporting of
|
|||
|
||||
## Backup and restore
|
||||
|
||||
### Backup
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
||||
### Automated backup
|
||||
#### Automated backup
|
||||
|
||||
!!! warning "Information for Red Hat Enterprise Linux (RHEL) 8.9 users"
|
||||
If you are using **RHEL 8.9** and plan on using an **external database**, you will need to install the `mysql-community-client` package to ensure the `mysqldump` command is available. You can install the package by executing the following commands:
|
||||
|
|
@ -696,7 +760,7 @@ Data is invaluable, especially in digital environments where it's susceptible to
|
|||
| `BACKUP_SCHEDULE` | `daily` | global | no | The frequency of the backup |
|
||||
| `BACKUP_ROTATION` | `7` | global | no | The number of backups to keep |
|
||||
|
||||
### Manual backup
|
||||
#### Manual backup
|
||||
|
||||
To manually initiate a backup, execute the following command:
|
||||
|
||||
|
|
@ -725,7 +789,11 @@ You can also specify a custom directory for the backup by providing the `BACKUP_
|
|||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it -e BACKUP_DIRECTORY=/path/to/backup/directory -v /path/to/backup/directory:/path/to/backup/directory <scheduler_container> bwcli plugin backup save
|
||||
docker exec -it -e BACKUP_DIRECTORY=/path/to/backup/directory <scheduler_container> bwcli plugin backup save
|
||||
```
|
||||
|
||||
```bash
|
||||
docker cp <scheduler_container>:/path/to/backup/directory /path/to/backup/directory
|
||||
```
|
||||
|
||||
!!! note "Specifications for MariaDB/MySQL"
|
||||
|
|
@ -762,7 +830,7 @@ You can also specify a custom directory for the backup by providing the `BACKUP_
|
|||
...
|
||||
```
|
||||
|
||||
### Manual restore
|
||||
#### Manual restore
|
||||
|
||||
To manually initiate a restore, execute the following command:
|
||||
|
||||
|
|
@ -791,7 +859,11 @@ You can also specify a custom backup file for the restore by providing the path
|
|||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it -v /path/to/backup/file:/path/to/backup/file <scheduler_container> bwcli plugin backup restore /path/to/backup/file
|
||||
docker cp /path/to/backup/file <scheduler_container>:/path/to/backup/file
|
||||
```
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin backup restore /path/to/backup/file
|
||||
```
|
||||
|
||||
!!! example "In case of failure"
|
||||
|
|
@ -807,5 +879,291 @@ You can also specify a custom backup file for the restore by providing the path
|
|||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it -e BACKUP_DIRECTORY=/var/tmp/bunkerweb/backups -v /var/tmp/bunkerweb/backups:/var/tmp/bunkerweb/backups <scheduler_container> bwcli plugin backup restore
|
||||
docker cp <scheduler_container>:/var/tmp/bunkerweb/backups /var/tmp/bunkerweb/backups
|
||||
```
|
||||
|
||||
```bash
|
||||
docker exec -it -e BACKUP_DIRECTORY=/var/tmp/bunkerweb/backups <scheduler_container> bwcli plugin backup restore
|
||||
```
|
||||
|
||||
### Backup S3 <img src='../assets/img/pro-icon.svg' alt='crow pro icon' height='24px' width='24px' style="transform : translateY(3px);"> (PRO)
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
||||
The Backup S3 tool seamlessly automates data protection, similar to the community backup plugin. However, it stands out by securely storing backups directly in an S3 bucket.
|
||||
|
||||
By activating this feature, you're proactively safeguarding your **data's integrity**. Storing backups **remotely** shields crucial information from threats like **hardware failures**, **cyberattacks**, or **natural disasters**. This ensures both **security** and **availability**, enabling swift recovery during **unexpected events**, preserving **operational continuity**, and ensuring **peace of mind**.
|
||||
|
||||
!!! warning "Information for Red Hat Enterprise Linux (RHEL) 8.9 users"
|
||||
If you are using **RHEL 8.9** and plan on using an **external database**, you will need to install the `mysql-community-client` package to ensure the `mysqldump` command is available. You can install the package by executing the following commands:
|
||||
|
||||
=== "MySQL/MariaDB"
|
||||
|
||||
1. **Install the MySQL repository configuration package**
|
||||
|
||||
```bash
|
||||
sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm
|
||||
```
|
||||
|
||||
2. **Enable the MySQL repository**
|
||||
|
||||
```bash
|
||||
sudo dnf config-manager --enable mysql80-community
|
||||
```
|
||||
|
||||
3. **Install the MySQL client**
|
||||
|
||||
```bash
|
||||
sudo dnf install mysql-community-client
|
||||
```
|
||||
|
||||
=== "PostgreSQL"
|
||||
|
||||
1. **Install the PostgreSQL repository configuration package**
|
||||
|
||||
```bash
|
||||
dnf install "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-$(uname -m)/pgdg-redhat-repo-latest.noarch.rpm"
|
||||
```
|
||||
|
||||
2. **Install the PostgreSQL client**
|
||||
|
||||
```bash
|
||||
dnf install postgresql<version>
|
||||
```
|
||||
|
||||
**List of features**
|
||||
|
||||
- Automatic data backup to an S3 bucket
|
||||
- Flexible scheduling options: daily, weekly, or monthly
|
||||
- Rotation management for controlling the number of backups to keep
|
||||
- Customizable compression level for backup files
|
||||
|
||||
**List of settings**
|
||||
|
||||
| Setting | Default | Context | Description |
|
||||
| ----------------------------- | ------- | ------- | ------------------------------------------------ |
|
||||
| `USE_BACKUP_S3` | `no` | global | Enable or disable the S3 backup feature |
|
||||
| `BACKUP_S3_SCHEDULE` | `daily` | global | Frequency of the backup (daily, weekly, monthly) |
|
||||
| `BACKUP_S3_ROTATION` | `7` | global | Number of backups to keep |
|
||||
| `BACKUP_S3_ENDPOINT` | | global | S3 endpoint |
|
||||
| `BACKUP_S3_BUCKET` | | global | S3 bucket name |
|
||||
| `BACKUP_S3_REGION` | | global | S3 region |
|
||||
| `BACKUP_S3_ACCESS_KEY_ID` | | global | S3 access key ID |
|
||||
| `BACKUP_S3_ACCESS_KEY_SECRET` | | global | S3 access key secret |
|
||||
| `BACKUP_S3_COMP_LEVEL` | `6` | global | Compression level of the backup zip file (1-9) |
|
||||
|
||||
#### Manual backup
|
||||
|
||||
To manually initiate a backup, execute the following command:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
bwcli plugin backup_s3 save
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin backup_s3 save
|
||||
```
|
||||
|
||||
This command will create a backup of your database and store it in the S3 bucket specified in the `BACKUP_S3_BUCKET` setting.
|
||||
|
||||
You can also specify a custom S3 bucket for the backup by providing the `BACKUP_S3_BUCKET` environment variable when executing the command:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
BACKUP_S3_BUCKET=your-bucket-name bwcli plugin backup_s3 save
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it -e BACKUP_S3_BUCKET=your-bucket-name <scheduler_container> bwcli plugin backup_s3 save
|
||||
```
|
||||
|
||||
!!! note "Specifications for MariaDB/MySQL"
|
||||
|
||||
In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:
|
||||
|
||||
```bash
|
||||
caching_sha2_password could not be loaded: Error loading shared library /usr/lib/mariadb/plugin/caching_sha2_password.so
|
||||
```
|
||||
|
||||
To resolve this issue, you can execute the following command to change the authentication plugin to `mysql_native_password`:
|
||||
|
||||
```sql
|
||||
ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';
|
||||
```
|
||||
|
||||
If you're using the Docker integration, you can add the following command to the `docker-compose.yml` file to automatically change the authentication plugin:
|
||||
|
||||
=== "MariaDB"
|
||||
|
||||
```yaml
|
||||
bw-db:
|
||||
image: mariadb:<version>
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
...
|
||||
```
|
||||
|
||||
=== "MySQL"
|
||||
|
||||
```yaml
|
||||
bw-db:
|
||||
image: mysql:<version>
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
...
|
||||
```
|
||||
|
||||
#### Manual restore
|
||||
|
||||
To manually initiate a restore, execute the following command:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
bwcli plugin backup_s3 restore
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin backup_s3 restore
|
||||
```
|
||||
|
||||
This command will create a temporary backup of your database in the S3 bucket specified in the `BACKUP_S3_BUCKET` setting and restore your database to the latest backup available in the bucket.
|
||||
|
||||
You can also specify a custom backup file for the restore by providing the path to it as an argument when executing the command:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
bwcli plugin backup_s3 restore s3_backup_file.zip
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin backup restore s3_backup_file.zip
|
||||
```
|
||||
|
||||
!!! example "In case of failure"
|
||||
|
||||
Don't worry if the restore fails, you can always restore your database to the previous state by executing the command again as a backup is created before the restore:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
bwcli plugin backup_s3 restore
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin backup_s3 restore
|
||||
```
|
||||
|
||||
## Migration of BunkerWeb
|
||||
|
||||
### Migration <img src='../assets/img/pro-icon.svg' alt='crow pro icon' height='24px' width='24px' style="transform : translateY(3px);"> (PRO)
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
||||
The Migration tool **revolutionizes** BunkerWeb configuration transfers between instances with its **user-friendly web interface**, simplifying the entire migration journey. Whether you're upgrading systems, scaling infrastructure, or transitioning environments, this tool empowers you to effortlessly transfer **settings, preferences, and data** with unmatched ease and confidence. Say goodbye to cumbersome manual processes and hello to a **seamless, hassle-free migration experience**.
|
||||
|
||||
**List of features**
|
||||
|
||||
- **Effortless Migration:** Easily transfer BunkerWeb configurations between instances without the complexities of manual procedures.
|
||||
|
||||
- **Intuitive Web Interface:** Navigate through the migration process effortlessly with a user-friendly web interface designed for intuitive operation.
|
||||
|
||||
- **Cross-Database Compatibility:** Enjoy seamless migration across various database platforms, including SQLite, MySQL, MariaDB, and PostgreSQL, ensuring compatibility with your preferred database environment.
|
||||
|
||||
#### Create a migration file
|
||||
|
||||
To manually create a migration file, execute the following command:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
bwcli plugin migration create /path/to/migration/file
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
1. Create a migration file:
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin migration create /path/to/migration/file
|
||||
```
|
||||
|
||||
2. Copy the migration file to your local machine:
|
||||
|
||||
```bash
|
||||
docker cp <scheduler_container>:/path/to/migration/file /path/to/migration/file
|
||||
```
|
||||
|
||||
This command will create a backup of your database and store it in the backup directory specified in the command.
|
||||
|
||||
!!! note "Specifications for MariaDB/MySQL"
|
||||
|
||||
In case you are using MariaDB/MySQL, you may encounter the following error when trying to backup your database:
|
||||
|
||||
```bash
|
||||
caching_sha2_password could not be loaded: Error loading shared library /usr/lib/mariadb/plugin/caching_sha2_password.so
|
||||
```
|
||||
|
||||
To resolve this issue, you can execute the following command to change the authentication plugin to `mysql_native_password`:
|
||||
|
||||
```sql
|
||||
ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';
|
||||
```
|
||||
|
||||
If you're using the Docker integration, you can add the following command to the `docker-compose.yml` file to automatically change the authentication plugin:
|
||||
|
||||
=== "MariaDB"
|
||||
|
||||
```yaml
|
||||
bw-db:
|
||||
image: mariadb:<version>
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
...
|
||||
```
|
||||
|
||||
=== "MySQL"
|
||||
|
||||
```yaml
|
||||
bw-db:
|
||||
image: mysql:<version>
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
...
|
||||
```
|
||||
|
||||
#### Initialize a migration
|
||||
|
||||
To manually initialize a migration, execute the following command:
|
||||
|
||||
=== "Linux"
|
||||
|
||||
```bash
|
||||
bwcli plugin migration migrate /path/to/migration/file
|
||||
```
|
||||
|
||||
=== "Docker"
|
||||
|
||||
1. Copy the migration file to the container:
|
||||
|
||||
```bash
|
||||
docker cp /path/to/migration/file <scheduler_container>:/path/to/migration/file
|
||||
```
|
||||
|
||||
2. Initialize the migration:
|
||||
|
||||
```bash
|
||||
docker exec -it <scheduler_container> bwcli plugin migration migrate /path/to/migration/file
|
||||
```
|
||||
|
||||
This command seamlessly migrates your BunkerWeb data to precisely match the configuration outlined in the migration file.
|
||||
|
|
|
|||
|
|
@ -15,41 +15,42 @@ When settings are considered as "multiple", it means that you can have multiple
|
|||
|
||||
STREAM support :warning:
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|------------------------------|------------------------------------------------------------------------------------------------------------------------|---------|--------|------------------------------------------------------------|
|
||||
|`IS_LOADING` |`no` |global |no |Internal use : set to yes when BW is loading. |
|
||||
|`NGINX_PREFIX` |`/etc/nginx/` |global |no |Where nginx will search for configurations. |
|
||||
|`HTTP_PORT` |`8080` |global |no |HTTP port number which bunkerweb binds to. |
|
||||
|`HTTPS_PORT` |`8443` |global |no |HTTPS port number which bunkerweb binds to. |
|
||||
|`MULTISITE` |`no` |global |no |Multi site activation. |
|
||||
|`SERVER_NAME` |`www.example.com` |multisite|no |List of the virtual hosts served by bunkerweb. |
|
||||
|`WORKER_PROCESSES` |`auto` |global |no |Number of worker processes. |
|
||||
|`WORKER_RLIMIT_NOFILE` |`2048` |global |no |Maximum number of open files for worker processes. |
|
||||
|`WORKER_CONNECTIONS` |`1024` |global |no |Maximum number of connections per worker. |
|
||||
|`LOG_FORMAT` |`$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"`|global |no |The format to use for access logs. |
|
||||
|`LOG_LEVEL` |`notice` |global |no |The level to use for error logs. |
|
||||
|`DNS_RESOLVERS` |`127.0.0.11` |global |no |DNS addresses of resolvers to use. |
|
||||
|`DATASTORE_MEMORY_SIZE` |`64m` |global |no |Size of the internal datastore. |
|
||||
|`CACHESTORE_MEMORY_SIZE` |`64m` |global |no |Size of the internal cachestore. |
|
||||
|`CACHESTORE_IPC_MEMORY_SIZE` |`16m` |global |no |Size of the internal cachestore (ipc). |
|
||||
|`CACHESTORE_MISS_MEMORY_SIZE` |`16m` |global |no |Size of the internal cachestore (miss). |
|
||||
|`CACHESTORE_LOCKS_MEMORY_SIZE`|`16m` |global |no |Size of the internal cachestore (locks). |
|
||||
|`USE_API` |`yes` |global |no |Activate the API to control BunkerWeb. |
|
||||
|`API_HTTP_PORT` |`5000` |global |no |Listen port number for the API. |
|
||||
|`API_LISTEN_IP` |`0.0.0.0` |global |no |Listen IP address for the API. |
|
||||
|`API_SERVER_NAME` |`bwapi` |global |no |Server name (virtual host) for the API. |
|
||||
|`API_WHITELIST_IP` |`127.0.0.0/8` |global |no |List of IP/network allowed to contact the API. |
|
||||
|`AUTOCONF_MODE` |`no` |global |no |Enable Autoconf Docker integration. |
|
||||
|`SWARM_MODE` |`no` |global |no |Enable Docker Swarm integration. |
|
||||
|`KUBERNETES_MODE` |`no` |global |no |Enable Kubernetes integration. |
|
||||
|`SERVER_TYPE` |`http` |multisite|no |Server type : http or stream. |
|
||||
|`LISTEN_STREAM` |`yes` |multisite|no |Enable listening for non-ssl (passthrough). |
|
||||
|`LISTEN_STREAM_PORT` |`1337` |multisite|no |Listening port for non-ssl (passthrough). |
|
||||
|`LISTEN_STREAM_PORT_SSL` |`4242` |multisite|no |Listening port for ssl (passthrough). |
|
||||
|`USE_UDP` |`no` |multisite|no |UDP listen instead of TCP (stream). |
|
||||
|`USE_IPV6` |`no` |global |no |Enable IPv6 connectivity. |
|
||||
|`IS_DRAFT` |`no` |multisite|no |Internal use : set to yes when the service is in draft mode.|
|
||||
|`TIMERS_LOG_LEVEL` |`debug` |global |no |Log level for timers. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|------------------------------|------------------------------------------------------------------------------------------------------------------------|---------|--------|--------------------------------------------------------------------------------------------|
|
||||
|`IS_LOADING` |`no` |global |no |Internal use : set to yes when BW is loading. |
|
||||
|`NGINX_PREFIX` |`/etc/nginx/` |global |no |Where nginx will search for configurations. |
|
||||
|`HTTP_PORT` |`8080` |global |no |HTTP port number which bunkerweb binds to. |
|
||||
|`HTTPS_PORT` |`8443` |global |no |HTTPS port number which bunkerweb binds to. |
|
||||
|`MULTISITE` |`no` |global |no |Multi site activation. |
|
||||
|`SERVER_NAME` |`www.example.com` |multisite|no |List of the virtual hosts served by bunkerweb. |
|
||||
|`WORKER_PROCESSES` |`auto` |global |no |Number of worker processes. |
|
||||
|`WORKER_RLIMIT_NOFILE` |`2048` |global |no |Maximum number of open files for worker processes. |
|
||||
|`WORKER_CONNECTIONS` |`1024` |global |no |Maximum number of connections per worker. |
|
||||
|`LOG_FORMAT` |`$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"`|global |no |The format to use for access logs. |
|
||||
|`LOG_LEVEL` |`notice` |global |no |The level to use for error logs. |
|
||||
|`DNS_RESOLVERS` |`127.0.0.11` |global |no |DNS addresses of resolvers to use. |
|
||||
|`DATASTORE_MEMORY_SIZE` |`64m` |global |no |Size of the internal datastore. |
|
||||
|`CACHESTORE_MEMORY_SIZE` |`64m` |global |no |Size of the internal cachestore. |
|
||||
|`CACHESTORE_IPC_MEMORY_SIZE` |`16m` |global |no |Size of the internal cachestore (ipc). |
|
||||
|`CACHESTORE_MISS_MEMORY_SIZE` |`16m` |global |no |Size of the internal cachestore (miss). |
|
||||
|`CACHESTORE_LOCKS_MEMORY_SIZE`|`16m` |global |no |Size of the internal cachestore (locks). |
|
||||
|`USE_API` |`yes` |global |no |Activate the API to control BunkerWeb. |
|
||||
|`API_HTTP_PORT` |`5000` |global |no |Listen port number for the API. |
|
||||
|`API_LISTEN_IP` |`0.0.0.0` |global |no |Listen IP address for the API. |
|
||||
|`API_SERVER_NAME` |`bwapi` |global |no |Server name (virtual host) for the API. |
|
||||
|`API_WHITELIST_IP` |`127.0.0.0/8` |global |no |List of IP/network allowed to contact the API. |
|
||||
|`AUTOCONF_MODE` |`no` |global |no |Enable Autoconf Docker integration. |
|
||||
|`SWARM_MODE` |`no` |global |no |Enable Docker Swarm integration. |
|
||||
|`KUBERNETES_MODE` |`no` |global |no |Enable Kubernetes integration. |
|
||||
|`SERVER_TYPE` |`http` |multisite|no |Server type : http or stream. |
|
||||
|`LISTEN_STREAM` |`yes` |multisite|no |Enable listening for non-ssl (passthrough). |
|
||||
|`LISTEN_STREAM_PORT` |`1337` |multisite|no |Listening port for non-ssl (passthrough). |
|
||||
|`LISTEN_STREAM_PORT_SSL` |`4242` |multisite|no |Listening port for ssl (passthrough). |
|
||||
|`USE_UDP` |`no` |multisite|no |UDP listen instead of TCP (stream). |
|
||||
|`USE_IPV6` |`no` |global |no |Enable IPv6 connectivity. |
|
||||
|`IS_DRAFT` |`no` |multisite|no |Internal use : set to yes when the service is in draft mode. |
|
||||
|`TIMERS_LOG_LEVEL` |`debug` |global |no |Log level for timers. |
|
||||
|`OVERRIDE_INSTANCES` | |global |no |List of BunkerWeb instances separated with spaces (format : fqdn-or-ip:5000 fqdn-or-ip:5000)|
|
||||
|
||||
|
||||
## Antibot
|
||||
|
|
|
|||
|
|
@ -470,3 +470,10 @@ In case you lost your UI credentials or have 2FA issues, you can connect to the
|
|||
```
|
||||
|
||||
You should now be able to log into the web UI only using your username and password.
|
||||
|
||||
**Upload plugin**
|
||||
|
||||
It may not be possible to upload a plugin from the UI in certain situations:
|
||||
|
||||
- Missing package to manage compressed files on your integration, in which case you will need to add the necessary packages
|
||||
- Safari browser : the 'safe mode' may prevent you from being able to add a plugin. You will need to make the necessary changes on your machine
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@
|
|||
=== "Docker"
|
||||
|
||||
```bash
|
||||
docker exec -it -e BACKUP_DIRECTORY=/path/to/backup/directory -v /path/to/backup/directory:/path/to/backup/directory <scheduler_container> bwcli plugin backup save
|
||||
docker exec -it -e BACKUP_DIRECTORY=/path/to/backup/directory <scheduler_container> bwcli plugin backup save
|
||||
```
|
||||
|
||||
```bash
|
||||
docker cp <scheduler_container>:/path/to/backup/directory /path/to/backup/directory
|
||||
```
|
||||
|
||||
=== "Linux"
|
||||
|
|
@ -47,13 +51,13 @@
|
|||
|
||||
=== "PostgreSQL"
|
||||
|
||||
1. **Install the PostgreSQL repository configuration package**
|
||||
4. **Install the PostgreSQL repository configuration package**
|
||||
|
||||
```bash
|
||||
dnf install "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-$(uname -m)/pgdg-redhat-repo-latest.noarch.rpm"
|
||||
```
|
||||
|
||||
2. **Install the PostgreSQL client**
|
||||
5. **Install the PostgreSQL client**
|
||||
|
||||
```bash
|
||||
dnf install postgresql<version>
|
||||
|
|
@ -145,13 +149,13 @@
|
|||
|
||||
=== "Linux"
|
||||
|
||||
1. **Stop the services**:
|
||||
3. **Stop the services**:
|
||||
```bash
|
||||
systemctl stop bunkerweb-scheduler
|
||||
systemctl stop bunkerweb-ui
|
||||
```
|
||||
|
||||
2. **Update BunkerWeb**:
|
||||
4. **Update BunkerWeb**:
|
||||
- Update BunkerWeb to the latest version by following the instructions in the [integration Linux page](integrations.md#linux).
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -855,6 +855,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
- www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
- www.example.com_MAX_CLIENT_SIZE=50m
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
|
@ -1040,7 +1041,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
volumes:
|
||||
bw-data:
|
||||
|
||||
|
|
@ -1195,7 +1196,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.REVERSE_PROXY_INTERCEPT_ERRORS=no"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
volumes:
|
||||
bw-data:
|
||||
|
||||
|
|
@ -1549,6 +1550,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
annotations:
|
||||
bunkerweb.io/www.example.com_USE_UI: "yes"
|
||||
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: '400 404 405 413 429 500 501 502 503 504'
|
||||
bunkerweb.io/www.example.com_MAX_CLIENT_SIZE: '50m'
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
|
|
@ -1602,6 +1604,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
www.example.com_MAX_CLIENT_SIZE=50m
|
||||
```
|
||||
|
||||
Don't forget to restart the `bunkerweb` service :
|
||||
|
|
@ -1635,6 +1638,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
www.example.com_MAX_CLIENT_SIZE=50m
|
||||
```
|
||||
|
||||
The variable `enable_ui` can be set to `true` in order to activate the web UI service and the variable `custom_ui` can be used to specify the configuration file for the web UI :
|
||||
|
|
@ -1709,6 +1713,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
www.example.com_MAX_CLIENT_SIZE=50m
|
||||
```
|
||||
|
||||
Don't forget to restart the `bunkerweb` service :
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ services:
|
|||
- www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
- www.example.com_MAX_CLIENT_SIZE=50m
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ USE_GZIP=yes
|
|||
www.example.com_USE_UI=yes
|
||||
www.example.com_USE_REVERSE_PROXY=yes
|
||||
www.example.com_REVERSE_PROXY_URL=/admin
|
||||
www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ USE_GZIP=yes
|
|||
www.example.com_USE_UI=yes
|
||||
www.example.com_USE_REVERSE_PROXY=yes
|
||||
www.example.com_REVERSE_PROXY_URL=/admin
|
||||
www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
EXTERNAL_PLUGIN_URLS=https://github.com/bunkerity/bunkerweb-plugins/archive/refs/heads/dev.zip
|
||||
|
|
@ -86,6 +86,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ services:
|
|||
- www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
- www.example.com_MAX_CLIENT_SIZE=50m
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ services:
|
|||
- www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
- www.example.com_MAX_CLIENT_SIZE=50m
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ services:
|
|||
- www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
- www.example.com_MAX_CLIENT_SIZE=50m
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ services:
|
|||
- www.example.com_REVERSE_PROXY_URL=/changeme
|
||||
- www.example.com_REVERSE_PROXY_HOST=http://bw-ui:7000
|
||||
- www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
- www.example.com_MAX_CLIENT_SIZE=50m
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-services
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ metadata:
|
|||
annotations:
|
||||
bunkerweb.io/www.example.com_USE_UI: "yes"
|
||||
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
|
||||
bunkerweb.io/www.example.com_MAX_CLIENT_SIZE: "50m"
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ metadata:
|
|||
annotations:
|
||||
bunkerweb.io/www.example.com_USE_UI: "yes"
|
||||
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
|
||||
bunkerweb.io/www.example.com_MAX_CLIENT_SIZE: "50m"
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ metadata:
|
|||
annotations:
|
||||
bunkerweb.io/www.example.com_USE_UI: "yes"
|
||||
bunkerweb.io/www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
|
||||
bunkerweb.io/www.example.com_MAX_CLIENT_SIZE: "50m"
|
||||
spec:
|
||||
rules:
|
||||
- host: www.example.com
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/changeme"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.MAX_CLIENT_SIZE=50m"
|
||||
|
||||
volumes:
|
||||
bw-data:
|
||||
|
|
|
|||
|
|
@ -10,25 +10,24 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#antibot" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#antibot" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
<!-- end info -->
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
<div class="core-card-status-container">
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#backup-and-restore" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#backup-and-restore" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
<div class="core-card">
|
||||
<div class="core-card-wrap">
|
||||
<h5 class="core-card-title">LAST BACKUP</h5>
|
||||
|
|
|
|||
|
|
@ -10,32 +10,32 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available
|
||||
<a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#bad-behavior" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">
|
||||
<p class="core-card-text-doc">More information available
|
||||
<a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#bad-behavior" class="core-card-text-doc-link">
|
||||
in the documentation
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#blacklisting" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#blacklisting" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
<div class="core-layout-separator"></div>
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#bunkernet" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#bunkernet" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#cors" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#cors" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#country" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#country" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#dnsbl" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#dnsbl" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -9,27 +9,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/settings/#errors" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/settings/#errors" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#greylisting" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#greylisting" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#limiting" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#limiting" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/settings/#miscellaneous" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/settings/#miscellaneous" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
<div class="core-layout-separator"></div>
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ def install_plugin(plugin_path: Path, db, preview: bool = True) -> bool:
|
|||
try:
|
||||
db = Database(LOGGER, sqlalchemy_string=getenv("DATABASE_URI"))
|
||||
db_metadata = db.get_metadata()
|
||||
db_config = db.get_config()
|
||||
current_date = datetime.now()
|
||||
pro_license_key = getenv("PRO_LICENSE_KEY", "").strip()
|
||||
|
||||
|
|
@ -157,7 +158,8 @@ try:
|
|||
|
||||
# ? If we already checked today, skip the check and if the metadata is the same, skip the check
|
||||
if (
|
||||
metadata.get("is_pro", False) == db_metadata["is_pro"]
|
||||
pro_license_key == db_config["PRO_LICENSE_KEY"]
|
||||
and metadata.get("is_pro", False) == db_metadata["is_pro"]
|
||||
and db_metadata["last_pro_check"]
|
||||
and current_date.replace(hour=0, minute=0, second=0, microsecond=0) == db_metadata["last_pro_check"].replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
):
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/settings/#redis" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/settings/#redis" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#reverse-scan" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#reverse-scan" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
<div class="core-card">
|
||||
<h5 class="core-card-title">INFO</h5>
|
||||
<div class="core-card-text-container">
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
<p data-info class="core-card-text">{{plugin.get('description')}}</p>
|
||||
</div>
|
||||
<p class="core-card-text mt-4 mb-2">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#whitelisting" class="hover:brightness-90 cursor-pointer mt-2 underline text-primary">in the documentation</a>.</p>
|
||||
<p class="core-card-text-doc">More information available <a href="https://docs.bunkerweb.io/{{ bw_version }}/security-tuning/#whitelisting" class="core-card-text-doc-link">in the documentation</a>.</p>
|
||||
</div>
|
||||
<!-- end info --> <div class="core-layout-separator"></div>
|
||||
<!-- end info -->
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ko" or "error" in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ko" or "error" in pre_render.get("data", {}) or pre_render.get("data") is not mapping %} <div class="core-layout-separator"></div>
|
||||
<div class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render["data"].get("error", "No log to show") }}</p>
|
||||
<p class="px-1 text-white break-words">(Pre rendering error) {{ pre_render.get("data", { "error" : "No log to show" }).get("error", "No log to show") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if pre_render["status"] and pre_render["status"] == "ok" and "error" not in pre_render["data"] %}
|
||||
{% if pre_render.get("status", False) and pre_render.get("status", False) == "ok" and pre_render.get("data") is mapping and "error" not in pre_render.get("data", {}) %}
|
||||
|
||||
|
||||
{% for key, value in pre_render["data"].items() %}
|
||||
{% for key, value in pre_render.get("data", {}).items() %}
|
||||
|
||||
{% if key.startswith("ping_") %}
|
||||
<div class="core-card-status">
|
||||
|
|
|
|||
|
|
@ -3,17 +3,17 @@
|
|||
from contextlib import contextmanager, suppress
|
||||
from copy import deepcopy
|
||||
from datetime import datetime
|
||||
from hashlib import sha256
|
||||
from inspect import getsourcefile
|
||||
from io import BytesIO
|
||||
from logging import Logger
|
||||
from os import _exit, getenv, listdir, sep
|
||||
from os.path import basename, join
|
||||
from os.path import join
|
||||
from pathlib import Path
|
||||
from re import compile as re_compile
|
||||
from sys import _getframe, path as sys_path
|
||||
from sys import argv, path as sys_path
|
||||
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
||||
from time import sleep
|
||||
from traceback import format_exc
|
||||
from zipfile import ZIP_DEFLATED, ZipFile
|
||||
|
||||
from model import (
|
||||
Base,
|
||||
|
|
@ -37,7 +37,7 @@ for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in ((
|
|||
if deps_path not in sys_path:
|
||||
sys_path.append(deps_path)
|
||||
|
||||
from common_utils import file_hash # type: ignore
|
||||
from common_utils import bytes_hash # type: ignore
|
||||
|
||||
from pymysql import install_as_MySQLdb
|
||||
from sqlalchemy import create_engine, event, MetaData as sql_metadata, text, inspect
|
||||
|
|
@ -717,6 +717,7 @@ class Database:
|
|||
.with_entities(
|
||||
Plugin_pages.template_checksum,
|
||||
Plugin_pages.actions_checksum,
|
||||
Plugin_pages.obfuscation_checksum,
|
||||
)
|
||||
.filter_by(plugin_id=plugin["id"])
|
||||
.first()
|
||||
|
|
@ -728,8 +729,21 @@ class Database:
|
|||
if {"template.html", "actions.py"}.issubset(listdir(str(path_ui))):
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
template_checksum = sha256(template).hexdigest()
|
||||
actions_checksum = sha256(actions).hexdigest()
|
||||
template_checksum = bytes_hash(template, algorithm="sha256")
|
||||
actions_checksum = bytes_hash(actions, algorithm="sha256")
|
||||
|
||||
obfuscation_file = None
|
||||
obfuscation_checksum = None
|
||||
obfuscation_dir = path_ui.joinpath("pyarmor_runtime_000000")
|
||||
if obfuscation_dir.is_dir():
|
||||
obfuscation_file = BytesIO()
|
||||
with ZipFile(obfuscation_file, "w", ZIP_DEFLATED) as zip_file:
|
||||
for path in obfuscation_dir.rglob("*"):
|
||||
if path.is_file():
|
||||
zip_file.write(path, path.relative_to(path_ui))
|
||||
obfuscation_file.seek(0, 0)
|
||||
obfuscation_file = obfuscation_file.getvalue()
|
||||
obfuscation_checksum = bytes_hash(obfuscation_file, algorithm="sha256")
|
||||
|
||||
if db_plugin_page:
|
||||
updates = {}
|
||||
|
|
@ -749,6 +763,14 @@ class Database:
|
|||
}
|
||||
)
|
||||
|
||||
if obfuscation_checksum != db_plugin_page.obfuscation_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.obfuscation_file: obfuscation_file,
|
||||
Plugin_pages.obfuscation_checksum: obfuscation_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if updates:
|
||||
self.logger.warning(f'Page for plugin "{plugin["id"]}" already exists, updating it with the new values')
|
||||
session.query(Plugin_pages).filter(Plugin_pages.plugin_id == plugin["id"]).update(updates)
|
||||
|
|
@ -764,6 +786,8 @@ class Database:
|
|||
template_checksum=template_checksum,
|
||||
actions_file=actions,
|
||||
actions_checksum=actions_checksum,
|
||||
obfuscation_file=obfuscation_file,
|
||||
obfuscation_checksum=obfuscation_checksum,
|
||||
)
|
||||
)
|
||||
remove = False
|
||||
|
|
@ -1103,7 +1127,7 @@ class Database:
|
|||
|
||||
custom_config["type"] = custom_config["type"].replace("-", "_").lower() # type: ignore
|
||||
custom_config["data"] = custom_config["data"].encode("utf-8") if isinstance(custom_config["data"], str) else custom_config["data"]
|
||||
custom_config["checksum"] = sha256(custom_config["data"]).hexdigest() # type: ignore
|
||||
custom_config["checksum"] = bytes_hash(custom_config["data"], algorithm="sha256") # type: ignore
|
||||
|
||||
service_id = custom_config.get("service_id", None) or None
|
||||
filters = {
|
||||
|
|
@ -1292,7 +1316,7 @@ class Database:
|
|||
return ""
|
||||
|
||||
def delete_job_cache(self, file_name: str, *, job_name: Optional[str] = None, service_id: Optional[str] = None):
|
||||
job_name = job_name or basename(getsourcefile(_getframe(1))).replace(".py", "")
|
||||
job_name = job_name or argv[0].replace(".py", "")
|
||||
filters = {"file_name": file_name}
|
||||
if job_name:
|
||||
filters["job_name"] = job_name
|
||||
|
|
@ -1312,7 +1336,7 @@ class Database:
|
|||
checksum: Optional[str] = None,
|
||||
) -> str:
|
||||
"""Update the plugin cache in the database"""
|
||||
job_name = job_name or basename(getsourcefile(_getframe(1))).replace(".py", "")
|
||||
job_name = job_name or argv[0].replace(".py", "")
|
||||
service_id = service_id or None
|
||||
with self.__db_session() as session:
|
||||
cache = session.query(Jobs_cache).filter_by(job_name=job_name, service_id=service_id, file_name=file_name).first()
|
||||
|
|
@ -1578,6 +1602,7 @@ class Database:
|
|||
.with_entities(
|
||||
Plugin_pages.template_checksum,
|
||||
Plugin_pages.actions_checksum,
|
||||
Plugin_pages.obfuscation_checksum,
|
||||
)
|
||||
.filter_by(plugin_id=plugin["id"])
|
||||
.first()
|
||||
|
|
@ -1587,32 +1612,46 @@ class Database:
|
|||
if path_ui.is_dir():
|
||||
remove = True
|
||||
if {"template.html", "actions.py"}.issubset(listdir(str(path_ui))):
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
template_checksum = bytes_hash(template, algorithm="sha256")
|
||||
actions_checksum = bytes_hash(actions, algorithm="sha256")
|
||||
|
||||
obfuscation_file = None
|
||||
obfuscation_checksum = None
|
||||
obfuscation_dir = path_ui.joinpath("pyarmor_runtime_000000")
|
||||
if obfuscation_dir.is_dir():
|
||||
obfuscation_file = BytesIO()
|
||||
with ZipFile(obfuscation_file, "w", ZIP_DEFLATED) as zip_file:
|
||||
for path in obfuscation_dir.rglob("*"):
|
||||
if path.is_file():
|
||||
zip_file.write(path, path.relative_to(path_ui))
|
||||
obfuscation_file.seek(0, 0)
|
||||
obfuscation_file = obfuscation_file.getvalue()
|
||||
obfuscation_checksum = bytes_hash(obfuscation_file, algorithm="sha256")
|
||||
|
||||
if not db_plugin_page:
|
||||
changes = True
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
|
||||
to_put.append(
|
||||
Plugin_pages(
|
||||
plugin_id=plugin["id"],
|
||||
template_file=template,
|
||||
template_checksum=sha256(template).hexdigest(),
|
||||
template_checksum=template_checksum,
|
||||
actions_file=actions,
|
||||
actions_checksum=sha256(actions).hexdigest(),
|
||||
actions_checksum=actions_checksum,
|
||||
obfuscation_file=obfuscation_file,
|
||||
obfuscation_checksum=obfuscation_checksum,
|
||||
)
|
||||
)
|
||||
remove = False
|
||||
else:
|
||||
updates = {}
|
||||
template_path = path_ui.joinpath("template.html")
|
||||
actions_path = path_ui.joinpath("actions.py")
|
||||
template_checksum = file_hash(str(template_path))
|
||||
actions_checksum = file_hash(str(actions_path))
|
||||
|
||||
if template_checksum != db_plugin_page.template_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.template_file: template_path.read_bytes(),
|
||||
Plugin_pages.template_file: template,
|
||||
Plugin_pages.template_checksum: template_checksum,
|
||||
}
|
||||
)
|
||||
|
|
@ -1620,11 +1659,19 @@ class Database:
|
|||
if actions_checksum != db_plugin_page.actions_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.actions_file: actions_path.read_bytes(),
|
||||
Plugin_pages.actions_file: actions,
|
||||
Plugin_pages.actions_checksum: actions_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if obfuscation_checksum != db_plugin_page.obfuscation_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.obfuscation_file: obfuscation_file,
|
||||
Plugin_pages.obfuscation_checksum: obfuscation_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if updates:
|
||||
changes = True
|
||||
session.query(Plugin_pages).filter(Plugin_pages.plugin_id == plugin["id"]).update(updates)
|
||||
|
|
@ -1732,35 +1779,49 @@ class Database:
|
|||
.with_entities(
|
||||
Plugin_pages.template_checksum,
|
||||
Plugin_pages.actions_checksum,
|
||||
Plugin_pages.obfuscation_checksum,
|
||||
)
|
||||
.filter_by(plugin_id=plugin["id"])
|
||||
.first()
|
||||
)
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
template_checksum = bytes_hash(template, algorithm="sha256")
|
||||
actions_checksum = bytes_hash(actions, algorithm="sha256")
|
||||
|
||||
obfuscation_file = None
|
||||
obfuscation_checksum = None
|
||||
obfuscation_dir = path_ui.joinpath("pyarmor_runtime_000000")
|
||||
if obfuscation_dir.is_dir():
|
||||
obfuscation_file = BytesIO()
|
||||
with ZipFile(obfuscation_file, "w", ZIP_DEFLATED) as zip_file:
|
||||
for path in obfuscation_dir.rglob("*"):
|
||||
if path.is_file():
|
||||
zip_file.write(path, path.relative_to(path_ui))
|
||||
obfuscation_file.seek(0, 0)
|
||||
obfuscation_file = obfuscation_file.getvalue()
|
||||
obfuscation_checksum = bytes_hash(obfuscation_file, algorithm="sha256")
|
||||
|
||||
if not db_plugin_page:
|
||||
template = path_ui.joinpath("template.html").read_bytes()
|
||||
actions = path_ui.joinpath("actions.py").read_bytes()
|
||||
|
||||
to_put.append(
|
||||
Plugin_pages(
|
||||
plugin_id=plugin["id"],
|
||||
template_file=template,
|
||||
template_checksum=sha256(template).hexdigest(),
|
||||
template_checksum=template_checksum,
|
||||
actions_file=actions,
|
||||
actions_checksum=sha256(actions).hexdigest(),
|
||||
actions_checksum=actions_checksum,
|
||||
obfuscation_file=obfuscation_file,
|
||||
obfuscation_checksum=obfuscation_checksum,
|
||||
)
|
||||
)
|
||||
else:
|
||||
updates = {}
|
||||
template_path = path_ui.joinpath("template.html")
|
||||
actions_path = path_ui.joinpath("actions.py")
|
||||
template_checksum = file_hash(str(template_path))
|
||||
actions_checksum = file_hash(str(actions_path))
|
||||
|
||||
if template_checksum != db_plugin_page.template_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.template_file: template_path.read_bytes(),
|
||||
Plugin_pages.template_file: template,
|
||||
Plugin_pages.template_checksum: template_checksum,
|
||||
}
|
||||
)
|
||||
|
|
@ -1768,15 +1829,23 @@ class Database:
|
|||
if actions_checksum != db_plugin_page.actions_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.actions_file: actions_path.read_bytes(),
|
||||
Plugin_pages.actions_file: actions,
|
||||
Plugin_pages.actions_checksum: actions_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if obfuscation_checksum != db_plugin_page.obfuscation_checksum:
|
||||
updates.update(
|
||||
{
|
||||
Plugin_pages.obfuscation_file: obfuscation_file,
|
||||
Plugin_pages.obfuscation_checksum: obfuscation_checksum,
|
||||
}
|
||||
)
|
||||
|
||||
if updates:
|
||||
session.query(Plugin_pages).filter(Plugin_pages.plugin_id == plugin["id"]).update(updates)
|
||||
|
||||
for command, file_name in plugin.get("bwcli", {}).items():
|
||||
for command, file_name in commands.items():
|
||||
if not plugin_path.joinpath("bwcli", file_name).is_file():
|
||||
self.logger.warning(f'Command "{command}"\'s file "{file_name}" does not exist in the plugin directory, skipping it')
|
||||
continue
|
||||
|
|
@ -1806,7 +1875,7 @@ class Database:
|
|||
with self.__db_session() as session:
|
||||
entities = [Plugins.id, Plugins.stream, Plugins.name, Plugins.description, Plugins.version, Plugins.type, Plugins.method, Plugins.checksum]
|
||||
if with_data:
|
||||
entities.append(Plugins.data)
|
||||
entities.append(Plugins.data) # type: ignore
|
||||
|
||||
db_plugins = session.query(Plugins).with_entities(*entities)
|
||||
if _type != "all":
|
||||
|
|
@ -1876,6 +1945,7 @@ class Database:
|
|||
with self.__db_session() as session:
|
||||
return {
|
||||
job.name: {
|
||||
"plugin_id": job.plugin_id,
|
||||
"every": job.every,
|
||||
"reload": job.reload,
|
||||
"success": job.success,
|
||||
|
|
@ -1898,6 +1968,7 @@ class Database:
|
|||
for job in (
|
||||
session.query(Jobs).with_entities(
|
||||
Jobs.name,
|
||||
Jobs.plugin_id,
|
||||
Jobs.every,
|
||||
Jobs.reload,
|
||||
Jobs.success,
|
||||
|
|
@ -2069,6 +2140,16 @@ class Database:
|
|||
|
||||
return page.template_file
|
||||
|
||||
def get_plugin_obfuscation(self, plugin: str) -> Optional[Any]:
|
||||
"""get obfuscation file for the plugin"""
|
||||
with self.__db_session() as session:
|
||||
page = session.query(Plugin_pages).with_entities(Plugin_pages.obfuscation_file).filter_by(plugin_id=plugin).first()
|
||||
|
||||
if not page:
|
||||
return None
|
||||
|
||||
return page.obfuscation_file
|
||||
|
||||
def get_ui_user(self) -> Optional[dict]:
|
||||
"""Get ui user."""
|
||||
with self.__db_session() as session:
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ class Plugin_pages(Base):
|
|||
template_checksum = Column(String(128), nullable=False)
|
||||
actions_file = Column(LargeBinary(length=(2**32) - 1), nullable=False)
|
||||
actions_checksum = Column(String(128), nullable=False)
|
||||
obfuscation_file = Column(LargeBinary(length=(2**32) - 1), default=None, nullable=True)
|
||||
obfuscation_checksum = Column(String(128), default=None, nullable=True)
|
||||
|
||||
plugin = relationship("Plugins", back_populates="pages")
|
||||
|
||||
|
|
|
|||
|
|
@ -151,9 +151,9 @@
|
|||
},
|
||||
{
|
||||
"id": "lua-resty-openssl",
|
||||
"name": "lua-resty-openssl v1.2.1",
|
||||
"name": "lua-resty-openssl v1.3.0",
|
||||
"url": "https://github.com/fffonion/lua-resty-openssl.git",
|
||||
"commit": "58c6ce6885556ed7cb85dde83d673fad05ba73aa",
|
||||
"commit": "79b9c2f787febd03b9741ef9fad084a39a888d7c",
|
||||
"post_install": "rm -r src/deps/src/lua-resty-openssl/t"
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ jobs:
|
|||
# TODO: arm64
|
||||
# latest and one version older for valgrind and perf test
|
||||
- nginx: "1.19.9"
|
||||
openssl: "3.1.4"
|
||||
openssl: "3.1.5"
|
||||
openssl_fips: "3.0.8"
|
||||
extras: "valgrind"
|
||||
lua_nginx_module: "v0.10.20"
|
||||
lua_resty_core: "v0.1.22"
|
||||
nginx_cc_opts: "-Wno-error"
|
||||
- nginx: "1.21.4"
|
||||
openssl: "3.1.4"
|
||||
openssl: "3.1.5"
|
||||
openssl_fips: "3.0.8"
|
||||
extras: "valgrind"
|
||||
lua_nginx_module: "v0.10.25"
|
||||
|
|
@ -48,23 +48,23 @@ jobs:
|
|||
lua_nginx_module: "v0.10.26"
|
||||
lua_resty_core: "v0.1.28"
|
||||
- nginx: "1.25.3"
|
||||
openssl: "3.0.12"
|
||||
openssl: "3.0.13"
|
||||
openssl_fips: "3.0.8"
|
||||
extras: "valgrind perf"
|
||||
lua_nginx_module: "v0.10.26"
|
||||
lua_resty_core: "v0.1.28"
|
||||
nginx_cc_opts: "-Wno-error"
|
||||
- nginx: "1.25.3"
|
||||
openssl: "3.1.4"
|
||||
openssl: "3.1.5"
|
||||
openssl_fips: "3.0.8"
|
||||
extras: "valgrind perf"
|
||||
lua_nginx_module: "v0.10.26"
|
||||
lua_resty_core: "v0.1.28"
|
||||
nginx_cc_opts: "-Wno-error"
|
||||
- nginx: "1.25.3"
|
||||
openssl: "3.2.0"
|
||||
openssl: "3.2.1"
|
||||
openssl_fips: "3.0.8"
|
||||
extras: "valgrind perf"
|
||||
extras: "valgrind perf lua-kong-nginx-module"
|
||||
lua_nginx_module: "v0.10.26"
|
||||
lua_resty_core: "v0.1.28"
|
||||
nginx_cc_opts: "-Wno-error"
|
||||
|
|
@ -115,6 +115,7 @@ jobs:
|
|||
git clone https://github.com/openresty/lua-nginx-module.git ./lua-nginx-module -b ${{ matrix.lua_nginx_module }}
|
||||
git clone https://github.com/openresty/no-pool-nginx.git ./no-pool-nginx
|
||||
git clone https://github.com/fffonion/lua-resty-openssl-aux-module ./lua-resty-openssl-aux-module
|
||||
git clone https://github.com/Kong/lua-kong-nginx-module.git ./lua-kong-nginx-module
|
||||
# lua libraries at parent directory of current repository
|
||||
popd
|
||||
git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core -b ${{ matrix.lua_resty_core }}
|
||||
|
|
@ -170,15 +171,17 @@ jobs:
|
|||
- name: Build Nginx
|
||||
env:
|
||||
NGINX_CC_OPTS: ${{ matrix.nginx_cc_opts }}
|
||||
NGINX_MODULES: ""
|
||||
run: |
|
||||
if [[ "${{ matrix.extras }}" == *valgrind* ]]; then NGINX_CC_OPTS="$NGINX_CC_OPTS -O0"; fi
|
||||
if [[ "${{ matrix.extras }}" == *lua-kong-nginx-module* ]]; then NGINX_MODULES="$NGINX_MODULES --add-module=../lua-kong-nginx-module"; fi
|
||||
export PATH=$BASE_PATH/work/nginx/sbin:$BASE_PATH/../nginx-devel-utils:$PATH
|
||||
export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH
|
||||
export NGX_LUA_LOC=$BASE_PATH/../lua-nginx-module
|
||||
export NGX_STREAM_LUA_LOC=$BASE_PATH/../stream-lua-nginx-module
|
||||
export
|
||||
cd $BASE_PATH
|
||||
if [ ! -e work ]; then ngx-build ${{ matrix.nginx }} --add-module=../ndk-nginx-module --add-module=../lua-nginx-module --add-module=../lua-resty-openssl-aux-module --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC $NGINX_CC_OPTS" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --with-debug > build.log 2>&1 || (cat build.log && exit 1); fi
|
||||
if [ ! -e work ]; then ngx-build ${{ matrix.nginx }} --add-module=../ndk-nginx-module --add-module=../lua-nginx-module --add-module=../lua-resty-openssl-aux-module $NGINX_MODULES --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC $NGINX_CC_OPTS" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --with-debug > build.log 2>&1 || (cat build.log && exit 1); fi
|
||||
nginx -V
|
||||
ldd `which nginx`|grep -E 'luajit|ssl|pcre'
|
||||
|
||||
|
|
@ -191,6 +194,8 @@ jobs:
|
|||
echo "Nginx SSL plain FFI"
|
||||
export CI_SKIP_NGINX_C=1
|
||||
TEST_NGINX_TIMEOUT=10 prove -j$JOBS t/openssl/ssl/ 2>&1
|
||||
export CI_SKIP_KONG_SSL_FUNCS=1
|
||||
TEST_NGINX_TIMEOUT=10 prove -j$JOBS t/openssl/ssl/ 2>&1
|
||||
|
||||
- name: Run Valgrind
|
||||
if: contains(matrix.extras, 'valgrind')
|
||||
|
|
@ -205,6 +210,9 @@ jobs:
|
|||
export CI_SKIP_NGINX_C=1
|
||||
stdbuf -o 0 -e 0 prove -j$JOBS t/openssl/ssl/ 2>&1 | grep -v "Connection refused" | grep -v "Retry connecting after" | tee output.log
|
||||
if grep -q 'insert_a_suppression_name_here' output.log; then echo "Valgrind found problems"; exit 1; fi
|
||||
export CI_SKIP_KONG_SSL_FUNCS=1
|
||||
stdbuf -o 0 -e 0 prove -j$JOBS t/openssl/ssl/ 2>&1 | grep -v "Connection refused" | grep -v "Retry connecting after" | tee output.log
|
||||
if grep -q 'insert_a_suppression_name_here' output.log; then echo "Valgrind found problems"; exit 1; fi
|
||||
|
||||
- name: Run FIPS Test
|
||||
run: |
|
||||
|
|
|
|||
11
src/deps/src/lua-resty-openssl/CHANGELOG.md
vendored
11
src/deps/src/lua-resty-openssl/CHANGELOG.md
vendored
|
|
@ -2,6 +2,12 @@
|
|||
## [Unreleased]
|
||||
|
||||
|
||||
<a name="1.3.0"></a>
|
||||
## [1.3.0] - 2024-04-15
|
||||
### features
|
||||
- **aux/nginx:** use lua-kong-nginx-module's get_socket_ssl when available ([#3](https://github.com/fffonion/lua-resty-openssl/issues/3)) [48c5107](https://github.com/fffonion/lua-resty-openssl/commit/48c51077444e375b2cdd5155693b49d92a82d4a1)
|
||||
|
||||
|
||||
<a name="1.2.1"></a>
|
||||
## [1.2.1] - 2024-02-27
|
||||
### bug fixes
|
||||
|
|
@ -488,8 +494,8 @@
|
|||
- **autogen:** generate tests for x509, csr and crl [1392428](https://github.com/fffonion/lua-resty-openssl/commit/1392428352164d2a1a6e0c03075ff65b55aecdee)
|
||||
- **objects:** add helper function for ASN1_OBJECT [d037706](https://github.com/fffonion/lua-resty-openssl/commit/d037706c11d716afe3616bdaf4658afc1763081d)
|
||||
- **pkey:** asymmetric encryption and decryption [6d60451](https://github.com/fffonion/lua-resty-openssl/commit/6d60451157edbf9cefb634f888dfa3e6d9be302f)
|
||||
- **x509:** getter/setters for extensions [243f40d](https://github.com/fffonion/lua-resty-openssl/commit/243f40d35562a516f404188a5c7eb8f5134d9b30)
|
||||
- **x509:** add get_ocsp_url and get_crl_url [6141b6f](https://github.com/fffonion/lua-resty-openssl/commit/6141b6f5aed38706b477a71d8c4383bf55da7eee)
|
||||
- **x509:** getter/setters for extensions [243f40d](https://github.com/fffonion/lua-resty-openssl/commit/243f40d35562a516f404188a5c7eb8f5134d9b30)
|
||||
- **x509.altname:** support iterate and decode over the stack [083a201](https://github.com/fffonion/lua-resty-openssl/commit/083a201746e02d51f6c5c640ad9bf8c6730ebe0b)
|
||||
- **x509.crl:** add crl module [242f8cb](https://github.com/fffonion/lua-resty-openssl/commit/242f8cb45d6c2df5918f26540c92a430d42feb5d)
|
||||
- **x509.csr:** autogen some csr functions as well [9800e36](https://github.com/fffonion/lua-resty-openssl/commit/9800e36c2ff8a299b88f24091cc722940a8652bb)
|
||||
|
|
@ -577,7 +583,8 @@
|
|||
- **x509:** export pubkey [ede4f81](https://github.com/fffonion/lua-resty-openssl/commit/ede4f817cb0fe092ad6f9ab5d6ecdcde864a9fd8)
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/1.2.1...HEAD
|
||||
[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/1.3.0...HEAD
|
||||
[1.3.0]: https://github.com/fffonion/lua-resty-openssl/compare/1.2.1...1.3.0
|
||||
[1.2.1]: https://github.com/fffonion/lua-resty-openssl/compare/1.2.0...1.2.1
|
||||
[1.2.0]: https://github.com/fffonion/lua-resty-openssl/compare/1.1.0...1.2.0
|
||||
[1.1.0]: https://github.com/fffonion/lua-resty-openssl/compare/1.0.2...1.1.0
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ try_require_modules()
|
|||
|
||||
|
||||
local _M = {
|
||||
_VERSION = '1.2.1',
|
||||
_VERSION = '1.3.0',
|
||||
}
|
||||
|
||||
function _M.load_modules()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
local ffi = require "ffi"
|
||||
local C = ffi.C
|
||||
local os = os
|
||||
|
||||
local SOCKET_CTX_INDEX = 1
|
||||
local NGX_OK = ngx.OK
|
||||
|
|
@ -30,6 +31,8 @@ end
|
|||
|
||||
|
||||
local stream_subsystem = false
|
||||
local get_sock_ssl
|
||||
|
||||
if ngx.config.subsystem == "stream" then
|
||||
stream_subsystem = true
|
||||
|
||||
|
|
@ -48,10 +51,21 @@ if ngx.config.subsystem == "stream" then
|
|||
|
||||
int ngx_stream_lua_resty_openssl_aux_get_socket_ssl_ctx(ngx_stream_lua_socket_tcp_upstream_t *u,
|
||||
void **_sess);
|
||||
|
||||
int ngx_stream_lua_kong_get_socket_ssl(ngx_stream_lua_socket_tcp_upstream_t *u,
|
||||
void **ssl_conn);
|
||||
]]
|
||||
|
||||
-- sanity test
|
||||
local _ = C.ngx_stream_lua_resty_openssl_aux_get_request_ssl
|
||||
local success
|
||||
if not os.getenv("CI_SKIP_KONG_SSL_FUNCS") then
|
||||
success, get_sock_ssl = pcall(function() return C.ngx_stream_lua_kong_get_socket_ssl end)
|
||||
end
|
||||
if not success or get_sock_ssl == nil then
|
||||
get_sock_ssl = C.ngx_stream_lua_resty_openssl_aux_get_socket_ssl_ctx
|
||||
end
|
||||
|
||||
else
|
||||
ffi.cdef [[
|
||||
typedef struct ngx_http_request_s ngx_http_request_t;
|
||||
|
|
@ -68,10 +82,20 @@ else
|
|||
|
||||
int ngx_http_lua_resty_openssl_aux_get_socket_ssl_ctx(ngx_http_lua_socket_tcp_upstream_t *u,
|
||||
void **_sess);
|
||||
|
||||
int ngx_http_lua_kong_ffi_get_socket_ssl(ngx_http_lua_socket_tcp_upstream_t *u,
|
||||
void **ssl_conn);
|
||||
]]
|
||||
|
||||
-- sanity test
|
||||
local _ = C.ngx_http_lua_resty_openssl_aux_get_request_ssl
|
||||
local success
|
||||
if not os.getenv("CI_SKIP_KONG_SSL_FUNCS") then
|
||||
success, get_sock_ssl = pcall(function() return C.ngx_http_lua_kong_ffi_get_socket_ssl end)
|
||||
end
|
||||
if not success or get_sock_ssl == nil then
|
||||
get_sock_ssl = C.ngx_http_lua_resty_openssl_aux_get_socket_ssl
|
||||
end
|
||||
end
|
||||
|
||||
local void_pp = ffi.new("void *[1]")
|
||||
|
|
@ -115,12 +139,7 @@ end
|
|||
get_socket_ssl = function(sock)
|
||||
local u = sock[SOCKET_CTX_INDEX]
|
||||
|
||||
local ret
|
||||
if stream_subsystem then
|
||||
ret = C.ngx_stream_lua_resty_openssl_aux_get_socket_ssl(u, void_pp)
|
||||
else
|
||||
ret = C.ngx_http_lua_resty_openssl_aux_get_socket_ssl(u, void_pp)
|
||||
end
|
||||
local ret = get_sock_ssl(u, void_pp)
|
||||
|
||||
if ret ~= NGX_OK then
|
||||
return nil, "cannot read u->peer.connection->ssl->connection"
|
||||
|
|
@ -151,4 +170,4 @@ return {
|
|||
get_req_ssl_ctx = get_req_ssl_ctx,
|
||||
get_socket_ssl = get_socket_ssl,
|
||||
get_socket_ssl_ctx = get_socket_ssl_ctx,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package = "lua-resty-openssl"
|
||||
version = "1.2.1-1"
|
||||
version = "1.3.0-1"
|
||||
source = {
|
||||
url = "git+https://github.com/fffonion/lua-resty-openssl.git",
|
||||
tag = "1.2.1"
|
||||
tag = "1.3.0"
|
||||
}
|
||||
description = {
|
||||
detailed = "FFI-based OpenSSL binding for LuaJIT.",
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
--license agpl3
|
||||
--version %VERSION%
|
||||
--architecture x86_64
|
||||
--depends bash --depends epel-release --depends python39 --depends 'nginx = 1:1.24.0-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends GeoIP-devel --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends brotli --depends openssl --depends libpq --depends mysql --depends postgresql --depends sqlite
|
||||
--depends bash --depends epel-release --depends python39 --depends 'nginx = 1:1.24.0-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends GeoIP-devel --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends brotli --depends openssl --depends libpq --depends mysql --depends postgresql --depends sqlite --depends unzip
|
||||
--description "BunkerWeb %VERSION% for CentOS Stream 8"
|
||||
--url "https://www.bunkerweb.io"
|
||||
--maintainer "Bunkerity <contact at bunkerity dot com>"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
--license agpl3
|
||||
--version %VERSION%
|
||||
--architecture %ARCH%
|
||||
--depends bash --depends python3 --depends procps --depends python3-pip --depends 'nginx = 1.24.0-1~bookworm' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends lsof --depends libpq5 --depends libpcre3 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3
|
||||
--depends bash --depends python3 --depends procps --depends python3-pip --depends 'nginx = 1.24.0-1~bookworm' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends lsof --depends libpq5 --depends libpcre3 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip
|
||||
--description "BunkerWeb %VERSION% for Debian 12"
|
||||
--url "https://www.bunkerweb.io"
|
||||
--maintainer "Bunkerity <contact at bunkerity dot com>"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
--license agpl3
|
||||
--version %VERSION%
|
||||
--architecture %ARCH%
|
||||
--depends bash --depends python3 --depends 'nginx >= 1:1.24.0' --depends 'nginx < 1:1.25.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends geoip-devel --depends gd --depends sudo --depends procps --depends lsof --depends nginx-mod-stream --depends pcre --depends libpq --depends libcap --depends openssl --depends logrotate --depends mysql --depends postgresql --depends sqlite3
|
||||
--depends bash --depends python3 --depends 'nginx >= 1:1.24.0' --depends 'nginx < 1:1.25.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends geoip-devel --depends gd --depends sudo --depends procps --depends lsof --depends nginx-mod-stream --depends pcre --depends libpq --depends libcap --depends openssl --depends logrotate --depends mysql --depends postgresql --depends sqlite3 --depends unzip
|
||||
--description "BunkerWeb %VERSION% for Fedora 39"
|
||||
--url "https://www.bunkerweb.io"
|
||||
--maintainer "Bunkerity <contact at bunkerity dot com>"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
--license agpl3
|
||||
--version %VERSION%
|
||||
--architecture %ARCH%
|
||||
--depends bash --depends python39 --depends 'nginx >= 1:1.24.0' --depends 'nginx < 1:1.25.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends geoip --depends libpq --depends libcap --depends openssl --depends sqlite
|
||||
--depends bash --depends python39 --depends 'nginx >= 1:1.24.0' --depends 'nginx < 1:1.25.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends geoip --depends libpq --depends libcap --depends openssl --depends sqlite --depends unzip
|
||||
--description "BunkerWeb %VERSION% for RHEL 8"
|
||||
--url "https://www.bunkerweb.io"
|
||||
--maintainer "Bunkerity <contact at bunkerity dot com>"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
--license agpl3
|
||||
--version %VERSION%
|
||||
--architecture %ARCH%
|
||||
--depends bash --depends python39 --depends 'nginx >= 1:1.24.0' --depends 'nginx < 1:1.25.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends libmaxminddb --depends libpq --depends libcap --depends openssl --depends mysql --depends postgresql --depends sqlite
|
||||
--depends bash --depends python39 --depends 'nginx >= 1:1.24.0' --depends 'nginx < 1:1.25.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends libmaxminddb --depends libpq --depends libcap --depends openssl --depends mysql --depends postgresql --depends sqlite --depends unzip
|
||||
--description "BunkerWeb %VERSION% for RHEL 9"
|
||||
--url "https://www.bunkerweb.io"
|
||||
--maintainer "Bunkerity <contact at bunkerity dot com>"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
--license agpl3
|
||||
--version %VERSION%
|
||||
--architecture %ARCH%
|
||||
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.24.0-1~jammy' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof --depends libpq5 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3
|
||||
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.24.0-1~jammy' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof --depends libpq5 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip
|
||||
--description "BunkerWeb %VERSION% for Ubuntu 22.04"
|
||||
--url "https://www.bunkerweb.io"
|
||||
--maintainer "Bunkerity <contact at bunkerity dot com>"
|
||||
|
|
|
|||
|
|
@ -113,8 +113,10 @@ function start() {
|
|||
stop_nginx
|
||||
|
||||
# Check if we are in slave/master mode
|
||||
export MASTER_MODE="$(grep "^MASTER_MODE=" /etc/bunkerweb/variables.env | cut -d '=' -f 2)"
|
||||
export SLAVE_MODE="$(grep "^SLAVE_MODE=" /etc/bunkerweb/variables.env | cut -d '=' -f 2)"
|
||||
MASTER_MODE="$(grep "^MASTER_MODE=" /etc/bunkerweb/variables.env | cut -d '=' -f 2)"
|
||||
export MASTER_MODE
|
||||
SLAVE_MODE="$(grep "^SLAVE_MODE=" /etc/bunkerweb/variables.env | cut -d '=' -f 2)"
|
||||
export SLAVE_MODE
|
||||
|
||||
if [ "$MASTER_MODE" != "yes" ] ; then
|
||||
# Generate temp conf for jobs and start nginx
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
|
|||
WORKDIR /usr/share/bunkerweb
|
||||
|
||||
# Add scheduler user, drop bwcli, install runtime dependencies, create data folders and set permissions
|
||||
RUN apk add --no-cache bash libgcc libstdc++ libpq openssl libmagic mariadb-client postgresql-client sqlite && \
|
||||
RUN apk add --no-cache bash unzip libgcc libstdc++ libpq openssl libmagic mariadb-client postgresql-client sqlite && \
|
||||
addgroup -g 101 scheduler && \
|
||||
adduser -h /var/cache/nginx -g scheduler -s /bin/sh -G scheduler -D -H -u 101 scheduler && \
|
||||
cp helpers/bwcli /usr/bin/ && \
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
|
|||
WORKDIR /usr/share/bunkerweb
|
||||
|
||||
# Add ui user, install runtime dependencies, create data folders and set permissions
|
||||
RUN apk add --no-cache bash libmagic mariadb-client postgresql-client sqlite && \
|
||||
RUN apk add --no-cache bash unzip libmagic mariadb-client postgresql-client sqlite && \
|
||||
addgroup -g 101 ui && \
|
||||
adduser -h /var/cache/nginx -g ui -s /bin/sh -G ui -D -H -u 101 ui && \
|
||||
echo "Docker" > INTEGRATION && \
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from string import ascii_letters, digits
|
|||
from sys import path as sys_path, modules as sys_modules
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
from uuid import uuid4
|
||||
|
||||
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("api",), ("db",))]:
|
||||
if deps_path not in sys_path:
|
||||
|
|
@ -302,18 +303,39 @@ def run_action(plugin: str, function_name: str = ""):
|
|||
if module is None:
|
||||
return {"status": "ko", "code": 404, "message": "The actions.py file for the plugin does not exist"}
|
||||
|
||||
obfuscation = db.get_plugin_obfuscation(plugin)
|
||||
tmp_dir = None
|
||||
|
||||
try:
|
||||
# Try to import the custom plugin
|
||||
with NamedTemporaryFile(mode="wb", suffix=".py", delete=True) as temp:
|
||||
temp.write(module)
|
||||
temp.flush()
|
||||
temp.seek(0)
|
||||
loader = SourceFileLoader("actions", temp.name)
|
||||
if obfuscation:
|
||||
tmp_dir = Path(sep, "var", "tmp", "bunkerweb", "ui", "action", str(uuid4()))
|
||||
tmp_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
action_file = tmp_dir.joinpath("actions.py")
|
||||
with ZipFile(BytesIO(obfuscation), "r") as zip_ref:
|
||||
zip_ref.extractall(tmp_dir)
|
||||
action_file.write_bytes(module)
|
||||
sys_path.append(tmp_dir.as_posix())
|
||||
loader = SourceFileLoader("actions", action_file.as_posix())
|
||||
actions = loader.load_module()
|
||||
else:
|
||||
with NamedTemporaryFile(mode="wb", suffix=".py", delete=True) as temp:
|
||||
temp.write(module)
|
||||
temp.flush()
|
||||
temp.seek(0)
|
||||
loader = SourceFileLoader("actions", temp.name)
|
||||
actions = loader.load_module()
|
||||
except:
|
||||
if tmp_dir:
|
||||
sys_path.pop()
|
||||
rmtree(tmp_dir, ignore_errors=True)
|
||||
|
||||
app.logger.exception("An error occurred while importing the plugin")
|
||||
return {"status": "ko", "code": 500, "message": "An error occurred while importing the plugin, see logs for more details"}
|
||||
|
||||
res = None
|
||||
message = None
|
||||
|
||||
try:
|
||||
# Try to get the custom plugin custom function and call it
|
||||
|
|
@ -332,11 +354,15 @@ def run_action(plugin: str, function_name: str = ""):
|
|||
finally:
|
||||
if sbin_nginx_path.is_file():
|
||||
# Remove the custom plugin from the shared library
|
||||
if sys_path:
|
||||
sys_path.pop()
|
||||
sys_modules.pop("actions", None)
|
||||
del actions
|
||||
|
||||
if tmp_dir:
|
||||
sys_path.pop()
|
||||
rmtree(tmp_dir, ignore_errors=True)
|
||||
|
||||
if message:
|
||||
app.logger.exception(message)
|
||||
if message or not isinstance(res, dict) and not res:
|
||||
return {"status": "ko", "code": 500, "message": message or "The plugin did not return a valid response"}
|
||||
|
||||
|
|
@ -401,7 +427,7 @@ def inject_variables():
|
|||
pro_expire=metadata["pro_expire"].strftime("%d-%m-%Y") if metadata["pro_expire"] else "Unknown",
|
||||
pro_overlapped=metadata["pro_overlapped"],
|
||||
plugins=app.config["CONFIG"].get_plugins(),
|
||||
bw_version="1.5.7"
|
||||
bw_version=bw_version,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -572,6 +598,7 @@ def setup():
|
|||
"REVERSE_PROXY_URL": request.form["ui_url"] or "/",
|
||||
"AUTO_LETS_ENCRYPT": request.form.get("auto_lets_encrypt", "no"),
|
||||
"INTERCEPTED_ERROR_CODES": "400 404 405 413 429 500 501 502 503 504",
|
||||
"MAX_CLIENT_SIZE": "50m",
|
||||
},
|
||||
request.form["server_name"],
|
||||
request.form["server_name"],
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ beautifulsoup4==4.12.3
|
|||
Flask==3.0.3
|
||||
Flask-Login==0.6.3
|
||||
Flask_WTF==1.2.1
|
||||
gunicorn[gthread]==21.2.0
|
||||
gunicorn[gthread]==22.0.0
|
||||
importlib-metadata==7.1.0
|
||||
pyotp==2.9.0
|
||||
python-magic==0.4.27
|
||||
python_dateutil==2.9.0.post0
|
||||
qrcode==7.4.2
|
||||
regex==2023.12.25
|
||||
regex==2024.4.16
|
||||
werkzeug==3.0.2
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ flask-wtf==1.2.1 \
|
|||
--hash=sha256:8bb269eb9bb46b87e7c8233d7e7debdf1f8b74bf90cc1789988c29b37a97b695 \
|
||||
--hash=sha256:fa6793f2fb7e812e0fe9743b282118e581fb1b6c45d414b8af05e659bd653287
|
||||
# via -r requirements.in
|
||||
gunicorn==21.2.0 \
|
||||
--hash=sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0 \
|
||||
--hash=sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033
|
||||
gunicorn==22.0.0 \
|
||||
--hash=sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9 \
|
||||
--hash=sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63
|
||||
# via -r requirements.in
|
||||
importlib-metadata==7.1.0 \
|
||||
--hash=sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570 \
|
||||
|
|
@ -70,9 +70,9 @@ importlib-metadata==7.1.0 \
|
|||
# via
|
||||
# -r requirements.in
|
||||
# flask
|
||||
itsdangerous==2.1.2 \
|
||||
--hash=sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44 \
|
||||
--hash=sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a
|
||||
itsdangerous==2.2.0 \
|
||||
--hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \
|
||||
--hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173
|
||||
# via
|
||||
# flask
|
||||
# flask-wtf
|
||||
|
|
@ -169,100 +169,100 @@ qrcode==7.4.2 \
|
|||
--hash=sha256:581dca7a029bcb2deef5d01068e39093e80ef00b4a61098a2182eac59d01643a \
|
||||
--hash=sha256:9dd969454827e127dbd93696b20747239e6d540e082937c90f14ac95b30f5845
|
||||
# via -r requirements.in
|
||||
regex==2023.12.25 \
|
||||
--hash=sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5 \
|
||||
--hash=sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770 \
|
||||
--hash=sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc \
|
||||
--hash=sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105 \
|
||||
--hash=sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d \
|
||||
--hash=sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b \
|
||||
--hash=sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9 \
|
||||
--hash=sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630 \
|
||||
--hash=sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6 \
|
||||
--hash=sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c \
|
||||
--hash=sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482 \
|
||||
--hash=sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6 \
|
||||
--hash=sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a \
|
||||
--hash=sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80 \
|
||||
--hash=sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5 \
|
||||
--hash=sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1 \
|
||||
--hash=sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f \
|
||||
--hash=sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf \
|
||||
--hash=sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb \
|
||||
--hash=sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2 \
|
||||
--hash=sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347 \
|
||||
--hash=sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20 \
|
||||
--hash=sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060 \
|
||||
--hash=sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5 \
|
||||
--hash=sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73 \
|
||||
--hash=sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f \
|
||||
--hash=sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d \
|
||||
--hash=sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3 \
|
||||
--hash=sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae \
|
||||
--hash=sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4 \
|
||||
--hash=sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2 \
|
||||
--hash=sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457 \
|
||||
--hash=sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c \
|
||||
--hash=sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4 \
|
||||
--hash=sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87 \
|
||||
--hash=sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0 \
|
||||
--hash=sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704 \
|
||||
--hash=sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f \
|
||||
--hash=sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f \
|
||||
--hash=sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b \
|
||||
--hash=sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5 \
|
||||
--hash=sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923 \
|
||||
--hash=sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715 \
|
||||
--hash=sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c \
|
||||
--hash=sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca \
|
||||
--hash=sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1 \
|
||||
--hash=sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756 \
|
||||
--hash=sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360 \
|
||||
--hash=sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc \
|
||||
--hash=sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445 \
|
||||
--hash=sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e \
|
||||
--hash=sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4 \
|
||||
--hash=sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a \
|
||||
--hash=sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8 \
|
||||
--hash=sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53 \
|
||||
--hash=sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697 \
|
||||
--hash=sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf \
|
||||
--hash=sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a \
|
||||
--hash=sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415 \
|
||||
--hash=sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f \
|
||||
--hash=sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9 \
|
||||
--hash=sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400 \
|
||||
--hash=sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d \
|
||||
--hash=sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392 \
|
||||
--hash=sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb \
|
||||
--hash=sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd \
|
||||
--hash=sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861 \
|
||||
--hash=sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232 \
|
||||
--hash=sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95 \
|
||||
--hash=sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7 \
|
||||
--hash=sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39 \
|
||||
--hash=sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887 \
|
||||
--hash=sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5 \
|
||||
--hash=sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39 \
|
||||
--hash=sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb \
|
||||
--hash=sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586 \
|
||||
--hash=sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97 \
|
||||
--hash=sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423 \
|
||||
--hash=sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69 \
|
||||
--hash=sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7 \
|
||||
--hash=sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1 \
|
||||
--hash=sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7 \
|
||||
--hash=sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5 \
|
||||
--hash=sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8 \
|
||||
--hash=sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91 \
|
||||
--hash=sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590 \
|
||||
--hash=sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe \
|
||||
--hash=sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c \
|
||||
--hash=sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64 \
|
||||
--hash=sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd \
|
||||
--hash=sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa \
|
||||
--hash=sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31 \
|
||||
--hash=sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988
|
||||
regex==2024.4.16 \
|
||||
--hash=sha256:00169caa125f35d1bca6045d65a662af0202704489fada95346cfa092ec23f39 \
|
||||
--hash=sha256:03576e3a423d19dda13e55598f0fd507b5d660d42c51b02df4e0d97824fdcae3 \
|
||||
--hash=sha256:03e68f44340528111067cecf12721c3df4811c67268b897fbe695c95f860ac42 \
|
||||
--hash=sha256:0534b034fba6101611968fae8e856c1698da97ce2efb5c2b895fc8b9e23a5834 \
|
||||
--hash=sha256:08dea89f859c3df48a440dbdcd7b7155bc675f2fa2ec8c521d02dc69e877db70 \
|
||||
--hash=sha256:0a38d151e2cdd66d16dab550c22f9521ba79761423b87c01dae0a6e9add79c0d \
|
||||
--hash=sha256:0c8290b44d8b0af4e77048646c10c6e3aa583c1ca67f3b5ffb6e06cf0c6f0f89 \
|
||||
--hash=sha256:10188fe732dec829c7acca7422cdd1bf57d853c7199d5a9e96bb4d40db239c73 \
|
||||
--hash=sha256:1210365faba7c2150451eb78ec5687871c796b0f1fa701bfd2a4a25420482d26 \
|
||||
--hash=sha256:12f6a3f2f58bb7344751919a1876ee1b976fe08b9ffccb4bbea66f26af6017b9 \
|
||||
--hash=sha256:159dc4e59a159cb8e4e8f8961eb1fa5d58f93cb1acd1701d8aff38d45e1a84a6 \
|
||||
--hash=sha256:20b7a68444f536365af42a75ccecb7ab41a896a04acf58432db9e206f4e525d6 \
|
||||
--hash=sha256:23cff1b267038501b179ccbbd74a821ac4a7192a1852d1d558e562b507d46013 \
|
||||
--hash=sha256:2c72608e70f053643437bd2be0608f7f1c46d4022e4104d76826f0839199347a \
|
||||
--hash=sha256:3399dd8a7495bbb2bacd59b84840eef9057826c664472e86c91d675d007137f5 \
|
||||
--hash=sha256:34422d5a69a60b7e9a07a690094e824b66f5ddc662a5fc600d65b7c174a05f04 \
|
||||
--hash=sha256:370c68dc5570b394cbaadff50e64d705f64debed30573e5c313c360689b6aadc \
|
||||
--hash=sha256:3a1018e97aeb24e4f939afcd88211ace472ba566efc5bdf53fd8fd7f41fa7170 \
|
||||
--hash=sha256:3d5ac5234fb5053850d79dd8eb1015cb0d7d9ed951fa37aa9e6249a19aa4f336 \
|
||||
--hash=sha256:4313ab9bf6a81206c8ac28fdfcddc0435299dc88cad12cc6305fd0e78b81f9e4 \
|
||||
--hash=sha256:445ca8d3c5a01309633a0c9db57150312a181146315693273e35d936472df912 \
|
||||
--hash=sha256:479595a4fbe9ed8f8f72c59717e8cf222da2e4c07b6ae5b65411e6302af9708e \
|
||||
--hash=sha256:4918fd5f8b43aa7ec031e0fef1ee02deb80b6afd49c85f0790be1dc4ce34cb50 \
|
||||
--hash=sha256:4aba818dcc7263852aabb172ec27b71d2abca02a593b95fa79351b2774eb1d2b \
|
||||
--hash=sha256:4e819a806420bc010489f4e741b3036071aba209f2e0989d4750b08b12a9343f \
|
||||
--hash=sha256:4facc913e10bdba42ec0aee76d029aedda628161a7ce4116b16680a0413f658a \
|
||||
--hash=sha256:549c3584993772e25f02d0656ac48abdda73169fe347263948cf2b1cead622f3 \
|
||||
--hash=sha256:5c02fcd2bf45162280613d2e4a1ca3ac558ff921ae4e308ecb307650d3a6ee51 \
|
||||
--hash=sha256:5f580c651a72b75c39e311343fe6875d6f58cf51c471a97f15a938d9fe4e0d37 \
|
||||
--hash=sha256:62120ed0de69b3649cc68e2965376048793f466c5a6c4370fb27c16c1beac22d \
|
||||
--hash=sha256:6295004b2dd37b0835ea5c14a33e00e8cfa3c4add4d587b77287825f3418d310 \
|
||||
--hash=sha256:65436dce9fdc0aeeb0a0effe0839cb3d6a05f45aa45a4d9f9c60989beca78b9c \
|
||||
--hash=sha256:684008ec44ad275832a5a152f6e764bbe1914bea10968017b6feaecdad5736e0 \
|
||||
--hash=sha256:684e52023aec43bdf0250e843e1fdd6febbe831bd9d52da72333fa201aaa2335 \
|
||||
--hash=sha256:6cc38067209354e16c5609b66285af17a2863a47585bcf75285cab33d4c3b8df \
|
||||
--hash=sha256:6f2f017c5be19984fbbf55f8af6caba25e62c71293213f044da3ada7091a4455 \
|
||||
--hash=sha256:743deffdf3b3481da32e8a96887e2aa945ec6685af1cfe2bcc292638c9ba2f48 \
|
||||
--hash=sha256:7571f19f4a3fd00af9341c7801d1ad1967fc9c3f5e62402683047e7166b9f2b4 \
|
||||
--hash=sha256:7731728b6568fc286d86745f27f07266de49603a6fdc4d19c87e8c247be452af \
|
||||
--hash=sha256:785c071c982dce54d44ea0b79cd6dfafddeccdd98cfa5f7b86ef69b381b457d9 \
|
||||
--hash=sha256:78fddb22b9ef810b63ef341c9fcf6455232d97cfe03938cbc29e2672c436670e \
|
||||
--hash=sha256:7bb966fdd9217e53abf824f437a5a2d643a38d4fd5fd0ca711b9da683d452969 \
|
||||
--hash=sha256:7cbc5d9e8a1781e7be17da67b92580d6ce4dcef5819c1b1b89f49d9678cc278c \
|
||||
--hash=sha256:803b8905b52de78b173d3c1e83df0efb929621e7b7c5766c0843704d5332682f \
|
||||
--hash=sha256:80b696e8972b81edf0af2a259e1b2a4a661f818fae22e5fa4fa1a995fb4a40fd \
|
||||
--hash=sha256:81500ed5af2090b4a9157a59dbc89873a25c33db1bb9a8cf123837dcc9765047 \
|
||||
--hash=sha256:89ec7f2c08937421bbbb8b48c54096fa4f88347946d4747021ad85f1b3021b3c \
|
||||
--hash=sha256:8ba6745440b9a27336443b0c285d705ce73adb9ec90e2f2004c64d95ab5a7598 \
|
||||
--hash=sha256:8c91e1763696c0eb66340c4df98623c2d4e77d0746b8f8f2bee2c6883fd1fe18 \
|
||||
--hash=sha256:8d015604ee6204e76569d2f44e5a210728fa917115bef0d102f4107e622b08d5 \
|
||||
--hash=sha256:8d1f86f3f4e2388aa3310b50694ac44daefbd1681def26b4519bd050a398dc5a \
|
||||
--hash=sha256:8f83b6fd3dc3ba94d2b22717f9c8b8512354fd95221ac661784df2769ea9bba9 \
|
||||
--hash=sha256:8fc6976a3395fe4d1fbeb984adaa8ec652a1e12f36b56ec8c236e5117b585427 \
|
||||
--hash=sha256:904c883cf10a975b02ab3478bce652f0f5346a2c28d0a8521d97bb23c323cc8b \
|
||||
--hash=sha256:911742856ce98d879acbea33fcc03c1d8dc1106234c5e7d068932c945db209c0 \
|
||||
--hash=sha256:91797b98f5e34b6a49f54be33f72e2fb658018ae532be2f79f7c63b4ae225145 \
|
||||
--hash=sha256:95399831a206211d6bc40224af1c635cb8790ddd5c7493e0bd03b85711076a53 \
|
||||
--hash=sha256:956b58d692f235cfbf5b4f3abd6d99bf102f161ccfe20d2fd0904f51c72c4c66 \
|
||||
--hash=sha256:98c1165f3809ce7774f05cb74e5408cd3aa93ee8573ae959a97a53db3ca3180d \
|
||||
--hash=sha256:9ab40412f8cd6f615bfedea40c8bf0407d41bf83b96f6fc9ff34976d6b7037fd \
|
||||
--hash=sha256:9df1bfef97db938469ef0a7354b2d591a2d438bc497b2c489471bec0e6baf7c4 \
|
||||
--hash=sha256:a01fe2305e6232ef3e8f40bfc0f0f3a04def9aab514910fa4203bafbc0bb4682 \
|
||||
--hash=sha256:a70b51f55fd954d1f194271695821dd62054d949efd6368d8be64edd37f55c86 \
|
||||
--hash=sha256:a7ccdd1c4a3472a7533b0a7aa9ee34c9a2bef859ba86deec07aff2ad7e0c3b94 \
|
||||
--hash=sha256:b340cccad138ecb363324aa26893963dcabb02bb25e440ebdf42e30963f1a4e0 \
|
||||
--hash=sha256:b74586dd0b039c62416034f811d7ee62810174bb70dffcca6439f5236249eb09 \
|
||||
--hash=sha256:b9d320b3bf82a39f248769fc7f188e00f93526cc0fe739cfa197868633d44701 \
|
||||
--hash=sha256:ba2336d6548dee3117520545cfe44dc28a250aa091f8281d28804aa8d707d93d \
|
||||
--hash=sha256:ba8122e3bb94ecda29a8de4cf889f600171424ea586847aa92c334772d200331 \
|
||||
--hash=sha256:bd727ad276bb91928879f3aa6396c9a1d34e5e180dce40578421a691eeb77f47 \
|
||||
--hash=sha256:c21fc21a4c7480479d12fd8e679b699f744f76bb05f53a1d14182b31f55aac76 \
|
||||
--hash=sha256:c2d0e7cbb6341e830adcbfa2479fdeebbfbb328f11edd6b5675674e7a1e37730 \
|
||||
--hash=sha256:c2ef6f7990b6e8758fe48ad08f7e2f66c8f11dc66e24093304b87cae9037bb4a \
|
||||
--hash=sha256:c4ed75ea6892a56896d78f11006161eea52c45a14994794bcfa1654430984b22 \
|
||||
--hash=sha256:cccc79a9be9b64c881f18305a7c715ba199e471a3973faeb7ba84172abb3f317 \
|
||||
--hash=sha256:d0800631e565c47520aaa04ae38b96abc5196fe8b4aa9bd864445bd2b5848a7a \
|
||||
--hash=sha256:d2da13568eff02b30fd54fccd1e042a70fe920d816616fda4bf54ec705668d81 \
|
||||
--hash=sha256:d61ae114d2a2311f61d90c2ef1358518e8f05eafda76eaf9c772a077e0b465ec \
|
||||
--hash=sha256:d83c2bc678453646f1a18f8db1e927a2d3f4935031b9ad8a76e56760461105dd \
|
||||
--hash=sha256:dd5acc0a7d38fdc7a3a6fd3ad14c880819008ecb3379626e56b163165162cc46 \
|
||||
--hash=sha256:df79012ebf6f4efb8d307b1328226aef24ca446b3ff8d0e30202d7ebcb977a8c \
|
||||
--hash=sha256:e0a2df336d1135a0b3a67f3bbf78a75f69562c1199ed9935372b82215cddd6e2 \
|
||||
--hash=sha256:e2f142b45c6fed48166faeb4303b4b58c9fcd827da63f4cf0a123c3480ae11fb \
|
||||
--hash=sha256:e697e1c0238133589e00c244a8b676bc2cfc3ab4961318d902040d099fec7483 \
|
||||
--hash=sha256:e757d475953269fbf4b441207bb7dbdd1c43180711b6208e129b637792ac0b93 \
|
||||
--hash=sha256:e87ab229332ceb127a165612d839ab87795972102cb9830e5f12b8c9a5c1b508 \
|
||||
--hash=sha256:ea355eb43b11764cf799dda62c658c4d2fdb16af41f59bb1ccfec517b60bcb07 \
|
||||
--hash=sha256:ec7e0043b91115f427998febaa2beb82c82df708168b35ece3accb610b91fac1 \
|
||||
--hash=sha256:eeaa0b5328b785abc344acc6241cffde50dc394a0644a968add75fcefe15b9d4 \
|
||||
--hash=sha256:f2d80a6749724b37853ece57988b39c4e79d2b5fe2869a86e8aeae3bbeef9eb0 \
|
||||
--hash=sha256:fa454d26f2e87ad661c4f0c5a5fe4cf6aab1e307d1b94f16ffdfcb089ba685c0 \
|
||||
--hash=sha256:fb83cc090eac63c006871fd24db5e30a1f282faa46328572661c0a24a2323a08 \
|
||||
--hash=sha256:fd80d1280d473500d8086d104962a82d77bfbf2b118053824b7be28cd5a79ea5
|
||||
# via -r requirements.in
|
||||
six==1.16.0 \
|
||||
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -234,7 +234,7 @@ class darkMode {
|
|||
body: JSON.stringify({ darkmode: isDark }),
|
||||
};
|
||||
const send = await fetch(
|
||||
`${location.href.split("/").slice(0, -1).join("/")}/darkmode`,
|
||||
document.querySelector("[data-mode-link]").getAttribute("data-mode-link"),
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -360,17 +360,18 @@ class Download {
|
|||
.hasAttribute(`data-${this.prefix}-download`)
|
||||
) {
|
||||
const btnEl = e.target.closest("button");
|
||||
const pluginId = btnEl.getAttribute("data-jobs-plugin");
|
||||
const jobName = btnEl.getAttribute("data-jobs-download");
|
||||
const fileName = btnEl.getAttribute("data-jobs-file");
|
||||
this.sendFileToDL(jobName, fileName);
|
||||
this.sendFileToDL(pluginId, jobName, fileName);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
async sendFileToDL(jobName, fileName) {
|
||||
async sendFileToDL(pluginId, jobName, fileName) {
|
||||
window.open(
|
||||
`${location.href}/download?job_name=${jobName}&file_name=${fileName}`,
|
||||
`${location.href}/download?plugin_id=${pluginId}&job_name=${jobName}&file_name=${fileName}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
class Ping {
|
||||
constructor(
|
||||
url = `${location.origin}${location.pathname}`,
|
||||
statusTextEl = null,
|
||||
statusColorEl = null,
|
||||
key_to_check = "ping",
|
||||
btnEl = null, // disabled while fethching
|
||||
statusTextEl = null, // update text with fetching result
|
||||
statusColorEl = null, // update color with fetching result
|
||||
key_to_check = "ping", // key to check in response data
|
||||
) {
|
||||
this.url = url;
|
||||
this.btnEl = btnEl;
|
||||
this.statusColorEl = statusColorEl;
|
||||
this.statusTextEl = statusTextEl;
|
||||
this.key_to_check = key_to_check;
|
||||
|
|
@ -82,6 +84,30 @@ class Ping {
|
|||
|
||||
// Key of fetch data need to match key of this.data
|
||||
updateEl(data) {
|
||||
// Show error
|
||||
if (data?.error) {
|
||||
const error = data?.error || "Action exception, no details available";
|
||||
console.log(error);
|
||||
// Remove previous data-action-error
|
||||
const prevError = document.querySelectorAll("[data-action-error]");
|
||||
if (prevError.length) prevError.forEach((el) => el.remove());
|
||||
// Add this one
|
||||
const error_html = `<div data-action-error class="core-layout-separator"></div>
|
||||
<div data-action-error class="my-2 flex justify-center col-span-12">
|
||||
<div class="mr-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 stroke-red-500 fill-white">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p class="px-1 text-white break-words">(Action error) ${error}</p>
|
||||
</div>
|
||||
`;
|
||||
// add HTML at the end of .core-layout
|
||||
document
|
||||
.querySelector("div.core-layout")
|
||||
.insertAdjacentHTML("beforeend", error_html);
|
||||
}
|
||||
|
||||
try {
|
||||
const successValues = [
|
||||
"success",
|
||||
|
|
@ -141,8 +167,14 @@ class Ping {
|
|||
|
||||
this.alertEl.classList.remove("hidden");
|
||||
|
||||
if (type !== "fetch")
|
||||
if (type === "fetch") {
|
||||
this.btnEl.setAttribute("disabled", "disabled");
|
||||
}
|
||||
|
||||
if (type !== "fetch") {
|
||||
this.btnEl.removeAttribute("disabled");
|
||||
setTimeout(() => this.alertEl.classList.add("hidden"), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
getAlertType(type) {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,24 @@ class Select {
|
|||
}
|
||||
|
||||
init() {
|
||||
// Add event listener to close dropdown if scroll event is triggered on window
|
||||
window.addEventListener("scroll", () => {
|
||||
this.dropsToHide = document.querySelectorAll(
|
||||
'[data-setting-select-dropdown][class*="flex"]',
|
||||
);
|
||||
if (!this.dropsToHide.length) return;
|
||||
|
||||
this.dropsToHide.forEach((dropdown) => {
|
||||
const btn = dropdown
|
||||
.closest("div[data-setting-container]")
|
||||
.querySelector("button[data-setting-select]");
|
||||
|
||||
if (dropdown.classList.contains("hidden")) return;
|
||||
btn.click();
|
||||
// Add dropdown to remove list
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener("click", (e) => {
|
||||
//CASE NO BTN SELECT CLICKED
|
||||
try {
|
||||
|
|
@ -164,6 +182,28 @@ class Select {
|
|||
dropdownEl.classList.toggle("hidden");
|
||||
dropdownEl.classList.toggle("flex");
|
||||
dropdownChevron.classList.toggle("rotate-180");
|
||||
// case open, we want to move dropdown position next to his data-select-container
|
||||
if (!dropdownEl.classList.contains("hidden")) {
|
||||
const selectContainer = btn.closest("div[data-select-container]");
|
||||
const selectContainerRect = selectContainer.getBoundingClientRect();
|
||||
const top = selectContainerRect.top + selectContainerRect.height;
|
||||
const left = selectContainerRect.left;
|
||||
const width = selectContainerRect.width;
|
||||
dropdownEl.style.top = `${top}px`;
|
||||
dropdownEl.style.left = `${left}px`;
|
||||
dropdownEl.style.width = `${width}px`;
|
||||
// Check dropdown height, if out of screen, move it up
|
||||
const dropdownRect = dropdownEl.getBoundingClientRect();
|
||||
const dropdownHeight = dropdownRect.height;
|
||||
const dropdownBottom = dropdownRect.bottom;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
if (dropdownBottom > windowHeight) {
|
||||
dropdownEl.style.top = `${
|
||||
top - dropdownHeight - selectContainerRect.height - 15
|
||||
}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,13 +220,19 @@ class TabsSelect {
|
|||
);
|
||||
const combobox = dropdown.querySelector("[data-combobox]");
|
||||
if (combobox) {
|
||||
// simulate clear combobox wit keyboard
|
||||
// simulate clear combobox with keyboard
|
||||
combobox.value = "";
|
||||
}
|
||||
dropdown.classList.toggle("hidden");
|
||||
dropdown.classList.toggle("flex");
|
||||
|
||||
// Case open, try to focus on combobox input
|
||||
if (!dropdown.classList.contains("hidden") && combobox) {
|
||||
// Unless already input focused (avoid conflict with search)
|
||||
if (
|
||||
!dropdown.classList.contains("hidden") &&
|
||||
combobox &&
|
||||
combobox.getAttribute("data-focus") !== "false"
|
||||
) {
|
||||
combobox.focus();
|
||||
}
|
||||
|
||||
|
|
@ -288,6 +294,9 @@ class FilterSettings {
|
|||
this.tabsEls = this.tabContainer.querySelectorAll(
|
||||
`[data-tab-select-handler]`,
|
||||
);
|
||||
this.comboboxEl = this.tabContainer
|
||||
.querySelector("[data-tab-select-dropdown]")
|
||||
.querySelector("[data-combobox]");
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
|
@ -300,11 +309,13 @@ class FilterSettings {
|
|||
});
|
||||
}
|
||||
|
||||
// Update plugin items based on current input
|
||||
if (this.comboboxEl) {
|
||||
this.comboboxEl.addEventListener("input", () => {
|
||||
this.runComboFilter();
|
||||
});
|
||||
|
||||
// Allow to run combobox filter when opening dropdown (because reset and focus on open)
|
||||
this.comboboxEl.addEventListener("focusin", () => {
|
||||
this.runComboFilter();
|
||||
});
|
||||
|
|
@ -352,7 +363,13 @@ class FilterSettings {
|
|||
}
|
||||
|
||||
runFilter() {
|
||||
// Reset previous state to start fresh
|
||||
this.resetFilter();
|
||||
// get current tab, this will be used to show other plugin tab if current is hidden after filter
|
||||
const tabNameBeforeFilter =
|
||||
this.tabContainer
|
||||
?.querySelector("[data-tab-select-dropdown-btn]")
|
||||
?.getAttribute("data-tab-id") || "";
|
||||
//get inp format
|
||||
const inpValue = this.input.value.trim().toLowerCase().replaceAll("_", " ");
|
||||
|
||||
|
|
@ -612,37 +629,74 @@ class FilterSettings {
|
|||
|
||||
// case no tab match
|
||||
if (isAllHidden) {
|
||||
// we want to show message "No match"
|
||||
this.tabContainer
|
||||
.querySelector("[data-tab-select-dropdown-btn]")
|
||||
.setAttribute("data-tab-id", "no-match");
|
||||
return (this.tabContainer.querySelector(
|
||||
this.tabContainer.querySelector(
|
||||
"[data-tab-select-dropdown-btn] span",
|
||||
).textContent = "No match");
|
||||
).textContent = "No match";
|
||||
// we want to close dropdown in case open previously
|
||||
this.toggleDropdown(true, true, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// click first not hidden tab
|
||||
const currTabEl = this.tabContainer.querySelector(
|
||||
// case at least one match
|
||||
const currTabBtn = this.tabContainer.querySelector(
|
||||
`[data-tab-select-handler='${tabNameBeforeFilter}']`,
|
||||
);
|
||||
|
||||
// case the previous plugin is still visible, set is as active by clicking it again
|
||||
if (currTabBtn && !currTabBtn.classList.contains("!hidden")) {
|
||||
currTabBtn.click();
|
||||
}
|
||||
|
||||
// case the previous plugin is hidden, click on the first not hidden tab
|
||||
if (currTabBtn?.classList?.contains("!hidden") || !currTabBtn) {
|
||||
firstNotHiddenEl.click();
|
||||
}
|
||||
|
||||
// furthermore, open dropdown so user can see remain plugins in case the first one is not the one he is looking for
|
||||
// and if more than one plugin available
|
||||
// but we want to avoid dropdown open if active element is input keyword and value is empty
|
||||
if (document.activeElement === this.input && this.input.value === "")
|
||||
return;
|
||||
|
||||
const hiddenTabsEl = this.tabContainer.querySelectorAll(
|
||||
`[data-tab-select-handler][class*="!hidden"]`,
|
||||
);
|
||||
|
||||
if (hiddenTabsEl.length < this.tabsEls.length - 1)
|
||||
this.toggleDropdown(true, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
toggleDropdown(
|
||||
avoidComboFocus = false,
|
||||
disableOpen = false,
|
||||
disableClose = false,
|
||||
) {
|
||||
// avoid this on mobile
|
||||
if (window.innerWidth < 768) return;
|
||||
const dropdownEl = this.tabContainer.querySelector(
|
||||
"[data-tab-select-dropdown]",
|
||||
);
|
||||
const dropdownBtn = this.tabContainer.querySelector(
|
||||
"[data-tab-select-dropdown-btn]",
|
||||
);
|
||||
|
||||
const currTabName = currTabEl.getAttribute("data-tab-id");
|
||||
|
||||
// case previously no match
|
||||
if (currTabName === "no-match" && !isAllHidden) {
|
||||
return firstNotHiddenEl.click();
|
||||
}
|
||||
|
||||
const currTabBtn = this.tabContainer.querySelector(
|
||||
`[data-tab-select-handler='${currTabName}']`,
|
||||
);
|
||||
|
||||
if (!currTabBtn.classList.contains("!hidden")) {
|
||||
return currTabBtn.click();
|
||||
}
|
||||
|
||||
if (currTabBtn.classList.contains("!hidden")) {
|
||||
return firstNotHiddenEl.click();
|
||||
}
|
||||
if (this.comboboxEl && avoidComboFocus)
|
||||
this.comboboxEl.setAttribute("data-focus", "false");
|
||||
let canClick = true;
|
||||
// check if can click based on next dropdown state
|
||||
if (disableClose && !dropdownEl.classList.contains("hidden"))
|
||||
canClick = false;
|
||||
if (disableOpen && dropdownEl.classList.contains("hidden"))
|
||||
canClick = false;
|
||||
if (canClick) dropdownBtn.click();
|
||||
// Case avoid focus on combobox, we need to reset here because the focusin event is not triggered
|
||||
if (this.comboboxEl && avoidComboFocus) this.runComboFilter();
|
||||
// Reset to default state
|
||||
if (this.comboboxEl) this.comboboxEl.setAttribute("data-focus", "true");
|
||||
}
|
||||
|
||||
resetFilter() {
|
||||
|
|
|
|||
|
|
@ -286,6 +286,14 @@
|
|||
@apply transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-300;
|
||||
}
|
||||
|
||||
.core-card-text-doc {
|
||||
@apply transition duration-300 ease-in-out mb-0 font-sans text-sm leading-normal dark:text-gray-300 px-1 mt-4 mb-2;
|
||||
}
|
||||
|
||||
.core-card-text-doc-link {
|
||||
@apply hover:brightness-90 cursor-pointer mt-2 underline text-sky-500;
|
||||
}
|
||||
|
||||
.center.core-card-text {
|
||||
@apply text-center;
|
||||
}
|
||||
|
|
@ -343,7 +351,15 @@
|
|||
}
|
||||
|
||||
.core-card-list {
|
||||
@apply ml-2 mr-2 mb-2 mt-2 h-fit content-start md:col-span-6 overflow-x-hidden overflow-y-auto grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words dark:brightness-110 bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border;
|
||||
@apply ml-2 mr-2 mb-2 mt-2 content-start md:col-span-6 overflow-x-hidden overflow-y-auto grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words dark:brightness-110 bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border;
|
||||
}
|
||||
|
||||
.core-card-list.no-data {
|
||||
@apply place-content-stretch;
|
||||
}
|
||||
|
||||
.core-card-list-no-data {
|
||||
@apply pb-[2rem] text-2xl text-center mb-0;
|
||||
}
|
||||
|
||||
.w-small.core-card-list {
|
||||
|
|
@ -522,6 +538,10 @@
|
|||
@apply text-sm tracking-wide dark:brightness-90 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-yellow-500 hover:bg-yellow-500/80 focus:bg-yellow-500/80 leading-normal ease-in shadow-xs hover:-translate-y-px active:opacity-85 hover:shadow-md disabled:cursor-not-allowed dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-700 dark:disabled:border-gray-700/0 disabled:hover:translate-y-0 disabled:hover:bg-gray-400 disabled:hover:border-gray-400/0 dark:disabled:hover:translate-y-0 dark:disabled:hover:bg-gray-700 dark:disabled:hover:border-gray-700/0;
|
||||
}
|
||||
|
||||
.core-card-upload-btn {
|
||||
@apply w-fit disabled:hover:translate-y-0 disabled:cursor-not-allowed disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 tracking-wide dark:brightness-125 hover:brightness-75 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-gradient-to-tl bg-primary leading-normal text-xs ease-in shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md;
|
||||
}
|
||||
|
||||
.core-card-test-status-container {
|
||||
@apply mx-1 flex justify-center items-center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ module.exports = {
|
|||
"text-yellow-500",
|
||||
"text-green-500",
|
||||
"text-red-500",
|
||||
"text-sky-500",
|
||||
],
|
||||
|
||||
presets: [],
|
||||
|
|
|
|||
116
src/ui/templates/account.html
vendored
116
src/ui/templates/account.html
vendored
|
|
@ -103,7 +103,9 @@
|
|||
<p class="my-2 mr-2 dark:text-gray-300 text-center font-bold">{{ pro_services }} services allowed</p>
|
||||
{% endif %}
|
||||
{% if pro_expire %}
|
||||
<p class="my-2 mr-2 dark:text-gray-300 text-center">License expiration date : <span data-expire class="font-bold">{{ pro_expire }}</span></p>
|
||||
<p class="my-2 mr-2 dark:text-gray-300 text-center">
|
||||
License expiration date : <span data-expire class="font-bold">{{ pro_expire }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
@ -115,60 +117,66 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<form class="mt-6 relative col-span-12 grid grid-cols-12 w-full justify-items-center"
|
||||
id="activate-key-form"
|
||||
action="account"
|
||||
method="POST"
|
||||
autocomplete="off">
|
||||
<div class="col-span-12">
|
||||
<h5 class="text-xl my-1 transition duration-300 ease-in-out text-md font-bold m-0 dark:text-gray-200">{%if is_pro_version %}UPDATE KEY {% else %} ACTIVATE KEY {% endif %}</h5>
|
||||
<form class="mt-6 relative col-span-12 grid grid-cols-12 w-full justify-items-center"
|
||||
id="activate-key-form"
|
||||
action="account"
|
||||
method="POST"
|
||||
autocomplete="off">
|
||||
<div class="col-span-12">
|
||||
<h5 class="text-xl my-1 transition duration-300 ease-in-out text-md font-bold m-0 dark:text-gray-200">
|
||||
{% if is_pro_version %}
|
||||
UPDATE KEY
|
||||
{% else %}
|
||||
ACTIVATE KEY
|
||||
{% endif %}
|
||||
</h5>
|
||||
</div>
|
||||
<input type="hidden" name="operation" value="activate-key" />
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden"
|
||||
name="next"
|
||||
value="{{ request.values.get('next', '') }}" />
|
||||
<div data-input-group
|
||||
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
|
||||
<h5 class="input-title">License key</h5>
|
||||
<label class="sr-only" for="license">License key</label>
|
||||
<input type="password"
|
||||
id="license"
|
||||
name="license"
|
||||
class="col-span-12 regular-input"
|
||||
placeholder="enter new license key"
|
||||
value=""
|
||||
pattern="^.*$"
|
||||
required />
|
||||
<div data-setting-password-container
|
||||
class="absolute flex right-6 md:right-8 h-5 w-5 top-[55%] md:top-[53%]">
|
||||
<button data-setting-password="visible"
|
||||
class="h-5 w-5 flex items-center align-middle dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
type="button">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512">
|
||||
<path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button data-setting-password="invisible"
|
||||
class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle"
|
||||
type="button">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512">
|
||||
<path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<input type="hidden" name="operation" value="activate-key" />
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden"
|
||||
name="next"
|
||||
value="{{ request.values.get('next', '') }}" />
|
||||
<div data-input-group
|
||||
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
|
||||
<h5 class="input-title">License key</h5>
|
||||
<label class="sr-only" for="license">License key</label>
|
||||
<input type="password"
|
||||
id="license"
|
||||
name="license"
|
||||
class="col-span-12 regular-input"
|
||||
placeholder="enter new license key"
|
||||
value=""
|
||||
pattern="^.*$"
|
||||
required />
|
||||
<div data-setting-password-container
|
||||
class="absolute flex right-6 md:right-8 h-5 w-5 top-[55%] md:top-[53%]">
|
||||
<button data-setting-password="visible"
|
||||
class="h-5 w-5 flex items-center align-middle dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
type="button">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512">
|
||||
<path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button data-setting-password="invisible"
|
||||
class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle"
|
||||
type="button">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512">
|
||||
<path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 flex justify-center mt-6">
|
||||
<button type="submit"
|
||||
id="activate-key-button"
|
||||
name="activate-key-button"
|
||||
class="valid-btn">SAVE</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-span-12 flex justify-center mt-6">
|
||||
<button type="submit"
|
||||
id="activate-key-button"
|
||||
name="activate-key-button"
|
||||
class="valid-btn">SAVE</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-tab-item="username"
|
||||
class="hidden grid grid-cols-12 w-full justify-items-center">
|
||||
|
|
|
|||
19
src/ui/templates/bans.html
vendored
19
src/ui/templates/bans.html
vendored
|
|
@ -48,19 +48,12 @@
|
|||
<div class="{% if bans|length == 0 %}hidden{% endif %} h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in bans_info %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for info in bans_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
|
|
|||
4
src/ui/templates/bans_modal.html
vendored
4
src/ui/templates/bans_modal.html
vendored
|
|
@ -125,7 +125,9 @@
|
|||
<input data-ban-add-inp type="hidden" name="data" value="" />
|
||||
<!-- action button -->
|
||||
<div class="w-full justify-center flex mt-6 mb-4">
|
||||
<button data-bans-modal-close type="button" class="dark:bg-slate-800 close-btn mr-3 text-base">Close</button>
|
||||
<button data-bans-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mr-3 text-base">Close</button>
|
||||
<button disabled data-bans-modal-submit type="submit" class="valid-btn">Add</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
|
|
|
|||
23
src/ui/templates/configs.html
vendored
23
src/ui/templates/configs.html
vendored
|
|
@ -14,21 +14,16 @@
|
|||
] %}
|
||||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in configs_info %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p data-info-{{ info['id'] }} role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in configs_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p data-info-{{ info['id'] }} role="gridcell" class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
<!-- filter -->
|
||||
|
|
|
|||
1
src/ui/templates/global_config.html
vendored
1
src/ui/templates/global_config.html
vendored
|
|
@ -92,7 +92,6 @@
|
|||
role="listbox"
|
||||
data-global-config-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-global-config-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
|
|
|
|||
48
src/ui/templates/head.html
vendored
48
src/ui/templates/head.html
vendored
|
|
@ -10,42 +10,42 @@
|
|||
<title>BunkerWeb UI</title>
|
||||
<link rel="icon" type="image/x-icon" href="images/favicon.ico" />
|
||||
<!-- tailwind style -->
|
||||
<link rel="stylesheet" type="text/css" href="./css/plugins.css" />
|
||||
<link rel="stylesheet" type="text/css" href="./css/dashboard.css" />
|
||||
<script type="module" src="./js/global.js" nonce="{{ script_nonce }}"></script>
|
||||
<script src="./js/plugins/utils.js" nonce="{{ script_nonce }}"></script>
|
||||
<link rel="stylesheet" href="css/plugins.css" />
|
||||
<link rel="stylesheet" href="css/dashboard.css" />
|
||||
<script type="module" src="js/global.js" nonce="{{ script_nonce }}"></script>
|
||||
<script src="js/plugins/utils.js" nonce="{{ script_nonce }}"></script>
|
||||
<script async
|
||||
src="./js/utils/purify/purify.min.js"
|
||||
src="js/utils/purify/purify.min.js"
|
||||
nonce="{{ script_nonce }}"></script>
|
||||
<script src="./js/editor/ace.js" nonce="{{ script_nonce }}"></script>
|
||||
<script src="js/editor/ace.js" nonce="{{ script_nonce }}"></script>
|
||||
{% if current_endpoint == "global_config" %}
|
||||
<script type="module" src="./js/global_config.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/global_config.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "configs" %}
|
||||
<script type="module" src="./js/configs.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/configs.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "services" %}
|
||||
<script type="module" src="./js/services.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/services.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "plugins" %}
|
||||
<script type="module" src="./js/plugins.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/plugins.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "cache" %}
|
||||
<script type="module" src="./js/cache.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/cache.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "logs" %}
|
||||
<link rel="stylesheet" type="text/css" href="./css/flatpickr.css" />
|
||||
<link rel="stylesheet" type="text/css" href="./css/flatpickr.dark.css" />
|
||||
<script defer src="./js/utils/flatpickr.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="./js/logs.js" nonce="{{ script_nonce }}"></script>
|
||||
<link rel="stylesheet" href="css/flatpickr.css" />
|
||||
<link rel="stylesheet" href="css/flatpickr.dark.css" />
|
||||
<script defer src="js/utils/flatpickr.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/logs.js" nonce="{{ script_nonce }}"></script>
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="./css/datepicker-foundation.css" />
|
||||
|
||||
href="css/datepicker-foundation.css" />
|
||||
{% elif current_endpoint == "jobs" %}
|
||||
<script type="module" src="./js/jobs.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/jobs.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "account" %}
|
||||
<script type="module" src="./js/account.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/account.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "reports" %}
|
||||
<script type="module" src="./js/reports.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/reports.js" nonce="{{ script_nonce }}"></script>
|
||||
{% elif current_endpoint == "bans" %}
|
||||
<link rel="stylesheet" type="text/css" href="./css/flatpickr.css" />
|
||||
<link rel="stylesheet" type="text/css" href="./css/flatpickr.dark.css" />
|
||||
<script defer src="./js/utils/flatpickr.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="./js/bans.js" nonce="{{ script_nonce }}"></script>
|
||||
<link rel="stylesheet" href="css/flatpickr.css" />
|
||||
<link rel="stylesheet" href="css/flatpickr.dark.css" />
|
||||
<script defer src="js/utils/flatpickr.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/bans.js" nonce="{{ script_nonce }}"></script>
|
||||
{% endif %}
|
||||
</head>
|
||||
|
|
|
|||
13
src/ui/templates/instances.html
vendored
13
src/ui/templates/instances.html
vendored
|
|
@ -27,16 +27,9 @@
|
|||
{% set instance_details = [{"name" : "TYPE", "value" : instance['_type']},{"name" : "HOSTNAME", "value" : instance['hostname']}] %}
|
||||
<!-- detail -->
|
||||
{% for detail in instance_details %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ detail['name'] }}
|
||||
</p>
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ detail['value'] }}
|
||||
</p>
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ detail['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ detail['value'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end detail -->
|
||||
|
|
|
|||
286
src/ui/templates/jobs.html
vendored
286
src/ui/templates/jobs.html
vendored
|
|
@ -14,19 +14,12 @@
|
|||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in jobs_info %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for info in jobs_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
|
@ -150,138 +143,143 @@
|
|||
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No jobs match</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div data-jobs-list-container
|
||||
class="w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<div class="overflow-auto w-full col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<div class="col-span-12">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">JOBS LIST</h5>
|
||||
</div>
|
||||
<div class="col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
{% set job_headers = [
|
||||
{
|
||||
"name": "Name",
|
||||
"custom_class": "col-span-3"
|
||||
},
|
||||
{
|
||||
"name": "Last run",
|
||||
"custom_class": "col-span-3"
|
||||
},
|
||||
{
|
||||
"name": "Every",
|
||||
"custom_class": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Reload",
|
||||
"custom_class": "flex justify-center col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Success",
|
||||
"custom_class": "flex justify-center col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Files",
|
||||
"custom_class": "col-span-3"
|
||||
}
|
||||
] %}
|
||||
<div class="min-w-[900px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
{% for header in job_headers %}
|
||||
<p class="{{ header['custom_class'] }} dark:text-gray-100 h-8 text-sm font-bold m-0 pb-2 border-b border-gray-400">
|
||||
{{ header['name'] }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-jobs-list>
|
||||
{% for job_name, value in jobs.items() %}
|
||||
<!-- job item-->
|
||||
{% set jobs_data = [
|
||||
{"type" : "text", "filter_name" : "name", "value" : job_name, "custom_class" : "col-span-3"},
|
||||
{"type" : "text", "filter_name" : "last_run", "value" : value['last_run'], "custom_class" : "col-span-3"},
|
||||
{"type" : "text", "filter_name" : "every", "value" : value['every'], "custom_class" : "col-span-1"},
|
||||
{"type" : "check", "filter_name" : "reload", "value" : value['reload'], "custom_class" : "col-span-1"},
|
||||
{"type" : "check", "filter_name" : "success", "value" : value['success'], "custom_class" : "col-span-1"},
|
||||
{"type" : "select", "filter_name" : "success", "value" : value['success'], "custom_class" : "col-span-3"},
|
||||
] %}
|
||||
<li data-jobs-item
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
|
||||
{% for data in jobs_data %}
|
||||
{% if data['type'] == "text" %}
|
||||
<p class="{{ data['custom_class'] }} dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="{{ data['value'] }}">
|
||||
{{ data['value'] }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "check" and data['value'] %}
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="true">
|
||||
<svg class="fill-green-500 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" />
|
||||
</svg>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "check" and not data['value'] %}
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="false">
|
||||
<svg class="fill-red-500 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" />
|
||||
</svg>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "select" %}
|
||||
<div class="{{ data['custom_class'] }} relative dark:text-gray-400 text-sm m-0 my-1"
|
||||
data-jobs-files>
|
||||
{% if value['cache'] %}
|
||||
<button data-jobs-setting-select="{{ job_name }}"
|
||||
class="py-1 text-sm disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left leading-6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span id="jobs-{{ job_name }}"
|
||||
data-name="jobs-{{ job_name }}"
|
||||
data-jobs-setting-select-text="{{ job_name }}">files</span>
|
||||
<!-- chevron -->
|
||||
<svg data-jobs-setting-select="{{ job_name }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div data-jobs-setting-select-dropdown="{{ job_name }}"
|
||||
class="hidden z-100 absolute h-full flex-col w-full translate-y-0.5">
|
||||
{% for file in value['cache'] %}
|
||||
<button data-jobs-download="{{ job_name }}"
|
||||
data-jobs-file="{{ file['file_name'] }}"
|
||||
data-jobs-setting-select-dropdown-btn="{{ job_name }}"
|
||||
value="files"
|
||||
class="{% if loop.index == loop.length %}rounded-b-lg {% endif %}{% if loop.first %}rounded-t-lg{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 bg-white dark:bg-slate-700 text-gray-700">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-sky-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 ml-2">{{ file['file_name'] }}</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</li>
|
||||
<!-- end job item-->
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
<h5 class="mx-4 mt-2 font-bold dark:text-white/90 mx-2">JOBS LIST</h5>
|
||||
</div>
|
||||
<div data-jobs-list-container
|
||||
class="relative min-w-[900px] w-full overflow-auto grid grid-cols-12 max-h-100 sm:max-h-125">
|
||||
|
||||
<div class="col-span-12">
|
||||
<!-- list container-->
|
||||
{% set job_headers = [
|
||||
{
|
||||
"name": "Name",
|
||||
"custom_class": "col-span-3"
|
||||
},
|
||||
{
|
||||
"name": "Last run",
|
||||
"custom_class": "col-span-3"
|
||||
},
|
||||
{
|
||||
"name": "Every",
|
||||
"custom_class": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Reload",
|
||||
"custom_class": "flex justify-center col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Success",
|
||||
"custom_class": "flex justify-center col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Files",
|
||||
"custom_class": "col-span-3"
|
||||
}
|
||||
] %}
|
||||
<div class="w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
{% for header in job_headers %}
|
||||
<p class="{{ header['custom_class'] }} dark:text-gray-100 h-8 text-sm font-bold m-0 pb-2 border-b border-gray-400">
|
||||
{{ header['name'] }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-jobs-list>
|
||||
{% for job_name, value in jobs.items() %}
|
||||
<!-- job item-->
|
||||
{% set jobs_data = [
|
||||
{"type" : "text", "filter_name" : "name", "value" : job_name, "custom_class" : "col-span-3"},
|
||||
{"type" : "text", "filter_name" : "last_run", "value" : value['last_run'], "custom_class" : "col-span-3"},
|
||||
{"type" : "text", "filter_name" : "every", "value" : value['every'], "custom_class" : "col-span-1"},
|
||||
{"type" : "check", "filter_name" : "reload", "value" : value['reload'], "custom_class" : "col-span-1"},
|
||||
{"type" : "check", "filter_name" : "success", "value" : value['success'], "custom_class" : "col-span-1"},
|
||||
{"type" : "select", "filter_name" : "success", "value" : value['success'], "custom_class" : "col-span-3"},
|
||||
] %}
|
||||
<li data-jobs-item
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
|
||||
{% for data in jobs_data %}
|
||||
{% if data['type'] == "text" %}
|
||||
<p class="{{ data['custom_class'] }} dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="{{ data['value'] }}">
|
||||
{{ data['value'] }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "check" and data['value'] %}
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="true">
|
||||
<svg class="fill-green-500 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" />
|
||||
</svg>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "check" and not data['value'] %}
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="false">
|
||||
<svg class="fill-red-500 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" />
|
||||
</svg>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "select" %}
|
||||
<div class="{{ data['custom_class'] }} relative dark:text-gray-400 text-sm m-0 my-1"
|
||||
data-jobs-files>
|
||||
{% if value['cache'] %}
|
||||
<button data-jobs-setting-select="{{ job_name }}"
|
||||
class="py-1 text-sm disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left leading-6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span id="jobs-{{ job_name }}"
|
||||
data-name="jobs-{{ job_name }}"
|
||||
data-jobs-setting-select-text="{{ job_name }}">files</span>
|
||||
<!-- chevron -->
|
||||
<svg data-jobs-setting-select="{{ job_name }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div data-jobs-setting-select-dropdown="{{ job_name }}"
|
||||
class="hidden z-100 absolute h-full flex-col w-full translate-y-0.5">
|
||||
{% for file in value['cache'] %}
|
||||
<button data-jobs-plugin="{{ value['plugin_id'] }}"
|
||||
data-jobs-download="{{ job_name }}"
|
||||
data-jobs-file="{{ file['file_name'] }}"
|
||||
data-jobs-setting-select-dropdown-btn="{{ job_name }}"
|
||||
value="files"
|
||||
class="{% if loop.index == loop.length %}rounded-b-lg {% endif %}{% if loop.first %}rounded-t-lg{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 bg-white dark:bg-slate-700 text-gray-700">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-sky-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 ml-2">{{ file['file_name'] }}</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</li>
|
||||
<!-- end job item-->
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
|
|
|||
368
src/ui/templates/menu.html
vendored
368
src/ui/templates/menu.html
vendored
|
|
@ -35,14 +35,14 @@
|
|||
<!-- logo and version -->
|
||||
<div class="w-full">
|
||||
<a aria-label="link to home"
|
||||
class="flex justify-center px-8 m-0 text-sm whitespace-nowrap dark:text-white text-slate-700"
|
||||
href="{% if current_endpoint == 'home' %}#{% else %}loading?next={{ url_for("home") }}{% endif %}">
|
||||
class="flex justify-center px-8 m-0 text-sm whitespace-nowrap dark:text-white text-slate-700"
|
||||
href="{% if current_endpoint == 'home' %}#{% else %}loading?next={{ url_for("home") }}{% endif %}">
|
||||
<img src="images/logo-menu-2.png"
|
||||
class="hidden dark:inline w-28 sm:w-36 transition-all duration-200 h-8 sm:h-10"
|
||||
alt="main logo" />
|
||||
class="hidden dark:inline w-28 sm:w-36 transition-all duration-200 h-8 sm:h-10"
|
||||
alt="main logo" />
|
||||
<img src="images/logo-menu.png"
|
||||
class="dark:hidden inline w-28 sm:w-36 transition-all duration-200 h-8 sm:h-10"
|
||||
alt="main logo" />
|
||||
class="dark:hidden inline w-28 sm:w-36 transition-all duration-200 h-8 sm:h-10"
|
||||
alt="main logo" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-2 w-full px-1">
|
||||
|
|
@ -50,197 +50,194 @@
|
|||
{{ username }}
|
||||
</h1>
|
||||
<a class="block underline mb-2 text-gray-600 dark:text-gray-400 text-sm text-center hover:brightness-90"
|
||||
href="{% if current_endpoint == 'account' %}#{% else %}loading?next={{ url_for("account") }}{% endif %}">manage account
|
||||
href="{% if current_endpoint == 'account' %}#{% else %}loading?next={{ url_for("account") }}{% endif %}">manage account
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr class="h-px mt-0 bg-transparent bg-gradient-to-r from-transparent via-black/40 to-transparent dark:bg-gradient-to-r dark:from-transparent dark:via-white dark:to-transparent" />
|
||||
<!-- end logo version -->
|
||||
</div>
|
||||
|
||||
<!-- list items -->
|
||||
<div class="items-center block w-auto overflow-auto grow basis-full">
|
||||
<!-- default anchor -->
|
||||
<ul class="flex flex-col pl-0 mb-0">
|
||||
{% set paths = [
|
||||
"home",
|
||||
"instances",
|
||||
"global_config",
|
||||
"services",
|
||||
"configs",
|
||||
"plugins",
|
||||
"cache",
|
||||
"reports",
|
||||
"bans",
|
||||
"jobs",
|
||||
"logs"
|
||||
] %}
|
||||
<!-- loop paths -->
|
||||
{% for path in paths %}
|
||||
<li class="mt-0.5 w-full">
|
||||
<a class="{% if current_endpoint == path %} font-semibold text-slate-700 dark:bg-primary/50 rounded-lg dark:hover:bg-primary/60 bg-primary/10 hover:bg-primary/30 {% else %} dark:hover:bg-primary/20 hover:bg-primary/5 {% endif %} dark:text-gray-200 py-1 ease-nav-brand my-0 mx-2 flex items-center whitespace-nowrap rounded-lg px-4 transition text-sm"
|
||||
href="{% if current_endpoint == path %}#{% else %}loading?next={{ url_for(path) }}{% endif %}">
|
||||
<div class="mr-2 flex items-center justify-center rounded-lg bg-center stroke-0 text-center p-1 xl:p-1.5">
|
||||
{% if path == "home" %}
|
||||
<svg class="stroke-sky-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "instances" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="stroke-stone-500 h-5.5 w-5.5 relative">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "global_config" %}
|
||||
<svg class="stroke-blue-400 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "services" %}
|
||||
<svg class="stroke-orange-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "configs" %}
|
||||
<svg class="stroke-blue-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "plugins" %}
|
||||
<svg class="stroke-yellow-400 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 01-.657.643 48.39 48.39 0 01-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 01-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 00-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 01-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 00.657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.4.604-.4.959v0c0 .333.277.599.61.58a48.1 48.1 0 005.427-.63 48.05 48.05 0 00.582-4.717.532.532 0 00-.533-.57v0c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.37 0 .713.128 1.003.349.283.215.604.401.96.401v0a.656.656 0 00.658-.663 48.422 48.422 0 00-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 01-.61-.58v0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "cache" %}
|
||||
<svg class="stroke-pink-600 h-5.5 w-5.5 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "reports" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="stroke-amber-500 dark:stroke-amber-500 h-6 w-6 relative">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 3v1.5M3 21v-6m0 0 2.77-.693a9 9 0 0 1 6.208.682l.108.054a9 9 0 0 0 6.086.71l3.114-.732a48.524 48.524 0 0 1-.005-10.499l-3.11.732a9 9 0 0 1-6.085-.711l-.108-.054a9 9 0 0 0-6.208-.682L3 4.5M3 15V4.5" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "bans" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="stroke-red-500 dark:stroke-red-500 h-6 w-6 relative">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 0 0 5.636 5.636m12.728 12.728A9 9 0 0 1 5.636 5.636m12.728 12.728L5.636 5.636" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "jobs" %}
|
||||
<svg class="stroke-emerald-600 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.125 2.25h-4.5c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125v-9M10.125 2.25h.375a9 9 0 019 9v.375M10.125 2.25A3.375 3.375 0 0113.5 5.625v1.5c0 .621.504 1.125 1.125 1.125h1.5a3.375 3.375 0 013.375 3.375M9 15l2.25 2.25L15 12" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "logs" %}
|
||||
<svg class="stroke-gray-600 dark:fill-gray-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 6.75h12M8.25 12h12m-12 5.25h12M3.75 6.75h.007v.008H3.75V6.75zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zM3.75 12h.007v.008H3.75V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm-.375 5.25h.007v.008H3.75v-.008zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="ml-1 duration-300 dark:text-gray-200 pointer-events-none ease">{{ path[0]|upper }}{{ path[1:].replace('_', ' ') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<!-- end loop paths-->
|
||||
</ul>
|
||||
<!-- end default anchor -->
|
||||
<ul>
|
||||
<li class="w-full mt-4">
|
||||
<h6 class="pl-6 ml-2 text-xs font-bold leading-tight uppercase dark:text-gray-400 dark:opacity-100 opacity-60">
|
||||
PLUGINS PAGE
|
||||
</h6>
|
||||
<!-- list items -->
|
||||
<div class="items-center block w-auto overflow-auto grow basis-full">
|
||||
<!-- default anchor -->
|
||||
<ul class="flex flex-col pl-0 mb-0">
|
||||
{% set paths = [
|
||||
"home",
|
||||
"instances",
|
||||
"global_config",
|
||||
"services",
|
||||
"configs",
|
||||
"plugins",
|
||||
"cache",
|
||||
"reports",
|
||||
"bans",
|
||||
"jobs",
|
||||
"logs"
|
||||
] %}
|
||||
<!-- loop paths -->
|
||||
{% for path in paths %}
|
||||
<li class="mt-0.5 w-full">
|
||||
<a class="{% if current_endpoint == path %} font-semibold text-slate-700 dark:bg-primary/50 rounded-lg dark:hover:bg-primary/60 bg-primary/10 hover:bg-primary/30 {% else %} dark:hover:bg-primary/20 hover:bg-primary/5 {% endif %} dark:text-gray-200 py-1 ease-nav-brand my-0 mx-2 flex items-center whitespace-nowrap rounded-lg px-4 transition text-sm"
|
||||
href="{% if current_endpoint == path %}#{% else %}loading?next={{ url_for(path) }}{% endif %}">
|
||||
<div class="mr-2 flex items-center justify-center rounded-lg bg-center stroke-0 text-center p-1 xl:p-1.5">
|
||||
{% if path == "home" %}
|
||||
<svg class="stroke-sky-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "instances" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="stroke-stone-500 h-5.5 w-5.5 relative">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "global_config" %}
|
||||
<svg class="stroke-blue-400 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "services" %}
|
||||
<svg class="stroke-orange-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "configs" %}
|
||||
<svg class="stroke-blue-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "plugins" %}
|
||||
<svg class="stroke-yellow-400 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 01-.657.643 48.39 48.39 0 01-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 01-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 00-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 01-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 00.657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.4.604-.4.959v0c0 .333.277.599.61.58a48.1 48.1 0 005.427-.63 48.05 48.05 0 00.582-4.717.532.532 0 00-.533-.57v0c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.37 0 .713.128 1.003.349.283.215.604.401.96.401v0a.656.656 0 00.658-.663 48.422 48.422 0 00-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 01-.61-.58v0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "cache" %}
|
||||
<svg class="stroke-pink-600 h-5.5 w-5.5 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "reports" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="stroke-amber-500 dark:stroke-amber-500 h-6 w-6 relative">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 3v1.5M3 21v-6m0 0 2.77-.693a9 9 0 0 1 6.208.682l.108.054a9 9 0 0 0 6.086.71l3.114-.732a48.524 48.524 0 0 1-.005-10.499l-3.11.732a9 9 0 0 1-6.085-.711l-.108-.054a9 9 0 0 0-6.208-.682L3 4.5M3 15V4.5" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "bans" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="stroke-red-500 dark:stroke-red-500 h-6 w-6 relative">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 0 0 5.636 5.636m12.728 12.728A9 9 0 0 1 5.636 5.636m12.728 12.728L5.636 5.636" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "jobs" %}
|
||||
<svg class="stroke-emerald-600 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.125 2.25h-4.5c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125v-9M10.125 2.25h.375a9 9 0 019 9v.375M10.125 2.25A3.375 3.375 0 0113.5 5.625v1.5c0 .621.504 1.125 1.125 1.125h1.5a3.375 3.375 0 013.375 3.375M9 15l2.25 2.25L15 12" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if path == "logs" %}
|
||||
<svg class="stroke-gray-600 dark:fill-gray-500 h-6 w-6 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 6.75h12M8.25 12h12m-12 5.25h12M3.75 6.75h.007v.008H3.75V6.75zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zM3.75 12h.007v.008H3.75V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm-.375 5.25h.007v.008H3.75v-.008zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="ml-1 duration-300 dark:text-gray-200 pointer-events-none ease">{{ path[0]|upper }}{{ path[1:].replace('_', ' ') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% for plugin in plugins %}
|
||||
{% if plugin['page'] %}
|
||||
<li class="mt-0.5 w-full">
|
||||
<a class="dark:hover:bg-primary/20 hover:bg-primary/5 hover:rounded-lg dark:text-gray-200 py-1 text-sm ease-nav-brand my-0 mx-2 flex items-center whitespace-nowrap px-4 transition"
|
||||
href="{{ request.url_root }}plugins/{{ plugin['id'] }}">
|
||||
<div class="mr-2 flex flex-wrap items-center justify-center rounded-lg bg-center stroke-0 text-center p-1 xl:p-1.5">
|
||||
{% if plugin['type'] != "pro" %}
|
||||
{% endfor %}
|
||||
<!-- end loop paths-->
|
||||
</ul>
|
||||
<!-- end default anchor -->
|
||||
<ul>
|
||||
<li class="w-full mt-4">
|
||||
<h6 class="pl-6 ml-2 text-xs font-bold leading-tight uppercase dark:text-gray-400 dark:opacity-100 opacity-60">
|
||||
PLUGINS PAGE
|
||||
</h6>
|
||||
</li>
|
||||
{% for plugin in plugins %}
|
||||
{% if plugin['page'] %}
|
||||
<li class="mt-0.5 w-full">
|
||||
<a class="dark:hover:bg-primary/20 hover:bg-primary/5 hover:rounded-lg dark:text-gray-200 py-1 text-sm ease-nav-brand my-0 mx-2 flex items-center whitespace-nowrap px-4 transition"
|
||||
href="{{ request.url_root }}plugins/{{ plugin['id'] }}">
|
||||
<div class="mr-2 flex flex-wrap items-center justify-center rounded-lg bg-center stroke-0 text-center p-1 xl:p-1.5">
|
||||
{% if plugin['type'] != "pro" %}
|
||||
<svg class="fill-gray-500 h-5 w-5 relative"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 384 512">
|
||||
<path d="M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
{% if plugin['type'] == "pro" %}
|
||||
{% endif %}
|
||||
{% if plugin['type'] == "pro" %}
|
||||
<svg class="h-5 w-5 dark:brightness-90 relative"
|
||||
viewBox="0 0 48 46"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="fill-yellow-500" d="M43.218 28.2327L43.6765 23.971C43.921 21.6973 44.0825 20.1957 43.9557 19.2497L44 19.25C46.071 19.25 47.75 17.5711 47.75 15.5C47.75 13.4289 46.071 11.75 44 11.75C41.929 11.75 40.25 13.4289 40.25 15.5C40.25 16.4366 40.5935 17.2931 41.1613 17.9503C40.346 18.4535 39.2805 19.515 37.6763 21.1128C36.4405 22.3438 35.8225 22.9593 35.1333 23.0548C34.7513 23.1075 34.3622 23.0532 34.0095 22.898C33.373 22.6175 32.9485 21.8567 32.0997 20.335L27.6262 12.3135C27.1025 11.3747 26.6642 10.5889 26.2692 9.95662C27.89 9.12967 29 7.44445 29 5.5C29 2.73857 26.7615 0.5 24 0.5C21.2385 0.5 19 2.73857 19 5.5C19 7.44445 20.11 9.12967 21.7308 9.95662C21.3358 10.589 20.8975 11.3746 20.3738 12.3135L15.9002 20.335C15.0514 21.8567 14.627 22.6175 13.9905 22.898C13.6379 23.0532 13.2487 23.1075 12.8668 23.0548C12.1774 22.9593 11.5595 22.3438 10.3238 21.1128C8.71968 19.515 7.6539 18.4535 6.83882 17.9503C7.4066 17.2931 7.75 16.4366 7.75 15.5C7.75 13.4289 6.07107 11.75 4 11.75C1.92893 11.75 0.25 13.4289 0.25 15.5C0.25 17.5711 1.92893 19.25 4 19.25L4.04428 19.2497C3.91755 20.1957 4.07905 21.6973 4.32362 23.971L4.782 28.2327C5.03645 30.5982 5.24802 32.849 5.50717 34.875H42.4928C42.752 32.849 42.9635 30.5982 43.218 28.2327Z" fill="#1C274C" />
|
||||
<path class="fill-yellow-500" d="M21.2803 45.5H26.7198C33.8098 45.5 37.3545 45.5 39.7198 43.383C40.7523 42.4588 41.4057 40.793 41.8775 38.625H6.1224C6.59413 40.793 7.24783 42.4588 8.2802 43.383C10.6454 45.5 14.1903 45.5 21.2803 45.5Z" fill="#1C274C" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="ml-1 duration-300 opacity-100 pointer-events-none ease">{{ plugin['name'] }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end plugin list -->
|
||||
</div>
|
||||
<!-- end top sidebar -->
|
||||
|
||||
<!-- end list items -->
|
||||
<!-- bottom sidebar -->
|
||||
viewBox="0 0 48 46"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="fill-yellow-500" d="M43.218 28.2327L43.6765 23.971C43.921 21.6973 44.0825 20.1957 43.9557 19.2497L44 19.25C46.071 19.25 47.75 17.5711 47.75 15.5C47.75 13.4289 46.071 11.75 44 11.75C41.929 11.75 40.25 13.4289 40.25 15.5C40.25 16.4366 40.5935 17.2931 41.1613 17.9503C40.346 18.4535 39.2805 19.515 37.6763 21.1128C36.4405 22.3438 35.8225 22.9593 35.1333 23.0548C34.7513 23.1075 34.3622 23.0532 34.0095 22.898C33.373 22.6175 32.9485 21.8567 32.0997 20.335L27.6262 12.3135C27.1025 11.3747 26.6642 10.5889 26.2692 9.95662C27.89 9.12967 29 7.44445 29 5.5C29 2.73857 26.7615 0.5 24 0.5C21.2385 0.5 19 2.73857 19 5.5C19 7.44445 20.11 9.12967 21.7308 9.95662C21.3358 10.589 20.8975 11.3746 20.3738 12.3135L15.9002 20.335C15.0514 21.8567 14.627 22.6175 13.9905 22.898C13.6379 23.0532 13.2487 23.1075 12.8668 23.0548C12.1774 22.9593 11.5595 22.3438 10.3238 21.1128C8.71968 19.515 7.6539 18.4535 6.83882 17.9503C7.4066 17.2931 7.75 16.4366 7.75 15.5C7.75 13.4289 6.07107 11.75 4 11.75C1.92893 11.75 0.25 13.4289 0.25 15.5C0.25 17.5711 1.92893 19.25 4 19.25L4.04428 19.2497C3.91755 20.1957 4.07905 21.6973 4.32362 23.971L4.782 28.2327C5.03645 30.5982 5.24802 32.849 5.50717 34.875H42.4928C42.752 32.849 42.9635 30.5982 43.218 28.2327Z" fill="#1C274C" />
|
||||
<path class="fill-yellow-500" d="M21.2803 45.5H26.7198C33.8098 45.5 37.3545 45.5 39.7198 43.383C40.7523 42.4588 41.4057 40.793 41.8775 38.625H6.1224C6.59413 40.793 7.24783 42.4588 8.2802 43.383C10.6454 45.5 14.1903 45.5 21.2803 45.5Z" fill="#1C274C" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class="ml-1 duration-300 opacity-100 pointer-events-none ease">{{ plugin['name'] }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end plugin list -->
|
||||
</div>
|
||||
<!-- end top sidebar -->
|
||||
<!-- end list items -->
|
||||
<!-- bottom sidebar -->
|
||||
<div class="flex flex-col justify-end mx-4 mt-2 mb-4">
|
||||
<!-- dark/light mode -->
|
||||
<div class="min-h-6 ml-12 my-4 flex justify-start">
|
||||
|
|
@ -251,6 +248,7 @@
|
|||
<input {% if dark_mode == True %}checked{% endif %}
|
||||
id="darkMode"
|
||||
data-dark-toggle
|
||||
data-mode-link="{{ url_for('darkmode') }}"
|
||||
class="dark:brightness-125 hover:brightness-75 rounded-10 duration-300 ease-in-out after:rounded-circle after:shadow-2xl after:duration-300 checked:after:translate-x-5.3 h-5 mt-0.5 relative float-left w-10 cursor-pointer appearance-none border border-solid border-gray-200 bg-slate-800/10 bg-none bg-contain bg-left bg-no-repeat align-top transition-all after:absolute after:top-px after:h-4 after:w-4 after:translate-x-px after:bg-white after:content-[''] checked:border-primary checked:bg-primary checked:bg-none checked:bg-right"
|
||||
type="checkbox" />
|
||||
<label for="darkMode"
|
||||
|
|
|
|||
20
src/ui/templates/plugins.html
vendored
20
src/ui/templates/plugins.html
vendored
|
|
@ -11,20 +11,12 @@
|
|||
] %}
|
||||
<div class="h-fit p-4 col-span-12 md:col-span-5 2xl:col-span-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="col-span-12 mb-4 font-bold dark:text-white/90">INFO</h5>
|
||||
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in plugins_info %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% for info in plugins_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -155,7 +147,7 @@
|
|||
</div>
|
||||
<!-- end filter -->
|
||||
<div data-plugins-list-container
|
||||
class="min-h-[55vh] max-h-80 overflow-hidden overflow-y-auto p-4 col-span-12 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
class="min-h-[55vh] max-h-80 overflow-auto p-4 col-span-12 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">LIST</h5>
|
||||
<div data-plugins-list class="grid grid-cols-12 gap-3">
|
||||
{% for plugin in plugins %}
|
||||
|
|
|
|||
58
src/ui/templates/reports.html
vendored
58
src/ui/templates/reports.html
vendored
|
|
@ -4,7 +4,15 @@
|
|||
{% set codes = ["all"] %}
|
||||
{% set reasons = ["all"] %}
|
||||
{% set countries = ["all"] %}
|
||||
{% set reasons_count = {} %}
|
||||
{% set codes_count = {} %}
|
||||
{% set countries_count = {} %}
|
||||
{% set methods_count = {} %}
|
||||
{% for report in reports %}
|
||||
{% if reasons_count.update({report["reason"]|string : reasons_count.get(report["reason"], 0) + 1}) %}{% endif %}
|
||||
{% if codes_count.update({report["status"]|string : codes_count.get(report["status"], 0) + 1}) %}{% endif %}
|
||||
{% if countries_count.update({report["country"]|string : codes_count.get(report["country"], 0) + 1}) %}{% endif %}
|
||||
{% if methods_count.update({report["method"]|string : methods_count.get(report["method"], 0) + 1}) %}{% endif %}
|
||||
{% if report["method"] not in methods %}
|
||||
{% if methods.append(report["method"]) %}{% endif %}
|
||||
{% endif %}
|
||||
|
|
@ -18,6 +26,31 @@
|
|||
{% if countries.append(report["country"]) %}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set top_reason = {"count": 0, "name": "unknown"} %}
|
||||
{% for key, value in reasons_count.items() %}
|
||||
{% if value|int > top_reason["count"]|int %}
|
||||
{% if top_reason.update({"count": value, "name" : key|string}) %}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set top_code = {"count": 0, "name": "unknown"} %}
|
||||
{% for key, value in codes_count.items() %}
|
||||
{% if value|int > top_code["count"]|int %}
|
||||
{% if top_code.update({ "count" : value|string, "name" : key}) %}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set top_country = {"count": 0, "name": "unknown"} %}
|
||||
{% for key, value in countries_count.items() %}
|
||||
{% if value|int > top_country["count"]|int %}
|
||||
{% if top_country.update({ "count" : value|string, "name" : key}) %}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set top_method = {"count": 0, "name": "unknown"} %}
|
||||
{% for key, value in methods_count.items() %}
|
||||
{% if value|int > top_method["count"]|int %}
|
||||
{% if top_method.update({ "count" : value|string, "name" : key}) %}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set total_report = reports|length %}
|
||||
<div class="{% if reports|length == 0 %}w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words {% else %}hidden{% endif %} ">
|
||||
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -34,25 +67,20 @@
|
|||
<!-- info-->
|
||||
{% if reports|length != 0 %}
|
||||
{% set reports_info = [
|
||||
{"name" : "REPORTING TOTAL", "data" : total_report|string},
|
||||
{"name" : "TOP REASON", "data" : total_reason|string},
|
||||
{"name" : "TOP STATUS CODE", "data" : top_code|string},
|
||||
{"name" : "REPORTING TOTAL", "data" : total_report|string or "0"},
|
||||
{"name" : "TOP METHOD", "data" : top_method['name']|string},
|
||||
{"name" : "TOP REASON", "data" : top_reason['name']|string},
|
||||
{"name" : "TOP COUNTRY", "data" : top_country['name']|string},
|
||||
{"name" : "TOP STATUS CODE", "data" : top_code['name']|string},
|
||||
] %}
|
||||
<div class=" h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in reports_info %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% for info in reports_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
15
src/ui/templates/services.html
vendored
15
src/ui/templates/services.html
vendored
|
|
@ -48,17 +48,10 @@
|
|||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in services_info %}
|
||||
<div role="row"
|
||||
class="card-detail-item">
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-title">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p role="gridcell"
|
||||
class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
124
src/ui/templates/services_modal.html
vendored
124
src/ui/templates/services_modal.html
vendored
|
|
@ -42,130 +42,10 @@
|
|||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div data-services-tabs-select-header class="flex flex-col">
|
||||
<div class="flex flex-col md:flex-row justify-start w-full items-start md:items-end gap-y-3 gap-x-4">
|
||||
<div class="w-full sm:min-w-[250px] max-w-[300px]">{% include "settings_tabs_select.html" %}</div>
|
||||
<div class="flex flex-col sm:flex-row">
|
||||
<!-- search inpt-->
|
||||
<div class="sm:mx-2 mb-1 min-w-[200px] flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="hidden sm:block my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
Search
|
||||
</h5>
|
||||
<label class="sr-only" for="settings-filter">search</label>
|
||||
<input type="text"
|
||||
id="settings-filter"
|
||||
name="settings-filter"
|
||||
class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="keyword"
|
||||
pattern="(.*?)"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
<!-- type plugin -->
|
||||
<div class="hidden mx-2 mb-1 min-w-[200px] sm:flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
Type
|
||||
</h5>
|
||||
<button aria-controls="filter-type" data-services-setting-select="type" class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value" id="services-type" data-name="services-type" data-services-setting-select-text="type">all</span>
|
||||
<!-- chevron -->
|
||||
<svg data-services-setting-select="type" class="transition-transform h-4 w-4 fill-gray-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-type" role="listbox" data-services-setting-select-dropdown="type" class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
|
||||
<button role="option" data-services-setting-select-dropdown-btn="type" value="all" class="dark:bg-primary bg-primary text-gray-300 border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
all
|
||||
</button>
|
||||
{% include "services_modal_settings_advanced.html" %}
|
||||
{% include "services_modal_delete.html" %}
|
||||
|
||||
<button role="option" data-services-setting-select-dropdown-btn="type" value="core" class=" bg-white dark:bg-slate-700 border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
core
|
||||
</button>
|
||||
|
||||
<button role="option" data-services-setting-select-dropdown-btn="type" value="external" class=" bg-white dark:bg-slate-700 border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
external
|
||||
</button>
|
||||
|
||||
<button role="option" data-services-setting-select-dropdown-btn="type" value="pro" class=" bg-white dark:bg-slate-700 rounded-b border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
pro
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end type plugin-->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
</div>
|
||||
<div data-services-nomatch
|
||||
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
|
||||
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="mb-2 w-8 h-8 dark:stroke-white/90 stroke-gray-800">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
|
||||
</svg>
|
||||
<h5 class="font-bold dark:text-white/90 mx-2 text-gray-800">No settings match</h5>
|
||||
</div>
|
||||
</div>
|
||||
<!-- new and edit form -->
|
||||
<form data-services-modal-form
|
||||
class="w-full h-[90vh] overflow-auto flex flex-col justify-between"
|
||||
id="form-new"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" id="operation" value="new" name="operation" />
|
||||
<input type="hidden" value="new" name="OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
{% include "settings_plugins.html" %}
|
||||
<!-- action button -->
|
||||
<div class="w-full flex-col items-center justify-center flex mt-10">
|
||||
<div class="flex justify-center">
|
||||
<button data-services-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-services-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
<p data-services-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
<!-- end new and edit form -->
|
||||
<!-- delete form-->
|
||||
<form data-services-modal-form-delete
|
||||
class="w-full h-full flex flex-col justify-between"
|
||||
id="form-delete-server_name"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" value="delete" name="operation" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
<input type="hidden" value="" name="SERVER_NAME" />
|
||||
<div class="flex justify-center">
|
||||
<p data-services-modal-text
|
||||
class="text-gray-700 dark:text-gray-300 mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm">
|
||||
</p>
|
||||
</div>
|
||||
<!-- action button -->
|
||||
<div class="w-full justify-center flex mt-10">
|
||||
<button data-services-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button type="submit" class="delete-btn mb-4 mr-3 text-base">Delete</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
</form>
|
||||
<!-- end delete form-->
|
||||
</div>
|
||||
</div>
|
||||
<!-- end modal -->
|
||||
|
|
|
|||
24
src/ui/templates/services_modal_delete.html
vendored
Normal file
24
src/ui/templates/services_modal_delete.html
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<!-- delete form-->
|
||||
<form data-services-modal-form-delete
|
||||
class="w-full h-full flex flex-col justify-between"
|
||||
id="form-delete-server_name"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" value="delete" name="operation" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
<input type="hidden" value="" name="SERVER_NAME" />
|
||||
<div class="flex justify-center">
|
||||
<p data-services-modal-text
|
||||
class="text-gray-700 dark:text-gray-300 mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm">
|
||||
</p>
|
||||
</div>
|
||||
<!-- action button -->
|
||||
<div class="w-full justify-center flex mt-10">
|
||||
<button data-services-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button type="submit" class="delete-btn mb-4 mr-3 text-base">Delete</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
</form>
|
||||
<!-- end delete form-->
|
||||
115
src/ui/templates/services_modal_settings_advanced.html
vendored
Normal file
115
src/ui/templates/services_modal_settings_advanced.html
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<div data-advanced data-services-tabs-select-header class="flex flex-col">
|
||||
<div class="flex flex-col md:flex-row justify-start w-full items-start md:items-end gap-y-3 gap-x-4">
|
||||
<div class="w-full sm:min-w-[250px] max-w-[300px]">{% include "settings_tabs_select.html" %}</div>
|
||||
<div class="flex flex-col sm:flex-row">
|
||||
<!-- search inpt-->
|
||||
<div class="sm:mx-2 mb-1 min-w-[200px] flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="hidden sm:block my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
Search
|
||||
</h5>
|
||||
<label class="sr-only" for="settings-filter">search</label>
|
||||
<input type="text"
|
||||
id="settings-filter"
|
||||
name="settings-filter"
|
||||
class="col-span-12 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="keyword"
|
||||
pattern="(.*?)"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
<!-- type plugin -->
|
||||
<div class="hidden mx-2 mb-1 min-w-[200px] sm:flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">Type</h5>
|
||||
<button aria-controls="filter-type"
|
||||
data-services-setting-select="type"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="services-type"
|
||||
data-name="services-type"
|
||||
data-services-setting-select-text="type">all</span>
|
||||
<!-- chevron -->
|
||||
<svg data-services-setting-select="type"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-type"
|
||||
role="listbox"
|
||||
data-services-setting-select-dropdown="type"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
<button role="option"
|
||||
data-services-setting-select-dropdown-btn="type"
|
||||
value="all"
|
||||
class="dark:bg-primary bg-primary text-gray-300 border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
all
|
||||
</button>
|
||||
<button role="option"
|
||||
data-services-setting-select-dropdown-btn="type"
|
||||
value="core"
|
||||
class=" bg-white dark:bg-slate-700 border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
core
|
||||
</button>
|
||||
<button role="option"
|
||||
data-services-setting-select-dropdown-btn="type"
|
||||
value="external"
|
||||
class=" bg-white dark:bg-slate-700 border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
external
|
||||
</button>
|
||||
<button role="option"
|
||||
data-services-setting-select-dropdown-btn="type"
|
||||
value="pro"
|
||||
class=" bg-white dark:bg-slate-700 rounded-b border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
pro
|
||||
</button>
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end type plugin-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
</div>
|
||||
<div data-advanced data-services-nomatch
|
||||
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
|
||||
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="mb-2 w-8 h-8 dark:stroke-white/90 stroke-gray-800">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
|
||||
</svg>
|
||||
<h5 class="font-bold dark:text-white/90 mx-2 text-gray-800">No settings match</h5>
|
||||
</div>
|
||||
</div>
|
||||
<!-- new and edit form -->
|
||||
<form data-advanced data-services-modal-form
|
||||
class="w-full h-[90vh] overflow-auto flex flex-col justify-between"
|
||||
id="form-new"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" id="operation" value="new" name="operation" />
|
||||
<input type="hidden" value="new" name="OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
{% include "settings_plugins.html" %}
|
||||
<!-- action button -->
|
||||
<div class="w-full flex-col items-center justify-center flex mt-10">
|
||||
<div class="flex justify-center">
|
||||
<button data-services-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-services-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
<p data-services-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
35
src/ui/templates/services_modal_settings_simple.html
vendored
Normal file
35
src/ui/templates/services_modal_settings_simple.html
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
<div data-simple class="flex flex-col">
|
||||
<div class="flex flex-col w-full items-end gap-y-3 gap-x-4">
|
||||
<h2 data-simple-step></h2>
|
||||
<p data-simple-description></p>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- new and edit form -->
|
||||
<form data-simple data-services-simple-modal-form
|
||||
class="w-full h-[90vh] overflow-auto flex flex-col justify-between"
|
||||
id="form-simple-new"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" id="simple_operation" value="new" name="simple_operation" />
|
||||
<input type="hidden" value="" name="simple_OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="simple_is_draft" />
|
||||
<input type="hidden" value="yes" name="simple_is_simple_mode" />
|
||||
|
||||
<!-- action button -->
|
||||
<div class="w-full flex-col items-center justify-center flex mt-10">
|
||||
<div class="flex justify-center">
|
||||
<button data-services-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-services-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
<p data-simple-services-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue