HEX
Server: Apache
System: Linux vps75080.inmotionhosting.com 3.10.0-1160.119.1.vz7.224.4 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User: reachcon (1003)
PHP: 7.2.34
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/reachcon/www/wp-content/themes/reach-connects/api.php
<?php

// Add ACF Fields to rest API
function my_rest_prepare_post($data, $post, $request) {
    $_data = $data->data;
    $fields = get_field_objects($post->ID);
	
    if(is_array($fields) && count($fields)>0){ 
		foreach ($fields as $key=>$value){ 
			if($value['type']=='oembed'){
				$video_url = get_field('video_url', $post->ID, FALSE);
				$video_thumb_url = get_video_thumbnail_uri($video_url);
				$_data[$key.'_thumbnail'] = $video_thumb_url;
				$code = get_field($key, $post->ID);
				$_data[$key] = str_replace(array('%', '"'), array('%p', '%q'), $code);
			}else{
				$_data[$key] = get_field($key, $post->ID);
			}
		}
	}
	// Add Featured Image
	if( has_post_thumbnail() ){
		$_data['featured_image'] = array(
			'full'=>get_the_post_thumbnail_url($post->ID,'full'),
			'thumb'=>get_the_post_thumbnail_url($post->ID,'Thumbnail')
		);
	}else{
		$_data['featured_image'] = array(
			'full'=>'https://www.pocketrestaurantconsultant.com/wp-content/uploads/default-article.png',
			'thumb'=>'https://www.pocketrestaurantconsultant.com/wp-content/uploads/default-article-150x150.png',
		);
	}
	$data->data = $_data;
    return $data;
}
add_filter("rest_prepare_post", 'my_rest_prepare_post', 10, 3);
add_filter("rest_prepare_videos", 'my_rest_prepare_post', 10, 3);
add_filter("rest_prepare_recipes", 'my_rest_prepare_post', 10, 3);


// API Check Password
function rest_api_login($data){
	if( !empty($data['user']) && !empty($data['pass']) ){
		$user = $data['user'];
		$pass = base64_decode($data['pass']);
		$user = wp_authenticate( $user, $pass );
		if(isset($user->ID)){
			$args = array(
				'id'      => $user->ID,
				'user'    => $user->user_login,
				'email'   => $user->user_email,
				'display' => $user->display_name,
			);
			$token = rest_api_token_create($args);
			if($token){
				$articles  = wp_count_posts();
					$articles = (isset($articles->publish)) ? $articles->publish : '0';
				$videos    = wp_count_posts('videos');
					$videos = (isset($videos->publish)) ? $videos->publish : '0';
				$recipes   = wp_count_posts('recipes');
					$recipes = (isset($recipes->publish)) ? $recipes->publish : '0';
				$documents = wp_count_posts('documents');
					$documents = (isset($documents->publish)) ? $documents->publish : '0';
				$result = array(
					'token'     => $token,
					'result'    => 1,
					'articles'  => $articles,
					'videos'    => $videos,
					'recipes'   => $recipes,
					'documents' => $documents
				);
			}else{ $result = array('result'=>4); }
		}else{
			////////////////////////////////////////////////////////////////////////////////////////////////////////
			// TODO
			// check for brute force attacks
			// $result = array('result'=>10);
			
			$result = array('result'=>2); // invalid username or password
		}
	}else{ $result = array('result'=>3); }
	return $result;
}




































function rest_api_register($data){
	if( !empty($data['user']) && !empty($data['pass']) ){
		$user  = $data['user'];
		$email  = $data['email'];
		$fname  = $data['fname'];
		$lname  = $data['lname'];
		$pass  = base64_decode($data['pass']);
		$user_id = username_exists( $user );
		if(!$user_id){ // Check if username is used
			if( email_exists($email) == false ){ // check if email is used
				$user_id = wp_create_user( $user, $pass, $email );
				if( is_wp_error( $user_id ) ){
					$result = array('result'=>2);
				}else{
					// Success!
					$user_update = wp_update_user( 
						array( 
							'ID' => $user_id, 
							'first_name' => $fname, 
							'last_name' => $lname,
							'show_admin_bar_front' => 'false', // This is used on the website end
						)
					);
					if( is_wp_error( $user_update ) ){
						wp_delete_user( $user_id );
						$result = array('result'=>2);
					}else{
						$result = array('result'=>1); // Success
					}
				}
			}else{ $result = array('result'=>4); }
		}else{ $result = array('result'=>3); }
	}else{ $result = array('result'=>2); }
	return $result;
}


function rest_api_email($data){
	if($data['email']!=''){
		if( email_exists($data['email']) == false ){ return array('result'=>1); }
		else{ return array('result'=>0); }
	}else{ return array('result'=>0); }
}

function rest_api_username($data){
	if($data['user']!=''){
		$user_id = username_exists( $data['user'] );
		if( is_wp_error( $user_id ) ){ return array('result'=>0); }
		else{ 
			if($user_id){ return array('user'=>$user_id,'result'=>0); }
			else{ return array('user'=>$user_id,'result'=>1); }
		}
	}else{ return array('result'=>0); }
}

























function rest_api_verify($data){
	if(!isset($data['token'])){ $result = array('result'=>2); }
	else{
		$token = rest_api_token_read($data['token']);
		if($token){ 
			$user = get_user_by( 'id', $token->id);
			if(isset($user->ID)){
				if( $token->user != $user->user_login || $token->email != $user->user_email || $token->display != $user->display_name ){ $result = array('result'=>3);}
				else{ 
					$articles  = wp_count_posts();
						$articles = (isset($articles->publish)) ? $articles->publish : '0';
					$videos    = wp_count_posts('videos');
						$videos = (isset($videos->publish)) ? $videos->publish : '0';
					$recipes   = wp_count_posts('recipes');
						$recipes = (isset($recipes->publish)) ? $recipes->publish : '0';
					$documents = wp_count_posts('documents');
						$documents = (isset($documents->publish)) ? $documents->publish : '0';
					$result = array(
						'result'    => 1,
						'articles'  => $articles,
						'videos'    => $videos,
						'recipes'   => $recipes,
						'documents' => $documents
					);
				}	
			}else{ $result = array('result'=>2); }
		}else{$result = array('result'=>2);}
	}
	return $result;
}

add_action( 'rest_api_init', function () {
 
	//register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func' ) );
	
	// Check username and password and return token
	register_rest_route( 'omada/v2', '/token/', array( 'methods' => 'POST', 'callback' => 'rest_api_login' ) );

	// Check username and password and return token
	register_rest_route( 'omada/v2', '/register/', array( 'methods' => 'POST', 'callback' => 'rest_api_register' ) );

	// Get User Data on login if token is correct
	register_rest_route( 'omada/v2', '/verify/', array( 'methods' => 'POST', 'callback' => 'rest_api_verify' ) );
	
	// Check if email address is exists
	register_rest_route( 'omada/v2', '/email/', array( 'methods' => 'POST', 'callback' => 'rest_api_email' ) );
	
	// Check if username exists
	register_rest_route( 'omada/v2', '/username/', array( 'methods' => 'POST', 'callback' => 'rest_api_username' ) );
	
	// change email / pass
	

});


















































// Check against brute force attacks
	function checkbrute($user_id) {
		// Get timestamp of current time 
		$now = time();
		// All login attempts are counted from the past 2 hours. 
		$attempts = $now - (5 * 60); //$now - (2 * 60 * 60);
		// Collect Attempts
		$bind=array(":attempts"=>$attempts,':id'=>$user_id);
		$select  = "user_id=:id AND time>:attempts LIMIT 20";
		$results = $this->db->select("login_attempts", $select, $bind);
		return count($results);
	}






















/**
 * JSON Web Token implementation, based on this spec:
 * http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
 * PHP version 5
 * @category Authentication
 * @package  Authentication_JWT
 * @author   Neuman Vong <neuman@twilio.com>
 * @author   Anant Narayanan <anant@php.net>
 * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
 * @link     https://github.com/firebase/php-jwt
 */
class JWT{
	/**
	 * Decodes a JWT string into a PHP object.
	 * @param string      $jwt    The JWT
	 * @param string|null $key    The secret key
	 * @param bool        $verify Don't skip verification process 
	 * @return object      The JWT's payload as a PHP object
	 * @throws UnexpectedValueException Provided JWT was invalid
	 * @throws DomainException          Algorithm was not provided
	 * @uses jsonDecode
	 * @uses urlsafeB64Decode
	 */
	public static function decode($jwt, $key = null, $verify = true){
		$tks = explode('.', $jwt);
		if (count($tks) != 3){ throw new UnexpectedValueException('Wrong number of segments'); }
		list($headb64, $bodyb64, $cryptob64) = $tks;
		if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
			throw new UnexpectedValueException('Invalid segment encoding');
		}
		if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
			throw new UnexpectedValueException('Invalid segment encoding');
		}
		$sig = JWT::urlsafeB64Decode($cryptob64);
		if ($verify){
			if(empty($header->alg)){ throw new DomainException('Empty algorithm'); }
			if ($sig != JWT::sign("$headb64.$bodyb64", $key, $header->alg)) {
				throw new UnexpectedValueException('Signature verification failed');
			}
		}
		return $payload;
	}
	/**
	 * Converts and signs a PHP object or array into a JWT string.
	 * @param object|array $payload PHP object or array
	 * @param string       $key     The secret key
	 * @param string       $algo    The signing algorithm. Supported
	 *                              algorithms are 'HS256', 'HS384' and 'HS512'
	 * @return string      A signed JWT
	 * @uses jsonEncode
	 * @uses urlsafeB64Encode
	 */
	public static function encode($payload, $key, $algo = 'HS256'){
		$header = array('typ' => 'JWT', 'alg' => $algo);
		$segments = array();
		$segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header));
		$segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload));
		$signing_input = implode('.', $segments);
		$signature = JWT::sign($signing_input, $key, $algo);
		$segments[] = JWT::urlsafeB64Encode($signature);
		return implode('.', $segments);
	}
	/**
	 * Sign a string with a given key and algorithm.
	 * @param string $msg    The message to sign
	 * @param string $key    The secret key
	 * @param string $method The signing algorithm. Supported
	 *                       algorithms are 'HS256', 'HS384' and 'HS512'
	 * @return string          An encrypted message
	 * @throws DomainException Unsupported algorithm was specified
	 */
	public static function sign($msg, $key, $method = 'HS256'){
		$methods = array( 'HS256' => 'sha256', 'HS384' => 'sha384', 'HS512' => 'sha512' );
		if (empty($methods[$method])){ throw new DomainException('Algorithm not supported'); }
		return hash_hmac($methods[$method], $msg, $key, true);
	}
	/**
	 * Decode a JSON string into a PHP object.
	 * @param string $input JSON string
	 * @return object          Object representation of JSON string
	 * @throws DomainException Provided string was invalid JSON
	 */
	public static function jsonDecode($input){
		$obj = json_decode($input);
		if (function_exists('json_last_error') && $errno = json_last_error()) { JWT::_handleJsonError($errno); } 
		else if ($obj === null && $input !== 'null'){ throw new DomainException('Null result with non-null input'); }
		return $obj;
	}
	/**
	 * Encode a PHP object into a JSON string.
	 * @param object|array $input A PHP object or array
	 * @return string          JSON representation of the PHP object or array
	 * @throws DomainException Provided object could not be encoded to valid JSON
	 */
	public static function jsonEncode($input){
		$json = json_encode($input);
		if (function_exists('json_last_error') && $errno = json_last_error()) { JWT::_handleJsonError($errno); } 
		else if ($json === 'null' && $input !== null) { throw new DomainException('Null result with non-null input'); }
		return $json;
	}
	/**
	 * Decode a string with URL-safe Base64.
	 * @param string $input A Base64 encoded string
	 * @return string A decoded string
	 */
	public static function urlsafeB64Decode($input){
		$remainder = strlen($input) % 4;
		if ($remainder){ $padlen = 4 - $remainder; $input .= str_repeat('=', $padlen); }
		return base64_decode(strtr($input, '-_', '+/'));
	}
	/**
	 * Encode a string with URL-safe Base64.
	 * @param string $input The string you want encoded
	 * @return string The base64 encode of what you passed in
	 */
	public static function urlsafeB64Encode($input){ return str_replace('=', '', strtr(base64_encode($input), '+/', '-_')); }
	/**
	 * Helper method to create a JSON error.
	 * @param int $errno An error number from json_last_error()
	 * @return void
	 */
	private static function _handleJsonError($errno){
		$messages = array(
			JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
			JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
			JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
		);
		throw new DomainException( isset($messages[$errno]) ? $messages[$errno] : 'Unknown JSON error: ' . $errno );
	}
}

	// Create Token
	function rest_api_token_create($arr){
		try{ return JWT::encode($arr, NONCE_SALT); }catch(Exception $e){ return false; }
	}
	
	// Read JWT and return payload
	function rest_api_token_read($token){
		try{
			$token = JWT::decode($token, NONCE_SALT);
			if(!empty($token)){ return $token; }
			return false;
		}catch(Exception $e){
			return false;
		}
	}