Skip to content

Commit

Permalink
Merge pull request jason5ng32#133 from jason5ng32/dev
Browse files Browse the repository at this point in the history
Add Proxy Rules Test
  • Loading branch information
jason5ng32 authored Mar 3, 2024
2 parents cd34665 + 63e4f7f commit d662505
Show file tree
Hide file tree
Showing 15 changed files with 401 additions and 89 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Notes: You can use my demo for free, and you can also deploy it yourself.
* 🚥 **WebRTC Detection**: Identifies the IP address used during WebRTC connections.
* 🛑 **DNS Leak Test**: Shows DNS endpoint data to evaluate the risk of DNS leaks when using VPNs or proxies.
* 🚀 **Speed Test**:Test your network speed with edge networks.
* 🚏 **Proxy Rule Testing**: Test the rule settings of proxy software to ensure their correctness.
* 🌐 **Global Latency Test**: Performe lantency tests on servers located in different regions around the world.
* 📡 **MTR Test**: Perform MTR tests on servers located in different regions around the world.
* 🌗 **Dark Mode**: Automatically toggles between dark and daylight modes based on system settings, with an option for manual switching.
Expand Down
1 change: 1 addition & 0 deletions README_FR.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Notes: Vous pouvez utiliser ma démo gratuitement et vous pouvez également la d
* 🚥 **Détection WebRTC** : Identifie l'adresse IP utilisée lors des connexions WebRTC.
* 🛑 **Test de fuite DNS** : Affiche les données de point de terminaison DNS pour évaluer le risque de fuites DNS lors de l'utilisation de VPN ou de proxies.
* 🚀 **Test de vitesse** : Testez la vitesse de votre réseau avec des réseaux de pointe.
* 🚏 **Test de règles** : Teste si les paramètres de règles fonctionnent correctement avec le logiciel de proxy.
* 🌐 **Test de latence mondiale** : Effectue des tests de latence sur des serveurs situés dans différentes régions du monde.
* 📡 **Test MTR** : Effectue des tests MTR sur des serveurs situés dans différentes régions du monde.
* 🌗 **Mode sombre** : Bascule automatiquement entre les modes sombre et clair en fonction des paramètres du système, avec une option de basculement manuel.
Expand Down
1 change: 1 addition & 0 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* 🚥 **WebRTC 检测**:查看使用 WebRTC 连接时使用的 IP
* 🛑 **DNS 泄露检测**:查看 DNS 出口信息,以便查看在 VPN/代理的情况下,是否存在 DNS 泄露隐私的风险
* 🚀 **网速测试**:利用边缘网络进行网速测试
* 🚏 **代理规则测试**:配合代理软件的规则设置,测试规则设置是否正常
* 🌐 **全球延迟测试**:从分布在全球的多个服务器进行延迟测试,了解你与全球网络的连接速度
* 📡 **MTR 测试**:从分布在全球的多个服务器进行 MTR 测试,了解你与全球的连接路径
* 🌗 **暗黑模式**:根据系统设置自动切换暗黑/白天模式,也可以手动切换
Expand Down
29 changes: 25 additions & 4 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@
aria-live="assertive" aria-atomic="true">
<div class="toast-header" :class="{ 'dark-mode-title': isDarkMode }">
<strong class="me-auto" :class="alertStyle">{{ alertTitle }}</strong>
<button type="button" class="btn-close" :class="{ 'dark-mode-close-button': isDarkMode }" data-bs-dismiss="toast"
aria-label="Close"></button>
<button type="button" class="btn-close" :class="{ 'dark-mode-close-button': isDarkMode }"
data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
{{ alertMessage }}
</div>
</div>
</div>
<div id="mainpart" class="container mt-5 jn-container">
<div data-bs-spy="scroll" data-bs-target="#navbar-top" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true"
class="rounded-2" tabindex="0">
<div data-bs-spy="scroll" data-bs-target="#navbar-top" data-bs-root-margin="0px 0px -40%"
data-bs-smooth-scroll="true" class="rounded-2" tabindex="0">
<IPCheck ref="IPCheckRef" />
<Connectivity ref="connectivityRef" />
<WebRTC ref="webRTCRef" />
<DNSLeaks ref="dnsLeaksRef" />
<RuleTest ref="ruleTestRef" />
<SpeedTest ref="speedTestRef" />
<GlobalLatency ref="globalLatencyRef" />
<MTRtest ref="mtrtestRef" />
Expand Down Expand Up @@ -52,6 +53,7 @@ import Footer from './components/footer.vue'
import QueryIP from './components/queryip.vue'
import HelpModal from './components/help.vue'
import PWA from './components/pwa.vue'
import RuleTest from './components/ruletest.vue'
import { mappingKeys, navigateCards, keyMap } from "./shortcut.js";
import { ref, computed, watch } from 'vue';
Expand Down Expand Up @@ -92,6 +94,7 @@ export default {
QueryIP,
HelpModal,
PWA,
RuleTest,
},
name: 'App',
data() {
Expand All @@ -102,6 +105,7 @@ export default {
originipDataCards: [],
originstunServers: [],
originleakTest: [],
originRuleTests: [],
alertToShow: false,
alertStyle: "",
alertMessage: "",
Expand Down Expand Up @@ -205,6 +209,7 @@ export default {
this.originipDataCards = JSON.parse(JSON.stringify(this.$refs.IPCheckRef.ipDataCards));
this.originstunServers = JSON.parse(JSON.stringify(this.$refs.webRTCRef.stunServers));
this.originleakTest = JSON.parse(JSON.stringify(this.$refs.dnsLeaksRef.leakTest));
this.originRuleTests = JSON.parse(JSON.stringify(this.$refs.ruleTestRef.ruleTests));
this.infoMask();
this.alertStyle = "text-warning";
this.alertMessage = this.$t('alert.maskedInfoMessage_1');
Expand Down Expand Up @@ -240,6 +245,9 @@ export default {
this.$refs.dnsLeaksRef.leakTest.forEach((server) => {
server.ip = "12.34.56.78";
});
this.$refs.ruleTestRef.ruleTests.forEach((test) => {
test.ip = "8.8.8.8";
});
this.infoMaskLevel = 1;
} else if (this.infoMaskLevel === 1) {
this.$refs.IPCheckRef.ipDataCards.forEach((card) => {
Expand All @@ -258,6 +266,9 @@ export default {
this.$refs.dnsLeaksRef.leakTest.forEach((server) => {
server.geo = "United States";
});
this.$refs.ruleTestRef.ruleTests.forEach((test) => {
test.country_code = "US";
});
this.infoMaskLevel = 2;
}
},
Expand All @@ -267,6 +278,7 @@ export default {
this.$refs.IPCheckRef.ipDataCards = JSON.parse(JSON.stringify(this.originipDataCards));
this.$refs.webRTCRef.stunServers = JSON.parse(JSON.stringify(this.originstunServers));
this.$refs.dnsLeaksRef.leakTest = JSON.parse(JSON.stringify(this.originleakTest));
this.$refs.ruleTestRef.ruleTests = JSON.parse(JSON.stringify(this.originRuleTests));
this.infoMaskLevel = 0;
},
Expand Down Expand Up @@ -392,6 +404,15 @@ export default {
},
description: this.$t('shortcutKeys.RefreshWebRTC'),
},
{
keys: "r",
action: () => {
this.scrollToElement("RuleTest", 80);
this.$refs.ruleTestRef.checkAllRuleTest(true);
this.$trackEvent('ShortCut', 'ShortCut', 'WebRTC');
},
description: this.$t('shortcutKeys.RefreshRuleTests'),
},
{
keys: "d",
action: () => {
Expand Down
20 changes: 10 additions & 10 deletions src/components/dnsleaks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<div class="dnsleak-test-section mb-4">
<div class="jn-title2">
<h2 id="DNSLeakTest" :class="{ 'mobile-h2': isMobile }">🛑 {{ $t('dnsleaktest.Title') }}</h2>
<button @click="checkAllDNSLeakTest(true)" :class="['btn', isDarkMode ? 'btn-dark dark-mode-refresh' : 'btn-light']"
aria-label="Refresh DNS Leak Test" v-tooltip="$t('Tooltips.RefreshDNSLeakTest')"><i
class="bi bi-arrow-clockwise"></i></button>
<button @click="checkAllDNSLeakTest(true)"
:class="['btn', isDarkMode ? 'btn-dark dark-mode-refresh' : 'btn-light']" aria-label="Refresh DNS Leak Test"
v-tooltip="$t('Tooltips.RefreshDNSLeakTest')"><i class="bi bi-arrow-clockwise"></i></button>
</div>
<div class="text-secondary">
<p>{{ $t('dnsleaktest.Note') }}</p>
Expand All @@ -17,19 +17,19 @@
<div class="card-body">
<p class="jn-con-title card-title"><i class="bi bi-heart-pulse-fill"></i> {{ leak.name }}</p>
<p class="card-text" :class="{
'text-info': leak.ip === $t('dnsleaktest.StatusWait') || leak.ip === $t('dnsleaktest.StatusError'),
'text-success': leak.ip.includes('.') || leak.ip.includes(':'),
}">
'text-info': leak.ip === $t('dnsleaktest.StatusWait') || leak.ip === $t('dnsleaktest.StatusError'),
'text-success': leak.ip.includes('.') || leak.ip.includes(':'),
}">
<i class="bi"
:class="[leak.ip === $t('dnsleaktest.StatusWait') || leak.ip === $t('dnsleaktest.StatusError') ? 'bi-hourglass-split' : 'bi-box-arrow-right']"></i>
{{ $t('dnsleaktest.Endpoint') }}: {{
leak.ip }}
leak.ip }}
</p>

<div class="alert" :class="{
'alert-info': leak.geo === $t('dnsleaktest.StatusWait'),
'alert-success': leak.geo !== $t('dnsleaktest.StatusWait'),
}" :data-bs-theme="isDarkMode ? 'dark' : ''">
'alert-info': leak.geo === $t('dnsleaktest.StatusWait'),
'alert-success': leak.geo !== $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.geo }}</strong>
Expand Down
22 changes: 4 additions & 18 deletions src/components/globallatency.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,26 +106,12 @@ export default {
const store = useStore();
const isDarkMode = computed(() => store.state.isDarkMode);
const isMobile = computed(() => store.state.isMobile);
const ipDataCards = computed(() => store.state.Global_ipDataCards);
const allIPs = ref([]); // 创建响应式引用
const getAllIPs = (cards) => {
let Global_allIPs = []; // 初始化数组
cards.forEach(card => {
if (card.ip && !card.ip.includes(' ') && !card.ip.includes(':')) {
Global_allIPs.push(card.ip);
}
});
Global_allIPs = [...new Set(Global_allIPs)]; // 去重
allIPs.value = Global_allIPs; // 更新 allIPs 响应式引用
};
// 监听 ipDataCards 的变化
watch(ipDataCards, (newVal) => {
getAllIPs(newVal);
let allIPs = computed(() => {
const _allIPs = store.state.Global_ipDataCards;
return _allIPs.filter(ip => ip && !ip.includes(' ') && !ip.includes(':'));
});
return {
isDarkMode,
isMobile,
Expand Down
45 changes: 27 additions & 18 deletions src/components/ipcheck.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<input v-if="isMobile" class="form-check-input" type="checkbox" id="collapseSwitch" @change="toggleCollapse"
:checked="!isCardsCollapsed" @click="$trackEvent('IPCheck', 'ToggleClick', 'Collaspes');"
aria-label="Toggle Card Display">
<label v-if="isMobile" class="form-check-label" for="collapseSwitch">&nbsp;<i class="bi bi-list-columns-reverse"
aria-hidden="true"></i></label>
<label v-if="isMobile" class="form-check-label" for="collapseSwitch">&nbsp;<i
class="bi bi-list-columns-reverse" aria-hidden="true"></i></label>
</div>

<div>
Expand Down Expand Up @@ -62,25 +62,26 @@
<div v-for="(card, index) in ipDataCards" :key="card.id" :ref="card.id"
:class="{ 'jn-opacity': !card.asn, 'col-xl-4': true, 'col-lg-6': true, 'col-md-6': true, 'mb-4': true }">
<div class="card jn-card" :class="{
'dark-mode dark-mode-border': isDarkMode,
'jn-ip-card1': !isMobile && ipGeoSource === 0,
'jn-ip-card2': !isMobile && ipGeoSource !== 0,
}">
'dark-mode dark-mode-border': isDarkMode,
'jn-ip-card1': !isMobile && ipGeoSource === 0,
'jn-ip-card2': !isMobile && ipGeoSource !== 0,
}">
<div class="card-header jn-ip-title jn-link1"
:class="{ 'dark-mode-title': isDarkMode, 'bg-light': !isDarkMode }" style="font-weight: bold;">
<span>
<i class="bi" :class="'bi-' + (index + 1) + '-circle-fill'"></i>&nbsp;
{{ $t('ipInfos.Source') }}: {{ card.source }}</span>
<button @click="refreshCard(card)" :class="['btn', isDarkMode ? 'btn-dark dark-mode-refresh' : 'btn-light']"
<button @click="refreshCard(card)"
:class="['btn', isDarkMode ? 'btn-dark dark-mode-refresh' : 'btn-light']"
:aria-label="'Refresh' + card.source" v-tooltip="$t('Tooltips.RefreshIPCard')">
<i class="bi bi-arrow-clockwise"></i></button>
</div>
<div class="p-3 placeholder-glow " :class="{
'dark-mode-title': isDarkMode,
'jn-link2-dark': isDarkMode,
'bg-light': !isDarkMode,
'jn-link2': !isDarkMode
}">
'dark-mode-title': isDarkMode,
'jn-link2-dark': isDarkMode,
'bg-light': !isDarkMode,
'jn-link2': !isDarkMode
}">
<span class="jn-text col-auto">
<i class="bi bi-pc-display-horizontal"></i>&nbsp;
</span>
Expand All @@ -97,7 +98,7 @@


<div v-if="(card.asn) || (card.ip === $t('ipInfos.IPv4Error')) || (card.ip === $t('ipInfos.IPv6Error'))
" class="card-body" :id="'IPInfo-' + (index + 1)">
" class="card-body" :id="'IPInfo-' + (index + 1)">
<ul class="list-group list-group-flush" v-if="card.country_name">

<img v-if="isMapShown" :src="isDarkMode ? card.mapUrl_dark : card.mapUrl"
Expand Down Expand Up @@ -200,7 +201,7 @@
<div class="p-3">
<span v-if="asnInfos[card.asn]">
<i class="bi bi-info-circle-fill"></i> <span class="fw-light">{{ $t('ipInfos.ASNInfo.note')
}}</span>
}}</span>
<br />
<template v-for="item in asnInfoItems">
<span class="fw-light">
Expand Down Expand Up @@ -409,6 +410,7 @@ export default {
ipDataCache: new Map(),
copiedStatus: {},
bingMapLanguage: this.$Lang,
IPArray: [],
};
},
Expand Down Expand Up @@ -468,6 +470,7 @@ export default {
let ip = data.ip;
this.ipDataCards[0].source = "TaoBao";
this.fetchIPDetails(0, ip);
this.IPArray = [...this.IPArray, ip];
document.head.removeChild(script);
delete window.ipCallback;
Expand All @@ -483,6 +486,7 @@ export default {
const response = await fetch("https://myip.ipip.net/json");
const data = await response.json();
const ip = data.data.ip;
this.IPArray = [...this.IPArray, ip];
this.ipDataCards[0].source = "IPIP.net";
this.fetchIPDetails(0, ip);
} catch (error) {
Expand Down Expand Up @@ -520,6 +524,7 @@ export default {
const data = await response.json();
const ip = data.remote_addr;
this.IPArray = [...this.IPArray, ip];
this.ipDataCards[1].source = "Upai";
this.fetchIPDetails(1, ip);
} catch (error) {
Expand All @@ -540,6 +545,7 @@ export default {
const data = await response.json();
const fullIp = data.ip;
const ip = fullIp.includes(',') ? fullIp.split(',')[0] : fullIp;
this.IPArray = [...this.IPArray, ip];
this.ipDataCards[1].source = "IPCheck.ing";
this.fetchIPDetails(1, ip);
} catch (error) {
Expand All @@ -557,6 +563,7 @@ export default {
const ipLine = lines.find((line) => line.startsWith("ip="));
if (ipLine) {
const ip = ipLine.split("=")[1];
this.IPArray = [...this.IPArray, ip];
this.fetchIPDetails(2, ip);
}
} catch (error) {
Expand All @@ -575,6 +582,7 @@ export default {
const ipLine = lines.find((line) => line.startsWith("ip="));
if (ipLine) {
const ip = ipLine.split("=")[1];
this.IPArray = [...this.IPArray, ip];
this.fetchIPDetails(3, ip);
}
} catch (error) {
Expand All @@ -592,6 +600,7 @@ export default {
}
const data = await response.json();
this.IPArray = [...this.IPArray, data.ip];
this.fetchIPDetails(4, data.ip);
} catch (error) {
console.error("Error fetching IPv4 address from ipify:", error);
Expand All @@ -608,6 +617,7 @@ export default {
}
const data = await response.json();
this.IPArray = [...this.IPArray, data.ip];
this.fetchIPDetails(5, data.ip);
} catch (error) {
console.error("Error fetching IPv6 address from ipify:", error);
Expand All @@ -634,7 +644,6 @@ export default {
// 检查是否有正在进行的查询,如果有,则等待该查询完成
if (this.pendingIPDetailsRequests.has(ip)) {
console.log("Waiting for pending IP details request to complete for IP: " + ip +" from source: " + this.sources[sourceID].text );
await this.pendingIPDetailsRequests.get(ip);
const cachedData = this.ipDataCache.get(ip);
if (cachedData) {
Expand Down Expand Up @@ -925,9 +934,9 @@ export default {
isCardsCollapsed(newVal) {
localStorage.setItem('isCardsCollapsed', JSON.stringify(newVal));
},
ipDataCards: {
handler(newValue) {
this.$store.commit('updateGlobalIpDataCards', newValue);
IPArray: {
handler() {
this.$store.commit('updateGlobalIpDataCards', this.IPArray);
},
deep: true,
},
Expand Down
21 changes: 3 additions & 18 deletions src/components/mtrtest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,9 @@ export default {
const store = useStore();
const isDarkMode = computed(() => store.state.isDarkMode);
const isMobile = computed(() => store.state.isMobile);
const ipDataCards = computed(() => store.state.Global_ipDataCards);
const allIPs = ref([]); // 创建响应式引用
const getAllIPs = (cards) => {
let Global_allIPs = []; // 初始化数组
cards.forEach(card => {
if (card.ip && !card.ip.includes(' ') && !card.ip.includes(':')) {
Global_allIPs.push(card.ip);
}
});
Global_allIPs = [...new Set(Global_allIPs)]; // 去重
allIPs.value = Global_allIPs; // 更新 allIPs 响应式引用
};
// 监听 ipDataCards 的变化
watch(ipDataCards, (newVal) => {
getAllIPs(newVal);
let allIPs = computed(() => {
const _allIPs = store.state.Global_ipDataCards;
return _allIPs.filter(ip => ip && !ip.includes(' ') && !ip.includes(':'));
});
return {
Expand Down
3 changes: 3 additions & 0 deletions src/components/nav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
<a class="nav-link" :class="{ 'text-white jn-deactive': isDarkMode }" href="#DNSLeakTest"
@click="$trackEvent('Nav', 'NavClick', 'DNSLeakTest')"> {{
$t('nav.DNSLeakTest') }}</a>
<a class="nav-link" :class="{ 'text-white jn-deactive': isDarkMode }" href="#RuleTest"
@click="$trackEvent('Nav', 'NavClick', 'RuleTest')"> {{
$t('nav.RuleTest') }}</a>
<a class="nav-link" :class="{ 'text-white jn-deactive': isDarkMode }" href="#SpeedTest"
@click="$trackEvent('Nav', 'NavClick', 'SpeedTest')"> {{ $t('nav.SpeedTest')
}}</a>
Expand Down
Loading

0 comments on commit d662505

Please sign in to comment.