Skip to content

Commit 0bc3391

Browse files
committed
Refactor: Use /api/user/info endpoint for get_api_status()
- Replace Pro detection hack (querying Pro-only plugins) with proper /api/user/info endpoint call - Returns accurate data: username, email, level, is_pro, quota, features - Still cached per client instance for efficiency
1 parent 63b5097 commit 0bc3391

2 files changed

Lines changed: 64 additions & 71 deletions

File tree

leakix/async_client.py

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -243,53 +243,49 @@ async def get_plugins(self) -> list[APIResult]:
243243

244244
async def get_api_status(self, force: bool = False) -> dict:
245245
"""
246-
Check API status and detect Pro subscription.
246+
Check API status and subscription info via /api/user/info endpoint.
247247
248248
Results are cached per client instance. Use force=True to refresh.
249249
250250
Args:
251251
force: Force refresh of cached status.
252252
253253
Returns:
254-
Dict with authenticated, is_pro, features, and plugins_count.
254+
Dict with username, email, level, is_pro, quota, features, created.
255255
"""
256256
if self._api_status is not None and not force:
257257
return self._api_status
258258

259-
status: dict = {
260-
"authenticated": bool(self.api_key),
261-
"is_pro": False,
262-
"features": [
263-
"search",
264-
"host_lookup",
265-
"domain_lookup",
266-
"subdomains",
267-
],
268-
"plugins_count": 0,
269-
}
270-
271259
if not self.api_key:
272-
self._api_status = status
273-
return status
274-
275-
# Test Pro by querying a Pro-only plugin (WpUserEnumHttp)
276-
try:
277-
result = await self.search("+plugin:WpUserEnumHttp", scope="leak", page=0)
278-
if result and len(result) > 0:
279-
status["is_pro"] = True
280-
status["features"].extend(["bulk_export", "pro_plugins"])
281-
except Exception:
282-
pass
283-
284-
# Get available plugins count
285-
try:
286-
plugins = await self.get_plugins()
287-
status["plugins_count"] = len(plugins)
288-
except Exception:
289-
pass
290-
291-
self._api_status = status
292-
return status
260+
self._api_status = {
261+
"authenticated": False,
262+
"is_pro": False,
263+
"features": [],
264+
"quota": {"total": 0, "remaining": 0, "used": 0},
265+
}
266+
return self._api_status
267+
268+
status_code, data = await self._get("/api/user/info")
269+
if status_code == 200 and isinstance(data, dict):
270+
self._api_status = {
271+
"authenticated": True,
272+
"username": data.get("username"),
273+
"email": data.get("email"),
274+
"level": data.get("level"),
275+
"is_pro": data.get("is_pro", False),
276+
"quota": data.get("quota", {}),
277+
"features": data.get("features", []),
278+
"created": data.get("created"),
279+
}
280+
else:
281+
self._api_status = {
282+
"authenticated": False,
283+
"is_pro": False,
284+
"features": [],
285+
"quota": {"total": 0, "remaining": 0, "used": 0},
286+
}
287+
288+
return self._api_status
293289

294290
async def is_pro(self) -> bool:
295291
"""Check if the API key has Pro access. Result is cached."""

leakix/client.py

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -313,54 +313,51 @@ def bulk_export_stream(self, queries: list[Query] | None = None):
313313

314314
def get_api_status(self, force: bool = False) -> dict:
315315
"""
316-
Check API status and detect Pro subscription.
316+
Check API status and subscription info via /api/user/info endpoint.
317317
318318
Results are cached per client instance. Use force=True to refresh.
319319
320320
Args:
321321
force: Force refresh of cached status.
322322
323323
Returns:
324-
Dict with authenticated, is_pro, features, and plugins_count.
324+
Dict with username, email, level, is_pro, quota, features, created.
325325
"""
326326
if self._api_status is not None and not force:
327327
return self._api_status
328328

329-
status: dict = {
330-
"authenticated": bool(self.api_key),
331-
"is_pro": False,
332-
"features": [
333-
"search",
334-
"host_lookup",
335-
"domain_lookup",
336-
"subdomains",
337-
],
338-
"plugins_count": 0,
339-
}
340-
341329
if not self.api_key:
342-
self._api_status = status
343-
return status
344-
345-
# Test Pro by querying a Pro-only plugin (WpUserEnumHttp)
346-
try:
347-
result = self.search("+plugin:WpUserEnumHttp", scope="leak", page=0)
348-
if result.is_success() and len(result.json()) > 0:
349-
status["is_pro"] = True
350-
status["features"].extend(["bulk_export", "pro_plugins"])
351-
except Exception:
352-
pass
353-
354-
# Get available plugins count
355-
try:
356-
plugins_response = self.get_plugins()
357-
if plugins_response.is_success():
358-
status["plugins_count"] = len(plugins_response.json())
359-
except Exception:
360-
pass
361-
362-
self._api_status = status
363-
return status
330+
self._api_status = {
331+
"authenticated": False,
332+
"is_pro": False,
333+
"features": [],
334+
"quota": {"total": 0, "remaining": 0, "used": 0},
335+
}
336+
return self._api_status
337+
338+
url = f"{self.base_url}/api/user/info"
339+
r = self.__get(url, params=None)
340+
if r.is_success():
341+
data = r.json()
342+
self._api_status = {
343+
"authenticated": True,
344+
"username": data.get("username"),
345+
"email": data.get("email"),
346+
"level": data.get("level"),
347+
"is_pro": data.get("is_pro", False),
348+
"quota": data.get("quota", {}),
349+
"features": data.get("features", []),
350+
"created": data.get("created"),
351+
}
352+
else:
353+
self._api_status = {
354+
"authenticated": False,
355+
"is_pro": False,
356+
"features": [],
357+
"quota": {"total": 0, "remaining": 0, "used": 0},
358+
}
359+
360+
return self._api_status
364361

365362
def is_pro(self) -> bool:
366363
"""Check if the API key has Pro access. Result is cached."""

0 commit comments

Comments
 (0)