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>
330 lines
20 KiB
PHP
330 lines
20 KiB
PHP
<?php
|
|
/** Phone binding and native profile persistence contract harness. */
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace {
|
|
define('ABSPATH', __DIR__ . '/');
|
|
define('MINUTE_IN_SECONDS', 60);
|
|
define('HOUR_IN_SECONDS', 3600);
|
|
$GLOBALS['jio_profile_meta'] = [];
|
|
$GLOBALS['jio_profile_users'] = [];
|
|
$GLOBALS['jio_nonce_valid'] = true;
|
|
$GLOBALS['jio_can_edit_user'] = true;
|
|
$GLOBALS['jio_current_user_id'] = 7;
|
|
$GLOBALS['jio_transients'] = [];
|
|
$GLOBALS['jio_expected_sms_code'] = '246810';
|
|
|
|
final class WP_User {
|
|
public function __construct(public int $ID) {}
|
|
}
|
|
|
|
final class WP_Error {
|
|
private array $errors = [];
|
|
public function add(string $code, string $message): void { $this->errors[$code][] = $message; }
|
|
public function get_error_codes(): array { return array_keys($this->errors); }
|
|
}
|
|
final class WP_REST_Request {
|
|
public function __construct(private array $params = [], private string $nonce = 'ok') {}
|
|
public function get_json_params(): array { return $this->params; }
|
|
public function get_header(string $name): string { return $name === 'X-WP-Nonce' ? $this->nonce : ''; }
|
|
}
|
|
final class WP_REST_Response {
|
|
public function __construct(public array $data, public int $status = 200) {}
|
|
}
|
|
function is_wp_error($value): bool { return $value instanceof WP_Error; }
|
|
|
|
function is_admin(): bool { return true; }
|
|
function current_user_can(string $capability, ...$args): bool {
|
|
$GLOBALS['jio_capability_checks'][] = [$capability, ...$args];
|
|
return $GLOBALS['jio_can_edit_user'];
|
|
}
|
|
function is_user_logged_in(): bool { return true; }
|
|
function get_current_user_id(): int { return (int) ($GLOBALS['jio_current_user_id'] ?? 7); }
|
|
function get_user_meta(int $user_id, string $key, bool $single = false) {
|
|
$value = $GLOBALS['jio_profile_meta'][$user_id][$key] ?? '';
|
|
return $single ? $value : ($value === '' ? [] : [$value]);
|
|
}
|
|
function update_user_meta(int $user_id, string $key, $value): bool {
|
|
$GLOBALS['jio_profile_meta'][$user_id][$key] = $value;
|
|
return true;
|
|
}
|
|
function get_users(array $args = []): array {
|
|
$results = [];
|
|
foreach ($GLOBALS['jio_profile_meta'] as $user_id => $meta) {
|
|
if (in_array((int) $user_id, array_map('intval', $args['exclude'] ?? []), true)) continue;
|
|
if (($meta[$args['meta_key'] ?? ''] ?? null) !== ($args['meta_value'] ?? null)) continue;
|
|
$results[] = in_array(($args['fields'] ?? ''), ['ids', 'ID'], true) ? (int) $user_id : new WP_User((int) $user_id);
|
|
if (count($results) >= (int) ($args['number'] ?? 1)) break;
|
|
}
|
|
return $results;
|
|
}
|
|
function sanitize_text_field($value): string { return trim(strip_tags((string) $value)); }
|
|
function sanitize_textarea_field($value): string { return sanitize_text_field($value); }
|
|
function sanitize_key($value): string { return preg_replace('/[^a-z0-9_\-]/', '', strtolower((string) $value)) ?? ''; }
|
|
function wp_unslash($value) { return $value; }
|
|
function esc_url_raw($value): string {
|
|
$value = trim((string) $value);
|
|
return $value === '' || filter_var($value, FILTER_VALIDATE_URL) ? $value : '';
|
|
}
|
|
function wp_verify_nonce(string $nonce, string $action): bool {
|
|
$GLOBALS['jio_nonce_checks'][] = [$nonce, $action];
|
|
return $GLOBALS['jio_nonce_valid'] && $nonce === 'ok';
|
|
}
|
|
function jio_require_captcha(string $scene, array $payload): bool { return true; }
|
|
function get_transient(string $key) { return $GLOBALS['jio_transients'][$key] ?? false; }
|
|
function set_transient(string $key, $value, int $expiration = 0): bool { $GLOBALS['jio_transients'][$key] = $value; return true; }
|
|
function delete_transient(string $key): bool { unset($GLOBALS['jio_transients'][$key]); return true; }
|
|
function wp_check_password(string $password, string $hash): bool { return $hash === 'fixture-hash' && $password === $GLOBALS['jio_expected_sms_code']; }
|
|
function wp_update_user(array $data) { return (int) ($data['ID'] ?? 0); }
|
|
function do_action(...$args): void {}
|
|
function add_action(...$args): void {}
|
|
function add_filter(string $hook, callable $callback, int $priority = 10, int $accepted_args = 1): void {
|
|
$GLOBALS['jio_profile_filters'][$hook][] = ['callback' => $callback, 'accepted_args' => $accepted_args];
|
|
}
|
|
function __(string $text, string $domain = ''): string { return $text; }
|
|
function esc_attr(string $value): string { return htmlspecialchars($value, ENT_QUOTES); }
|
|
function esc_html_e(string $text, string $domain = ''): void { echo htmlspecialchars($text, ENT_QUOTES); }
|
|
function esc_attr_e(string $text, string $domain = ''): void { echo htmlspecialchars($text, ENT_QUOTES); }
|
|
function esc_url(string $value): string { return $value; }
|
|
function selected($selected, $current = true, bool $echo = true): string { return (string) $selected === (string) $current ? 'selected="selected"' : ''; }
|
|
function wp_nonce_field(string $action, string $name): void {}
|
|
function get_avatar(...$args): string { return '<img alt="">'; }
|
|
function wp_max_upload_size(): int { return 2097152; }
|
|
function size_format(int $bytes): string { return (string) $bytes; }
|
|
function wp_check_filetype_and_ext(...$args): array { return []; }
|
|
function wp_match_mime_types(...$args): bool { return true; }
|
|
function wp_getimagesize(...$args): array|false { return false; }
|
|
function wp_get_attachment_image_url(...$args): string|false { return false; }
|
|
function get_post(...$args) { return null; }
|
|
function get_post_meta(...$args) { return ''; }
|
|
function wp_delete_attachment(...$args): bool { return true; }
|
|
function get_current_screen() { return null; }
|
|
|
|
require dirname(__DIR__, 2) . '/inc/helpers/jio-user-center.php';
|
|
}
|
|
|
|
namespace Jio\Sms {
|
|
final class SMS {
|
|
public static function is_phonenumber(string $phone): bool { return (bool) preg_match('/^1[3-9]\d{9}$/', $phone); }
|
|
}
|
|
}
|
|
|
|
namespace Jio\Settings {
|
|
final class Settings {
|
|
public static function get_all(): array { return ['bind_phone' => true]; }
|
|
}
|
|
}
|
|
|
|
namespace Jio\Auth {
|
|
require dirname(__DIR__, 2) . '/src/Auth/ServicePart1b.php';
|
|
final class PhoneHarnessService { use ServicePart1b; }
|
|
final class Service { use ServicePart1b; }
|
|
}
|
|
|
|
namespace Jio\Admin {
|
|
require dirname(__DIR__, 2) . '/src/Admin/UserControllerAuthPhoneOperations.php';
|
|
final class PhoneOperationsHarness {
|
|
use UserControllerAuthPhoneOperations;
|
|
public function get_json_params(\WP_REST_Request $request): array { return $request->get_json_params(); }
|
|
public function error(string $message, int $status = 400): \WP_REST_Response { return new \WP_REST_Response(['success' => false, 'message' => $message], $status); }
|
|
public function success(array $data): \WP_REST_Response { return new \WP_REST_Response(array_merge(['success' => true], $data), 200); }
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
require dirname(__DIR__, 2) . '/src/User/ProfileAdmin.php';
|
|
|
|
function check(bool $condition, string $message): void {
|
|
if (!$condition) throw new RuntimeException($message);
|
|
}
|
|
|
|
$GLOBALS['jio_profile_meta'][7] = [
|
|
'jio_phone' => '13900000000',
|
|
'jio_profile_details' => [
|
|
'privacy' => 'public', 'gender' => 'female', 'website' => 'https://example.test',
|
|
'qq' => '123456', 'wechat' => 'wxid', 'weibo' => 'https://weibo.com/user',
|
|
'github' => 'https://github.com/user', 'address' => 'Shanghai',
|
|
],
|
|
];
|
|
|
|
$bad_format = \Jio\Auth\PhoneHarnessService::bind_phone(['phone' => 'bad'], true);
|
|
check(empty($bad_format['success']), 'phone binding accepted malformed number');
|
|
$unverified = \Jio\Auth\PhoneHarnessService::bind_phone(['phone' => '13800000007'], false);
|
|
check(empty($unverified['success']), 'phone binding accepted missing verification');
|
|
|
|
$GLOBALS['jio_profile_meta'][8]['phone_number'] = '13800000008';
|
|
$duplicate = \Jio\Auth\PhoneHarnessService::bind_phone(['phone' => '13800000008'], true);
|
|
check(empty($duplicate['success']), 'phone binding accepted a number owned by another user');
|
|
|
|
$bound = \Jio\Auth\PhoneHarnessService::bind_phone(['phone' => '13800000007'], true);
|
|
check(!empty($bound['success']), 'verified phone binding failed');
|
|
check(get_user_meta(7, 'phone_number', true) === '13800000007', 'verified phone was not stored in canonical meta');
|
|
check(get_user_meta(7, 'jio_phone_verified', true) === '1', 'verified marker was not stored');
|
|
check(get_user_meta(7, 'jio_phone', true) === '13900000000', 'legacy phone key was unexpectedly migrated or rewritten');
|
|
|
|
$same_phone = \Jio\Auth\PhoneHarnessService::bind_phone(['phone' => '13800000007'], true);
|
|
check(empty($same_phone['success']), 'binding accepted the current phone as a change');
|
|
|
|
$phone_to_bind = '13800000010';
|
|
$otp_key = 'jio_auth_code_' . md5('account_bind_new_phone_7|' . strtolower(trim($phone_to_bind)));
|
|
$operations = new \Jio\Admin\PhoneOperationsHarness();
|
|
$old_phone = '13800000007';
|
|
$old_otp_key = 'jio_auth_code_' . md5('account_verify_old_phone_7|' . strtolower(trim($old_phone)));
|
|
$GLOBALS['jio_transients'][$old_otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() + 300];
|
|
$GLOBALS['jio_expected_sms_code'] = '246810';
|
|
$wrong_old_code = $operations->user_verify_phone(new WP_REST_Request(['phone' => $old_phone, 'code' => '000000']));
|
|
check(empty($wrong_old_code->data['success']), 'REST phone replacement accepted an incorrect old-number code');
|
|
check(($GLOBALS['jio_transients'][$old_otp_key]['attempts'] ?? 0) === 1, 'incorrect old-number code attempt was not recorded');
|
|
$GLOBALS['jio_transients'][$old_otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() - 1];
|
|
$expired_old_code = $operations->user_verify_phone(new WP_REST_Request(['phone' => $old_phone, 'code' => '246810']));
|
|
check(empty($expired_old_code->data['success']), 'REST phone replacement accepted an expired old-number code');
|
|
check(!isset($GLOBALS['jio_transients'][$old_otp_key]), 'expired old-number code was not discarded');
|
|
$GLOBALS['jio_transients'][$old_otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() + 300];
|
|
$verified_old_phone = $operations->user_verify_phone(new WP_REST_Request(['phone' => $old_phone, 'code' => '246810']));
|
|
check(!empty($verified_old_phone->data['success']), 'REST phone replacement rejected the correct old-number code');
|
|
check(!isset($GLOBALS['jio_transients'][$old_otp_key]), 'valid old-number code was not consumed');
|
|
check(($GLOBALS['jio_transients']['jio_account_phone_old_7']['phone'] ?? '') === $old_phone, 'old-number proof was not issued for the current account');
|
|
$GLOBALS['jio_transients'][$otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() + 300];
|
|
$wrong_code = $operations->user_bind_phone(new WP_REST_Request(['phone' => $phone_to_bind, 'code' => '000000']));
|
|
check(empty($wrong_code->data['success']), 'REST phone binding accepted an incorrect SMS code');
|
|
check(($GLOBALS['jio_transients'][$otp_key]['attempts'] ?? 0) === 1, 'incorrect SMS code attempt was not recorded');
|
|
$GLOBALS['jio_transients'][$otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() - 1];
|
|
$expired_code = $operations->user_bind_phone(new WP_REST_Request(['phone' => $phone_to_bind, 'code' => '246810']));
|
|
check(empty($expired_code->data['success']), 'REST phone binding accepted an expired SMS code');
|
|
check(!isset($GLOBALS['jio_transients'][$otp_key]), 'expired SMS code was not discarded');
|
|
$duplicate_phone = '13800000008';
|
|
$duplicate_otp_key = 'jio_auth_code_' . md5('account_bind_new_phone_7|' . strtolower(trim($duplicate_phone)));
|
|
$GLOBALS['jio_transients'][$duplicate_otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() + 300];
|
|
$duplicate_code = $operations->user_bind_phone(new WP_REST_Request(['phone' => $duplicate_phone, 'code' => '246810']));
|
|
check(empty($duplicate_code->data['success']), 'REST phone binding accepted a number owned by another user');
|
|
check(isset($GLOBALS['jio_transients'][$duplicate_otp_key]), 'duplicate-number validation consumed the valid SMS code');
|
|
$GLOBALS['jio_transients'][$otp_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() + 300];
|
|
$valid_code = $operations->user_bind_phone(new WP_REST_Request(['phone' => $phone_to_bind, 'code' => '246810']));
|
|
check(!empty($valid_code->data['success']), 'REST phone binding rejected the correct SMS code');
|
|
check(get_user_meta(7, 'phone_number', true) === $phone_to_bind, 'REST phone binding did not store the canonical phone meta');
|
|
check(!isset($GLOBALS['jio_transients'][$otp_key]), 'valid SMS code was not consumed');
|
|
check(!isset($GLOBALS['jio_transients']['jio_account_phone_old_7']), 'successful phone change did not consume the old-number proof');
|
|
|
|
$initial_bind_user_id = 9;
|
|
$initial_bind_phone = '13800000011';
|
|
$initial_bind_code_key = 'jio_auth_code_' . md5('account_bind_new_phone_9|' . strtolower(trim($initial_bind_phone)));
|
|
$GLOBALS['jio_current_user_id'] = $initial_bind_user_id;
|
|
$GLOBALS['jio_transients'][$initial_bind_code_key] = ['hash' => 'fixture-hash', 'attempts' => 0, 'expires' => time() + 300];
|
|
$initial_bind = $operations->user_bind_phone(new WP_REST_Request(['phone' => $initial_bind_phone, 'code' => '246810']));
|
|
check(!empty($initial_bind->data['success']), 'first-time phone binding incorrectly required an old-number proof');
|
|
check(get_user_meta($initial_bind_user_id, 'phone_number', true) === $initial_bind_phone, 'first-time phone binding did not store the canonical phone meta');
|
|
check(!isset($GLOBALS['jio_transients'][$initial_bind_code_key]), 'successful first-time phone binding did not consume its SMS code');
|
|
$GLOBALS['jio_current_user_id'] = 7;
|
|
|
|
$_POST = [
|
|
'jio_profile_admin_nonce' => 'ok',
|
|
'jio_admin_avatar_nonce' => 'ok',
|
|
'jio_profile_gender' => 'male',
|
|
'jio_profile_qq' => '7654321',
|
|
'jio_profile_wechat' => 'new-wechat',
|
|
'jio_profile_weibo' => 'https://weibo.com/new-user',
|
|
'jio_profile_github' => 'https://github.com/new-user',
|
|
'jio_profile_website' => 'https://new.example.test',
|
|
'jio_profile_address' => 'Beijing',
|
|
'phone_number' => '13800000007',
|
|
'jio_phone_edit_unlocked' => '0',
|
|
];
|
|
$_FILES = [];
|
|
\Jio\User\ProfileAdmin::save(7);
|
|
$details = jio_get_user_profile_details(7);
|
|
check($details['privacy'] === 'public', 'admin profile update erased social privacy setting');
|
|
check($details['gender'] === 'male' && $details['weibo'] === 'https://weibo.com/new-user' && $details['address'] === 'Beijing', 'admin profile fields did not persist');
|
|
check($details['website'] === 'https://new.example.test', 'personal website field did not persist');
|
|
|
|
$front_save = jio_save_user_center_profile(7, ['nickname' => 'Profile User']);
|
|
check($front_save === true, 'user-center profile save failed');
|
|
$details = jio_get_user_profile_details(7);
|
|
check($details['weibo'] === 'https://weibo.com/new-user' && $details['address'] === 'Beijing', 'front profile save erased admin-added fields');
|
|
$details['privacy'] = 'private';
|
|
update_user_meta(7, 'jio_profile_details', $details);
|
|
$private_view = jio_get_visible_user_profile_details(7, 9);
|
|
check($private_view['weibo'] === '' && $private_view['address'] === '', 'private social details leaked to another viewer');
|
|
$owner_view = jio_get_visible_user_profile_details(7, 7);
|
|
check($owner_view['weibo'] === 'https://weibo.com/new-user' && $owner_view['address'] === 'Beijing', 'owner cannot read private social details');
|
|
$details['privacy'] = 'public';
|
|
update_user_meta(7, 'jio_profile_details', $details);
|
|
$public_view = jio_get_visible_user_profile_details(7, 9);
|
|
check($public_view['weibo'] === 'https://weibo.com/new-user' && $public_view['address'] === 'Beijing', 'public social details are not visible to another viewer');
|
|
|
|
\Jio\User\ProfileAdmin::init();
|
|
$profile_hook = $GLOBALS['jio_profile_filters']['user_profile_update_errors'][0] ?? [];
|
|
check(($profile_hook['accepted_args'] ?? 0) === 3, 'profile validation must receive all three WordPress hook arguments');
|
|
$validate_profile = $profile_hook['callback'];
|
|
|
|
$_POST = ['jio_profile_admin_nonce' => 'ok', 'phone_number' => 'not-a-phone', 'jio_phone_edit_unlocked' => '1'];
|
|
$invalid_errors = new WP_Error();
|
|
$validate_profile($invalid_errors, true, (object) ['ID' => 7]);
|
|
check(in_array('jio_profile_phone', $invalid_errors->get_error_codes(), true), 'invalid admin phone format was not rejected');
|
|
|
|
$_POST = ['user_id' => 8, 'jio_profile_admin_nonce' => 'ok', 'phone_number' => '13800000008', 'jio_phone_edit_unlocked' => '1'];
|
|
$GLOBALS['jio_capability_checks'] = [];
|
|
$GLOBALS['jio_nonce_checks'] = [];
|
|
$duplicate_errors = new WP_Error();
|
|
$validate_profile($duplicate_errors, true, (object) ['ID' => 7]);
|
|
check(in_array('jio_profile_phone_exists', $duplicate_errors->get_error_codes(), true), 'admin profile accepted a duplicate phone');
|
|
check($GLOBALS['jio_capability_checks'] === [['edit_user', 7]], 'profile permission check used the posted ID instead of the hook user');
|
|
check($GLOBALS['jio_nonce_checks'] === [['ok', 'jio_profile_admin_nonce_7']], 'profile nonce used the posted ID instead of the hook user');
|
|
|
|
foreach ([(object) ['ID' => 0], (object) []] as $new_user) {
|
|
$_POST = ['user_id' => 7, 'jio_profile_admin_nonce' => 'ok', 'phone_number' => 'not-a-phone', 'jio_phone_edit_unlocked' => '1'];
|
|
$GLOBALS['jio_capability_checks'] = [];
|
|
$GLOBALS['jio_nonce_checks'] = [];
|
|
$new_user_errors = new WP_Error();
|
|
$validate_profile($new_user_errors, false, $new_user);
|
|
check($new_user_errors->get_error_codes() === [], 'a new user without an ID was validated against the posted user');
|
|
check($GLOBALS['jio_capability_checks'] === [] && $GLOBALS['jio_nonce_checks'] === [], 'a missing hook user ID fell back to POST');
|
|
}
|
|
|
|
$_POST = ['jio_profile_admin_nonce' => 'wrong', 'phone_number' => 'not-a-phone', 'jio_phone_edit_unlocked' => '1'];
|
|
$invalid_nonce_errors = new WP_Error();
|
|
$validate_profile($invalid_nonce_errors, true, (object) ['ID' => 7]);
|
|
check($invalid_nonce_errors->get_error_codes() === ['jio_profile_nonce'], 'invalid nonce did not stop profile validation');
|
|
|
|
$GLOBALS['jio_can_edit_user'] = false;
|
|
$GLOBALS['jio_nonce_checks'] = [];
|
|
$denied_errors = new WP_Error();
|
|
$validate_profile($denied_errors, true, (object) ['ID' => 7]);
|
|
check($denied_errors->get_error_codes() === [] && $GLOBALS['jio_nonce_checks'] === [], 'profile validation bypassed the edit-user permission guard');
|
|
$GLOBALS['jio_can_edit_user'] = true;
|
|
|
|
$_POST = ['phone_number' => 'not-a-phone', 'jio_phone_edit_unlocked' => '1'];
|
|
$missing_nonce_errors = new WP_Error();
|
|
$validate_profile($missing_nonce_errors, true, (object) ['ID' => 7]);
|
|
check($missing_nonce_errors->get_error_codes() === [], 'unrelated profile submissions triggered custom field validation');
|
|
|
|
$_POST = ['jio_profile_admin_nonce' => 'ok', 'phone_number' => get_user_meta(7, 'phone_number', true), 'jio_phone_edit_unlocked' => '1'];
|
|
$valid_errors = new WP_Error();
|
|
$validate_profile($valid_errors, true, (object) ['ID' => 7]);
|
|
check($valid_errors->get_error_codes() === [], 'valid stdClass profile data did not pass validation');
|
|
|
|
$_POST = ['jio_profile_admin_nonce' => 'wrong', 'phone_number' => '13800000009', 'jio_phone_edit_unlocked' => '1'];
|
|
$before_phone = get_user_meta(7, 'phone_number', true);
|
|
$before_details = get_user_meta(7, 'jio_profile_details', true);
|
|
\Jio\User\ProfileAdmin::save(7);
|
|
check(get_user_meta(7, 'phone_number', true) === $before_phone, 'invalid admin nonce changed the phone');
|
|
check(get_user_meta(7, 'jio_profile_details', true) === $before_details, 'invalid admin nonce changed profile details');
|
|
|
|
$_POST = ['jio_profile_admin_nonce' => 'ok', 'phone_number' => '13800000009', 'jio_phone_edit_unlocked' => '1'];
|
|
\Jio\User\ProfileAdmin::save(7);
|
|
check(get_user_meta(7, 'phone_number', true) === '13800000009', 'unlocked admin phone change was not saved');
|
|
check(get_user_meta(7, 'jio_phone_verified', true) === '1', 'admin phone change cleared its verified marker');
|
|
$_POST['phone_number'] = '';
|
|
\Jio\User\ProfileAdmin::save(7);
|
|
check(get_user_meta(7, 'phone_number', true) === '13800000009', 'blank admin phone unexpectedly cleared the binding');
|
|
|
|
$before_details = get_user_meta(7, 'jio_profile_details', true);
|
|
$GLOBALS['jio_can_edit_user'] = false;
|
|
$_POST = ['jio_profile_admin_nonce' => 'ok', 'jio_profile_address' => 'Unauthorized change'];
|
|
\Jio\User\ProfileAdmin::save(7);
|
|
$GLOBALS['jio_can_edit_user'] = true;
|
|
check(get_user_meta(7, 'jio_profile_details', true) === $before_details, 'user without edit permission changed profile details');
|
|
|
|
echo "User profile phone harness passed\n";
|
|
}
|