Skip to content

Commit

Permalink
Merge pull request #246 from jason5ng32/dev
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
jason5ng32 authored Oct 8, 2024
2 parents 7a6a05c + a7436b8 commit a054f09
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 41 deletions.
Binary file modified common/maxmind-db/GeoLite2-ASN.mmdb
Binary file not shown.
Binary file modified common/maxmind-db/GeoLite2-City.mmdb
Binary file not shown.
45 changes: 34 additions & 11 deletions frontend/components/DnsLeaksTest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,25 @@
leak.ip }}
</p>

<div class="alert" :class="{
<div class="alert d-flex flex-column" :class="{
'alert-info': leak.country === t('dnsleaktest.StatusWait'),
'alert-success': leak.country !== t('dnsleaktest.StatusWait'),
}" :data-bs-theme="isDarkMode ? 'dark' : ''">
<i class="bi"
:class="[leak.ip === t('dnsleaktest.StatusWait') || leak.ip === t('dnsleaktest.StatusError') ? 'bi-hourglass-split' : 'bi-geo-alt-fill']"></i>
{{ t('dnsleaktest.EndpointCountry') }}: <strong>{{ leak.country }}&nbsp;</strong>
<span v-if="leak.country !== t('dnsleaktest.StatusWait') && leak.country !== t('dnsleaktest.StatusError')"
:class="'jn-fl fi fi-' + leak.country_code.toLowerCase()"></span>

<span class="jn-org">
<i class="bi"
:class="[leak.org === t('dnsleaktest.StatusWait') || leak.org === t('dnsleaktest.StatusError') ? 'bi-hourglass-split' : 'bi-geo-alt-fill']"></i>
{{ t('ipInfos.ISP') }}: <span :title="leak.org">{{ leak.org }}</span>
</span>

<span class="mt-2">
<i class="bi"
:class="[leak.ip === t('dnsleaktest.StatusWait') || leak.ip === t('dnsleaktest.StatusError') ? 'bi-hourglass-split' : 'bi-geo-alt-fill']"></i>
{{ t('ipInfos.Country') }}: <span
:class="[ leak.country !== t('dnsleaktest.StatusWait') ? 'fw-bold':'']">{{ leak.country
}}&nbsp;</span>
<span v-show="leak.country_code" :class="'jn-fl fi fi-' + leak.country_code.toLowerCase()"></span>
</span>
</div>
</div>
</div>
Expand Down Expand Up @@ -67,9 +77,10 @@ const lang = computed(() => store.lang);
const createDefaultCard = () => ({
name: t('dnsleaktest.Name'),
country_code: t('dnsleaktest.StatusWait'),
country_code: '',
country: t('dnsleaktest.StatusWait'),
ip: t('dnsleaktest.StatusWait'),
org: t('dnsleaktest.StatusWait'),
});
const leakTest = reactive([
Expand Down Expand Up @@ -116,6 +127,7 @@ const fetchLeakTestIpApiCom = (index) => {
const geoSplit = data.dns.geo.split(" - ");
leakTest[index].country_code = countryLookup.byCountry(geoSplit[0]).iso2;
leakTest[index].country = getCountryName(leakTest[index].country_code, lang.value);
leakTest[index].org = geoSplit[1] || '';
leakTest[index].ip = data.dns.ip;
resolve();
} else {
Expand All @@ -126,8 +138,9 @@ const fetchLeakTestIpApiCom = (index) => {
.catch((error) => {
console.error("Error fetching leak test data:", error);
leakTest[index].country = t('dnsleaktest.StatusError');
leakTest[index].country_code = t('dnsleaktest.StatusError');
leakTest[index].ip = t('dnsleaktest.StatusError');
leakTest[index].country_code = '';
leakTest[index].org = '';
reject(error);
});
});
Expand All @@ -153,6 +166,7 @@ const fetchLeakTestSfSharkCom = (index, key) => {
if (keyEntry && keyEntry.CountryCode && keyEntry.IP) {
leakTest[index].country_code = keyEntry.CountryCode;
leakTest[index].country = getCountryName(keyEntry.CountryCode, lang.value);
leakTest[index].org = keyEntry.ISP || '';
leakTest[index].ip = keyEntry.IP;
resolve();
} else {
Expand All @@ -162,8 +176,10 @@ const fetchLeakTestSfSharkCom = (index, key) => {
})
.catch((error) => {
console.error("Error fetching leak test data:", error);
leakTest[index].geo = t('dnsleaktest.StatusError');
leakTest[index].ip = t('dnsleaktest.StatusError');
leakTest[index].country = t('dnsleaktest.StatusError');
leakTest[index].country_code = '';
leakTest[index].org = '';
reject(error);
});
});
Expand All @@ -178,7 +194,8 @@ const checkAllDNSLeakTest = async (isRefresh) => {
server.geo = t('dnsleaktest.StatusWait');
server.ip = t('dnsleaktest.StatusWait');
server.country = t('dnsleaktest.StatusWait');
server.country_code = t('dnsleaktest.StatusWait');
server.country_code = '';
server.org = t('dnsleaktest.StatusWait');
});
}
Expand Down Expand Up @@ -220,4 +237,10 @@ defineExpose({
});
</script>

<style scoped></style>
<style scoped>
.jn-org {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
81 changes: 73 additions & 8 deletions frontend/components/WebRtcTest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,30 @@
}">
<i class="bi"
:class="[stun.ip === t('webrtc.StatusWait') ? 'bi-hourglass-split' : 'bi-pc-display-horizontal']">&nbsp;</i>
<span :class="{ 'jn-ip-font': stun.ip.length > 32 }"> {{ stun.ip }}</span>
<span :class="{ 'jn-ip-font': stun.ip.length > 32 }"> {{ stun.ip }}
</span>

</p>
<div v-if="stun.natType" class="alert" :class="{
<div v-if="stun.natType" class="alert d-flex flex-column" :class="{
'alert-info': stun.natType === t('webrtc.StatusWait'),
'alert-success': stun.natType !== t('webrtc.StatusWait'),
}" :data-bs-theme="isDarkMode ? 'dark' : ''">
<i class="bi"
:class="[stun.natType === t('webrtc.StatusWait') ? 'bi-hourglass-split' : ' bi-controller']"></i> {{
stun.natType }}
<span>
<i class="bi"
:class="[stun.natType === t('webrtc.StatusWait') ? 'bi-hourglass-split' : ' bi-controller']"></i> NAT:
{{
stun.natType }}
</span>

<span class="mt-2">
<i class="bi"
:class="[stun.country === t('webrtc.StatusWait') || stun.country === t('webrtc.StatusError') ? 'bi-hourglass-split' : 'bi-geo-alt-fill']"></i>
{{ t('ipInfos.Country') }}: <span :class="[ stun.country !== t('webrtc.StatusWait') ? 'fw-bold':'']">{{
stun.country }}&nbsp;</span>
<span v-show="stun.country_code" :class="'jn-fl fi fi-' + stun.country_code"></span>
</span>


</div>
</div>
</div>
Expand All @@ -48,12 +63,15 @@ import { ref, computed, onMounted, reactive, watch } from 'vue';
import { useMainStore } from '@/store';
import { useI18n } from 'vue-i18n';
import { trackEvent } from '@/utils/use-analytics';
import { transformDataFromIPapi } from '@/utils/transform-ip-data.js';
import getCountryName from '@/utils/country-name.js';
const { t } = useI18n();
const store = useMainStore();
const isDarkMode = computed(() => store.isDarkMode);
const isMobile = computed(() => store.isMobile);
const lang = computed(() => store.lang);
const isStarted = ref(false);
Expand All @@ -65,27 +83,35 @@ const stunServers = reactive([
url: "stun.l.google.com:19302",
ip: t('webrtc.StatusWait'),
natType: t('webrtc.StatusWait'),
country: t('webrtc.StatusWait'),
country_code: '',
},
{
id: "blackberry",
name: "BlackBerry",
url: "stun.voip.blackberry.com:3478",
ip: t('webrtc.StatusWait'),
natType: t('webrtc.StatusWait'),
country: t('webrtc.StatusWait'),
country_code: '',
},
{
id: "twilio",
name: "Twilio",
url: "global.stun.twilio.com",
ip: t('webrtc.StatusWait'),
natType: t('webrtc.StatusWait'),
country: t('webrtc.StatusWait'),
country_code: '',
},
{
id: "cloudflare",
name: "Cloudflare",
url: "stun.cloudflare.com",
ip: t('webrtc.StatusWait'),
natType: t('webrtc.StatusWait'),
country: t('webrtc.StatusWait'),
country_code: '',
},
]);
Expand All @@ -98,17 +124,28 @@ const checkSTUNServer = async (stun) => {
const pc = new RTCPeerConnection(servers);
let candidateReceived = false;
pc.onicecandidate = (event) => {
// 分别获取 STUN 服务器的 IP 地址和 NAT 类型
pc.onicecandidate = async (event) => {
if (event.candidate) {
candidateReceived = true;
const candidate = event.candidate.candidate;
const ipMatch = /([0-9a-f]{1,4}(:[0-9a-f]{1,4}){7}|[0-9a-f]{0,4}(:[0-9a-f]{1,4}){0,6}::[0-9a-f]{0,4}|::[0-9a-f]{1,4}(:[0-9a-f]{1,4}){0,6}|[0-9]{1,3}(\.[0-9]{1,3}){3})/i.exec(candidate);
if (ipMatch) {
stun.ip = ipMatch[0];
try {
let countryInfo = await fetchCountryCode(stun.ip);
stun.country_code = countryInfo[0];
stun.country = countryInfo[1];
} catch (error) {
console.error("Error fetching country code:", error);
reject(error);
pc.close();
return;
}
IPArray.value = [...IPArray.value, stun.ip];
stun.natType = determineNATType(candidate);
pc.close();
resolve(); // 成功时解析 Promise
resolve();
}
}
};
Expand All @@ -126,11 +163,12 @@ const checkSTUNServer = async (stun) => {
} catch (error) {
console.error("STUN Server Test Error:", error);
stun.ip = t('webrtc.StatusError');
reject(error); // 捕获异常时拒绝 Promise
reject(error);
}
});
};
// 分析ICE候选信息,推断NAT类型
const determineNATType = (candidate) => {
const parts = candidate.split(' ');
Expand All @@ -149,6 +187,31 @@ const determineNATType = (candidate) => {
}
};
// 通过 Maxmind 获取 IP 地区归属
const fetchCountryCode = async (ip) => {
let setLang = lang.value;
if (setLang === 'zh') {
setLang = 'zh-CN';
}
const source = store.ipDBs.find(source => source.text === "MaxMind");
try {
const url = store.getDbUrl(source.id, ip, setLang);
const response = await fetch(url);
const data = await response.json();
const ipData = transformDataFromIPapi(data, source.id, t, lang.value);
if (ipData) {
let country_code = ipData.country_code.toLowerCase();
let country = getCountryName(ipData.country_code, lang.value);
return [country_code, country];
}
} catch (error) {
console.error("Error fetching IP country code", error);
}
}
// 测试所有 STUN 服务器
const checkAllWebRTC = async (isRefresh) => {
if (isRefresh) {
Expand All @@ -158,6 +221,8 @@ const checkAllWebRTC = async (isRefresh) => {
const promises = stunServers.map((server) => {
server.ip = t('webrtc.StatusWait');
server.natType = t('webrtc.StatusWait');
server.country = t('webrtc.StatusWait');
server.country_code = '';
return checkSTUNServer(server);
});
Expand Down
10 changes: 5 additions & 5 deletions frontend/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@
"StatusWait": "Awaiting Test or Connection Error",
"StatusError": "Test Error",
"NATType": {
"srflx": "Possibly Port Restricted Cone or Symmetric NAT",
"prflx": "Possibly Port Restricted Cone NAT",
"relay": "Possibly Symmetric NAT",
"host": "Possibly Full Cone NAT",
"unknown": "Unknown NAT Type"
"srflx": "Port Restricted Cone or Symmetric",
"prflx": "Port Restricted Cone",
"relay": "Symmetric",
"host": "Full Cone",
"unknown": "Unknown Type"
}
},
"dnsleaktest": {
Expand Down
10 changes: 5 additions & 5 deletions frontend/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@
"StatusWait": "En attente du test ou erreur de connexion",
"StatusError": "Erreur de test",
"NATType": {
"srflx": "Possiblement Port Restricted Cone ou Symmetric NAT",
"prflx": "Possiblement Port Restricted Cone NAT",
"relay": "Possiblement Symmetric NAT",
"host": "Possiblement Full Cone NAT",
"unknown": "Type de NAT inconnu"
"srflx": "Port Restricted Cone ou Symmetric",
"prflx": "Port Restricted Cone",
"relay": "Symmetric",
"host": "Full Cone",
"unknown": "Type de inconnu"
}
},
"dnsleaktest": {
Expand Down
10 changes: 5 additions & 5 deletions frontend/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@
"StatusWait": "待检测或连接错误",
"StatusError": "测试出错",
"NATType": {
"srflx": "可能是端口限制型或对称型 NAT",
"prflx": "可能是端口限制型 NAT",
"relay": "可能是对称型 NAT",
"host": "可能是全锥型 NAT",
"unknown": "未知 NAT 类型"
"srflx": "端口限制型或对称型",
"prflx": "端口限制型",
"relay": "对称型",
"host": "全锥型",
"unknown": "未知类型"
}
},
"dnsleaktest": {
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@
"code-inspector-plugin": "^0.16.1",
"concurrently": "^9.0.1",
"country-code-lookup": "^0.1.3",
"detect-gpu": "^5.0.49",
"detect-gpu": "^5.0.51",
"dotenv": "^16.4.5",
"express": "^4.21.0",
"express-rate-limit": "^7.4.0",
"express-rate-limit": "^7.4.1",
"express-slow-down": "^2.0.3",
"flag-icons": "^7.2.3",
"http-proxy-middleware": "^3.0.2",
"maxmind": "^4.3.21",
"http-proxy-middleware": "^3.0.3",
"maxmind": "^4.3.22",
"nodemon": "^3.1.7",
"pinia": "^2.2.2",
"pinia": "^2.2.4",
"svgmap": "^2.11.1",
"ua-parser-js": "^1.0.39",
"vue": "^3.5.8",
"vue-i18n": "^10.0.3",
"vue": "^3.5.11",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5",
"whoiser": "^1.18.0"
},
Expand Down

0 comments on commit a054f09

Please sign in to comment.