flower
/

review · segments

I've got things deployed currently on our staging server and am looking at the /api/dashboard/login route/login page - what's the user/pass I'm supposed to use here?

codex 1186 events 2 segments staging

segment 1 of 2

Identify dashboard login credentials for staging

Done

The user asked what user/pass to use for /api/dashboard/login on staging. The assistant searched routes, config, controllers, middleware, and views to trace the auth flow. It found that the dashboard uses an email allowlist (DASHBOARD_ADMIN_EMAILS) plus a shared password (DASHBOARD_PASSWORD) from env, not a per-user database login. It also found that if WORDPRESS_LOGGED_IN_KEY and WORDPRESS_LOGGED_IN_SALT are set, a valid WordPress admin session cookie can bypass the form entirely. The assistant reported the source of truth: use an email from the staging allowlist and the shared env password.

outcome

Credentials source identified: DASHBOARD_ADMIN_EMAILS (comma-separated email allowlist) + DASHBOARD_PASSWORD (shared password) from staging .env; WP cookie bypass also possible if configured.

next steps

key decisions

open questions

1 week ago 1 week ago

segment 2 of 2

Diagnose form-action URL mismatch and WP cookie bypass failure

Abandoned

The user reported two issues: (1) the login form posts to /dashboard/login but the app is mounted at /api, so the correct URL should be /api/dashboard/login; (2) WORDPRESS_LOGGED_IN_KEY and WORDPRESS_LOGGED_IN_SALT are set and match the staging Woo environment, but the WP cookie bypass doesn't work. The assistant verified the deployed commit (0457c73) matches local staging HEAD and includes the AuthCookie validator. It traced the form action in login.blade.php (hardcoded /dashboard/login) and the AuthCookie validator logic. It discovered that the validator mirrors older WordPress password-hash assumptions (phpass $P$ prefix), but the sibling Woo checkout runs WordPress 6.8.3 which uses bcrypt password hashes. WordPress changed the cookie pass-fragment rule for bcrypt hashes (uses last 4 chars instead of chars 8-11), so the validator's pass_frag extraction may produce a different HMAC key, causing the cookie to fail validation silently. The assistant also noted that the hardcoded /dashboard/ URLs in routes and views need to be updated to account for the /api mount prefix.

outcome

Two root causes identified: (1) hardcoded /dashboard/ form action and route paths need prefixing to /api/dashboard/; (2) AuthCookie::validateCookie() uses substr($user_pass, 8, 4) for pass_frag, but WordPress 6.8 bcrypt hashes require substr($user_pass, -4), causing HMAC mismatch and silent cookie rejection.

next steps

  • Fix the form action in resources/views/dashboard/login.blade.php from /dashboard/login to /dashboard/login (or use route() helper with named routes)
  • Fix all hardcoded /dashboard/ URLs in views (login.blade.php, index.blade.php, layout.blade.php) to account for the /api mount prefix
  • Update AuthCookie::validateCookie() to handle WordPress 6.8+ bcrypt password hashes by using substr($user_pass, -4) when the hash doesn't start with $P$
  • Consider renaming routes from /dashboard/login to /api/login or /api/dashboard/login for consistency with the mount prefix
  • Test the WP cookie bypass on staging after fixes are deployed

key decisions

  • The AuthCookie validator intentionally reads the raw Cookie header to bypass EncryptCookies middleware, which is correct
  • The shop WordPress sets COOKIEPATH to '/' so the cookie should be sent to /api paths
  • The pass_frag extraction logic must match WordPress's wp_validate_auth_cookie() for the installed WP version

open questions

  • Is the cookie actually being sent by the browser to staging.thedarkroom.com/api/*? (COOKIEPATH=/ should allow it, but needs browser devtools verification)
  • Are the WORDPRESS_LOGGED_IN_KEY and WORDPRESS_LOGGED_IN_SALT on the staging FOS server exactly the same values as on the staging Woo server?
  • Should the dashboard routes be moved under the /api prefix (e.g., /api/dashboard) or should the form action use a relative/route() URL that respects the mount point?

1 week ago 1 week ago