Files
wordpress-theme-aksrt/src/Auth/OAuthProviderCatalog.php
T
kate522 b1c3d86e44 refactor(oauth): drop the hand-written providers and keep only what the SDK ships
The previous commit added five direct clients (Douyin, Microsoft, Facebook,
Twitter, Apple) written against each platform's own endpoints. Maintaining
five bespoke OAuth implementations — including Apple's ES256 client secret and
Twitter's PKCE — is maintenance the bundled yurunsoft SDK does not ask for,
and none of them could be verified without production credentials.

Only providers yurunsoft/yurun-oauth-login actually implements stay on the
direct surface: GitHub, Gitee, QQ, Google, Weibo, Weixin, Baidu and Alipay.
Baidu and Alipay move into OAuthProviderBroker's existing client() switch and
normalize() map rather than living in a separate class, so there is no new
layer to reason about.

OAuthProviderClient, its harness and its contract test are deleted outright
(-809 lines). The Apple form_post handling added to handle_callback() is
reverted too — without Apple there is no POST callback to read.

The aggregate-login channel keeps its 16 platforms, matching the reference;
that list describes what the aggregation provider offers, not a local
implementation. Brand icons for those names stay for the same reason.

Verification: 869 widget/navigation tests pass, the PSR-4 audit reports 0
errors, and the catalog constant, PHP schema and Vue schema now list the same
16 aggregate platforms.
2026-11-04 18:33:37 +08:00

226 lines
6.9 KiB
PHP

<?php
/**
* @package Jio
*/
namespace Jio\Auth;
use Jio\Settings\Settings;
defined('ABSPATH') || exit;
final class OAuthProviderCatalog {
private const DIRECT = [
'github' => [
'label' => 'GitHub',
'id_key' => 'github_appid',
'secret_key' => 'github_appkey',
],
'gitee' => [
'label' => 'Gitee',
'id_key' => 'gitee_appid',
'secret_key' => 'gitee_appkey',
],
'qq' => [
'label' => 'QQ',
'id_key' => 'qq_appid',
'secret_key' => 'qq_appkey',
],
'google' => [
'label' => 'Google',
'id_key' => 'google_client_id',
'secret_key' => 'google_client_secret',
],
'weibo' => [
'label' => 'Weibo',
'id_key' => 'weibo_appid',
'secret_key' => 'weibo_appkey',
],
'weixin' => [
'label' => 'WeChat',
'id_key' => 'weixin_appid',
'secret_key' => 'weixin_appsecret',
],
'baidu' => [
'label' => '百度',
'id_key' => 'baidu_appid',
'secret_key' => 'baidu_appkey',
],
'alipay' => [
'label' => '支付宝',
'id_key' => 'alipay_appid',
'secret_key' => 'alipay_appkey',
'extra_keys' => ['private_key' => 'alipay_private_key'],
],
];
/** 彩虹聚合登录支持的平台,与参考主题一致。 */
public const CLOGIN_TYPES = [
'qq', 'weixin', 'alipay', 'weibo', 'douyin', 'baidu', 'github', 'gitee',
'dingtalk', 'huawei', 'xiaomi', 'google', 'microsoft', 'facebook', 'twitter', 'apple',
];
public static function direct_keys(): array {
return array_keys(self::DIRECT);
}
public static function all_binding_keys(): array {
$keys = array_merge(self::direct_keys(), ['weixingzh']);
foreach (self::CLOGIN_TYPES as $type) {
$keys[] = 'clogin_' . $type;
}
return $keys;
}
public static function is_direct(string $provider): bool {
return isset(self::DIRECT[sanitize_key($provider)]);
}
public static function is_binding_provider(string $provider): bool {
return in_array(sanitize_key($provider), self::all_binding_keys(), true);
}
public static function label(string $provider): string {
$provider = sanitize_key($provider);
if (isset(self::DIRECT[$provider])) {
return self::DIRECT[$provider]['label'];
}
if ($provider === 'weixingzh') {
return __('微信公众号', 'jio');
}
if (str_starts_with($provider, 'clogin_')) {
$type = substr($provider, 7);
if (in_array($type, self::CLOGIN_TYPES, true)) {
return self::label($type) . ' · ' . __('聚合', 'jio');
}
}
return ucfirst($provider);
}
public static function icon_key(string $provider): string {
$provider = sanitize_key($provider);
return str_starts_with($provider, 'clogin_') ? substr($provider, 7) : $provider;
}
public static function master_enabled(): bool {
return !Settings::close_sign() && (bool) Settings::get_value('oauth_s', false);
}
public static function provider_config(string $provider): ?array {
$provider = sanitize_key($provider);
if (!isset(self::DIRECT[$provider])) {
return null;
}
$settings = Settings::get_all();
$definition = self::DIRECT[$provider];
$client_id = trim((string) ($settings[$definition['id_key']] ?? ''));
$client_secret = trim((string) ($settings[$definition['secret_key']] ?? ''));
$extra = [];
foreach ((array) ($definition['extra_keys'] ?? []) as $field => $setting_key) {
$extra[$field] = trim((string) ($settings[$setting_key] ?? ''));
}
return [
'provider' => $provider,
'enabled' => self::master_enabled() && !empty($settings['oauth_' . $provider . '_s']),
'client_id' => $client_id,
'client_secret' => $client_secret,
'configured' => $client_id !== '' && $client_secret !== '',
] + $extra;
}
public static function enabled_direct_keys(): array {
if (!self::master_enabled()) {
return [];
}
$result = [];
foreach (self::direct_keys() as $provider) {
$config = self::provider_config($provider);
if ($config && $config['enabled'] && $config['configured']) {
$result[] = $provider;
}
}
return $result;
}
public static function proxy_mode(): string {
$mode = sanitize_key((string) Settings::get_value('oauth_proxy_mode', 'close'));
return in_array($mode, ['close', 'server', 'client'], true) ? $mode : 'close';
}
public static function proxy_secret(): string {
return trim((string) Settings::get_value('oauth_proxy_secret', ''));
}
public static function proxy_server_url(): string {
return esc_url_raw(trim((string) Settings::get_value('oauth_proxy_server_url', '')));
}
public static function proxy_server_providers(): array {
$providers = (array) Settings::get_value('oauth_proxy_server_providers', []);
$result = [];
foreach (array_values(array_intersect(array_map('sanitize_key', $providers), self::direct_keys())) as $provider) {
$config = self::provider_config($provider);
if ($config && $config['configured']) {
$result[] = $provider;
}
}
return $result;
}
public static function proxy_client_providers(): array {
$providers = (array) Settings::get_value('oauth_proxy_client_providers', []);
return array_values(array_intersect(array_map('sanitize_key', $providers), self::direct_keys()));
}
public static function bind_type(): string {
$type = sanitize_key((string) Settings::get_value('oauth_bind_type', 'auto'));
return in_array($type, ['auto', 'manual'], true) ? $type : 'auto';
}
public static function clogin_settings(): array {
$settings = Settings::get_all();
$raw = (array) ($settings['clogin_oauth_s'] ?? self::CLOGIN_TYPES);
$types = array_values(array_intersect(array_map('sanitize_key', $raw), self::CLOGIN_TYPES));
return [
'enabled' => self::master_enabled() && !empty($settings['clogin_s']),
'url' => esc_url_raw(trim((string) ($settings['clogin_url'] ?? ''))),
'id' => trim((string) ($settings['clogin_id'] ?? '')),
'key' => trim((string) ($settings['clogin_key'] ?? '')),
'types' => $types,
];
}
public static function enabled_login_keys(): array {
if (!self::master_enabled()) {
return [];
}
if (self::proxy_mode() === 'client') {
if (self::proxy_server_url() === '' || self::proxy_secret() === '') {
return [];
}
return self::proxy_client_providers();
}
$result = self::enabled_direct_keys();
$settings = Settings::get_all();
if (!empty($settings['oauth_weixingzh_s'])) {
$gzh_type = sanitize_key((string) ($settings['weixingzh_gzh_type'] ?? 'service'));
$has_base = trim((string) ($settings['weixingzh_token'] ?? '')) !== ''
&& trim((string) ($settings['weixingzh_appid'] ?? '')) !== '';
$has_mode = $gzh_type === 'subscribe'
? trim((string) ($settings['weixingzh_code_qrcode'] ?? '')) !== ''
: trim((string) ($settings['weixingzh_appsecret'] ?? '')) !== '';
if ($has_base && $has_mode) {
$result[] = 'weixingzh';
}
}
$clogin = self::clogin_settings();
if ($clogin['enabled'] && $clogin['url'] !== '' && $clogin['id'] !== '' && $clogin['key'] !== '') {
foreach ($clogin['types'] as $type) {
$result[] = 'clogin_' . $type;
}
}
return array_values(array_unique($result));
}
}