Compare commits
38 Commits
master
...
3b59de608a
Author | SHA1 | Date | |
---|---|---|---|
3b59de608a | |||
606d58e197 | |||
63effd893e | |||
69c8934a77 | |||
665ab0aeac | |||
b0400e59a0 | |||
e36a2cbd77 | |||
1392c62d31 | |||
e37bf086dd | |||
67228048e1 | |||
de1a7f0687 | |||
1c74b82f6e | |||
df131d2fb5 | |||
4d10b191c7 | |||
071113592b | |||
b5283110d2 | |||
3914190175 | |||
0022e0d7c2 | |||
0f8b0154f8 | |||
e3e3b45c65 | |||
cd1261418a | |||
96abdd9852 | |||
22c85234da | |||
4bba4f9410 | |||
d928ad2ce3 | |||
63050a8065 | |||
0b08c1ce9c | |||
b7a8602e34 | |||
42eff5e0fa | |||
3d36c2704a | |||
ae036686b8 | |||
70f91c7586 | |||
913d53b757 | |||
8b68547644 | |||
0f85fcf021 | |||
1d4606db27 | |||
116bbe5218 | |||
1b52864952 |
75
checkloc.php
Normal file
75
checkloc.php
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db.inc.php';
|
||||||
|
if (isset($_SESSION['glink']) && !empty($_SESSION['glink'])) {
|
||||||
|
session_unset();
|
||||||
|
session_destroy();
|
||||||
|
} else {
|
||||||
|
http_response_code(403);
|
||||||
|
die('Forbidden.');
|
||||||
|
}
|
||||||
|
// FUNCTION TO CALCULATE HAVERSINE DISTANCE GIVEN COORDINATES OF
|
||||||
|
// TWO POINTS, AND RADIUS (IN KM)
|
||||||
|
function haversine_distance($lat1, $long1, $lat2, $long2, $radius) {
|
||||||
|
$term_1 = $lat2 - $lat1;
|
||||||
|
$term_1 = $term_1 / 2;
|
||||||
|
$term_1 = sin($term_1);
|
||||||
|
$term_1 = pow($term_1, 2);
|
||||||
|
|
||||||
|
$term_2 = $long2 - $long1;
|
||||||
|
$term_2 = $term_2 / 2;
|
||||||
|
$term_2 = sin($term_2);
|
||||||
|
$term_2 = pow($term_2, 2);
|
||||||
|
$term_2 = $term_2 * cos($lat1);
|
||||||
|
$term_2 = $term_2 * cos($lat2);
|
||||||
|
|
||||||
|
$distance = $term_1 + $term_2;
|
||||||
|
$distance = sqrt($distance);
|
||||||
|
$distance = asin($distance);
|
||||||
|
$distance = $distance * 2;
|
||||||
|
$distance = $distance * $radius;
|
||||||
|
|
||||||
|
return $distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function km_to_miles($distance) {
|
||||||
|
return $distance * 0.62137119;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$user_lat = $_GET["latitude"];
|
||||||
|
$user_lat = $user_lat * (M_PI / 180);
|
||||||
|
$user_long = $_GET["longitude"];
|
||||||
|
$user_long = $user_long * (M_PI / 180);
|
||||||
|
$glink = $_GET["glink"];
|
||||||
|
|
||||||
|
$session = init_cass_db();
|
||||||
|
|
||||||
|
$statement = $session->prepare('SELECT latitude,longitude,radius,url FROM data WHERE shortlink=? ALLOW FILTERING;');
|
||||||
|
$result = $session->execute($statement,array('arguments' => array($glink)));
|
||||||
|
|
||||||
|
$link_lat = floatval($result[0]['latitude']);
|
||||||
|
$link_lat = $link_lat * (M_PI / 180);
|
||||||
|
$link_long = floatval($result[0]['longitude']);
|
||||||
|
$link_long = $link_long * (M_PI / 180);
|
||||||
|
$target_radius = intval($result[0]['radius']);
|
||||||
|
|
||||||
|
$url = $result[0]['url'];
|
||||||
|
|
||||||
|
$distance = haversine_distance($link_lat, $link_long, $user_lat, $user_long, 6371.009);
|
||||||
|
$distance = km_to_miles($distance);
|
||||||
|
|
||||||
|
if ($distance <= $target_radius) {
|
||||||
|
printf("%s",$url);
|
||||||
|
} else {
|
||||||
|
printf("B");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
9
db.inc.php
Normal file
9
db.inc.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
function init_cass_db() {
|
||||||
|
$cluster = Cassandra::cluster()->withPersistentSessions(true)->build();
|
||||||
|
$keyspace = 'glink';
|
||||||
|
$session = $cluster->connect($keyspace);
|
||||||
|
|
||||||
|
return $session;
|
||||||
|
}
|
||||||
|
?>
|
BIN
fonts/ArchivoBlack-Regular.ttf
Normal file
BIN
fonts/ArchivoBlack-Regular.ttf
Normal file
Binary file not shown.
45
header.php
Normal file
45
header.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
?>
|
||||||
|
<nav class="flex items-center justify-between flex-wrap bg-gray-500 p-6 shadow-lg shadow-black/50 sticky top-0"> <!--dark:bg-black-->
|
||||||
|
<div class="flex items-center flex-shrink-0 text-white mr-6">
|
||||||
|
<svg id="logo" class="fill-current h-8 w-8 mr-2" width="54" height="54" viewBox="0 0 54 54" xmlns="http://www.w3.org/2000/svg"><path d="M13.5 22.1c1.8-7.2 6.3-10.8 13.5-10.8 10.8 0 12.15 8.1 17.55 9.45 3.6.9 6.75-.45 9.45-4.05-1.8 7.2-6.3 10.8-13.5 10.8-10.8 0-12.15-8.1-17.55-9.45-3.6-.9-6.75.45-9.45 4.05zM0 38.3c1.8-7.2 6.3-10.8 13.5-10.8 10.8 0 12.15 8.1 17.55 9.45 3.6.9 6.75-.45 9.45-4.05-1.8 7.2-6.3 10.8-13.5 10.8-10.8 0-12.15-8.1-17.55-9.45-3.6-.9-6.75.45-9.45 4.05z"/></svg>
|
||||||
|
<span class="font-semibold text-xl tracking-tight">G-Link</span>
|
||||||
|
</div>
|
||||||
|
<div class="block lg:hidden">
|
||||||
|
<button id="hamburger-menu" class="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white">
|
||||||
|
<svg class="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="menu-options" class="w-full lg:block flex-grow lg:flex lg:items-center lg:w-auto hidden">
|
||||||
|
<div class="text-sm lg:flex-grow">
|
||||||
|
<a href="#head" class="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-black mr-4 hover:bg-gray-200 hover:border hover:border-gray-200 hover:rounded text-teal-200 py-1 px-3">
|
||||||
|
A
|
||||||
|
</a>
|
||||||
|
<a href="#head" class="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-black mr-4 hover:bg-gray-200 hover:border hover:border-gray-200 hover:rounded text-teal-200 py-1 px-3">
|
||||||
|
B
|
||||||
|
</a>
|
||||||
|
<a href="#head" class="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-black mr-4 hover:bg-gray-200 hover:border hover:border-gray-200 hover:rounded text-teal-200 py-1 px-3">
|
||||||
|
C
|
||||||
|
</a>
|
||||||
|
<a href="/index.html" class="block mt-4 lg:inline-block lg:mt-0 bg-blue-600 brightness-125 border border-blue-500 rounded text-teal-200 hover:text-black py-1 px-3">
|
||||||
|
Products (Form)
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<?php if (isset($_SESSION['user'])) { ?>
|
||||||
|
<a href="logout.php" class="inline-block text-sm px-4 py-2 leading-none border rounded text-white border-white hover:border-transparent hover:text-teal-500 hover:bg-white mt-4 lg:mt-0">
|
||||||
|
Log Out
|
||||||
|
</a>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
menu = document.querySelector("#hamburger-menu");
|
||||||
|
options = document.querySelector("#menu-options");
|
||||||
|
menu.addEventListener("click", () => {
|
||||||
|
options.classList.toggle("hidden");
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</nav>
|
5
howItWorks.txt
Normal file
5
howItWorks.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
1. Enter the URL that you want to shorten.
|
||||||
|
2. Enter the GLink - a keyword used to identify your URL. This is optional, and if this textbox is left blank, a random GLink will be generated for you. The GLink that you enter will be appended to the URL, like so: glink.zip/<your keyword>
|
||||||
|
3. If you don't want to geo-restrict it, you're good to go! Skip to step 5.
|
||||||
|
4. If you want to geo-restrict the link, select the checkbox, and provide a radius to use as a 'containment zone'. Only those individuals who are within that radius from your current location will be able to access the Glink.
|
||||||
|
5. Click 'Zip it!' to generate your custom URL.
|
81
index.html
81
index.html
@@ -1,31 +1,80 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>GLink</title>
|
<title>GLink</title>
|
||||||
<link rel="stylesheet" href="index.css">
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="output.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="bg-gray-50">
|
||||||
|
<h1 class="ml-4 text-5xl font-narrow">Link Shortener</h1>
|
||||||
|
<p class="ml-4 font-fingerpaint">Hello There!</p>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// The reason this works (i.e. I can use PHP in a .html file)
|
||||||
|
// is because I have configured my .htaccess file to treat every file
|
||||||
|
// ending in .html, as if it contains embedded PHP.
|
||||||
|
// However, this is a strain on resources as it means _every_ HTML
|
||||||
|
// file will be parsed for PHP code, even if it doesn't contain any.
|
||||||
|
// An alternative to doing this, is to use the .php file extension for
|
||||||
|
// any HTML file that has embedded PHP code, and the .html extension
|
||||||
|
// for static HTML files.
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php include 'header.php'; ?>
|
||||||
|
|
||||||
<div id="root">
|
<div id="root">
|
||||||
<h1>Link Shortener</h1>
|
|
||||||
<form id="form" method="GET" action="result.php" onsubmit="return validate()">
|
<form id="form" method="GET" action="result.php" onsubmit="return validate()">
|
||||||
|
|
||||||
<!-- <form id="form"> -->
|
<div class="flex flex-wrap">
|
||||||
<label for="url">URL:</label><span class="mandatory">*</span>
|
<label for="URL" class="text-2xl ml-4 font-rubik self-center">URL</label>
|
||||||
<input type="text" name="url" id="URL" value="https://example.com" required><br><br>
|
<span class="mandatory font-rubik self-center text-2xl">*</span>
|
||||||
|
<span class="font-rubik self-center m-1 text-2xl">:</span>
|
||||||
|
<div class="p-0.5 m-4 rounded-lg max-w-sm bg-gradient-to-r from-cyan-500 to-cyan-500 focus-within:from-rose-400 focus-within:via-fuchsia-500 focus-within:to-indigo-500 focus-within:caret-gray-600 focus-within:p-[3.2px]">
|
||||||
|
<input type="text" name="url" id="URL" placeholder="https://example.com" required class="p-2 w-full rounded-lg focus:outline-none focus:shadow-lg focus:focus:shadow-black/50 text-center text-lg text-black font-bold">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<label for="labels">GLink:</label><span class="mandatory">*</span>
|
<div class="flex flex-wrap">
|
||||||
<label for="GLink" id="labels" class="glink">glink.zip/</label><input type="text" name="glink" id="GLink" class="glink" value="exampleWebsite" required>
|
<label for="labels" class="text-2xl ml-4 font-rubik self-center">GLink</label>
|
||||||
|
<span class="mandatory font-rubik text-2xl self-center">*</span>
|
||||||
|
<span class="font-rubik self-center m-1 text-2xl">:</span>
|
||||||
|
<label for="GLink" id="labels" class=" ml-2 glink text-center text-xl self-center">glink.zip/</label>
|
||||||
|
<div class="p-0.5 ml-2 mr-4 my-4 rounded-lg max-w-sm bg-gradient-to-r from-cyan-500 to-cyan-500 focus-within:from-rose-400 focus-within:via-fuchsia-500 focus-within:to-indigo-500 focus-within:caret-gray-600 focus-within:p-[3.2px]">
|
||||||
|
<input type="text" name="glink" id="GLink" class="glink p-2 w-full rounded-lg focus:outline-none focus:shadow-lg focus:focus:shadow-black/50 text-center text-lg text-black font-bold" placeholder="exampleWebsite">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<span role="alert" id="error" aria-hidden="true">Invalid URL</span>
|
<label for="restricted" class="ml-4 self-center text-2xl font-rubik lg:invisible">Geo-restricted? : </label><input type="checkbox" name="restricted" id="restricted" class="ml-2 mr-4 my-4 text-center font-rubik ease-soft rounded-1.4 w-6 h-6 cursor-pointer checked:accent-blue-700 shadow-lg shadow-black/50 peer"><span id="loadingText" class="font-rubik self-center text-center text-xl" style="position: relative; left: 20px;"></span>
|
||||||
|
|
||||||
|
<span class="flex flex-wrap invisible peer-checked:visible" id="js-enabled">
|
||||||
|
<label for="radiusSelect" id="radius_label" class="ml-4 font-rubik text-2xl self-center">Radius</label><span id="mandatory-radius" class="mandatory font-rubik text-2xl self-center">*</span><span class="font-rubik self-center m-1 text-2xl">:</span>
|
||||||
|
<div class="p-0.5 ml-2 mr-4 my-4 rounded-lg max-w-sm bg-gradient-to-r from-cyan-500 to-cyan-500 focus-within:from-rose-400 focus-within:via-fuchsia-500 focus-within:to-indigo-500 focus-within:p-[3.2px]">
|
||||||
|
<select name="radius" id="radius" class="cursor-pointer text-lg p-2 w-full rounded-lg focus:outline-none invalid:text-gray-400 font-bold">
|
||||||
|
<option value="" selected disabled hidden>Choose a radius for your geo link</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>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<noscript>
|
||||||
|
<style>
|
||||||
|
#js-enabled {display: none;}
|
||||||
|
</style>
|
||||||
|
</noscript>
|
||||||
|
<span role="alert" class="m-4 font-rubik" id="error" aria-hidden="true">Invalid entry</span>
|
||||||
|
<input type="submit" id="button" value="Zip It!" class="scale-125 brightness-125 ml-20 font-rubik bg-gradient-to-r from-cyan-500 to-blue-500 hover:from-cyan-400 hover:to-blue-400 hover:shadow-lg hover:shadow-black/50 transition hover:-translate-y-1 hover:scale-150 duration-600 ease-in-out rounded-full cursor-pointer">
|
||||||
|
<input type="hidden" name="latitude" id="latitude">
|
||||||
|
<input type="hidden" name="longitude" id="longitude">
|
||||||
|
|
||||||
<br><br>
|
|
||||||
<input type="submit" id="button" value="Zip It!">
|
|
||||||
</form>
|
</form>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<img src="./cat.gif">
|
||||||
<img src="cat.gif">
|
<p id="footer" class="object-none object-bottom">Insert Footer Here</p>
|
||||||
</div>
|
<script src="./index.js"></script>
|
||||||
<script src="index.js"></script>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
141
index.js
141
index.js
@@ -1,21 +1,101 @@
|
|||||||
//const submit = document.getElementById("button");
|
// const submit = document.getElementById("button");
|
||||||
//submit.addEventListener('click', validate);
|
mycheckbox = document.getElementById("restricted");
|
||||||
function validate() {
|
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() {
|
|||||||
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,30 +133,43 @@ function validate() {
|
|||||||
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;
|
||||||
|
|
||||||
/* var xmlhttp = new XMLHttpRequest();
|
|
||||||
xmlhttp.open('GET','result.php',true);
|
|
||||||
xmlhttp.send();
|
|
||||||
console.log(xmlhttp.responseText);*/
|
|
||||||
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
84
login.html
Normal file
84
login.html
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-full bg-white">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="output.css">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body class="h-full">
|
||||||
|
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
||||||
|
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Log in to your account</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<form class="space-y-6" action="login.php" method="GET"> <!--Change to php-->
|
||||||
|
<div>
|
||||||
|
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input id="email" name="email" type="email" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
<div id="email-error" class="hidden mt-2 text-red-800 text-xs">
|
||||||
|
invalid Email
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Password</label>
|
||||||
|
<div class="text-sm">
|
||||||
|
<a href="#" class="font-semibold text-indigo-600 hover:text-indigo-500">Forgot password?</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 relative block">
|
||||||
|
<input id="password" name="password" type="password" autocomplete="off" required class="block w-11/12 rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
|
||||||
|
<span id="pswd-invisible" class="absolute inset-y-0 right-0 flex items-center px-1 rounded-r-md">
|
||||||
|
<svg class="w-6 h-6 m-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" color="black"
|
||||||
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span id="pswd-visible" class="absolute inset-y-0 right-0 flex items-center px-1 hidden">
|
||||||
|
<svg class="w-6 h-6 m-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p id="domain" class="hidden text-red-800 text-xs">
|
||||||
|
<b>Invalid characters entered</b>
|
||||||
|
</p>
|
||||||
|
<p id="letter" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>lowercase</b> letter
|
||||||
|
</p>
|
||||||
|
<p id="capital" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>capital (uppercase)</b> letter
|
||||||
|
</p>
|
||||||
|
<p id="number" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>number</b>
|
||||||
|
</p>
|
||||||
|
<p id="symbol" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>symbol</b>
|
||||||
|
</p>
|
||||||
|
<p id="length" class="hidden text-red-800 text-xs">
|
||||||
|
Minimum <b>10 characters</b>
|
||||||
|
</p>
|
||||||
|
<p id="auth" class="hidden text-red-800 text-xs">
|
||||||
|
Incorrect Email or password
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Log in</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="login.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
168
login.js
Normal file
168
login.js
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
let email = document.getElementById("email");
|
||||||
|
let password = document.getElementById("password");
|
||||||
|
let pswd_visible = document.getElementById("pswd-visible");
|
||||||
|
let pswd_invisible = document.getElementById("pswd-invisible");
|
||||||
|
|
||||||
|
console.log(window.location.pathname);
|
||||||
|
pswd_visible.addEventListener('click', () => {
|
||||||
|
pswd_visible.classList.add("hidden");
|
||||||
|
pswd_invisible.classList.remove("hidden");
|
||||||
|
password.type = "password";
|
||||||
|
});
|
||||||
|
pswd_invisible.addEventListener('click', () => {
|
||||||
|
pswd_invisible.classList.add("hidden");
|
||||||
|
pswd_visible.classList.remove("hidden");
|
||||||
|
password.type = "text";
|
||||||
|
});
|
||||||
|
if (window.location.pathname === '/signup.html') {
|
||||||
|
let check_pswd_visible = document.getElementById("check-pswd-visible");
|
||||||
|
let check_pswd_invisible = document.getElementById("check-pswd-invisible");
|
||||||
|
let check_password = document.getElementById("verify");
|
||||||
|
check_pswd_visible.addEventListener('click', () => {
|
||||||
|
check_pswd_visible.classList.add("hidden");
|
||||||
|
check_pswd_invisible.classList.remove("hidden");
|
||||||
|
check_password.type = "password";
|
||||||
|
});
|
||||||
|
check_pswd_invisible.addEventListener('click', () => {
|
||||||
|
check_pswd_invisible.classList.add("hidden");
|
||||||
|
check_pswd_visible.classList.remove("hidden");
|
||||||
|
check_password.type = "text";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let emailRX = new RegExp("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z]+)+$");
|
||||||
|
let domainError = document.getElementById("domain");
|
||||||
|
let domainRX = new RegExp("^[a-zA-Z0-9!@#$%^&*_]*$");
|
||||||
|
let emailError = document.getElementById("email-error");
|
||||||
|
let capsRX = new RegExp(".*[A-Z]+");
|
||||||
|
let capsError = document.getElementById("capital");
|
||||||
|
let lowRX = new RegExp(".*[a-z]+");
|
||||||
|
let lowError = document.getElementById("letter");
|
||||||
|
let numRX = new RegExp(".*[0-9]+");
|
||||||
|
let numError = document.getElementById("number");
|
||||||
|
let symbolRX = new RegExp(".*[!@#$%^&*_]+");
|
||||||
|
let symbolError = document.getElementById("symbol");
|
||||||
|
let MIN_LENGTH = 10;
|
||||||
|
let lenError = document.getElementById("length");
|
||||||
|
if (window.location.pathname === '/login.html') {
|
||||||
|
let auth_error = document.getElementById("auth");
|
||||||
|
let query = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(query);
|
||||||
|
const errorType = urlParams.get('error');
|
||||||
|
console.log(window.location.pathname);
|
||||||
|
if (errorType === 'auth') {
|
||||||
|
auth_error.classList.add('block');
|
||||||
|
auth_error.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
auth_error.classList.remove('block');
|
||||||
|
auth_error.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
email.addEventListener('keyup', function(event) {
|
||||||
|
if (emailRX.test(email.value)) {
|
||||||
|
console.log("email valid");
|
||||||
|
email.classList.add("ring-green-400");
|
||||||
|
email.classList.add("focus:ring-green-400");
|
||||||
|
email.classList.remove("ring-red-400");
|
||||||
|
email.classList.remove("focus:ring-red-400");
|
||||||
|
emailError.classList.add("hidden");
|
||||||
|
emailError.classList.remove("block");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.log("email invalid");
|
||||||
|
email.classList.add("ring-red-400");
|
||||||
|
email.classList.add("focus:ring-red-400");
|
||||||
|
email.classList.remove("ring-green-400");
|
||||||
|
email.classList.remove("focus:ring-green-400");
|
||||||
|
emailError.classList.remove("hidden");
|
||||||
|
emailError.classList.add("block");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
password.addEventListener('keyup', () => {
|
||||||
|
if (document.location.pathname === '/login.html') {
|
||||||
|
if (document.getElementById('auth').classList.contains('block')) {
|
||||||
|
document.getElementById('auth').classList.remove('block');
|
||||||
|
document.getElementById('auth').classList.add('hidden');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let pswd = password.value;
|
||||||
|
if (!capsRX.test(pswd)) {
|
||||||
|
capsError.classList.remove("hidden");
|
||||||
|
capsError.classList.add("block");
|
||||||
|
} else {
|
||||||
|
capsError.classList.add("hidden");
|
||||||
|
capsError.classList.remove("block");
|
||||||
|
}
|
||||||
|
if (!lowRX.test(pswd)) {
|
||||||
|
lowError.classList.remove("hidden");
|
||||||
|
lowError.classList.add("block");
|
||||||
|
} else {
|
||||||
|
lowError.classList.add("hidden");
|
||||||
|
lowError.classList.remove("block");
|
||||||
|
}
|
||||||
|
if (!numRX.test(pswd)) {
|
||||||
|
numError.classList.remove("hidden");
|
||||||
|
numError.classList.add("block");
|
||||||
|
} else {
|
||||||
|
numError.classList.add("hidden");
|
||||||
|
numError.classList.remove("block");
|
||||||
|
}
|
||||||
|
if (!symbolRX.test(pswd)) {
|
||||||
|
symbolError.classList.remove("hidden");
|
||||||
|
symbolError.classList.add("block");
|
||||||
|
} else {
|
||||||
|
symbolError.classList.add("hidden");
|
||||||
|
symbolError.classList.remove("block");
|
||||||
|
}
|
||||||
|
if (!domainRX.test(pswd)) {
|
||||||
|
domainError.classList.remove("hidden");
|
||||||
|
domainError.classList.add("block");
|
||||||
|
} else {
|
||||||
|
domainError.classList.add("hidden");
|
||||||
|
domainError.classList.remove("block");
|
||||||
|
}
|
||||||
|
if (pswd.length < MIN_LENGTH) {
|
||||||
|
lenError.classList.remove("hidden");
|
||||||
|
lenError.classList.add("block");
|
||||||
|
} else {
|
||||||
|
lenError.classList.add("hidden");
|
||||||
|
lenError.classList.remove("block");
|
||||||
|
}
|
||||||
|
if (capsError.classList.contains("block") || lowError.classList.contains("block") || numError.classList.contains("block") || symbolError.classList.contains("block") || lenError.classList.contains("block")) {
|
||||||
|
password.classList.remove("ring-green-400");
|
||||||
|
password.classList.remove("focus:ring-green-400");
|
||||||
|
password.classList.add("ring-red-400");
|
||||||
|
password.classList.add("focus:ring-red-400");
|
||||||
|
} else {
|
||||||
|
password.classList.add("ring-green-400");
|
||||||
|
password.classList.add("focus:ring-green-400");
|
||||||
|
password.classList.remove("ring-red-400");
|
||||||
|
password.classList.remove("focus:ring-red-400");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (window.location.pathname === '/signup.html') {
|
||||||
|
let check_password = document.getElementById("verify");
|
||||||
|
let check_password_error = document.getElementById("check-password-error");
|
||||||
|
check_password.addEventListener("keyup", () => {
|
||||||
|
let check = check_password.value;
|
||||||
|
if (check !== password.value) {
|
||||||
|
check_password_error.classList.remove("hidden");
|
||||||
|
check_password_error.classList.add("block");
|
||||||
|
} else {
|
||||||
|
check_password_error.classList.add("hidden");
|
||||||
|
check_password_error.classList.remove("block")
|
||||||
|
}
|
||||||
|
if (check_password_error.classList.contains("block")) {
|
||||||
|
check_password.classList.remove("ring-green-400");
|
||||||
|
check_password.classList.remove("focus:ring-green-400");
|
||||||
|
check_password.classList.add("ring-red-400");
|
||||||
|
check_password.classList.add("focus:ring-red-400");
|
||||||
|
} else {
|
||||||
|
check_password.classList.add("ring-green-400");
|
||||||
|
check_password.classList.add("focus:ring-green-400");
|
||||||
|
check_password.classList.remove("ring-red-400");
|
||||||
|
check_password.classList.remove("focus:ring-red-400");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
29
login.php
Normal file
29
login.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'db.inc.php';
|
||||||
|
|
||||||
|
$email = $_GET['email'];
|
||||||
|
$password = $_GET['password'];
|
||||||
|
|
||||||
|
$session = init_cass_db();
|
||||||
|
|
||||||
|
$statement = $session->prepare('SELECT password_hash FROM users WHERE email=? ALLOW FILTERING;');
|
||||||
|
|
||||||
|
$result = $session->execute($statement,array('arguments' => array($email)));
|
||||||
|
|
||||||
|
if ($result->count() <= 0) {
|
||||||
|
echo('Invalid email address or password.');
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
$hash = $result[0]['password_hash'];
|
||||||
|
|
||||||
|
if (password_verify($password,$hash) != true) {
|
||||||
|
echo('Invalid email address or password.');
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
session_start();
|
||||||
|
$_SESSION['user'] = $email;
|
||||||
|
header('Location: https://glink.zip?res=success');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
23
logout.php
Normal file
23
logout.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (session_status() != PHP_SESSION_ACTIVE) {
|
||||||
|
header('Location: https://glink.zip');
|
||||||
|
}
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// Unset all session variables
|
||||||
|
session_unset();
|
||||||
|
$_SESSION = array();
|
||||||
|
|
||||||
|
// Delete the session cookie by setting an equivalent one with a blank value
|
||||||
|
$params = session_get_cookie_params();
|
||||||
|
|
||||||
|
setcookie(session_name(),'', time()-42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
|
||||||
|
|
||||||
|
// Destroy the session
|
||||||
|
session_destroy();
|
||||||
|
|
||||||
|
header('Location: https://glink.zip/');
|
||||||
|
?>
|
||||||
|
|
1672
output.css
Normal file
1672
output.css
Normal file
File diff suppressed because it is too large
Load Diff
43
redirect.php
Normal file
43
redirect.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'db.inc.php';
|
||||||
|
session_start();
|
||||||
|
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: https://glink.zip/");
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$session = init_cass_db();
|
||||||
|
|
||||||
|
$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) {
|
||||||
|
$_SESSION['glink'] = $uri;
|
||||||
|
header("Location: https://glink.zip/reqloc.html?glink=" . $uri);
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
header("Location: " . $row['url']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
59
reqloc.html
Normal file
59
reqloc.html
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<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) {
|
||||||
|
if (request.responseText == "B") {
|
||||||
|
alert("You are not authorized to access this GLink, as you are outside the permitted radius. If you think this is an error, please try again on a mobile device.");
|
||||||
|
} else {
|
||||||
|
window.location.replace(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>
|
14
result.js
14
result.js
@@ -1,14 +0,0 @@
|
|||||||
console.log('Beginning database execution');
|
|
||||||
|
|
||||||
const cassandra = require('cassandra-driver');
|
|
||||||
|
|
||||||
const client = new cassandra.Client({
|
|
||||||
contactPoints: ['127.0.0.1:9042'],
|
|
||||||
keyspace: 'glink',
|
|
||||||
});
|
|
||||||
|
|
||||||
const query = 'SELECT name FROM data WHERE id = ?';
|
|
||||||
|
|
||||||
console.log(query);
|
|
||||||
|
|
||||||
client.execute(query, [5]).then(result => console.log('User name is %s',result.rows[0].name));
|
|
123
result.php
123
result.php
@@ -1,42 +1,119 @@
|
|||||||
<?php
|
<?php
|
||||||
ini_set('display_errors', 1);
|
require_once 'db.inc.php';
|
||||||
use Casssandra;
|
|
||||||
|
|
||||||
$cluster = Cassandra::cluster()->build();
|
function gen_base62_rand_shortlink($len) {
|
||||||
$keyspace = 'glink';
|
$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);
|
||||||
|
|
||||||
|
$session = init_cass_db();
|
||||||
|
|
||||||
$url = $_GET["url"];
|
$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"];
|
$shortlink = $_GET["glink"];
|
||||||
|
|
||||||
$session = $cluster->connect($keyspace);
|
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 = 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);
|
$rand_num = rand(0,99999999);
|
||||||
|
|
||||||
$values = array(
|
$statement = $session->prepare('INSERT INTO data (id, url, shortlink, is_geo, radius, latitude, longitude, when_created) VALUES (?,?,?,?,?,?,?,toTimestamp(now())) USING TTL 20');
|
||||||
'id' => $rand_num,
|
|
||||||
'url' => $url,
|
|
||||||
'shortlink' => $shortlink,
|
|
||||||
);
|
|
||||||
$statement = new Cassandra\SimpleStatement('INSERT INTO data (id, url, shortlink, when_created) VALUES (?,?,?,toTimestamp(now()))');
|
|
||||||
$options = array('arguments' => $values);
|
|
||||||
$result = $session->execute($statement,$options);
|
|
||||||
|
|
||||||
$statement = new Cassandra\SimpleStatement('SELECT url,shortlink FROM data WHERE id=?');
|
if ($is_geo == 1) {
|
||||||
$options = array('arguments' => array('id' => $rand_num));
|
$options = array($rand_num,$url,$shortlink,boolval($is_geo),intval($radius), $latitude, $longitude);
|
||||||
$result = $session->execute($statement,$options);
|
} 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]);
|
//$stringRepresentation= json_encode($result[0]);
|
||||||
|
|
||||||
//printf("%s\n\n\n",$stringRepresentation);
|
//printf("%s\n\n\n",$stringRepresentation);
|
||||||
|
|
||||||
foreach($result as $row) {
|
//foreach($result as $row) {
|
||||||
if (is_null($row)) {
|
// if (is_null($row)) {
|
||||||
printf('Unsuccessful');
|
// printf('Unsuccessful');
|
||||||
} else {
|
// } else {
|
||||||
printf('Successful: The URL you entered was: %s and your GLink is: https://glink.zip/%s', $row['url'],$row['shortlink']);
|
printf('Successful: The URL you entered was: %s and your GLink is: https://glink.zip/%s', $url,$shortlink);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
//printf('Done');
|
//printf('Done');
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
109
signup.html
Normal file
109
signup.html
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-full bg-white">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="output.css">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body class="h-full">
|
||||||
|
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
|
||||||
|
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Sign up for an account</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<form class="space-y-6" action="signup.php" method="GET"> <!--Change to php-->
|
||||||
|
<div>
|
||||||
|
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input id="email" name="email" type="email" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
<div id="email-error" class="hidden mt-2 text-red-800 text-xs">
|
||||||
|
invalid Email
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="password" class="block text-sm font-medium leading-6 text-gray-900">Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 relative block">
|
||||||
|
<input id="password" name="password" type="password" autocomplete="off" required class="block w-11/12 rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
|
||||||
|
<span id="pswd-invisible" class="absolute inset-y-0 right-0 flex items-center px-1 rounded-r-md">
|
||||||
|
<svg class="w-6 h-6 m-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" color="black"
|
||||||
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span id="pswd-visible" class="absolute inset-y-0 right-0 flex items-center px-1 hidden">
|
||||||
|
<svg class="w-6 h-6 m-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p id="domain" class="hidden text-red-800 text-xs">
|
||||||
|
<b>Invalid characters entered</b>
|
||||||
|
</p>
|
||||||
|
<p id="letter" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>lowercase</b> letter
|
||||||
|
</p>
|
||||||
|
<p id="capital" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>capital (uppercase)</b> letter
|
||||||
|
</p>
|
||||||
|
<p id="number" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>number</b>
|
||||||
|
</p>
|
||||||
|
<p id="symbol" class="hidden text-red-800 text-xs">
|
||||||
|
A <b>symbol</b>
|
||||||
|
</p>
|
||||||
|
<p id="length" class="hidden text-red-800 text-xs">
|
||||||
|
Minimum <b>10 characters</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="verify" class="block text-sm font-medium leading-6 text-gray-900">Retype Password</label>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 relative block">
|
||||||
|
<input id="verify" name="verify" type="password" autocomplete="off" required class="block w-11/12 rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6">
|
||||||
|
|
||||||
|
<span id="check-pswd-invisible" class="absolute inset-y-0 right-0 flex items-center px-1 rounded-r-md">
|
||||||
|
<svg class="w-6 h-6 m-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" color="black"
|
||||||
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span id="check-pswd-visible" class="absolute inset-y-0 right-0 flex items-center px-1 hidden">
|
||||||
|
<svg class="w-6 h-6 m-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p id="check-password-error" class="hidden text-red-800 text x-s">
|
||||||
|
Passwords <b>do not</b> match
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Sign up</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="login.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
28
signup.php
Normal file
28
signup.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'db.inc.php';
|
||||||
|
|
||||||
|
$email = $_GET['email'];
|
||||||
|
$email = strval($email);
|
||||||
|
$username = $_GET['username'];
|
||||||
|
$password = $_GET['password'];
|
||||||
|
$id = rand(0,99999999);
|
||||||
|
|
||||||
|
$hash = password_hash($password,PASSWORD_BCRYPT);
|
||||||
|
|
||||||
|
$session = init_cass_db();
|
||||||
|
|
||||||
|
$statement = $session->prepare("SELECT id FROM users WHERE email=? ALLOW FILTERING;");
|
||||||
|
$result = $session->execute($statement, array('arguments' => array($email)));
|
||||||
|
|
||||||
|
if ($result->count() != 0) {
|
||||||
|
echo('The username or email address already exists. Please try another email address.');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$statement = $session->prepare('INSERT INTO users (id,email,username,password_hash) VALUES (?,?,null,?);');
|
||||||
|
$result = $session->execute($statement, array('arguments' => array($id,$email,$hash)));
|
||||||
|
|
||||||
|
echo('Registration successful.');
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
Reference in New Issue
Block a user