fix(oauth): actually use the third-party avatar and seed it only once
The OAuth flow wrote the provider avatar to `jio_oauth_avatar`, but nothing ever read it — every user who signed up through GitHub/QQ saw a Gravatar hash or the default avatar instead of their own picture. The reference seeds its `custom_avatar` from the OAuth profile and its resolver reads it back, so both halves were missing here. jio_get_custom_avatar_url() now falls back to the stored OAuth avatar when no uploaded one exists, which puts the chain at uploaded → third-party → external service → default. The theme already swaps WordPress's get_avatar_data, so one change covers every avatar surface. Writes go through a single seed_avatar() guard: it no-ops when an uploaded avatar or an existing OAuth avatar is present, matching the reference's `if ($args['avatar'] && !$custom_avatar)`. Previously both the bind path and the login refresh overwrote the meta unconditionally, which would have wiped a user's own picture on their next social login. Because the OAuth avatar now shows through once the upload is gone, both "restore default" flows (the REST endpoint and the admin profile box) delete it too; the admin checkbox also appears when only an OAuth avatar is set, since $avatar_url is now non-empty in that case. Baidu serves avatars from tb.himg.baidu.com, which 403s — rewritten to himg.bdimg.com the way the reference does. On top of that the URL is upgraded to https when the site runs over SSL, because the reference's scheme-relative form still yields a plain http:// when copied verbatim, and browsers block it as mixed content. WeChatShare was reading `custom_avatar` — a reference-theme key this codebase never writes — so its author branch always fell through to get_avatar_url(); it now uses the shared resolver like every other surface. Verification: drove the resolver through five states with a stub (none / OAuth only / both / upload only / Baidu legacy host) and confirmed the expected URL each time. Added oauth-avatar-contract.test.cjs to pin the resolution order, the seed guard, and the reset cleanup. 868 widget and navigation tests pass; the PSR-4 path audit reports 0 errors.
This commit is contained in:
1 parent
7d78a33a9d
commit
6f29e3d865
6 files changed
+137
-16
No files matched your search
@@ -71,9 +71,7 @@ final class OAuthAccountService {
|
||||
$bindings[] = $provider;
|
||||
}
|
||||
update_user_meta($user_id, 'jio_oauth_bindings', array_values(array_unique($bindings)));
|
||||
if (!empty($identity['avatar_url'])) {
|
||||
update_user_meta($user_id, 'jio_oauth_avatar', esc_url_raw((string) $identity['avatar_url']));
|
||||
}
|
||||
self::seed_avatar($user_id, $identity);
|
||||
return true;
|
||||
} finally {
|
||||
OAuthTransactionStore::release_lock($scope, (string) $lock);
|
||||
@@ -114,9 +112,27 @@ final class OAuthAccountService {
|
||||
$bindings[] = $provider;
|
||||
update_user_meta($user_id, 'jio_oauth_bindings', array_values(array_unique($bindings)));
|
||||
}
|
||||
if (!empty($identity['avatar_url'])) {
|
||||
update_user_meta($user_id, 'jio_oauth_avatar', esc_url_raw((string) $identity['avatar_url']));
|
||||
self::seed_avatar($user_id, $identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 建档或首次绑定时以第三方头像补齐,之后不再覆盖。
|
||||
*
|
||||
* 参考主题只在用户没有自定义头像时写入(`if ($args['avatar'] && !$custom_avatar)`),
|
||||
* 这样用户换过的头像不会被后续第三方登录冲掉。
|
||||
*/
|
||||
private static function seed_avatar(int $user_id, array $identity): void {
|
||||
$avatar = trim((string) ($identity['avatar_url'] ?? ''));
|
||||
if ($user_id <= 0 || $avatar === '') {
|
||||
return;
|
||||
}
|
||||
if ((int) get_user_meta($user_id, 'jio_avatar_attachment_id', true) > 0) {
|
||||
return;
|
||||
}
|
||||
if (trim((string) get_user_meta($user_id, 'jio_oauth_avatar', true)) !== '') {
|
||||
return;
|
||||
}
|
||||
update_user_meta($user_id, 'jio_oauth_avatar', esc_url_raw($avatar));
|
||||
}
|
||||
|
||||
private static function has_recovery_after_unbind(int $user_id, string $provider): bool {
|
||||
|
||||
Reference in new issue
Block a user