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: 11 additions & 6 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ jobs:
run: |
set -euo pipefail

required_client_id="$EXPECTED_CLIENT_ID"
configured_expected_client_id="${EXPECTED_CLIENT_ID:-}"
if [ -z "$configured_expected_client_id" ]; then
echo "::error::Missing required secret WEBAPP_EXPECTED_CLIENT_ID"
exit 1
fi
base_url=$(node -e 'const u = new URL(process.env.WEBHOOK_URL); console.log(`${u.protocol}//${u.host}`)')
auth_url="${base_url}/api/auth/discord"
auth_config_url="${base_url}/api/health/auth-config"
Expand Down Expand Up @@ -248,20 +252,21 @@ jobs:
'
)"

expected_client_id="$(echo "$expected_values" | sed -n '1p')"
auth_config_client_id="$(echo "$expected_values" | sed -n '1p')"
expected_redirect_uri="$(echo "$expected_values" | sed -n '2p')"

if [ -z "$expected_client_id" ] || [ -z "$expected_redirect_uri" ]; then
if [ -z "$auth_config_client_id" ] || [ -z "$expected_redirect_uri" ]; then
echo "::error::Unable to derive OAuth expectations from auth-config payload"
exit 1
fi

if [ "$expected_client_id" != "$required_client_id" ]; then
echo "::error::Auth-config client_id does not match WEBAPP_EXPECTED_CLIENT_ID"
echo "::error::expected=$required_client_id actual=$expected_client_id"
if [ "$auth_config_client_id" != "$configured_expected_client_id" ]; then
echo "::error::Auth-config client_id (${auth_config_client_id}) does not match WEBAPP_EXPECTED_CLIENT_ID secret"
exit 1
fi

expected_client_id="$configured_expected_client_id"

echo "==> Running OAuth redirect contract smoke check: $auth_url"

for attempt in $(seq 1 18); do
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- GitGuardian incident hardening: removed hardcoded compose PostgreSQL password
fallbacks, enforced secret-managed expected client-id checks in deploy OAuth
smoke validation, and replaced secret-like literals in test/example fixtures
- Deploy workflow OAuth smoke now fails fast when
`WEBAPP_EXPECTED_CLIENT_ID` is missing and reports explicit auth-config
client-id mismatches.
- Bundle-size CI workflow now exports `YOUTUBE_DL_SKIP_DOWNLOAD=true` (with
workflow token) so `youtube-dl-exec` postinstall no longer fails on anonymous
GitHub API rate limits during `npm ci`
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,9 @@ See `.env.example` for all available options. Key variables:
| `REDIS_HOST` | No | Redis host (default: localhost) |
| `WEBAPP_ENABLED` | No | Enable web dashboard (default: false) |
| `WEBAPP_SESSION_SECRET` | No | Session encryption key |
| `WEBAPP_REDIRECT_URI` | No | Explicit Discord OAuth callback URL (must match Discord app settings and deploy smoke contract); fallback callback source when `WEBAPP_BACKEND_URL` is unset |
| `WEBAPP_EXPECTED_CLIENT_ID` | No | Expected Discord app client id for `/api/health/auth-config` mismatch detection when explicitly set |
| `WEBAPP_BACKEND_URL` | No | Public backend/API origin used as canonical host for backend links and bot Last.fm connect links (must be an absolute HTTP(S) URL; recommended production canonical: `https://lucky-api.lucassantana.tech`) |
| `WEBAPP_REDIRECT_URI` | No | Explicit Discord OAuth callback URL (must match Discord app settings and deploy smoke contract) |
| `WEBAPP_EXPECTED_CLIENT_ID` | No | Expected Discord app client id for `/api/health/auth-config` mismatch detection when explicitly set (recommended via deployment secret) |
| `WEBAPP_BACKEND_URL` | No | Public backend/API origin used for backend links and bot Last.fm connect links (must be an absolute HTTP(S) URL; recommended: `https://lucky-api.lucassantana.tech`) |
| `CLIENT_SECRET` | No | Discord OAuth secret (for dashboard) |
| `SENTRY_DSN` | No | Error tracking |

Expand Down
Loading