string('token'); if (mahak_debug_enabled()) { $this->debugContext['jwt_timestamps'] = $this->inspectJwtTimestamps($token); } $payload = $this->decrypt_jwt_token($token); $identifier_name = get_configured_option('user-identifier'); $identifier_value = $payload[$identifier_name] ?? null; $name = $payload['name'] ?? config('mahak.translates.new-user'); $user_id = $this->find_or_create_user($identifier_name, $identifier_value, $name); $this->login_user($user_id); $redirect_path = get_configured_option('after-login-route'); wp_redirect(home_url($redirect_path)); exit(); } public function decrypt_jwt_token(string $token): array { $jwt_secret = get_configured_option('jwt-secret'); $decoded = JwtDecoder::decodeHs256($token, $jwt_secret); $data = $decoded['data'] ?? null; if (!is_array($data)) { throw new UnexpectedValueException('JWT data must be an object.'); } return $data; } public function find_or_create_user(string $identifier_name, string $identifier_value, string $name): int { $user = get_user_by($identifier_name, $identifier_value); if ($user) { return $user->ID; } $random_password = wp_generate_password(12, true); $username = $identifier_value; $email = $identifier_name === 'email' ? $identifier_value : ''; if (username_exists($username)) { $username .= '_'.wp_generate_password(4, false); } $user_id = wp_create_user($username, $random_password, $email); if (is_wp_error($user_id)) { throw new RuntimeException( 'WordPress could not create the user: '.$user_id->get_error_message() ); } $updated_user_id = wp_update_user([ 'ID' => $user_id, 'display_name' => $name, ]); if (is_wp_error($updated_user_id)) { throw new RuntimeException( 'WordPress could not update the user: '.$updated_user_id->get_error_message() ); } return $user_id; } protected function handleException(Throwable $exception): void { $status = $exception->getCode() === 403 ? 403 : 500; $fallbackView = $exception instanceof UnexpectedValueException ? 'invalid-token' : 'server-error'; mahak_render_error($exception, $status, $fallbackView, $this->debugContext); } private function inspectJwtTimestamps(string $token): array { $segments = explode('.', $token); if (count($segments) !== 3) { return []; } $encodedPayload = strtr($segments[1], '-_', '+/'); $encodedPayload .= str_repeat('=', (4 - strlen($encodedPayload) % 4) % 4); $json = base64_decode($encodedPayload, true); $payload = $json === false ? null : json_decode($json, true); if (!is_array($payload)) { return []; } $timestamps = []; foreach (['iat', 'nbf', 'exp'] as $claim) { if (array_key_exists($claim, $payload)) { $value = is_scalar($payload[$claim]) ? (string) $payload[$claim] : '[non-scalar]'; $timestamps[$claim] = strlen($value) > 64 ? substr($value, 0, 64).'…' : $value; } } return $timestamps; } public function login_user(int $user_id): bool { wp_set_auth_cookie($user_id); wp_set_current_user($user_id); do_action('wp_login', get_userdata($user_id)->user_login, get_userdata($user_id)); return true; } }