Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #230

Merged
merged 6 commits into from
Jul 29, 2024
Merged

Dev #230

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
13 changes: 9 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Server
BACKEND_PORT="11966"
FRONTEND_PORT="18966"
BING_MAP_API_KEY=""
ALLOWED_DOMAINS=""
# APIs
BING_MAP_API_KEY=""
IPINFO_API_TOKEN=""
KEYCDN_USER_AGENT=""
IPCHECKING_API_KEY=""
CLOUDFLARE_API=""
IPAPIIS_API_KEY=""
IPCHECKING_API_KEY=""
MAC_LOOKUP_API_KEY=""
# Security related
SECURITY_BLACKLIST_LOG_FILE_PATH=""
SECURITY_RATE_LIMIT=""
SECURITY_DELAY_AFTER=""
IPAPIIS_API_KEY=""
MAC_LOOKUP_API_KEY=""
# Google Analytics
VITE_GOOGLE_ANALYTICS_ID=""
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ You can use the program without adding any environment variables, but if you wan
| `KEYCDN_USER_AGENT` | No | `""` | The domain name when using KeyCDN, must contain https prefix. Used to obtain IP address information through KeyCDN |
| `CLOUDFLARE_API` | No | `""` | API Key for Cloudflare, used to obtain AS system information through Cloudflare |
| `MAC_LOOKUP_API_KEY` | No | `""` | API Key for MAC Lookup, used to obtain MAC address information |
| `VITE_GOOGLE_ANALYTICS_ID` | **Yes** | `""` | Google Analytics ID, used to track user behavior |

### Using Environment Variables in a Node Environment

Expand Down
1 change: 1 addition & 0 deletions README_FR.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ Vous pouvez utiliser le programme sans ajouter de variables d'environnement, mai
| `KEYCDN_USER_AGENT` | Non | `""` | Le nom de domaine lorsque vous utilisez KeyCDN, doit contenir le préfixe https. Utilisé pour obtenir des informations sur l'adresse IP via KeyCDN |
| `CLOUDFLARE_API` | Non | `""` | Clé API pour Cloudflare, utilisée pour obtenir des informations sur le système AS via Cloudflare |
| `MAC_LOOKUP_API_KEY` | Non | `""` | Clé API pour MAC Lookup, utilisée pour obtenir des informations sur l'adresse MAC via MAC Lookup |
| `VITE_GOOGLE_ANALYTICS_ID` | **Oui** | `""` | Identifiant Google Analytics, utilisé pour l'analyse des utilisateurs |

### Utilisation des variables d'environnement dans un environnement Node

Expand Down
1 change: 1 addition & 0 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latest
| `KEYCDN_USER_AGENT` | 否 | `""` | 使用 KeyCDN 时的域名,需包含 https 前缀。用于通过 KeyCDN 获取 IP 归属地信息 |
| `CLOUDFLARE_API` | 否 | `""` | Cloudflare 的 API Key,用于通过 Cloudflare 获取 AS 系统的信息 |
| `MAC_LOOKUP_API_KEY` | 否 | `""` | MAC 查询的 API Key,用于通过 MAC Lookup 获取 MAC 地址的归属信息 |
| `VITE_GOOGLE_ANALYTICS_ID` | **是** | `""` | Google Analytics 的 ID,用于统计访问量 |

### 在 Node 环境里使用环境变量

Expand Down
2 changes: 1 addition & 1 deletion api/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default (req, res) => {
}

const hostname = referer ? new URL(referer).hostname : '';
const originalSite = hostname === 'ipcheck.ing' || hostname === 'www.ipcheck.ing';
const originalSite = hostname === 'ipcheck.ing' || hostname === 'www.ipcheck.ing' || hostname === 'localtest.ipcheck.ing';

const envConfigs = {
bingMap: process.env.BING_MAP_API_KEY,
Expand Down
18 changes: 9 additions & 9 deletions api/macchecker.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ const modifyData = (data) => {
data.isLocal = isLocal ? true : false;
data.isGlobal = !isLocal ? true : false;
data.isUnicast = !isMulticast ? true : false;
data.macPrefix = data.macPrefix? data.macPrefix : 'N/A';
data.company = data.company? data.company : 'N/A';
data.country = data.country? data.country : 'N/A';
data.address = data.address? data.address : 'N/A';
data.updated = data.updated? data.updated : 'N/A';
data.blockStart = data.blockStart? data.blockStart : 'N/A';
data.blockEnd = data.blockEnd? data.blockEnd : 'N/A';
data.blockSize = data.blockSize? data.blockSize : 'N/A';
data.blockType = data.blockType? data.blockType : 'N/A';
data.macPrefix = data.macPrefix ? data.macPrefix.match(/.{1,2}/g).join(':') : 'N/A';
data.company = data.company ? data.company : 'N/A';
data.country = data.country ? data.country : 'N/A';
data.address = data.address ? data.address : 'N/A';
data.updated = data.updated ? data.updated : 'N/A';
data.blockStart = data.blockStart ? data.blockStart.match(/.{1,2}/g).join(':') : 'N/A';
data.blockEnd = data.blockEnd ? data.blockEnd.match(/.{1,2}/g).join(':') : 'N/A';
data.blockSize = data.blockSize ? data.blockSize : 'N/A';
data.blockType = data.blockType ? data.blockType : 'N/A';

return data;
}
61 changes: 61 additions & 0 deletions api/maxmind.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import maxmind from 'maxmind';
import { isValidIP } from '../common/valid-ip.js';
import { refererCheck } from '../common/referer-check.js';

let cityLookup, asnLookup;

// 异步初始化数据库
async function initDatabases() {
cityLookup = await maxmind.open('./common/maxmind-db/GeoLite2-City.mmdb');
asnLookup = await maxmind.open('./common/maxmind-db/GeoLite2-ASN.mmdb');
}

initDatabases();

export default (req, res) => {

// 限制只能从指定域名访问
const referer = req.headers.referer;
if (!refererCheck(referer)) {
return res.status(403).json({ error: referer ? 'Access denied' : 'What are you doing?' });
}

const ip = req.query.ip;
if (!ip) {
return res.status(400).json({ error: 'No IP address provided' });
}

// 检查 IP 地址是否合法
if (!isValidIP(ip)) {
return res.status(400).json({ error: 'Invalid IP address' });
}

// 获取请求语言
const lang = req.query.lang === 'zh-CN' || req.query.lang === 'en' || req.query.lang === 'fr' ? req.query.lang : 'en';

try {
const city = cityLookup.get(ip);
const asn = asnLookup.get(ip);
let result = modifyJson(ip, lang, city, asn);
res.json(result);
} catch (e) {
res.status(500).json({ error: e.message });
}
}

function modifyJson(ip, lang, city, asn) {
city = city || {};
asn = asn || {};
return {
ip,
city: city.city ? city.city.names[lang] || city.city.names.en : "N/A",
region: city.subdivisions ? city.subdivisions[0].names[lang] || city.subdivisions[0].names.en : "N/A",
country: city.country ? city.country.iso_code : "N/A",
country_name: city.country ? city.country.names[lang] : "N/A",
country_code: city.country ? city.country.iso_code : "N/A",
latitude: city.location ? city.location.latitude : "N/A",
longitude: city.location ? city.location.longitude : "N/A",
asn: asn.autonomous_system_number ? "AS" + asn.autonomous_system_number : "N/A",
org: asn.autonomous_system_organization ? asn.autonomous_system_organization : "N/A"
};
};
2 changes: 2 additions & 0 deletions backend-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import whois from './api/whois.js';
import ipapiisHandler from './api/ipapiis.js';
import invisibilitytestHandler from './api/invisibilitytest.js';
import macChecker from './api/macchecker.js';
import maxmindHandler from './api/maxmind.js';

dotenv.config();

Expand Down Expand Up @@ -137,6 +138,7 @@ app.get('/api/whois', whois);
app.get('/api/ipapiis', ipapiisHandler);
app.get('/api/invisibility', invisibilitytestHandler);
app.get('/api/macchecker', macChecker);
app.get('/api/maxmind', maxmindHandler);

// 使用查询参数处理所有配置请求
app.get('/api/configs', validateConfigs);
Expand Down
Binary file added common/maxmind-db/GeoLite2-ASN.mmdb
Binary file not shown.
Binary file added common/maxmind-db/GeoLite2-City.mmdb
Binary file not shown.
10 changes: 7 additions & 3 deletions frontend/components/SpeedTest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@
v-if="speedTestStatus === 'finished' && hasScores">
<p id="score" class="speedtest-p"><i class="bi bi-calendar2-check"></i> {{ t('speedtest.score') }}
{{ t('speedtest.videoStreaming') }}
<span :class="speedTest.streamingScore >= 50 ? 'text-success' : 'text-warning'">
<span :class="speedTest.streamingScore >= 50 ? 'text-success' : 'jn-text-warning'">
{{ speedTest.streamingScore }}
</span>
{{ t('speedtest.gaming') }}
<span :class="speedTest.gamingScore >= 50 ? 'text-success' : 'text-warning'">
<span :class="speedTest.gamingScore >= 50 ? 'text-success' : 'jn-text-warning'">
{{ speedTest.gamingScore }}
</span>
{{ t('speedtest.rtc') }}
<span :class="speedTest.rtcScore >= 50 ? 'text-success' : 'text-warning'">
<span :class="speedTest.rtcScore >= 50 ? 'text-success' : 'jn-text-warning'">
{{ speedTest.rtcScore }}
</span>
{{ t('speedtest.resultNote') }}
Expand Down Expand Up @@ -365,4 +365,8 @@ defineExpose({
background-color: var(--bs-btn-hover-bg);
border-color: var(--bs-btn-hover-border-color);
}
.jn-text-warning {
--bs-text-opacity: 1;
color: #c67c14;
}
</style>
9 changes: 5 additions & 4 deletions frontend/components/advanced-tools/MacChecker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

<div id="macCheckResult" class="row" v-if="macCheckResult.success">
<div class="col-lg-8 col-md-8 col-12 mb-4">
<div class="card jn-card" :class="{ 'dark-mode dark-mode-border': isDarkMode }">
<div class="card h-100" :class="{ 'dark-mode dark-mode-border': isDarkMode }">
<div class="card-body row">
<h3 class="mb-4">{{ t('macchecker.manufacturer') }}</h3>
<div class="col-lg-6 col-md-6 col-12">
Expand Down Expand Up @@ -84,7 +84,7 @@
</div>

<div class="col-lg-4 col-md-4 col-12 mb-4">
<div class="card jn-card" :class="{ 'dark-mode dark-mode-border': isDarkMode}">
<div class="card h-100" :class="{ 'dark-mode dark-mode-border': isDarkMode}">
<div class="card-body">
<h3 class="mb-4">{{ t('macchecker.property') }}</h3>
<div class="table-responsive text-nowrap">
Expand Down Expand Up @@ -162,8 +162,9 @@ const tableItems = computed(() => {
// 检查 MAC 是否有效
const validateInput = (input) => {
if (!input) return null;
// 清理所有的分隔符
const normalizedInput = input.replace(/[:-]/g, '');
// 清理所有的分隔符和空格
const normalizedInput = input.replace(/[:-]/g, '')
.replace(/\s+/g, '');
// 检查长度和格式
if (normalizedInput.length < 6 || normalizedInput.length > 12 || !/^[0-9A-Fa-f]+$/.test(normalizedInput)) {
errorMsg.value = t('macchecker.invalidMAC');
Expand Down
1 change: 1 addition & 0 deletions frontend/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const useMainStore = defineStore('main', {
{ id: 4, text: 'KeyCDN', url: '/api/keycdn?ip={{ip}}', enabled: true },
{ id: 5, text: 'IP.SB', url: '/api/ipsb?ip={{ip}}', enabled: true },
{ id: 6, text: 'IPAPI.is', url: '/api/ipapiis?ip={{ip}}', enabled: true },
{ id: 7, text: 'MaxMind', url: '/api/maxmind?ip={{ip}}&lang={{lang}}', enabled: true },
],
}),

Expand Down
4 changes: 3 additions & 1 deletion frontend/utils/use-analytics.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Analytics from 'analytics';
import googleAnalytics from '@analytics/google-analytics';

const analyticsID = import.meta.env.VITE_GOOGLE_ANALYTICS_ID || '';

// Google Analytics 配置
const analytics = Analytics({
app: 'MyIP',
plugins: [
googleAnalytics({
measurementIds: ['G-TEYKKD81TL'],
measurementIds: [analyticsID],
})
]
});
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@
"express-slow-down": "^2.0.3",
"flag-icons": "^7.2.3",
"http-proxy-middleware": "^3.0.0",
"maxmind": "^4.3.20",
"nodemon": "^3.1.4",
"pinia": "^2.1.7",
"svgmap": "^2.10.1",
"vue": "^3.4.29",
"vue": "^3.4.31",
"vue-i18n": "^9.13.1",
"vue-router": "^4.4.0",
"whoiser": "^1.17.3"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.5",
"vite": "^5.3.1",
"vite": "^5.3.3",
"vite-plugin-pwa": "^0.20.0"
}
}