mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-12-02 07:38:22 +00:00
Add global CAPTCHA config and EspoCRM seeder
- Introduce shared CAPTCHA settings and RECAPTCHA_ENABLED/HCAPTCHA_ENABLED flags in group_vars - Wire reCAPTCHA/hCaptcha credentials into EspoCRM, Keycloak, Listmonk and Nextcloud - Replace EspoCRM set_flags.php with generic seed_config.php and hook it into entrypoint/env - Fix run_once handling in sys-ctl-cln-disc-space and minor CSS Jinja spacing issue https://chatgpt.com/share/692a1d4f-1154-800f-a4ae-bb068aa24a53
This commit is contained in:
@@ -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) }}"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) #}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
147
roles/web-app-espocrm/files/seed_config.php
Normal file
147
roles/web-app-espocrm/files/seed_config.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* Generic EspoCRM config seeder.
|
||||
*
|
||||
* Automatically scans all environment variables starting with ESPOCRM_SEED_,
|
||||
* converts them into EspoCRM camelCase config keys, and writes them via ConfigWriter.
|
||||
*
|
||||
* Example:
|
||||
* ESPOCRM_SEED_RECAPTCHA_SECRET_KEY=xyz
|
||||
* becomes:
|
||||
* recaptchaSecretKey => "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.");
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* set_flags.php – Ensure EspoCRM runtime flags are set idempotently.
|
||||
*/
|
||||
|
||||
require "/var/www/html/bootstrap.php";
|
||||
|
||||
$app = new \Espo\Core\Application();
|
||||
$c = $app->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";
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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 }}"
|
||||
|
||||
@@ -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
|
||||
|
||||
## 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') }}"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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: >-
|
||||
|
||||
@@ -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 }}"
|
||||
@@ -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,}$"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user