201 lines
6.2 KiB
Markdown
201 lines
6.2 KiB
Markdown
# Production 403 Errors - Root Cause & Fix
|
|
|
|
## Diagnosis Summary
|
|
|
|
**Issue:** All API endpoints returning 302 redirects to Pangolin authentication page
|
|
**Root Cause:** Pangolin tunnel resources configured with authentication enabled (should be "Not Protected")
|
|
**Status:** CORS configuration ✅ FIXED | Pangolin resources ❌ NEEDS MANUAL FIX
|
|
|
|
---
|
|
|
|
## What Was Fixed
|
|
|
|
### ✅ CORS Configuration (COMPLETED)
|
|
|
|
**File:** `/home/bunker-admin/changemaker.lite/.env`
|
|
|
|
**Changes applied:**
|
|
```bash
|
|
# Changed from development to production
|
|
NODE_ENV=production
|
|
|
|
# Added production domain to CORS whitelist
|
|
CORS_ORIGINS=http://app.betteredmonton.org,https://app.betteredmonton.org,http://localhost:3000,http://localhost
|
|
```
|
|
|
|
**API container restarted:** ✅ Done
|
|
|
|
---
|
|
|
|
## What Still Needs Manual Fix
|
|
|
|
### ❌ Pangolin Resource Authentication (REQUIRES MANUAL ACTION)
|
|
|
|
**Problem:** Resources are configured with authentication, causing 302 redirects to auth page.
|
|
|
|
**Evidence:**
|
|
```bash
|
|
$ curl -I https://api.betteredmonton.org/api/health
|
|
HTTP/2 302
|
|
location: https://pangolin.bnkserve.org/auth/resource/68488f80-b055-41ea-bc1b-0ab905fb8a53?redirect=...
|
|
```
|
|
|
|
**Fix Required:** Change authentication setting for ALL Pangolin resources to "Not Protected"
|
|
|
|
---
|
|
|
|
## Step-by-Step Fix Instructions
|
|
|
|
### 1. Log in to Pangolin Dashboard
|
|
|
|
URL: https://api.bnkserve.org (remove `/v1` from API URL)
|
|
|
|
### 2. Navigate to Resources
|
|
|
|
Dashboard → **Resources** → **Public**
|
|
|
|
### 3. Edit Each Resource
|
|
|
|
For EACH of these critical resources:
|
|
- ✅ **app.betteredmonton.org** (Admin GUI + Public Pages)
|
|
- ✅ **api.betteredmonton.org** (Main API)
|
|
- ✅ **media.betteredmonton.org** (Media API)
|
|
- db.betteredmonton.org (NocoDB)
|
|
- docs.betteredmonton.org (MkDocs)
|
|
- code.betteredmonton.org (Code Server)
|
|
- git.betteredmonton.org (Gitea)
|
|
- n8n.betteredmonton.org (n8n)
|
|
- grafana.betteredmonton.org (Grafana)
|
|
- listmonk.betteredmonton.org (Listmonk)
|
|
- qr.betteredmonton.org (Mini QR)
|
|
- home.betteredmonton.org (Homepage)
|
|
|
|
**Most critical (fix these first):**
|
|
1. **api.betteredmonton.org** - Main API (all endpoints fail without this)
|
|
2. **app.betteredmonton.org** - Admin GUI (login page won't work)
|
|
3. **media.betteredmonton.org** - Media API (video library features)
|
|
|
|
### 4. Change Authentication Setting
|
|
|
|
For each resource:
|
|
1. Click **Edit** (pencil icon)
|
|
2. Find **Authentication** or **Access Policy** section
|
|
3. Change from **"Protected"** or **"Authenticated"** to:
|
|
- **"Not Protected"** OR
|
|
- **"Public Access"** OR
|
|
- **"No Authentication"**
|
|
(exact wording depends on Pangolin UI version)
|
|
4. Click **Save**
|
|
|
|
### 5. Verify Fix
|
|
|
|
After changing authentication settings, test each endpoint:
|
|
|
|
**Test API:**
|
|
```bash
|
|
curl https://api.betteredmonton.org/api/health
|
|
# Expected: {"status":"healthy","checks":{"database":"ok","redis":"ok"}}
|
|
# NOT: 302 redirect
|
|
```
|
|
|
|
**Test Public Campaigns:**
|
|
```bash
|
|
curl https://api.betteredmonton.org/api/campaigns/public
|
|
# Expected: JSON array of campaigns
|
|
# NOT: 302 redirect
|
|
```
|
|
|
|
**Test Admin GUI:**
|
|
Visit https://app.betteredmonton.org in browser
|
|
- Should see login page
|
|
- NO redirect to Pangolin auth page
|
|
|
|
---
|
|
|
|
## Why This Happened
|
|
|
|
1. **Pangolin resources default to "Protected"** - requires manual change to "Not Protected"
|
|
2. **Manual setup process** - automated setup was removed, so resources must be configured manually
|
|
3. **No API enforcement** - Pangolin API doesn't enforce "Not Protected" when creating resources programmatically
|
|
|
|
---
|
|
|
|
## Resource Configuration Reference
|
|
|
|
**Correct settings for ALL resources:**
|
|
- **Protocol:** HTTPS (SSL enabled)
|
|
- **Target:** nginx:80 (all services route through nginx)
|
|
- **Authentication:** **Not Protected** ← THIS IS CRITICAL
|
|
- **SSL/TLS:** Enabled
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Still seeing 302 redirects after changing settings?
|
|
|
|
1. **Clear browser cache** - old redirects may be cached
|
|
2. **Try incognito/private window**
|
|
3. **Wait 30-60 seconds** - Pangolin may need time to update routing
|
|
4. **Check resource status** - ensure resource shows as "Active" in Pangolin dashboard
|
|
5. **Verify target** - should point to `nginx:80` (not individual service ports)
|
|
|
|
### API works locally but not via tunnel?
|
|
|
|
Confirm:
|
|
- [ ] Newt container is running: `docker compose ps newt`
|
|
- [ ] Newt logs show connection: `docker compose logs newt --tail 50`
|
|
- [ ] PANGOLIN_SITE_ID, PANGOLIN_NEWT_ID, PANGOLIN_NEWT_SECRET are set in .env
|
|
- [ ] Nginx is running: `docker compose ps nginx`
|
|
|
|
### Health endpoint works but other endpoints fail?
|
|
|
|
Check in this order:
|
|
1. Test public endpoints (no auth): `/api/campaigns/public`, `/api/shifts/public`
|
|
2. Test protected endpoints with valid JWT: `/api/campaigns`, `/api/users`
|
|
3. Check auth store in browser DevTools: localStorage should have `auth-storage` with tokens
|
|
4. Verify JWT secrets haven't changed (would invalidate existing tokens)
|
|
|
|
---
|
|
|
|
## Post-Fix Verification Checklist
|
|
|
|
After changing Pangolin resource authentication to "Not Protected":
|
|
|
|
- [ ] Health endpoint returns JSON (not 302): `curl https://api.betteredmonton.org/api/health`
|
|
- [ ] Public campaigns endpoint works: `curl https://api.betteredmonton.org/api/campaigns/public`
|
|
- [ ] Admin GUI loads: visit https://app.betteredmonton.org
|
|
- [ ] Login works: can authenticate with admin credentials
|
|
- [ ] Campaign management page loads data (no console errors)
|
|
- [ ] Representative lookup functions
|
|
- [ ] Public campaign page accessible: https://app.betteredmonton.org/campaigns
|
|
- [ ] Map page loads: https://app.betteredmonton.org/map
|
|
- [ ] Shifts page works: https://app.betteredmonton.org/shifts
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
**What was done:**
|
|
1. ✅ Updated `.env` with production CORS origins
|
|
2. ✅ Set NODE_ENV to production
|
|
3. ✅ Restarted API container
|
|
4. ✅ Verified API works locally
|
|
|
|
**What you need to do:**
|
|
1. ❌ Log in to Pangolin dashboard at https://api.bnkserve.org
|
|
2. ❌ Edit each resource and set Authentication to "Not Protected"
|
|
3. ❌ Verify endpoints no longer return 302 redirects
|
|
4. ❌ Test application is fully functional
|
|
|
|
**Time estimate:** 5-10 minutes to update all 12 resources
|
|
|
|
---
|
|
|
|
## Contact
|
|
|
|
If you encounter issues after following these steps:
|
|
- Check Pangolin documentation: https://pangolin.bnkserve.org/docs (if available)
|
|
- Review Newt container logs: `docker compose logs newt`
|
|
- Verify nginx routing: `docker compose logs nginx | grep betteredmonton.org`
|