Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions frontend/src/components/tools/ToolPanels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ function HeadersPanel() {
</Card>
{result.origin_ip && (
<Card title={t('toolPanels.headers.origin')}>
<Row label="IP" value={result.origin_ip} />
<Row label={t('toolPanels.headers.ip')} value={result.origin_ip} />
<Row label={t('toolPanels.headers.rdns')} value={result.origin_rdns} />
{result.origin_geo && (
<>
Expand Down Expand Up @@ -690,7 +690,7 @@ function SubnetPanel() {
)}
{errors.prefix && <span className="text-[11px] text-red">{errors.prefix}</span>}
</div>
<RunBtn loading={false} label="Calculate" onClick={run} />
<RunBtn loading={false} label={t('toolPanels.subnet.calculate')} onClick={run} />
</div>

{prefixMode === 'cidr' && (
Expand All @@ -710,15 +710,15 @@ function SubnetPanel() {

{result && (
<Card>
<Row label="Network Address" value={`${result.networkAddress}/${result.cidr}`} />
<Row label="Subnet Mask" value={result.subnetMask} />
<Row label="Wildcard Mask" value={result.wildcardMask} />
<Row label="Broadcast Address" value={result.broadcastAddress} />
<Row label="First Usable IP" value={result.firstUsable} />
<Row label="Last Usable IP" value={result.lastUsable} />
<Row label="Usable Hosts" value={result.usableHosts.toLocaleString()} />
<Row label="Total Addresses" value={result.totalHosts.toLocaleString()} />
<Row label="IP Type" value={result.ipType} />
<Row label={t('toolPanels.subnet.networkAddress')} value={`${result.networkAddress}/${result.cidr}`} />
<Row label={t('toolPanels.subnet.subnetMask')} value={result.subnetMask} />
<Row label={t('toolPanels.subnet.wildcardMask')} value={result.wildcardMask} />
<Row label={t('toolPanels.subnet.broadcastAddress')} value={result.broadcastAddress} />
<Row label={t('toolPanels.subnet.firstUsableIp')} value={result.firstUsable} />
<Row label={t('toolPanels.subnet.lastUsableIp')} value={result.lastUsable} />
<Row label={t('toolPanels.subnet.usableHosts')} value={result.usableHosts.toLocaleString()} />
<Row label={t('toolPanels.subnet.totalAddresses')} value={result.totalHosts.toLocaleString()} />
<Row label={t('toolPanels.subnet.ipType')} value={result.ipType} />
</Card>
)}
</div>
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "Ausgabe",
"invalid": "Ungültige Eingabe für den gewählten Modus."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "JWT-Decoder",
"placeholder": "JWT-Token einfügen (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "Output",
"invalid": "Invalid input for the selected mode."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "JWT Decoder",
"placeholder": "Paste a JWT token (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,18 @@
"output": "Salida",
"invalid": "Entrada no válida para el modo seleccionado."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "Decodificador JWT",
"placeholder": "Pegue un token JWT (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,18 @@
"output": "Résultat",
"invalid": "Entrée invalide pour le mode sélectionné."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "Décodeur JWT",
"placeholder": "Collez un jeton JWT (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "Output",
"invalid": "Input non valido per la modalità selezionata."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "Decoder JWT",
"placeholder": "Incolla un token JWT (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,18 @@
"output": "Wynik",
"invalid": "Nieprawidłowe dane wejściowe dla wybranego trybu."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "Dekoder JWT",
"placeholder": "Wklej token JWT (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "Saída",
"invalid": "Entrada inválida para o modo selecionado."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "Decodificador JWT",
"placeholder": "Cole um token JWT (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "Результат",
"invalid": "Некорректные данные для выбранного режима."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "Декодер JWT",
"placeholder": "Вставьте JWT-токен (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/tr.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "Çıktı",
"invalid": "Seçilen mod için geçersiz girdi."
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "JWT Çözücü",
"placeholder": "Bir JWT belirteci yapıştırın (eyJ...)…",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/messages/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
"output": "输出",
"invalid": "所选模式的输入无效。"
},
"subnet": {
"calculate": "Calculate",
"networkAddress": "Network Address",
"subnetMask": "Subnet Mask",
"wildcardMask": "Wildcard Mask",
"broadcastAddress": "Broadcast Address",
"firstUsableIp": "First Usable IP",
"lastUsableIp": "Last Usable IP",
"usableHosts": "Usable Hosts",
"totalAddresses": "Total Addresses",
"ipType": "IP Type"
},
"jwt": {
"title": "JWT 解码器",
"placeholder": "粘贴 JWT 令牌(eyJ...)…",
Expand Down
16 changes: 3 additions & 13 deletions modules/cert_transparency.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@
sys.path.append('..')
from config import Colors, USER_AGENT
from modules import get_proxies, get_with_retry
from modules.module_status import annotate, classify, reason_for, OK, RATE_LIMITED, ERROR


def _http_failure(result: Dict[str, Any], source: str, status_code: int) -> Dict[str, Any]:
if status_code in (429, 503):
return annotate(
result,
RATE_LIMITED,
f"{source} is busy or rate limited (HTTP {status_code}); try again later",
)
return annotate(result, ERROR, f"{source} returned status {status_code}")
from modules.module_status import annotate, annotate_http_failure, classify, reason_for, OK, RATE_LIMITED, ERROR


class CertTransparency:
Expand Down Expand Up @@ -44,7 +34,7 @@ def _search_crtsh(self, domain: str) -> Dict[str, Any]:


if response.status_code != 200:
return _http_failure(result, "crt.sh", response.status_code)
return annotate_http_failure(result, "crt.sh", response.status_code)

try:
certs = response.json()
Expand Down Expand Up @@ -144,7 +134,7 @@ def _search_certspotter(self, domain: str) -> Dict[str, Any]:
proxies=get_proxies(),
)
if response.status_code != 200:
return _http_failure(result, "certspotter", response.status_code)
return annotate_http_failure(result, "certspotter", response.status_code)
try:
issuances = response.json()
except Exception:
Expand Down
10 changes: 10 additions & 0 deletions modules/module_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,13 @@ def annotate(result: Dict[str, Any], status: str, reason: Optional[str] = None)
else:
result["error"] = None
return result


def annotate_http_failure(result: Dict[str, Any], source: str, status_code: int) -> Dict[str, Any]:
if status_code in (429, 503):
return annotate(
result,
RATE_LIMITED,
f"{source} is busy or rate limited (HTTP {status_code}); try again later",
)
return annotate(result, ERROR, f"{source} returned status {status_code}")
18 changes: 4 additions & 14 deletions modules/wayback.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,7 @@
sys.path.append('..')
from config import Colors
from modules import get_proxies, get_with_retry
from modules.module_status import annotate, OK, RATE_LIMITED, ERROR


def _http_failure(result: Dict[str, Any], source: str, status_code: int) -> Dict[str, Any]:
if status_code in (429, 503):
return annotate(
result,
RATE_LIMITED,
f"{source} is busy or rate limited (HTTP {status_code}); try again later",
)
return annotate(result, ERROR, f"{source} returned status {status_code}")
from modules.module_status import annotate, annotate_http_failure, OK, RATE_LIMITED, ERROR


class WaybackMachine:
Expand Down Expand Up @@ -51,7 +41,7 @@ def get_snapshots(self, url: str, limit: int = 20) -> Dict[str, Any]:
)

if r.status_code != 200:
return _http_failure(result, "CDX API", r.status_code)
return annotate_http_failure(result, "CDX API", r.status_code)

rows = r.json()
if not rows or len(rows) < 2:
Expand Down Expand Up @@ -131,7 +121,7 @@ def get_all_urls(self, domain: str, limit: int = 100) -> Dict[str, Any]:
)

if r.status_code != 200:
return _http_failure(result, "CDX API", r.status_code)
return annotate_http_failure(result, "CDX API", r.status_code)

rows = r.json()
if not rows or len(rows) < 2:
Expand Down Expand Up @@ -170,7 +160,7 @@ def check_availability(self, url: str) -> Dict[str, Any]:
result["closest_snapshot"] = closest.get("url")
return annotate(result, OK)
else:
return _http_failure(result, "Wayback availability API", r.status_code)
return annotate_http_failure(result, "Wayback availability API", r.status_code)
except Exception as e:
return annotate(result, ERROR, str(e))

Expand Down
21 changes: 21 additions & 0 deletions tests/test_module_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from modules.module_status import (
annotate,
annotate_http_failure,
classify,
reason_for,
status_notice,
Expand Down Expand Up @@ -189,3 +190,23 @@ def test_telegram_id_skipped_without_token(self):
assert result["error"] is None


class TestAnnotateHttpFailure:
def test_rate_limited(self):
# 429 and 503 should result in RATE_LIMITED
r429 = annotate_http_failure({}, "My API", 429)
assert r429["status"] == RATE_LIMITED
assert "rate limited" in r429["status_reason"]
assert "429" in r429["status_reason"]
assert "My API" in r429["status_reason"]
assert r429["error"] is None

r503 = annotate_http_failure({}, "Other API", 503)
assert r503["status"] == RATE_LIMITED
assert "503" in r503["status_reason"]

def test_error(self):
# 500 should result in ERROR
r500 = annotate_http_failure({}, "Bad API", 500)
assert r500["status"] == ERROR
assert "returned status 500" in r500["error"]
assert "Bad API" in r500["error"]
Loading