__('安全验证失败,请刷新页面重试', 'aksrt')]); } $user_id = isset($_POST['user_id']) ? (int) $_POST['user_id'] : 0; $result = function_exists('aksrt_save_user_center_profile') ? aksrt_save_user_center_profile($user_id, $_POST) : new WP_Error('aksrt_profile_unavailable', __('保存失败', 'aksrt')); if (is_wp_error($result)) { wp_send_json_error(['message' => $result->get_error_message()]); } wp_send_json_success(['message' => __('保存成功!', 'aksrt')]); }); // ============================================================ // AJAX: 发送邮箱验证码(修改密码/更改邮箱通用) // ============================================================ if (!function_exists('aksrt_get_email_code_key')) : function aksrt_get_email_code_key(int $user_id, string $scene): string { return 'aksrt_email_code_' . $scene . '_' . $user_id; } endif; if (!function_exists('aksrt_get_email_code_rate_key')) : function aksrt_get_email_code_rate_key(int $user_id, string $scene, string $target = ''): string { $suffix = $target !== '' ? '_' . md5(strtolower($target)) : ''; return 'aksrt_email_code_rate_' . $scene . '_' . $user_id . $suffix; } endif; if (!function_exists('aksrt_store_email_code')) : function aksrt_store_email_code(int $user_id, string $scene, string $code, string $target = ''): void { set_transient( aksrt_get_email_code_key($user_id, $scene), [ 'hash' => wp_hash_password($code), 'target' => $target, 'issued_at' => time(), ], 5 * MINUTE_IN_SECONDS ); } endif; if (!function_exists('aksrt_consume_email_code')) : function aksrt_consume_email_code(int $user_id, string $scene, string $code, string $target = ''): bool { $key = aksrt_get_email_code_key($user_id, $scene); $stored = get_transient($key); if (!is_array($stored) || empty($stored['hash']) || !wp_check_password($code, $stored['hash'])) { return false; } if ($target !== '' && strtolower((string) ($stored['target'] ?? '')) !== strtolower($target)) { return false; } delete_transient($key); return true; } endif; add_action('wp_ajax_aksrt_send_email_code', function () { if ( ! isset( $_POST['_settings_nonce'] ) || ! wp_verify_nonce( $_POST['_settings_nonce'], 'aksrt_account_settings' ) ) { wp_send_json_error( array( 'message' => __( '安全验证失败,请刷新页面重试', 'aksrt' ) ) ); } if ( ! is_user_logged_in() ) { wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) ); } $scene = isset( $_POST['scene'] ) ? sanitize_key( (string) $_POST['scene'] ) : ''; if ( ! in_array( $scene, array( 'change_password', 'change_email' ), true ) ) { wp_send_json_error( array( 'message' => __( '无效的验证场景', 'aksrt' ) ) ); } if ( function_exists( 'aksrt_require_captcha' ) ) { $captcha_result = aksrt_require_captcha( $scene, wp_unslash( $_POST ) ); if ( $captcha_result !== true ) { wp_send_json_error( array( 'message' => $captcha_result ) ); } } $current_user = wp_get_current_user(); $target_email = ''; $success_message = ''; if ( $scene === 'change_password' ) { $target_email = $current_user->user_email; if ( empty( $target_email ) || ! is_email( $target_email ) ) { wp_send_json_error( array( 'message' => __( '当前账号未绑定有效邮箱', 'aksrt' ) ) ); } $success_message = __( '验证码已发送到您的注册邮箱', 'aksrt' ); } else { $new_email = isset( $_POST['new_email'] ) ? trim( wp_unslash( $_POST['new_email'] ) ) : ''; $current_password = isset( $_POST['current_password'] ) ? trim( wp_unslash( $_POST['current_password'] ) ) : ''; if ( empty( $current_password ) || ! wp_check_password( $current_password, $current_user->user_pass, $current_user->ID ) ) { wp_send_json_error( array( 'message' => __( '当前密码不正确', 'aksrt' ) ) ); } if ( empty( $new_email ) || ! is_email( $new_email ) ) { wp_send_json_error( array( 'message' => __( '请输入有效的新邮箱地址', 'aksrt' ) ) ); } if ( strtolower( $new_email ) === strtolower( $current_user->user_email ) ) { wp_send_json_error( array( 'message' => __( '新邮箱与当前邮箱相同', 'aksrt' ) ) ); } if ( email_exists( $new_email ) ) { wp_send_json_error( array( 'message' => __( '该邮箱已被其他账号使用', 'aksrt' ) ) ); } $target_email = $new_email; $success_message = __( '验证码已发送到新邮箱,请完成验证后再提交', 'aksrt' ); } // 频率限制:60秒内不能重复发送 $rate_key = aksrt_get_email_code_rate_key( $current_user->ID, $scene, $target_email ); if ( get_transient( $rate_key ) ) { wp_send_json_error( array( 'message' => __( '操作过于频繁,请稍后再试', 'aksrt' ) ) ); } set_transient( $rate_key, true, 60 ); // 生成验证码并同步发送,只有真正发信成功后才写入验证码缓存。 $code = str_pad( (string) random_int( 0, 999999 ), 6, '0', STR_PAD_LEFT ); $site_name = get_bloginfo( 'name' ); $default_subject = '[' . $site_name . '] ' . __( '邮箱验证码', 'aksrt' ); $default_content = sprintf( __( "您好 %s,\n\n您正在进行敏感操作验证,验证码为:\n\n【%s】\n\n验证码有效期为 5 分钟。如非本人操作,请忽略此邮件。", 'aksrt' ), $current_user->display_name, $code ); $sent = class_exists( '\AKSRT\Settings\Settings' ) ? \AKSRT\Settings\Settings::send_event_email( 'change_code', $target_email, $default_subject, $default_content, [ '{username}' => $current_user->display_name, '{site_name}' => $site_name, '{code}' => $code ] ) : wp_mail( $target_email, $default_subject, $default_content, [ 'Content-Type: text/plain; charset=UTF-8' ] ); if ( ! $sent ) { delete_transient( $rate_key ); error_log( '[AKSRT] 验证码邮件发送失败 user_id=' . $current_user->ID . ' email=' . $target_email . ' scene=' . $scene ); wp_send_json_error( array( 'message' => __( '验证码邮件发送失败,请稍后重试', 'aksrt' ) ) ); } aksrt_store_email_code( $current_user->ID, $scene, $code, $target_email ); wp_send_json_success( array( 'message' => $success_message ) ); }); // ============================================================ // AJAX: 修改密码 // ============================================================ add_action('wp_ajax_aksrt_change_password', function () { if ( ! isset( $_POST['_settings_nonce'] ) || ! wp_verify_nonce( $_POST['_settings_nonce'], 'aksrt_account_settings' ) ) { wp_send_json_error( array( 'message' => __( '安全验证失败,请刷新页面重试', 'aksrt' ) ) ); } $user_id = get_current_user_id(); if ( ! $user_id ) { wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) ); } $old_password = isset( $_POST['old_password'] ) ? trim( wp_unslash( $_POST['old_password'] ) ) : ''; $new_password = isset( $_POST['new_password'] ) ? trim( wp_unslash( $_POST['new_password'] ) ) : ''; $new_password_confirm = isset( $_POST['new_password_confirm'] ) ? trim( wp_unslash( $_POST['new_password_confirm'] ) ) : ''; $email_code = isset( $_POST['email_code'] ) ? sanitize_text_field( $_POST['email_code'] ) : ''; // 验证原密码 $user = get_userdata( $user_id ); if ( ! $user || ! wp_check_password( $old_password, $user->data->user_pass, $user_id ) ) { wp_send_json_error( array( 'message' => __( '原密码不正确', 'aksrt' ) ) ); } // 验证新密码强度 if ( mb_strlen( $new_password ) < 6 ) { wp_send_json_error( array( 'message' => __( '新密码长度至少6位', 'aksrt' ) ) ); } if ( mb_strlen( $new_password ) > 128 ) { wp_send_json_error( array( 'message' => __( '新密码过长', 'aksrt' ) ) ); } if ( $new_password !== $new_password_confirm ) { wp_send_json_error( array( 'message' => __( '两次输入的新密码不一致', 'aksrt' ) ) ); } // 人机验证 if ( function_exists( 'aksrt_require_captcha' ) ) { $captcha_result = aksrt_require_captcha( 'change_password', wp_unslash( $_POST ) ); if ( $captcha_result !== true ) { wp_send_json_error( array( 'message' => $captcha_result ) ); } } // 验证邮箱验证码 if ( ! aksrt_consume_email_code( $user_id, 'change_password', $email_code, $user->user_email ) ) { wp_send_json_error( array( 'message' => __( '邮箱验证码错误或已过期', 'aksrt' ) ) ); } // 设置新密码 wp_set_password( $new_password, $user_id ); if ( class_exists( 'WP_Session_Tokens' ) ) { WP_Session_Tokens::get_instance( $user_id )->destroy_all(); } // 清除登录态 wp_clear_auth_cookie(); wp_send_json_success( array( 'message' => __( '密码修改成功,即将跳转到登录页…', 'aksrt' ), 'redirect_to' => aksrt_get_login_url(), )); }); // ============================================================ // AJAX: 更改邮箱 // ============================================================ add_action('wp_ajax_aksrt_change_email', function () { if ( ! isset( $_POST['_settings_nonce'] ) || ! wp_verify_nonce( $_POST['_settings_nonce'], 'aksrt_account_settings' ) ) { wp_send_json_error( array( 'message' => __( '安全验证失败,请刷新页面重试', 'aksrt' ) ) ); } $user_id = get_current_user_id(); if ( ! $user_id ) { wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) ); } $current_password = isset( $_POST['current_password'] ) ? trim( wp_unslash( $_POST['current_password'] ) ) : ''; $new_email = isset( $_POST['new_email'] ) ? trim( wp_unslash( $_POST['new_email'] ) ) : ''; $email_code = isset( $_POST['email_code'] ) ? sanitize_text_field( $_POST['email_code'] ) : ''; $current_user = wp_get_current_user(); if ( empty( $current_password ) || ! wp_check_password( $current_password, $current_user->user_pass, $current_user->ID ) ) { wp_send_json_error( array( 'message' => __( '当前密码不正确', 'aksrt' ) ) ); } // 验证新邮箱格式 if ( empty( $new_email ) || ! is_email( $new_email ) ) { wp_send_json_error( array( 'message' => __( '请输入有效的邮箱地址', 'aksrt' ) ) ); } if ( strtolower( $new_email ) === strtolower( $current_user->user_email ) ) { wp_send_json_error( array( 'message' => __( '新邮箱与当前邮箱相同', 'aksrt' ) ) ); } // 检查邮箱是否已被使用 if ( email_exists( $new_email ) ) { wp_send_json_error( array( 'message' => __( '该邮箱已被其他账号使用', 'aksrt' ) ) ); } // 人机验证 if ( function_exists( 'aksrt_require_captcha' ) ) { $captcha_result = aksrt_require_captcha( 'change_email', wp_unslash( $_POST ) ); if ( $captcha_result !== true ) { wp_send_json_error( array( 'message' => $captcha_result ) ); } } // 验证邮箱验证码 if ( ! aksrt_consume_email_code( $user_id, 'change_email', $email_code, $new_email ) ) { wp_send_json_error( array( 'message' => __( '邮箱验证码错误或已过期', 'aksrt' ) ) ); } // 更新邮箱 $old_email = $current_user->user_email; $update_result = wp_update_user( [ 'ID' => $user_id, 'user_email' => $new_email, ] ); if ( is_wp_error( $update_result ) ) { wp_send_json_error( array( 'message' => $update_result->get_error_message() ?: __( '邮箱更新失败,请稍后重试', 'aksrt' ) ) ); } if ( is_email( $old_email ) ) { $site_name = get_bloginfo( 'name' ); $default_subject = '[' . $site_name . '] ' . __( '账号邮箱已变更', 'aksrt' ); $default_content = sprintf( __( "您好 %s,\n\n您的账号邮箱已成功修改为:%s\n\n如果这不是您的操作,请立即联系站点管理员。", 'aksrt' ), $current_user->display_name, $new_email ); if ( class_exists( '\AKSRT\Settings\Settings' ) ) { \AKSRT\Settings\Settings::send_event_email( 'change_notice', $old_email, $default_subject, $default_content, [ '{username}' => $current_user->display_name, '{site_name}' => $site_name, '{new_email}' => $new_email ] ); } else { wp_mail( $old_email, $default_subject, $default_content, [ 'Content-Type: text/plain; charset=UTF-8' ] ); } } $verify_url = ''; $verify_message = ''; update_user_meta( $user_id, 'aksrt_email_verified', 1 ); if ( class_exists( 'WP_Session_Tokens' ) ) { WP_Session_Tokens::get_instance( $user_id )->destroy_all(); } // 清除登录态 wp_clear_auth_cookie(); wp_send_json_success( array( 'message' => $verify_message !== '' ? __( '邮箱修改成功,请前往新邮箱完成验证后重新登录…', 'aksrt' ) : __( '邮箱修改成功,即将跳转到登录页…', 'aksrt' ), 'redirect_to' => $verify_url !== '' ? $verify_url : aksrt_get_login_url(), 'verify_url' => $verify_url, )); });