feat: add encrypted settings, guided Stripe setup, and admin credentials page

Store API keys and secrets encrypted in the SQLite database via the
existing Vault module (AES-256-GCM). The only external dependency is
SECRET_KEY_BASE — everything else lives in the portable DB file.

- Add encrypted_value column to settings table with new "encrypted" type
- Add put_secret/get_secret/delete_setting/secret_hint to Settings context
- Add Secrets module to load encrypted config into Application env at startup
- Add Stripe.Setup module with connect/disconnect/verify_api_key flow
  - Auto-creates webhook endpoints via Stripe API in production
  - Detects localhost and shows Stripe CLI instructions for dev
- Add admin credentials page at /admin/settings with guided setup:
  - Not configured: single Secret key input with dashboard link
  - Connected (production): status display, webhook info, disconnect
  - Connected (dev): Stripe CLI instructions, manual signing secret input
- Remove Stripe env vars from dev.exs and runtime.exs
- Fix CSSCache test startup crash (handle_continue instead of init)
- Add nav link for Credentials page

507 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-07 17:12:53 +00:00
parent ff1bc483b9
commit eede9bb517
15 changed files with 829 additions and 19 deletions

View File

@@ -103,9 +103,17 @@ defmodule SimpleshopTheme.Theme.CSSCache do
write_concurrency: false
])
# Warm the cache on startup
warm()
{:ok, %{}, {:continue, :warm}}
end
{:ok, %{}}
@impl true
def handle_continue(:warm, state) do
try do
warm()
rescue
_ -> :ok
end
{:noreply, state}
end
end