diff --git a/license.txt b/license.txt index 597ee70..9d92405 100644 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2024 Userfront Inc. +Copyright (c) 2024 Userfront Inc. (https://userfront.com/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/readme.txt b/readme.txt index 9129b20..1660a3c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,13 +1,113 @@ === Userfront Auth === -Tags: authentication, authorization, security, user, account, roles, email, password, multi-factor, single sign-on, social, passwordless, mfa, 2fa, sso, oauth2, openid, saml +Tags: auth, roles, social, sso, mfa Tested up to: 6.6.2 Requires at least: 6.6.2 Requires PHP: 7.4 License: MIT License URI: https://github.com/userfront/wordpress/blob/main/license.txt -Stable tag: 1.2.0 +Stable tag: 1.2.3 Contributors: userfront +Userfront is a premier auth & identity platform. Install full-fledged authentication and authorization with 2FA/MFA and OAuth to WordPress within minutes. + == Description == -Userfront is a premier auth & identity platform. Install full-fledged authentication and authorization with 2FA/MFA and OAuth to WordPress within minutes. \ No newline at end of file +This plugin replaces standard WordPress login forms with one powered by [Auth0](https://auth0.com) that enables: + +- **Universal authentication** + - Over 30 social login providers + - Enterprise connections (ADFS, Active Directory / LDAP, SAML, Office 365, Google Apps and more) + - Connect your own database + - Passwordless connections (using email or SMS) +- **Ultra secure** + - Multifactor authentication + - Password policies + - Email validation + - Mitigate brute force attacks + +== Installation == + +This plugin requires a [free or paid](https://auth0.com/pricing) Auth0 account. + +1. [Sign up here](https://auth0.com/signup). +2. Follow the [installation instructions here](https://auth0.com/docs/cms/wordpress/installation). + +== Technical Notes == + +**IMPORTANT**: By using this plugin you are delegating the site authentication and profile handling to Auth0. That means that you won't be using the WordPress database to authenticate users and the default WordPress login forms will be replaced. + +Please see our [How It Works page](https://auth0.com/docs/cms/wordpress/how-does-it-work) for more information on how Auth0 authenticates and manages your users. + += Migrating Existing Users = + +Auth0 allows multiple authentication providers. You can have social providers like Facebook, Twitter, Google+, and more, a database of users and passwords (just like WordPress but hosted in Auth0), or you can use an Enterprise directory like Active Directory, LDAP, Office365, Google Apps, or SAML. All those authentication providers might give you an email and a flag indicating whether the email was verified or not. We use that email (only if it is verified) to associate a previous **existing** user with the one coming from Auth0. + +If the email was not verified and there is an account with that email in WordPress, the user will be presented with a page saying that the email was not verified and a link to "Re-send the verification email." For either scenario, you can choose whether it is mandatory that the user has a verified email or not in the plugin settings. + +**Please note:** In order for a user to log in using Auth0, they will need to sign up via the Auth0 login form (or have an account created for them in Auth0). Once signup is complete, their Auth0 user will be automatically associated with their WordPress user. + += Widget = + +You can enable Auth0 as a WordPress widget in order to show it in a sidebar. The widget inherits the main plugin settings but can be overridden with its own settings in the widget form. Note: this form will not display for logged-in users. + += Shortcode = + +Also, you can use the Auth0 widget as a shortcode in your editor. Just add the following to use the global settings: + + [auth0] + +Like widgets, shortcode login forms will use the settings of the plugin. It can be customized by adding the following attributes: + +- `icon_url` - A direct URL to an image used at the top of the login form +- `form_title` - Text to appear at the top of the login form +- `gravatar` - Display the user's Gravatar; set to `1` for yes +- `redirect_to` - A direct URL to use after successful login +- `dict` - Valid JSON to override form text ([see options here](https://github.com/auth0/lock/blob/master/src/i18n/en.js)) +- `extra_conf` - Valid JSON to override Lock configuration ([see options here](https://auth0.com/docs/libraries/lock/v11/configuration)) +- `show_as_modal` - Display a button that triggers the login form in a modal; set to `1` for yes +- `modal_trigger_name` - Button text to display when using a modal + +Example: + + [auth0 show_as_modal="1" modal_trigger_name="Login button: This text is configurable!"] + +Note: this form will not display for logged-in users. + +== Frequently Asked Questions == + += Can I customize the Auth0 login form? = + +The Auth0 login form is called Lock and it's [open source on GitHub](https://github.com/auth0/lock). You can style the form like any of your site components by enqueuing a stylesheet in your theme. Use the [`login_enqueue_scripts`](https://developer.wordpress.org/reference/hooks/login_enqueue_scripts/) hook to style the form on wp-login.php, [`wp_enqueue_scripts`](https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/) to style widgets and shortcodes, or both to affect the form in all locations. + += Can I access the user profile information? = + +The Auth0 plugin transparently handles login information for your WordPress site and the plugins you use, so that it looks like any other login. User profile data changes in WordPress **are not** currently sent to Auth0 but changes to the Auth0 user account **are** stored in WordPress user meta (under the key `auth0_obj` prefixed with `$wpdb->prefix`). + += When I install this plugin, will existing users still be able to log in? = + +Yes, either by allowing the WordPress login form to be displayed or through migrating existing users. See the **Technical Notes** section above. + += What authentication providers do you support? = + +Please see our [complete list of supported social and enterprise authentication providers](https://auth0.com/docs/identityproviders). + += How can I use Lock configuration options that are not provided on the settings page? = + +Use the "Extra Settings" field on the plugin settings' **Advanced** tab to add a JSON object with all additional configurations. For more information on what else can be configured, see the [documentation](https://auth0.com/docs/libraries/lock/v11/configuration). + += Is this plugin compatible with WooCommerce? = + +Yes, this plugin will override the default WooCommerce login forms with the Auth0 login form. + += My question is not covered here ... what do I do? = + +All is not lost! + +* If you're setting up the plugin for the first time or having issues with users logging in, please review our [troubleshooting](https://auth0.com/docs/cms/wordpress/troubleshoot) and [configuration](https://auth0.com/docs/cms/wordpress/configuration) documentation. +* If you found a bug in the plugin code, please [submit an issue](https://github.com/auth0/wp-auth0/issues) or [create a pull request](https://github.com/auth0/wp-auth0/pulls) on GitHub. +* If you have questions about how to use Auth0 or the plugin, please [post on our community site](https://community.auth0.com/) or create a [support forum request here](https://wordpress.org/support/plugin/auth0). +* You can see additional documentation and answers on our [support site](https://support.auth0.com/). Customers on a paid Auth0 plan can [submit a trouble ticket](https://support.auth0.com/tickets) for a fast response. + +== Changelog == + +[Complete list of changes for this and other releases](https://github.com/auth0/wp-auth0/releases) \ No newline at end of file diff --git a/userfront.php b/userfront.php index ba7fecb..dbc2da0 100644 --- a/userfront.php +++ b/userfront.php @@ -4,67 +4,30 @@ * * @package UserfrontWordpress * @author Userfront - * @version 1.2.2 + * @version 1.2.3 * * @wordpress-plugin * Plugin Name: Userfront Auth * Plugin URI: https://github.com/userfront/wordpress * Description: Userfront is a premier auth & identity platform. Install full-fledged authentication and authorization with 2FA/MFA and OAuth to WordPress within minutes. + * Version: 1.2.3 * Author: Userfront - * Version: 1.2.2 * Author URI: https://userfront.com + * License: MIT */ +define('DEFAULT_PAGE_CONTENT', 'Add your Workspace ID to the plugin settings then reload this page. ☺️'); +define('PANTHEON_COOKIE_PREFIX', 'STYXKEY_'); +define('ACCESS_COOKIE_PREFIX', 'access_'); +define('ID_COOKIE_PREFIX', 'id_'); +define('REFRESH_COOKIE_PREFIX', 'refresh_'); +define('NONCE', '_wpnonce'); +define('ACTION', 'update-userfront_options'); + /** * Helpers */ -// Fetch data from a URL -function fetch($url, $method, $data = false, $headers = array()) -{ - $ch = curl_init(); - - switch ($method) { - case 'POST': - curl_setopt($ch, CURLOPT_POST, 1); - if ($data) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - } - break; - - case 'PUT': - curl_setopt($ch, CURLOPT_PUT, 1); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); - if ($data) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - } - break; - - case 'DELETE': - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); - if ($data) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - } - break; - - default: - if ($data) { - $url = sprintf('%s?%s', $url, http_build_query($data)); - } - } - - curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($headers, array('Content-Type: application/json'))); - - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - $result = curl_exec($ch); - - curl_close($ch); - - return $result; -} - // Add redirect header and kill the script function redirect($url, $permanent = false) { @@ -90,16 +53,25 @@ function delete_cookie($cookieName, $useRealCookieName = true) function get_self($jwt) { // TODO: Use jwt.verify instead - $url = 'https://api.userfront.com/v0/self'; - $data = fetch($url, 'GET', false, array('Authorization: Bearer ' . $jwt)); - return json_decode($data); + $data = wp_remote_get('https://api.userfront.com/v0/self', array( + 'headers' => array( + 'Authorization' => 'Bearer ' . $jwt + ) + )); + return isset($data["body"]) ? json_decode($data["body"]) : null; } function update_self($jwt, $data) { - $url = 'https://api.userfront.com/v0/self'; - $data_json = json_encode($data); - $data = fetch($url, 'PUT', $data_json, array('Authorization: Bearer ' . $jwt)); - return json_decode($data); + $data_json = wp_json_encode($data); + $data = wp_remote_request( + 'https://api.userfront.com/v0/self', + array( + 'method' => 'PUT', + 'headers' => array('Authorization' => 'Bearer ' . $jwt), + 'body' => $data_json, + ) + ); + return isset($data["body"]) ? json_decode($data["body"]) : null; } // Insert a new user into the WordPress database, if it doesn't exist @@ -139,88 +111,6 @@ function update_user($self, $wpUserId) } } -/** - * Userfront database table - */ - -// Create -function wp_create_database_table() -{ - global $wpdb; - - $table_name = $wpdb->prefix . 'userfront'; - - $charset_collate = $wpdb->get_charset_collate(); - - $sql = "CREATE TABLE $table_name ( - id mediumint(9) NOT NULL AUTO_INCREMENT, - loginPageId text DEFAULT NULL, - signupPageId text DEFAULT NULL, - resetPasswordPageId text DEFAULT NULL, - time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, - PRIMARY KEY (id) - ) $charset_collate;"; - - require_once ABSPATH . 'wp-admin/includes/upgrade.php'; - dbDelta($sql); -} - -// Insert -function wp_insert_record_into_table() -{ - global $wpdb; - - $table_name = $wpdb->prefix . 'userfront'; - - $wpdb->insert( - $table_name, - array( - 'time' => current_time('mysql') - ) - ); -} - -// Read -function wp_select_records_from_table() -{ - global $wpdb; - - $table_name = $wpdb->prefix . 'userfront'; - - $results = $wpdb->get_results("SELECT * FROM $table_name"); - - return $results; -} - -// Update -function wp_update_record_in_table($loginPageId, $signupPageId, $resetPasswordPageId) -{ - global $wpdb; - - $table_name = $wpdb->prefix . 'userfront'; - - $wpdb->update( - $table_name, - array( - 'loginPageId' => $loginPageId, - 'signupPageId' => $signupPageId, - 'resetPasswordPageId' => $resetPasswordPageId, - 'time' => current_time('mysql') - ), - array('id' => 1) - ); -} - -// Delete -function wp_delete_table() -{ - global $wpdb; - - $table_name = $wpdb->prefix . 'userfront'; - - $wpdb->query("DROP TABLE IF EXISTS $table_name"); -} - /** * Hooks */ @@ -240,27 +130,29 @@ function init() if (isset($workspaceId)) { $isPantheon = isset($_ENV['PANTHEON_ENVIRONMENT']); - $cookiePrefix = $isPantheon ? 'STYXKEY_' : ''; + $cookiePrefix = $isPantheon ? PANTHEON_COOKIE_PREFIX : ''; - $userfrontAccessCookie = 'access_' . $workspaceId; + $userfrontAccessCookie = ACCESS_COOKIE_PREFIX . $workspaceId; $accessCookie = $cookiePrefix . $userfrontAccessCookie; - $userfrontIdCookie = 'id_' . $workspaceId; + $userfrontIdCookie = ID_COOKIE_PREFIX . $workspaceId; $idCookie = $cookiePrefix . $userfrontIdCookie; - $userfrontRefreshCookie = 'refresh_' . $workspaceId; + $userfrontRefreshCookie = REFRESH_COOKIE_PREFIX . $workspaceId; $refreshCookie = $cookiePrefix . $userfrontRefreshCookie; $isLoggedIntoUserfront = isset($_COOKIE[$accessCookie]) && isset($_COOKIE[$idCookie]) && isset($_COOKIE[$refreshCookie]); + $requestUri = isset($_SERVER['REQUEST_URI']) ? esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) : ''; + $isWpLoginRoute = str_starts_with( - $_SERVER['REQUEST_URI'], + $requestUri, '/wp-login.php' ); $isLoginRoute = str_starts_with( - $_SERVER['REQUEST_URI'], + $requestUri, '/login' ); $isPostLoginRoute = str_starts_with( - $_SERVER['REQUEST_URI'], + $requestUri, '/post-login' ); $isLogoutAction = isset($_GET['action']) && $_GET['action'] == 'logout'; @@ -278,7 +170,7 @@ function updateCookies() { prev[name] = value.join("="); return prev; }, {}); - ["id", "refresh", "access"].forEach(key => document.cookie = "STYXKEY_" + key + "_' . $workspaceId . '=" + cookies[key + ".' . $workspaceId . '"]); + ["id", "refresh", "access"].forEach(key => document.cookie = "STYXKEY_" + key + "_' . esc_js($workspaceId) . '=" + cookies[key + ".' . esc_js($workspaceId) . '"]); window.location.href = "/dashboard"; } updateCookies(); @@ -308,9 +200,10 @@ function updateCookies() { !$isLoggedIn && $isLoggedIntoUserfront ) { $self = get_self( - $_COOKIE[$accessCookie] + sanitize_text_field(wp_unslash($_COOKIE[$accessCookie])) ); - $name = explode(' ', $self->name); + $userfrontName = property_exists($self, 'name') ? $self->name : ''; + $name = explode(' ', $userfrontName); $firstName = $name[0]; $lastName = $name[count($name) - 1]; @@ -341,7 +234,7 @@ function updateCookies() { $wpUserName = $user->first_name . ' ' . $user->last_name; // Update the Userfront user update_self( - $_COOKIE[$accessCookie], + sanitize_text_field(wp_unslash($_COOKIE[$accessCookie])), array( 'username' => $user->user_login, 'name' => $hasName ? $wpUserName : '', @@ -390,7 +283,7 @@ function updateCookies() { if ($isLoginRoute && !$isPantheon && $isCreateAccountEnabled) { if (isset($_GET['redirect_to'])) { - redirect($_GET['redirect_to']); + redirect(esc_url_raw(wp_unslash($_GET['redirect_to']))); } else { redirect('/dashboard'); } @@ -571,18 +464,18 @@ function add_admin_settings() } function display_userfront_settings_message() { - esc_html_e(''); + echo 'Configure the Userfront plugin settings.'; } function display_userfront_workspace_field() { $value = get_option('userfront-workspaceId'); - echo ''; + echo ''; } function display_userfront_organization_field() { $value = get_option('userfront-organizationId'); - echo ''; + echo ''; } function display_login_checkbox() @@ -643,91 +536,94 @@ function display_userfront_menu_page() $isPantheon = isset($_ENV['PANTHEON_ENVIRONMENT']); $success = false; + $isSubmission = isset($_GET['settings-updated']) ? $_GET['settings-updated'] == true : false; + // Event listener for the plugin settings - if (isset($_GET['settings-updated']) && $_GET['settings-updated'] === 'true') { + if ($isSubmission) { $workspaceId = get_option('userfront-workspaceId'); $isLoginEnabled = get_option('userfront-login', true); $isSignupEnabled = get_option('userfront-signup', true); $isResetPasswordEnabled = get_option('userfront-reset-password', true); - // Update the login, signup, and reset password pages with the new tenant ID - $values = wp_select_records_from_table(); - foreach ($values as $value) { - if ($isLoginEnabled && isset($value->loginPageId)) { - // Update the login page with the new tenant ID - wp_update_post( - array( - 'ID' => $value->loginPageId, - 'post_content' => '
' - ) - ); - } else if ($isLoginEnabled && !isset($value->loginPageId)) { - // Insert the login page into the database - $value->loginPageId = wp_insert_post( - array( - 'post_title' => 'Login', - 'post_content' => '', - 'post_status' => 'publish', - 'post_author' => 1, - 'post_type' => 'page', - ) - ); - } else { - // Delete the login page - wp_delete_post($value->loginPageId, true); - } - if ($isSignupEnabled && isset($value->signupPageId)) { - // Update the signup page with the new tenant ID - wp_update_post( - array( - 'ID' => $value->signupPageId, - 'post_content' => '' - ) - ); - } else if ($isSignupEnabled && !isset($value->signupPageId)) { - // Insert the signup page into the database - $value->signupPageId = wp_insert_post( - array( - 'post_title' => 'Signup', - 'post_content' => '', - 'post_status' => 'publish', - 'post_author' => 1, - 'post_type' => 'page', - ) - ); - } else { - // Delete the signup page - wp_delete_post($value->signupPageId, true); - } - if ($isResetPasswordEnabled && isset($value->resetPasswordPageId)) { - // Update the reset password page with the new tenant ID - wp_update_post( - array( - 'ID' => $value->resetPasswordPageId, - 'post_content' => '' - ) - ); - } else if ($isResetPasswordEnabled && !isset($value->resetPasswordPageId)) { - // Insert the reset password page into the database - $value->resetPasswordPageId = wp_insert_post( - array( - 'post_title' => 'Reset Password', - 'post_content' => '', - 'post_status' => 'publish', - 'post_author' => 1, - 'post_type' => 'page', - ) - ); - } else { - // Delete the reset password page - wp_delete_post($value->resetPasswordPageId, true); - } + $loginPageId = get_option('userfront-login-page-id'); + $signupPageId = get_option('userfront-signup-page-id'); + $resetPasswordPageId = get_option('userfront-reset-password-page-id'); + + if ($isLoginEnabled && $loginPageId) { + // Update the login page with the new tenant ID + wp_update_post( + array( + 'ID' => $loginPageId, + 'post_content' => $workspaceId ? '
' : DEFAULT_PAGE_CONTENT + ) + ); + } else if ($isLoginEnabled && !$loginPageId) { + // Insert the login page into the database + $loginPageId = wp_insert_post( + array( + 'post_title' => 'Login', + 'post_content' => $workspaceId ? '' : DEFAULT_PAGE_CONTENT, + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + ) + ); + update_option('userfront-login-page-id', $loginPageId); + } else { + // Delete the login page + wp_delete_post($loginPageId, true); + update_option('userfront-login-page-id', null); + } + + if ($isSignupEnabled && $signupPageId) { + // Update the signup page with the new tenant ID + wp_update_post( + array( + 'ID' => $signupPageId, + 'post_content' => $workspaceId ? '' : DEFAULT_PAGE_CONTENT + ) + ); + } else if ($isSignupEnabled && !$signupPageId) { + // Insert the signup page into the database + $signupPageId = wp_insert_post( + array( + 'post_title' => 'Signup', + 'post_content' => $workspaceId ? '' : DEFAULT_PAGE_CONTENT, + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + ) + ); + update_option('userfront-signup-page-id', $signupPageId); + } else { + // Delete the signup page + wp_delete_post($signupPageId, true); + update_option('userfront-signup-page-id', null); + } - // Save the page IDs to the database - wp_update_record_in_table( - $isLoginEnabled ? $value->loginPageId : null, - $isSignupEnabled ? $value->signupPageId : null, - $isResetPasswordEnabled ? $value->resetPasswordPageId : null + if ($isResetPasswordEnabled && $resetPasswordPageId) { + // Update the reset password page with the new tenant ID + wp_update_post( + array( + 'ID' => $resetPasswordPageId, + 'post_content' => $workspaceId ? '' : DEFAULT_PAGE_CONTENT + ) ); + } else if ($isResetPasswordEnabled && !$resetPasswordPageId) { + // Insert the reset password page into the database + $resetPasswordPageId = wp_insert_post( + array( + 'post_title' => 'Reset Password', + 'post_content' => $workspaceId ? '' : DEFAULT_PAGE_CONTENT, + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + ) + ); + update_option('userfront-reset-password-page-id', $resetPasswordPageId); + } else { + // Delete the reset password page + wp_delete_post($resetPasswordPageId, true); + update_option('userfront-reset-password-page-id', null); } $success = true; @@ -743,7 +639,9 @@ function display_userfront_menu_page() echo '

Settings saved successfully.

'; } - echo '
'; + echo ''; + + wp_nonce_field(ACTION, NONCE); do_settings_sections('userfront-options-page'); settings_fields('userfront'); @@ -760,15 +658,36 @@ function display_userfront_menu_page() ); function activation_hook() { - // Create the database table - wp_create_database_table(); - // Insert the default record into the database - wp_insert_record_into_table(); + register_setting( + 'userfront', + 'userfront-login-page-id', + [ + 'type' => 'string', + 'label' => 'Login Page ID', + ] + ); + register_setting( + 'userfront', + 'userfront-signup-page-id', + [ + 'type' => 'string', + 'label' => 'Signup Page ID' + ] + ); + register_setting( + 'userfront', + 'userfront-reset-password-page-id', + [ + 'type' => 'string', + 'label' => 'Reset Password Page ID' + ] + ); + // Insert the login page into the database $loginPageId = wp_insert_post( array( 'post_title' => 'Login', - 'post_content' => 'Add your Workspace ID to the plugin settings then reload this page. ☺️', + 'post_content' => DEFAULT_PAGE_CONTENT, 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'page', @@ -778,7 +697,7 @@ function activation_hook() $signupPageId = wp_insert_post( array( 'post_title' => 'Signup', - 'post_content' => 'Add your Workspace ID to the plugin settings then reload this page. ☺️', + 'post_content' => DEFAULT_PAGE_CONTENT, 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'page', @@ -788,18 +707,15 @@ function activation_hook() $resetPasswordPageId = wp_insert_post( array( 'post_title' => 'Reset Password', - 'post_content' => 'Add your Workspace ID to the plugin settings then reload this page. ☺️', + 'post_content' => DEFAULT_PAGE_CONTENT, 'post_status' => 'publish', 'post_author' => 1, 'post_type' => 'page', ) ); - // Save the page IDs to the database - wp_update_record_in_table( - $loginPageId, - $signupPageId, - $resetPasswordPageId - ); + update_option('userfront-login-page-id', $loginPageId); + update_option('userfront-signup-page-id', $signupPageId); + update_option('userfront-reset-password-page-id', $resetPasswordPageId); } // Fires after a plugin has been deactivated @@ -818,15 +734,9 @@ function deactivation_hook() delete_option('userfront-signup'); delete_option('userfront-reset-password'); delete_option('userfront-account-creation'); - // Delete the pages - $values = wp_select_records_from_table(); - foreach ($values as $value) { - wp_delete_post($value->loginPageId, true); - wp_delete_post($value->signupPageId, true); - wp_delete_post($value->resetPasswordPageId, true); - } - // Delete the database table - wp_delete_table(); + delete_option('userfront-login-page-id'); + delete_option('userfront-signup-page-id'); + delete_option('userfront-reset-password-page-id'); } function enqueue_userfront_script()