Commit Graph

13 Commits

Author SHA1 Message Date
b5fcb7c14a fix: add Google Fonts domains to CSP policy
Vuexy loads fonts via webfontloader from fonts.googleapis.com and
fonts.gstatic.com. The previous CSP blocked these, causing a white screen.

- style-src: added https://fonts.googleapis.com
- font-src: added https://fonts.gstatic.com
- Removed frame-ancestors from meta tags (ignored in meta, console warnings)

Updated in all three index.html dev meta tags and both Nginx SPA/portal configs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 16:20:51 +02:00
940297f214 security: implement CSP headers (API middleware + Nginx configs + dev meta tags)
API middleware:
- SecurityHeaders now sets Content-Security-Policy from config/security.php
- Default API policy: "default-src 'none'; frame-ancestors 'none'"
- Supports report-only mode via CSP_REPORT_ONLY env var
- Policy value configurable via CSP_POLICY env var

Nginx deployment configs (deploy/nginx/):
- security-headers.conf: shared headers for all server blocks
- csp-api.conf: restrictive JSON-only policy for api.crewli.app
- csp-spa.conf: SPA policy for app/admin (self + unsafe-inline styles)
- csp-portal.conf: portal policy matching SPA

Development:
- CSP meta tags added to all three index.html files
- Includes 'unsafe-inline' + 'unsafe-eval' for Vite HMR/loader script
- Each app allows its own ws:// port for HMR websocket

Resolves security finding A13-9.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 16:14:37 +02:00
513ca519b2 security: migrate auth tokens to httpOnly cookies (hybrid bearer token approach)
Backend:
- CookieBearerToken middleware reads httpOnly cookie and injects Authorization
  header before Sanctum validates (prepended to API middleware group)
- SetAuthCookie trait provides cookie creation/expiry helpers with per-app
  cookie names (crewli_admin_token, crewli_app_token, crewli_portal_token)
- LoginController sets token via Set-Cookie, removes it from JSON body
- LogoutController expires the auth cookie on logout
- AuthRefreshController (POST /auth/refresh) rotates tokens with new cookie
- InvitationController accept also sets token via cookie, not JSON body
- All cookies: httpOnly, SameSite=Strict, Secure (in production)

Frontend (all three SPAs):
- Removed all localStorage token storage (apps/app, apps/portal)
- Removed all JS-readable cookie token storage (apps/admin)
- Removed Authorization: Bearer header interceptors from axios
- Auth stores now rely on GET /auth/me to validate httpOnly cookie
- Admin app: new Pinia auth store replaces useCookie-based auth pattern
- withCredentials: true ensures browser sends cookies automatically

Fixes security findings A13-1 (localStorage tokens) and A13-2 (admin
cookie flags). Tokens are now invisible to JavaScript.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 16:06:44 +02:00
836cffa232 feat: password reset, email change with verification, and password change
Password reset: multi-app support with custom notification linking to correct
frontend (app/portal/admin). Email change: self-service with password
confirmation and admin-initiated, both sending verification to new address
with 24h expiry. Confirmation sent to old email on completion. Password
change: authenticated endpoint revoking other sessions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:38:54 +02:00
b8286d6a84 security: round 4 — frontend hardening (deps, XSS, cookie security)
Vulnerable dependencies upgraded:
- Backend: league/commonmark >=2.8.2 (HTML injection bypass),
  phpunit/phpunit >=11.5.50, laravel/tinker (psysh LPE)
- Frontend: axios 1.13→1.15 (SSRF + metadata exfiltration),
  @casl/ability updated (prototype pollution)
- Removed swiper from all 3 apps (prototype pollution CVE,
  only used in Vuexy demo pages)

XSS vectors removed:
- Deleted Vuexy demo pages with v-html rendering API data:
  help-center/article, academy/course-details
- Deleted all front-pages (landing, pricing, checkout, payment) —
  Vuexy marketing template, not Crewli business logic
- Deleted swiper demo components and views
- Fixed admin main.ts: replaced innerHTML with template literal
  with safe DOM construction using textContent

Cookie security:
- Added SameSite=Strict and Secure flags to admin cookie defaults

Cleanup:
- Removed swiper SCSS from all 3 apps
- Removed swiper custom element config from all 3 vite configs
- Portal localStorage cleanup verified: reset() clears all keys,
  called on both explicit logout and 401 interceptor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 07:15:00 +02:00
1028498705 security: round 1 — quick wins (rate limiting, headers, mass assignment, logging)
- Add throttle middleware to login (5/min), portal/token-auth (10/min),
  volunteer-register (5/min), and invitation routes (10/min)
- Set Sanctum token expiration to 7 days
- Remove billing_status from UpdateOrganisationRequest (super_admin only)
- Revoke all Sanctum tokens on password reset
- Strengthen password rules: min 8 chars, mixed case, numbers
- Create SecurityHeaders middleware (X-Content-Type-Options, X-Frame-Options,
  HSTS, Referrer-Policy, Permissions-Policy)
- Fix open redirect on all 3 login pages (validate ?to= starts with /)
- Set APP_DEBUG=false in .env.example
- Log failed login attempts with email, IP, user-agent
- Log authorization failures (403) with user, IP, path, method
- Harden mass assignment: remove user_id from Person, audit fields from
  ShiftAssignment, system fields from UserInvitation $fillable
- Replace real DB records with factory make() in mail preview routes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 01:34:51 +02:00
ef195a6777 feat(mail): center-align action button in email template
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 00:49:41 +02:00
0d24506c89 feat: consolidate frontend API layer, add query-client, and harden backend Fase 1
Frontend:
- Consolidate duplicate API layers into single src/lib/axios.ts per app
- Remove src/lib/api-client.ts and src/utils/api.ts (admin)
- Add src/lib/query-client.ts with TanStack Query config per app
- Update all imports and auto-import config

Backend:
- Fix organisations.billing_status default to 'trial'
- Fix user_invitations.invited_by_user_id to nullOnDelete
- Add MeResource with separated app_roles and pivot-based org roles
- Add cross-org check to EventPolicy view() and update()
- Restrict EventPolicy create/update to org_admin/event_manager (not org_member)
- Attach creator as org_admin on organisation store
- Add query scopes to Event and UserInvitation models
- Improve factories with Dutch test data
- Expand test suite from 29 to 41 tests (90 assertions)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:35:34 +02:00
fda161ee09 chore: align migrations, docs, and frontends with crewli.app setup
- Replace dated migrations with ordered 2026_04_07_* chain; fold users update into base migration
- Update OrganisationScope, AppServiceProvider, seeders, api routes, and .env.example
- Refresh Cursor rules, CLAUDE.md, Makefile, README, and docs (API, SCHEMA, SETUP)
- Adjust admin/app/portal HTML, packages, api-client, events types, and theme config
- Update docker-compose and VS Code settings; remove stray Office lock files from resources

Made-with: Cursor
2026-04-07 10:45:34 +02:00
5e2ede14b4 fix(admin): index redirect uses auth cookies and Spatie roles
- Gate redirect on userData + accessToken; map org roles to events route
- Keep legacy admin/client role redirects for compatibility
- Rename organizer app HTML title to Event Crew - App
- Add Cursor database rules (ULID, JSON, indexes, soft deletes)

Made-with: Cursor
2026-03-30 10:32:42 +02:00
4cda1c0a92 docs: expand EventCrew README with stack and structure
Sync auto-imports and typed-router generated declarations from Vue tooling.

Made-with: Cursor
2026-03-29 23:27:11 +02:00
1cb7674d52 refactor: align codebase with EventCrew domain and trim legacy band stack
- Update API: events, users, policies, routes, resources, migrations
- Remove deprecated models/resources (customers, setlists, invitations, etc.)
- Refresh admin app and docs; remove apps/band

Made-with: Cursor
2026-03-29 23:19:06 +02:00
34e12e00b3 feat: initial commit - Band Management application 2026-01-06 03:11:46 +01:00