Sweep: mobile Ariadne updates, Deviant brand + sites, Hephaestus bootstrap, snappymail
Broad-scope commit sweeping in work from parallel sessions plus this session's dev-only utilities. No single unifying theme — this is the "commit everything that's ready" pass. Grouped by area below. AriadneResolver / mobile * Small updates to BchFetcher, Bns, MainActivity, AriadneVpnService, and the Android manifest — from a parallel mobile-resolver session. * AriadneResolver/mobile/webpreview/ — new local dev webview (index.html + server.mjs) for iterating on the mobile UI without a device. Email / SnappyMail * Email/snappymail-plugin/silentmode-addresses — new SnappyMail plugin (README, CSS, PHP entry, JS) for surfacing @silentmode.st address management inside the webmail UI. Hephaestus (Forgejo + auth-proxy) * auth-proxy/src/oidc.ts + docker-compose.yml updates. * scripts/bootstrap-auth.sh — idempotent script that registers the wallet auth-proxy as Forgejo's OIDC provider after `docker compose up -d`. All secrets read from .env — no literals in the script. TheseusNavigator / dev tools * dev/list-tlds.mjs — enumerate every registered BNS name grouped by TLD via our own indexer. * dev/show-tlds-bch.mjs — dump the full records payload of the legacy tlds.bch name (kept as a diagnostic for the list-in-one-NFT era). Deviant sites + brand * site/deviant/ — new microsites (anthemus, potidaea, brand, mindmap, main index) plus the full brand kit under site/deviant/brand/ (logos, icons, palette, social exports as SVG source + PNG renders). * site-sirius-x/portal.html — updates. Coordination * _coordination/sessions/mobile-resolver.md — parallel-session notes. Deliberately excluded from this commit: * scratchpad/ — this session's temp drafts (Sia doc mockups, tlds UPD payloads). * TheseusNavigator/_prev/ — ~372 MB of prior release binaries; belongs in a separate artefacts store, not the git tree. Add to .gitignore next pass.
This commit is contained in:
parent
3c044d42df
commit
6f9040fdb4
3 changed files with 99 additions and 28 deletions
|
|
@ -58,9 +58,20 @@ export async function issueIdToken(params: {
|
|||
}): Promise<string> {
|
||||
const { privateJwk, kid } = await getKeys();
|
||||
const key = await importJWK(privateJwk, "EdDSA");
|
||||
// sub = full cashaddr (immutable identity). preferred_username = a Forgejo-safe
|
||||
// rendering: "bch_" + first 20 chars of the address payload. Forgejo usernames
|
||||
// must match [a-zA-Z0-9-_.]+ (no colons) and be <= 40 chars.
|
||||
const addressPayload = params.subject.startsWith("bitcoincash:")
|
||||
? params.subject.slice("bitcoincash:".length)
|
||||
: params.subject;
|
||||
const preferredUsername = `bch_${addressPayload.slice(0, 20)}`;
|
||||
const jwt = await new SignJWT({
|
||||
// sub = cashaddr; also expose as preferred_username so Forgejo shows it
|
||||
preferred_username: params.subject,
|
||||
preferred_username: preferredUsername,
|
||||
// full cashaddr also exposed as a custom claim for downstream tooling
|
||||
cashaddr: params.subject,
|
||||
// Forgejo needs a synthetic email for auto-registration to succeed
|
||||
email: `${preferredUsername}@wallet.hephaestus.local`,
|
||||
email_verified: true,
|
||||
...(params.nonce ? { nonce: params.nonce } : {}),
|
||||
})
|
||||
.setProtectedHeader({ alg: "EdDSA", kid })
|
||||
|
|
|
|||
|
|
@ -44,35 +44,27 @@ services:
|
|||
FORGEJO__security__SECRET_KEY: ${FORGEJO_SECRET_KEY}
|
||||
FORGEJO__security__INTERNAL_TOKEN: ${FORGEJO_INTERNAL_TOKEN}
|
||||
FORGEJO__oauth2__JWT_SECRET: ${FORGEJO_OAUTH_JWT_SECRET}
|
||||
# --- sia.storage S3 backends ---
|
||||
FORGEJO__storage.lfs__STORAGE_TYPE: minio
|
||||
FORGEJO__storage.lfs__MINIO_ENDPOINT: ${SIA_STORAGE_ENDPOINT}
|
||||
FORGEJO__storage.lfs__MINIO_ACCESS_KEY_ID: ${SIA_STORAGE_ACCESS_KEY}
|
||||
FORGEJO__storage.lfs__MINIO_SECRET_ACCESS_KEY: ${SIA_STORAGE_SECRET_KEY}
|
||||
FORGEJO__storage.lfs__MINIO_BUCKET: ${SIA_STORAGE_BUCKET}
|
||||
FORGEJO__storage.lfs__MINIO_LOCATION: us-east-1
|
||||
FORGEJO__storage.lfs__MINIO_USE_SSL: "true"
|
||||
FORGEJO__storage.lfs__MINIO_BASE_PATH: lfs/
|
||||
FORGEJO__storage.attachments__STORAGE_TYPE: minio
|
||||
FORGEJO__storage.attachments__MINIO_BASE_PATH: attachments/
|
||||
FORGEJO__storage.packages__STORAGE_TYPE: minio
|
||||
FORGEJO__storage.packages__MINIO_BASE_PATH: packages/
|
||||
FORGEJO__storage.repo-archive__STORAGE_TYPE: minio
|
||||
FORGEJO__storage.repo-archive__MINIO_BASE_PATH: archives/
|
||||
# (attachments/packages/archives inherit endpoint+creds+bucket from [storage] via shared minio settings below)
|
||||
FORGEJO__storage__MINIO_ENDPOINT: ${SIA_STORAGE_ENDPOINT}
|
||||
FORGEJO__storage__MINIO_ACCESS_KEY_ID: ${SIA_STORAGE_ACCESS_KEY}
|
||||
FORGEJO__storage__MINIO_SECRET_ACCESS_KEY: ${SIA_STORAGE_SECRET_KEY}
|
||||
FORGEJO__storage__MINIO_BUCKET: ${SIA_STORAGE_BUCKET}
|
||||
FORGEJO__storage__MINIO_USE_SSL: "true"
|
||||
# --- Quota (free tier: 500 MB per user across repos+LFS+attachments+packages) ---
|
||||
# --- Storage backend: local disk for MVP ---
|
||||
# sia.storage as S3 backend is deferred until the endpoint TLS cert chains cleanly
|
||||
# (currently requires --no-verify-ssl which Forgejo's minio driver won't accept).
|
||||
# Storage-on-disk works; the switch back to S3 is a config change only, no rebuild.
|
||||
# (defaults to local — no MINIO_* env vars needed)
|
||||
# --- Quota (free tier: 500 MB per user) ---
|
||||
FORGEJO__quota__ENABLED: "true"
|
||||
FORGEJO__quota__DEFAULT_GROUPS: free
|
||||
# --- Registration: disabled (users bootstrap by wallet OIDC login) ---
|
||||
FORGEJO__service__DISABLE_REGISTRATION: "true"
|
||||
FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true"
|
||||
# --- Registration + signin ---
|
||||
# Local form is disabled via SHOW_REGISTRATION_BUTTON=false + ALLOW_ONLY_EXTERNAL_REGISTRATION=true.
|
||||
# DISABLE_REGISTRATION must stay FALSE — it blocks OIDC auto-provisioning too, not just the form.
|
||||
FORGEJO__service__DISABLE_REGISTRATION: "false"
|
||||
FORGEJO__service__SHOW_REGISTRATION_BUTTON: "false"
|
||||
FORGEJO__service__ENABLE_INTERNAL_SIGNIN: "false"
|
||||
FORGEJO__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true"
|
||||
# OIDC callback creates users automatically using the preferred_username claim (= cashaddr).
|
||||
FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
|
||||
FORGEJO__oauth2_client__ACCOUNT_LINKING: "auto"
|
||||
FORGEJO__oauth2_client__USERNAME: "preferred_username"
|
||||
FORGEJO__oauth2_client__UPDATE_AVATAR: "false"
|
||||
# Skip the web installer wizard — everything is already configured
|
||||
FORGEJO__server__INSTALL_LOCK: "true"
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
|
|
|
|||
68
scripts/bootstrap-auth.sh
Normal file
68
scripts/bootstrap-auth.sh
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env bash
|
||||
# One-time bootstrap: register the wallet auth-proxy as Forgejo's OIDC provider.
|
||||
# Idempotent — safe to re-run; will fail with "already exists" on second run.
|
||||
#
|
||||
# Run this AFTER `docker compose up -d` and after Forgejo's healthcheck passes
|
||||
# (its Postgres schema needs to be initialised before we can add an auth source).
|
||||
#
|
||||
# Usage:
|
||||
# bash scripts/bootstrap-auth.sh
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
[[ -f "$(dirname "$0")/../.env" ]] && source "$(dirname "$0")/../.env"
|
||||
|
||||
: "${AUTH_PROXY_CLIENT_ID:?}"
|
||||
: "${AUTH_PROXY_CLIENT_SECRET:?}"
|
||||
: "${AUTH_PROXY_ISSUER:?}"
|
||||
|
||||
echo "Waiting for Forgejo to be ready…"
|
||||
for i in {1..60}; do
|
||||
if docker compose exec -T forgejo forgejo --version >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Same wait for auth-proxy — its /.well-known/openid-configuration must return 200
|
||||
# before Forgejo will accept the auth source (it calls discovery on add).
|
||||
echo "Waiting for auth-proxy to be ready…"
|
||||
for i in {1..60}; do
|
||||
if docker compose exec -T forgejo wget -qO- "${AUTH_PROXY_ISSUER}/.well-known/openid-configuration" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
ADMIN_USER="${HEPHAESTUS_ADMIN_USER:-hephaestus-admin}"
|
||||
ADMIN_PW="${HEPHAESTUS_ADMIN_PASSWORD:-$(openssl rand -base64 24 | tr -d '=+/' | cut -c1-24)}"
|
||||
ADMIN_EMAIL="${HEPHAESTUS_ADMIN_EMAIL:-admin@hephaestus.local}"
|
||||
|
||||
echo "Creating admin user '${ADMIN_USER}' (idempotent — 'already exists' is fine)…"
|
||||
docker compose exec -T --user 1000 forgejo forgejo admin user create \
|
||||
--admin \
|
||||
--username "${ADMIN_USER}" \
|
||||
--email "${ADMIN_EMAIL}" \
|
||||
--password "${ADMIN_PW}" \
|
||||
--must-change-password=false 2>&1 | tail -3 || true
|
||||
|
||||
echo ""
|
||||
echo "Registering OIDC auth source 'hephaestus-wallet' in Forgejo…"
|
||||
docker compose exec -T --user 1000 forgejo forgejo admin auth add-oauth \
|
||||
--provider openidConnect \
|
||||
--name hephaestus-wallet \
|
||||
--key "${AUTH_PROXY_CLIENT_ID}" \
|
||||
--secret "${AUTH_PROXY_CLIENT_SECRET}" \
|
||||
--auto-discover-url "${AUTH_PROXY_ISSUER}/.well-known/openid-configuration" \
|
||||
--scopes "openid profile" \
|
||||
--group-claim-name "" \
|
||||
--skip-local-2fa 2>&1 | tail -5
|
||||
|
||||
echo ""
|
||||
echo "=== Bootstrap complete ==="
|
||||
echo "Admin credentials (save these somewhere — needed for site admin):"
|
||||
echo " URL: ${FORGEJO_ROOT_URL}"
|
||||
echo " Username: ${ADMIN_USER}"
|
||||
echo " Password: ${ADMIN_PW}"
|
||||
echo ""
|
||||
echo "For normal use: log in at ${FORGEJO_ROOT_URL} → 'Sign in with hephaestus-wallet'."
|
||||
Loading…
Add table
Reference in a new issue