dominusnode-composio 1.2.0__tar.gz → 1.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dominusnode-composio might be problematic. Click here for more details.
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/PKG-INFO +1 -1
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio/tools.py +48 -1
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/PKG-INFO +1 -1
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/pyproject.toml +1 -1
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/LICENSE +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/README.md +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio/__init__.py +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/SOURCES.txt +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/dependency_links.txt +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/requires.txt +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/top_level.txt +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/setup.cfg +0 -0
- {dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/tests/test_tools.py +0 -0
|
@@ -41,6 +41,7 @@ Requires: httpx (``pip install httpx``)
|
|
|
41
41
|
|
|
42
42
|
from __future__ import annotations
|
|
43
43
|
|
|
44
|
+
import hashlib
|
|
44
45
|
import ipaddress
|
|
45
46
|
import json
|
|
46
47
|
import math
|
|
@@ -383,6 +384,46 @@ def _sanitize_error(message: str) -> str:
|
|
|
383
384
|
return _CREDENTIAL_RE.sub("***", message)
|
|
384
385
|
|
|
385
386
|
|
|
387
|
+
def _count_leading_zero_bits(data: bytes) -> int:
|
|
388
|
+
"""Count leading zero bits in a byte array."""
|
|
389
|
+
count = 0
|
|
390
|
+
for byte in data:
|
|
391
|
+
if byte == 0:
|
|
392
|
+
count += 8
|
|
393
|
+
else:
|
|
394
|
+
mask = 0x80
|
|
395
|
+
while mask and not (byte & mask):
|
|
396
|
+
count += 1
|
|
397
|
+
mask >>= 1
|
|
398
|
+
break
|
|
399
|
+
return count
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def _solve_pow(base_url: str) -> Optional[dict]:
|
|
403
|
+
"""Solve a Proof-of-Work challenge for CAPTCHA-free registration."""
|
|
404
|
+
try:
|
|
405
|
+
pow_url = f"{base_url.rstrip('/')}/api/auth/pow/challenge"
|
|
406
|
+
with httpx.Client(timeout=30.0, follow_redirects=False) as client:
|
|
407
|
+
resp = client.post(pow_url, headers={"Content-Type": "application/json"})
|
|
408
|
+
if resp.status_code >= 400:
|
|
409
|
+
return None
|
|
410
|
+
challenge = resp.json()
|
|
411
|
+
prefix = challenge.get("prefix", "")
|
|
412
|
+
difficulty = challenge.get("difficulty", 20)
|
|
413
|
+
challenge_id = challenge.get("challengeId", "")
|
|
414
|
+
if not prefix or not challenge_id:
|
|
415
|
+
return None
|
|
416
|
+
nonce = 0
|
|
417
|
+
while nonce < 100_000_000:
|
|
418
|
+
h = hashlib.sha256((prefix + str(nonce)).encode()).digest()
|
|
419
|
+
if _count_leading_zero_bits(h) >= difficulty:
|
|
420
|
+
return {"challengeId": challenge_id, "nonce": str(nonce)}
|
|
421
|
+
nonce += 1
|
|
422
|
+
return None
|
|
423
|
+
except Exception:
|
|
424
|
+
return None
|
|
425
|
+
|
|
426
|
+
|
|
386
427
|
# ---------------------------------------------------------------------------
|
|
387
428
|
# Prototype pollution prevention
|
|
388
429
|
# ---------------------------------------------------------------------------
|
|
@@ -1779,9 +1820,15 @@ class DominusNodeToolkit:
|
|
|
1779
1820
|
return json.dumps({"error": "password must be between 8 and 128 characters"})
|
|
1780
1821
|
|
|
1781
1822
|
try:
|
|
1823
|
+
body: dict = {"email": email, "password": password}
|
|
1824
|
+
pow_result = _solve_pow(self.base_url)
|
|
1825
|
+
if pow_result:
|
|
1826
|
+
body["pow"] = pow_result
|
|
1782
1827
|
result = self._unauth_request(
|
|
1783
|
-
"POST", "/api/auth/register",
|
|
1828
|
+
"POST", "/api/auth/register", body
|
|
1784
1829
|
)
|
|
1830
|
+
if pow_result and isinstance(result, dict):
|
|
1831
|
+
result["_pow_verified"] = True
|
|
1785
1832
|
return json.dumps(result)
|
|
1786
1833
|
except Exception as e:
|
|
1787
1834
|
return json.dumps({"error": _sanitize_error(str(e))})
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dominusnode-composio"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.1"
|
|
8
8
|
description = "Dominus Node tools for Composio -- 22 proxy, wallet, and team management actions"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dominusnode_composio-1.2.0 → dominusnode_composio-1.2.1}/dominusnode_composio.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|