Merge branch 'dev' of github.com:bunkerity/bunkerweb into dev

This commit is contained in:
fl0ppy-d1sk 2023-10-03 13:05:40 +02:00
commit 0eb18cb31e
No known key found for this signature in database
GPG key ID: 93EE47CC3D061500
47 changed files with 284 additions and 232 deletions

View file

@ -3,7 +3,7 @@
exclude: (^LICENSE.md$|^src/VERSION$|^src/(bw/misc/root-ca.pem$|deps/src/|common/core/modsecurity/files|ui/static/js/(editor/|utils/purify/|tsparticles\.bundle\.min\.js))|\.(svg|drawio|patch\d?|ascii|tf|tftpl)$)
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: f71fa2c1f9cf5cb705f73dffe4b21f7c61470ba9 # frozen: v4.4.0
hooks:
- id: requirements-txt-fixer
- id: trailing-whitespace
@ -14,25 +14,41 @@ repos:
- id: check-case-conflict
- repo: https://github.com/ambv/black
rev: 23.9.1
rev: e87737140f32d3cd7c44ede75f02dcd58e55820e # frozen: 23.9.1
hooks:
- id: black
name: Black Python Formatter
language_version: python3.9
- repo: https://github.com/pre-commit/mirrors-prettier
rev: fc260393cc4ec09f8fc0a5ba4437f481c8b55dc1 # frozen: v3.0.3
hooks:
- id: prettier
name: Prettier Code Formatter
- repo: https://github.com/pycqa/flake8
rev: 6.1.0
rev: 10f4af6dbcf93456ba7df762278ae61ba3120dc6 # frozen: 6.1.0
hooks:
- id: flake8
name: Flake8 Python Linter
args: ["--max-line-length=250", "--ignore=E266,E402,E722,W503"]
- repo: https://github.com/codespell-project/codespell
rev: 6e41aba91fb32e9feb741a6258eefeb9c6e4a482 # frozen: v2.2.6
hooks:
- id: codespell
name: Codespell Spell Checker
exclude: (^src/(common/core/.+/files|bw/loading)/.+.html|modsecurity-rules.conf.*)$
entry: codespell --ignore-regex="(tabEl|Widgits)" --skip src/ui/static/js/utils/flatpickr.js,CHANGELOG.md
language: python
types: [text]
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
rev: b813e6fe08b87541cb77296359ba1b7a50a00c98 # frozen: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.9.0
rev: 3f77b826548d8dc2d26675f077361c92773b50a7 # frozen: v0.9.0
hooks:
- id: shellcheck

View file

@ -7,6 +7,7 @@ src/deps/src/
mkdocs.yml
CHANGELOG.md
CONTRIBUTING.md
CODE_OF_CONDUCT.md
LICENSE.md
README.md
SECURITY.md

View file

@ -335,10 +335,10 @@ Please contact us at [contact@bunkerity.com](mailto:contact@bunkerity.com) if yo
## Community
To get free community support you can use the following medias :
To get free community support you can use the following media :
* The #help channel of BunkerWeb in the [Discord server](https://discord.com/invite/fTf46FmtyD)
* The help category of [GitHub dicussions](https://github.com/bunkerity/bunkerweb/discussions)
* The help category of [GitHub discussions](https://github.com/bunkerity/bunkerweb/discussions)
* The [/r/BunkerWeb](https://www.reddit.com/r/BunkerWeb) subreddit
* The [Server Fault](https://serverfault.com/) and [Super User](https://superuser.com/) forums

View file

@ -17,10 +17,10 @@ Please contact us at [contact@bunkerity.com](mailto:contact@bunkerity.com) if yo
## Where to get community support ?
To get free community support, you can use the following medias :
To get free community support, you can use the following media :
- The #help channel of BunkerWeb in the [Discord server](https://discord.com/invite/fTf46FmtyD)
- The help category of [GitHub dicussions](https://github.com/bunkerity/bunkerweb/discussions)
- The help category of [GitHub discussions](https://github.com/bunkerity/bunkerweb/discussions)
- The [/r/BunkerWeb](https://www.reddit.com/r/BunkerWeb) subreddit
- The [Server Fault](https://serverfault.com/) and [Super User](https://superuser.com/) forums

View file

@ -1,7 +1,7 @@
# Concepts
<figure markdown>
![Overwiew](assets/img/concepts.svg){ align=center, width="600" }
![Overview](assets/img/concepts.svg){ align=center, width="600" }
</figure>
## Integrations

View file

@ -106,7 +106,7 @@ The first step is to install the plugin by putting the plugin files inside the c
When using the [Swarm integration](integrations.md#swarm), plugins must be written to the volume mounted on `/data/plugins` into the scheduler container.
!!! info "Swarm volume"
Configuring a Swarm volume that will persist when the scheduler service is running on different nodes is not covered is in this documentation. We will assume that you have a shared folder mounted on `/shared` accross all nodes.
Configuring a Swarm volume that will persist when the scheduler service is running on different nodes is not covered is in this documentation. We will assume that you have a shared folder mounted on `/shared` across all nodes.
The first thing to do is to create the plugins folder :
@ -460,7 +460,7 @@ Some helpers modules provide common helpful helpers :
- `self.logger` : print logs
- `bunkerweb.utils` : various useful functions
- `bunkerweb.datastore` : access the global shared data on one instance (key/value store)
- `bunkerweb.clusterstore` : access a Redis data store shared beetween BunkerWeb instances (key/value store)
- `bunkerweb.clusterstore` : access a Redis data store shared between BunkerWeb instances (key/value store)
To access the functions, you first need to **require** the modules :

View file

@ -2322,7 +2322,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
!!! warning "Feature is in beta"
This feature is not production-ready. Feel free to test it and report us any bug using [issues](https://github.com/bunkerity/bunkerweb/issues) in the GitHub repository.
By default, BunkerWeb will only listen on IPv4 adresses and won't use IPv6 for network communications. If you want to enable IPv6 support, you need to set `USE_IPV6=yes`. Please note that IPv6 configuration of your network and environment is out-of-the-scope of this documentation.
By default, BunkerWeb will only listen on IPv4 addresses and won't use IPv6 for network communications. If you want to enable IPv6 support, you need to set `USE_IPV6=yes`. Please note that IPv6 configuration of your network and environment is out-of-the-scope of this documentation.
=== "Docker"

View file

@ -284,4 +284,4 @@ If you have bots that need to access your website, the recommended way to avoid
## Timezone
When using container-based integrations, the timezone of the container may not match the one of the host machine. To resolve that, you can set the `TZ` environment variable to the timezone of your choice on your containers (e.g. `TZ=Europe/Paris`). You will find the list of timezone identifers [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List).
When using container-based integrations, the timezone of the container may not match the one of the host machine. To resolve that, you can set the `TZ` environment variable to the timezone of your choice on your containers (e.g. `TZ=Europe/Paris`). You will find the list of timezone identifiers [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List).

View file

@ -18,7 +18,7 @@ services:
REVERSE_PROXY_URL: "/"
REVERSE_PROXY_HOST: "http://mydrupal"
CUSTOM_CONF_MODSEC_CRS_drupal: 'SecAction "id:900130,phase:1,nolog,pass,t:none,setvar:tx.crs_exclusions_drupal=1"'
# Onces the installation is done, you can remove these lines
# Once the installation is done, you can remove these lines
LIMIT_REQ_URL_1: "/core/install.php"
LIMIT_REQ_RATE_1: "5r/s"
labels:
@ -75,6 +75,7 @@ volumes:
bw-data:
db-data:
networks:
bw-universe:
ipam:

View file

@ -18,7 +18,7 @@ services:
USE_REVERSE_PROXY: "yes"
REVERSE_PROXY_URL: "/"
REVERSE_PROXY_HOST: "http://myps"
# Onces the installation is done, you can remove these lines
# Once the installation is done, you can remove these lines
LIMIT_REQ_URL_1: "/install/index.php"
LIMIT_REQ_RATE_1: "8r/s"
labels:
@ -85,6 +85,7 @@ volumes:
ps-data:
db-data:
networks:
bw-universe:
ipam:

View file

@ -231,7 +231,7 @@ class IngressController(Controller):
locked = False
continue
self._logger.info(
f"Catched kubernetes event ({watch_type}), deploying new configuration ...",
f"Caught kubernetes event ({watch_type}), deploying new configuration ...",
)
try:
ret = self.apply_config()

View file

@ -130,7 +130,7 @@ class SwarmController(Controller):
self.__internal_lock.release()
locked = False
continue
self._logger.info(f"Catched Swarm event ({event_type}), deploying new configuration ...")
self._logger.info(f"Caught Swarm event ({event_type}), deploying new configuration ...")
if not self.apply_config():
self._logger.error("Error while deploying new configuration")
else:

View file

@ -16,7 +16,7 @@ log "ENTRYPOINT" "" "Starting BunkerWeb v$(cat /usr/share/bunkerweb/VERSIO
# trap SIGTERM and SIGINT
function trap_exit() {
# shellcheck disable=SC2317
log "ENTRYPOINT" "" "Catched stop operation, stopping nginx ..."
log "ENTRYPOINT" "" "Caught stop operation, stopping nginx ..."
# shellcheck disable=SC2317
nginx -s stop
}
@ -25,7 +25,7 @@ trap "trap_exit" TERM INT QUIT
# trap SIGHUP
function trap_reload() {
# shellcheck disable=SC2317
log "ENTRYPOINT" "" "Catched reload operation"
log "ENTRYPOINT" "" "Caught reload operation"
# shellcheck disable=SC2317
if [ -f /var/run/bunkerweb/nginx.pid ] ; then
# shellcheck disable=SC2317

File diff suppressed because one or more lines are too long

View file

@ -20,7 +20,7 @@ function plugin:initialize(id, ctx)
end
end
self.is_request = multisite
-- Store common objets
-- Store common objects
self.logger = logger:new(self.id)
local use_redis, err = utils.get_variable("USE_REDIS", false)
if not use_redis then

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -127,7 +127,7 @@ try:
blacklist_path.joinpath(f"{kind}.list").unlink(missing_ok=True)
deleted, err = del_file_in_db(f"{kind}.list", db)
if not deleted:
logger.warning(f"Coudn't delete {kind}.list from cache : {err}")
logger.warning(f"Couldn't delete {kind}.list from cache : {err}")
if all_fresh:
_exit(0)

View file

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -111,7 +111,7 @@ try:
greylist_path.joinpath(f"{kind}.list").unlink(missing_ok=True)
deleted, err = del_file_in_db(f"{kind}.list", db)
if not deleted:
logger.warning(f"Coudn't delete {kind}.list from cache : {err}")
logger.warning(f"Couldn't delete {kind}.list from cache : {err}")
if all_fresh:
_exit(0)

View file

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -81,7 +81,7 @@ try:
tmp_realip_path.joinpath("combined.list").unlink(missing_ok=True)
deleted, err = del_file_in_db("combined.list", db)
if not deleted:
logger.warning(f"Coudn't delete combined.list from cache : {err}")
logger.warning(f"Couldn't delete combined.list from cache : {err}")
logger.info("RealIP list is already in cache, skipping download...")
_exit(0)

View file

@ -111,7 +111,7 @@ try:
whitelist_path.joinpath(f"{kind}.list").unlink(missing_ok=True)
deleted, err = del_file_in_db(f"{kind}.list", db)
if not deleted:
logger.warning(f"Coudn't delete {kind}.list from cache : {err}")
logger.warning(f"Couldn't delete {kind}.list from cache : {err}")
if all_fresh:
_exit(0)

View file

@ -77,8 +77,8 @@ class Database:
with suppress(FileExistsError):
Path(dirname(sqlalchemy_string.split("///")[1])).mkdir(parents=True, exist_ok=True)
elif "+" in sqlalchemy_string and "+pymysql" not in sqlalchemy_string:
splitted = sqlalchemy_string.split("+")
sqlalchemy_string = f"{splitted[0]}:{':'.join(splitted[1].split(':')[1:])}"
split = sqlalchemy_string.split("+")
sqlalchemy_string = f"{split[0]}:{':'.join(split[1].split(':')[1:])}"
self.database_uri = sqlalchemy_string
error = False

View file

@ -162,8 +162,8 @@ class Configurator:
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
splitted = line.split("=", 1)
variables[splitted[0]] = splitted[1]
split = line.split("=", 1)
variables[split[0]] = split[1]
return variables
def get_config(self) -> Dict[str, Any]:

View file

@ -32,12 +32,12 @@ def get_instance_configs_and_apis(instance: Any, db, _type="Docker"):
apis = []
for var in instance.attrs["Config"]["Env"] if _type == "Docker" else instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]:
splitted = var.split("=", 1)
if custom_confs_rx.match(splitted[0]):
custom_conf = custom_confs_rx.search(splitted[0]).groups()
split = var.split("=", 1)
if custom_confs_rx.match(split[0]):
custom_conf = custom_confs_rx.search(split[0]).groups()
custom_confs.append(
{
"value": f"# CREATED BY ENV\n{splitted[1]}",
"value": f"# CREATED BY ENV\n{split[1]}",
"exploded": (
custom_conf[0],
custom_conf[1],
@ -47,14 +47,14 @@ def get_instance_configs_and_apis(instance: Any, db, _type="Docker"):
)
logger.info(f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}")
else:
tmp_config[splitted[0]] = splitted[1]
tmp_config[split[0]] = split[1]
if not db and splitted[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=splitted[1], pool=False)
elif splitted[0] == "API_HTTP_PORT":
api_http_port = splitted[1]
elif splitted[0] == "API_SERVER_NAME":
api_server_name = splitted[1]
if not db and split[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=split[1], pool=False)
elif split[0] == "API_HTTP_PORT":
api_http_port = split[1]
elif split[0] == "API_SERVER_NAME":
api_server_name = split[1]
apis.append(
API(
@ -222,12 +222,12 @@ if __name__ == "__main__":
for instance in docker_client.containers.list(filters={"label": "bunkerweb.INSTANCE"}):
for var in instance.attrs["Config"]["Env"]:
splitted = var.split("=", 1)
if custom_confs_rx.match(splitted[0]):
custom_conf = custom_confs_rx.search(splitted[0]).groups()
split = var.split("=", 1)
if custom_confs_rx.match(split[0]):
custom_conf = custom_confs_rx.search(split[0]).groups()
custom_confs.append(
{
"value": f"# CREATED BY ENV\n{splitted[1]}",
"value": f"# CREATED BY ENV\n{split[1]}",
"exploded": (
custom_conf[0],
custom_conf[1],
@ -237,14 +237,14 @@ if __name__ == "__main__":
)
logger.info(f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}")
else:
tmp_config[splitted[0]] = splitted[1]
tmp_config[split[0]] = split[1]
if not db and splitted[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=splitted[1], pool=False)
elif splitted[0] == "API_HTTP_PORT":
api_http_port = splitted[1]
elif splitted[0] == "API_SERVER_NAME":
api_server_name = splitted[1]
if not db and split[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=split[1], pool=False)
elif split[0] == "API_HTTP_PORT":
api_http_port = split[1]
elif split[0] == "API_SERVER_NAME":
api_server_name = split[1]
apis.append(
API(

View file

@ -226,7 +226,7 @@ function reload()
log "SYSTEMCTL" "" "BunkerWeb service reloaded ..."
}
# List of differents args
# List of different args
case $1 in
"start")
start

View file

@ -6,7 +6,7 @@
# trap SIGTERM and SIGINT
function trap_exit() {
# shellcheck disable=SC2317
log "ENTRYPOINT" " " "Catched stop operation"
log "ENTRYPOINT" " " "Caught stop operation"
# shellcheck disable=SC2317
if [ -f "/var/run/bunkerweb/scheduler.pid" ] ; then
# shellcheck disable=SC2317

View file

@ -93,7 +93,7 @@ def stop(status, _stop=True):
def handle_stop(signum, frame):
app.logger.info("Catched stop operation")
app.logger.info("Caught stop operation")
app.logger.info("Stopping web ui ...")
stop(0, False)
@ -1330,13 +1330,13 @@ def logs_container(container_id):
)
for log in tmp_logs:
splitted = log.split(" ")
timestamp = splitted[0]
split = log.split(" ")
timestamp = split[0]
if to_date is not None and dateutil_parse(timestamp).timestamp() > to_date:
break
log = " ".join(splitted[1:])
log = " ".join(split[1:])
log_lower = log.lower()
if "[48;2" in log or not log.strip():

View file

@ -72,7 +72,7 @@ class News {
excerpt,
tags,
date,
lastUpdate
lastUpdate,
);
let cleanHTML = DOMPurify.sanitize(cardHTML);
//add to DOM
@ -191,7 +191,7 @@ class darkMode {
};
const send = await fetch(
`${location.href.split("/").slice(0, -1).join("/")}/darkmode`,
data
data,
);
}
}
@ -231,7 +231,7 @@ class FlashMsg {
flashEl.remove();
//update count
this.flashCount.textContent = document.querySelectorAll(
"[data-flash-message]"
"[data-flash-message]",
).length;
}
} catch (err) {}
@ -300,7 +300,7 @@ const setMenu = new Menu();
const setNewsSidebar = new Sidebar(
"[data-sidebar-info]",
"[data-sidebar-info-open]",
"[data-sidebar-info-close]"
"[data-sidebar-info-close]",
);
const setCheckbox = new Checkbox();
@ -311,7 +311,7 @@ const setDisabledPop = new DisabledPop();
const setFlashSidebar = new Sidebar(
"[data-flash-sidebar]",
"[data-flash-sidebar-open]",
"[data-flash-sidebar-close]"
"[data-flash-sidebar-close]",
);
const setNews = new News();
const setDarkM = new darkMode();

View file

@ -133,15 +133,15 @@ class Dropdown {
}
toggleSelectBtn(e) {
const attribut = e.target
const attribute = e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`,
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
);
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${attribut}"]`,
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");

View file

@ -130,15 +130,15 @@ class Dropdown {
}
toggleSelectBtn(e) {
const attribut = e.target
const attribute = e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`,
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
);
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${attribut}"]`,
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");

View file

@ -36,7 +36,7 @@ class Dropdown {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`data-${this.prefix}-setting-select-dropdown-btn`
`data-${this.prefix}-setting-select-dropdown-btn`,
);
//stop if same value to avoid new fetching
const isSameVal = this.isSameValue(btnSetting, btnValue);
@ -57,7 +57,7 @@ class Dropdown {
closeAllDrop() {
const drops = document.querySelectorAll(
`[data-${this.prefix}-setting-select-dropdown]`
`[data-${this.prefix}-setting-select-dropdown]`,
);
drops.forEach((drop) => {
drop.classList.add("hidden");
@ -65,8 +65,8 @@ class Dropdown {
document
.querySelector(
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
`data-${this.prefix}-setting-select-dropdown`
)}"]`
`data-${this.prefix}-setting-select-dropdown`,
)}"]`,
)
.classList.remove("rotate-180");
});
@ -74,7 +74,7 @@ class Dropdown {
isSameValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`,
);
const currVal = selectCustom.textContent;
return currVal === value ? true : false;
@ -82,30 +82,30 @@ class Dropdown {
setSelectNewValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[data-${this.prefix}-setting-select="${btnSetting}"]`
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
);
selectCustom.querySelector(
`[data-${this.prefix}-setting-select-text]`
`[data-${this.prefix}-setting-select-text]`,
).textContent = value;
}
hideDropdown(btnSetting) {
//hide dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
//svg effect
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
);
dropdownChevron.classList.remove("rotate-180");
}
changeDropBtnStyle(btnSetting, selectedBtn) {
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
);
//reset dropdown btns
const btnEls = dropdownEl.querySelectorAll("button");
@ -116,7 +116,7 @@ class Dropdown {
"bg-primary",
"bg-primary",
"text-gray-300",
"text-gray-300"
"text-gray-300",
);
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
});
@ -124,21 +124,21 @@ class Dropdown {
selectedBtn.classList.remove(
"bg-white",
"dark:bg-slate-700",
"text-gray-700"
"text-gray-700",
);
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
}
toggleSelectBtn(e) {
const attribut = e.target
const attribute = e.target
.closest("button")
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
);
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${attribut}"]`
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
@ -300,7 +300,7 @@ class Upload {
this.dropZoneElement.classList.remove(
"border-solid",
"bg-gray-100",
"dark:bg-slate-700/50"
"dark:bg-slate-700/50",
);
this.dropZoneElement.classList.add("border-dashed");
}
@ -309,7 +309,7 @@ class Upload {
this.dropZoneElement.classList.add(
"border-solid",
"bg-gray-100",
"dark:bg-slate-700/50"
"dark:bg-slate-700/50",
);
this.dropZoneElement.classList.remove("border-dashed");
}
@ -346,13 +346,13 @@ class Upload {
if (xhr.status == 201) {
this.uploadedArea.insertAdjacentHTML(
"afterbegin",
this.fileSuccess(name, fileSize)
this.fileSuccess(name, fileSize),
);
this.allowReload();
} else {
this.uploadedArea.insertAdjacentHTML(
"afterbegin",
this.fileFail(name, fileSize)
this.fileFail(name, fileSize),
);
}
}
@ -451,10 +451,10 @@ class Modal {
this.modalExtInp = this.modal.querySelector("input#external");
this.modalTitle = this.modal.querySelector(
`[data-${this.prefix}-modal-title]`
`[data-${this.prefix}-modal-title]`,
);
this.modalTxt = this.modal.querySelector(
`[data-${this.prefix}-modal-text]`
`[data-${this.prefix}-modal-text]`,
);
this.init();
}

View file

@ -449,7 +449,7 @@ class Multiple {
);
//clone schema to create a group with new num
const schemaClone = schema.cloneNode(true);
//add special attribut for disabled logic
//add special attribute for disabled logic
this.changeCloneSuffix(schemaClone, setNum);
//set disabled / enabled state
this.setDisabledMultNew(schemaClone);
@ -730,7 +730,7 @@ class Multiple {
const select = settingContainer.querySelector("select");
select.setAttribute("data-method", method);
//click the custom select dropdown btn vavlue to update select value
//click the custom select dropdown btn value to update select value
select.parentElement
.querySelector(
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`,

View file

@ -52,18 +52,18 @@ class Select {
try {
if (!e.target.closest("button")) {
const selectEls = document.querySelectorAll(
"div[data-setting-select-dropdown]"
"div[data-setting-select-dropdown]",
);
selectEls.forEach((select) => {
select.classList.add("hidden");
select.classList.remove("flex");
});
const btnEls = document.querySelectorAll(
"button[data-setting-select]"
"button[data-setting-select]",
);
btnEls.forEach((btn) => {
const dropdownChevron = btn.querySelector(
`svg[data-setting-select]`
`svg[data-setting-select]`,
);
dropdownChevron.classList.remove("rotate-180");
});
@ -87,7 +87,7 @@ class Select {
.hasAttribute(`data-setting-select-dropdown-btn`)
) {
const btn = e.target.closest(
`button[data-setting-select-dropdown-btn]`
`button[data-setting-select-dropdown-btn]`,
);
const btnValue = btn.getAttribute("value");
@ -116,7 +116,7 @@ class Select {
//close dropdown
const dropdownChevron = selectCustom.querySelector(
`svg[data-setting-select]`
`svg[data-setting-select]`,
);
dropdownChevron.classList.remove("rotate-180");
@ -139,7 +139,7 @@ class Select {
});
//select new one
const newOption = selectEl.querySelector(
`option[value="${selectedValue}"]`
`option[value="${selectedValue}"]`,
);
newOption.selected = true;
newOption.setAttribute("selected", "");

View file

@ -80,7 +80,6 @@ services:
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe

View file

@ -114,7 +114,7 @@ do
export CLIENT_CACHE_ETAG="no"
fi
elif [ "$test" = "cache_control" ] ; then
echo "📝 Running tests whith clientcache control set to public, max-age=3600 ..."
echo "📝 Running tests with clientcache control set to public, max-age=3600 ..."
if [ "$integration" == "docker" ] ; then
find . -type f -name 'docker-compose.*' -exec sed -i 's@CLIENT_CACHE_ETAG: "no"@CLIENT_CACHE_ETAG: "yes"@' {} \;
find . -type f -name 'docker-compose.*' -exec sed -i 's@CLIENT_CACHE_CONTROL: "public, max-age=15552000"@CLIENT_CACHE_CONTROL: "public, max-age=3600"@' {} \;

View file

@ -70,7 +70,6 @@ services:
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe

View file

@ -74,11 +74,11 @@ try:
response.raise_for_status()
if custom_headers:
splitted = custom_headers.split(":")
split = custom_headers.split(":")
if response.headers.get(splitted[0].strip()) != splitted[1].strip():
if response.headers.get(split[0].strip()) != split[1].strip():
print(
f"❌ Header {splitted[0].strip()} is not set to {splitted[1].strip()}, exiting ...\nheaders: {response.headers}",
f"❌ Header {split[0].strip()} is not set to {split[1].strip()}, exiting ...\nheaders: {response.headers}",
flush=True,
)
exit(1)

View file

@ -214,7 +214,7 @@ do
unset X_XSS_PROTECTION
fi
elif [ "$test" = "multiple_no_httponly_flag" ] ; then
echo "🎛️ Running tests with HttpOnly flag overriden for cookie \"bw_cookie\" and default cookies flags ..."
echo "🎛️ Running tests with HttpOnly flag overridden for cookie \"bw_cookie\" and default cookies flags ..."
if [ "$integration" == "docker" ] ; then
find . -type f -name 'docker-compose.*' -exec sed -i 's@COOKIE_FLAGS: ".*"$@COOKIE_FLAGS: "* HttpOnly SameSite=Lax"@' {} \;
sed -i '27i \ COOKIE_FLAGS_1: "bw_cookie SameSite=Lax"' docker-compose.yml

View file

@ -176,7 +176,7 @@ do
export REDIS_DATABASE="1"
export REDIS_SSL="yes"
echo "🧰 Stoping redis ..."
echo "🧰 Stopping redis ..."
sudo killall redis-server
# shellcheck disable=SC2181
if [ $? -ne 0 ] ; then

View file

@ -71,7 +71,6 @@ services:
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe

View file

@ -93,7 +93,6 @@ services:
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe

View file

@ -80,7 +80,6 @@ services:
volumes:
bw-data:
networks:
bw-universe:
name: bw-universe