diff --git a/README.md b/README.md index 1349b73..22722b8 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,22 @@ This reads codes from email; it does not generate them (that is `pyotp`'s job). `requirements.txt`: ``` -aiomail @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.4 +aiomail @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.5 # OAuth token providers (Microsoft / Google) need the extra: -aiomail[oauth] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.4 +aiomail[oauth] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.5 ``` Direct: ```bash -pip install "aiomail @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.4" -pip install "aiomail[oauth] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.4" +pip install "aiomail @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.5" +pip install "aiomail[oauth] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aiomail.git@v0.1.5" ``` Requires `aioimaplib` and `beautifulsoup4` (pulled transitively). The `oauth` extra adds `aiohttp` for the refresh-token providers. -Drop the `@v0.1.4` suffix from the line above to install the latest unpinned. +Drop the `@v0.1.5` suffix from the line above to install the latest unpinned. ## Password auth diff --git a/pyproject.toml b/pyproject.toml index c96174c..4c863f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "aiomail" -version = "0.1.4" +version = "0.1.5" description = "async IMAP one-time-code retrieval with password/OAuth2 auth and dynamic matching" requires-python = ">=3.10" dependencies = [ diff --git a/src/aiomail/__init__.py b/src/aiomail/__init__.py index 61216d9..d8278a4 100644 --- a/src/aiomail/__init__.py +++ b/src/aiomail/__init__.py @@ -29,4 +29,4 @@ __all__ = [ "DEFAULT_FOLDERS", ] -__version__ = "0.1.4" +__version__ = "0.1.5" diff --git a/src/aiomail/oauth.py b/src/aiomail/oauth.py index c10c9de..25fe58b 100644 --- a/src/aiomail/oauth.py +++ b/src/aiomail/oauth.py @@ -81,7 +81,9 @@ class _RefreshTokenProvider: self._failures = 0 return token else: - body = await resp.text() + # log a truncated error body only — a token-endpoint + # response can carry sensitive material; never dump it whole + body = (await resp.text())[:200] log.warning("token endpoint %s -> %s: %s", endpoint, resp.status, body) except Exception as exc: log.warning("token request to %s failed: %s", endpoint, exc) diff --git a/src/aiomail/retrieve.py b/src/aiomail/retrieve.py index 072c29c..fc9df78 100644 --- a/src/aiomail/retrieve.py +++ b/src/aiomail/retrieve.py @@ -113,12 +113,14 @@ async def retrieve_otp( if max_age is not None: age = _age_seconds(message) if age is not None and age > max_age: - log.info("code %s skipped, too old (%.0fs > %.0fs)", code, age, max_age) + log.info("code skipped, too old (%.0fs > %.0fs)", age, max_age) continue if mark_seen: await client.mark_seen(email_id) - log.info("found code %s in %s", code, folder) + # never log the code value — it's a live single-use secret that would + # reach any aggregation/retention sink the host wires up + log.info("found code in %s", folder) return code if attempt < retries: