refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.
Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)
Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
(dropped 3 stale entries, added the 17 missing ones)
Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
when it is empty
Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.
Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5b16bc6e15
commit
35bb96e82f
997 files changed
+28216
-28188
No files matched your search
+47
-47
@@ -2,21 +2,21 @@
|
||||
/**
|
||||
* WeChat Official Account QR and verification-code authentication.
|
||||
*
|
||||
* @package AKSRT
|
||||
* @package Jio
|
||||
*/
|
||||
|
||||
namespace AKSRT\Auth;
|
||||
namespace Jio\Auth;
|
||||
|
||||
use AKSRT\Settings\Settings;
|
||||
use Jio\Settings\Settings;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class WeixinGzh {
|
||||
|
||||
private const ACCESS_OPTION = 'aksrt_weixingzh_access_token';
|
||||
private const SCENE_OPTION_PREFIX = 'aksrt_weixingzh_scene_';
|
||||
private const CODE_OPTION_PREFIX = 'aksrt_weixingzh_code_';
|
||||
private const DEDUPE_OPTION_PREFIX = 'aksrt_weixingzh_event_';
|
||||
private const ACCESS_OPTION = 'jio_weixingzh_access_token';
|
||||
private const SCENE_OPTION_PREFIX = 'jio_weixingzh_scene_';
|
||||
private const CODE_OPTION_PREFIX = 'jio_weixingzh_code_';
|
||||
private const DEDUPE_OPTION_PREFIX = 'jio_weixingzh_event_';
|
||||
private const SCAN_KIND = 'weixingzh_scan';
|
||||
private const CODE_KIND = 'weixingzh_code';
|
||||
private const SCAN_TTL = 5 * MINUTE_IN_SECONDS;
|
||||
@@ -42,17 +42,17 @@ final class WeixinGzh {
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
register_rest_route('aksrt/v1', '/auth/qrcode-login', [
|
||||
register_rest_route('jio/v1', '/auth/qrcode-login', [
|
||||
'methods' => ['GET', 'POST'],
|
||||
'callback' => [$this, 'rest_qrcode_login'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
register_rest_route('aksrt/v1', '/auth/check-qrcode-login', [
|
||||
register_rest_route('jio/v1', '/auth/check-qrcode-login', [
|
||||
'methods' => ['GET', 'POST'],
|
||||
'callback' => [$this, 'rest_check_qrcode_login'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
register_rest_route('aksrt/v1', '/auth/weixingzh-code', [
|
||||
register_rest_route('jio/v1', '/auth/weixingzh-code', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'rest_code_login'],
|
||||
'permission_callback' => '__return_true',
|
||||
@@ -96,7 +96,7 @@ final class WeixinGzh {
|
||||
return $limited;
|
||||
}
|
||||
if (!self::is_enabled()) {
|
||||
return $this->error_response(__('微信公众号登录未开启或配置不完整', 'aksrt'), 400);
|
||||
return $this->error_response(__('微信公众号登录未开启或配置不完整', 'jio'), 400);
|
||||
}
|
||||
$context = $this->request_context($request);
|
||||
if (is_wp_error($context)) {
|
||||
@@ -108,7 +108,7 @@ final class WeixinGzh {
|
||||
$data = $this->request_data($request);
|
||||
$bind_pass = sanitize_text_field((string) ($data['bind_pass'] ?? ''));
|
||||
if (!OAuth::validate_bind_pass($bind_pass, 'weixingzh', $context['user_id'], false)) {
|
||||
return $this->error_response(__('请先完成人机验证后再绑定', 'aksrt'), 403);
|
||||
return $this->error_response(__('请先完成人机验证后再绑定', 'jio'), 403);
|
||||
}
|
||||
$context['bind_pass'] = $bind_pass;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ final class WeixinGzh {
|
||||
|
||||
$appid = trim((string) ($config['appid'] ?? ''));
|
||||
$secret = trim((string) ($config['appsecret'] ?? ''));
|
||||
$scene = 'aksrt_' . rtrim(strtr(base64_encode(random_bytes(18)), '+/', '-_'), '=');
|
||||
$scene = 'jio_' . rtrim(strtr(base64_encode(random_bytes(18)), '+/', '-_'), '=');
|
||||
$transaction = '';
|
||||
try {
|
||||
$transaction = OAuthTransactionStore::issue(self::SCAN_KIND, [
|
||||
@@ -147,8 +147,8 @@ final class WeixinGzh {
|
||||
throw new \RuntimeException((string) ($created['errmsg'] ?? 'qrcode_create_failed'));
|
||||
}
|
||||
$image = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . rawurlencode((string) $created['ticket']);
|
||||
$html = '<img class="signin-qrcode-img" src="' . esc_url($image) . '" alt="' . esc_attr__('微信公众号扫码登录二维码', 'aksrt') . '" style="width:160px;height:160px;" />';
|
||||
$html .= '<p class="text-center mt10 em09 muted-2-color"><i class="fa fab fa-weixin c-green"></i> ' . esc_html__('微信扫码登录', 'aksrt') . '</p>';
|
||||
$html = '<img class="signin-qrcode-img" src="' . esc_url($image) . '" alt="' . esc_attr__('微信公众号扫码登录二维码', 'jio') . '" style="width:160px;height:160px;" />';
|
||||
$html .= '<p class="text-center mt10 em09 muted-2-color"><i class="fa fab fa-weixin c-green"></i> ' . esc_html__('微信扫码登录', 'jio') . '</p>';
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
@@ -164,7 +164,7 @@ final class WeixinGzh {
|
||||
OAuthTransactionStore::delete($transaction);
|
||||
$this->delete_scene_mapping($scene, $transaction);
|
||||
}
|
||||
return $this->error_response(__('创建微信登录二维码失败,请稍后重试', 'aksrt'), 502);
|
||||
return $this->error_response(__('创建微信登录二维码失败,请稍后重试', 'jio'), 502);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,12 +174,12 @@ final class WeixinGzh {
|
||||
return $limited;
|
||||
}
|
||||
if (!self::is_enabled()) {
|
||||
return $this->error_response(__('微信公众号登录未开启或配置不完整', 'aksrt'), 400);
|
||||
return $this->error_response(__('微信公众号登录未开启或配置不完整', 'jio'), 400);
|
||||
}
|
||||
$data = $this->request_data($request);
|
||||
$token = sanitize_text_field((string) ($data['token'] ?? ''));
|
||||
if ($token === '') {
|
||||
return $this->error_response(__('缺少 token', 'aksrt'), 400);
|
||||
return $this->error_response(__('缺少 token', 'jio'), 400);
|
||||
}
|
||||
$row = OAuthTransactionStore::peek($token, self::SCAN_KIND, true);
|
||||
if (!$row) {
|
||||
@@ -194,7 +194,7 @@ final class WeixinGzh {
|
||||
], 200);
|
||||
}
|
||||
if (!$this->binding_user_matches($payload)) {
|
||||
return $this->error_response(__('绑定会话与当前用户不匹配', 'aksrt'), 403);
|
||||
return $this->error_response(__('绑定会话与当前用户不匹配', 'jio'), 403);
|
||||
}
|
||||
$claimed = OAuthTransactionStore::claim($token, self::SCAN_KIND, true);
|
||||
if (!$claimed) {
|
||||
@@ -210,12 +210,12 @@ final class WeixinGzh {
|
||||
return $limited;
|
||||
}
|
||||
if (!self::is_enabled()) {
|
||||
return $this->error_response(__('微信公众号登录未开启或配置不完整', 'aksrt'), 400);
|
||||
return $this->error_response(__('微信公众号登录未开启或配置不完整', 'jio'), 400);
|
||||
}
|
||||
$data = $this->request_data($request);
|
||||
$code = strtoupper(sanitize_text_field((string) ($data['code'] ?? '')));
|
||||
if (preg_match('/^[A-Z0-9]{6,12}$/', $code) !== 1) {
|
||||
return $this->error_response(__('请输入至少 6 位的有效验证码', 'aksrt'), 400);
|
||||
return $this->error_response(__('请输入至少 6 位的有效验证码', 'jio'), 400);
|
||||
}
|
||||
$context = $this->request_context($request);
|
||||
if (is_wp_error($context)) {
|
||||
@@ -225,12 +225,12 @@ final class WeixinGzh {
|
||||
if ($context['action'] === 'bind') {
|
||||
$bind_pass = sanitize_text_field((string) ($data['bind_pass'] ?? ''));
|
||||
if (!OAuth::validate_bind_pass($bind_pass, 'weixingzh', $context['user_id'], false)) {
|
||||
return $this->error_response(__('请先完成人机验证后再绑定', 'aksrt'), 403);
|
||||
return $this->error_response(__('请先完成人机验证后再绑定', 'jio'), 403);
|
||||
}
|
||||
}
|
||||
$claimed = $this->claim_code_transaction($code, $context);
|
||||
if (!$claimed) {
|
||||
return $this->error_response(__('验证码无效、已过期或尝试次数过多', 'aksrt'), 400);
|
||||
return $this->error_response(__('验证码无效、已过期或尝试次数过多', 'jio'), 400);
|
||||
}
|
||||
$payload = is_array($claimed['payload'] ?? null) ? $claimed['payload'] : [];
|
||||
if ($context['action'] === 'bind') {
|
||||
@@ -243,7 +243,7 @@ final class WeixinGzh {
|
||||
* WeChat server URL verification.
|
||||
*/
|
||||
public function maybe_server_verify(): void {
|
||||
if (empty($_GET['aksrt_weixingzh']) || ($_SERVER['REQUEST_METHOD'] ?? '') !== 'GET' || !isset($_GET['echostr'])) {
|
||||
if (empty($_GET['jio_weixingzh']) || ($_SERVER['REQUEST_METHOD'] ?? '') !== 'GET' || !isset($_GET['echostr'])) {
|
||||
return;
|
||||
}
|
||||
if (!self::is_enabled() || !$this->verify_webhook_signature()) {
|
||||
@@ -264,7 +264,7 @@ final class WeixinGzh {
|
||||
* Receive plaintext WeChat server messages.
|
||||
*/
|
||||
public function maybe_server_message(): void {
|
||||
if (empty($_GET['aksrt_weixingzh']) || ($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST' || isset($_GET['echostr'])) {
|
||||
if (empty($_GET['jio_weixingzh']) || ($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST' || isset($_GET['echostr'])) {
|
||||
return;
|
||||
}
|
||||
if (!self::is_enabled() || !$this->verify_webhook_signature()) {
|
||||
@@ -312,18 +312,18 @@ final class WeixinGzh {
|
||||
*/
|
||||
private function code_mode_response(array $config, array $context): \WP_REST_Response {
|
||||
$qr = trim((string) ($config['code_qrcode'] ?? ''));
|
||||
$keyword = trim((string) ($config['code_keyword'] ?? __('登录', 'aksrt')));
|
||||
$html = '<img class="signin-qrcode-img" src="' . esc_url($qr) . '" alt="' . esc_attr__('微信公众号验证码登录二维码', 'aksrt') . '" style="width:160px;height:160px;object-fit:contain;" />';
|
||||
$html .= '<form class="aksrt-weixingzh-code-form" data-aksrt-weixingzh-code>';
|
||||
$html .= '<p class="muted-2-color em09">' . esc_html(sprintf(__('关注公众号后发送「%s」获取验证码', 'aksrt'), $keyword)) . '</p>';
|
||||
$keyword = trim((string) ($config['code_keyword'] ?? __('登录', 'jio')));
|
||||
$html = '<img class="signin-qrcode-img" src="' . esc_url($qr) . '" alt="' . esc_attr__('微信公众号验证码登录二维码', 'jio') . '" style="width:160px;height:160px;object-fit:contain;" />';
|
||||
$html .= '<form class="jio-weixingzh-code-form" data-jio-weixingzh-code>';
|
||||
$html .= '<p class="muted-2-color em09">' . esc_html(sprintf(__('关注公众号后发送「%s」获取验证码', 'jio'), $keyword)) . '</p>';
|
||||
$html .= '<input type="hidden" name="action" value="' . esc_attr($context['action']) . '" />';
|
||||
$html .= '<input type="hidden" name="user_id" value="' . esc_attr((string) $context['user_id']) . '" />';
|
||||
$html .= '<input type="hidden" name="redirect_to" value="' . esc_attr($context['redirect_to']) . '" />';
|
||||
if (!empty($context['bind_pass'])) {
|
||||
$html .= '<input type="hidden" name="bind_pass" value="' . esc_attr((string) $context['bind_pass']) . '" />';
|
||||
}
|
||||
$html .= '<input type="text" name="code" class="form-control" minlength="6" maxlength="12" autocomplete="one-time-code" placeholder="' . esc_attr__('请输入验证码', 'aksrt') . '" required />';
|
||||
$html .= '<button type="submit" class="but c-blue btn-block mt10">' . esc_html__('登录', 'aksrt') . '</button>';
|
||||
$html .= '<input type="text" name="code" class="form-control" minlength="6" maxlength="12" autocomplete="one-time-code" placeholder="' . esc_attr__('请输入验证码', 'jio') . '" required />';
|
||||
$html .= '<button type="submit" class="but c-blue btn-block mt10">' . esc_html__('登录', 'jio') . '</button>';
|
||||
$html .= '</form>';
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
@@ -341,10 +341,10 @@ final class WeixinGzh {
|
||||
$requested_user_id = isset($data['user_id']) ? (int) $data['user_id'] : 0;
|
||||
if ($action === 'bind') {
|
||||
if ($current_user_id <= 0) {
|
||||
return new \WP_Error('weixingzh_bind_login_required', __('请先登录后再绑定微信公众号', 'aksrt'));
|
||||
return new \WP_Error('weixingzh_bind_login_required', __('请先登录后再绑定微信公众号', 'jio'));
|
||||
}
|
||||
if ($requested_user_id > 0 && $requested_user_id !== $current_user_id) {
|
||||
return new \WP_Error('weixingzh_bind_user_mismatch', __('绑定请求与当前用户不匹配', 'aksrt'));
|
||||
return new \WP_Error('weixingzh_bind_user_mismatch', __('绑定请求与当前用户不匹配', 'jio'));
|
||||
}
|
||||
}
|
||||
$redirect = OAuthUrlPolicy::validated_redirect((string) ($data['redirect_to'] ?? ''), home_url('/'));
|
||||
@@ -381,7 +381,7 @@ final class WeixinGzh {
|
||||
private function complete_browser_identity(array $payload): \WP_REST_Response {
|
||||
$openid = trim((string) ($payload['openid'] ?? ''));
|
||||
if ($openid === '') {
|
||||
return $this->error_response(__('微信身份信息无效', 'aksrt'), 400);
|
||||
return $this->error_response(__('微信身份信息无效', 'jio'), 400);
|
||||
}
|
||||
$profile = is_array($payload['profile'] ?? null) ? $payload['profile'] : [];
|
||||
$identity = [
|
||||
@@ -395,17 +395,17 @@ final class WeixinGzh {
|
||||
];
|
||||
if ((string) ($payload['action'] ?? 'login') === 'bind') {
|
||||
if (!$this->binding_user_matches($payload)) {
|
||||
return $this->error_response(__('绑定会话与当前用户不匹配', 'aksrt'), 403);
|
||||
return $this->error_response(__('绑定会话与当前用户不匹配', 'jio'), 403);
|
||||
}
|
||||
$bind_pass = sanitize_text_field((string) ($payload['bind_pass'] ?? ''));
|
||||
if (!OAuth::validate_bind_pass($bind_pass, 'weixingzh', get_current_user_id(), true)) {
|
||||
return $this->error_response(__('绑定验证已过期,请重新完成人机验证', 'aksrt'), 403);
|
||||
return $this->error_response(__('绑定验证已过期,请重新完成人机验证', 'jio'), 403);
|
||||
}
|
||||
$result = OAuthAccountService::bind(get_current_user_id(), 'weixingzh', $identity);
|
||||
if (is_wp_error($result)) {
|
||||
return $this->error_response($result->get_error_message(), 409);
|
||||
}
|
||||
$redirect = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url('settings') : home_url('/');
|
||||
$redirect = function_exists('jio_get_user_center_url') ? jio_get_user_center_url('settings') : home_url('/');
|
||||
$redirect = add_query_arg(['oauth_action' => 'bind', 'oauth_provider' => 'weixingzh'], $redirect);
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
@@ -423,8 +423,8 @@ final class WeixinGzh {
|
||||
'user_data' => $identity,
|
||||
'redirect_to' => $redirect,
|
||||
], 15 * MINUTE_IN_SECONDS, true);
|
||||
$bind_url = function_exists('aksrt_get_bind_url')
|
||||
? aksrt_get_bind_url($obk)
|
||||
$bind_url = function_exists('jio_get_bind_url')
|
||||
? jio_get_bind_url($obk)
|
||||
: add_query_arg(['tab' => 'bind', 'obk' => $obk], home_url('/sign/'));
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
@@ -436,11 +436,11 @@ final class WeixinGzh {
|
||||
],
|
||||
], 200);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error_response(__('无法创建账号绑定会话,请重试', 'aksrt'), 500);
|
||||
return $this->error_response(__('无法创建账号绑定会话,请重试', 'jio'), 500);
|
||||
}
|
||||
}
|
||||
if (!$user instanceof \WP_User) {
|
||||
return $this->error_response(is_wp_error($user) ? $user->get_error_message() : __('微信账号匹配失败', 'aksrt'), 400);
|
||||
return $this->error_response(is_wp_error($user) ? $user->get_error_message() : __('微信账号匹配失败', 'jio'), 400);
|
||||
}
|
||||
OAuthAccountService::complete_login($user, true);
|
||||
$redirect = OAuthUrlPolicy::validated_redirect((string) ($payload['redirect_to'] ?? ''), home_url('/'));
|
||||
@@ -500,7 +500,7 @@ final class WeixinGzh {
|
||||
$code = $this->issue_code($from);
|
||||
$template = trim((string) ($config['code_reply'] ?? ''));
|
||||
if ($template === '') {
|
||||
$template = __('您的验证码是:%s,有效期 %d 分钟。', 'aksrt');
|
||||
$template = __('您的验证码是:%s,有效期 %d 分钟。', 'jio');
|
||||
}
|
||||
$message = str_replace(['%code%', '%time%', '%s', '%d'], [$code, '5', $code, '5'], $template);
|
||||
$this->echo_text_reply($from, $to, $message);
|
||||
@@ -854,14 +854,14 @@ final class WeixinGzh {
|
||||
}
|
||||
|
||||
private function rate_limit(string $scope, int $max, int $window, int $minimum_interval): ?\WP_REST_Response {
|
||||
$ip = function_exists('aksrt_get_client_ip')
|
||||
? trim((string) aksrt_get_client_ip())
|
||||
$ip = function_exists('jio_get_client_ip')
|
||||
? trim((string) jio_get_client_ip())
|
||||
: trim((string) ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
|
||||
$key = 'aksrt_weixingzh_rate_' . hash('sha256', $scope . '|' . $ip);
|
||||
$key = 'jio_weixingzh_rate_' . hash('sha256', $scope . '|' . $ip);
|
||||
$lock_scope = 'weixingzh-rate:' . $key;
|
||||
$lock = OAuthTransactionStore::acquire_lock($lock_scope, 5);
|
||||
if ($lock === false) {
|
||||
return $this->error_response(__('请求过于频繁,请稍后重试', 'aksrt'), 429);
|
||||
return $this->error_response(__('请求过于频繁,请稍后重试', 'jio'), 429);
|
||||
}
|
||||
try {
|
||||
$now = time();
|
||||
@@ -871,7 +871,7 @@ final class WeixinGzh {
|
||||
}
|
||||
$last_at = (float) ($row['last_at'] ?? 0);
|
||||
if ((int) ($row['count'] ?? 0) >= $max || microtime(true) - $last_at < $minimum_interval) {
|
||||
return $this->error_response(__('请求过于频繁,请稍后重试', 'aksrt'), 429);
|
||||
return $this->error_response(__('请求过于频繁,请稍后重试', 'jio'), 429);
|
||||
}
|
||||
$row['count'] = (int) $row['count'] + 1;
|
||||
$row['last_at'] = microtime(true);
|
||||
|
||||
Reference in new issue
Block a user