Add daily-digest Phase A: per-package SMTP send + admin test endpoint (v0.1.0:75)
Groundwork for the daily activity digest: give the CRM an outbound mail path. Today nothing leaves the box (Gmail capture + drafts only), so this adds a dedicated, per-package SMTP account independent of any StartOS system-wide SMTP. - configureDigestSmtp Start9 action: writes host/port/from/username/password/ security to /data/secrets/smtp/* (password piped over stdin, never argv/env; per-field files, owner-only) — mirrors the setAnthropicApiKey pattern. - docker_entrypoint.sh reads those at boot and exports SMTP_* (operator env wins). - backend/smtp_send.py: stdlib smtplib wrapper reading SMTP_* (one code path for dev .env and the box); starttls/tls/none modes. - POST /api/admin/digest/test-email (admin-only): proves the pipe. Recipients are restricted to the active-admin set — an arbitrary `to` is rejected, so the endpoint is not an open relay; send failures are logged, not echoed (an SMTP auth error can carry the credential). - Tests: test_smtp_send.py (sender), test_smtp_endpoint.py (gating + relay restriction + no-leak). 18/18 backend green; s9pk typechecks. Analysis/summarization for the digest body (Phase B) will run on Spark, never Claude — the digest is deliberately un-anonymized. Decisions + Phase B plan in ROADMAP.md.
This commit is contained in:
@@ -69,6 +69,28 @@ elif [ -z "${ANTHROPIC_API_KEY:-}" ]; then
|
||||
echo "[entrypoint] Architect: no API key yet (drop it at $ANTHROPIC_KEY_FILE to enable thesis generation)"
|
||||
fi
|
||||
|
||||
# ── Daily-digest SMTP (per-package custom mailbox) ──────────────
|
||||
# The CRM emails a daily activity digest. Credentials come from the "Configure
|
||||
# Digest SMTP" StartOS action, which writes one file per field under
|
||||
# $SECRETS_DIR/smtp. We read them back here (plain cat — never eval) and export
|
||||
# SMTP_* for the server process. Each value is read only if not already set in
|
||||
# the service environment, so an operator override still wins. Self-disabling
|
||||
# until host is present (the digest mailer reports "not configured").
|
||||
SMTP_DIR="$SECRETS_DIR/smtp"
|
||||
if [ -z "${SMTP_HOST:-}" ] && [ -f "$SMTP_DIR/host" ]; then
|
||||
export SMTP_HOST="$(cat "$SMTP_DIR/host")"
|
||||
export SMTP_PORT="${SMTP_PORT:-$(cat "$SMTP_DIR/port" 2>/dev/null || echo 587)}"
|
||||
export SMTP_FROM="${SMTP_FROM:-$(cat "$SMTP_DIR/from" 2>/dev/null || true)}"
|
||||
export SMTP_USERNAME="${SMTP_USERNAME:-$(cat "$SMTP_DIR/username" 2>/dev/null || true)}"
|
||||
export SMTP_PASSWORD="${SMTP_PASSWORD:-$(cat "$SMTP_DIR/password" 2>/dev/null || true)}"
|
||||
export SMTP_SECURITY="${SMTP_SECURITY:-$(cat "$SMTP_DIR/security" 2>/dev/null || echo starttls)}"
|
||||
echo "[entrypoint] Digest SMTP: configured (host $SMTP_HOST)"
|
||||
elif [ -n "${SMTP_HOST:-}" ]; then
|
||||
echo "[entrypoint] Digest SMTP: using SMTP_HOST from the service environment"
|
||||
else
|
||||
echo "[entrypoint] Digest SMTP: not configured (use the Configure Digest SMTP action)"
|
||||
fi
|
||||
|
||||
# ── Phase-0 ingest / retrieval env ──────────────────────────────
|
||||
# These are consumed by the ingest pipeline (backend/ingest/) and the MCP
|
||||
# server (backend/mcp/) — NOT by the CRM web server, which ignores them.
|
||||
|
||||
Reference in New Issue
Block a user