Compare commits

...

22 Commits

Author SHA1 Message Date
22c85234da Sent the requested glink to reqloc.html as a GET variable, so that the Glink can be sent to the PHP file 2023-06-17 13:56:02 -05:00
4bba4f9410 NOT FINISHED: Created a file to process the user's location 2023-06-17 13:55:05 -05:00
d928ad2ce3 Created file to request the user's location to determine if they are allowed to acces the glink 2023-06-17 13:54:31 -05:00
63050a8065 Changed variable names to match HTML document 2023-06-17 13:54:09 -05:00
0b08c1ce9c Added code to hide radius drop-down menu if geo-restriction checkbox was not selected 2023-06-17 13:53:51 -05:00
b7a8602e34 Added code to wait for location to be retrieved before allowing user to submit, and hid the radius drop-down if geo-location wasn't checked 2023-06-15 23:00:21 -05:00
42eff5e0fa Added code to redirect the user to a different page if the GLink they requested is geo-restricted 2023-06-15 18:49:31 -05:00
3d36c2704a Added code to retrieve the user's location and store it in the database 2023-06-15 18:48:36 -05:00
ae036686b8 Added code to fetch the user's location, and send it as a GET/POST variable 2023-06-12 15:29:24 -05:00
70f91c7586 Fixed bug where I accessed the database without opening a session 2023-06-12 15:28:30 -05:00
913d53b757 Added form field to allow user to georestrict the link 2023-06-12 15:28:02 -05:00
8b68547644 Added code to generate a random GLink if the user doesn't submit one 2023-06-09 20:03:30 -05:00
0f85fcf021 Made the Glink field optional 2023-06-09 20:03:01 -05:00
1d4606db27 Added code to redirect the user if the database query returns a URL 2023-06-08 21:36:33 -05:00
116bbe5218 Started working on redirect when user enters a GLink 2023-06-08 10:46:59 -05:00
1b52864952 Added server-side checks to input 2023-06-08 10:46:41 -05:00
92b70e632b Added code to print out the inserted data, and to check if the data was inserted by querying the database for the inserted data 2023-06-08 01:32:30 -05:00
c81937d6a5 Added code to insert data into Cassandra DB 2023-06-06 23:53:32 -05:00
f451850601 DO NOT USE - SWITCHED TO PHP INSTEAD - Added code to make database query 2023-06-06 13:23:27 -05:00
3bc6a56516 Added PHP file to make database queries 2023-06-06 13:22:15 -05:00
536af5f9c5 Removed event parameter from function so that it could be used with the HTML form 'onsubmit' 2023-06-06 13:21:57 -05:00
e5bdf2cc2c Switched to PHP instead of node.js, fixed bug where PHP would not be called regardless of input 2023-06-06 13:21:23 -05:00
7 changed files with 420 additions and 72 deletions

14
checkloc.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
$latitude = $_GET["latitude"];
$longitude = $_GET["longitude"];
$glink = $_GET["glink"];
printf("Lat is %s, Long is %s, and glink is %s",$latitude,$longitude,$glink);
// Check the database to see if user is allowed to access the URL. If they are, respond 'Yes' (for the time being), if they are not, respond 'No' (for the time being).
// To check if the user is allowed to access the URL, check if the distance between their location and the location in the database is less than the radius. To compute the
// distance, use something like Haversine Forumla.
?>

View File

@@ -7,17 +7,34 @@
<body> <body>
<div id="root"> <div id="root">
<h1>Link Shortener</h1> <h1>Link Shortener</h1>
<form id="form" action="result.js"> <form id="form" method="GET" action="result.php" onsubmit="return validate()">
<!-- <form id="form"> -->
<label for="url">URL:</label><span class="mandatory">*</span> <label for="url">URL:</label><span class="mandatory">*</span>
<input type="text" name="url" id="URL" value="example.com" required><br><br> <input type="text" name="url" id="URL" value="https://example.com" required><br><br>
<label for="labels">GLink:</label><span class="mandatory">*</span> <label for="labels">GLink:</label><span class="mandatory">*</span>
<label for="GLink" id="labels" class="glink">glink.zip/</label><input type="text" name="glink" id="GLink" class="glink" value="exampleWebsite" required> <label for="GLink" id="labels" class="glink">glink.zip/</label><input type="text" name="glink" id="GLink" class="glink" value="exampleWebsite">
<span role="alert" id="error" aria-hidden="true">Invalid URL</span> <span role="alert" id="error" aria-hidden="true">Invalid URL</span>
<br><br>
<label for="restricted">Geo-restricted?: </label> <input type="checkbox" name="restricted" id="restricted"> <span id="loadingText" style="position: relative; left: 20px;"></span>
<br><br>
<label for="radius" hidden="hidden" id="radius_label">Radius: </label> <span id="mandatory-radius" class="mandatory" hidden="hidden">*</span>
<select name="radius" id="radius" hidden="hidden">
<option value="" selected disabled hidden>Select a radius</option>
<option value="5">5 mi</option>
<option value="10">10 mi</option>
<option value="15">15 mi</option>
<option value="20">20 mi</option>
</select>
<br><br> <br><br>
<input type="submit" id="button" value="Zip It!"> <input type="submit" id="button" value="Zip It!">
<input type="hidden" name="latitude" id="latitude">
<input type="hidden" name="longitude" id="longitude">
</form> </form>
<hr> <hr>
<div> <div>

136
index.js
View File

@@ -1,21 +1,101 @@
const submit = document.getElementById("button"); // const submit = document.getElementById("button");
submit.addEventListener('click', validate); mycheckbox = document.getElementById("restricted");
function validate(e) { mycheckbox.addEventListener('change',checkboxCallback);
e.preventDefault(); window.onload = function() {
if (mycheckbox.checked) {
document.getElementById("radius_label").hidden = false;
document.getElementById("mandatory-radius").hidden = false;
var radiusSelect = document.getElementById("radius");
radiusSelect.hidden = false;
radiusSelect.required = true;
}
}
var lat = document.getElementById("latitude");
lat.setValue = function(newValue) {
this.value = newValue;
valueReceived();
}
function valueReceived() {
let load = document.getElementById("loadingText");
load.innerHTML = "Location retrieved";
load.style.color = "green";
}
function valueRequested() {
let load = document.getElementById("loadingText");
load.innerHTML = "Location requested. Please wait...";
load.style.color = "red";
}
function checkboxCallback(event) {
const radiusLabel = document.getElementById("radius_label");
const radiusSelect = document.getElementById("radius");
const mandatoryRadius = document.getElementById("mandatory-radius");
if (event.currentTarget.checked) {
radiusLabel.hidden = false;
mandatoryRadius.hidden = false;
radiusSelect.hidden = false;
radiusSelect.required = true;
valueRequested();
getLocation();
} else {
radiusLabel.hidden = true;
mandatoryRadius.hidden = true;
radiusSelect.hidden = true;
radiusSelect.required = false;
}
}
function getLocation() {
console.log("GeoLocation");
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
console.log("Your browser does not support geolocation.");
}
}
function showPosition(position) {
console.log("Gotten positions");
console.log(position.coords.latitude);
console.log(position.coords.longitude);
document.getElementById("latitude").setValue(position.coords.latitude);
document.getElementById("longitude").value = position.coords.longitude;
console.log("done");
}
// submit.addEventListener('click', validate);
function validate() {
//e.preventDefault();
const checked = document.getElementById("restricted");
if (checked.checked) {
const lat = document.getElementById("latitude");
const long = document.getElementById("longitude");
if (lat.value === "" || long.value === "") {
/* wait */
return false
}
}
const url = document.getElementById("URL"); const url = document.getElementById("URL");
const glink = document.getElementById("GLink"); let glink = document.getElementById("GLink");
const error = document.getElementById("error");
// if (!url) { // if (!url) {
// /* Flag */ // /* Flag */
// } // }
let valid = true; let valid = true;
const domainExp = new RegExp("http(s)*:\\/\\/[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)+"); const domainExp = new RegExp("^http(s)*:\\/\\/[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)+$");
const filepathExp = new RegExp("[a-zA-Z]+"); const filepathExp = new RegExp("^[a-zA-Z]+$");
const glinkExp = new RegExp("^[a-zA-Z]*$");
let glinkStr = glink.value;
let count = 0; let count = 0;
let index = -1; let index = -1;
let domain = ""; let domain = "";
let filepath = ""; let filepath = "";
for (let i=0; i < url.value.length; i++) { for (let i = 0; i < url.value.length; i++) {
if (url.value.charAt(i) == '/') { if (url.value.charAt(i) == '/') {
count++; count++;
} }
@@ -36,8 +116,16 @@ function validate(e) {
domain = url.value; domain = url.value;
} }
console.log(domain); console.log(domain);
if (domain.match(domainExp)) /** and is available? */{
const error = document.getElementById("error"); if (glinkStr === "") {
var result = window.confirm("You have left the glink field blank. A random one will be generated for you.");
if (result === false) {
return false;
}
}
if (domain.match(domainExp) && glinkStr.match(glinkExp))/** and is available? */{
if (error.classList.contains("visible")) { if (error.classList.contains("visible")) {
error.classList.remove("visible"); error.classList.remove("visible");
} }
@@ -45,23 +133,43 @@ function validate(e) {
url.classList.remove("invalid"); url.classList.remove("invalid");
} }
url.classList.add("valid"); url.classList.add("valid");
if (glink.classList.contains("invalid")) {
glink.classList.remove("invalid");
}
glink.classList.add("valid");
error.setAttribute('aria-hidden', true); error.setAttribute('aria-hidden', true);
error.setAttribute('aria-invalid', false); error.setAttribute('aria-invalid', false);
console.log("Valid"); console.log("Valid with url= " +url.value+ " glink=" +glink);
return valid; return valid;
} else { } else {
/*flag*/ /*flag*/
const error = document.getElementById("error");
error.classList.add("visible"); error.classList.add("visible");
//error.classList.add("hidden"); //error.classList.add("hidden");
if (!domain.match(domainExp)) {
if (url.classList.contains("valid")) { if (url.classList.contains("valid")) {
url.classList.remove("valid"); url.classList.remove("valid");
} }
url.classList.add("invalid"); url.classList.add("invalid");
} else {
if (url.classList.contains("invalid")) {
url.classList.remove("invalid");
}
url.classList.add("valid");
}
if (!glinkStr.match(glinkExp)) {
if (glink.classList.contains("valid")) {
glink.classList.remove("valid");
}
glink.classList.add("invalid");
} else {
if (glink.classList.contains("invalid")) {
glink.classList.remove("invalid");
}
glink.classList.add("valid");
}
error.setAttribute('aria-hidden', false); error.setAttribute('aria-hidden', false);
error.setAttribute('aria-invalid', true); error.setAttribute('aria-invalid', true);
return false;
} }
} }

42
redirect.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
use Cassandra;
$uri = $_SERVER['REQUEST_URI'];
$uri = substr($uri,1);
$matches_uri = preg_match('/^[a-zA-Z]+$/',$uri);
if (($matches_uri == 0) || ($matches_uri == false)) {
header("Location: http://glink.zip/");
exit;
} else {
$cluster = Cassandra::cluster()->withPersistentSessions(true)->build();
$keyspace = 'glink';
$session = $cluster->connect($keyspace);
$statement = $session->prepare('SELECT url,is_geo FROM data WHERE shortlink=? ALLOW FILTERING;');
$result = $session->execute($statement,array('arguments' => array($uri)));
if ($result->count() == 0) {
printf('The given GLink was invalid, and doesn\'t point to a specific web page.');
exit;
}
foreach($result as $row) {
if (is_null($row)) {
printf('The given GLink was invalid, and doesn\'t point to a specific web page.');
exit;
} else {
if ($row['is_geo'] == true) {
header("Location: https://glink.zip/reqloc.html?glink=" . $uri);
exit;
} else {
header("Location: " . $row['url']);
exit;
}
}
}
}
?>

55
reqloc.html Normal file
View File

@@ -0,0 +1,55 @@
<html>
<head>
<title>Location needed</title>
</head>
<body onload="get_location()">
This link is geo-restricted. Your location is needed to verify that you are authorized to access this link.
<script>
var params = new URLSearchParams(window.location.search);
var glink = params.get("glink");
var lat;
var long;
var method = "GET";
var request;
function requestHandler() {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
alert(request.responseText);
} else {
console.log("Error sending data to server.");
}
}
}
function storeLocation(position) {
lat = position.coords.latitude;
long = position.coords.longitude;
}
function callbackFunction(position) {
storeLocation(position);
request = new XMLHttpRequest();
request.onreadystatechange = requestHandler;
if (method == "GET") {
request.open("GET","/checkloc.php?latitude=" + encodeURIComponent(lat) + "&longitude=" + encodeURIComponent(long) + "&glink=" + encodeURIComponent(glink));
request.send();
} else if (method == "POST") {
request.open("POST","/checkloc.php");
request.send("latitude=" + encodeURIComponent(lat) + "&longitude=" + encodeURIComponent(long));
}
}
function get_location() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(callbackFunction);
} else {
alert('You cannot access this GLink as your browser does not support geolocation.');
}
}
</script>
</body>
</html>

View File

@@ -1,8 +0,0 @@
const cassandra = require('cassandra-driver');
const client = new cassandra.Client({
contactPoints: ['127.0.0.1:9042'],
keyspace: 'glink',
});
const query =

120
result.php Normal file
View File

@@ -0,0 +1,120 @@
<?php
function gen_base62_rand_shortlink($len) {
$rand_bytes = random_bytes(intval(($len * 2) / 3));
$rand_string = base64_encode($rand_bytes);
$rand_string = str_replace("+","",$rand_string);
$rand_string = str_replace("/","",$rand_string);
$rand_string = str_replace("=","",$rand_string);
if (mb_strlen($rand_string) < $len) {
$curlen = mb_strlen($rand_string);
$rand_string = $rand_string . gen_rand_shortlink($len - $curlen);
}
return $rand_string;
}
function gen_rand_shortlink($len) {
$to_return = '';
$possible_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
while (mb_strlen($to_return) < $len) {
$to_return = $to_return . $possible_chars[rand(0, mb_strlen($possible_chars)-1)];
}
return $to_return;
}
ini_set('display_errors', 1);
$cluster = Cassandra::cluster()->withPersistentSessions(true)->build();
$keyspace = 'glink';
$session = $cluster->connect($keyspace);
$url = $_GET["url"];
if (isset($_GET["restricted"])) {
$is_geo = 1;
} else {
$is_geo = 0;
}
if ($is_geo == 1) {
$radius = $_GET["radius"];
$latitude = $_GET["latitude"];
$latitude = doubleval($latitude);
$longitude = $_GET["longitude"];
$longitude = doubleval($longitude);
}
$matches = preg_match('/^http(s)*:\\/\\/[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)+$/',$url);
if (($matches == 0) || ($matches == false)) {
printf("The URL entered was invalid. Please try again.");
return;
}
$shortlink = $_GET["glink"];
if ($shortlink != '') {
$matches_shortlink = preg_match('/^[a-zA-Z]+$/',$shortlink);
if (($matches_shortlink == 0) || ($matches_shortlink == false)) {
printf("The GLink entered was invalid. The GLink can only contain letters. Please try again.");
return;
}
} else {
/* generate a random shortlink */
gen_shortlink:
$rand_string = gen_rand_shortlink(6); /* the function is defined at the start of this file */
$shortlink = $rand_string;
/* Check if shortlink is already taken by querying the database */
$statement = $session->prepare('SELECT url FROM data WHERE shortlink=? ALLOW FILTERING');
$result = $session->execute($statement,array('arguments' => array($shortlink)));
if ($result->count() != 0) {
goto gen_shortlink;
}
}
//$statement = new Cassandra\SimpleStatement('SELECT name FROM data WHERE id=5');
$statement = $session->prepare('SELECT url FROM data WHERE shortlink=? ALLOW FILTERING');
$options = array('arguments' => array($shortlink));
$result = $session->execute($statement,$options);
if ($result->count() != 0) {
printf('That GLink is already taken. Please try another one.');
exit;
}
$rand_num = rand(0,99999999);
$statement = $session->prepare('INSERT INTO data (id, url, shortlink, is_geo, radius, latitude, longitude, when_created) VALUES (?,?,?,?,?,?,?,toTimestamp(now())) USING TTL 20');
if ($is_geo == 1) {
$options = array($rand_num,$url,$shortlink,boolval($is_geo),intval($radius), $latitude, $longitude);
} else {
$options = array($rand_num,$url,$shortlink,boolval($is_geo),null,null,null);
}
$result = $session->execute($statement,array('arguments' => $options));
//$stringRepresentation= json_encode($result[0]);
//printf("%s\n\n\n",$stringRepresentation);
//foreach($result as $row) {
// if (is_null($row)) {
// printf('Unsuccessful');
// } else {
printf('Successful: The URL you entered was: %s and your GLink is: https://glink.zip/%s', $url,$shortlink);
// }
//}
//printf('Done');
?>