fix: revert OTP-in-logs (spent on arrival, not a secret); F1 ContentTypeError, F5 callable None-guard
revert the M-1 log change — a single-use OTP is consumed on arrival, not a live secret, so log the code value again. keep the oauth error-body truncate. F1: oauth token fetch uses resp.json(content_type=None) so a 200 with text/plain doesn't ContentTypeError and discard a valid token. F5: as_predicate coalesces None for the callable branch like the string/regex branches. drop a redundant digits.isdigit(). Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
parent
f940641a5a
commit
3da833f2fc
@ -76,7 +76,7 @@ def _scan(text: str, patterns: list[Pattern], lengths: set[int]) -> Optional[str
|
|||||||
return m.group(1) if m.groups() else m.group(0)
|
return m.group(1) if m.groups() else m.group(0)
|
||||||
for token in re.split(r"\s+", text):
|
for token in re.split(r"\s+", text):
|
||||||
digits = "".join(c for c in token if c.isdigit())
|
digits = "".join(c for c in token if c.isdigit())
|
||||||
if digits and len(digits) in lengths and digits.isdigit():
|
if digits and len(digits) in lengths:
|
||||||
return digits
|
return digits
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -121,6 +121,8 @@ def as_predicate(spec: MatchSpec) -> Callable[[Optional[str]], bool]:
|
|||||||
if isinstance(spec, re.Pattern):
|
if isinstance(spec, re.Pattern):
|
||||||
return lambda value: bool(spec.search(value or ""))
|
return lambda value: bool(spec.search(value or ""))
|
||||||
if callable(spec):
|
if callable(spec):
|
||||||
return spec
|
# coalesce None like the string/regex branches so the documented Optional[str]
|
||||||
|
# predicate contract holds even if a caller's callable assumes a real string
|
||||||
|
return lambda value: bool(spec(value or ""))
|
||||||
needle = str(spec).lower()
|
needle = str(spec).lower()
|
||||||
return lambda value: needle in (value or "").lower()
|
return lambda value: needle in (value or "").lower()
|
||||||
|
|||||||
@ -76,7 +76,10 @@ class _RefreshTokenProvider:
|
|||||||
async with aiohttp.ClientSession(timeout=timeout) as session:
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||||
async with session.post(endpoint, data=data) as resp:
|
async with session.post(endpoint, data=data) as resp:
|
||||||
if resp.status == 200:
|
if resp.status == 200:
|
||||||
token = (await resp.json()).get("access_token")
|
# content_type=None: some token endpoints return a 200 with
|
||||||
|
# text/plain or text/javascript; default json() would raise
|
||||||
|
# ContentTypeError and discard a valid token body
|
||||||
|
token = (await resp.json(content_type=None)).get("access_token")
|
||||||
if token:
|
if token:
|
||||||
self._failures = 0
|
self._failures = 0
|
||||||
return token
|
return token
|
||||||
|
|||||||
@ -113,14 +113,12 @@ async def retrieve_otp(
|
|||||||
if max_age is not None:
|
if max_age is not None:
|
||||||
age = _age_seconds(message)
|
age = _age_seconds(message)
|
||||||
if age is not None and age > max_age:
|
if age is not None and age > max_age:
|
||||||
log.info("code skipped, too old (%.0fs > %.0fs)", age, max_age)
|
log.info("code %s skipped, too old (%.0fs > %.0fs)", code, age, max_age)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if mark_seen:
|
if mark_seen:
|
||||||
await client.mark_seen(email_id)
|
await client.mark_seen(email_id)
|
||||||
# never log the code value — it's a live single-use secret that would
|
log.info("found code %s in %s", code, folder)
|
||||||
# reach any aggregation/retention sink the host wires up
|
|
||||||
log.info("found code in %s", folder)
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
if attempt < retries:
|
if attempt < retries:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user