Skip to content

Feature/inline login hooks#913

Merged
superdav42 merged 3 commits intomainfrom
feature/inline-login-hooks
Apr 22, 2026
Merged

Feature/inline login hooks#913
superdav42 merged 3 commits intomainfrom
feature/inline-login-hooks

Conversation

@superdav42
Copy link
Copy Markdown
Collaborator

@superdav42 superdav42 commented Apr 22, 2026

Summary by CodeRabbit

  • Refactor
    • Enhanced inline login flows with improved error handling and support for add-on functionality.

superdav42 and others added 2 commits April 22, 2026 13:42
The inline-login flow in checkout.js previously read and reset reCAPTCHA /
hCaptcha / Cap token inputs directly, coupling the core plugin to specific
captcha providers. Replace that with generic wp.hooks extension points so
any addon can participate in the lifecycle:

* wu_inline_login_data (filter) — augment the AJAX request payload
  (e.g. append captcha tokens)
* wu_inline_login_success (action) — react to a successful login
* wu_inline_login_error (action) — react to a failed login
  (e.g. reset a captcha widget)
* wu_inline_login_prompt_ready (action) — initialize widgets once
  the prompt container is live in the DOM

The captcha addon now hooks these instead of relying on hardcoded
selectors and a window.wuCaptchaResetInlineLogin global.

Supersedes #901.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a Promise-collecting pre-submission hook so addons can perform
async work (like solving an invisible captcha) before the inline
login AJAX request is built.

Matches the existing `wu_before_form_submitted` pattern — addons push
promises into the filter array; core awaits `Promise.all(...)` before
proceeding. If any promise rejects, the error message is surfaced to
the user and the request is aborted.

This fixes a timing race where invisible reCAPTCHA / hCaptcha / Cap
widgets had not yet populated their token input by the time the user
clicked Submit on the inline login prompt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • assets/js/checkout.min.js is excluded by !**/*.min.js

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e85c6f4a-341f-41f0-9c8f-2e7177f02caf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The inline login flow in the checkout process is refactored to support asynchronous addon operations and extensible payload construction through WordPress-style hooks. The implementation now uses async/await patterns, runs pre-submission filters, removes client-side captcha harvesting, and allows payload manipulation via filters before submission, with success and failure actions emitted throughout.

Changes

Cohort / File(s) Summary
Inline Login Async Refactoring
assets/js/checkout.js
Converted handle_inline_login and handleLogin to async functions; added wu_before_inline_login_submitted filter with Promise.all for pre-submission validation; removed captcha token harvesting; introduced wu_inline_login_data filter for extensible payload construction; added wu_inline_login_success and wu_inline_login_error hook actions; new wu_inline_login_prompt_ready action fires when handlers attach.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With async hops and filter flows,
The login path extensibly grows,
Hooks now whisper what to do,
Addons dance in payload's queue,
No captcha caught, just pure delight—
Our promises all resolve just right! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feature/inline login hooks' directly reflects the main change: refactoring inline login flows to support async addon work and extensible payload building via WordPress hooks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/inline-login-hooks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
assets/js/checkout.js (1)

1251-1270: ⚠️ Potential issue | 🟠 Major

Handle success: false AJAX responses in the inline login callback.

The handle_inline_login() PHP handler returns wp_send_json_error() responses with HTTP 200 status, which jQuery's AJAX success callback receives. The current code checks if (results.success) but lacks an else block, so invalid credentials silently clear logging_in without displaying an error or firing wu_inline_login_error.

Proposed fix
 	this.request('wu_inline_login', login_data, function(results) {
 
 		that.logging_in = false;
 
 		if (results.success) {
 
 			/**
 			 * Fires when an inline login attempt succeeds.
 			 *
 			 * `@param` {Object} results    The AJAX success response.
 			 * `@param` {string} field_type The field type ('email' or 'username').
 			 */
 			hooks.doAction('wu_inline_login_success', results, field_type);
 
 			// Login successful - reload page to show logged-in state
 			window.location.reload();
+			return;
 
 		}
+
+		that.login_error = results.data && results.data.message
+			? results.data.message
+			: (wu_checkout.i18n.login_failed || 'Login failed. Please try again.');
+
+		hooks.doAction('wu_inline_login_error', results, field_type);
 
 	}, function(error) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/checkout.js` around lines 1251 - 1270, The AJAX success callback
for this.request('wu_inline_login', ...) currently only handles results.success
true and ignores wp_send_json_error responses; update the callback to add an
else branch for when results.success is false that resets that.logging_in (if
needed), fires the existing hook hooks.doAction('wu_inline_login_error',
results, field_type) and surfaces the error to the user (reusing the same
UI/error handling used in the error callback or the page's inline-login error
display) so invalid credentials are not silently dropped; reference the AJAX
handler handle_inline_login and ensure behavior mirrors the error callback path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/js/checkout.js`:
- Around line 1224-1233: When the Promise.all of
hooks.applyFilters('wu_before_inline_login_submitted', [], field_type) rejects
the catch block currently sets this.logging_in and this.login_error but does not
emit the failure hook; call the same failure handler used by the nested prompt
path (emit the 'wu_inline_login_error' hook or invoke the existing handleError
path) with the error and field_type so addons can reset captcha/widgets, then
preserve the existing this.logging_in=false and return false behavior. Ensure
you reference the rejection from
hooks.applyFilters('wu_before_inline_login_submitted', [], field_type) and emit
'wu_inline_login_error' (or call handleError) with err and field_type before
returning.

---

Outside diff comments:
In `@assets/js/checkout.js`:
- Around line 1251-1270: The AJAX success callback for
this.request('wu_inline_login', ...) currently only handles results.success true
and ignores wp_send_json_error responses; update the callback to add an else
branch for when results.success is false that resets that.logging_in (if
needed), fires the existing hook hooks.doAction('wu_inline_login_error',
results, field_type) and surfaces the error to the user (reusing the same
UI/error handling used in the error callback or the page's inline-login error
display) so invalid credentials are not silently dropped; reference the AJAX
handler handle_inline_login and ensure behavior mirrors the error callback path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 77291f7d-f0fa-4d01-9a83-ecf6aa7f6fe7

📥 Commits

Reviewing files that changed from the base of the PR and between cd31442 and 7dd536b.

⛔ Files ignored due to path filters (1)
  • assets/js/checkout.min.js is excluded by !**/*.min.js
📒 Files selected for processing (1)
  • assets/js/checkout.js

Comment thread assets/js/checkout.js
Comment on lines +1224 to 1233
try {

if (hcaptcha_token) {
login_data[ 'h-captcha-response' ] = hcaptcha_token;
}
await Promise.all(hooks.applyFilters('wu_before_inline_login_submitted', [], field_type));

} catch (err) {

this.logging_in = false;
this.login_error = (err && err.message) ? err.message : (wu_checkout.i18n.login_failed || 'Login failed. Please try again.');
return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Emit the failure hook when pre-submit work rejects.

This failure path sets login_error but skips wu_inline_login_error, so addons that reset captcha/widgets on login failure will not run for rejected wu_before_inline_login_submitted promises. The nested prompt path already routes this through handleError.

Proposed fix
 	} catch (err) {
 
 		this.logging_in = false;
-		this.login_error = (err && err.message) ? err.message : (wu_checkout.i18n.login_failed || 'Login failed. Please try again.');
+		this.login_error = (err && err.message) ? err.message : (wu_checkout.i18n.login_failed || 'Login failed. Please try again.');
+		hooks.doAction('wu_inline_login_error', {
+			data: {
+				message: this.login_error,
+			},
+			originalError: err,
+		}, field_type);
 		return false;
 
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/checkout.js` around lines 1224 - 1233, When the Promise.all of
hooks.applyFilters('wu_before_inline_login_submitted', [], field_type) rejects
the catch block currently sets this.logging_in and this.login_error but does not
emit the failure hook; call the same failure handler used by the nested prompt
path (emit the 'wu_inline_login_error' hook or invoke the existing handleError
path) with the error and field_type so addons can reset captcha/widgets, then
preserve the existing this.logging_in=false and return false behavior. Ensure
you reference the rejection from
hooks.applyFilters('wu_before_inline_login_submitted', [], field_type) and emit
'wu_inline_login_error' (or call handleError) with err and field_type before
returning.

@superdav42
Copy link
Copy Markdown
Collaborator Author

Closing — this PR has merge conflicts with the base branch. If the linked issue is still open, a worker will be dispatched to re-attempt with a fresh branch.

Closed by deterministic merge pass (pulse-wrapper.sh).

@superdav42 superdav42 closed this Apr 22, 2026
@superdav42 superdav42 reopened this Apr 22, 2026
@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@github-actions
Copy link
Copy Markdown

Performance Test Results

Performance test results for b09ea53 are in 🛎️!

Note: the numbers in parentheses show the difference to the previous (baseline) test run. Differences below 2% or 0.5 in absolute values are not shown.

URL: /

Run DB Queries Memory Before Template Template WP Total LCP TTFB LCP - TTFB
0 41 37.83 MB 909.50 ms (+59.50 ms / +7% ) 162.50 ms (-5.50 ms / -3% ) 1114.50 ms (+24.00 ms / +2% ) 2084.00 ms 2005.70 ms 85.85 ms
1 56 49.03 MB 894.00 ms (-54.50 ms / -6% ) 144.50 ms (-7.50 ms / -5% ) 1042.00 ms (-60.00 ms / -6% ) 2028.00 ms (-50.00 ms / -2% ) 1950.25 ms (-49.85 ms / -3% ) 77.55 ms

@superdav42 superdav42 merged commit 7823b1a into main Apr 22, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant