diff --git a/README_FR.md b/README_FR.md index 3d28e6a75..e97cb8d4e 100644 --- a/README_FR.md +++ b/README_FR.md @@ -96,15 +96,15 @@ docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latest Les guides complets se trouvent dans le centre de documentation MyIP : **[docs.ipcheck.ing](https://docs.ipcheck.ing)** (sélecteur de langue en haut à droite) -* [Guide du développeur](https://docs.ipcheck.ing/developer) — déploiement, configuration, architecture et contribution -* [Base de connaissances](https://docs.ipcheck.ing/knowledge-base) — utilisation de chaque outil, diagnostic réseau pas à pas, concepts réseau +* [Guide du développeur](https://docs.ipcheck.ing/developer/fr) — déploiement, configuration, architecture et contribution +* [Base de connaissances](https://docs.ipcheck.ing/knowledge-base/fr) — utilisation de chaque outil, diagnostic réseau pas à pas, concepts réseau ## ⚙️ Configuration Deux réglages comptent avant tout : -* **MaxMind GeoLite2 (requis)** — identifiants gratuits pour la géolocalisation IP et les recherches ASN. Sans eux, la source MaxMind renvoie 503. → [Configuration MaxMind](https://docs.ipcheck.ing/developer/getting-started/maxmind-setup) -* **`ALLOWED_DOMAINS` (requis sur un vrai domaine)** — liste blanche de noms d'hôte pour l'API backend. Sans elle, toute requête venant d'un domaine autre que localhost reçoit un 403. → [Reverse proxy et domaines](https://docs.ipcheck.ing/developer/getting-started/reverse-proxy-and-domains) +* **MaxMind GeoLite2 (requis)** — identifiants gratuits pour la géolocalisation IP et les recherches ASN. Sans eux, la source MaxMind renvoie 503. → [Configuration MaxMind](https://docs.ipcheck.ing/developer/getting-started/fr/maxmind-setup) +* **`ALLOWED_DOMAINS` (requis sur un vrai domaine)** — liste blanche de noms d'hôte pour l'API backend. Sans elle, toute requête venant d'un domaine autre que localhost reçoit un 403. → [Reverse proxy et domaines](https://docs.ipcheck.ing/developer/getting-started/fr/reverse-proxy-and-domains) ```bash docker run -d -p 18966:18966 \ @@ -116,7 +116,7 @@ docker run -d -p 18966:18966 \ jason5ng32/myip:latest ``` -Tout le reste — clés API optionnelles, sécurité et limitation de débit, journalisation, Sentry, domaines de l'API curl — est documenté dans la [référence des variables d'environnement](https://docs.ipcheck.ing/developer/reference/environment-variables). +Tout le reste — clés API optionnelles, sécurité et limitation de débit, journalisation, Sentry, domaines de l'API curl — est documenté dans la [référence des variables d'environnement](https://docs.ipcheck.ing/developer/reference/fr/environment-variables). ## 👩🏻‍💻 Utilisation avancée diff --git a/README_RU.md b/README_RU.md index 460341867..e5a7c0e3e 100644 --- a/README_RU.md +++ b/README_RU.md @@ -96,15 +96,15 @@ docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latest Полные руководства — в центре документации MyIP: **[docs.ipcheck.ing](https://docs.ipcheck.ing)** (переключатель языка в правом верхнем углу) -* [Руководство разработчика](https://docs.ipcheck.ing/developer) — развёртывание, настройка, архитектура и участие в разработке -* [База знаний](https://docs.ipcheck.ing/knowledge-base) — как пользоваться каждым инструментом, пошаговая диагностика сети, сетевые концепции +* [Руководство разработчика](https://docs.ipcheck.ing/developer/ru) — развёртывание, настройка, архитектура и участие в разработке +* [База знаний](https://docs.ipcheck.ing/knowledge-base/ru) — как пользоваться каждым инструментом, пошаговая диагностика сети, сетевые концепции ## ⚙️ Конфигурация Прежде всего важны две настройки: -* **MaxMind GeoLite2 (обязательно)** — бесплатные учётные данные для геолокации IP и запросов ASN. Без них источник MaxMind возвращает 503. → [Настройка MaxMind](https://docs.ipcheck.ing/developer/getting-started/maxmind-setup) -* **`ALLOWED_DOMAINS` (обязательно на реальном домене)** — белый список хостов для backend API. Без него любой запрос с домена, отличного от localhost, получает 403. → [Обратный прокси и домены](https://docs.ipcheck.ing/developer/getting-started/reverse-proxy-and-domains) +* **MaxMind GeoLite2 (обязательно)** — бесплатные учётные данные для геолокации IP и запросов ASN. Без них источник MaxMind возвращает 503. → [Настройка MaxMind](https://docs.ipcheck.ing/developer/getting-started/ru/maxmind-setup) +* **`ALLOWED_DOMAINS` (обязательно на реальном домене)** — белый список хостов для backend API. Без него любой запрос с домена, отличного от localhost, получает 403. → [Обратный прокси и домены](https://docs.ipcheck.ing/developer/getting-started/ru/reverse-proxy-and-domains) ```bash docker run -d -p 18966:18966 \ @@ -116,7 +116,7 @@ docker run -d -p 18966:18966 \ jason5ng32/myip:latest ``` -Всё остальное — необязательные ключи API, безопасность и ограничение частоты запросов, логирование, Sentry, домены curl API — описано в [справочнике переменных окружения](https://docs.ipcheck.ing/developer/reference/environment-variables). +Всё остальное — необязательные ключи API, безопасность и ограничение частоты запросов, логирование, Sentry, домены curl API — описано в [справочнике переменных окружения](https://docs.ipcheck.ing/developer/reference/ru/environment-variables). ## 👩🏻‍💻 Расширенное использование diff --git a/README_ZH.md b/README_ZH.md index d9228d0e5..32dcbfe58 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -96,15 +96,15 @@ docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latest 完整文档在 MyIP 文档中心:**[docs.ipcheck.ing](https://docs.ipcheck.ing)**(右上角可切换中文) -* [开发者指南](https://docs.ipcheck.ing/developer) —— 部署、配置、架构说明与参与贡献 -* [知识库](https://docs.ipcheck.ing/knowledge-base) —— 每个工具的使用说明、网络问题排查指南、网络概念科普 +* [开发者指南](https://docs.ipcheck.ing/developer/zh) —— 部署、配置、架构说明与参与贡献 +* [知识库](https://docs.ipcheck.ing/knowledge-base/zh) —— 每个工具的使用说明、网络问题排查指南、网络概念科普 ## ⚙️ 配置 开始之前,有两项配置最重要: -* **MaxMind GeoLite2(必须)** —— 免费凭证,为 IP 地理位置与 ASN 查询提供数据。不配置时 MaxMind 数据源会返回 503。→ [MaxMind 配置指南](https://docs.ipcheck.ing/developer/getting-started/maxmind-setup) -* **`ALLOWED_DOMAINS`(使用真实域名时必须)** —— 后端 API 的域名白名单。不配置时,来自非 localhost 域名的请求都会收到 403。→ [反向代理与域名](https://docs.ipcheck.ing/developer/getting-started/reverse-proxy-and-domains) +* **MaxMind GeoLite2(必须)** —— 免费凭证,为 IP 地理位置与 ASN 查询提供数据。不配置时 MaxMind 数据源会返回 503。→ [MaxMind 配置指南](https://docs.ipcheck.ing/developer/getting-started/zh/maxmind-setup) +* **`ALLOWED_DOMAINS`(使用真实域名时必须)** —— 后端 API 的域名白名单。不配置时,来自非 localhost 域名的请求都会收到 403。→ [反向代理与域名](https://docs.ipcheck.ing/developer/getting-started/zh/reverse-proxy-and-domains) ```bash docker run -d -p 18966:18966 \ @@ -116,7 +116,7 @@ docker run -d -p 18966:18966 \ jason5ng32/myip:latest ``` -其余全部为可选配置 —— 第三方 API Key、安全与限流、日志、Sentry、CURL API 域名等,详见[环境变量参考](https://docs.ipcheck.ing/developer/reference/environment-variables)。 +其余全部为可选配置 —— 第三方 API Key、安全与限流、日志、Sentry、CURL API 域名等,详见[环境变量参考](https://docs.ipcheck.ing/developer/reference/zh/environment-variables)。 ## 👩🏻‍💻 高级用法 diff --git a/api/ipapi-is.js b/api/ipapi-is.js index f1c49b20d..4defa0c48 100644 --- a/api/ipapi-is.js +++ b/api/ipapi-is.js @@ -12,9 +12,13 @@ function buildUrl(req) { return `https://api.ipapi.is?q=${ipAddress}&key=${key}`; } -function modifyJsonForIPAPI(json) { - let asn = json.asn || {}; - const { ip, location, is_datacenter, is_proxy, is_vpn, is_tor } = json; +// Both nested objects are optional: the upstream answers 200 with a null +// `location` (and no `asn`) for addresses it can't place — anycast ranges, +// bogons — so neither may be dereferenced directly. +export function modifyJsonForIPAPI(json) { + const asn = json.asn || {}; + const location = json.location || {}; + const { ip, is_datacenter, is_proxy, is_vpn, is_tor } = json; return { ip: ip, diff --git a/common/rdap.js b/common/rdap.js index 55b2c6fe3..d90da54b0 100644 --- a/common/rdap.js +++ b/common/rdap.js @@ -134,7 +134,10 @@ export const rdapIp = async (ip, { timeoutMs = 5000 } = {}) => { throw new Error(`No RDAP endpoint for ${ip}`); } - const url = `${trimSlash(base)}/ip/${encodeURIComponent(ip)}`; + // Literal IP, not encodeURIComponent: colons are legal in a URL path, + // the guard layer already ensures a well-formed IP, and some RIR + // delegates (e.g. IDNIC behind APNIC's redirect) reject %3A with a 400. + const url = `${trimSlash(base)}/ip/${ip}`; const res = await fetchUpstream(url, { timeoutMs }); if (res.status === 404) { throw new Error(`IP not found: ${ip}`); diff --git a/frontend/components/Additional.vue b/frontend/components/Additional.vue index c01e33c97..c5008b041 100644 --- a/frontend/components/Additional.vue +++ b/frontend/components/Additional.vue @@ -88,9 +88,6 @@ const openCurlModal = () => { trackEvent('Additional', 'AdditionalClick', 'Curl'); }; -defineExpose({ - openCurlModal, -});