mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
precommit + update services mode and filters
* remove simple mode for current version * fix input filtering and services modal
This commit is contained in:
parent
2df047a18c
commit
b1945e1be0
11 changed files with 459 additions and 1330 deletions
|
|
@ -1,129 +1,129 @@
|
|||
{
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with high security level required for your web service. False positives will certainly appear without any custom edit.",
|
||||
"steps": [
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with high security level required for your web service. False positives will certainly appear without any custom edit.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''",
|
||||
"SERVE_FILES": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable and configure HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes",
|
||||
"SSL_PROTOCOLS": "TLSv1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"DENY_HTTP_STATUS": "444",
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "5",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "captcha",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "yes",
|
||||
"CORS_ALLOW_ORIGIN": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Reverse scan",
|
||||
"description": "Configure reverse scan of client to detect open proxy or datacenter connections.",
|
||||
"settings": {
|
||||
"USE_REVERSE_SCAN": "yes",
|
||||
"REVERSE_SCAN_PORTS": "22 80 443 3128 8000 8080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes",
|
||||
"MODSECURITY_CRS_VERSION": "4"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''",
|
||||
"SERVE_FILES": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable and configure HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes",
|
||||
"SSL_PROTOCOLS": "TLSv1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"DENY_HTTP_STATUS": "444",
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "5",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "captcha",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "yes",
|
||||
"CORS_ALLOW_ORIGIN": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Reverse scan",
|
||||
"description": "Configure reverse scan of client to detect open proxy or datacenter connections.",
|
||||
"settings": {
|
||||
"USE_REVERSE_SCAN": "yes",
|
||||
"REVERSE_SCAN_PORTS": "22 80 443 3128 8000 8080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes",
|
||||
"MODSECURITY_CRS_VERSION": "4"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "template-high",
|
||||
"type": "modsec-crs",
|
||||
"data": "SecAction \"id:900000,phase:1,pass,t:none,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',setvar:tx.blocking_paranoia_level=4\""
|
||||
}
|
||||
]
|
||||
"name": "template-high",
|
||||
"type": "modsec-crs",
|
||||
"data": "SecAction \"id:900000,phase:1,pass,t:none,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',setvar:tx.blocking_paranoia_level=4\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +1,111 @@
|
|||
{
|
||||
"name": "low",
|
||||
"description": "Generic settings template with low security level to avoid false positives and get started with BunkerWeb.",
|
||||
"steps": [
|
||||
"name": "low",
|
||||
"description": "Generic settings template with low security level to avoid false positives and get started with BunkerWeb.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "no",
|
||||
"REVERSE_PROXY_WS": "yes",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD|PUT|PATCH|OPTIONS|DELETE",
|
||||
"MAX_SIZES": "50m",
|
||||
"COOKIE_FLAGS": "* SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "",
|
||||
"X_FRAME_OPTIONS": "",
|
||||
"PERMISSIONS_POLICY": "",
|
||||
"FEATURE_POLICY": "",
|
||||
"KEEP_UPSTREAM_HEADERS": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "3600",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "20",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": 20,
|
||||
"LIMIT_CONN_MAX_HTTP2": 200,
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "5r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "no",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "no",
|
||||
"REVERSE_PROXY_WS": "yes",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD|PUT|PATCH|OPTIONS|DELETE",
|
||||
"MAX_SIZES": "50m",
|
||||
"COOKIE_FLAGS": "* SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "",
|
||||
"X_FRAME_OPTIONS": "",
|
||||
"PERMISSIONS_POLICY": "",
|
||||
"FEATURE_POLICY": "",
|
||||
"KEEP_UPSTREAM_HEADERS": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "3600",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "20",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": 20,
|
||||
"LIMIT_CONN_MAX_HTTP2": 200,
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "5r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "no",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "template-low",
|
||||
"type": "modsec-crs",
|
||||
"description": "Override ModSecurity CRS settings.",
|
||||
"data": "SecAction \"id:900110,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=7,setvar:tx.outbound_anomaly_score_threshold=4\""
|
||||
}
|
||||
]
|
||||
"name": "template-low",
|
||||
"type": "modsec-crs",
|
||||
"description": "Override ModSecurity CRS settings.",
|
||||
"data": "SecAction \"id:900110,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=7,setvar:tx.outbound_anomaly_score_threshold=4\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,110 +1,110 @@
|
|||
{
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with medium security level aimed for average web service in production. False positives may appear depending on your environment.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "10",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "javascript",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "no",
|
||||
"CORS_ALLOW_ORIGIN": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with medium security level aimed for average web service in production. False positives may appear depending on your environment.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "10",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "javascript",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "no",
|
||||
"CORS_ALLOW_ORIGIN": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ try:
|
|||
SEND_FILE_MAX_AGE_DEFAULT=86400,
|
||||
SCRIPT_NONCE=sha256(urandom(32)).hexdigest(),
|
||||
DB=db,
|
||||
UI_TEMPLATES=get_ui_templates()
|
||||
UI_TEMPLATES=get_ui_templates(),
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
app.logger.error(repr(e), e.filename)
|
||||
|
|
@ -173,6 +173,7 @@ csrf.init_app(app)
|
|||
LOG_RX = re_compile(r"^(?P<date>\d+/\d+/\d+\s\d+:\d+:\d+)\s\[(?P<level>[a-z]+)\]\s\d+#\d+:\s(?P<message>[^\n]+)$")
|
||||
REVERSE_PROXY_PATH = re_compile(r"^(?P<host>https?://.{1,255}(:((6553[0-5])|(655[0-2]\d)|(65[0-4]\d{2})|(6[0-4]\d{3})|([1-5]\d{4})|([0-5]{0,5})|(\d{1,4})))?)$")
|
||||
|
||||
|
||||
def get_ui_data():
|
||||
ui_data = "Error"
|
||||
while ui_data == "Error":
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from glob import glob
|
|||
from os import sep
|
||||
from os.path import join
|
||||
|
||||
|
||||
def get_ui_templates():
|
||||
ui_templates = []
|
||||
for template_file in glob(join(sep, "usr", "share", "bunkerweb", "templates", "*.json")):
|
||||
|
|
@ -10,10 +11,7 @@ def get_ui_templates():
|
|||
ui_template = {}
|
||||
with open(template_file, "r") as f:
|
||||
bw_template = loads(f.read())
|
||||
ui_template = {
|
||||
"name": bw_template["name"],
|
||||
"description": bw_template["description"]
|
||||
}
|
||||
ui_template = {"name": bw_template["name"], "description": bw_template["description"]}
|
||||
ui_template["steps"] = []
|
||||
for bw_step in bw_template["steps"]:
|
||||
ui_step = {}
|
||||
|
|
@ -21,10 +19,7 @@ def get_ui_templates():
|
|||
ui_step["description"] = bw_step["description"]
|
||||
ui_step["settings"] = []
|
||||
for setting, value in bw_step["settings"].items():
|
||||
ui_setting = {
|
||||
"setting_id": setting,
|
||||
"value": value
|
||||
}
|
||||
ui_setting = {"setting_id": setting, "value": value}
|
||||
ui_step["settings"].append(ui_setting)
|
||||
ui_template["steps"].append(ui_step)
|
||||
ui_templates.append(ui_template)
|
||||
|
|
@ -33,4 +28,4 @@ def get_ui_templates():
|
|||
# TODO: log
|
||||
pass
|
||||
# print(ui_templates, flush=True)
|
||||
return ui_templates
|
||||
return ui_templates
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import {
|
|||
CheckNoMatchFilter,
|
||||
showInvalid,
|
||||
SettingsAdvanced,
|
||||
SettingsSimple,
|
||||
SettingsSwitch,
|
||||
} from "./utils/settings.js";
|
||||
|
||||
class SettingsService {
|
||||
|
|
@ -24,12 +22,6 @@ class SettingsService {
|
|||
this.settingsMultiple,
|
||||
"services",
|
||||
);
|
||||
this.simpleSettings = new SettingsSimple(
|
||||
document.querySelector("[data-simple][data-services-modal-form]"),
|
||||
this.settingsMultiple,
|
||||
"services",
|
||||
);
|
||||
|
||||
this.initSettingsService();
|
||||
}
|
||||
|
||||
|
|
@ -117,133 +109,6 @@ class SettingsService {
|
|||
forceEnabled,
|
||||
emptyServerName,
|
||||
);
|
||||
|
||||
// Click on right security level dropdown btn
|
||||
// This will fire security level event listener
|
||||
this.simpleSettings.updateData(
|
||||
action,
|
||||
oldServName,
|
||||
operation,
|
||||
settings,
|
||||
forceEnabled,
|
||||
setMethodUI,
|
||||
emptyServerName,
|
||||
);
|
||||
const modeBtn = document.querySelector(
|
||||
"button[data-toggle-settings-mode-btn]",
|
||||
);
|
||||
const mode = modeBtn.getAttribute("data-toggle-settings-mode-btn");
|
||||
if (action === "new") {
|
||||
mode !== "simple" ? modeBtn.click() : null;
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="standard"]`,
|
||||
)
|
||||
.click();
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="custom"]`,
|
||||
)
|
||||
.setAttribute("disabled", "true");
|
||||
} else {
|
||||
mode !== "advanced" ? modeBtn.click() : null;
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="custom"]`,
|
||||
)
|
||||
.removeAttribute("disabled");
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="custom"]`,
|
||||
)
|
||||
.click();
|
||||
}
|
||||
}
|
||||
} catch (err) {}
|
||||
// security level
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute("data-setting-select-dropdown-btn") ==
|
||||
"security-level"
|
||||
) {
|
||||
// get current common values
|
||||
const action = this.simpleSettings.currAction;
|
||||
const oldServName = this.simpleSettings.oldServName;
|
||||
const operation = this.simpleSettings.operation;
|
||||
const forceEnabled = this.simpleSettings.forceEnabled;
|
||||
const setMethodUI = this.simpleSettings.setMethodUI;
|
||||
const emptyServerName = this.simpleSettings.emptyServerName;
|
||||
// get custom security level settings of service if custom choose
|
||||
const value = e.target.closest("button").getAttribute("value");
|
||||
|
||||
// mainSettings is the settings of the service
|
||||
let mainSettings;
|
||||
|
||||
// Try to get settings in a valid format
|
||||
try {
|
||||
mainSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`[data-old-name][data-value="${oldServName}"]`)
|
||||
.closest("[data-services-service]")
|
||||
.getAttribute("data-settings"),
|
||||
);
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
if (!settings) {
|
||||
mainSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`[data-old-name][data-value="${oldServName}"]`)
|
||||
.closest("[data-services-service]")
|
||||
.getAttribute("data-settings")
|
||||
.replaceAll(`'`, `"`),
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
// In case we want a security level, we need to get the settings of the security level
|
||||
// In order to filter and merge both to avoid overriding disabled settings (method != ui|default)
|
||||
let compareSettings = null;
|
||||
if (value !== "custom") {
|
||||
// Try to get settings in a valid format
|
||||
try {
|
||||
compareSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`input#security-level-${value}`)
|
||||
.getAttribute("data-settings"),
|
||||
);
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
if (!compareSettings) {
|
||||
compareSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`input#security-level-${value}`)
|
||||
.getAttribute("data-settings")
|
||||
.replaceAll(`'`, `"`),
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
}
|
||||
// No main settings if new
|
||||
if (action === "new") {
|
||||
mainSettings = JSON.parse(JSON.stringify(compareSettings));
|
||||
compareSettings = null;
|
||||
}
|
||||
|
||||
this.simpleSettings.setSimple(
|
||||
action,
|
||||
oldServName,
|
||||
operation,
|
||||
mainSettings,
|
||||
compareSettings,
|
||||
setMethodUI,
|
||||
forceEnabled,
|
||||
emptyServerName,
|
||||
true,
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
|
|
@ -260,9 +125,6 @@ class ServiceModal {
|
|||
"[data-services-tabs-select-header]",
|
||||
]);
|
||||
this.modalCard = this.modal.querySelector("[data-services-modal-card]");
|
||||
this.switchModeBtn = this.modal.querySelector(
|
||||
"[data-toggle-settings-mode-btn]",
|
||||
);
|
||||
//modal forms
|
||||
this.formNewEdit = this.modal.querySelector(
|
||||
"[data-advanced][data-services-modal-form]",
|
||||
|
|
@ -270,9 +132,7 @@ class ServiceModal {
|
|||
this.formDelete = this.modal.querySelector(
|
||||
"[data-services-modal-form-delete]",
|
||||
);
|
||||
this.simpleForm = this.modal.querySelector(
|
||||
"[data-simple][data-services-modal-form]",
|
||||
);
|
||||
|
||||
//container
|
||||
this.container = document.querySelector("main");
|
||||
this.currAction = "";
|
||||
|
|
@ -370,10 +230,9 @@ class ServiceModal {
|
|||
this.setCardViewportHeight(action === "delete" ? false : true);
|
||||
this.setHeaderActionsVisible(action === "delete" ? false : true);
|
||||
this.SetSelectTabsVisible(action === "delete" ? false : true);
|
||||
this.setModeVisible(action);
|
||||
this.resetFilterSettings();
|
||||
if (action === "edit" || action === "new" || action === "clone") {
|
||||
this.formNewEdit.classList.remove("hidden");
|
||||
this.simpleForm.classList.remove("hidden");
|
||||
|
||||
const oldNameValue = action === "edit" ? oldServName : "";
|
||||
|
||||
|
|
@ -401,6 +260,20 @@ class ServiceModal {
|
|||
this.openModal();
|
||||
}
|
||||
|
||||
resetFilterSettings() {
|
||||
// Reset select
|
||||
const selectTypeAll = document
|
||||
.querySelector("#filter-type[data-services-setting-select-dropdown]")
|
||||
.querySelector(
|
||||
'button[value="all"][data-services-setting-select-dropdown-btn="type"]',
|
||||
);
|
||||
selectTypeAll.click();
|
||||
const inpKeyword = this.modal.querySelector("input#settings-filter");
|
||||
inpKeyword.value = "";
|
||||
// dispatch event input
|
||||
inpKeyword.dispatchEvent(new Event("input"));
|
||||
}
|
||||
|
||||
setIsDraft(isDraft, method) {
|
||||
const draftVal = isDraft ? "yes" : "no";
|
||||
|
||||
|
|
@ -437,18 +310,12 @@ class ServiceModal {
|
|||
this.modal
|
||||
.querySelector("[data-toggle-draft-btn]")
|
||||
.classList.remove("hidden");
|
||||
this.modal
|
||||
.querySelector("[data-toggle-settings-mode-btn]")
|
||||
.classList.remove("hidden");
|
||||
}
|
||||
|
||||
if (!setVisible) {
|
||||
this.modal
|
||||
.querySelector("[data-toggle-draft-btn]")
|
||||
.classList.add("hidden");
|
||||
this.modal
|
||||
.querySelector("[data-toggle-settings-mode-btn]")
|
||||
.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,29 +331,8 @@ class ServiceModal {
|
|||
}
|
||||
}
|
||||
|
||||
switchMode(mode) {
|
||||
if (mode === "advanced") {
|
||||
this.formNewEdit.classList.remove("hidden");
|
||||
this.simpleForm.classList.add("hidden");
|
||||
}
|
||||
|
||||
if (mode === "simple") {
|
||||
this.formNewEdit.classList.add("hidden");
|
||||
this.simpleForm.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
setModeVisible(action) {
|
||||
if (action === "new" || action === "clone" || action === "edit") {
|
||||
this.switchModeBtn.classList.remove("hidden");
|
||||
} else {
|
||||
this.switchModeBtn.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
hideForms() {
|
||||
this.formNewEdit.classList.add("hidden");
|
||||
this.simpleForm.classList.add("hidden");
|
||||
this.formDelete.classList.add("hidden");
|
||||
}
|
||||
|
||||
|
|
@ -842,13 +688,6 @@ const setFilterGlobal = new FilterSettings(
|
|||
|
||||
const settings = new SettingsService();
|
||||
|
||||
const switchSettings = new SettingsSwitch(
|
||||
document.querySelector("[data-toggle-settings-mode-btn]"),
|
||||
document.querySelector("main"),
|
||||
["advanced", "simple"],
|
||||
"services",
|
||||
);
|
||||
|
||||
const checkServiceModalKeyword = new CheckNoMatchFilter(
|
||||
document.querySelector("input#settings-filter"),
|
||||
"input",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
14
src/ui/templates/services_modal.html
vendored
14
src/ui/templates/services_modal.html
vendored
|
|
@ -31,19 +31,6 @@
|
|||
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button data-toggle-settings-mode-btn="advanced"
|
||||
class="transition hover:brightness-75 dark:hover:brightness-110 sm:ml-4 flex items-center border border-gray-700 dark:border-gray-300 dark:bg-slate-700 bg-gray-50/10 text-gray-800 rounded py-1 px-2 mt-1.5 sm:mt-0">
|
||||
<p data-toggle-settings-mode="simple"
|
||||
class="hidden dark:text-gray-100 mb-0 mr-2 pointer-events-none">Simple</p>
|
||||
<p data-toggle-settings-mode="advanced"
|
||||
class="dark:text-gray-100 mb-0 mr-2 pointer-events-none">Advanced</p>
|
||||
<svg data-toggle-settings-mode="simple" class="hidden translate-y-0.5 w-5 h-5 fill-gray-700 stroke-white/0 dark:fill-gray-300 pointer-events-none" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.84 1.804A1 1 0 0 1 8.82 1h2.36a1 1 0 0 1 .98.804l.331 1.652a6.993 6.993 0 0 1 1.929 1.115l1.598-.54a1 1 0 0 1 1.186.447l1.18 2.044a1 1 0 0 1-.205 1.251l-1.267 1.113a7.047 7.047 0 0 1 0 2.228l1.267 1.113a1 1 0 0 1 .206 1.25l-1.18 2.045a1 1 0 0 1-1.187.447l-1.598-.54a6.993 6.993 0 0 1-1.929 1.115l-.33 1.652a1 1 0 0 1-.98.804H8.82a1 1 0 0 1-.98-.804l-.331-1.652a6.993 6.993 0 0 1-1.929-1.115l-1.598.54a1 1 0 0 1-1.186-.447l-1.18-2.044a1 1 0 0 1 .205-1.251l1.267-1.114a7.05 7.05 0 0 1 0-2.227L1.821 7.773a1 1 0 0 1-.206-1.25l1.18-2.045a1 1 0 0 1 1.187-.447l1.598.54A6.992 6.992 0 0 1 7.51 3.456l.33-1.652ZM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<svg data-toggle-settings-mode="advanced" class="translate-y-0.5 w-5 h-5 fill-gray-700 stroke-white/0 dark:fill-gray-300 pointer-events-none" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path fill-rule="evenodd" d="M8.34 1.804A1 1 0 0 1 9.32 1h1.36a1 1 0 0 1 .98.804l.295 1.473c.497.144.971.342 1.416.587l1.25-.834a1 1 0 0 1 1.262.125l.962.962a1 1 0 0 1 .125 1.262l-.834 1.25c.245.445.443.919.587 1.416l1.473.294a1 1 0 0 1 .804.98v1.361a1 1 0 0 1-.804.98l-1.473.295a6.95 6.95 0 0 1-.587 1.416l.834 1.25a1 1 0 0 1-.125 1.262l-.962.962a1 1 0 0 1-1.262.125l-1.25-.834a6.953 6.953 0 0 1-1.416.587l-.294 1.473a1 1 0 0 1-.98.804H9.32a1 1 0 0 1-.98-.804l-.295-1.473a6.957 6.957 0 0 1-1.416-.587l-1.25.834a1 1 0 0 1-1.262-.125l-.962-.962a1 1 0 0 1-.125-1.262l.834-1.25a6.957 6.957 0 0 1-.587-1.416l-1.473-.294A1 1 0 0 1 1 10.68V9.32a1 1 0 0 1 .804-.98l1.473-.295c.144-.497.342-.971.587-1.416l-.834-1.25a1 1 0 0 1 .125-1.262l.962-.962A1 1 0 0 1 5.38 3.03l1.25.834a6.957 6.957 0 0 1 1.416-.587l.294-1.473ZM13 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="-translate-y-1"
|
||||
aria-label="close modal"
|
||||
|
|
@ -57,7 +44,6 @@
|
|||
</div>
|
||||
|
||||
{% include "services_modal_settings_advanced.html" %}
|
||||
{% include "services_modal_settings_simple.html" %}
|
||||
{% include "services_modal_delete.html" %}
|
||||
|
||||
</div>
|
||||
|
|
|
|||
156
src/ui/templates/services_modal_settings_simple.html
vendored
156
src/ui/templates/services_modal_settings_simple.html
vendored
|
|
@ -1,156 +0,0 @@
|
|||
{% set security_levels = ['standard', 'advanced', 'high', 'custom'] %}
|
||||
|
||||
{% set standard = {
|
||||
"USE_ANTIBOT": {
|
||||
"value": "javascript",
|
||||
"method": "default"
|
||||
},
|
||||
"SERVER_NAME": {
|
||||
"value": "test",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_URL": {
|
||||
"value": "/testfesf",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_RATE": {
|
||||
"value": "1r/s",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_URL_1": {
|
||||
"value": "/test",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_RATE_1": {
|
||||
"value": "3r/s",
|
||||
"method": "default"
|
||||
},
|
||||
"CUSTOM_CONFIG_MODSEC_1" : {
|
||||
"value": "test",
|
||||
"method": "default",
|
||||
"type" : "modsec",
|
||||
"name" : "modsec 1"
|
||||
},
|
||||
"CUSTOM_CONFIG_MODSEC_2" : {
|
||||
"value": "test 2",
|
||||
"method": "default",
|
||||
"type" : "modsec",
|
||||
"name" : "modsec 2"
|
||||
},
|
||||
}%}
|
||||
|
||||
{% set advanced = {
|
||||
"USE_ANTIBOT": {
|
||||
"value": "no",
|
||||
"method": "default"
|
||||
},
|
||||
}%}
|
||||
|
||||
{% set high = {
|
||||
"USE_ANTIBOT": {
|
||||
"value": "javascript",
|
||||
"method": "default"
|
||||
},
|
||||
}%}
|
||||
|
||||
{# When multiple, setting_id need to be a setting that is part of a multiple to get all settings on the same group #}
|
||||
{# On levels, we should set a list of dict with setting_id as key and value as value #}
|
||||
|
||||
{% set steps = [
|
||||
{
|
||||
"name" : "STEP 1 - STARTING UP",
|
||||
"description" : "we need some information to get started.",
|
||||
"settings" : [
|
||||
{"plugin_id" : "security-level", "setting_id": "SECURITY_LEVEL", "title" : "DEFINE SECURITY LEVEL", "subtitle" : "This will determine default settings value for the next steps. You'll be allow to modify settings to match your case if needed.", "setting" : {'context': 'global', 'default': 'standard', 'help': 'Determine the default settings value. You can override them.', 'id': 'security-level', 'label': 'Security level', 'regex': '^(security_levels[0]|security_levels[1]|security_levels[2]|security_levels[3])$', 'type': 'select', 'select': [security_levels[0], security_levels[1], security_levels[2], security_levels[3]]} },
|
||||
{"plugin_id" : "general", "setting_id": "SERVER_NAME", "title" : "DEFINE HOST", "subtitle" : "We need this to connect BunkerWeb to your application. You need to set your domain name."},
|
||||
{"plugin_id" : "limit", "setting_id": "LIMIT_REQ_URL", "title" : "Define header", "subtitle" : "test header multiple rendering" },
|
||||
],
|
||||
"configs": []
|
||||
},
|
||||
{
|
||||
"name" : "STEP 2 - ANTIBOT",
|
||||
"description" : "Avoid spammer and bot to access your website.",
|
||||
"settings" : [
|
||||
{"plugin_id" : "antibot", "setting_id": "USE_ANTIBOT", "title" : "Define the type of your antibot", "subtitle" : "Javascript, Captcha or Cookie don't need additionnal settings to be fill. Recaptcha, Hcaptcha and Turnstile need secret key and site key delivered from providers." },
|
||||
],
|
||||
"configs": [
|
||||
{"id" : "CUSTOM_CONFIG_MODSEC", "type" : "modsec", "name" : "modsecrules", "subtitle" : "This will determine the modsecurity rules to apply to this service."},
|
||||
]
|
||||
},
|
||||
]
|
||||
%}
|
||||
|
||||
{# Get setting for each settings on steps #}
|
||||
{% for step in steps %}
|
||||
{% for setting in step.get('settings') %}
|
||||
{% for plugin in plugins %}
|
||||
{% if setting["plugin_id"] == plugin["id"]%}
|
||||
|
||||
{% if setting.update({"setting" : plugin["settings"][setting["setting_id"]]})%}{%endif%}
|
||||
|
||||
{# Case multiple, get all settings on same group #}
|
||||
{% set is_multiple = plugin["settings"][setting["setting_id"]].get("multiple", "") %}
|
||||
{% if is_multiple %}
|
||||
{% set multiples = {"multiples" : []}%}
|
||||
{% for mult_setting, value in plugin["settings"].items() %}
|
||||
{% if value.get("multiple", "") == is_multiple %}
|
||||
{% set mult_value = value %}
|
||||
{% if mult_value.update({"name" : mult_setting}) %}{%endif%}
|
||||
{% if multiples["multiples"].append(mult_value) %}{%endif%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if setting.update(multiples)%}{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
<input type="hidden" id="security-level-{{security_levels[0]}}" data-settings="{{ standard }}" />
|
||||
<input type="hidden" id="security-level-{{security_levels[1]}}" data-settings="{{ advanced }}" />
|
||||
<input type="hidden" id="security-level-{{security_levels[2]}}" data-settings="{{ high }}" />
|
||||
|
||||
<!-- new and edit form -->
|
||||
<form data-simple data-services-modal-form
|
||||
class="!hidden 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" value="new" name="operation" />
|
||||
<input type="hidden" value="" name="OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
<input type="hidden" value="easy" name="mode" />
|
||||
|
||||
{% for step in steps %}
|
||||
<div data-step="{{loop.index}}" class="flex flex-col {% if loop.index != 1 %} hidden {% endif %}">
|
||||
<div class="flex flex-col w-full items-start mt-2">
|
||||
<h2 class="ml-2 mr-1 text-xl transition duration-300 ease-in-out font-bold text-md uppercase dark:text-white/90 mb-0" data-simple-step>{{ step.get("name")}}</h2>
|
||||
<p class="ml-2 mr-1 text-base dark:text-gray-300 mb-1" data-simple-description>{{ step.get("description")}}</p>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
{% set plugin_simple = step.get('settings') %}
|
||||
{% set configs = step.get('configs') %}
|
||||
{% include "settings_simple.html" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- 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="close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-simple-back
|
||||
type="button"
|
||||
disabled
|
||||
class="info-btn mb-4 mr-3 text-base">Back</button>
|
||||
<button data-simple-next type="button" class="mb-4 valid-btn">Continue</button>
|
||||
<button data-services-modal-submit type="submit" class="hidden 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>
|
||||
105
src/ui/templates/settings_simple.html
vendored
105
src/ui/templates/settings_simple.html
vendored
|
|
@ -1,105 +0,0 @@
|
|||
{% set current_endpoint = current_endpoint or url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
|
||||
<!-- plugin item -->
|
||||
<div class="w-full grid grid-cols-12">
|
||||
{% for setting_simple in plugin_simple %}
|
||||
{% set setting_input = { "name" : setting_simple.get('setting_id'), "multiples" : setting_simple.get("multiples", {}), "method" : setting_simple.get('setting').get("method", "default"), "help" : setting_simple.get('setting').get("help"), "label" : setting_simple.get('setting').get("label"), "id" : setting_simple.get('setting').get("id"), "type" : setting_simple.get('setting').get("type"), "default" : setting_simple.get('setting').get("default", "default"), "select" : setting_simple.get('setting').get("select"), "regex" : setting_simple.get('setting').get("regex"), "value" : setting_simple.get('setting').get("value"), "is_multiple" : True if setting_simple.get('setting').get("multiple", "") else False, "multiple_name" : setting_simple.get('setting').get('multiple') } %}
|
||||
<div data-simple id="{{ setting_simple['plugin_id'] }}-simple"
|
||||
class="w-full h-full px-1 mb-2 col-span-12 {% if not setting_input['is_multiple'] %} mt-2 md:col-span-6 {%else%} mt-4 {% endif %} grid grid-cols-12 h-full items-end">
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<div class="flex flex-col justify-start items-start">
|
||||
<h5 class="sm:pl-3 sm:pr-2 mt-2 transition duration-300 ease-in-out font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ setting_simple['title'] }}
|
||||
</h5>
|
||||
<p class="max-w-[550px] sm:pl-3 sm:pr-2 text-sm dark:text-gray-300 mb-0">{{ setting_simple['subtitle'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% if not setting_input.get('is_multiple') %}
|
||||
<!-- end title and desc -->
|
||||
<div class="w-full col-span-12">
|
||||
<div data-setting-container data-{{ current_endpoint }}-type="{{ setting_input['type'] }}" data-{{ current_endpoint }}-context="{{ setting_input['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ setting_input["id"] }}">
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html" %}
|
||||
{% include "setting_select.html" %}
|
||||
{% include "setting_checkbox.html" %}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end plugin settings not multiple -->
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if setting_input.get('is_multiple') %}
|
||||
<!-- plugin multiple handler -->
|
||||
<div data-multiple-handler="{{ setting_input['multiple_name'] }}"
|
||||
class="flex items-center mx-4 mb-2 mt-5 col-span-12 ">
|
||||
<h5 class="input-title max-w-[150px] sm:max-w-[350px]">{{ setting_simple['plugin_id'] }}</h5>
|
||||
<button data-{{ attribute_name }}-multiple-add="{{ setting_input['multiple_name'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Add
|
||||
</button>
|
||||
<button data-{{ attribute_name }}-multiple-toggle="{{ setting_input['multiple_name'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
SHOW / HIDE
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin multiple handler-->
|
||||
<!-- multiple settings -->
|
||||
<div data-{{ attribute_name }}-settings-multiple="{{ setting_input['multiple_name'] }}_SCHEMA" class=" col-span-12 bg-gray-50 dark:bg-slate-900/30 hidden w-full mt-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting in setting_input.get("multiples") %}
|
||||
{% set setting_input = { "name" : setting.get("name"), "context" : setting.get("context"), "method" : setting.get("method", "default"), "help" : setting.get("help"), "label" : setting.get("label"), "id" : setting.get("id"), "type" : setting.get("type"), "default" : setting.get("default", "default"), "select" : setting.get("select"), "regex" : setting.get("regex"), "value" : setting.get("value", setting.get('default')), "is_multiple" : True} %}
|
||||
<div data-setting-container="{{ setting_input['name'] }}_SCHEMA" data-{{ attribute_name }}-type="{{ setting_input['type'] }}" data-{{ attribute_name }}-context="{{ setting_input['context'] }}" class="relative mx-2 md:mx-3 my-2 md:my-3 col-span-12 md:col-span-6 2xl:col-span-4" id="form-edit-{{ attribute_name }}-{{ setting_input['id'] }}_SCHEMA">
|
||||
<!-- title and info -->
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html" %}
|
||||
{% include "setting_select.html" %}
|
||||
{% include "setting_checkbox.html" %}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div data-multiple-delete-container
|
||||
class="col-span-12 flex justify-center my-4">
|
||||
<button data-{{ attribute_name }}-multiple-delete="{{ setting_simple['plugin_id'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end multiple settings -->
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- custom configs -->
|
||||
{% for config in configs %}
|
||||
<div data-simple data-config-container
|
||||
class="w-full h-full px-1 mt-4 mb-2 col-span-12 grid grid-cols-12 h-full items-end">
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<div class="flex flex-col justify-start items-start">
|
||||
<h5 class="sm:pl-3 sm:pr-2 mt-2 transition duration-300 ease-in-out font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ config['title'] }}
|
||||
</h5>
|
||||
<p class="max-w-[550px] sm:pl-3 sm:pr-2 text-sm dark:text-gray-300 mb-0">{{ config['subtitle'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div data-editor-container="{{config['id']}}_SCHEMA" data-default-type="{{config['type']}}" data-default-name="{{config['name']}}" class="hidden w-full col-span-12 px-4">
|
||||
<div class="mb-2 flex flex-wrap justify-start items-center" >
|
||||
<input disabled type="text"
|
||||
name="CONFIG_NAME"
|
||||
data-editor-filename
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 sm:ml-1 max-w-40 focus:valid:border-green-500 focus:file: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-1.5 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700"
|
||||
placeholder="{{config['name']}}"
|
||||
required />
|
||||
<p class="ml-1 mb-0 dark:text-white/80 text-gray-700/80 text-sm">
|
||||
.conf
|
||||
</p>
|
||||
</div>
|
||||
<textarea data-editor-input class="hidden"></textarea>
|
||||
<!-- editor-->
|
||||
<div data-editor class="text-base w-full h-50 overflow-hidden overflow-y-auto my-2 border border-gray-300 dark:border-slate-800">
|
||||
</div>
|
||||
<!-- editor-->
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
@ -61,7 +61,8 @@ try:
|
|||
|
||||
log_info("Toggle modal checked, trying settings ...")
|
||||
|
||||
assert_button_click(DRIVER, "//button[@data-toggle-settings-mode-btn='simple']")
|
||||
# simple mode
|
||||
# assert_button_click(DRIVER, "//button[@data-toggle-settings-mode-btn='simple']")
|
||||
|
||||
log_info("Start trying combobox filter ...")
|
||||
|
||||
|
|
@ -270,19 +271,19 @@ try:
|
|||
|
||||
assert_button_click(DRIVER, "//button[@data-services-action='new']")
|
||||
|
||||
current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
if current_mode != "simple":
|
||||
log_error(f"""Default mode for new service need to be simple and not {current_mode}...""")
|
||||
exit(1)
|
||||
# current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
# if current_mode != "simple":
|
||||
# log_error(f"""Default mode for new service need to be simple and not {current_mode}...""")
|
||||
# exit(1)
|
||||
|
||||
# Switch to advanced mode
|
||||
DRIVER.execute_script("document.querySelector('button[data-toggle-settings-mode-btn]').click()")
|
||||
# # Switch to advanced mode
|
||||
# DRIVER.execute_script("document.querySelector('button[data-toggle-settings-mode-btn]').click()")
|
||||
|
||||
current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
# current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
|
||||
if current_mode != "advanced":
|
||||
log_error(f"""Switching mode needed to return advanced mode, but he have {current_mode}...""")
|
||||
exit(1)
|
||||
# if current_mode != "advanced":
|
||||
# log_error(f"""Switching mode needed to return advanced mode, but he have {current_mode}...""")
|
||||
# exit(1)
|
||||
|
||||
server_name_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-services-modal-form and @data-advanced]//input[@id='SERVER_NAME']")
|
||||
assert isinstance(server_name_input, WebElement), "Input is not a WebElement"
|
||||
|
|
|
|||
Loading…
Reference in a new issue