fix(profile): align account dialogs and contracts

This commit is contained in:
kate522 committed 2026-10-06 01:09:04 +08:00
1 parent f646fa8573
commit 248912f610
17 files changed
+1339 -832

No files matched your search

@@ -81,7 +81,7 @@ $config = [
</div>
<div class="but-average modal-buts uc-auth-modal__footer">
<button type="button" class="but" data-aksrt-modal-close><?php esc_html_e('取消', 'aksrt'); ?></button>
<button type="submit" class="but c-blue"><i class="fa fa-check mr6" aria-hidden="true"></i><?php esc_html_e('确认提交', 'aksrt'); ?></button>
<button type="submit" class="but c-blue"><i class="fa fas fa-check mr6" aria-hidden="true"></i><?php esc_html_e('确认提交', 'aksrt'); ?></button>
</div>
</form>
</div>
@@ -1,25 +1,29 @@
<?php
/**
* User center account settings rows and runtime modal templates.
* User center account settings rows and reference-theme account dialogs.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
$account_user = isset($target_user) && $target_user instanceof WP_User
? $target_user
: wp_get_current_user();
$account_user = isset($target_user) && $target_user instanceof WP_User ? $target_user : wp_get_current_user();
$account_user_id = $account_user instanceof WP_User ? (int) $account_user->ID : (int) ($user_id ?? 0);
$account_email = $account_user instanceof WP_User ? (string) $account_user->user_email : '';
$account_phone = $account_user_id > 0 ? (string) get_user_meta($account_user_id, 'phone_number', true) : '';
$user_settings = class_exists('\\AKSRT\\Settings\\Settings') ? \AKSRT\Settings\Settings::get_all() : [];
$sms_settings = class_exists('\\AKSRT\\Sms\\SMS') ? \AKSRT\Sms\SMS::get_instance()->get_provider_config() : [];
$account_oauth_new = $account_user_id > 0 && get_user_meta($account_user_id, 'oauth_new', true);
$user_settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_all() : [];
$sms_settings = class_exists('\AKSRT\Sms\SMS') ? \AKSRT\Sms\SMS::get_instance()->get_provider_config() : [];
$phone_available = !empty($user_settings['bind_phone']) && (($sms_settings['sms_sdk'] ?? 'null') !== 'null');
$phone_visible = $account_phone !== '' || $phone_available;
$phone_label = $account_phone !== '' ? $account_phone : __('暂未绑定', 'aksrt');
$email_action = $account_email !== '' ? __('修改', 'aksrt') : __('绑定', 'aksrt');
$phone_action = $account_phone !== '' ? __('修改', 'aksrt') : __('绑定', 'aksrt');
$agreement = function_exists('aksrt_get_auth_agreement_view') ? aksrt_get_auth_agreement_view() : ['enabled' => false, 'required' => false, 'label_html' => ''];
$email_verify_required = $account_email !== '' && !empty($user_settings['email_set_captch']);
$reset_channel = class_exists('\\AKSRT\\Settings\\Settings') ? \AKSRT\Settings\Settings::reset_password_verification_type() : 'email';
$sign_in_available = !class_exists('\\AKSRT\\Settings\\Settings') || (!\AKSRT\Settings\Settings::close_sign() && !\AKSRT\Settings\Settings::close_signin());
$can_recover_password = $sign_in_available && ($reset_channel === 'email_phone'
? ($account_email !== '' || $account_phone !== '')
: ($reset_channel === 'phone' ? $account_phone !== '' : $account_email !== ''));
$recovery_target = $reset_channel === 'phone' ? $account_phone : ($account_email !== '' ? $account_email : $account_phone);
$recovery_channel = $reset_channel === 'email_phone' ? '' : $reset_channel;
$render_row = static function (string $icon, string $title, string $value, string $action, string $modal, string $icon_tone, string $action_tone, bool $interactive = true): void {
?>
@@ -28,116 +32,122 @@ $render_row = static function (string $icon, string $title, string $value, strin
<span class="aksrt-account-row__icon aksrt-account-row__icon--<?php echo esc_attr($icon_tone); ?>"><i class="fa fas <?php echo esc_attr($icon); ?>" aria-hidden="true"></i></span>
<strong class="aksrt-account-row__copy"><?php echo esc_html($title); ?></strong>
</div>
<?php if ($value !== '') : ?>
<div class="aksrt-account-row__value" title="<?php echo esc_attr($value); ?>"><?php echo esc_html($value); ?></div>
<?php endif; ?>
<?php if ($value !== '') : ?><div class="aksrt-account-row__value" title="<?php echo esc_attr($value); ?>"><?php echo esc_html($value); ?></div><?php endif; ?>
<?php if ($interactive) : ?>
<button type="button" class="but hollow <?php echo esc_attr($action_tone); ?> aksrt-account-row__action" data-aksrt-settings-modal="<?php echo esc_attr($modal); ?>">
<?php echo esc_html($action); ?>
</button>
<?php else : ?>
<span class="aksrt-account-row__action aksrt-account-row__action--unavailable"><?php esc_html_e('暂不可修改', 'aksrt'); ?></span>
<?php endif; ?>
<button type="button" class="but hollow <?php echo esc_attr($action_tone); ?> aksrt-account-row__action" data-aksrt-settings-modal="<?php echo esc_attr($modal); ?>"><?php echo esc_html($action); ?></button>
<?php else : ?><span class="aksrt-account-row__action aksrt-account-row__action--unavailable"><?php esc_html_e('暂不可修改', 'aksrt'); ?></span><?php endif; ?>
</div>
<?php
};
$render_email_form = static function () use ($user_settings, $agreement): void {
?>
<form id="email-new-form">
<div class="relative line-form mb10 modal-line-field"><input type="email" id="email-new" name="new_email" class="line-form-input" required><div class="scale-placeholder"><?php esc_html_e('请输入邮箱', 'aksrt'); ?></div><i class="line-form-line"></i></div>
<?php if (!empty($user_settings['email_set_captch'])) : ?><div class="relative line-form mb10 modal-line-field"><input type="text" id="email-code" name="code" class="line-form-input" maxlength="6" inputmode="numeric" required><div class="scale-placeholder"><?php esc_html_e('验证码', 'aksrt'); ?></div><button type="button" class="but c-blue code-send-btn account-code-send" data-account-code-scene="change_email"><?php esc_html_e('发送验证码', 'aksrt'); ?></button><i class="line-form-line"></i></div><?php endif; ?>
<?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('change_email'); ?><?php endif; ?>
<?php if (!empty($agreement['enabled'])) : ?><label class="form-checkbox muted-color mb20"><input type="checkbox" name="agree_terms" value="1"<?php echo !empty($agreement['required']) ? ' required' : ' checked'; ?>> <?php echo wp_kses_post($agreement['label_html']); ?></label><?php endif; ?>
<button type="submit" class="but jb-blue padding-lg btn-block"><i class="fa fas fa-check" aria-hidden="true"></i> <?php esc_html_e('确认提交', 'aksrt'); ?></button>
</form>
<?php
};
$render_phone_form = static function () use ($agreement): void {
?>
<form id="aksrt-bind-phone-form">
<div class="relative line-form mb10 modal-line-field"><input type="tel" id="bind-phone-input" name="phone" inputmode="tel" autocomplete="tel" required><div class="scale-placeholder"><?php esc_html_e('手机号', 'aksrt'); ?></div><i class="line-form-line"></i></div>
<div class="relative line-form mb10 modal-line-field"><input type="text" id="bind-phone-code" name="code" class="line-form-input" maxlength="6" inputmode="numeric" autocomplete="one-time-code" required><div class="scale-placeholder"><?php esc_html_e('验证码', 'aksrt'); ?></div><button type="button" class="but c-blue code-send-btn" data-aksrt-sms-trigger data-aksrt-sms-scene="bind_new_phone"><?php esc_html_e('发送验证码', 'aksrt'); ?></button><i class="line-form-line"></i></div>
<?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('bind_phone'); ?><?php endif; ?>
<?php if (!empty($agreement['enabled'])) : ?><label class="form-checkbox muted-color mb20"><input type="checkbox" name="agree_terms" value="1"<?php echo !empty($agreement['required']) ? ' required' : ' checked'; ?>> <?php echo wp_kses_post($agreement['label_html']); ?></label><?php endif; ?>
<button type="submit" class="but jb-blue padding-lg btn-block"><i class="fa fas fa-check" aria-hidden="true"></i> <?php esc_html_e('确认提交', 'aksrt'); ?></button>
</form>
<?php
};
?>
<section class="aksrt-account-settings" data-aksrt-settings-root data-aksrt-captcha-scope>
<div class="aksrt-account-settings__section">
<div class="aksrt-account-settings__heading">
<div>
<h3 class="title-h-left"><b><?php esc_html_e('绑定邮箱', 'aksrt'); ?></b></h3>
<p><?php esc_html_e('绑定邮箱账号,及时接收订单、审核等重要信息', 'aksrt'); ?></p>
</div>
</div>
<div class="aksrt-account-list">
<?php $render_row('fa-envelope', __('邮箱', 'aksrt'), $account_email !== '' ? $account_email : __('暂未绑定', 'aksrt'), $email_action, 'email', 'blue', $account_email !== '' ? 'c-yellow-2' : 'c-blue'); ?>
</div>
<div class="aksrt-account-settings__heading"><div><h3 class="title-h-left"><b><?php esc_html_e('绑定邮箱', 'aksrt'); ?></b></h3><p><?php esc_html_e('绑定邮箱账号,及时接收订单、审核等重要信息', 'aksrt'); ?></p></div></div>
<div class="aksrt-account-list"><?php $render_row('fa-envelope', __('邮箱', 'aksrt'), $account_email !== '' ? $account_email : __('暂未绑定', 'aksrt'), $account_email !== '' ? __('修改', 'aksrt') : __('绑定', 'aksrt'), 'email', 'blue', $account_email !== '' ? 'c-yellow-2' : 'c-blue'); ?></div>
</div>
<?php if ($phone_visible) : ?>
<?php if ($account_phone !== '' || $phone_available) : ?>
<div class="aksrt-account-settings__section">
<div class="aksrt-account-settings__heading">
<div>
<h3 class="title-h-left"><b><?php esc_html_e('绑定手机', 'aksrt'); ?></b></h3>
<p><?php esc_html_e('绑定手机号,提高账户安全性', 'aksrt'); ?></p>
</div>
</div>
<div class="aksrt-account-list">
<?php $render_row('fa-phone', __('手机号', 'aksrt'), $phone_label, $phone_action, 'phone', 'blue-2', $account_phone !== '' ? 'c-yellow' : 'c-blue', $phone_available); ?>
</div>
<div class="aksrt-account-settings__heading"><div><h3 class="title-h-left"><b><?php esc_html_e('绑定手机', 'aksrt'); ?></b></h3><p><?php esc_html_e('绑定手机号,提高账户安全性', 'aksrt'); ?></p></div></div>
<div class="aksrt-account-list"><?php $render_row('fa-phone', __('手机号', 'aksrt'), $account_phone !== '' ? $account_phone : __('暂未绑定', 'aksrt'), $account_phone !== '' ? __('修改', 'aksrt') : __('绑定', 'aksrt'), 'phone', 'blue-2', $account_phone !== '' ? 'c-yellow' : 'c-blue', $phone_available); ?></div>
</div>
<?php endif; ?>
<?php require __DIR__ . '/settings-bindings.php'; ?>
<div class="aksrt-account-settings__section">
<div class="aksrt-account-settings__heading">
<div>
<h3 class="title-h-left"><b><?php esc_html_e('账户密码', 'aksrt'); ?></b></h3>
<p><?php esc_html_e('定期修改密码有助于账户安全', 'aksrt'); ?></p>
</div>
</div>
<div class="aksrt-account-list">
<?php $render_row('fa-unlock-alt', __('账户密码', 'aksrt'), '', __('修改密码', 'aksrt'), 'password', 'purple', 'c-blue-2'); ?>
</div>
<div class="aksrt-account-settings__heading"><div><h3 class="title-h-left"><b><?php esc_html_e('账户密码', 'aksrt'); ?></b></h3><p><?php echo $account_oauth_new ? esc_html__('您还未设置过密码,请在此设置新密码', 'aksrt') : esc_html__('定期修改密码有助于账户安全', 'aksrt'); ?></p></div></div>
<div class="aksrt-account-list"><?php $render_row('fa-unlock-alt', __('账户密码', 'aksrt'), '', $account_oauth_new ? __('设置新密码', 'aksrt') : __('修改密码', 'aksrt'), 'password', 'purple', 'c-blue-2'); ?></div>
</div>
<template data-aksrt-settings-modal-template="password">
<div class="aksrt-settings-modal">
<div class="modal-colorful-header colorful-bg jb-yellow">
<button type="button" class="close" data-aksrt-modal-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fa fas fa-times" aria-hidden="true"></i></button>
<div class="colorful-make"></div>
<div class="text-center"><div class="em2x"><i class="fa fas fa-unlock-alt" aria-hidden="true"></i></div><div class="mt10 em12 padding-w10"><?php esc_html_e('修改密码', 'aksrt'); ?></div></div>
<div class="aksrt-settings-modal" data-account-dialog="password" data-recovery-channel="<?php echo esc_attr($recovery_channel); ?>" data-recovery-target="<?php echo esc_attr($recovery_target); ?>">
<div class="modal-colorful-header colorful-bg jb-yellow"><button type="button" class="close" data-aksrt-modal-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fa fas fa-times" aria-hidden="true"></i></button><div class="colorful-make"></div><div class="text-center"><div class="em2x"><i class="fa fas fa-unlock-alt" aria-hidden="true"></i></div><div class="mt10 em12 padding-w10" data-account-password-title data-change-label="<?php echo esc_attr($account_oauth_new ? __('设置密码', 'aksrt') : __('修改密码', 'aksrt')); ?>" data-recovery-label="<?php esc_attr_e('重设密码', 'aksrt'); ?>"><?php echo $account_oauth_new ? esc_html__('设置密码', 'aksrt') : esc_html__('修改密码', 'aksrt'); ?></div></div></div>
<div class="aksrt-settings-modal__pane" data-account-password-pane="change">
<form id="pwd-form" autocomplete="off" novalidate>
<div class="aksrt-settings-modal__fields">
<?php if (!$account_oauth_new) : ?><div class="relative line-form mb10 modal-line-field"><input type="password" id="pwd-old" name="passwordold" class="line-form-input" tabindex="1" required><div class="scale-placeholder"><?php esc_html_e('请输入原密码', 'aksrt'); ?></div><button type="button" class="toggle-pwd abs-right passw" data-target="pwd-old" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fas fa-eye" aria-hidden="true"></i></button><i class="line-form-line"></i></div><?php endif; ?>
<div class="relative line-form mb10 modal-line-field"><input type="password" id="pwd-new" name="password" class="line-form-input" tabindex="2" required minlength="6"><div class="scale-placeholder"><?php echo $account_oauth_new ? esc_html__('设置新密码', 'aksrt') : esc_html__('请输入新密码', 'aksrt'); ?></div><button type="button" class="toggle-pwd abs-right passw" data-target="pwd-new" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fas fa-eye" aria-hidden="true"></i></button><i class="line-form-line"></i></div>
<div class="relative line-form mb10 modal-line-field"><input type="password" id="pwd-confirm" name="password2" class="line-form-input" tabindex="3" required minlength="6"><div class="scale-placeholder"><?php esc_html_e('请再次输入新密码', 'aksrt'); ?></div><button type="button" class="toggle-pwd abs-right passw" data-target="pwd-confirm" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fas fa-eye" aria-hidden="true"></i></button><i class="line-form-line"></i></div>
<?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('change_password'); ?><?php endif; ?>
</div>
<?php if ($account_oauth_new) : ?><input type="hidden" name="oauth_new" value="1"><?php endif; ?>
<button type="submit" class="but jb-blue padding-lg btn-block"><i class="fa fas fa-check" aria-hidden="true"></i> <span data-aksrt-settings-submit-label><?php esc_html_e('确认提交', 'aksrt'); ?></span></button>
</form>
<?php if (!$account_oauth_new && $can_recover_password) : ?><div class="text-right mt6"><button type="button" class="em09 muted-2-color account-recovery-toggle" data-account-recovery-open><?php esc_html_e('忘记原密码?点击重设密码', 'aksrt'); ?></button></div><?php endif; ?>
</div>
<form id="pwd-form" autocomplete="off" novalidate>
<div class="aksrt-settings-modal__fields">
<div class="modal-field"><label for="pwd-old"><?php esc_html_e('原密码', 'aksrt'); ?></label><input type="password" id="pwd-old" name="old_password" required minlength="1"><button type="button" class="toggle-pwd" data-target="pwd-old" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fa-eye" aria-hidden="true"></i></button></div>
<div class="modal-field"><label for="pwd-new"><?php esc_html_e('新密码', 'aksrt'); ?></label><input type="password" id="pwd-new" name="new_password" required minlength="6" placeholder="<?php esc_attr_e('至少6位字符', 'aksrt'); ?>"><button type="button" class="toggle-pwd" data-target="pwd-new" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fa-eye" aria-hidden="true"></i></button><div class="pwd-strength" id="pwd-strength-bar"><div class="pwd-strength__fill"></div></div><span class="pwd-strength__text" id="pwd-strength-text"></span></div>
<div class="modal-field"><label for="pwd-new-confirm"><?php esc_html_e('确认新密码', 'aksrt'); ?></label><input type="password" id="pwd-new-confirm" name="new_password_confirm" required minlength="6" placeholder="<?php esc_attr_e('再次输入新密码', 'aksrt'); ?>"><button type="button" class="toggle-pwd" data-target="pwd-new-confirm" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fa-eye" aria-hidden="true"></i></button></div>
<div class="modal-field modal-field--code"><label for="pwd-code"><?php esc_html_e('当前邮箱验证码', 'aksrt'); ?></label><div class="code-input-group"><input type="text" id="pwd-code" name="email_code" maxlength="6" inputmode="numeric" pattern="[0-9]*" placeholder="<?php esc_attr_e('6位数字验证码', 'aksrt'); ?>" required><button type="button" class="but hollow code-send-btn" id="pwd-send-code"><?php esc_html_e('发送到当前邮箱', 'aksrt'); ?></button></div></div>
<?php aksrt_render_captcha('change_password'); ?>
</div>
<button type="submit" class="but jb-blue padding-lg btn-block" id="pwd-submit"><i class="fa fas fa-check" aria-hidden="true"></i> <span data-aksrt-settings-submit-label><?php esc_html_e('确认提交', 'aksrt'); ?></span></button>
</form>
<?php if (!$account_oauth_new && $can_recover_password) : ?>
<div class="aksrt-settings-modal__pane" data-account-password-pane="recovery" hidden>
<div class="text-right mb10"><button type="button" class="em09 but p2-10 account-recovery-toggle" data-account-recovery-back><i class="fa fas fa-angle-left em12" aria-hidden="true"></i> <?php esc_html_e('返回使用原密码修改密码', 'aksrt'); ?></button></div>
<form id="pwd-recovery-form" autocomplete="off" novalidate>
<div class="aksrt-settings-modal__fields">
<div class="relative line-form mb10 modal-line-field"><input type="text" id="pwd-recovery-target" name="target" value="<?php echo esc_attr($recovery_target); ?>" class="line-form-input" autocomplete="username" required><div class="scale-placeholder"><?php esc_html_e('邮箱或手机号', 'aksrt'); ?></div><i class="line-form-line"></i></div>
<div class="relative line-form mb10 modal-line-field"><input type="text" id="pwd-recovery-code" name="code" class="line-form-input" maxlength="6" inputmode="numeric" autocomplete="one-time-code" required><div class="scale-placeholder"><?php esc_html_e('验证码', 'aksrt'); ?></div><button type="button" class="but c-blue code-send-btn" data-account-recovery-send><?php esc_html_e('发送验证码', 'aksrt'); ?></button><i class="line-form-line"></i></div>
<?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('lostpassword'); ?><?php endif; ?>
<div class="relative line-form mb10 modal-line-field"><input type="password" id="pwd-recovery-new" name="password" class="line-form-input" required minlength="6"><div class="scale-placeholder"><?php esc_html_e('设置新密码', 'aksrt'); ?></div><button type="button" class="toggle-pwd abs-right passw" data-target="pwd-recovery-new" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fas fa-eye" aria-hidden="true"></i></button><i class="line-form-line"></i></div>
<div class="relative line-form mb10 modal-line-field"><input type="password" id="pwd-recovery-confirm" name="password_confirm" class="line-form-input" required minlength="6"><div class="scale-placeholder"><?php esc_html_e('重复密码', 'aksrt'); ?></div><button type="button" class="toggle-pwd abs-right passw" data-target="pwd-recovery-confirm" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fas fa-eye" aria-hidden="true"></i></button><i class="line-form-line"></i></div>
</div>
<button type="submit" class="but jb-green padding-lg btn-block"><i class="fa fas fa-check" aria-hidden="true"></i> <span data-aksrt-settings-submit-label><?php esc_html_e('确认提交', 'aksrt'); ?></span></button>
</form>
</div>
<?php endif; ?>
</div>
</template>
<template data-aksrt-settings-modal-template="email">
<div class="aksrt-settings-modal">
<div class="modal-colorful-header colorful-bg jb-blue">
<button type="button" class="close" data-aksrt-modal-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fa fas fa-times" aria-hidden="true"></i></button>
<div class="colorful-make"></div>
<div class="text-center"><div class="em2x"><i class="fa fas fa-envelope" aria-hidden="true"></i></div><div class="mt10 em12 padding-w10"><?php echo esc_html($account_email !== '' ? __('更改邮箱', 'aksrt') : __('绑定邮箱', 'aksrt')); ?></div></div>
</div>
<form id="email-form" autocomplete="off" novalidate>
<div class="aksrt-settings-modal__fields">
<?php if ($account_email !== '') : ?><div class="modal-field"><label><?php esc_html_e('当前邮箱', 'aksrt'); ?></label><div class="readonly-display"><?php echo esc_html($account_email); ?></div></div><?php endif; ?>
<div class="modal-field"><label for="email-current-password"><?php esc_html_e('当前密码', 'aksrt'); ?></label><input type="password" id="email-current-password" name="current_password" required minlength="1" placeholder="<?php esc_attr_e('请输入当前登录密码', 'aksrt'); ?>"><button type="button" class="toggle-pwd" data-target="email-current-password" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><i class="fa fa-eye" aria-hidden="true"></i></button></div>
<div class="modal-field"><label for="email-new"><?php esc_html_e('新邮箱', 'aksrt'); ?></label><input type="email" id="email-new" name="new_email" required placeholder="<?php esc_attr_e('请输入新的邮箱地址', 'aksrt'); ?>"></div>
<div class="modal-field modal-field--code"><label for="email-code"><?php esc_html_e('新邮箱验证码', 'aksrt'); ?></label><div class="code-input-group"><input type="text" id="email-code" name="email_code" maxlength="6" inputmode="numeric" pattern="[0-9]*" placeholder="<?php esc_attr_e('6位数字验证码', 'aksrt'); ?>" required><button type="button" class="but hollow code-send-btn" id="email-send-code"><?php esc_html_e('发送到新邮箱', 'aksrt'); ?></button></div><p class="settings-hint settings-hint--bottom"><?php esc_html_e('验证码将发送到你填写的新邮箱,验证通过后才会正式切换。', 'aksrt'); ?></p></div>
<?php aksrt_render_captcha('change_email'); ?>
<div class="aksrt-settings-modal" data-account-dialog="email">
<div class="modal-colorful-header colorful-bg jb-blue"><button type="button" class="close" data-aksrt-modal-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fa fas fa-times" aria-hidden="true"></i></button><div class="colorful-make"></div><div class="text-center"><div class="em2x"><i class="fa fas fa-envelope" aria-hidden="true"></i></div><div class="mt10 em12 padding-w10"><?php echo esc_html($account_email !== '' ? __('修改邮箱', 'aksrt') : __('绑定邮箱', 'aksrt')); ?></div></div></div>
<?php if ($email_verify_required) : ?>
<ul class="mb20 step-simple account-step-list" data-account-step-list="email"><li class="active"><span><?php esc_html_e('验证老邮箱', 'aksrt'); ?></span></li><li><span><?php esc_html_e('验证新邮箱', 'aksrt'); ?></span></li><li><span><?php esc_html_e('修改成功', 'aksrt'); ?></span></li></ul>
<div class="account-step-panels">
<div class="account-step is-active" data-account-step="email-old"><p class="muted-2-color"><?php printf(esc_html__('请在下方获取验证码以验证您的老邮箱 %s', 'aksrt'), '<span class="badg">' . esc_html($account_email) . '</span>'); ?></p><form id="email-old-verify-form"><div class="relative line-form mb10 modal-line-field"><input type="text" name="code" class="line-form-input" maxlength="6" inputmode="numeric" required><div class="scale-placeholder"><?php esc_html_e('验证码', 'aksrt'); ?></div><button type="button" class="but c-blue code-send-btn account-code-send" data-account-code-scene="verify_email"><?php esc_html_e('发送验证码', 'aksrt'); ?></button><i class="line-form-line"></i></div><?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('change_email'); ?><?php endif; ?><button type="submit" class="but jb-blue padding-lg btn-block"><i class="fa fas fa-shield-alt" aria-hidden="true"></i> <?php esc_html_e('立即验证', 'aksrt'); ?></button></form></div>
<div class="account-step" data-account-step="email-new"><p class="muted-2-color"><?php esc_html_e('请输入您需要修改的新邮箱账号', 'aksrt'); ?></p><?php $render_email_form(); ?></div>
<div class="account-step" data-account-step="email-success"><div class="text-center padding-h10"><i class="fa fas fa-check-circle c-green em3x mb10" aria-hidden="true"></i><p><?php esc_html_e('邮箱修改成功', 'aksrt'); ?></p></div></div>
</div>
<button type="submit" class="but jb-blue padding-lg btn-block" id="email-submit"><i class="fa fas fa-check" aria-hidden="true"></i> <span data-aksrt-settings-submit-label><?php esc_html_e('确认提交', 'aksrt'); ?></span></button>
</form>
<?php else : ?>
<div class="aksrt-settings-modal__pane"><p class="muted-2-color"><?php esc_html_e('请输入您需要修改的新邮箱账号', 'aksrt'); ?></p><?php $render_email_form(); ?></div>
<?php endif; ?>
</div>
</template>
<?php if ($phone_available) : ?>
<template data-aksrt-settings-modal-template="phone">
<div class="aksrt-settings-modal">
<div class="modal-colorful-header colorful-bg jb-blue">
<button type="button" class="close" data-aksrt-modal-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fa fas fa-times" aria-hidden="true"></i></button>
<div class="colorful-make"></div>
<div class="text-center"><div class="em2x"><i class="fa fas fa-mobile-alt" aria-hidden="true"></i></div><div class="mt10 em12 padding-w10"><?php echo esc_html($account_phone !== '' ? __('修改手机', 'aksrt') : __('绑定手机', 'aksrt')); ?></div></div>
</div>
<form id="aksrt-bind-phone-form" autocomplete="off" novalidate data-aksrt-bind-phone-form>
<div class="aksrt-settings-modal__fields">
<div class="modal-field"><label for="bind-phone-input"><?php esc_html_e('手机号', 'aksrt'); ?></label><input type="tel" id="bind-phone-input" name="phone" data-aksrt-phone-input inputmode="tel" autocomplete="tel" required placeholder="<?php esc_attr_e('请输入手机号', 'aksrt'); ?>"></div>
<div class="modal-field modal-field--code"><label for="bind-phone-code"><?php esc_html_e('短信验证码', 'aksrt'); ?></label><div class="code-input-group"><input type="text" id="bind-phone-code" name="code" maxlength="6" inputmode="numeric" autocomplete="one-time-code" required placeholder="<?php esc_attr_e('请输入验证码', 'aksrt'); ?>"><button type="button" class="but hollow code-send-btn" data-aksrt-sms-trigger data-aksrt-sms-scene="bind_phone" data-aksrt-sms-phone="#bind-phone-input"><?php esc_html_e('获取验证码', 'aksrt'); ?></button></div></div>
<?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('bind_phone'); ?><?php endif; ?>
<div class="aksrt-settings-modal" data-account-dialog="phone">
<div class="modal-colorful-header colorful-bg jb-blue"><button type="button" class="close" data-aksrt-modal-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fa fas fa-times" aria-hidden="true"></i></button><div class="colorful-make"></div><div class="text-center"><div class="em2x"><i class="fa fas fa-phone" aria-hidden="true"></i></div><div class="mt10 em12 padding-w10"><?php echo esc_html($account_phone !== '' ? __('修改手机', 'aksrt') : __('绑定手机', 'aksrt')); ?></div></div></div>
<?php if ($account_phone !== '') : ?>
<ul class="mb20 step-simple account-step-list" data-account-step-list="phone"><li class="active"><span><?php esc_html_e('验证老手机', 'aksrt'); ?></span></li><li><span><?php esc_html_e('验证新手机', 'aksrt'); ?></span></li><li><span><?php esc_html_e('修改成功', 'aksrt'); ?></span></li></ul>
<div class="account-step-panels">
<div class="account-step is-active" data-account-step="phone-old"><p class="muted-2-color"><?php printf(esc_html__('请在下方获取验证码以验证您的老手机号 %s', 'aksrt'), '<br><span class="badg">' . esc_html($account_phone) . '</span>'); ?></p><form id="phone-old-verify-form"><input type="hidden" name="phone" value="<?php echo esc_attr($account_phone); ?>"><div class="relative line-form mb10 modal-line-field"><input type="text" name="code" class="line-form-input" maxlength="6" inputmode="numeric" required><div class="scale-placeholder"><?php esc_html_e('验证码', 'aksrt'); ?></div><button type="button" class="but c-blue code-send-btn account-code-send" data-aksrt-sms-trigger data-aksrt-sms-scene="verify_old_phone"><?php esc_html_e('发送验证码', 'aksrt'); ?></button><i class="line-form-line"></i></div><?php if (function_exists('aksrt_render_captcha')) : ?><?php aksrt_render_captcha('bind_phone'); ?><?php endif; ?><button type="submit" class="but jb-blue padding-lg btn-block"><i class="fa fas fa-shield-alt" aria-hidden="true"></i> <?php esc_html_e('立即验证', 'aksrt'); ?></button></form></div>
<div class="account-step" data-account-step="phone-new"><p class="muted-2-color"><?php esc_html_e('请输入您需要修改的新手机号码', 'aksrt'); ?></p><?php $render_phone_form(); ?></div>
<div class="account-step" data-account-step="phone-success"><div class="text-center padding-h10"><i class="fa fas fa-check-circle c-green em3x mb10" aria-hidden="true"></i><p><?php esc_html_e('手机号修改成功', 'aksrt'); ?></p></div></div>
</div>
<button type="submit" class="but jb-blue padding-lg btn-block"><i class="fa fas fa-check" aria-hidden="true"></i> <span data-aksrt-settings-submit-label><?php esc_html_e('确认提交', 'aksrt'); ?></span></button>
</form>
<?php else : ?>
<div class="aksrt-settings-modal__pane"><p class="muted-2-color"><?php esc_html_e('请输入您需要绑定的手机号', 'aksrt'); ?></p><?php $render_phone_form(); ?></div>
<?php endif; ?>
</div>
</template>
<?php endif; ?>
+326 -283
View File
@@ -1,322 +1,365 @@
<?php
/**
* User profile/password/email AJAX handlers
*
* @package AKSRT
*/
/** User profile and account settings AJAX handlers. */
defined('ABSPATH') || exit;
if (!function_exists('aksrt_account_captcha_error_data')) :
function aksrt_account_captcha_error_data($result): array {
if (is_wp_error($result)) {
return [
'code' => $result->get_error_code() ?: 'aksrt_captcha_failed',
'message' => $result->get_error_message() ?: __('人机验证失败,请重试', 'aksrt'),
];
}
return [
'code' => 'aksrt_captcha_failed',
'message' => __('人机验证失败,请重试', 'aksrt'),
];
if (!function_exists('aksrt_account_captcha_error_data')) {
function aksrt_account_captcha_error_data($result): array {
return [
'code' => is_wp_error($result) ? ($result->get_error_code() ?: 'aksrt_captcha_failed') : 'aksrt_captcha_failed',
'message' => is_wp_error($result)
? ($result->get_error_message() ?: __('人机验证失败,请重试', 'aksrt'))
: __('人机验证失败,请重试', 'aksrt'),
];
}
}
endif;
// ============================================================
add_action('wp_ajax_aksrt_save_profile', function () {
if (!isset($_POST['_profile_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_profile_nonce'])), 'aksrt_profile_save')) {
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
}
add_action('wp_ajax_aksrt_save_profile', function (): void {
if (
!isset($_POST['_profile_nonce'])
|| !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_profile_nonce'])), 'aksrt_profile_save')
) {
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', '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'));
$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')]);
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;
function aksrt_account_code_key(int $user_id, string $scene, string $target): string {
return 'aksrt_account_code_' . $user_id . '_' . sanitize_key($scene) . '_' . md5(strtolower(trim($target)));
}
endif;
function aksrt_account_store_code(int $user_id, string $scene, string $target, string $code): void {
set_transient(
aksrt_account_code_key($user_id, $scene, $target),
['hash' => wp_hash_password($code), 'attempts' => 0],
5 * MINUTE_IN_SECONDS
);
}
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' ) ) );
}
function aksrt_account_consume_code(int $user_id, string $scene, string $target, string $code, bool $consume = true): bool {
$key = aksrt_account_code_key($user_id, $scene, $target);
$stored = get_transient($key);
if (!is_array($stored) || empty($stored['hash'])) {
return false;
}
if ( ! is_user_logged_in() ) {
wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) );
}
$attempts = (int) ($stored['attempts'] ?? 0) + 1;
if ($attempts > 6) {
delete_transient($key);
return false;
}
$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 (!wp_check_password($code, (string) $stored['hash'])) {
$stored['attempts'] = $attempts;
set_transient($key, $stored, 5 * MINUTE_IN_SECONDS);
return false;
}
if ( function_exists( 'aksrt_require_captcha' ) ) {
$captcha_result = aksrt_require_captcha( $scene, wp_unslash( $_POST ) );
if ( $captcha_result !== true ) {
wp_send_json_error( aksrt_account_captcha_error_data( $captcha_result ) );
}
}
if ($consume) {
delete_transient($key);
}
return true;
}
$current_user = wp_get_current_user();
$target_email = '';
$success_message = '';
function aksrt_account_proof_key(int $user_id, string $kind): string {
return 'aksrt_account_proof_' . sanitize_key($kind) . '_' . $user_id;
}
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'] ) ) : '';
function aksrt_account_set_proof(int $user_id, string $kind, string $target): void {
set_transient(
aksrt_account_proof_key($user_id, $kind),
['target' => strtolower(trim($target))],
30 * MINUTE_IN_SECONDS
);
}
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' ) ) );
}
function aksrt_account_consume_proof(int $user_id, string $kind, string $target, bool $consume = true): bool {
$key = aksrt_account_proof_key($user_id, $kind);
$proof = get_transient($key);
if (!is_array($proof) || strtolower(trim((string) ($proof['target'] ?? ''))) !== strtolower(trim($target))) {
return false;
}
$target_email = $new_email;
$success_message = __( '验证码已发送到新邮箱,请完成验证后再提交', 'aksrt' );
}
if ($consume) {
delete_transient($key);
}
return true;
}
// 频率限制: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 );
function aksrt_account_rate_limited(int $user_id, string $scene): bool {
$key = 'aksrt_account_rate_' . sanitize_key($scene) . '_' . $user_id;
$count = (int) get_transient($key);
if ($count >= 8) {
return true;
}
// 生成验证码并同步发送,只有真正发信成功后才写入验证码缓存。
$code = str_pad( (string) random_int( 0, 999999 ), 6, '0', STR_PAD_LEFT );
set_transient($key, $count + 1, 10 * MINUTE_IN_SECONDS);
return false;
}
$site_name = get_bloginfo( 'name' );
$sent = \AKSRT\Settings\Settings::send_event_email(
'change_code',
$target_email,
[ '{username}' => $current_user->display_name, '{site_name}' => $site_name, '{code}' => $code ]
);
function aksrt_account_reset_rate(int $user_id, string $scene): void {
delete_transient('aksrt_account_rate_' . sanitize_key($scene) . '_' . $user_id);
}
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' ) ) );
}
function aksrt_account_email_verification_required(): bool {
$settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_all() : [];
return !empty($settings['email_set_captch']);
}
aksrt_store_email_code( $current_user->ID, $scene, $code, $target_email );
add_action('wp_ajax_aksrt_send_account_email_code', function (): void {
if (
!isset($_POST['_settings_nonce'])
|| !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_settings_nonce'])), 'aksrt_account_settings')
) {
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
}
wp_send_json_success( array( 'message' => $success_message ) );
$user_id = get_current_user_id();
$user = wp_get_current_user();
if (!$user_id || !($user instanceof WP_User)) {
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
}
$scene = sanitize_key((string) wp_unslash($_POST['scene'] ?? ''));
if (!in_array($scene, ['verify_email', 'change_email'], true)) {
wp_send_json_error(['message' => __('无效的验证场景', 'aksrt')]);
}
if (!aksrt_account_email_verification_required()) {
wp_send_json_error(['message' => __('邮箱验证码验证未开启', 'aksrt')]);
}
$target = $scene === 'verify_email'
? (string) $user->user_email
: sanitize_email((string) wp_unslash($_POST['new_email'] ?? ''));
if (!is_email($target)) {
wp_send_json_error(['message' => __('邮箱格式错误', 'aksrt')]);
}
if ($scene === 'change_email') {
if (strtolower($target) === strtolower((string) $user->user_email)) {
wp_send_json_error(['message' => __('修改邮箱不能与现邮箱相同', 'aksrt')]);
}
if (email_exists($target)) {
wp_send_json_error(['message' => __('该邮箱已有绑定账号', 'aksrt')]);
}
}
if (function_exists('aksrt_require_captcha')) {
$captcha = aksrt_require_captcha('change_email', wp_unslash($_POST));
if ($captcha !== true) {
wp_send_json_error(aksrt_account_captcha_error_data($captcha));
}
}
$rate_key = 'aksrt_account_email_rate_' . $user_id . '_' . $scene . '_' . md5(strtolower($target));
if (get_transient($rate_key)) {
wp_send_json_error(['message' => __('操作过于频繁,请稍后再试', 'aksrt')]);
}
set_transient($rate_key, true, 60);
$code = str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);
$sent = class_exists('\AKSRT\Settings\Settings')
? \AKSRT\Settings\Settings::send_event_email('change_code', $target, [
'{username}' => $user->display_name,
'{site_name}' => get_bloginfo('name'),
'{code}' => $code,
])
: false;
if (!$sent) {
delete_transient($rate_key);
wp_send_json_error(['message' => __('验证码邮件发送失败,请稍后重试', 'aksrt')]);
}
aksrt_account_store_code($user_id, $scene, $target, $code);
wp_send_json_success([
'message' => $scene === 'verify_email'
? __('验证码已发送到您的老邮箱', 'aksrt')
: __('验证码已发送到新邮箱', 'aksrt'),
'countdown' => 60,
]);
});
// ============================================================
// 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' ) ) );
}
add_action('wp_ajax_aksrt_verify_account_email', function (): void {
if (
!isset($_POST['_settings_nonce'])
|| !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_settings_nonce'])), 'aksrt_account_settings')
) {
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
}
$user_id = get_current_user_id();
if ( ! $user_id ) {
wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) );
}
$user_id = get_current_user_id();
$user = wp_get_current_user();
if (!$user_id || !($user instanceof WP_User) || !is_email((string) $user->user_email)) {
wp_send_json_error(['message' => __('当前账号未绑定有效邮箱', 'aksrt')]);
}
if (!aksrt_account_email_verification_required()) {
wp_send_json_error(['message' => __('邮箱验证码验证未开启', 'aksrt')]);
}
if (function_exists('aksrt_require_captcha')) {
$captcha = aksrt_require_captcha('change_email', wp_unslash($_POST));
if ($captcha !== true) {
wp_send_json_error(aksrt_account_captcha_error_data($captcha));
}
}
$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'] ) : '';
$code = sanitize_text_field((string) wp_unslash($_POST['code'] ?? ''));
if (!aksrt_account_consume_code($user_id, 'verify_email', (string) $user->user_email, $code)) {
wp_send_json_error(['message' => __('验证码错误或已过期', 'aksrt')]);
}
// 验证原密码
$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( aksrt_account_captcha_error_data( $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(),
));
aksrt_account_set_proof($user_id, 'email_old', (string) $user->user_email);
wp_send_json_success(['message' => __('验证成功', 'aksrt')]);
});
// ============================================================
// 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' ) ) );
}
add_action('wp_ajax_aksrt_change_password', function (): void {
if (
!isset($_POST['_settings_nonce'])
|| !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_settings_nonce'])), 'aksrt_account_settings')
) {
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
}
$user_id = get_current_user_id();
if ( ! $user_id ) {
wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) );
}
$user_id = get_current_user_id();
if (!$user_id) {
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
}
$user = get_userdata($user_id);
if (!($user instanceof WP_User)) {
wp_send_json_error(['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'] ) : '';
$oauth_new = (bool) get_user_meta($user_id, 'oauth_new', true);
$password = trim((string) wp_unslash($_POST['password'] ?? ''));
$password2 = trim((string) wp_unslash($_POST['password2'] ?? ''));
if (function_exists('aksrt_require_captcha')) {
$captcha = aksrt_require_captcha('change_password', wp_unslash($_POST));
if ($captcha !== true) {
wp_send_json_error(aksrt_account_captcha_error_data($captcha));
}
}
$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 (!$oauth_new) {
$old_password = trim((string) wp_unslash($_POST['passwordold'] ?? ''));
if ($old_password === '') {
wp_send_json_error(['message' => __('请输入原密码', 'aksrt')]);
}
if ($old_password === $password) {
wp_send_json_error(['message' => __('新密码和原密码不能相同', 'aksrt')]);
}
if (aksrt_account_rate_limited($user_id, 'change_password')) {
wp_send_json_error(['message' => __('错误次数过多,请稍后再试', 'aksrt')]);
}
if (!wp_check_password($old_password, $user->user_pass, $user_id)) {
wp_send_json_error(['message' => __('原密码错误', 'aksrt')]);
}
}
// 验证新邮箱格式
if ( empty( $new_email ) || ! is_email( $new_email ) ) {
wp_send_json_error( array( 'message' => __( '请输入有效的邮箱地址', 'aksrt' ) ) );
}
$valid = class_exists('\AKSRT\Auth\Service')
? \AKSRT\Auth\Service::validate_password($password, $password2)
: __('认证服务不可用', 'aksrt');
if ($valid !== true) {
wp_send_json_error(['message' => (string) $valid]);
}
if ( strtolower( $new_email ) === strtolower( $current_user->user_email ) ) {
wp_send_json_error( array( 'message' => __( '新邮箱与当前邮箱相同', 'aksrt' ) ) );
}
$result = wp_update_user(['ID' => $user_id, 'user_pass' => $password]);
if (is_wp_error($result)) {
wp_send_json_error(['message' => $result->get_error_message()]);
}
// 检查邮箱是否已被使用
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( aksrt_account_captcha_error_data( $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' );
\AKSRT\Settings\Settings::send_event_email(
'change_notice',
$old_email,
[ '{username}' => $current_user->display_name, '{site_name}' => $site_name, '{new_email}' => $new_email ]
);
}
$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,
));
delete_user_meta($user_id, 'oauth_new');
aksrt_account_reset_rate($user_id, 'change_password');
wp_send_json_success([
'message' => $oauth_new
? __('密码设置成功', 'aksrt')
: __('修改成功,下次请使用新密码登录', 'aksrt'),
'reload' => true,
]);
});
add_action('wp_ajax_aksrt_change_email', function (): void {
if (
!isset($_POST['_settings_nonce'])
|| !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_settings_nonce'])), 'aksrt_account_settings')
) {
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
}
$user_id = get_current_user_id();
$user = wp_get_current_user();
if (!$user_id || !($user instanceof WP_User)) {
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
}
$new_email = sanitize_email((string) wp_unslash($_POST['new_email'] ?? ''));
if (!is_email($new_email)) {
wp_send_json_error(['message' => __('邮箱格式错误', 'aksrt')]);
}
if ($user->user_email !== '' && strtolower($new_email) === strtolower((string) $user->user_email)) {
wp_send_json_error(['message' => __('修改邮箱不能与现邮箱相同', 'aksrt')]);
}
if (email_exists($new_email)) {
wp_send_json_error(['message' => __('该邮箱已有绑定账号', 'aksrt')]);
}
$agreement = function_exists('aksrt_get_auth_agreement_view') ? aksrt_get_auth_agreement_view() : ['enabled' => false, 'required' => false];
if (!empty($agreement['required']) && empty($_POST['agree_terms'])) {
wp_send_json_error(['message' => __('请先同意相关协议', 'aksrt')]);
}
if (function_exists('aksrt_require_captcha')) {
$captcha = aksrt_require_captcha('change_email', wp_unslash($_POST));
if ($captcha !== true) {
wp_send_json_error(aksrt_account_captcha_error_data($captcha));
}
}
$verification_required = aksrt_account_email_verification_required();
$old_email = (string) $user->user_email;
if (
$old_email !== ''
&& $verification_required
&& !aksrt_account_consume_proof($user_id, 'email_old', $old_email, false)
) {
wp_send_json_error(['message' => __('请先验证老邮箱', 'aksrt')]);
}
if (
$verification_required
&& !aksrt_account_consume_code(
$user_id,
'change_email',
$new_email,
sanitize_text_field((string) wp_unslash($_POST['code'] ?? '')),
false
)
) {
wp_send_json_error(['message' => __('验证码错误或已过期', 'aksrt')]);
}
$result = wp_update_user(['ID' => $user_id, 'user_email' => $new_email]);
if (is_wp_error($result)) {
wp_send_json_error(['message' => $result->get_error_message() ?: __('邮箱更新失败,请稍后重试', 'aksrt')]);
}
if ($old_email !== '' && $verification_required) {
delete_transient(aksrt_account_proof_key($user_id, 'email_old'));
}
if ($verification_required) {
delete_transient(aksrt_account_code_key($user_id, 'change_email', $new_email));
}
update_user_meta($user_id, 'aksrt_email_verified', 1);
if ($old_email !== '' && is_email($old_email) && class_exists('\AKSRT\Settings\Settings')) {
\AKSRT\Settings\Settings::send_event_email('change_notice', $old_email, [
'{username}' => $user->display_name,
'{site_name}' => get_bloginfo('name'),
'{new_email}' => $new_email,
]);
}
wp_send_json_success([
'message' => $old_email !== '' ? __('邮箱修改成功', 'aksrt') : __('邮箱绑定成功', 'aksrt'),
'reload' => true,
]);
});