Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,23 @@ The entrypoint script handles:
| `SIMPLERISK_DB_USERNAME/PASSWORD/DATABASE` | DB credentials |
| `SIMPLERISK_CRON_SETUP` | Enable/disable PHP cron (default: enabled) |
| `SIMPLERISK_CSRF_SECRET` | Override auto-generated CSRF secret |
| `ADMIN_USERNAME` | Username for initial admin user (only during `DB_SETUP`; idempotent) |
| `ADMIN_PASSWORD` | Password for initial admin user |
| `ADMIN_EMAIL` | Email for initial admin user |
| `ADMIN_NAME` | Display name for initial admin user (default: `Administrator`) |
| `MAIL_TRANSPORT` | `smtp` or `sendmail` |
| `MAIL_FROM_EMAIL` | Sender address (validated against email regex) |
| `MAIL_FROM_NAME` | Sender display name |
| `MAIL_REPLYTO_EMAIL` | Reply-to address (same regex as from) |
| `MAIL_REPLYTO_NAME` | Reply-to display name |
| `MAIL_HOST` | SMTP hostname |
| `MAIL_PORT` | SMTP port (numeric) |
| `MAIL_ENCRYPTION` | `none`, `tls`, or `ssl` |
| `MAIL_SMTPAUTH` | `true` or `false` |
| `MAIL_SMTPAUTOTLS` | `true` or `false` |
| `MAIL_USERNAME` | SMTP auth username |
| `MAIL_PASSWORD` | SMTP auth password (not applied if empty) |
| `MAIL_PREPEND` | Subject-line prefix string |

### CI/CD

Expand Down
25 changes: 25 additions & 0 deletions simplerisk-minimal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,28 @@ docker run -d --name simplerisk -e SIMPLERISK_DB_PASSWORD=pass -e SIMPLERISK_DB_
| `SIMPLERISK_DB_FOR_SESSIONS` | `true` | Indicator that the application will store all sessions on the configured database |
| `SIMPLERISK_DB_SSL_CERT_PATH` | Empty string (`''`) | Path where SSL certificates, to contact the database, are located |
| `SIMPLERISK_CRON_SETUP` | `enabled` | Install the cron job to run in this Docker container |
| `SIMPLERISK_CSRF_SECRET` | Auto-generated | Override the auto-generated CSRF secret |
| `ADMIN_USERNAME` | — | Username for an initial admin user created once during `DB_SETUP`. Requires `ADMIN_PASSWORD` and `ADMIN_EMAIL`. Skipped if the username already exists |
| `ADMIN_PASSWORD` | — | Password for the initial admin user |
| `ADMIN_EMAIL` | — | Email address for the initial admin user |
| `ADMIN_NAME` | `Administrator` | Display name for the initial admin user |

## Mail settings

The following environment variables configure the outbound mail settings stored in the SimpleRisk database (`settings` table). They are applied on every container start, so changing a value and restarting the container is all that is needed to update the configuration. Invalid values are silently skipped with a warning in the container logs.

| Variable Name | Default Value | Purpose |
|:-------------:|:-------------:|:--------|
| `MAIL_TRANSPORT` | — | Transport to use: `smtp` or `sendmail` |
| `MAIL_FROM_EMAIL` | — | Sender email address (must be a valid email) |
| `MAIL_FROM_NAME` | — | Sender display name |
| `MAIL_REPLYTO_EMAIL` | — | Reply-to email address (must be a valid email) |
| `MAIL_REPLYTO_NAME` | — | Reply-to display name |
| `MAIL_HOST` | — | SMTP server hostname |
| `MAIL_PORT` | — | SMTP server port (must be numeric) |
| `MAIL_ENCRYPTION` | — | Encryption method: `none`, `tls`, or `ssl` |
| `MAIL_SMTPAUTH` | — | Whether SMTP authentication is required: `true` or `false` |
| `MAIL_SMTPAUTOTLS` | — | Whether to automatically use TLS: `true` or `false` |
| `MAIL_USERNAME` | — | SMTP authentication username |
| `MAIL_PASSWORD` | — | SMTP authentication password (not applied if empty) |
| `MAIL_PREPEND` | — | Prefix string prepended to all outbound email subjects |
57 changes: 57 additions & 0 deletions simplerisk-minimal/common/docker/configure-admin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
if (php_sapi_name() !== 'cli') { exit(1); }

require_once('/var/www/simplerisk/includes/functions.php');
require_once('/var/www/simplerisk/includes/permissions.php');

$username = getenv('ADMIN_USERNAME') ?: null;
$password = getenv('ADMIN_PASSWORD') ?: null;
$email = getenv('ADMIN_EMAIL') ?: null;
$name = getenv('ADMIN_NAME') ?: 'Administrator';

if (!$username || !$password || !$email) {
fwrite(STDERR, "ADMIN_USERNAME, ADMIN_PASSWORD, and ADMIN_EMAIL are required.\n");
exit(1);
}

$db = db_open();
$stmt = $db->prepare("SELECT COUNT(*) FROM user");
$stmt->execute();
$count = (int)$stmt->fetchColumn();
db_close($db);

if ($count > 0) {
echo "Database already has users, skipping admin user creation.\n";
exit(0);
}

if (get_id_by_user($username)) {
echo "User '{$username}' already exists, skipping.\n";
exit(0);
}

$salt = '';
$values = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));
for ($i = 0; $i < 20; $i++) {
$salt .= $values[array_rand($values)];
}
set_time_limit(120);
$hash = crypt($password, '$2a$15$' . md5($salt));

$user_id = add_user(
'simplerisk',
$username,
$email,
$name,
$salt,
$hash,
[],
1,
1,
0,
0,
0,
get_possible_permission_ids()
);

echo "Admin user '{$username}' created with ID {$user_id}.\n";
107 changes: 107 additions & 0 deletions simplerisk-minimal/common/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,91 @@ set_cron(){
fi
}

apply_mail_setting(){
local db_key="$1" value="$2"
# Escape backslashes then single quotes for a MySQL single-quoted string literal
local escaped
escaped=$(printf '%s' "$value" | sed 's/\\/\\\\/g' | sed "s/'/\\\\'/g")
mysql -u "$SIMPLERISK_DB_USERNAME" \
-p"$SIMPLERISK_DB_PASSWORD" \
-h "$SIMPLERISK_DB_HOSTNAME" \
-P "$SIMPLERISK_DB_PORT" \
"$SIMPLERISK_DB_DATABASE" \
-e "UPDATE settings SET value='${escaped}' WHERE name='${db_key}';" \
|| print_log "mail_settings:warn" "Failed to update ${db_key}"
}

set_mail_settings(){
local email_regex='^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'

# transport: smtp or sendmail
if [ -n "${MAIL_TRANSPORT:-}" ]; then
case "${MAIL_TRANSPORT}" in
smtp|sendmail) apply_mail_setting phpmailer_transport "$MAIL_TRANSPORT" ;;
*) print_log "mail_settings:warn" "MAIL_TRANSPORT='${MAIL_TRANSPORT}' must be 'smtp' or 'sendmail' — skipping" ;;
esac
fi

# email addresses: validate regex
if [ -n "${MAIL_FROM_EMAIL:-}" ]; then
if [[ "${MAIL_FROM_EMAIL}" =~ $email_regex ]]; then
apply_mail_setting phpmailer_from_email "$MAIL_FROM_EMAIL"
else
print_log "mail_settings:warn" "MAIL_FROM_EMAIL is not a valid email address — skipping"
fi
fi

if [ -n "${MAIL_REPLYTO_EMAIL:-}" ]; then
if [[ "${MAIL_REPLYTO_EMAIL}" =~ $email_regex ]]; then
apply_mail_setting phpmailer_replyto_email "$MAIL_REPLYTO_EMAIL"
else
print_log "mail_settings:warn" "MAIL_REPLYTO_EMAIL is not a valid email address — skipping"
fi
fi

# free-form strings
[ -n "${MAIL_FROM_NAME:-}" ] && apply_mail_setting phpmailer_from_name "$MAIL_FROM_NAME"
[ -n "${MAIL_REPLYTO_NAME:-}" ] && apply_mail_setting phpmailer_replyto_name "$MAIL_REPLYTO_NAME"
[ -n "${MAIL_HOST:-}" ] && apply_mail_setting phpmailer_host "$MAIL_HOST"
[ -n "${MAIL_USERNAME:-}" ] && apply_mail_setting phpmailer_username "$MAIL_USERNAME"
[ -n "${MAIL_PREPEND:-}" ] && apply_mail_setting phpmailer_prepend "$MAIL_PREPEND"

# booleans: true or false
if [ -n "${MAIL_SMTPAUTOTLS:-}" ]; then
case "${MAIL_SMTPAUTOTLS}" in
true|false) apply_mail_setting phpmailer_smtpautotls "$MAIL_SMTPAUTOTLS" ;;
*) print_log "mail_settings:warn" "MAIL_SMTPAUTOTLS must be 'true' or 'false' — skipping" ;;
esac
fi

if [ -n "${MAIL_SMTPAUTH:-}" ]; then
case "${MAIL_SMTPAUTH}" in
true|false) apply_mail_setting phpmailer_smtpauth "$MAIL_SMTPAUTH" ;;
*) print_log "mail_settings:warn" "MAIL_SMTPAUTH must be 'true' or 'false' — skipping" ;;
esac
fi

# smtpsecure: none, tls, or ssl
if [ -n "${MAIL_ENCRYPTION:-}" ]; then
case "${MAIL_ENCRYPTION}" in
none|tls|ssl) apply_mail_setting phpmailer_smtpsecure "$MAIL_ENCRYPTION" ;;
*) print_log "mail_settings:warn" "MAIL_ENCRYPTION must be 'none', 'tls', or 'ssl' — skipping" ;;
esac
fi

# port: numeric only
if [ -n "${MAIL_PORT:-}" ]; then
if [[ "${MAIL_PORT}" =~ ^[0-9]+$ ]]; then
apply_mail_setting phpmailer_port "$MAIL_PORT"
else
print_log "mail_settings:warn" "MAIL_PORT must be numeric — skipping"
fi
fi

# password: only applied when non-empty
[ -n "${MAIL_PASSWORD:-}" ] && apply_mail_setting phpmailer_password "$MAIL_PASSWORD"
}

delete_db(){
print_log "db_deletion: prepare" "Performing database deletion"

Expand Down Expand Up @@ -158,6 +243,10 @@ EOSQL" "Was not able to apply settings on database. Check error above. Exiting."
# Update the SIMPLERISK_INSTALLED value
exec_cmd "sed -i \"s/\('SIMPLERISK_INSTALLED', \)'false'/\1'true'/g\" $CONFIG_PATH"

# Create admin user if ADMIN_USERNAME is provided (optional, non-fatal)
# shellcheck disable=SC2015
[ -n "${ADMIN_USERNAME:-}" ] && exec_cmd_nobail "php /docker/configure-admin.php" || print_log "initial_setup:warn" "Admin user creation failed; check output above"

# shellcheck disable=SC2015
[ "${DB_SETUP:-}" = "automatic-only" ] && print_log "initial_setup:info" "Running setup only (automatic-only). Container will be discarded." && exit 0 || true
}
Expand All @@ -176,6 +265,23 @@ unset_variables() {
unset SIMPLERISK_DB_SSL_CERT_PATH
unset SIMPLERISK_CSRF_SECRET
unset SIMPLERISK_CRON_SETUP
unset MAIL_TRANSPORT
unset MAIL_FROM_EMAIL
unset MAIL_FROM_NAME
unset MAIL_REPLYTO_EMAIL
unset MAIL_REPLYTO_NAME
unset MAIL_HOST
unset MAIL_SMTPAUTOTLS
unset MAIL_SMTPAUTH
unset MAIL_USERNAME
unset MAIL_PASSWORD
unset MAIL_ENCRYPTION
unset MAIL_PORT
unset MAIL_PREPEND
unset ADMIN_USERNAME
unset ADMIN_PASSWORD
unset ADMIN_EMAIL
unset ADMIN_NAME
}

_main() {
Expand All @@ -193,6 +299,7 @@ _main() {
[[ "${DB_SETUP:-}" == "delete" ]] && delete_db || true
# shellcheck disable=SC2015
[[ "${DB_SETUP:-}" = automatic* ]] && db_setup || true
set_mail_settings
unset_variables
exec "$@"
}
Expand Down