wip chase sms 2fa
parent
43aba0c848
commit
9640d762e0
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import re
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
stream = httpx.stream(
|
||||||
|
'GET',
|
||||||
|
'https://ntfy.pyrocufflink.blue/chase2fa/raw',
|
||||||
|
timeout=httpx.Timeout(5, read=None),
|
||||||
|
)
|
||||||
|
with stream as r:
|
||||||
|
for line in r.iter_lines():
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
m = re.search(r'\d{4,}', line)
|
||||||
|
if m:
|
||||||
|
print(m.group(0))
|
||||||
|
break
|
41
xactfetch.py
41
xactfetch.py
|
@ -551,11 +551,8 @@ class Chase:
|
||||||
with self.saved_cookies.open(encoding='utf-8') as f:
|
with self.saved_cookies.open(encoding='utf-8') as f:
|
||||||
cookies = await asyncio.to_thread(json.load, f)
|
cookies = await asyncio.to_thread(json.load, f)
|
||||||
await self.page.context.add_cookies(cookies)
|
await self.page.context.add_cookies(cookies)
|
||||||
except:
|
except Exception as e:
|
||||||
log.warning(
|
log.debug('Failed to load saved cookies: %s', e)
|
||||||
'Could not load saved cookies, '
|
|
||||||
'SMS verification will be required!'
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
log.info('Successfully loaded saved cookies')
|
log.info('Successfully loaded saved cookies')
|
||||||
|
|
||||||
|
@ -587,9 +584,39 @@ class Chase:
|
||||||
await logonbox.get_by_role('button', name='Sign in').click()
|
await logonbox.get_by_role('button', name='Sign in').click()
|
||||||
log.debug('Waiting for page load')
|
log.debug('Waiting for page load')
|
||||||
await self.page.wait_for_load_state()
|
await self.page.wait_for_load_state()
|
||||||
await self.page.get_by_role('button', name='Pay Card').wait_for(
|
logonframe = self.page.frame_locator('iframe[title="logon"]')
|
||||||
timeout=120000
|
t_2fa = asyncio.create_task(
|
||||||
|
logonframe.get_by_role(
|
||||||
|
'heading', name="We don't recognize this device"
|
||||||
|
).wait_for()
|
||||||
)
|
)
|
||||||
|
t_finished = asyncio.create_task(
|
||||||
|
self.page.get_by_role('button', name='Pay Card').wait_for()
|
||||||
|
)
|
||||||
|
done, pending = await asyncio.wait(
|
||||||
|
(t_2fa, t_finished),
|
||||||
|
return_when=asyncio.FIRST_COMPLETED,
|
||||||
|
)
|
||||||
|
for t in pending:
|
||||||
|
t.cancel()
|
||||||
|
for t in done:
|
||||||
|
await t
|
||||||
|
if t_2fa in done:
|
||||||
|
log.warning('Device verification (SMS 2-factor auth) required')
|
||||||
|
await logonframe.get_by_label('Tell us how: Choose one').click()
|
||||||
|
await logonframe.locator(
|
||||||
|
'#container-1-simplerAuth-dropdownoptions-styledselect'
|
||||||
|
).click()
|
||||||
|
otp_task = asyncio.create_task(self.get_secret('bank.chase.otp'))
|
||||||
|
await logonframe.get_by_role('button', name='Next').click()
|
||||||
|
log.info('Waiting for SMS verification code')
|
||||||
|
otp = await otp_task
|
||||||
|
log.debug('Filling verification code form')
|
||||||
|
await logonframe.get_by_label('One-time code').fill(otp)
|
||||||
|
await logonframe.get_by_label('Password').fill(password)
|
||||||
|
await logonframe.get_by_role('button', name='Next').click()
|
||||||
|
await self.page.wait_for_load_state()
|
||||||
|
await self.page.get_by_role('button', name='Pay Card').wait_for()
|
||||||
log.info('Successfully logged in to Chase')
|
log.info('Successfully logged in to Chase')
|
||||||
self._logged_in = True
|
self._logged_in = True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue