diff --git a/group_vars/all/00_general.yml b/group_vars/all/00_general.yml index 5503d935..a18536c7 100644 --- a/group_vars/all/00_general.yml +++ b/group_vars/all/00_general.yml @@ -88,3 +88,15 @@ RBAC: GROUP: NAME: "/roles" # Name of the group which holds the RBAC roles CLAIM: "groups" # Name of the claim containing the RBAC groups + +# You need to set both keys to enable them +CAPTCHA: + RECAPTCHA: + KEY: "" + SECRET: "" + HCAPTCHA: + KEY: "" + SECRET: "" + +RECAPTCHA_ENABLED: "{{ (CAPTCHA.RECAPTCHA.KEY | length > 0) and (CAPTCHA.RECAPTCHA.SECRET | length > 0) }}" +HCAPTCHA_ENABLED: "{{ (CAPTCHA.HCAPTCHA.KEY | length > 0) and (CAPTCHA.HCAPTCHA.SECRET | length > 0) }}" diff --git a/roles/sys-ctl-cln-disc-space/tasks/01_core.yml b/roles/sys-ctl-cln-disc-space/tasks/01_core.yml index 6f71ffa6..cb60e92b 100644 --- a/roles/sys-ctl-cln-disc-space/tasks/01_core.yml +++ b/roles/sys-ctl-cln-disc-space/tasks/01_core.yml @@ -15,3 +15,5 @@ system_service_tpl_exec_start: "{{ system_service_script_exec }} {{ SIZE_PERCENT_CLEANUP_DISC_SPACE }}" system_service_tpl_exec_start_pre: '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(" ") }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(" ") }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"' system_service_force_linear_sync: false + +- include_tasks: utils/run_once.yml \ No newline at end of file diff --git a/roles/sys-ctl-cln-disc-space/tasks/main.yml b/roles/sys-ctl-cln-disc-space/tasks/main.yml index e037cace..c4874550 100644 --- a/roles/sys-ctl-cln-disc-space/tasks/main.yml +++ b/roles/sys-ctl-cln-disc-space/tasks/main.yml @@ -1,5 +1,2 @@ -- block: - - include_tasks: 01_core.yml - - include_tasks: utils/run_once.yml +- include_tasks: 01_core.yml when: run_once_sys_ctl_cln_disc_space is not defined - diff --git a/roles/sys-front-inj-css/templates/css/default.css.j2 b/roles/sys-front-inj-css/templates/css/default.css.j2 index 0e857e72..5c0795d8 100644 --- a/roles/sys-front-inj-css/templates/css/default.css.j2 +++ b/roles/sys-front-inj-css/templates/css/default.css.j2 @@ -105,7 +105,7 @@ body, html[native-dark-active] { background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-93), var(--color-01-91), var(--color-01-95), var(--color-01-93)); background-attachment: fixed; color: var(--color-01-40); - font-family: {{design.font.type}}; + font-family: {{ design.font.type }}; } {# All links (applies to all anchor elements regardless of state) #} diff --git a/roles/web-app-espocrm/config/main.yml b/roles/web-app-espocrm/config/main.yml index f0dfd365..cd5e2c7b 100644 --- a/roles/web-app-espocrm/config/main.yml +++ b/roles/web-app-espocrm/config/main.yml @@ -6,7 +6,7 @@ features: oidc: true central_database: true logout: true - recaptcha: true # Required for leads formulars + recaptcha: "{{ RECAPTCHA_ENABLED | bool }}" # Required for leads formulars server: csp: flags: @@ -30,6 +30,10 @@ server: - espo.crm.{{ PRIMARY_DOMAIN }} email: from_name: "Customer Relationship Management ({{ PRIMARY_DOMAIN }})" +credentials: + recaptcha: + key: "{{ CAPTCHA.RECAPTCHA.KEY }}" + secret: "{{ CAPTCHA.RECAPTCHA.SECRET }}" docker: services: database: diff --git a/roles/web-app-espocrm/files/docker-entrypoint-custom.sh b/roles/web-app-espocrm/files/docker-entrypoint-custom.sh index 31222af2..3cb2bf08 100644 --- a/roles/web-app-espocrm/files/docker-entrypoint-custom.sh +++ b/roles/web-app-espocrm/files/docker-entrypoint-custom.sh @@ -16,18 +16,14 @@ bool_norm () { } # --- Environment initialization ---------------------------------------------- -MAINTENANCE="$(bool_norm "${ESPO_INIT_MAINTENANCE_MODE:-false}")" -CRON_DISABLED="$(bool_norm "${ESPO_INIT_CRON_DISABLED:-false}")" -USE_CACHE="$(bool_norm "${ESPO_INIT_USE_CACHE:-true}")" +MAINTENANCE="$(bool_norm "${ESPOCRM_SEED_MAINTENANCE_MODE}")" +CRON_DISABLED="$(bool_norm "${ESPOCRM_SEED_CRON_DISABLED}")" +USE_CACHE="$(bool_norm "${ESPOCRM_SEED_USE_CACHE}")" APP_DIR="/var/www/html" # Provided by env.j2 (fallback ensures robustness) -SET_FLAGS_SCRIPT="${ESPOCRM_SET_FLAGS_SCRIPT:-/usr/local/bin/set_flags.php}" -if [ ! -f "$SET_FLAGS_SCRIPT" ]; then - log "WARN: SET_FLAGS_SCRIPT '$SET_FLAGS_SCRIPT' not found; falling back to /usr/local/bin/set_flags.php" - SET_FLAGS_SCRIPT="/usr/local/bin/set_flags.php" -fi +SEED_CONFIG_SCRIPT="${ESPOCRM_SCRIPT_SEED}" # --- Wait for bootstrap.php (max 60s, e.g. fresh volume) ---------------------- log "Waiting for ${APP_DIR}/bootstrap.php..." @@ -41,10 +37,10 @@ if [ ! -f "${APP_DIR}/bootstrap.php" ]; then exit 1 fi -# --- Apply config flags via set_flags.php ------------------------------------ -log "Applying runtime flags via set_flags.php..." -if ! php "${SET_FLAGS_SCRIPT}"; then - log "ERROR: set_flags.php execution failed" +# --- Apply config flags via seed_config.php ------------------------------------ +log "Applying runtime flags via seed_config.php..." +if ! php "${SEED_CONFIG_SCRIPT}"; then + log "ERROR: seed_config.php execution failed" exit 1 fi diff --git a/roles/web-app-espocrm/files/seed_config.php b/roles/web-app-espocrm/files/seed_config.php new file mode 100644 index 00000000..c7c7eb3c --- /dev/null +++ b/roles/web-app-espocrm/files/seed_config.php @@ -0,0 +1,147 @@ + "xyz" + */ + +require "/var/www/html/bootstrap.php"; + +$app = new \Espo\Core\Application(); +$c = $app->getContainer(); +$config = $c->get("config"); +$writer = $c->get("injectableFactory")->create("\Espo\Core\Utils\Config\ConfigWriter"); + +/** + * Convert an ENV suffix like "RECAPTCHA_SECRET_KEY" to camelCase "recaptchaSecretKey". + */ +function to_camel_case(string $input): string +{ + $input = strtolower($input); + $parts = explode('_', $input); + $result = array_shift($parts); + + foreach ($parts as $part) { + $result .= ucfirst($part); + } + + return $result; +} + +/** + * Normalize booleans if the value looks boolean-like. + * Returns true/false for typical boolean strings, otherwise the original string. + */ +function cast_value(string $value) +{ + $normalized = strtolower(trim($value)); + + if (in_array($normalized, ['1', 'true', 'yes', 'on'], true)) { + return true; + } + + if (in_array($normalized, ['0', 'false', 'no', 'off'], true)) { + return false; + } + + return $value; // keep as string +} + +/** + * Simple debug logger to STDERR. + * This keeps STDOUT clean so automation can rely on "CHANGED"/"UNCHANGED". + */ +function seed_debug(string $message): void +{ + fwrite(STDERR, "[seed] " . $message . PHP_EOL); +} + +// Determine debug mode from ESPOCRM_SEED_DEBUG +$debugEnv = getenv('ESPOCRM_SEED_DEBUG'); +$debug = false; +if ($debugEnv !== false) { + $normalized = strtolower(trim($debugEnv)); + $debug = in_array($normalized, ['1', 'true', 'yes', 'on'], true); +} + +if ($debug) { + seed_debug("Seeder started, scanning ESPOCRM_SEED_* variables …"); +} + +$changed = false; + +foreach ($_ENV as $envKey => $envValue) { + // Only process variables beginning with ESPOCRM_SEED_ + if (strpos($envKey, 'ESPOCRM_SEED_') !== 0) { + continue; + } + + // Extract the config part (after prefix) + $rawKey = substr($envKey, strlen('ESPOCRM_SEED_')); // e.g. "RECAPTCHA_SECRET_KEY" + + if ($rawKey === '') { + continue; + } + + // Convert to camelCase + $configKey = to_camel_case($rawKey); + + // Normalize boolean or keep string + $value = cast_value((string) $envValue); + + if ($debug) { + seed_debug(sprintf( + "ENV %s -> config key '%s' = %s", + $envKey, + $configKey, + var_export($value, true) + )); + } + + $current = $config->get($configKey); + + if ($current !== $value) { + if ($debug) { + seed_debug(sprintf( + "Updating '%s': %s -> %s", + $configKey, + var_export($current, true), + var_export($value, true) + )); + } + + $writer->set($configKey, $value); + $changed = true; + } else { + if ($debug) { + seed_debug(sprintf( + "No change for '%s' (already %s)", + $configKey, + var_export($current, true) + )); + } + } +} + +if ($changed) { + if ($debug) { + seed_debug("Changes detected, saving configuration …"); + } + $writer->save(); + echo "CHANGED\n"; +} else { + if ($debug) { + seed_debug("No changes detected."); + } + echo "UNCHANGED\n"; +} + +if ($debug) { + seed_debug("Seeder finished."); +} diff --git a/roles/web-app-espocrm/files/set_flags.php b/roles/web-app-espocrm/files/set_flags.php deleted file mode 100644 index 83007cd3..00000000 --- a/roles/web-app-espocrm/files/set_flags.php +++ /dev/null @@ -1,33 +0,0 @@ -getContainer(); -$cfg = $c->get("config"); -$w = $c->get("injectableFactory")->create("\Espo\Core\Utils\Config\ConfigWriter"); - -// Read from ENV -$flags = [ - "maintenanceMode" => in_array(strtolower(getenv("ESPO_INIT_MAINTENANCE_MODE") ?: "false"), ["1","true","yes","on"]), - "cronDisabled" => in_array(strtolower(getenv("ESPO_INIT_CRON_DISABLED") ?: "false"), ["1","true","yes","on"]), - "useCache" => in_array(strtolower(getenv("ESPO_INIT_USE_CACHE") ?: "true"), ["1","true","yes","on"]) -]; - -$changed = false; -foreach ($flags as $k => $v) { - if ($cfg->get($k) !== $v) { - $w->set($k, $v); - $changed = true; - } -} - -if ($changed) { - $w->save(); - echo "CHANGED\n"; -} else { - echo "UNCHANGED\n"; -} diff --git a/roles/web-app-espocrm/tasks/main.yml b/roles/web-app-espocrm/tasks/main.yml index e5b120d2..89523391 100644 --- a/roles/web-app-espocrm/tasks/main.yml +++ b/roles/web-app-espocrm/tasks/main.yml @@ -13,10 +13,10 @@ - docker compose up - docker compose build -- name: "Deploy '{{ ESPOCRM_SET_FLAG_SCRIPT_HOST_ABS }}'" +- name: "Deploy '{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}'" copy: - src: "{{ ESPOCRM_SET_FLAG_SCRIPT_FILE }}" - dest: "{{ ESPOCRM_SET_FLAG_SCRIPT_HOST_ABS }}" + src: "{{ ESPOCRM_SCRIPT_SEED_FILE }}" + dest: "{{ ESPOCRM_SCRIPT_SEED_HOST_ABS }}" notify: - docker compose up - docker compose build @@ -47,7 +47,7 @@ - name: Run flag setter as root (fallback) command: > docker exec --user root {{ ESPOCRM_CONTAINER }} - php {{ ESPOCRM_SET_FLAG_SCRIPT_DOCKER }} + php {{ ESPOCRM_SCRIPT_SEED_DOCKER }} register: flags_result_root changed_when: "'CHANGED' in flags_result_root.stdout" diff --git a/roles/web-app-espocrm/templates/Dockerfile.j2 b/roles/web-app-espocrm/templates/Dockerfile.j2 index 145d7f2e..fa65f32d 100644 --- a/roles/web-app-espocrm/templates/Dockerfile.j2 +++ b/roles/web-app-espocrm/templates/Dockerfile.j2 @@ -1,7 +1,7 @@ FROM "{{ ESPOCRM_IMAGE }}:{{ ESPOCRM_VERSION }}" -COPY {{ ESPOCRM_SET_FLAG_SCRIPT_HOST_REL }} {{ ESPOCRM_SET_FLAG_SCRIPT_DOCKER }} -RUN chmod +x {{ ESPOCRM_SET_FLAG_SCRIPT_DOCKER }} +COPY {{ ESPOCRM_SCRIPT_SEED_HOST_REL }} {{ ESPOCRM_SCRIPT_SEED_DOCKER }} +RUN chmod +x {{ ESPOCRM_SCRIPT_SEED_DOCKER }} COPY {{ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_REL }} {{ ESPOCRM_ENTRYPOINT_SCRIPT_DOCKER }} RUN chmod +x {{ ESPOCRM_ENTRYPOINT_SCRIPT_DOCKER }} diff --git a/roles/web-app-espocrm/templates/env.j2 b/roles/web-app-espocrm/templates/env.j2 index 6b8c0ae4..5cf474e6 100644 --- a/roles/web-app-espocrm/templates/env.j2 +++ b/roles/web-app-espocrm/templates/env.j2 @@ -104,8 +104,19 @@ ESPOCRM_CONFIG_OIDC_USERNAME_CLAIM={{ OIDC.ATTRIBUTES.USERNAME }} # ESPOCRM_CONFIG_OIDC_GROUP_CLAIM=group {% endif %} -# --- Espo init toggles controlled at container start (used by custom entrypoint) -ESPO_INIT_MAINTENANCE_MODE=false # false = disable maintenance (recommended) -ESPO_INIT_CRON_DISABLED=false # false = enable cron jobs in config -ESPO_INIT_USE_CACHE=true # true = enable caching -ESPOCRM_SET_FLAGS_SCRIPT={{ ESPOCRM_SET_FLAG_SCRIPT_DOCKER }} +## Seed Configuration + +ESPOCRM_SEED_DEBUG={{ MODE_DEBUG | lower }} + +ESPOCRM_SCRIPT_SEED={{ ESPOCRM_SCRIPT_SEED_DOCKER }} + +## Espo init toggles controlled at container start (used by custom entrypoint) +ESPOCRM_SEED_MAINTENANCE_MODE={{ ESPOCRM_MAINTENANCE_MODE }} +ESPOCRM_SEED_CRON_DISABLED={{ ESPOCRM_CRON_DISABLED }} +ESPOCRM_SEED_USE_CACHE={{ ESPOCRM_USE_CACHE }} + +## ReCAPTCHA +ESPOCRM_SEED_RECAPTCHA_VERSION="v3" +ESPOCRM_SEED_RECAPTCHA_ENABLED="{{ ESPOCRM_RECAPTCHA_ENABLED }}" +ESPOCRM_SEED_RECAPTCHA_PUBLIC_KEY="{{ ESPOCRM_RECAPTCHA_KEY }}" +ESPOCRM_SEED_RECAPTCHA_SECRET_KEY="{{ ESPOCRM_RECAPTCHA_SECRET }}" diff --git a/roles/web-app-espocrm/vars/main.yml b/roles/web-app-espocrm/vars/main.yml index 106e5e28..335a1ea5 100644 --- a/roles/web-app-espocrm/vars/main.yml +++ b/roles/web-app-espocrm/vars/main.yml @@ -2,6 +2,7 @@ application_id: "web-app-espocrm" entity_name: "{{ application_id | get_entity_name }}" + # Database database_type: "mariadb" @@ -31,17 +32,28 @@ ESPOCRM_ENTRYPOINT_SCRIPT_HOST_ABS: "{{ [ docker_compose.directories.volumes, ES ESPOCRM_ENTRYPOINT_SCRIPT_HOST_REL: "volumes/{{ ESPOCRM_ENTRYPOINT_SCRIPT_FILE }}" ESPOCRM_ENTRYPOINT_SCRIPT_DOCKER: "{{ [ '/usr/local/bin/', ESPOCRM_ENTRYPOINT_SCRIPT_FILE ] | path_join }}" -### Set Flag -ESPOCRM_SET_FLAG_SCRIPT_FILE: "set_flags.php" -ESPOCRM_SET_FLAG_SCRIPT_HOST_ABS: "{{ [ docker_compose.directories.volumes, ESPOCRM_SET_FLAG_SCRIPT_FILE ] | path_join }}" -ESPOCRM_SET_FLAG_SCRIPT_HOST_REL: "volumes/{{ ESPOCRM_SET_FLAG_SCRIPT_FILE }}" -ESPOCRM_SET_FLAG_SCRIPT_DOCKER: "{{ [ '/usr/local/bin/', ESPOCRM_SET_FLAG_SCRIPT_FILE ] | path_join }}" - ESPOCRM_CONFIG_FILE_PRIVATE: "/var/www/html/data/config-internal.php" ESPOCRM_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" ESPOCRM_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}" ESPOCRM_USER: "www-data" -ESPO_INIT_MAINTENANCE_MODE: "{{ applications | get_app_conf(application_id, 'maintenance_mode') | default(false) }}" -ESPO_INIT_CRON_DISABLED: "{{ ESPO_INIT_MAINTENANCE_MODE }}" # disable cron only when in maintenance -ESPO_INIT_USE_CACHE: "{{ not ESPO_INIT_MAINTENANCE_MODE }}" # enable cache when NOT in maintenance \ No newline at end of file + +## Seeding + +### Seeding Script Parameter +ESPOCRM_SCRIPT_SEED_FILE: "seed_config.php" +ESPOCRM_SCRIPT_SEED_HOST_ABS: "{{ [ docker_compose.directories.volumes, ESPOCRM_SCRIPT_SEED_FILE ] | path_join }}" +ESPOCRM_SCRIPT_SEED_HOST_REL: "volumes/{{ ESPOCRM_SCRIPT_SEED_FILE }}" +ESPOCRM_SCRIPT_SEED_DOCKER: "{{ [ '/usr/local/bin/', ESPOCRM_SCRIPT_SEED_FILE ] | path_join }}" + +### Seeding Values + +#### Maintanance +ESPOCRM_MAINTENANCE_MODE: "{{ applications | get_app_conf(application_id, 'maintenance_mode') }}" +ESPOCRM_CRON_DISABLED: "{{ ESPOCRM_MAINTENANCE_MODE }}" # disable cron only when in maintenance +ESPOCRM_USE_CACHE: "{{ not ESPOCRM_MAINTENANCE_MODE }}" # enable cache when NOT in maintenance + +#### reCAPTCHA +ESPOCRM_RECAPTCHA_ENABLED: "{{ applications | get_app_conf(application_id, 'features.recaptcha') }}" +ESPOCRM_RECAPTCHA_KEY: "{{ applications | get_app_conf(application_id, 'credentials.recaptcha.key') }}" +ESPOCRM_RECAPTCHA_SECRET: "{{ applications | get_app_conf(application_id, 'credentials.recaptcha.secret') }}" diff --git a/roles/web-app-keycloak/config/main.yml b/roles/web-app-keycloak/config/main.yml index 7d45d789..6e29dcc0 100644 --- a/roles/web-app-keycloak/config/main.yml +++ b/roles/web-app-keycloak/config/main.yml @@ -7,7 +7,7 @@ features: desktop: true ldap: true central_database: true - recaptcha: true + recaptcha: "{{ RECAPTCHA_ENABLED | bool }}" # Doesn't make sense to activate logout page for keycloak, because the logout page # anyhow should be included via iframe in keycloak. @@ -45,12 +45,10 @@ docker: pids_limit: 1024 database: enabled: true - credentials: recaptcha: - website_key: "" # Required if you enabled recaptcha: - secret_key: "" # Required if you enabled recaptcha: - + key: "{{ CAPTCHA.RECAPTCHA.KEY }}" + secret: "{{ CAPTCHA.RECAPTCHA.SECRET }}" accounts: bootstrap: username: "administrator" diff --git a/roles/web-app-keycloak/tasks/main.yml b/roles/web-app-keycloak/tasks/main.yml index 326b6a6b..bef8ef20 100644 --- a/roles/web-app-keycloak/tasks/main.yml +++ b/roles/web-app-keycloak/tasks/main.yml @@ -34,5 +34,4 @@ - name: "Load reCAPTCHA Update routines for '{{ application_id }}'" include_tasks: update/06_recaptcha.yml - when: applications | get_app_conf(application_id, 'features.recaptcha', False) - + when: KEYCLOAK_RECAPTCHA_ENABLED | bool diff --git a/roles/web-app-keycloak/templates/import/realm.json.j2 b/roles/web-app-keycloak/templates/import/realm.json.j2 index bcd44f9a..634cd5a1 100644 --- a/roles/web-app-keycloak/templates/import/realm.json.j2 +++ b/roles/web-app-keycloak/templates/import/realm.json.j2 @@ -2114,7 +2114,7 @@ "autheticatorFlow": false, "userSetupAllowed": false }, -{%- if applications | get_app_conf(application_id, 'features.recaptcha', False) %} +{%- if KEYCLOAK_RECAPTCHA_ENABLED | bool %} { "authenticatorConfig": "Google reCaptcha", "authenticator": "registration-recaptcha-action", @@ -2204,15 +2204,15 @@ } ], "authenticatorConfig": [ -{%- if applications | get_app_conf(application_id, 'features.recaptcha', False) %} +{%- if KEYCLOAK_RECAPTCHA_ENABLED | bool %} { "alias": "Google reCaptcha", "config": { "action": "register", "useRecaptchaNet": "false", "recaptcha.v3": "true", - "secret.key": "{{ applications | get_app_conf(application_id, 'credentials.recaptcha.secret_key', True) }}", - "site.key": "{{ applications | get_app_conf(application_id, 'credentials.recaptcha.website_key', True) }}" + "secret.key": "{{ KEYCLOAK_RECAPTCHA_SECRET }}", + "site.key": "{{ KEYCLOAK_RECAPTCHA_KEY }}" } }, {%- endif %} diff --git a/roles/web-app-keycloak/vars/main.yml b/roles/web-app-keycloak/vars/main.yml index a3641eb0..d01510cb 100644 --- a/roles/web-app-keycloak/vars/main.yml +++ b/roles/web-app-keycloak/vars/main.yml @@ -77,6 +77,11 @@ KEYCLOAK_LDAP_USER_OBJECT_CLASSES: > ) | join(', ') }} +# reCAPTCHA +KEYCLOAK_RECAPTCHA_ENABLED: "{{ applications | get_app_conf(application_id, 'features.recaptcha') }}" +KEYCLOAK_RECAPTCHA_KEY: "{{ applications | get_app_conf(application_id, 'credentials.recaptcha.key') }}" +KEYCLOAK_RECAPTCHA_SECRET: "{{ applications | get_app_conf(application_id, 'credentials.recaptcha.secret') }}" + # Dictionaries KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}" KEYCLOAK_DICTIONARY_REALM: >- diff --git a/roles/web-app-listmonk/config/main.yml b/roles/web-app-listmonk/config/main.yml index fc905937..eb196c7b 100644 --- a/roles/web-app-listmonk/config/main.yml +++ b/roles/web-app-listmonk/config/main.yml @@ -6,7 +6,7 @@ features: central_database: true oidc: true logout: true - hcaptcha: true + hcaptcha: "{{ HCAPTCHA_ENABLED | bool }}" server: domains: canonical: @@ -23,9 +23,13 @@ docker: database: enabled: true listmonk: - image: listmonk/listmonk - version: latest + image: listmonk/listmonk + version: latest backup: no_stop_required: true - name: listmonk - port: 9000 + name: listmonk + port: 9000 +credentials: + hcaptcha: + key: "{{ CAPTCHA.HCAPTCHA.KEY }}" + secret: "{{ CAPTCHA.HCAPTCHA.SECRET }}" \ No newline at end of file diff --git a/roles/web-app-listmonk/schema/main.yml b/roles/web-app-listmonk/schema/main.yml index a4a7269d..f985f62f 100644 --- a/roles/web-app-listmonk/schema/main.yml +++ b/roles/web-app-listmonk/schema/main.yml @@ -3,13 +3,3 @@ credentials: description: "Initial password for the Listmonk administrator account" algorithm: "sha256" validation: "^[a-f0-9]{64}$" - - hcaptcha_site_key: - description: "Public site key used by Listmonk to render hCaptcha" - algorithm: "plain" - validation: "^[0-9a-zA-Z_-]{32,}$" - - hcaptcha_secret: - description: "Private hCaptcha secret key for server-side verification" - algorithm: "plain" - validation: "^[0-9a-zA-Z_-]{32,}$" diff --git a/roles/web-app-listmonk/vars/main.yml b/roles/web-app-listmonk/vars/main.yml index e2a6ce04..e211f959 100644 --- a/roles/web-app-listmonk/vars/main.yml +++ b/roles/web-app-listmonk/vars/main.yml @@ -38,10 +38,10 @@ LISTMONK_SETTINGS: value: 'true' - key: "security.captcha_key" - value: '"{{ applications | get_app_conf(application_id, "credentials.hcaptcha_site_key") }}"' + value: '"{{ applications | get_app_conf(application_id, "credentials.hcaptcha.key") }}"' - key: "security.captcha_secret" - value: '"{{ applications | get_app_conf(application_id, "credentials.hcaptcha_secret") }}"' + value: '"{{ applications | get_app_conf(application_id, "credentials.hcaptcha.secret") }}"' # SMTP servers - key: "smtp" diff --git a/roles/web-app-nextcloud/config/main.yml b/roles/web-app-nextcloud/config/main.yml index fe1dea83..db1bb419 100644 --- a/roles/web-app-nextcloud/config/main.yml +++ b/roles/web-app-nextcloud/config/main.yml @@ -127,7 +127,7 @@ features: oidc: true central_database: true logout: true - hcaptcha: true + hcaptcha: "{{ HCAPTCHA_ENABLED | bool }}" default_quota: '1000000000' # Quota to assign if no quota is specified in the OIDC response (bytes) legacy_login_mask: enabled: False # If true, then legacy login mask is shown. Otherwise just SSO