Jake Vanderwerf
2026-02-04 2127b1bdd73ecd2423e443992da4b442f5a3c1a3
inc/managers/LoginManager.php
@@ -1,11 +1,9 @@
<?php
namespace JVBase\managers;
use JVBase\blocks\CustomBlocks;
use JVBase\forms\TaxonomySelector;
use JVBase\meta\MetaManager;
use JVBase\meta\MetaForm;
use JVBase\managers\AjaxRateLimiter;
use JVBase\meta\Form;
use JVBase\utility\Features;
use WP_Error;
use WP_User;
@@ -17,8 +15,8 @@
class LoginManager
{
   protected Features $siteFeatures;
   protected ?MetaForm $metaForm = null;
   protected CacheManager $cache;
   protected ?Form $form = null;
   protected Cache $cache;
   protected array $forms =[];
@@ -43,7 +41,7 @@
      $this->siteFeatures = Features::forSite();
      $this->cache = CacheManager::for('login');
      $this->cache = Cache::for('login');
      // Initialize magic link support if enabled
      if ($this->siteFeatures->has('magicLink')) {
@@ -227,12 +225,14 @@
                  'type' => 'email',
                  'label' => __('Email Address', 'jvb'),
                  'required' => true,
                  'autocomplete' => 'email',
                  'placeholder' => 'look@me.com',
               ],
               'user_password' => [
                  'type' => 'text',
                  'subtype'=> 'password',
                  'label' => __('Password', 'jvb'),
                  'autocomplete' => 'current-password',
                  'required' => true,
               ],
               'remember_me' => [
@@ -316,9 +316,7 @@
   }
   // Add nonce for security
   $logout_url = wp_nonce_url($logout_url, 'log-out');
   return $logout_url;
   return wp_nonce_url($logout_url, 'log-out');
}
   public function getLoginPage():int|false
   {
@@ -401,7 +399,7 @@
   protected function setup():void
   {
      $this->action = $this->getAction();
      if (in_array($this->action, ['logout']) || array_key_exists('loggedout', $_GET)) {
      if ($this->action == 'logout' || array_key_exists('loggedout', $_GET)) {
         wp_logout();
         wp_redirect(esc_attr($_GET['redirect_to'] ?? get_home_url()));
         exit;
@@ -533,7 +531,6 @@
   protected function renderForms():void
   {
      $this->metaForm = new MetaForm();
      $form = $this->action.'form';
      ?>
      <section class="login-box col btw">
@@ -552,7 +549,7 @@
            do_action('jvb_add_token_inputs', $this->action);
            foreach ($this->fields as $name => $config) {
               $this->metaForm->render($name, '', $config);
               echo Form::render($name, '', $config);
            }
            $this->maybeTurnstile();
@@ -861,115 +858,111 @@
      SCRIPTS
   ************************************************************************/
   public function enqueueScripts(): void
   {
      if (!$this->isLoginPage()) {
         return;
      }
{
    if (!$this->isLoginPage()) {
        return;
    }
      $this->maybeTurnstileScripts();
      wp_enqueue_script('jvb-form');
      $action = $this->getAction();
      ob_start();
      ?>
    $this->maybeTurnstileScripts();
    wp_enqueue_script('jvb-form');
    $action = $this->getAction();
document.addEventListener('DOMContentLoaded', async function () {
    $redirect_to = isset($_GET['redirect_to']) ? esc_url_raw($_GET['redirect_to']) : '';
    $has_turnstile = Features::hasIntegration('cloudflare');
    ob_start();
    ?>
   document.addEventListener('DOMContentLoaded', async function () {
      const hasTurnstile = <?= json_encode($has_turnstile) ?>;
      const redirectTo = <?= json_encode($redirect_to) ?>;
      window.auth.subscribe(event => {
         if (event === 'auth-loaded') {
            const form = document.querySelector('.login form');
            if (!form) return;
            if (!form || !window.jvbForm) return;
            if (!window.jvbForm) {
               console.error('jvbForm not loaded');
               return;
            }
            window.LoginController = new window.jvbForm();
            window.LoginController.registerForm(form, {
            window.jvbForm.registerForm(form, {
               autosave: false,
               endpoint: <?= "'{$action}'" ?>,
               endpoint: '<?= $action ?>',
               formStatus: false,
               cache: false,
            });
            window.LoginController.subscribe((event, data) => {
            window.jvbForm.subscribe((event, data) => {
               if (event === 'form-submit') {
                  handleFormSubmission(data);
                  const { config } = data;
                  const formElement = config.element;
                  // Collect current form data
                  const formData = new FormData(formElement);
                  const formObject = Object.fromEntries(formData.entries());
                  // Add redirect_to from URL
                  if (redirectTo) {
                     formObject.redirect_to = redirectTo;
                  }
                  const submit = formElement.querySelector('[type=submit]');
                  const oldText = submit.textContent;
                  window.jvbForm.showFormStatus(config.id, 'uploading');
                  submit.disabled = true;
                  submit.textContent = 'Loading...';
                  window.auth.fetch(`${jvbSettings.api}auth/<?= $action ?>`, {
                     method: 'POST',
                     body: JSON.stringify(formObject)
                  })
                  .then(response => response.json().then(result => ({ response, result })))
                  .then(({ response, result }) => {
                     if (!response.ok) {
                        window.jvbForm.showFormStatus(config.id, 'error');
                        window.jvbForm.handleFormError(formElement, result);
                        return;
                     }
                     window.jvbForm.showFormStatus(config.id, 'submitted');
                     if (result.message) {
                        window.jvbForm.handleFormSuccess(formElement, result);
                     }
                     if (window.auth?.handleLogin && result.auth) {
                        return window.auth.handleLogin(result.auth).then(() => {
                           if (result.redirect) {
                              setTimeout(() => {
                                 window.location.href = result.redirect;
                              }, 100);
                           }
                        });
                     } else if (result.redirect) {
                        setTimeout(() => {
                           window.location.href = result.redirect;
                        }, 100);
                     }
                  })
                  .catch(error => {
                     console.error('Form submission error:', error);
                     window.jvbForm.showFormStatus(config.id, 'error');
                     window.jvbForm.handleFormError(formElement, {
                        message: 'Network error. Please check your connection and try again.',
                        code: 'network_error'
                     });
                  })
                  .finally(() => {
                     submit.textContent = oldText;
                     submit.disabled = false;
                  });
               }
            });
            async function handleFormSubmission(data) {
            let realFormData = data.fullData;
            const { formId, config, data: formData } = data;
            const form = config.element;
            const submit = form.querySelector('[type=submit]');
            let oldText = submit.textContent;
            window.LoginController.showFormStatus(formId, 'uploading');
            try {
               submit.disabled = true;
               submit.textContent = 'Loading...';
               const response = await window.auth.fetch(`${jvbSettings.api}auth/<?php echo $action; ?>`, {
                  method: 'POST',
                  body: JSON.stringify(realFormData)
               });
                  const result = await response.json();
                  // Handle errors
                  if (!response.ok) {
                     window.LoginController.showFormStatus(formId, 'error');
                     window.LoginController.handleFormError(form, result);
                     return;
                  }
                  // Handle success
                  window.LoginController.showFormStatus(formId, 'submitted');
                  // Show success message briefly before redirect
                  if (result.message) {
                     window.LoginController.handleFormSuccess(form, result);
                  }
                  if (window.auth && typeof window.auth.handleLogin === 'function' && Object.hasOwn(result, 'auth')) {
                     console.log('Awaiting Auth...');
                     await window.auth.handleLogin(result.auth); // Pass the full result
                  }
                  // Handle redirect
                  if (result.redirect) {
                     setTimeout(() => {
                        window.location.href = result.redirect;
                     }, 100); // Brief delay to show success message
                  }
               } catch (error) {
                  console.error('Form submission error:', error);
                  window.LoginController.showFormStatus(formId, 'error');
                  window.LoginController.handleFormError(form, {
                     message: 'Network error. Please check your connection and try again.',
                     code: 'network_error'
                  });
               } finally {
                  submit.textContent = oldText;
                  submit.disabled = false;
               }
            }
         }
      });
   });
});
      <?php
   <?php
      $script = ob_get_clean();
      wp_add_inline_script('jvb-form', $script);
   }