<commit_before><?php
	require_once(dirname(__FILE__) . '/../Bank.php');
	require_once(dirname(__FILE__) . '/../Account.php');
	require_once(dirname(__FILE__) . '/../Transaction.php');

	require_once(dirname(__FILE__) . '/../3rdparty/simpletest/browser.php');
	require_once(dirname(__FILE__) . '/../3rdparty/phpquery/phpQuery/phpQuery.php');

	/**
	 * Code to scrape HSBC to get Account and Transaction objects.
	 */
	class HSBC extends WebBank {
		private $account = '';
		private $securekey = '';
		private $secretword = '';

		private $securityDomain = 'www.security.hsbc.co.uk';
		private $saasDomain = 'www.saas.hsbc.co.uk';

		private $accounts = null;

		/**
		 * Create a HSBC.
		 *
		 * @param $account Account number (IB...)
		 * @param $secretword Secret Word
		 * @param $securekey Secure Key Code
		 */
		public function __construct($account, $secretword, $securekey) {
			parent::__construct();
			$this->account = $account;
			$this->secretword = $secretword;
			$this->securekey = $securekey;
		}

		/**
		 * String representation of this bank.
		 */
		public function __toString() {
			return 'HSBC/' . $this->account;
		}

		/**
		 * Force a fresh login.
		 *
		 * @return true if login was successful, else false.
		 */
		public function login($fresh = false) {
			if (!$fresh) {
				$this->newBrowser(true);
				$page = $this->browser->get('https://' . $this->saasDomain . '/1/3/personal/online-banking?BlitzToken=<PASSWORD>');
				if ($this->isLoggedIn($page)) {
					return true;
				}
			} else {
				$this->newBrowser(false);
			}

			$page = $this->browser->get('https://www.hsbc.co.uk/');
			$page = $this->getDocument($page);

			// Move to login page
			$element = $page->find('a[title="Log on to Personal Internet Banking"');
			$loginurl = $element->eq(0)->attr('href');
			$page = $this->browser->get('https://www.hsbc.co.uk/' . $loginurl);

			// Fill out the form and submit it.
			$this->browser->setFieldById('intbankingID', $this->account);
			// $this->browser->setMaximumRedirects(1);
			$page = $this->browser->submitFormById('logonForm');
			// Submit a couple of SaaS forms.

			while (preg_match('#document\.tempForm\.submit#Ums', $page)) {
				$page = $this->browser->submitFormByName('tempForm');
			}

			$securityDomain = parse_url($this->browser->getUrl());
			$this->securityDomain = $securityDomain['host'];

			if ($this->securekey == '##') {
				$this->browser->get('https://' . $this->securityDomain . '/gsa/IDV_CAM20_OTP_CHALLENGE/?__USER=withSecKey');
				$this->securekey = getUserInput('Please enter the securekey code for '.$this->account.': ');
				if ($this->securekey === false) {
					return false;
				}

				// Set the fields
				$this->browser->setFieldById('memorableAnswer', $this->secretword);
				$this->browser->setFieldById('idv_OtpCredential', $this->securekey);
			} else if (startsWith($this->securekey, '@')) {
				$page = $this->browser->get('https://' . $this->securityDomain . '/gsa/IDV_CAM10TO30_AUTHENTICATION/?__USER=withOutSecKey');

				if (!preg_match('#chalNums: \[([0-9], [0-9], [0-9])\]#Ums', $page, $matches)) {
					return false;
				}

				$wanted = explode(',', $matches[1]);
				$digits = array();
				foreach ($wanted as $d) {
					if ($d == '8') { $d = strlen($this->securekey) - 1; }
					if ($d == '7') { $d = strlen($this->securekey) - 2; }

					$digits[] = $this->securekey[$d];
				}

				$this->browser->setFieldById('memorableAnswer', $this->secretword);
				$this->browser->setFieldById('password', implode('', $digits));
			}
<commit_msg>Update HSBC to work again, handle all the extra form-based redirects.<commit_after><?php
	require_once(dirname(__FILE__) . '/../Bank.php');
	require_once(dirname(__FILE__) . '/../Account.php');
	require_once(dirname(__FILE__) . '/../Transaction.php');

	require_once(dirname(__FILE__) . '/../3rdparty/simpletest/browser.php');
	require_once(dirname(__FILE__) . '/../3rdparty/phpquery/phpQuery/phpQuery.php');

	/**
	 * Code to scrape HSBC to get Account and Transaction objects.
	 */
	class HSBC extends WebBank {
		private $account = '';
		private $securekey = '';
		private $secretword = '';

		private $securityDomain = 'www.security.hsbc.co.uk';
		private $saasDomain = 'www.saas.hsbc.co.uk';

		private $accounts = null;

		/**
		 * Create a HSBC.
		 *
		 * @param $account Account number (IB...)
		 * @param $secretword Secret Word
		 * @param $securekey Secure Key Code
		 */
		public function __construct($account, $secretword, $securekey) {
			parent::__construct();
			$this->account = $account;
			$this->secretword = $secretword;
			$this->securekey = $securekey;
		}

		/**
		 * String representation of this bank.
		 */
		public function __toString() {
			return 'HSBC/' . $this->account;
		}

		/**
		 * Handle any form-based redirects.
		 *
		 * @param $page (By Ref) Page that we want to check for redirects.
		 */
		public function followFormRedirect(&$page) {
			while (preg_match('#document\.tempForm\.submit#Ums', $page) || preg_match('#var autoSubmitForm = document.getElementById\("[^"]+"\);#Ums', $page)) {
				if (preg_match('#document\.tempForm\.submit#Ums', $page)) {
					$page = $this->browser->submitFormByName('tempForm');
				}
				if (preg_match('#var autoSubmitForm = document.getElementById\("([^"]+)"\);#Ums', $page, $m)) {
					$page = $this->browser->submitFormByName($m[1]);
				}
			}
		}

		/**
		 * Get the requested page, following any post-get redirects.
		 *
		 * @param $url URL of page to get.
		 * @param $justGet (Default: false) Just get the page, don't try to auth.
		 */
		protected function getPage($url, $justGet = false) {
			$page = parent::getPage($url, $justGet);
			$this->followFormRedirect($page);
			return $page;
		}

		/**
		 * Force a fresh login.
		 *
		 * @return true if login was successful, else false.
		 */
		public function login($fresh = false) {
			if (!$fresh) {
				$this->newBrowser(true);
				$page = $this->browser->get('https://' . $this->saasDomain . '/1/3/personal/online-banking?BlitzToken=<PASSWORD>');
				$this->followFormRedirect($page);

				if ($this->isLoggedIn($page)) {
					return true;
				}
			} else {
				$this->newBrowser(false);
			}

			$page = $this->browser->get('https://www.hsbc.co.uk/');
			$this->followFormRedirect($page);
			$page = $this->getDocument($page);

			// Move to login page
			$element = $page->find('a[title="Log on to Personal Internet Banking"');
			$loginurl = $element->eq(0)->attr('href');
			$page = $this->browser->get('https://www.hsbc.co.uk' . $loginurl);
			$this->followFormRedirect($page);

			// Fill out the form and submit it.
			$this->browser->setFieldById('Username1', $this->account);
			// $this->browser->setMaximumRedirects(1);
			$page = $this->browser->submitFormById('ibLogonForm');

			// Submit a couple of SaaS forms.
			$this->followFormRedirect($page);

			$securityDomain = parse_url($this->browser->getUrl());
			$this->securityDomain = $securityDomain['host'];

			if ($this->securekey == '##') {
				$this->browser->get('https://' . $this->securityDomain . '/gsa/IDV_CAM20_OTP_CHALLENGE/?__USER=withSecKey');
				$this->securekey = getUserInput('Please enter the securekey code for '.$this->account.': ');
				if ($this->securekey === false) {
					return false;
				}

				// Set the fields
				$this->browser->setFieldById('memorableAnswer', $this->secretword);
				$this->browser->setFieldById('idv_OtpCredential', $this->securekey);
			} else if (startsWith($this->securekey, '@')) {
				$page = $this->browser->get('https://' . $this->securityDomain . '/gsa/IDV_CAM10TO30_AUTHENTICATION/?__USER=withOutSecKey');

				if (!preg_match('#chalNums: \[([0-9], [0-9], [0-9])\]#Ums', $page, $matches)) {
					return false;
				}
				$wanted = explode(',', $matches[1]);
				$digits = array();
				foreach ($wanted as $d) {
					if ($d == '8') { $d = strlen($this->securekey) - 1; }
					if ($d == '7') { $d = strlen($this->securekey) - 2; }

					$digits[] = $this->securekey[$d];
				}

				$this->browser->setFieldById('memorableAnswer', $this->secretword);
				$this->browser->setFieldById('password', implode('', $digits));
			}

{'fraction_non_alphanumeric': 0.19810508182601205, 'fraction_numerical': 0.005906238464377999, 'mean_word_length': 3.4807056229327453, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 122, 'https://': 10, 'lorem ipsum': 0, 'www.': 8, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5773756', 'n_tokens_mistral': 3189, 'n_tokens_neox': 2679, 'n_words': 536}