Skip to content

v2.0.0-rc.3: release hardening for develop - #1421

Merged
daveearley merged 1 commit into
developfrom
release/v2.0.0-rc.3
Oct 20, 2026
Merged

daveearley merged 1 commit into
developfrom
release/v2.0.0-rc.3

Conversation

@max-1-max

@max-1-max max-1-max commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

What this does

Gets develop ready to release as v2.0.0-rc.3. It covers everything in develop that isn't in main yet (team access, lineup and homepage sections, settings redesign, saved widgets, first day of week, social and enterprise SSO, API keys) and the app bugs found while checking every help-center article against the code.

Version files are bumped to 2.0.0-rc.3 (VERSION, backend/VERSION, composer.json, package.json).

Changes by area

Security

  • Homepage designer previews only accept settings from the app's own parent frame and send with an explicit target origin. They can't be framed by other sites, and frame protection now matches any letter case or URL encoding of the protected paths.
  • Changing an enterprise SSO connection's issuer, client ID or endpoints requires the client secret again, so the stored secret is never sent to a new provider.
  • Stopping impersonation invalidates the impersonation token.
  • Members who must use SSO are refused before the 2FA prompt. Platform superadmins can't link, sign in through or confirm their identity with an account's company SSO.
  • Saved widgets return a 422 for newly submitted product, category or date ids that aren't on the event. Ids deleted since the last save are dropped, so saving still works.
  • Changing an event's offline payment instructions needs Manage payments and a signed-in session. Re-sending the saved value is always accepted.

Money and capacity

  • Webhook payloads carry full prices regardless of who triggered them.
  • Stripe refunds:
    • A second partial refund of the same amount within 24h goes through.
    • A pending refund stays Refund pending instead of showing as failed.
    • The buyer's refund email is sent once Stripe confirms the refund succeeded.
  • Reactivating a cancelled attendee checks ticket quantity (per date), shared capacity and date capacity, and returns a 422 when there's no room.
  • Struck "was" prices use per-date overrides and the tax-inclusive figure. The cart total rounds per line, as checkout does.
  • The marked-as-paid email attaches the invoice marked Paid.

Product decisions in this PR

  • Date-only picks in end and expiry fields default to 23:59.
  • SSO_BUTTONS_VISIBLE is removed.
  • Active members, the owner included, can connect the account's enterprise SSO connection from Settings → Security. Require SSO no longer signs out or revokes the API keys of members the connection can't sign in, and the Team page and SSO panel agree on who is exempt.
  • The Licence dialog and ee/LICENCE say exactly what keeps working after a lapse.
  • POST /events/{id}/attendees/{public_id}/check_in is marked deprecated in the API reference. Its behaviour is unchanged, except that a check-out of a never-checked-in attendee returns 409 instead of 500.

Messaging and webhooks

  • "Send as test" only emails the sender, for every recipient type, sends immediately, and stays a test after review.
  • Composing without recipients asks for them. "Message Attendees" from a ticket keeps the ticket selected.
  • Webhook deliveries are queued on the webhook queue and retried (3 tries). Payloads over 120 KB are sent inline once, as before, so queued messages stay well under SQS's 256 KB limit.

Operators and config

  • Queue batching and failed jobs default to the pgsql connection, which fixes 500s on the all-in-one image. The all-in-one compose passes DB_CONNECTION and APP_API_RATE_LIMIT_PER_MINUTE.
  • APP_CDN_URL is read through config, so it works with config:cache.
  • The organizer "attendee self-service by default" setting saves.
  • backend/VERSION is kept in sync by scripts/set-version.sh.
  • Pure-logic E2E unit specs run on every PR in a stack-less job.
  • The spam-check content hash is unchanged for events whose content hasn't changed, so deploying doesn't re-scan every live event.

Product areas

  • Lineup and schedule:
    • The stage grid no longer stacks overlapping slots or cuts off titles.
    • The "now" line shows only on today.
    • Recurring events with the schedule hidden show the right performers per date.
    • Imports lock only the lineup, not the event row that checkout uses.
  • Homepage sections:
    • Server errors show readable messages.
    • Section and sponsor limits are explained.
    • Long words and URLs wrap.
    • Anonymisation scrubs organizer section text.
  • Widgets:
    • Events-list embeds keep host aff/promo_code/utm_* parameters.
    • Lineup and schedule dialogs stay visible in short embeds.
    • Not-found widgets render without hydration errors.
    • /widget/* sends X-Robots-Tag: noindex.
  • Settings and team:
    • The date and time fields no longer squeeze two-column forms.
    • Viewers no longer hit dead ends, grey empty cells or a reload loop.
    • Members with no last name, and the owner, can be edited.
  • Accessibility:
    • Dialogs and drawers return focus when closed, including those opened from row menus.
    • Controls have names.
    • Drag-and-drop announcements are translated.
  • API reference: valid OpenAPI 3.1 with no lint errors. IntegrationApiReferenceTest guards against duplicate operationIds and invalid tuple schemas.
  • Translations: every new string is translated in every locale. Broken placeholders in es, fr, pt, pt-br, vi, zh-cn, zh-hk and sk are fixed.

API and behaviour changes to note in the release

  • offline_payment_instructions changes need Manage payments and a session: API keys and Organizer-role members get a 422 when the value would change.
  • The legacy attendee check_in endpoint is deprecated.
  • Webhooks are now at-least-once with retries. Receivers should de-duplicate on event_type, the payload id and event_sent_at.
  • The Stripe refund email depends on Stripe refund webhooks, so self-hosted installs without them stop sending it.
  • /auth/sso/providers no longer returns buttons_visible.
  • Additive fields:
    • price_before_discount_including_taxes_and_fees on public product prices
    • schedule_days on public lineup entries (recurring events only)
    • is_checked_in on attendees in the public order payload
    • meta.linkable_connections on GET /users/me/sso-identities

How it was tested

  • Backend Unit suite: 2,177 pass, also with no database reachable, as CI runs it. It was 2,074 on develop.
  • Backend Feature suite: 1,376 pass. It was 1,185 on develop.
  • E2E on the hermetic stack, images built from this tree: self-hosted lane 801 passed, SaaS lane 783 passed. Three specs needed updates, and they now pass in both modes: one asserted the old behaviour of reactivating an attendee onto a cancelled date, which is now refused, and two pressed Escape before focus had reached the dialog.
  • E2E pure-logic unit specs: 149 pass.
  • npx tsc --noEmit: 36 errors, the same set as develop, none new.
  • pint --test passes on every changed PHP file.
  • api-reference:export and scramble:analyze are clean, and Redocly lint reports 0 errors.
  • Every UI fix was checked in headless Chromium at 390, 768 and 1440px on the dev stack.

Fixes, tests and decisions for everything in develop that is not yet in
main (team access, lineup and homepage sections, settings redesign, saved
widgets, first day of week, SSO, API keys, enterprise SSO in ee), plus the
app bugs found while auditing the help center.

Security
- Homepage previews only accept settings from the app's own parent frame and
  can't be framed by other sites; frame protection matches any letter case
  or URL encoding of the protected paths.
- Changing an enterprise SSO connection's issuer, client or endpoints needs a
  new client secret, so the stored one is never sent to a new provider.
- Stopping impersonation invalidates the impersonation token.
- SSO-enforced members are refused before the 2FA prompt; platform
  superadmins can't link, sign in through or confirm identity with an
  account's company SSO.
- Saved widgets reject newly submitted ids that aren't on the event.
- Offline payment instructions need Manage payments and a session to change.

Money and capacity
- Webhook payloads keep full prices whoever triggers them.
- A second partial Stripe refund of the same amount goes through; a pending
  refund stays Refund pending instead of failed; the refund email is sent
  once Stripe confirms success.
- Reactivating a cancelled attendee checks ticket, shared and date capacity.
- Struck "was" prices use per-date overrides and the tax-inclusive figure;
  the cart total rounds per line like checkout.
- The marked-as-paid email attaches the paid invoice.

Product decisions
- Version 2.0.0-rc.3.
- Date-only picks in end and expiry fields default to 23:59.
- SSO_BUTTONS_VISIBLE removed.
- Active members, the owner included, can link the account's enterprise
  connection; Require SSO no longer signs out or revokes keys of members the
  connection can't sign in.
- Licence lapse copy and ee/LICENCE describe what keeps working.
- The legacy attendee check_in API endpoint is deprecated.

Messaging, webhooks and config
- "Send as test" only ever emails the sender and sends immediately.
- Webhook deliveries are queued and retried; payloads too large to queue are
  sent inline once.
- Queue batching and failed jobs default to pgsql; APP_CDN_URL is read via
  config; the organizer attendee self-service default saves.

Plus lineup, schedule, homepage section, widget, settings and accessibility
fixes, a valid OpenAPI 3.1 reference, and translations for every locale.
Backend tests go from 3,259 to 3,553 and E2E tests from 601 to 784.
@railway-app

railway-app Bot commented Oct 20, 2026

Copy link
Copy Markdown

This PR was not deployed automatically as @max-1-max does not have access to the Railway project.

In order to get automatic PR deploys, please add @max-1-max to your workspace on Railway.

@github-actions

Copy link
Copy Markdown
Contributor

✅ E2E smoke tests: Everything passed.

Mode Result ✅ Passed ❌ Failed ⚠️ Flaky ⏭️ Skipped ⏱️ Duration
Self-hosted ✅ Passed 111 0 0 0 3m 44s

Open the run

@daveearley
daveearley merged commit 43d2f5c into develop Oct 20, 2026
10 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants