# Audit Report: give.charityright.org.uk
**Date:** 9 March 2026  
**Auditor:** Claude Code (automated Playwright audit)  
**Viewport tested:** 1440×900 (desktop), 375×812 (mobile)  
**Entry URL:** https://give.charityright.org.uk → auto-redirects to `/sadaqah`

---

## Overview

`give.charityright.org.uk` is the donation micro-site for Charity Right (UK Charity #1155108). It is a **single-page, campaign-focused donation portal** currently showing a **Sadaqah fundraising page**. The site allows visitors to:

- Select a donation amount (slider + quick-pick buttons, £3–£15 default range)
- Optionally add UK Gift Aid (with house number + postcode collection)
- Complete payment via Stripe (card + Google Pay)
- Share the campaign

**Tech stack clues:**
- Custom server-side rendered (SSR) app — no Vue/React/Next fingerprint detected at root
- Stripe.js v3 for payments
- Cloudflare (CDN, challenge platform, Turnstile/hCaptcha)
- Google Tag Manager (GTM-PX5XJXX)
- TikTok Pixel, Facebook Pixel, Google Analytics (multiple GA4 properties), Hotjar 3395285
- CookieHub for consent management
- WAHA (WhatsApp HTTP API) running at `waha.charityright.org.uk` — separate service, credentials leaked in console (see Security)

---

## Phase 1 — Homepage Audit

### Redirect behaviour
- `/` → `/sadaqah` (permanent or temporary redirect — not a true homepage, no navigation)

### Page title
- ✅ `Give Sadaqah — Charity Right` — clear, descriptive

### Meta tags
| Tag | Value | Issue |
|-----|-------|-------|
| `<meta name="description">` | **MISSING** | ❌ No standard description tag |
| `<meta property="og:title">` | `Give Sadaqah — Charity Right` | ✅ |
| `<meta property="og:description">` | `50p feeds a child. Give Sadaqah in 30 seconds.` | ✅ |
| `<meta property="og:image">` | `https://www.charityright.org.uk/wp-content/uploads/2026/02/cr-wrong-1.jpg` | ⚠️ Cross-domain OG image (WordPress) |
| `<meta name="robots">` | **MISSING** | ⚠️ No robots directives |
| `<meta name="viewport">` | `width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover` | ⚠️ `user-scalable=no` disables pinch-zoom — accessibility violation (WCAG 1.4.4) |

### Console errors on load
- ✅ 0 JS errors on sadaqah page itself
- 1 WARNING: Hotjar refuses to load (detects headless browser user-agent) — benign in production

### Cookie consent
- ✅ CookieHub banner shown on first visit (`dialog "About cookies on this site"`)
- ✅ Three options: "Allow all cookies", "Deny all", "Cookie settings"
- ⚠️ "Cookie settings" link uses `href="#"` (dead anchor) — should be `href` to settings panel or use `button` semantics

---

## Phase 2 — Navigation & Links

The site has **no navigation bar or header menu**. It is a single campaign page only. There are no internal links to other sections of the give site.

**External link found:**
- `https://www.charityright.org.uk/donate/` — links to main website (different domain)

**Routes tested:**

| Path | Result |
|------|--------|
| `/sadaqah` | ✅ 200 — Sadaqah donation page |
| `/zakat` | ❌ 404 — "Not Found" blank page |
| `/fidya` | ❌ 404 — "Not Found" blank page |
| `/qurban` | ❌ 404 — "Not Found" blank page |
| `/kaffarah` | ❌ 404 — "Not Found" blank page |
| `/login` | ❌ 404 — "Not Found" blank page |
| `/register` | ❌ 404 — "Not Found" blank page |
| `/campaigns` | ❌ 404 — "Not Found" blank page |
| `/donate` | ❌ 404 — "Not Found" blank page |
| `/appeal` | ❌ 404 — "Not Found" blank page |

**Key issue:** The 404 page returns **no `<title>`** tag and **no styled error page** — just the raw text "Not Found". There is no redirect to a helpful error page and no way back to a valid URL.

---

## Phase 3 — Donation Flow

### Flow architecture
The site uses an **inline slide-up payment panel** (overlay `div#overlay`) rather than a separate checkout page. This is a smooth UX pattern.

### Step 1: Amount selection
- Slider control: 6 (£6 default, feeds 12 children @ 50p/meal)
- Quick-pick buttons: £3, £6, £9, £12, £15
- ✅ Real-time meal counter updates
- ✅ Clear impact messaging ("Feeds 12 children")

### Step 2: Gift Aid
- ✅ Gift Aid toggle button (pre-selected/enabled by default)
- ✅ Calculates HMRC top-up (£6 → £7.50 total)
- House number + postcode fields appear when Gift Aid active
- ⚠️ **No validation visible** if Gift Aid address fields are left empty when proceeding
- ⚠️ Gift Aid declaration text is small/light — readability concern

### Step 3: "Give £6 Sadaqah" button
- Clicking opens a side/bottom panel (`div#overlay.open`)
- The overlay **blocks interaction** with the main page while open (correct modal behaviour)

### Step 4: Checkout panel ("Complete your Sadaqah")
Fields present:
| Field | Type | Placeholder | Label visible |
|-------|------|-------------|---------------|
| Full name | `textbox` | "As it appears on your card" | ✅ "Full name" |
| Email | `textbox` | "For your donation receipt" | ✅ "Email" |
| Card number | Stripe iframe | "Card number" | ✅ "Number" |
| Expiry | Stripe iframe | "MM / YY" | ✅ |
| CVC | Stripe iframe | "CVC" | ✅ |

- "Donate £6" button is **`disabled` by default** — only enabled when Stripe iframe reports complete card details
- ✅ Correct — prevents empty form submission
- ⚠️ Clicking "Give £6 Sadaqah" without filling name/email still opens the overlay — those fields have **no pre-validation** before opening the panel
- ✅ No `<form>` element (0 forms found) — form data handled entirely via JS/Stripe Elements
- ✅ Google Pay option available in Stripe Elements
- ✅ Trust signals: "🔒 Encrypted · Powered by Stripe" and "256-bit secure · No account needed · UK Charity 1155108"

### Empty form submission
- Donate button stays disabled until Stripe card fields are valid — no empty submit possible via UI
- **No visible validation errors** for empty name/email fields — they appear to be validated client-side by Stripe before enabling the button (TBC)

### Donation amount £1 test
- Minimum selectable via slider unclear (minimum appears to be £3 via preset buttons)
- Manual slider minimum not tested — slider defaults to £6

---

## Phase 4 — Mobile Responsiveness (375×812)

### Layout
- ✅ Page renders correctly at 375×812
- ✅ Same UI elements visible — no hidden/broken sections
- ✅ Campaign image scales correctly
- ✅ Quick-pick amount buttons visible and tappable
- ✅ Gift Aid toggle renders correctly
- ✅ Checkout panel (overlay) renders at mobile size
- ⚠️ `user-scalable=no` in viewport meta means users **cannot zoom** on mobile — this is an accessibility violation for low-vision users
- ⚠️ No hamburger menu (site is single-page, so this is acceptable, but there's no navigation at all)
- ✅ No horizontal scroll detected at 375px width

---

## Phase 5 — Performance & Accessibility

### Accessibility
| Check | Result | Issue |
|-------|--------|-------|
| Images missing `alt` | 0 | ✅ |
| Dead anchors `href="#"` | 1 | ⚠️ Cookie settings button uses `href="#"` |
| Unlabelled inputs | 1 | ⚠️ One input has no `aria-label` or `placeholder` |
| `user-scalable=no` in viewport | YES | ❌ WCAG 1.4.4 violation |
| Inline `onclick` handlers | 3 | ⚠️ 3 elements use inline event handlers |
| No `<nav>` landmark | Confirmed | ⚠️ No navigation landmark (single-page is valid but no skip-to-content) |
| No `<meta name="description">` | Confirmed | ❌ SEO/accessibility issue |

### Performance
- **Page load time:** 2,433ms (performance.timing) — acceptable
- **External scripts loaded:** 9 external `<script src>` tags

**External scripts inventory:**
1. `analytics.tiktok.com` — TikTok Pixel (×3 scripts)
2. `connect.facebook.net` — Facebook Pixel (×2 scripts, including large config JS)
3. `static.hotjar.com` — Hotjar session recording
4. `www.googletagmanager.com` — GTM (×1) + GA4 gtag (×4 separate GA properties!)
5. `cdn.cookiehub.eu` — CookieHub consent
6. `js.stripe.com/v3/` — Stripe.js
7. `googleads.g.doubleclick.net` — Google Ads conversion tracking (×2)

**⚠️ Performance concern:** 4 separate Google Analytics 4 properties (`G-1B4QR9YTTB`, `G-6RGJ9BTW2Q`, `G-4DB6TJNHZR`, `AW-876060108`, `AW-925998688`) + GTM + TikTok + Facebook + Hotjar = **significant tracking script bloat**. Each fires multiple analytics events per page load.

**Network errors (analytics):** Multiple `net::ERR_ABORTED` for analytics.google.com POSTs on page navigation — these appear to be in-flight beacons aborted during navigation (non-critical but noisy).

---

## Phase 6 — Key Pages

| Page | Status | Notes |
|------|--------|-------|
| `/sadaqah` | ✅ 200 | Main and only working page |
| `/zakat` | ❌ 404 | Common Islamic giving category — missing |
| `/fidya` | ❌ 404 | Ramadan-specific — missing |
| `/qurban` | ❌ 404 | Eid-related — missing |
| `/kaffarah` | ❌ 404 | Missing |
| `/login` | ❌ 404 | No user accounts on this domain |
| `/register` | ❌ 404 | No user accounts on this domain |
| `/campaigns` | ❌ 404 | Missing |

The site appears to only have the one `/sadaqah` route currently live. All other paths return bare 404 responses.

---

## Phase 7 — Security

### HTTPS
- ✅ Site is fully HTTPS (`https://give.charityright.org.uk`)
- ✅ Stripe iframe loads over HTTPS
- ✅ No mixed content detected
- ✅ Cloudflare CDN with challenge platform (`cdn-cgi/challenge-platform`)

### Forms
- ✅ No `<form>` elements found — payment handled entirely via Stripe.js (no raw card data hits the server)
- ✅ Stripe tokenisation means card details never touch CharityRight servers

### Cookies
| Cookie | Domain | Secure? | HttpOnly? | Concern |
|--------|--------|---------|-----------|---------|
| `cf_clearance` | `.charityright.org.uk` | ✅ (HTTPS-only session) | N/A | Cloudflare bot protection |
| `__stripe_mid`, `__stripe_sid` | `.give.charityright.org.uk` | ✅ | Unknown | Stripe session — should be HttpOnly |
| `cookiehub` | `.charityright.org.uk` | ✅ | N/A | Consent preferences |
| `_ga`, `_ga_*` | `.charityright.org.uk` | ✅ | N/A | Google Analytics |
| `_fbp` | `.charityright.org.uk` | ✅ | N/A | Facebook Pixel |
| `_ttp` | `.charityright.org.uk` + `.tiktok.com` | ✅ | N/A | TikTok tracking |
| `IDE` | `.doubleclick.net` | ✅ | N/A | Google Ads |

⚠️ `__stripe_mid` and `__stripe_sid` are visible in `document.cookie` — meaning they are **not HttpOnly**. Stripe session cookies should ideally be HttpOnly to prevent XSS token theft (though Stripe sets these itself — CharityRight cannot control this).

### 🚨 CRITICAL: Credentials in Browser Console

**From previous browsing session logs captured in the test environment:**

```
[ERROR] SecurityError: Failed to execute 'replaceState' on 'History': 
A history state object with URL 
'https://waha.charityright.org.uk/dashboard/' cannot be created in a document 
with origin 'https://waha.charityright.org.uk' and URL 
'https://admin:J59vAcWI56BReJEFCi@waha.charityright.org.uk/dashboard/'.
```

**This is a CRITICAL security issue.** The URL `https://admin:J59vAcWI56BReJEFCi@waha.charityright.org.uk/dashboard/` contains **basic authentication credentials in plaintext** (`admin:J59vAcWI56BReJEFCi`). These were captured in the browser's console log, meaning:

1. Anyone with DevTools access to `waha.charityright.org.uk` could see these credentials
2. The credentials are for the WAHA (WhatsApp HTTP API) admin dashboard
3. WAHA controls WhatsApp messaging for the organisation — a breach here could expose donor communications

**Immediate action required:** Change the WAHA admin password and remove credentials from any hardcoded URLs. Use proper session-based auth instead.

### Hub API 401 Errors
Multiple failed requests to `hub.quikcue.com/api/user/*` (401 Unauthorized):
```
GET https://hub.quikcue.com/api/user/lifecycle → 401
GET https://hub.quikcue.com/api/user/admin → 401
GET https://hub.quikcue.com/api/user/init → 401
```
The give.charityright.org.uk site is calling **QuikCue's hub API** on every page load and receiving 401s. These appear to be unauthenticated calls. This could indicate a misconfigured integration or leftover code from a shared codebase.

### Development URL in Production
From console errors: `http://localhost:3000/api/pledges → 400 Bad Request`  
A hardcoded `localhost:3000` URL is being called from production. This is a development/staging configuration leak.

---

## Console Errors Summary

| Error | Source | Severity |
|-------|--------|----------|
| `localhost:3000/api/pledges` returning 400 | Sadaqah page JS | 🔴 High — dev URL in prod |
| `hub.quikcue.com/api/user/*` returning 401 (×8+ times) | Page load | 🟠 Medium — unnecessary failed requests |
| `waha.charityright.org.uk` credentials in URL | WAHA dashboard JS | 🔴 Critical — credential leak |
| `waha.charityright.org.uk/api/*` returning 401 | WAHA dashboard | 🟡 Low — expected if not logged in |
| `give.charityright.org.uk/favicon.ico` returning 404 | Browser | 🟡 Low — missing favicon |
| `analytics.google.com` ERR_ABORTED (×6) | Navigation beacons | 🟢 Info — benign race condition |

---

## Summary Table

| # | Issue | Location | Severity | Category |
|---|-------|----------|----------|----------|
| 1 | **Credentials in URL**: `admin:J59vAcWI56BReJEFCi` in WAHA console error | `waha.charityright.org.uk` | 🔴 **Critical** | Security |
| 2 | **`localhost:3000/api/pledges`** called from production | `/sadaqah` JS | 🔴 **Critical** | Config / Security |
| 3 | **All routes 404** except `/sadaqah` — no error page, no redirect | `/zakat`, `/fidya`, etc. | 🟠 **High** | Navigation |
| 4 | **404 page has no title, no styling, no back link** | All 404 responses | 🟠 **High** | UX |
| 5 | **`hub.quikcue.com` API called 8+ times with 401** on every page load | `/sadaqah` | 🟠 **High** | Performance / Config |
| 6 | **Missing `<meta name="description">`** | All pages | 🟠 **High** | SEO |
| 7 | **`user-scalable=no` in viewport meta** — disables pinch zoom | All pages | 🟠 **High** | Accessibility (WCAG 1.4.4) |
| 8 | **4 separate GA4 properties** + 2 Google Ads + TikTok + Facebook + Hotjar | All pages | 🟡 **Medium** | Performance / Privacy |
| 9 | **No Gift Aid address validation** before proceeding to checkout | `/sadaqah` | 🟡 **Medium** | UX / Data quality |
| 10 | **Name/email not validated** before overlay opens | `/sadaqah` checkout | 🟡 **Medium** | UX |
| 11 | **OG image served from WordPress domain** (`charityright.org.uk/wp-content/`) | `/sadaqah` | 🟡 **Medium** | Reliability / Performance |
| 12 | **No `<meta name="robots">`** directive | All pages | 🟡 **Medium** | SEO |
| 13 | **`href="#"`** on cookie settings anchor | Cookie banner | 🟡 **Medium** | Accessibility |
| 14 | **1 unlabelled input** (no aria-label, no placeholder) | `/sadaqah` | 🟡 **Medium** | Accessibility |
| 15 | **3 inline `onclick` handlers** | `/sadaqah` | 🟡 **Medium** | Code quality |
| 16 | **Hotjar not loading** (detects headless/bot UA) | All pages | 🟡 **Medium** | Analytics |
| 17 | **Missing favicon** (404 on `/favicon.ico`) | All pages | 🟢 **Low** | Branding |
| 18 | **No skip-to-content link** | All pages | 🟢 **Low** | Accessibility |
| 19 | **No `<nav>` landmark** | All pages | 🟢 **Low** | Accessibility |
| 20 | **Stripe session cookies not HttpOnly** | `/sadaqah` | 🟢 **Low** | Security (Stripe-controlled) |

---

## Recommendations (Priority Order)

### 🔴 Immediate (Critical)
1. **Rotate WAHA admin credentials** — `admin:J59vAcWI56BReJEFCi` is exposed in browser console. Change password immediately. Audit who accessed WAHA.
2. **Remove `localhost:3000` URL** from production build — likely a `.env` misconfiguration. The `/api/pledges` call should point to the production API endpoint.

### 🟠 High Priority
3. **Add styled 404 page** with charity branding, navigation back to `/sadaqah`, and proper `<title>`.
4. **Fix `hub.quikcue.com` API calls** — either authenticate them properly or remove them from the give site (wrong codebase/integration).
5. **Add `<meta name="description">`** — currently only `og:description` is set.
6. **Remove `user-scalable=no`** from viewport meta — replace with `user-scalable=yes` to comply with WCAG 1.4.4.

### 🟡 Medium Priority
7. **Audit tracking scripts** — consolidate 4 GA4 properties if possible, remove duplicates. Each extra script adds load time and GDPR surface area.
8. **Validate Gift Aid fields before opening checkout overlay** — show inline error if Gift Aid is enabled but address fields are empty.
9. **Validate name/email before showing checkout overlay** — currently you can open the payment panel without entering name/email.
10. **Move OG image to `give.charityright.org.uk` CDN** — remove cross-domain WordPress dependency.
11. **Replace `href="#"` on Cookie Settings** with proper button element or `href="javascript:void(0)"`.
12. **Fix unlabelled input** — audit the 1 input missing both `aria-label` and `placeholder`.

### 🟢 Low Priority
13. Add favicon to `give.charityright.org.uk`.
14. Add `<meta name="robots" content="index,follow">` explicitly.
15. Add skip-to-content link for keyboard/screen reader users.

---

## Screenshots Captured

| File | Description |
|------|-------------|
| `screenshots/cr-homepage.png` | Full page — sadaqah donation page at 1440×900 |
| `screenshots/cr-donation-form.png` | Full page after clicking "Give £6 Sadaqah" |
| `screenshots/cr-form-filled.png` | Checkout overlay with name/email filled |
| `screenshots/cr-form-ready.png` | Checkout overlay with full card details entered, Donate button enabled |
| `screenshots/cr-overlay-open.png` | Overlay state after form interaction |
| `screenshots/cr-mobile.png` | Full page at 375×812 mobile viewport |
| `screenshots/cr-zakat.png` | 404 page for /zakat |
