Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
8c8bc45
initial commit: add setup for better-auth
JacksonMeade Dec 29, 2025
877ba7d
feat: create auth client
JacksonMeade Dec 29, 2025
ffb4026
feat: add better auth and strip out old apis
JacksonMeade Dec 30, 2025
efb50bd
fix: cut out dj registry API
JacksonMeade Dec 30, 2025
86ac68a
fix: clean up comments and bad variable names
JacksonMeade Dec 30, 2025
176b2f8
fix: reinstate onboarding and settings flow
JacksonMeade Dec 31, 2025
5b6bc9e
feat: add organization-specific utilities
JacksonMeade Dec 31, 2025
7215546
fix: update admin roster to properly use better auth
JacksonMeade Dec 31, 2025
ae36f16
feat: use string for user ID
JacksonMeade Dec 31, 2025
bbddd77
fix: routing
JacksonMeade Jan 16, 2026
3e31875
fix: add experience toggling to accounts
JacksonMeade Jan 16, 2026
d38ca8b
fix: now playing widget background color
JacksonMeade Jan 17, 2026
c8c140e
feat: implement reset password form
JacksonMeade Jan 17, 2026
8abd28b
feat: implement onboarding
JacksonMeade Jan 18, 2026
9d7d9e6
fix: promotions
JacksonMeade Jan 18, 2026
5870f59
fix: remove debug logging
JacksonMeade Jan 18, 2026
814065f
chore: clean up typescript compilation errors
JacksonMeade Jan 18, 2026
d7ca282
test: port auth test suites to Better Auth
Jan 27, 2026
90f4fec
docs: add local development setup and environment documentation
Jan 27, 2026
1b3918c
fix: use nodejs_compat_v2 for Better Auth compatibility
Jan 27, 2026
104956b
fix: update login form tests for Better Auth changes
Jan 27, 2026
ed57c5c
test: add comprehensive E2E authentication tests with CI/CD
Jan 27, 2026
56c166c
fix: resolve TypeScript errors in test fixtures
Jan 27, 2026
318ace8
fix: resolve E2E test failures with improved page objects and selectors
Jan 27, 2026
bf2761e
fix: sync package-lock.json with playwright dependencies
Jan 27, 2026
77f6425
fix: resolve TypeScript errors in unit tests
Jan 27, 2026
1d75482
fix: use longer BETTER_AUTH_SECRET in E2E workflow (min 32 chars)
Jan 27, 2026
87e8440
fix: add build step before setup:e2e-users in E2E workflow
Jan 27, 2026
7ebfe9a
fix: add BETTER_AUTH_JWKS_URL to E2E workflow
Jan 27, 2026
5144517
fix: specify playwright config path in test:e2e scripts
Jan 27, 2026
a77c759
fix: escape heredoc to prevent $1100 interpolation
Jan 27, 2026
698c1da
perf: implement session reuse in E2E tests
Jan 27, 2026
14def5e
fix: use __dirname for consistent auth storage path
Jan 27, 2026
22e6734
fix: expand testDir to include auth.setup.ts for setup project
Jan 27, 2026
091f2cf
fix: add missing imports in admin test files
Jan 27, 2026
bcf1457
fix: remove --project flag to allow setup dependency to run
Jan 28, 2026
9a98e52
fix: improve auth setup error handling and ensure .auth directory exists
Jan 28, 2026
53f905c
fix: reduce retries and timeout to avoid CI time limit
Jan 28, 2026
8d78064
fix: resolve E2E test failures for logout and page navigation
Jan 28, 2026
4b058f3
fix: resolve E2E test failures and fix admin password reset API
Jan 29, 2026
4c44a3f
fix: use organization member roles instead of user roles for role man…
Jan 29, 2026
0745e52
fix: improve toast assertion in demote MD to DJ test
Jan 29, 2026
a46c194
fix: use separate DJ2 session for RBAC tests to avoid logout conflicts
Jan 29, 2026
eb3d765
fix: run auth setup tests sequentially to avoid concurrency issues
Jan 29, 2026
fa455a9
fix: improve E2E test reliability with serial mode and storageState
Jan 29, 2026
572ce6e
feat: improve E2E test stability and coverage
Jan 29, 2026
2f055c6
test: skip flaky E2E tests and add adminReset1 user
Jan 29, 2026
1ce45a5
fix: re-enable session navigation E2E tests
Jan 29, 2026
fbfb77f
fix: wait for refetch before releasing role change spinner state
Jan 29, 2026
4a885ca
fix: use setUserPassword API for admin password reset
Jan 29, 2026
8b58676
fix: improve incomplete user detection for onboarding redirect
Jan 29, 2026
3500f61
fix: add validation for required fields when creating user
Jan 29, 2026
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
81 changes: 81 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
lint-and-typecheck:
name: Lint & Type Check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Type check
run: npx tsc --noEmit

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Run unit tests
run: npm run test:run

- name: Upload coverage
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-report
path: coverage/
retention-days: 7

build:
name: Build
runs-on: ubuntu-latest
env:
NEXT_PUBLIC_BACKEND_URL: http://localhost:8080
NEXT_PUBLIC_BETTER_AUTH_URL: http://localhost:8082/auth
NEXT_PUBLIC_DASHBOARD_HOME_PAGE: /dashboard/flowsheet
NEXT_PUBLIC_VERSION: ci
NEXT_PUBLIC_DEFAULT_EXPERIENCE: modern
NEXT_PUBLIC_ENABLED_EXPERIENCES: modern,classic
NEXT_PUBLIC_ALLOW_EXPERIENCE_SWITCHING: "true"
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build
187 changes: 187 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
name: E2E Tests

on:
push:
branches: [main, new-authentication-provider]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
backend_ref:
description: 'Backend-Service branch/tag to use'
required: false
default: 'main'

env:
# Frontend configuration
NEXT_PUBLIC_BACKEND_URL: http://localhost:8085
NEXT_PUBLIC_BETTER_AUTH_URL: http://localhost:8084/auth
NEXT_PUBLIC_DASHBOARD_HOME_PAGE: /dashboard/flowsheet
NEXT_PUBLIC_VERSION: e2e
NEXT_PUBLIC_DEFAULT_EXPERIENCE: modern
NEXT_PUBLIC_ENABLED_EXPERIENCES: modern,classic
NEXT_PUBLIC_ALLOW_EXPERIENCE_SWITCHING: "true"
NEXT_PUBLIC_ONBOARDING_TEMP_PASSWORD: temppass123
SESSION_SECRET: e2e-secret-for-testing
APP_ORGANIZATION_ID: test-org-id-0000000000000000001
# E2E test config
E2E_BASE_URL: http://localhost:3000
# Backend service ports (E2E profile)
E2E_DB_PORT: 5434
E2E_AUTH_PORT: 8084
E2E_BACKEND_PORT: 8085

jobs:
e2e:
name: E2E Tests
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- name: Checkout dj-site
uses: actions/checkout@v4
with:
path: dj-site

- name: Checkout Backend-Service
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/Backend-Service
ref: ${{ github.event.inputs.backend_ref || 'main' }}
path: Backend-Service
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: |
dj-site/package-lock.json
Backend-Service/package-lock.json

- name: Create Backend .env file
working-directory: Backend-Service
run: |
cat > .env << 'EOF'
DB_HOST=localhost
DB_PORT=5434
DB_NAME=wxyc_db
DB_USERNAME=wxyc_admin
DB_PASSWORD='RadioIsEpic$1100'
BETTER_AUTH_SECRET=e2e-auth-secret-for-testing-min-32-chars
BETTER_AUTH_URL=http://localhost:8084/auth
BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000
FRONTEND_SOURCE=http://localhost:3000
DEFAULT_ORG_SLUG=test-org
DEFAULT_ORG_NAME=Test Organization
APP_ORGANIZATION_ID=test-org-id-0000000000000000001
E2E_DB_PORT=5434
E2E_AUTH_PORT=8084
E2E_BACKEND_PORT=8085
EOF

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Start backend services with Docker Compose
working-directory: Backend-Service
run: |
# Build and start E2E services
docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e up -d e2e-db

# Wait for database to be ready
echo "Waiting for database..."
timeout 60 bash -c 'until docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e exec -T e2e-db pg_isready; do sleep 2; done'

# Run database initialization
docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e up e2e-db-init

# Start auth and backend services
docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e up -d e2e-auth e2e-backend

# Wait for services to be healthy
echo "Waiting for auth service..."
timeout 120 bash -c 'until curl -sf http://localhost:8084/healthcheck; do sleep 5; done'

echo "Waiting for backend service..."
timeout 120 bash -c 'until curl -sf http://localhost:8085/healthcheck; do sleep 5; done'

- name: Install Backend-Service dependencies
working-directory: Backend-Service
run: npm ci

- name: Build Backend-Service workspaces
working-directory: Backend-Service
run: npm run build

- name: Set up E2E test users
working-directory: Backend-Service
env:
DB_HOST: localhost
DB_PORT: 5434
DB_NAME: wxyc_db
DB_USERNAME: wxyc_admin
DB_PASSWORD: 'RadioIsEpic$1100'
BETTER_AUTH_JWKS_URL: http://localhost:8084/auth/.well-known/jwks.json
run: |
# Wait a moment for services to fully stabilize
sleep 5
npm run setup:e2e-users

- name: Install dj-site dependencies
working-directory: dj-site
run: npm ci

- name: Install Playwright browsers
working-directory: dj-site
run: npx playwright install --with-deps chromium

- name: Build dj-site
working-directory: dj-site
run: npm run build

- name: Start dj-site
working-directory: dj-site
run: |
npm run start &

# Wait for frontend to be ready
echo "Waiting for frontend..."
timeout 60 bash -c 'until curl -sf http://localhost:3000; do sleep 2; done'

- name: Run E2E tests
working-directory: dj-site
run: npm run test:e2e -- --reporter=html --reporter=github

- name: Show service logs on failure
if: failure()
working-directory: Backend-Service
run: |
echo "=== Auth Service Logs ==="
docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e logs e2e-auth --tail=100
echo ""
echo "=== Backend Service Logs ==="
docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e logs e2e-backend --tail=100

- name: Upload Playwright report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: dj-site/playwright-report/
retention-days: 30

- name: Upload test results
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-results
path: dj-site/test-results/
retention-days: 7

- name: Cleanup
if: always()
working-directory: Backend-Service
run: |
docker compose -f dev_env/docker-compose.yml --env-file .env --profile e2e down -v --remove-orphans
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

# testing
/coverage
/test-results/
/playwright-report/
/playwright/.cache/

# next.js
/.next/
Expand Down Expand Up @@ -39,3 +42,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
e2e/.auth
e2e/.e2e-ports
e2e/.djsite.log
e2e/.djsite.pid
67 changes: 65 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,75 @@ The revised catalog leverages services defined in `api-service.js`, which utiliz
- Github Pages: For hosting the frontend and automating publication.
- Axios: A JavaScript library used for making HTTP requests to the AWS API Gateway.

## Local Development Prerequisites

The frontend requires the WXYC Backend-Service to be running locally for full functionality. Without the backend:
- Authentication will not work
- API calls (flowsheet, library, etc.) will fail
- Most features will be unavailable

**Option 1: Manual Setup**
1. Clone and start [Backend-Service](https://github.com/WXYC/Backend-Service) following its Quick Start guide
2. Ensure both backend (:8080) and auth (:8082) services are running
3. Continue with frontend setup below

**Option 2: Automated Setup**
Use the setup script from [wxyc-shared](https://github.com/WXYC/wxyc-shared) to automatically configure the entire stack.

## Installation and Setup
1. Clone the repository: `git clone https://github.com/WXYC/dj-site.git`
2. Navigate to the project directory: `cd dj-site`
3. Install dependencies: `npm install`
4. Run the application: `npm run dev`
5. Access the application locally: Open your web browser and visit `http://localhost:3000`
4. Create `.env.local` with required environment variables (see below)
5. Run the application: `npm run dev`
6. Access the application locally: Open your web browser and visit `http://localhost:3000`

## Environment Variables

Create a `.env.local` file in the project root with the following variables:

```bash
# Backend API URL (required)
NEXT_PUBLIC_BACKEND_URL=http://localhost:8080

# Better Auth service URL (required for authentication)
NEXT_PUBLIC_BETTER_AUTH_URL=http://localhost:8082/auth

# Default page after login
NEXT_PUBLIC_DASHBOARD_HOME_PAGE=/dashboard/flowsheet

# UI Experience settings
NEXT_PUBLIC_DEFAULT_EXPERIENCE=modern
NEXT_PUBLIC_ENABLED_EXPERIENCES=modern,classic
NEXT_PUBLIC_ALLOW_EXPERIENCE_SWITCHING=true
```

### Environment Variable Reference

| Variable | Required | Description |
|----------|----------|-------------|
| `NEXT_PUBLIC_BACKEND_URL` | Yes | Backend API base URL |
| `NEXT_PUBLIC_BETTER_AUTH_URL` | Yes | Auth service URL (must end with `/auth`) |
| `NEXT_PUBLIC_DASHBOARD_HOME_PAGE` | No | Redirect path after login |
| `NEXT_PUBLIC_DEFAULT_EXPERIENCE` | No | Default UI theme (`modern` or `classic`) |
| `NEXT_PUBLIC_ENABLED_EXPERIENCES` | No | Comma-separated list of available themes |
| `NEXT_PUBLIC_ALLOW_EXPERIENCE_SWITCHING` | No | Enable theme switching in UI |

## Authentication Flow

The application uses [Better Auth](https://www.better-auth.com/) for authentication, running as a separate service within Backend-Service.

**How it works:**
1. User submits credentials on the login page
2. Frontend sends request to Better Auth service (`NEXT_PUBLIC_BETTER_AUTH_URL`)
3. Better Auth validates credentials against the PostgreSQL database
4. On success, Better Auth returns a JWT token stored in an HTTP-only cookie
5. Subsequent API requests include the token automatically
6. Backend validates tokens via JWKS endpoint

**Test credentials** (local development):
- Username: `test_member`, `test_dj1`, `test_dj2`, `test_music_director`, or `test_station_manager`
- Password: `testpassword123`

## Testing

Expand Down
Loading
Loading