<?php
require_once 'curl.php';
class Icloud_V2
{
	public $login;
	public $pass;
	public $init = false;
	public $clien_context = array('appName' => 'iCloud Find (Web)', 'appVersion' => '2.0', 'timezone' => 'Pacific/Pago_Pago', 'inactiveTime' => '0', 'apiVersion' => '3.0', 'fmly' => true);
	public $server_context = array();

	public function Icloud_V2($login, $pass)
	{
		$this->login = $login;
		$this->pass = $pass;

		if (!($this->Auth())) {
			throw new Exception('Auth problem');
		}

	}

	public function Auth()
	{
		$url = 'https://www.icloud.com/';
		$page = Curl::OpenPage($url);
		$url = 'https://setup.icloud.com/setup/ws/1/validate?clientBuildNumber=17CProject120&clientId=D361E20D-BDF5-4A65-88E7-7423B1B2E78A&clientMasteringNumber=17C71';
		$page = Curl::PostQuery($url, '');
		$widget_key = explode('widgetKey=', $page);
		$widget_key = explode('#!create', $widget_key[1]);
		$widget_key = $widget_key[0];
		$data = '{"accountName":"' . $this->login . '","password":"' . $this->pass . '","rememberMe":false,"trustTokens":[]}';
		$url = 'https://idmsa.apple.com/appleauth/auth/signin';
		$headers = array('Host: idmsa.apple.com', 'Accept: application/json, text/javascript, */*; q=0.01', 'Accept-Language: uk,ru;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding: gzip, deflate, br', 'Content-Type: application/json', 'X-Apple-Widget-Key: ' . $widget_key, 'X-Requested-With: XMLHttpRequest', 'Connection: keep-alive');
		$page = Curl::PostQuery($url, $data, $headers, false, true, true);
		$token = explode('X-Apple-Session-Token: ', $page);
		$token = explode('Cache-Control:', $token[1]);
		$token = $token[0];
		$token = str_replace("\r\n", '', $token);
		$url = 'https://setup.icloud.com/setup/ws/1/accountLogin?clientBuildNumber=17CProject120&clientId=B252067A-7338-40CF-A829-1FF30BA31B99&clientMasteringNumber=17C71';
		$post = '{"dsWebAuthToken":"' . $token . '","extended_login":false}';
		$page = Curl::PostQuery($url, $post, array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com'), 'https://www.icloud.com/');
		$result = json_decode($page, true);

		if (!(empty($result['webservices']['findme']['url']))) {
			$this->host = $result['webservices']['findme']['url'];
		}
		 else {
			$this->host = '';
		}

		if (!(empty($result['webservices']['account']['url']))) {
			$this->settings_host = $result['webservices']['account']['url'];
		}
		 else {
			$this->settings_host = '';
		}

		if (isset($result['dsInfo']['dsid'])) {
			if (!(empty($result['dsInfo']['hsaEnabled']))) {
			}


			$this->ds_id = $result['dsInfo']['dsid'];
			return true;
		}


		return false;
	}

	static public function CheckRecoveryKey($recovery_key)
	{
		Curl::Start();
		$url = 'https://idmsa.apple.com/appleauth/auth/verify/recoverykey';
		$post = '{"recoveryKey":"123412341234"}';
		$header = array('Accept:application/json', 'Accept-Encoding:gzip, deflate, lzma, br', 'Accept-Language:en-US,en;q=0.8', 'Connection:keep-alive', 'Content-Length:32', 'Content-Type:application/json', 'Cookie:POD=us~en; s_fid=2C298D2D6EB18A89-310B4C6ECE363F66; s_vnum_n2_us=30%7C2%2C4%7C1%2C5%7C1; s_vi=[CS]v1|2BAD381D85031FD5-40001186C00017AE[CE]; JSESSIONID=EE0FE9FC80E29D9177F68EF75385DC7A; X-SESS=14b5a3d9db2c7473178edc71110a457a677991a2faf083d2c418791213df7ddfc32d163d; dstimeoffset=-180; aa=DD0B449F3CA54BC28D8AD273DD6EC11B75214C1D9DBCD24620FC309057FE72B9A4A51D3725C17852CC4F71B0FB0B2E09131160E186F05A774BD58BB5C2D95D9FA33821B7CD5844C64776B7347277BDEF746C69A9451945E7817F4A1E075C6B2DECE005829F37A5DC1DB187E0613A3C8FE123DC9D7D1B3C3BA856B247E65996E71A5BCFB1C02DF80A74328B8746832FFCA4DDCB2594E8C45C97A2B31CE4577111FCC90FD4E8A5BE1AAF3213438C5E01F0C12C25650A5244ABB2130AA22FB7D342005F809A81B15DA865544F74259B058BD8378F68CA02DB21BE6E90507695DA29014669F6E4E2EA3EB5FCAD64A3CE83664E1FED7A34C85E84B1E7BDABA70C519D; site=RUS; dslang=RU-RU', 'Host:idmsa.apple.com', 'Origin:https://idmsa.apple.com', 'Referer:https://idmsa.apple.com/appleauth/auth/signin?widgetKey=af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3&locale=ru_RU&rv=1' . "\n" . 'scnt:e03ed71d2f72204ce2610ea39abaed5d', 'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 OPR/38.0.2220.41', 'X-Apple-Domain-Id:1', 'X-Apple-I-FD-Client-Info:{"U":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 OPR/38.0.2220.41","L":"en-US","Z":"GMT+03:00","V":"1.1","F":"FGa44j1e3NlY5BSo9z4ofjb75PaK4Vpjt.gEngMQEjZr_WhXTA6FL.26y8GGEDd5ihORoVyFGh8cmvSuCKzIlnY6xljQlpRDBLraeL3Cb12qgXK_Pmtd0vcxolmThjCH_FtWASHp815LyjaY2.rINj.rIN4WzcjftckcKyAd65hz74WySXvOxwawgCgIlNu1k.Nzl998tp7ppfAaZ6m1CdC5MQjGejuTDRNziCvTDfWlXqwpHkWgsFTpZHgfLMC7ES6iaDIphteJe6B8Qwvw0BpUMnGWqbPaRgwe98vDdYejftckuyPBDjaY2ftckkCoq75uQ0FVua0A94F1xQei.uJtHoqvynx9MsFyxYMAqJkL6elSHfNvr91y.eaB0Tf3dlI697.rTL4yfgzWKwHCSFQ_v9NA14WX3NqhyA_r_LwwKdBvpZfWfUXtStKjE4PIDzp9hyr1BNlr9.NlY5QB4bVNjMk.E0k"}', 'X-Apple-ID-Session-Id:DD0B449F3CA54BC28D8AD273DD6EC11B75214C1D9DBCD24620FC309057FE72B9A4A51D3725C17852CC4F71B0FB0B2E09131160E186F05A774BD58BB5C2D95D9FA33821B7CD5844C64776B7347277BDEF746C69A9451945E7817F4A1E075C6B2DECE005829F37A5DC1DB187E0613A3C8FE123DC9D7D1B3C3BA856B247E65996E71A5BCFB1C02DF80A74328B8746832FFCA4DDCB2594E8C45C97A2B31CE4577111FCC90FD4E8A5BE1AAF3213438C5E01F0C12C25650A5244ABB2130AA22FB7D342005F809A81B15DA865544F74259B058BD8378F68CA02DB21BE6E90507695DA29014669F6E4E2EA3EB5FCAD64A3CE83664E1FED7A34C85E84B1E7BDABA70C519D', 'X-Apple-Locale:ru_RU', 'X-Apple-Widget-Key:af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3', 'X-Requested-With:XMLHttpRequest');
		$page = Curl::OpenPageWithPost($url, $post, $header);
	}

	public function Rand()
	{
		$this->clien_context['inactiveTime'] = rand(1, 1000);
	}

	public function Init()
	{
		if (!($this->init)) {
			$url = $this->host . '/fmipservice/client/web/initClient?dsid=' . $this->ds_id;
			$post = array('clientContext' => $this->clien_context);
			$page = Curl::PostQuery($url, json_encode($post), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com'));
			$data = json_decode($page, true);

			if (!(isset($data['serverContext']))) {
				throw new Exception('INIT[Server context not found]');
			}


			$this->server_context = $data['serverContext'];

			if ($data['statusCode'] != 200) {
				throw new Exception('Can\'t init app');
			}


			$this->init = true;
		}

	}

	public function GetDevices()
	{
		$this->Init();

		if (!($this->host)) {
			throw new Exception('Service unavailable');
		}


		$url = $this->host . '/fmipservice/client/web/refreshClient?dsid=' . $this->ds_id;
		$post = array('serverContext' => $this->server_context, 'clientContext' => $this->clien_context);
		$page = Curl::PostQuery($url, json_encode($post), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com'));
		$result = json_decode($page, true);

		if (!(isset($result['serverContext']))) {
			throw new Exception('GetDevices ERROR[Server context not found]');
		}


		if ($result['statusCode'] != 200) {
			throw new Exception('GetDevices ERROR');
		}


		$this->server_context = $result['serverContext'];

		if (isset($result['content']) && (0 < count($result['content']))) {
			$devices = array();

			foreach ($result['content'] as $dev ) {
				$device_short = array('id' => $dev['id'], 'name' => $dev['name'], 'deviceStatus' => $dev['deviceStatus'], 'deviceColor' => $dev['deviceColor'], 'deviceDisplayName' => $dev['deviceDisplayName'], 'rawDeviceModel' => $dev['rawDeviceModel']);
				array_push($devices, $device_short);
			}

			return $devices;
		}


		$devices = array();
		return $devices;
	}

	public function Locating($device, $timeout = 30)
	{
		if (!($this->host)) {
			throw new Exception('Service unavailable');
		}


		$i = 0;

		while ($i < $timeout) {
			$url = $this->host . '/fmipservice/client/web/refreshClient?dsid=' . $this->ds_id;
			$client_context = $this->clien_context;
			$client_context['shouldLocate'] = true;
			$client_context['selectedDevice'] = $device['id'];
			$post = array('serverContext' => $this->server_context, 'clientContext' => $client_context);
			$page = Curl::PostQuery($url, json_encode($post), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com'));
			$result = json_decode($page, true);

			if (!(isset($result['serverContext']))) {
				throw new Exception('Location ERROR[Server context not found]');
			}


			if ($result['statusCode'] != 200) {
				throw new Exception('Location ERROR');
			}


			$this->server_context = $result['serverContext'];

			if (isset($result['content']) && (0 < count($result['content']))) {
				return $result['content'];
			}


			throw new Exception('Location problem');

			foreach ($result['content'] as $dev ) {
				if ($dev['id'] == $device['id']) {
					if ($device['location']['locationFinished']) {
					}


					return true;
				}
			}

			sleep(1);
			$i = $i + 1;
		}

		return false;
	}

	public function LostModeOff($device)
	{
		$request = array('device' => $device['id'], 'lostModeEnabled' => true, 'trackingEnabled' => false, 'emailUpdates' => false, 'userText' => false, 'serverContext' => $this->server_context, 'clientContext' => $this->clien_context);
		$url = $this->host . '/fmipservice/client/web/lostDevice?&dsid=' . $this->ds_id;
		$page = Curl::PostQuery($url, json_encode($request), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com'));
		$result = json_decode($page, true);

		if (isset($result['content']) && (0 < count($result['content']))) {
			return $result['content'][0];
		}


		return false;
	}

	public function getAuthToken($device)
	{
		$request = array('authToken' => $this->pass, 'device' => $device['id'], 'serverContext' => $this->server_context, 'clientContext' => $this->clien_context);
		$url = $this->host . '/fmipservice/client/web/authForUserDevice?dsid=' . $this->ds_id;
		$page = Curl::PostQuery($url, json_encode($request), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com', 'Referer: https://www.icloud.com/applications/find/current/en-us/index.html?'));
		$data = json_decode($page, true);

		if ($data['statusCode'] != 200) {
			throw new Exception('Can\'t get auth token');
		}


		return $data['authToken'];
	}

	public function RemoveByImei($data)
	{
		if (!(isset($data['imei'])) && !(isset($data['serial']))) {
			throw new Exception('Imei or serial required');
		}


		$devices = $this->GetSettingsDevices();
		$c_device = false;

		foreach ($devices as $device ) {
			if (isset($data['imei'])) {
				if (isset($device['imei'])) {
					$imei = str_replace('●', '', $device['imei']);

					if (preg_match('|^[0-9]*' . $imei . '$|isUS', $data['imei'])) {
						$c_device = $device;
						break;
					}

				}


				if (isset($device['imei'])) {
					$serial = str_replace('●', '', $device['serialNumber']);

					if (preg_match('|^.*' . $serial . '$|isUS', $data['imei'])) {
						$c_device = $device;
						break;
					}

				}

			}
		}

		if (!($c_device)) {
			throw new Exception('Device not found');
		}


		$devices = $this->GetDevices();
		sleep(40);

		foreach ($devices as $device ) {
			if ($device['name'] == $c_device['name']) {
				if (!($this->SettingsRemove($c_device))) {
					throw new Exception('Can\'t remove device from settings');
				}


				if (!($this->Remove($device))) {
					throw new Exception('Can\'t remove device from map page');
				}


				return true;
			}
		}

		throw new Exception('Device not found on page');
	}

	public function RemoveAll()
	{
		$devices_s = $this->GetSettingsDevices();
		sleep(15);
		$setting_device = array();

		foreach ($devices_s as $device_s ) {
			$this->SettingsRemove($device_s);
			array_push($setting_device, $device_s);
		}

		$devices = $this->GetDevices();
		sleep(40);
		$remove_device = array();
		$unremove_device = array();

		foreach ($devices as $device ) {
			if (!($this->Remove($device))) {
				array_push($unremove_device, $device);
			}
			 else {
				array_push($remove_device, $device);
			}
		}

		return array($remove_device, $unremove_device, $setting_device);
	}

	public function Remove($device)
	{
		if ($device['deviceStatus'] == 200) {
			return false;
		}


		$token = $this->getAuthToken($device);
		$request = array('authToken' => $token, 'device' => $device['id'], 'serverContext' => $this->server_context, 'clientContext' => $this->clien_context);
		$url = $this->host . '/fmipservice/client/web/remove?dsid=' . $this->ds_id;
		$page = Curl::PostQuery($url, json_encode($request), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com', 'Referer: https://www.icloud.com/applications/find/current/en-us/index.html?'));
		$result = json_decode($page, true);
		$request = array('device' => $device['id'], 'serverContext' => $this->server_context, 'clientContext' => $this->clien_context, 'authToken' => $token, 'passcode' => '', 'text' => '');
		$url = $this->host . '/fmipservice/client/web/remoteWipeWithUserAuth?dsid=' . $this->ds_id;
		$page = Curl::PostQuery($url, json_encode($request), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com', 'Referer: https://www.icloud.com/applications/find/current/en-us/index.html?'));
		$result = json_decode($page, true);

		if (isset($result['statusCode']) && ($result['statusCode'] == 200)) {
			return $this->isDeviceRemoved($device);
		}

	}

	public function isDeviceRemoved($s_device)
	{
		$devices = $this->GetDevices();
		sleep(10);

		foreach ($devices as $device ) {
			if ($device['id'] == $s_device['id']) {
				$this->Remove($device);
			}

		}

		return true;
	}

	public function GetSettingsDevices()
	{
		if (!($this->settings_host)) {
			throw new Exception('Service unavailable');
		}


		$url = $this->settings_host . '/setup/web/device/getDevices?dsid=' . $this->ds_id;
		$page = Curl::OpenPage($url, array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com', 'Referer: https://www.icloud.com/applications/settings/current/en-us/index.html'));
		$data = json_decode($page, true);

		if (isset($data['devices'])) {
			$devices = array();

			foreach ($data['devices'] as $dev ) {
				$device_short = array('imei' => $dev['imei'], 'serialNumber' => $dev['serialNumber'], 'name' => $dev['name'], 'modelDisplayName' => $dev['modelDisplayName'], 'udid' => $dev['udid']);
				array_push($devices, $device_short);
			}

			return $devices;
		}


		return array();
	}

	public function SettingsRemove($device)
	{
		if (!(isset($device['udid']))) {
			throw new Exception('Invalid device');
		}


		if (!($this->settings_host)) {
			throw new Exception('Service unavailable');
		}


		$url = $this->settings_host . '/setup/web/device/removeDevice?dsid=' . $this->ds_id;
		$request = array('udid' => $device['udid']);
		$page = Curl::PostQuery($url, json_encode($request), array('Accept: */*', 'Accept-Encoding: gzip,deflate,sdch', 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4', 'Origin: https://www.icloud.com', 'Referer: https://www.icloud.com/applications/settings/current/en-us/index.html'));
		$data = json_decode($page, true);
		echo '<pre>';
		print_r($data);
		echo '<pre>';

		if (isset($data['devices'])) {
			return true;
		}


		return false;
	}
}


?>