Four fixes from a security review pass:
- Neutralise CSV formula injection in the payments export: fields with a
leading =, +, -, @, tab, or CR (e.g. a hostile student display name) are
apostrophe-prefixed in PaymentReport::csvLine() so they open as text in
Excel/Google Sheets. Fixes#39.
- Sanitise policy bodies with wp_kses_post at output in
PolicyEndpoint::index() (the booking JS renders that HTML raw), so a
future write path that forgets kses can never become stored XSS.
Fixes#40.
- Store invite tokens hashed (SHA-256) at rest: a database leak can no
longer redeem pending invites. The registration link is shown once, at
creation; the pending list shows email/invited date; lookups hash the
submitted token. Existing plaintext pending invites must be re-issued.
Fixes#41.
- Validate availability slot datetimes on both creation paths (REST and
admin form) via AvailabilitySlot::normalizeDateTime(): canonical and
datetime-local forms normalise to Y-m-d H:i:s, garbage and end <= start
are rejected (REST 400) instead of reaching the DATETIME column or
throwing inside the weekly-series date arithmetic. Fixes#42.
composer test (204 tests, 594 assertions), PHPStan L6, and PHPCS all green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Studio Settings gains a default HST rate; the rate is frozen onto each
payment at booking and computed against the pre-tax subtotal, with the
total billed as subtotal + tax. The rate is overridable per booking on
My Lessons while unpaid (recomputing the tax amount), comped
registrations are never taxed, and receipts break out subtotal/HST/total.
Builds the payments report (roadmap #8) from us_payments: a monthly
per-instructor view with subtotal, HST collected, and grand-total
aggregation, plus a nonce-protected CSV export via admin-post. Studio
admins see all instructors and can filter; instructors are scoped to
their own rows. The Payment Report menu is gated on export_payments so
instructors (who lack manage_billing) can reach it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update availability, lesson-booking, and user-roles docs and add specs
for offerings, group classes, registration questions, versioned policies,
Stripe payments (with e-transfer/comp overrides and receipts), and
monthly per-instructor payment reporting. Tracked in issues #1-#9.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>