PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 4.0.0
WP 2FA – Two-factor authentication for WordPress v4.0.0
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / assets / js / test-email-new.js
wp-2fa / includes / assets / js Last commit date
customize-styles.js 6 days ago exclude-self-prompt.js 6 days ago intlTelInput-vanilla.js 6 days ago policies-hash-state.js 6 days ago save-policies-new.js 6 days ago save-settings-new.js 6 days ago settings-design-logic.js 6 days ago settings-hash-state.js 6 days ago test-email-new.js 6 days ago wizard-new.js 6 days ago
test-email-new.js
169 lines
1 /**
2 * Test Email (New Settings) — handles [data-check-email-2fa] buttons.
3 *
4 * For each button:
5 * 1. Walk up the DOM to find the closest provider-content (or settings-card).
6 * 2. Look for a TinyMCE editor first, then a plain <textarea> for the body.
7 * 3. Look for an <input[type=text]> for the subject.
8 * 4. POST subject + body to the AJAX endpoint; if no body is found the
9 * server sends a generic delivery-test message.
10 *
11 * Depends on wp2faTestEmail (localized from PHP):
12 * - ajaxUrl, nonce, sendingText, errorText
13 *
14 * @package wp-2fa
15 * @since 2.8.0
16 */
17 ( function () {
18 'use strict';
19
20 /**
21 * Try to read the content of a TinyMCE editor instance whose textarea
22 * lives inside `container`. Returns the HTML string or empty string.
23 */
24 function getTinyMCEContent( container ) {
25 if ( typeof window.tinymce === 'undefined' ) {
26 return '';
27 }
28 var textareas = container.querySelectorAll( 'textarea' );
29 for ( var i = 0; i < textareas.length; i++ ) {
30 var editor = window.tinymce.get( textareas[ i ].id );
31 if ( editor ) {
32 return editor.getContent();
33 }
34 }
35 return '';
36 }
37
38 /**
39 * Find the email body from the closest ancestor that wraps the button.
40 * TinyMCE takes precedence; falls back to a plain <textarea>.
41 */
42 function findBody( button ) {
43 // Walk up to the provider-content, settings-card, or tab-panel.
44 var container = button.closest( '.provider-content' )
45 || button.closest( '.settings-card' )
46 || button.closest( '.tab-panel' )
47 || button.closest( '.settings-page' );
48
49 if ( ! container ) {
50 return '';
51 }
52
53 // 1. TinyMCE
54 var tmceContent = getTinyMCEContent( container );
55 if ( tmceContent ) {
56 return tmceContent;
57 }
58
59 // 2. Plain textarea
60 var textarea = container.querySelector( 'textarea' );
61 if ( textarea && textarea.value.trim() ) {
62 return textarea.value.trim();
63 }
64
65 return '';
66 }
67
68 /**
69 * Find the email subject from the closest ancestor.
70 */
71 function findSubject( button ) {
72 var container = button.closest( '.provider-content' )
73 || button.closest( '.settings-card' )
74 || button.closest( '.tab-panel' )
75 || button.closest( '.settings-page' );
76
77 if ( ! container ) {
78 return '';
79 }
80
81 var input = container.querySelector( 'input[type="text"]' );
82 return input ? input.value.trim() : '';
83 }
84
85 /**
86 * Show a notice next to the button.
87 */
88 function showNotice( button, message, isSuccess ) {
89 // Remove any previous notice on this button.
90 var prev = button.parentNode.querySelector( '.wp2fa-test-email-notice' );
91 if ( prev ) {
92 prev.remove();
93 }
94
95 var notice = document.createElement( 'span' );
96 notice.className = 'wp2fa-test-email-notice';
97 notice.style.cssText = 'display:inline-block;margin-left:10px;padding:4px 10px;border-radius:3px;font-size:13px;'
98 + ( isSuccess
99 ? 'color:#155724;background:#d4edda;border:1px solid #c3e6cb;'
100 : 'color:#721c24;background:#f8d7da;border:1px solid #f5c6cb;' );
101 notice.innerHTML = message;
102
103 button.parentNode.insertBefore( notice, button.nextSibling );
104
105 // Auto-dismiss after 8 seconds.
106 setTimeout( function () {
107 if ( notice.parentNode ) {
108 notice.remove();
109 }
110 }, 8000 );
111 }
112
113 /**
114 * Handle the click.
115 */
116 function onTestEmailClick( e ) {
117 var button = e.target.closest( '[data-check-email-2fa]' );
118 if ( ! button ) {
119 return;
120 }
121 e.preventDefault();
122
123 // Prevent double-clicks.
124 if ( button.disabled ) {
125 return;
126 }
127
128 var originalValue = button.value;
129 button.disabled = true;
130 button.value = wp2faTestEmail.sendingText;
131
132 var body = findBody( button );
133 var subject = findSubject( button );
134
135 var formData = new FormData();
136 formData.append( 'action', 'wp2fa_send_test_email_new' );
137 formData.append( 'nonce', wp2faTestEmail.nonce );
138 formData.append( 'subject', subject );
139 formData.append( 'body', body );
140
141 fetch( wp2faTestEmail.ajaxUrl, {
142 method: 'POST',
143 credentials: 'same-origin',
144 body: formData,
145 } )
146 .then( function ( res ) {
147 return res.json();
148 } )
149 .then( function ( data ) {
150 var msg = ( data && data.data && data.data.message ) ? data.data.message : '';
151 if ( data.success ) {
152 showNotice( button, msg, true );
153 } else {
154 showNotice( button, msg || wp2faTestEmail.errorText, false );
155 }
156 } )
157 .catch( function () {
158 showNotice( button, wp2faTestEmail.errorText, false );
159 } )
160 .finally( function () {
161 button.disabled = false;
162 button.value = originalValue;
163 } );
164 }
165
166 // Event delegation — works for buttons rendered now and in the future.
167 document.addEventListener( 'click', onTestEmailClick );
168 } )();
169