447 lines
19 KiB
PHP
447 lines
19 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>IP Pheasant</title>
|
|
<link rel="icon" href="logo.png" type="image/x-icon">
|
|
<link rel="stylesheet" type="text/css" href="styles.css">
|
|
<link rel="stylesheet" href="https://use.typekit.net/rvs8lhv.css">
|
|
|
|
<script>
|
|
|
|
const apiKey = "<?php echo getenv('apiKey'); ?>";
|
|
const accessToken = "<?php echo getenv('accessToken'); ?>";
|
|
const gistId = "<?php echo getenv('gistId'); ?>" ;
|
|
const gistId2 = "<?php echo getenv('gistId2'); ?>" ;
|
|
let ipv4Result, ipv6Result;
|
|
|
|
function checkUrl(url) {
|
|
return fetch(url, { method: 'HEAD' })
|
|
.then(response => {
|
|
if (response.ok) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
})
|
|
.catch(() => false);
|
|
}
|
|
|
|
function getCurrentDateTime() {
|
|
// Create a new Date object
|
|
const currentDate = new Date();
|
|
|
|
// Extract date components
|
|
const year = currentDate.getFullYear();
|
|
const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // Months are zero-based
|
|
const day = String(currentDate.getDate()).padStart(2, '0');
|
|
|
|
// Extract time components
|
|
const hours = String(currentDate.getHours()).padStart(2, '0');
|
|
const minutes = String(currentDate.getMinutes()).padStart(2, '0');
|
|
const seconds = String(currentDate.getSeconds()).padStart(2, '0');
|
|
|
|
// Construct the date and time string
|
|
const dateTimeString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
|
// Return the date and time string
|
|
return dateTimeString;
|
|
}
|
|
|
|
function updateGist(address) {
|
|
// Fetch the current content of the Gist file
|
|
fetch(`https://api.github.com/gists/${gistId2}`, {
|
|
headers: {
|
|
'Authorization': `token ${accessToken}`,
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
const filename = Object.keys(data.files)[0];
|
|
let content = data.files[filename].content;
|
|
|
|
// Remove existing header if present
|
|
if (content && content.startsWith('Address,Time\n')) {
|
|
content = content.slice(content.indexOf('\n') + 1);
|
|
}
|
|
|
|
// Construct the updated content with the new IP address entry at the top
|
|
const updatedContent = `Address,Time\n${address}\n${content || ''}`;
|
|
|
|
// Update the Gist file with the updated content
|
|
fetch(`https://api.github.com/gists/${gistId2}`, {
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Authorization': `token ${accessToken}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
files: {
|
|
[filename]: {
|
|
content: updatedContent
|
|
}
|
|
}
|
|
})
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to update Gist');
|
|
}
|
|
console.log('Gist updated successfully');
|
|
})
|
|
.catch(error => {
|
|
console.error('Error updating Gist:', error);
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching Gist:', error);
|
|
});
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////
|
|
|
|
let visitCount = 0;
|
|
|
|
// Fetch Gist data
|
|
fetch(`https://api.github.com/gists/${gistId}`, {
|
|
headers: {
|
|
'Authorization': `token ${accessToken}`,
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
// Extract content of the first file in the Gist
|
|
const filename = Object.keys(data.files)[0];
|
|
const content = data.files[filename].content;
|
|
visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
|
|
|
// Increment visit count
|
|
visitCount++;
|
|
|
|
// Update Gist content
|
|
const updatedContent = visitCount.toString();
|
|
const updatedFiles = { ...data.files, [filename]: { ...data.files[filename], content: updatedContent } };
|
|
|
|
return fetch(`https://api.github.com/gists/${gistId}`, {
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Authorization': `token ${accessToken}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
files: updatedFiles
|
|
})
|
|
});
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to update Gist');
|
|
}
|
|
console.log('Gist updated successfully');
|
|
})
|
|
.catch(error => {
|
|
console.error('Error updating Gist:', error);
|
|
});
|
|
|
|
|
|
|
|
|
|
///////////////////////////
|
|
|
|
if (navigator.onLine) {
|
|
let ipv4Fetch = fetch('https://ipv4.lafibre.info/ip.php')
|
|
.then(res => res.text())
|
|
.then(res => {
|
|
ipv4Result = res;
|
|
console.log('IPv4 Result:', ipv4Result);
|
|
document.getElementById('ipv4-address').textContent = ipv4Result;
|
|
getv4info();
|
|
return true; // Resolve promise if IPv4 fetch is successful
|
|
})
|
|
.catch(error => {
|
|
console.error('IPv4 Fetch Error:', error);
|
|
return false; // Reject promise if IPv4 fetch fails
|
|
});
|
|
|
|
let ipv6Check = checkUrl('https://ipv6.lafibre.info/ip.php')
|
|
.then(isIPv6Online => {
|
|
if (isIPv6Online) {
|
|
return fetch('https://ipv6.lafibre.info/ip.php')
|
|
.then(response => response.text())
|
|
.then(res => {
|
|
ipv6Result = res;
|
|
console.log('IPv6 Result:', ipv6Result);
|
|
document.getElementById('ipv6-address').textContent = ipv6Result;
|
|
getv6info();
|
|
return true; // Resolve promise if IPv6 fetch is successful
|
|
})
|
|
.catch(error => {
|
|
console.error('IPv6 Fetch Error:', error);
|
|
return false; // Reject promise if IPv6 fetch fails
|
|
});
|
|
} else {
|
|
console.log('IPv6 URL is offline.');
|
|
return false; // Reject promise if IPv6 URL is offline
|
|
}
|
|
});
|
|
|
|
// Check if both IPv4 and IPv6 fetches/checks are successful
|
|
Promise.all([ipv4Fetch, ipv6Check])
|
|
.then(results => {
|
|
if (results[0] && results[1]) {
|
|
// Both IPv4 and IPv6 sites are working
|
|
console.log('Both IPv4 and IPv6 sites are working.');
|
|
updateGist(`${ipv4Result} | ${ipv6Result},${getCurrentDateTime()}`)
|
|
// You can perform further actions here
|
|
} else if (results[0]) {
|
|
// Only IPv4 site is working
|
|
console.log('Only IPv4 site is working.');
|
|
updateGist(`${ipv4Result},${getCurrentDateTime()}`)
|
|
// Perform action for scenario where only IPv4 is available (Echo 1)
|
|
console.log(1);
|
|
} else if (results[1]) {
|
|
// Only IPv6 site is working
|
|
console.log('Only IPv6 site is working.');
|
|
updateGist(`${ipv6Result},${getCurrentDateTime()}`)
|
|
// Perform action for scenario where only IPv6 is available (Echo 2)
|
|
console.log(2);
|
|
} else {
|
|
// Both IPv4 and IPv6 sites are not working
|
|
console.log('Both IPv4 and IPv6 sites are not working.');
|
|
updateGist(`Failed Client,${getCurrentDateTime()}`)
|
|
// Handle accordingly
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
});
|
|
};
|
|
|
|
|
|
|
|
function getv4info(){
|
|
var request = new XMLHttpRequest();
|
|
url = 'https://api.ipdata.co/'+ ipv4Result +'?api-key=' + apiKey
|
|
console.log("URL:", url)
|
|
request.open('GET', url);
|
|
|
|
request.setRequestHeader('Accept', 'application/json');
|
|
|
|
request.onreadystatechange = function () {
|
|
if (this.readyState === 4) {
|
|
|
|
ipv4Json=JSON.parse(this.responseText)
|
|
console.log(ipv4Json);
|
|
|
|
var dataList = document.getElementById('asn-list-v4')
|
|
if (ipv4Json.asn) {
|
|
// Create an array of keys you want to display
|
|
var keysToDisplay = ["asn", "name", "route"];
|
|
|
|
function capitalizeFirstLetter(string) {
|
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
}
|
|
|
|
// Loop through the keys and create <li> elements with the data
|
|
keysToDisplay.forEach(function(key) {
|
|
var listItem = document.createElement('li');
|
|
listItem.className = 'list-item';
|
|
|
|
var keyElement = document.createElement('p');
|
|
keyElement.className = 'key';
|
|
keyElement.textContent = capitalizeFirstLetter(key);
|
|
|
|
if (key === 'asn'){
|
|
keyElement.textContent = key.toUpperCase()
|
|
}
|
|
|
|
var valueElement = document.createElement('code');
|
|
valueElement.textContent = ipv4Json.asn[key];
|
|
|
|
listItem.appendChild(keyElement);
|
|
listItem.appendChild(valueElement);
|
|
|
|
dataList.appendChild(listItem);
|
|
});
|
|
} else {
|
|
// Create a list item indicating 'None'
|
|
var listItem = document.createElement('li');
|
|
listItem.textContent = 'None';
|
|
dataList.appendChild(listItem);
|
|
}
|
|
|
|
var city = (ipv4Json.city + ", ");
|
|
var region = (ipv4Json.region_code + " ");
|
|
var postal = (ipv4Json.postal + " ")
|
|
var countryName = (ipv4Json.country_name);
|
|
var countryFlagURL = (ipv4Json.flag)
|
|
|
|
var fullLocation = (city + region + postal + countryName)
|
|
const locationv4 = document.getElementById('locationv4');
|
|
locationv4.textContent = fullLocation
|
|
|
|
const countryFlag = document.getElementById('countryFlagv4');
|
|
countryFlag.src = countryFlagURL;
|
|
|
|
|
|
}
|
|
};
|
|
request.send();
|
|
|
|
}
|
|
|
|
function getv6PTR(){
|
|
|
|
console.log("not yet setup for PTR")
|
|
}
|
|
|
|
function getv6info(){
|
|
var request = new XMLHttpRequest();
|
|
url = 'https://api.ipdata.co/'+ ipv6Result +'?api-key=' + apiKey
|
|
console.log("URL:", url)
|
|
request.open('GET', url);
|
|
|
|
request.setRequestHeader('Accept', 'application/json');
|
|
|
|
request.onreadystatechange = function () {
|
|
if (this.readyState === 4) {
|
|
|
|
ipv6Json=JSON.parse(this.responseText)
|
|
console.log(ipv6Json);
|
|
|
|
var dataList = document.getElementById('asn-list-v6')
|
|
if (ipv6Json.asn) {
|
|
// Create an array of keys you want to display
|
|
var keysToDisplay = ["asn", "name", "route"];
|
|
|
|
function capitalizeFirstLetter(string) {
|
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
}
|
|
|
|
// Loop through the keys and create <li> elements with the data
|
|
keysToDisplay.forEach(function(key) {
|
|
var listItem = document.createElement('li');
|
|
listItem.className = 'list-item';
|
|
|
|
var keyElement = document.createElement('p');
|
|
keyElement.className = 'key';
|
|
keyElement.textContent = capitalizeFirstLetter(key);
|
|
|
|
if (key === 'asn'){
|
|
keyElement.textContent = key.toUpperCase()
|
|
}
|
|
|
|
var valueElement = document.createElement('code');
|
|
valueElement.textContent = ipv6Json.asn[key];
|
|
|
|
listItem.appendChild(keyElement);
|
|
listItem.appendChild(valueElement);
|
|
|
|
dataList.appendChild(listItem);
|
|
});
|
|
} else {
|
|
// Create a list item indicating 'None'
|
|
var listItem = document.createElement('li');
|
|
listItem.textContent = 'None';
|
|
dataList.appendChild(listItem);
|
|
}
|
|
|
|
if (ipv6Json.city === null){
|
|
var city = ""
|
|
}else{
|
|
var city = (ipv6Json.city + ", ");
|
|
}
|
|
|
|
if (ipv6Json.region_code === null){
|
|
var region = ""
|
|
}else{
|
|
var region = (ipv6Json.region_code + " ");
|
|
}
|
|
|
|
if (ipv6Json.postal === null){
|
|
var postal = ""
|
|
}else{
|
|
var postal = (ipv6Json.postal + " ")
|
|
}
|
|
|
|
|
|
var countryName = (ipv6Json.country_name);
|
|
var countryFlagURL = (ipv6Json.flag)
|
|
|
|
var fullLocation = (city + region + postal + countryName)
|
|
const locationv6 = document.getElementById('locationv6');
|
|
locationv6.textContent = fullLocation
|
|
|
|
const countryFlag = document.getElementById('countryFlagv6');
|
|
countryFlag.src = countryFlagURL;
|
|
|
|
}
|
|
};
|
|
request.send();
|
|
|
|
}
|
|
|
|
|
|
//updateGist(ipv4Result, ipv6Result);
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="content">
|
|
<div class="center-container">
|
|
<div class="header">
|
|
<img src="logo.png" class="logo">
|
|
<div class="header-content">
|
|
<h1>IP Pheasant</h1>
|
|
<p>Where the Pheasant shows all the IP!</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="ipv4Div" class="ipBlock">
|
|
<div class="h2-container">
|
|
<h2 id="ipv4">IPv4</h2>
|
|
</div>
|
|
<h3>Address:</h3>
|
|
<p class="ip-address">
|
|
<code id="ipv4-address">None</code>
|
|
|
|
</p>
|
|
|
|
<h3>ASN Info:</h3>
|
|
<p>
|
|
<ul id="asn-list-v4"></ul>
|
|
</p>
|
|
<div class="location">
|
|
<span id="locationv4"></span>
|
|
<img id="countryFlagv4" class = "countryFlag">
|
|
</div>
|
|
</div>
|
|
|
|
<div id="ipv6Div" class="ipBlock">
|
|
<div class="h2-container">
|
|
<h2 id="ipv6">IPv6</h2>
|
|
</div>
|
|
<h3>Address:</h3>
|
|
<p class="ip-address">
|
|
<code id="ipv6-address">None</code>
|
|
</p>
|
|
|
|
<h3>ASN Info:</h3>
|
|
<p>
|
|
<ul id="asn-list-v6"></ul>
|
|
</p>
|
|
<div class="location">
|
|
<span id="locationv6"></span>
|
|
<img id="countryFlagv6" class = "countryFlag">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<footer class="footer">
|
|
<p>© 2024 ippheasant.com. All rights reserved.</p>
|
|
</footer>
|
|
</body>
|
|
</html>
|