Skip to content

Email-only tenant password reset — Production Readiness ​

FieldValue
ScopeShared-host tenant forgot/reset (/#/forgot-password, /#/reset-password/{token}) resolve workspace from email like login
Date2026-10-06
E2EHeaded Chrome auth.forgot-reset.workflow.spec.ts — passed (validation → unknown email → known email → reset → sign-in, one session). Auth project: forgot/reset smoke passed.

Locked scope ​

Tenant Application password reset on a non-workspace host (app.elosync.com). Customer Portal picker flow and Central forgot-password (no workspace) are out of scope except that Central remains email-only.

Audit report (2026-10-06) ​

IDSeverityFindingResolution
A1HighInitializeTenancy resolved email → tenant only for tenant.auth.login. Forgot/reset on the shared SPA returned workspace_requiredFixed: email resolution also for tenant.auth.forgot-password and tenant.auth.reset-password
A2HighUnknown emails without a workspace leaked workspace_required (account enumeration)Fixed: pass-through + generic success when tenancy is not initialized
A3HighTenant SPA still required a Workspace field when workspace_host_bound is falseRemoved workspace from tenant forgot/reset pages; POST body is { email }
A4MedReset form kept a stale hidden token after HashRouter navigated to a new /reset-password/{token} URLSync token/email from route + query; submit uses the current URL token
A5MedPlaywright auth project did not honour E2E_BROWSER_CHANNEL (headed Chrome missing bundled Chromium)Applied the same channel mapping as the tenant project
A6LowEmpty-login e2e submitted Vite DEV-prefilled credentials instead of validating blank fieldsLoginPage.clearCredentials() before empty submit
A7InfoMobile forgot-password required workspace even though login is email-firstWorkspace is optional; email alone submits
A8HighPassword-reset notifications were ShouldQueue on emails. Local QUEUE_CONNECTION=database had 458 stuck jobs (including resets) with no worker — token created, inbox empty. Central mail provider was also logFixed: tenant / central / portal reset notifications send synchronously in the HTTP request. Ops still need a real mail provider (not log) for inbox delivery; other product mail still uses the emails queue

Verification matrix ​

CheckBackendFrontendDocsMobile
Email-only forgot (known user) sends reset mailPass (Pest)Pass (headed e2e)PassOptional workspace
Unknown email generic success, no workspace_requiredPass (Pest)Pass (headed e2e)PassN/A
Email-only reset + login afterPass (Pest)Pass (headed e2e)PassN/A
Client validation (empty / invalid / mismatch)N/APass (headed e2e)PassN/A
No workspace field on shared-host tenant pagesN/APassPassOptional field
Reset URL token stays in sync on SPA navigationN/APass (A4)PassN/A

Go-live ​

  1. Deploy Backend (InitializeTenancy + ForgotPasswordController generic success + synchronous password-reset notifications).
  2. Deploy Frontend (email-only forgot/reset + reset token URL sync).
  3. Deploy Mobile (optional workspace on forgot-password).
  4. Confirm Central Settings → Mail is a real provider (SMTP / Postmark / Mailgun), not log — log never reaches an inbox.
  5. Smoke https://app.elosync.com/#/forgot-password: no Workspace field; submit email; open reset mail; set password; sign in with email only.
  6. Confirm Customer Portal /#/portal/forgot-password still uses email → company picker (portal emails are not globally unique).

Pest / Playwright ​

  • php artisan test --compact tests/Unit/AuthPasswordResetNotificationSyncTest.php tests/Feature/Tenant/Auth/TenantAuthTest.php tests/Feature/Tenant/Auth/PasswordResetParityTest.php tests/Feature/Tenant/Isolation/TenantIsolationTest.php
  • E2E_BROWSER_CHANNEL=chrome E2E_BASE_URL=http://localhost:5175 npm run test:e2e:auth:headed (or the workflow spec alone)

Official documentation for the EloSync SaaS Platform.