mirror of
https://github.com/gamaio/UnPS-Short.git
synced 2024-12-22 18:32:40 +00:00
Add Shortv4-2 files, watered down UnPSAPI, and Bootstrap 3
This commit is contained in:
commit
b674bdb593
113
api/api.backend.php
Normal file
113
api/api.backend.php
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
*
|
||||||
|
* UnPS-API Backend
|
||||||
|
*
|
||||||
|
* Remember to sanitize everything before sending it here!
|
||||||
|
*
|
||||||
|
* ============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
function checkRemoteFile($link){
|
||||||
|
if (@file_get_contents($link)): return true;
|
||||||
|
else: return false;
|
||||||
|
endif;
|
||||||
|
}
|
||||||
|
|
||||||
|
include('hashpass.php');
|
||||||
|
|
||||||
|
class api{
|
||||||
|
// Begin Short
|
||||||
|
function shorten($apidb, $apikey, $sdb, $link, $dpass=null){
|
||||||
|
$apisql = "SELECT * FROM `users` WHERE `key` = '$apikey' LIMIT 1";
|
||||||
|
if(!$result = $apidb->query($apisql)) return 'ERROR: ['.$apidb->error.']';
|
||||||
|
if($row = $result->fetch_assoc()){
|
||||||
|
$canshort = $row['short'];
|
||||||
|
$name = $row['name'];
|
||||||
|
|
||||||
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
|
||||||
|
$apisql = "INSERT INTO `apiuse` (time, name, apikey, ip, type, allowed, misc) VALUES (NOW(), '$name', '$apikey', '$ip', 'Link Shorten', '$canshort', '$link')";
|
||||||
|
if(!$result = $apidb->query($apisql)) return 'ERROR: ['.$apidb->error.']';
|
||||||
|
}
|
||||||
|
if($canshort != 1) return 'You are not authorized to shorten links';
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM `links` WHERE `link` = '$link' LIMIT 1;";
|
||||||
|
if($result = $sdb->query($sql)){
|
||||||
|
if($row = $result->fetch_assoc()){
|
||||||
|
$short = $row['shortlink'];
|
||||||
|
return "Existing link: <a href=\"http://unps.us/?l=$short\" target=\"$short\">http://unps.us/?l=$short</a>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(checkRemoteFile($link) !== true) return "Dead Link: $link";
|
||||||
|
$short = substr(number_format(time() * mt_rand(),0,'',''),0,10);
|
||||||
|
$short = base_convert($short, 10, 36);
|
||||||
|
|
||||||
|
$dpass = substr(number_format(time() * mt_rand(),0,'',''),0,10);
|
||||||
|
$dpass = base_convert($short.$dpass, 10, 36);
|
||||||
|
|
||||||
|
if($dpass != null): $sql = "INSERT INTO `links` (link, shortlink, dpass) VALUES ('$link', '$short', '$dpass')";
|
||||||
|
else: $sql = "INSERT INTO `links` (link, shortlink, dpass) VALUES ('$link', '$short', '$apikey')";
|
||||||
|
endif;
|
||||||
|
|
||||||
|
if($result = $sdb->query($sql)): return "Shortened: <a href=\"http://unps.us/?l=$short\" target=\"$short\">http://unps.us/?l=$short</a><br />Your link deletion password (write this down): $dpass";
|
||||||
|
else: return 'ERROR: ['.$sdb->error.']';
|
||||||
|
endif;
|
||||||
|
}
|
||||||
|
|
||||||
|
function delShort ($apidb, $apikey, $sdb, $link, $dpass=null){
|
||||||
|
$apisql = "SELECT * FROM `users` WHERE `key` = '$apikey' LIMIT 1";
|
||||||
|
if(!$result = $apidb->query($apisql)) return 'ERROR: ['.$apidb->error.']';
|
||||||
|
if($row = $result->fetch_assoc()){
|
||||||
|
$canshort = $row['short'];
|
||||||
|
$name = $row['name'];
|
||||||
|
|
||||||
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
|
||||||
|
$apisql = "INSERT INTO `apiuse` (time, name, apikey, ip, type, allowed, misc) VALUES (NOW(), '$name', '$apikey', '$ip', 'Short Link Delete', '$canshort', '$link')";
|
||||||
|
if(!$result = $apidb->query($apisql)) return 'ERROR: ['.$apidb->error.']';
|
||||||
|
}
|
||||||
|
if($canshort != 1) return 'You are not authorized to delete short links';
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM `links` WHERE `shortlink` = '$link' LIMIT 1;";
|
||||||
|
if($result = $sdb->query($sql)){
|
||||||
|
if($row = $result->fetch_assoc()){
|
||||||
|
$short = $row['shortlink'];
|
||||||
|
$password = $row['dpass'];
|
||||||
|
|
||||||
|
if($dpass != null) $apikey = $dpass;
|
||||||
|
|
||||||
|
if($apikey == $password){
|
||||||
|
$sql = "DELETE FROM `links` WHERE `shortlink` = '$link' AND `dpass` = '$apikey' LIMIT 1;";
|
||||||
|
if(!$result = $sdb->query($sql)) return 'ERROR: ['.$sdb->error.']';
|
||||||
|
echo "Deleted: $link";
|
||||||
|
return;
|
||||||
|
}else{ return "The password doesn't match. Delete $link aborted!"; }
|
||||||
|
}
|
||||||
|
}else{ return 'ERROR: ['.$sdb->error.']'; }
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportLink($apidb, $apikey, $sdb, $link, $reason){
|
||||||
|
$apisql = "SELECT * FROM `users` WHERE `key` = '$apikey' LIMIT 1;";
|
||||||
|
if(!$result = $apidb->query($apisql)) return 'ERROR: ['.$apidb->error.']';
|
||||||
|
if($row = $result->fetch_assoc()){
|
||||||
|
$canshort = $row['short'];
|
||||||
|
$name = $row['name'];
|
||||||
|
|
||||||
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
|
||||||
|
$apisql = "INSERT INTO `apiuse` (time, name, apikey, ip, type, allowed, misc) VALUES (NOW(), '$name', '$apikey', '$ip', 'Report Link', '$canshort', '$link')";
|
||||||
|
if(!$result = $apidb->query($apisql)) return 'ERROR: ['.$apidb->error.']';
|
||||||
|
}
|
||||||
|
if($canshort != 1) return 'You are not authorized to shorten links, meaning you also can\'t report false negatives';
|
||||||
|
|
||||||
|
$sql = "INSERT INTO `manual` (time, apikey, ip, link, reason) VALUES(NOW(), '$apikey', '$ip', '$link', '$reason');";
|
||||||
|
if(!$result = $sdb->query($sql)) return 'ERROR: ['.$sdb->error.']';
|
||||||
|
return "Reported $link. Please check back in a day or two";
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Short
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
11
api/dbsettings.php
Normal file
11
api/dbsettings.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// DBSettings
|
||||||
|
|
||||||
|
$apidb = new mysqli('localhost', 'api', 'password', 'api'); // Connect to main APIDB
|
||||||
|
if($apidb->connect_errno > 0) die('Unable to connect to database [' . $apidb->connect_error . '] - Check dbsettings.php');
|
||||||
|
|
||||||
|
$shortdb = new mysqli('localhost', 'short', 'password', 'short'); // Connect to link shortener DB
|
||||||
|
if($shortdb->connect_errno > 0) die('Unable to connect to database [' . $shortdb->connect_error . '] - Check dbsettings.php');
|
||||||
|
|
||||||
|
?>
|
40
api/hashpass.php
Normal file
40
api/hashpass.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/* HashPass() function takes $plaintext, $salt and $i (number of iterations) as inputs and outputs $hashpass - $salt and $i are optional
|
||||||
|
* Copyright David Todd (C) 2012
|
||||||
|
* http://www.unps-gama.info
|
||||||
|
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
||||||
|
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
|
||||||
|
* If no $salt provided, generate large int and output $hashpass and $salt
|
||||||
|
* If no $i (number of iterations) provided, go through once and return - not as secure as using iterations, but chances are low it will get cracked easily
|
||||||
|
* If no $plaintext provided, die with error message saved to error variable
|
||||||
|
*/
|
||||||
|
|
||||||
|
function hashpass($plaintext, $salt, $i){
|
||||||
|
if($plaintext == null) die("No password given"); // Die with error
|
||||||
|
$plaintext = hash("sha1", $plaintext); // First step - get plaintext sha1
|
||||||
|
if($salt == null || $salt == ''){
|
||||||
|
$salt = mt_rand(10000, 20000); // Generate random number between 1000 and 20000
|
||||||
|
$salt = hash("sha1", $salt); // Get sha1 hash of random number
|
||||||
|
$salt = $salt.mt_rand(5000, 80000); // Append new random number between 5000 and 80000 to md5 salt
|
||||||
|
$salt = hash("sha256", $salt); // Take a sha256 hash of new salt and done with salt generation
|
||||||
|
}
|
||||||
|
if($i == null || $i == ''){
|
||||||
|
$plaintext = hash("sha256", $plaintext.$salt); // Take first sha256 hash of $plaintext+$salt (64 bits)
|
||||||
|
$plaintext = hash("sha1", $salt.$plaintext.$salt); // Take sha1 of salt+plaintext+salt (32 bits)
|
||||||
|
$plaintext = hash("sha512", $salt.$plaintext.$salt.$salt.$plaintext.$salt); // Take sha512 of this (128bits)
|
||||||
|
$hashpass = hash("sha256", $plaintext); // final hash is sha256 of the sha512 above (back down to 64bits)
|
||||||
|
return $hashpass."/".$salt; // Give calling script the hashed password and salt, seperate strings with "/" to be exploded into array later
|
||||||
|
}else{
|
||||||
|
$il = '';
|
||||||
|
while($il < $i && $il <= 50){
|
||||||
|
$plaintext = hash("sha256", $plaintext.$salt); // Take first sha256 hash of $plaintext+$salt (64 bits)
|
||||||
|
$plaintext = hash("sha1", $salt.$plaintext.$salt); // Take sha1 of salt+plaintext+salt (32 bits)
|
||||||
|
$plaintext = hash("sha512", $salt.$plaintext.$salt.$salt.$plaintext.$salt); // Take sha512 of this (128bits)
|
||||||
|
$il++;
|
||||||
|
//echo "Iteration: $il Password: $plaintext\r\n";
|
||||||
|
}
|
||||||
|
$hashpass = hash("sha256", $plaintext); // final hash is sha256 of the sha512 above (back down to 64bits)
|
||||||
|
return $hashpass."/".$salt; // Give calling script the hashed password and salt, seperate strings with "/" to be exploded into array later
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
4845
assets/bootstrap/css/bootstrap.css
vendored
Normal file
4845
assets/bootstrap/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
assets/bootstrap/css/bootstrap.min.css
vendored
Normal file
9
assets/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1988
assets/bootstrap/js/bootstrap.js
vendored
Normal file
1988
assets/bootstrap/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
assets/bootstrap/js/bootstrap.min.js
vendored
Normal file
6
assets/bootstrap/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
197
assets/css/elements.css
Normal file
197
assets/css/elements.css
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
.hidden { display: none; }
|
||||||
|
.unhidden { display: block; }
|
||||||
|
|
||||||
|
body{
|
||||||
|
line-height:1;
|
||||||
|
font-family:"Lucida Grande", Arial, Helvetica, Sans-Serif;
|
||||||
|
background-color: #434C56;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-wrapper {
|
||||||
|
position: relative;
|
||||||
|
z-index: 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav a{
|
||||||
|
-webkit-transition: all 0.30s ease-in-out;
|
||||||
|
-moz-transition: all 0.30s ease-in-out;
|
||||||
|
-ms-transition: all 0.30s ease-in-out;
|
||||||
|
-o-transition: all 0.30s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav a:hover{
|
||||||
|
background-color: #000;
|
||||||
|
color: #248;
|
||||||
|
webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 15px rgba(94, 125, 142, 0.9) !important;
|
||||||
|
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 15px rgba(94, 125, 142, 0.9) !important;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 15px rgba(94, 125, 142, 0.9) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set widths on the navbar form inputs since otherwise they're 100% wide */
|
||||||
|
.navbar-form input[type="text"], .navbar-form input[type="password"] {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu{
|
||||||
|
opacity: 0.9;
|
||||||
|
background-color: rgb(94, 125, 142);
|
||||||
|
filter: alpha(opacity=90);
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-pic{
|
||||||
|
max-height: 20px;
|
||||||
|
max-width: 20px;
|
||||||
|
border-radius: 20%;
|
||||||
|
-webkit-border-radius: 20%;
|
||||||
|
-moz-border-radius: 20%;
|
||||||
|
box-shadow: 0 0 8px rgba(0, 0, 0, .8);
|
||||||
|
-webkit-box-shadow: 0 0 8px rgba(0, 0, 0, .8);
|
||||||
|
-moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#uname-dropdown{
|
||||||
|
color: rgb(96, 123, 152);
|
||||||
|
}
|
||||||
|
|
||||||
|
#uname-dropdown:hover{
|
||||||
|
color: rgb(152, 123, 96);
|
||||||
|
}
|
||||||
|
|
||||||
|
#logout-link:hover{
|
||||||
|
color: red;
|
||||||
|
box-shadow: 0 0 8px rgba(0, 0, 0, .8);
|
||||||
|
-webkit-box-shadow: 0 0 8px rgba(0, 0, 0, .8);
|
||||||
|
-moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrap {
|
||||||
|
min-height: 100%;
|
||||||
|
height: auto !important;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto -46px;
|
||||||
|
padding: 0 0 46px;
|
||||||
|
background-image: -ms-linear-gradient(top, #3a3f44 0%, #434C56 100%);
|
||||||
|
background-image: -moz-linear-gradient(top, #3a3f44 0%, #434C56 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #3a3f44 0%, #434C56 100%);
|
||||||
|
background-image: -webkit-linear-gradient(top, #3a3f44 0%, #434C56 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#note{
|
||||||
|
color: #eee;
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 4px;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten {
|
||||||
|
max-width: 600px;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten .form-shorten-heading{
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten .radio-center .btn{
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten input[type="text"], .form-shorten textarea{
|
||||||
|
position: relative;
|
||||||
|
font-size: 14px;
|
||||||
|
height: auto;
|
||||||
|
padding: 7px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten input[type="text"]:focus,{
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten input[type="text"], .form-shorten textarea{
|
||||||
|
margin-bottom: -1px;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten .radio-center input[type="radio"]:hover{
|
||||||
|
color:#200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-shorten .btn-primary{
|
||||||
|
background-color: #333;
|
||||||
|
border: 1px solid #444;
|
||||||
|
-webkit-transition: all 0.30s ease-in-out;
|
||||||
|
-moz-transition: all 0.30s ease-in-out;
|
||||||
|
-ms-transition: all 0.30s ease-in-out;
|
||||||
|
-o-transition: all 0.30s ease-in-out;
|
||||||
|
}
|
||||||
|
.form-shorten .btn-primary:hover{
|
||||||
|
background-color: #3c6190;
|
||||||
|
border: 1px solid rgba(81, 203, 238, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#message{
|
||||||
|
float: center;
|
||||||
|
text-align: center;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
height: 46px;
|
||||||
|
background-color: #333;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
#footer {
|
||||||
|
margin-left: -17px;
|
||||||
|
margin-right: -20px;
|
||||||
|
padding-left: 17px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy-link, #tos-link, #reg-link{
|
||||||
|
float: right;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#privacy-link:hover, #tos-link:hover, #reg-link:hover{
|
||||||
|
-webkit-box-shadow: 0 8px 6px -6px rgba(94, 125, 142, 0.9);
|
||||||
|
-moz-box-shadow: 0 8px 6px -6px rgba(94, 125, 142, 0.9);
|
||||||
|
box-shadow: 0 8px 6px -6px rgba(94, 125, 142, 0.9);
|
||||||
|
-webkit-transition: all 0.90s ease-in-out;
|
||||||
|
-moz-transition: all 0.90s ease-in-out;
|
||||||
|
-ms-transition: all 0.90s ease-in-out;
|
||||||
|
-o-transition: all 0.90s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text], textarea {
|
||||||
|
-webkit-transition: all 0.30s ease-in-out;
|
||||||
|
-moz-transition: all 0.30s ease-in-out;
|
||||||
|
-ms-transition: all 0.30s ease-in-out;
|
||||||
|
-o-transition: all 0.30s ease-in-out;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text]:focus, textarea:focus {
|
||||||
|
box-shadow: 0 0 5px rgba(81, 203, 238, 1);
|
||||||
|
border: 1px solid rgba(81, 203, 238, 1);
|
||||||
|
padding: 6px 0px 6px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
background: -webkit-linear-gradient(#eee, #aaa);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
83
assets/css/jquery.countdown.css
Normal file
83
assets/css/jquery.countdown.css
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
.countdownHolder{
|
||||||
|
width:450px;
|
||||||
|
margin:0 auto;
|
||||||
|
font: 40px/1.5 'Open Sans Condensed',sans-serif;
|
||||||
|
text-align:center;
|
||||||
|
letter-spacing:-3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position{
|
||||||
|
display: inline-block;
|
||||||
|
height: 1.6em;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
width: 1.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.digit{
|
||||||
|
position:absolute;
|
||||||
|
display:block;
|
||||||
|
width:1em;
|
||||||
|
background-color:#444;
|
||||||
|
border-radius:0.2em;
|
||||||
|
text-align:center;
|
||||||
|
color:#fff;
|
||||||
|
letter-spacing:-1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.digit.static{
|
||||||
|
box-shadow:1px 1px 1px rgba(4, 4, 4, 0.35);
|
||||||
|
|
||||||
|
background-image: linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
|
||||||
|
background-image: -o-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
|
||||||
|
background-image: -moz-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
|
||||||
|
background-image: -webkit-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
|
||||||
|
background-image: -ms-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
|
||||||
|
|
||||||
|
background-image: -webkit-gradient(
|
||||||
|
linear,
|
||||||
|
left bottom,
|
||||||
|
left top,
|
||||||
|
color-stop(0.5, #3A3A3A),
|
||||||
|
color-stop(0.5, #444444)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You can use these classes to hide parts
|
||||||
|
* of the countdown that you don't need.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.countDays{ /* display:none !important;*/ }
|
||||||
|
.countDiv0{ /* display:none !important;*/ }
|
||||||
|
.countHours{}
|
||||||
|
.countDiv1{}
|
||||||
|
.countMinutes{}
|
||||||
|
.countDiv2{}
|
||||||
|
.countSeconds{}
|
||||||
|
|
||||||
|
|
||||||
|
.countDiv{
|
||||||
|
display:inline-block;
|
||||||
|
width:16px;
|
||||||
|
height:1.6em;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countDiv:before,
|
||||||
|
.countDiv:after{
|
||||||
|
position:absolute;
|
||||||
|
width:5px;
|
||||||
|
height:5px;
|
||||||
|
background-color:#444;
|
||||||
|
border-radius:50%;
|
||||||
|
left:50%;
|
||||||
|
margin-left:-3px;
|
||||||
|
top:0.5em;
|
||||||
|
box-shadow:1px 1px 1px rgba(4, 4, 4, 0.5);
|
||||||
|
content:'';
|
||||||
|
}
|
||||||
|
|
||||||
|
.countDiv:after{
|
||||||
|
top:0.9em;
|
||||||
|
}
|
138
assets/js/jquery.countdown.js
Normal file
138
assets/js/jquery.countdown.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/**
|
||||||
|
* @name jQuery Countdown Plugin
|
||||||
|
* @author Martin Angelov
|
||||||
|
* @version 1.0
|
||||||
|
* @url http://tutorialzine.com/2011/12/countdown-jquery/
|
||||||
|
* @license MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($){
|
||||||
|
|
||||||
|
// Number of seconds in every time division
|
||||||
|
var days = 24*60*60,
|
||||||
|
hours = 60*60,
|
||||||
|
minutes = 60;
|
||||||
|
|
||||||
|
// Creating the plugin
|
||||||
|
$.fn.countdown = function(prop){
|
||||||
|
|
||||||
|
var options = $.extend({
|
||||||
|
callback : function(){},
|
||||||
|
timestamp : 0
|
||||||
|
},prop);
|
||||||
|
|
||||||
|
var left, d, h, m, s, positions;
|
||||||
|
|
||||||
|
// Initialize the plugin
|
||||||
|
init(this, options);
|
||||||
|
|
||||||
|
positions = this.find('.position');
|
||||||
|
|
||||||
|
(function tick(){
|
||||||
|
|
||||||
|
// Time left
|
||||||
|
left = Math.floor((options.timestamp - (new Date())) / 1000);
|
||||||
|
|
||||||
|
if(left < 0){
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of days left
|
||||||
|
d = Math.floor(left / days);
|
||||||
|
updateDuo(0, 1, d);
|
||||||
|
left -= d*days;
|
||||||
|
|
||||||
|
// Number of hours left
|
||||||
|
h = Math.floor(left / hours);
|
||||||
|
updateDuo(2, 3, h);
|
||||||
|
left -= h*hours;
|
||||||
|
|
||||||
|
// Number of minutes left
|
||||||
|
m = Math.floor(left / minutes);
|
||||||
|
updateDuo(4, 5, m);
|
||||||
|
left -= m*minutes;
|
||||||
|
|
||||||
|
// Number of seconds left
|
||||||
|
s = left;
|
||||||
|
updateDuo(6, 7, s);
|
||||||
|
|
||||||
|
// Calling an optional user supplied callback
|
||||||
|
options.callback(d, h, m, s);
|
||||||
|
|
||||||
|
// Scheduling another call of this function in 1s
|
||||||
|
setTimeout(tick, 1000);
|
||||||
|
})();
|
||||||
|
|
||||||
|
// This function updates two digit positions at once
|
||||||
|
function updateDuo(minor,major,value){
|
||||||
|
switchDigit(positions.eq(minor),Math.floor(value/10)%10);
|
||||||
|
switchDigit(positions.eq(major),value%10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function init(elem, options){
|
||||||
|
elem.addClass('countdownHolder');
|
||||||
|
|
||||||
|
// Creating the markup inside the container
|
||||||
|
$.each(['Days','Hours','Minutes','Seconds'],function(i){
|
||||||
|
$('<span class="count'+this+'">').html(
|
||||||
|
'<span class="position">\
|
||||||
|
<span class="digit static">0</span>\
|
||||||
|
</span>\
|
||||||
|
<span class="position">\
|
||||||
|
<span class="digit static">0</span>\
|
||||||
|
</span>'
|
||||||
|
).appendTo(elem);
|
||||||
|
|
||||||
|
if(this!="Seconds"){
|
||||||
|
elem.append('<span class="countDiv countDiv'+i+'"></span>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an animated transition between the two numbers
|
||||||
|
function switchDigit(position,number){
|
||||||
|
|
||||||
|
var digit = position.find('.digit')
|
||||||
|
|
||||||
|
if(digit.is(':animated')){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(position.data('digit') == number){
|
||||||
|
// We are already showing this number
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
position.data('digit', number);
|
||||||
|
|
||||||
|
var replacement = $('<span>',{
|
||||||
|
'class':'digit',
|
||||||
|
css:{
|
||||||
|
top:'-2.1em',
|
||||||
|
opacity:0
|
||||||
|
},
|
||||||
|
html:number
|
||||||
|
});
|
||||||
|
|
||||||
|
// The .static class is added when the animation
|
||||||
|
// completes. This makes it run smoother.
|
||||||
|
|
||||||
|
digit
|
||||||
|
.before(replacement)
|
||||||
|
.removeClass('static')
|
||||||
|
.animate({top:'2.5em',opacity:0},'fast',function(){
|
||||||
|
digit.remove();
|
||||||
|
})
|
||||||
|
|
||||||
|
replacement
|
||||||
|
.delay(100)
|
||||||
|
.animate({top:0,opacity:1},'fast',function(){
|
||||||
|
replacement.addClass('static');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})(jQuery);
|
19
assets/js/main.countdown.js
Normal file
19
assets/js/main.countdown.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
$(function(){
|
||||||
|
var note = $('#note'),
|
||||||
|
ts = new Date(2013, 7, 20, 12, 30);
|
||||||
|
|
||||||
|
$('#countdown').countdown({
|
||||||
|
timestamp : ts,
|
||||||
|
callback : function(days, hours, minutes, seconds){
|
||||||
|
var message = "";
|
||||||
|
message += days + " day" + ( days==1 ? '':'s' ) + ", ";
|
||||||
|
message += hours + " hour" + ( hours==1 ? '':'s' ) + ", ";
|
||||||
|
message += minutes + " minute" + ( minutes==1 ? '':'s' ) + " and ";
|
||||||
|
message += seconds + " second" + ( seconds==1 ? '':'s' ) + " <br />";
|
||||||
|
message += "Until the relaunch of <a href=\"http://unps.us\">UnPS.US</a>";
|
||||||
|
|
||||||
|
note.html(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
205
index.php
Normal file
205
index.php
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
<?php
|
||||||
|
// session_start(); // - Disabled for now because the user system isn't ready -
|
||||||
|
|
||||||
|
if(!empty($_GET['l'])){
|
||||||
|
include('api/dbsettings.php');
|
||||||
|
$link = $shortdb->real_escape_string(strtolower(stripslashes(strip_tags($_GET['l']))));
|
||||||
|
$sql = "SELECT * FROM `links` WHERE `shortlink` = '$link' LIMIT 1;";
|
||||||
|
if($result = $shortdb->query($sql)){
|
||||||
|
if($row = $result->fetch_assoc()){
|
||||||
|
$link = $row['link'];
|
||||||
|
header("location:$link");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function userpic($email){
|
||||||
|
$default = "http://fox.gy/fCDIjceUvkk.png";
|
||||||
|
$size = 20;
|
||||||
|
$grav_url = "http://www.gravatar.com/avatar/".md5(strtolower(trim($email)))."?d=".urlencode($default)."&s=".$size;
|
||||||
|
return $grav_url;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>UnPS Link Shortener</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
||||||
|
<meta name="description" content="UnPS Link Shortener"/>
|
||||||
|
<meta name="keywords" content="UnPS, GAMA, Shorten, Link"/>
|
||||||
|
<meta name="author" content="David Todd"/>
|
||||||
|
|
||||||
|
<link href="assets/bootstrap/css/bootstrap.css" rel="stylesheet" media="screen" />
|
||||||
|
<link href="assets/css/elements.css?<?php echo time(); ?>" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300" />
|
||||||
|
<link rel="stylesheet" href="assets/css/jquery.countdown.css" />
|
||||||
|
<link rel="shortcut icon" type="image/ico" href="favicon.ico"/>
|
||||||
|
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrap">
|
||||||
|
<div class="navbar-wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar navbar-inverse navbar-static-top">
|
||||||
|
<div class="container">
|
||||||
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<div class="nav-collapse collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a class="active" href="http://unps-gama.info/about.php#logo"><img src="favicon.ico" style="max-height:20px;"></a></li>
|
||||||
|
<li><a class="active" href="http://unps-gama.info">Home</a></li>
|
||||||
|
<li><a href="http://unps-gama.info/about.php">About</a></li>
|
||||||
|
<li><a href="http://unps-gama.info/contact.php">Contact</a></li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Services <b class="caret"></b></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="http://img.unps-gama.info">Image Host</a></li>
|
||||||
|
<li><a href="http://unps.us">Link Shortener</a></li>
|
||||||
|
<li><a href="http://api.unps.us">UnPS-API</a></li>
|
||||||
|
<li><a href="http://b.unps.us">Site Blog</a></li>
|
||||||
|
<li><a href="https://twitter.com/UnPSDashGAMA">UnPS Twitter</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li class="nav-header">Programming Work</li>
|
||||||
|
<li><a href="https://github.com/alopexc0de">GitHub</a></li>
|
||||||
|
<li><a href="https://bitbucket.org/alopexc0de">Bitbucket</a></li>
|
||||||
|
<li><a href="http://p.unps.us">Projects</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Friends <b class="caret"></b></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li class="nav-header"> c0de</li>
|
||||||
|
<li><a href="http://c0de.unps.us">Personal Blog</a></li>
|
||||||
|
<li><a href="https://facebook.com/alopexc0de">Facebook</a></li>
|
||||||
|
<li><a href="skype:alopexlagopus-c0de?chat">C0de's Skype</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li class="nav-header"> Hosted Sites</li>
|
||||||
|
<li><a href="http://haruka.unps-gama.info">Haruka's Blog</a></li>
|
||||||
|
<li><a href="http://kitsu.unps-gama.info">Kitsu's Stuff</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li class="nav-header"> Other Friends</li>
|
||||||
|
<li><a href="http://mc.doridian.de">Our Amazing Server Host</a></li>
|
||||||
|
<li><a href="http://furcast.fm">Awesome Furry Talk Show</a></li>
|
||||||
|
<li><a href="http://leonfox.net">Networking Guru</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<!-- User area -->
|
||||||
|
<?php if(isset($_SESSION['uname'])){ ?>
|
||||||
|
<ul class="nav navbar-nav" style="float:right;">
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" id="uname-dropdown" data-toggle="dropdown"><img id="profile-pic" src="<?php echo userpic($_SESSION['email']); ?>" alt="User gravatar image" /> <?php echo $_SESSION['uname'] ?> <b class="caret"></b></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li><a href="http://unps-gama.info/account.php">Account</a></li>
|
||||||
|
<li><a href="http://unps-gama.info/friends.php">Friends</a></li>
|
||||||
|
<li><a href="http://unps-gama.info/stats.php?all">Stats</a></li>
|
||||||
|
<li><a href="http://unps-gama.info/stats.php?links">Short Links</a></li>
|
||||||
|
<li><a href="http://unps-gama.info/stats.php?pics">Uploaded Pictures</a></li>
|
||||||
|
<li><a id="logout-link" href="http://unps-gama.info/signout.php">Sign Out</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<?php }else{ ?>
|
||||||
|
<form class="navbar-form form-inline pull-right" action="http://unps-gama.info/login.php" method="post">
|
||||||
|
<input type="text" placeholder="Email" class="form-control">
|
||||||
|
<input type="password" placeholder="Password" class="form-control">
|
||||||
|
<button type="submit" class="btn" disabled="disabled">Sign in</button>
|
||||||
|
</form>
|
||||||
|
<?php } ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container" style="float:center;">
|
||||||
|
<div id="countdown"></div>
|
||||||
|
|
||||||
|
<div id="note"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<form class="form-shorten" id="form-shorten">
|
||||||
|
<h2 class="form-shorten-heading">Please give me a link to shorten...</h2>
|
||||||
|
<input type="text" id="link" class="form-control" name="link" placeholder="http://" autofocus>
|
||||||
|
<div id="shorten-password">
|
||||||
|
<input type="text" id="pass" class="form-control" name="password" placeholder="Password" autofocus>
|
||||||
|
</div>
|
||||||
|
<div id="report-details">
|
||||||
|
<textarea name="report-details" id="report" class="form-control" placeholder="Reason for reporting this link"></textarea>
|
||||||
|
</div>
|
||||||
|
<div id="radio-center" style="padding-left:16%;">
|
||||||
|
<label class="btn" style="color:#eee;"><input type="radio" id="shorten" name="linkmod" value="shorten" checked="checked">Shorten Link</label>
|
||||||
|
<label class="btn" style="color:#eee;"><input type="radio" id="dellink" name="linkmod" value="dellink">Delete Link</label>
|
||||||
|
<label class="btn" style="color:#eee;"><input type="radio" id="replink" name="linkmod" value="replink">Report Link</label>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary btn-block" id="short-button" type="submit">Shorten</button>
|
||||||
|
</form>
|
||||||
|
<div id="message">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" style="position:fixed; width:100%; padding:5px; bottom:7px; ">
|
||||||
|
<div class="container">
|
||||||
|
<br /><p class="text-muted credit">
|
||||||
|
Copyright © 2012-2013 UnPS-GAMATechnologies - <a href="http://getbootstrap.com/">Bootstrap</a> is © 2013 Twitter Inc.
|
||||||
|
<a id="privacy-link" href="http://unps-gama.info/privacy.php">Privacy Policy</a> <a id="tos-link" href="http://unps-gama.info/terms.php">Terms Of Service</a> <?php if(!isset($_SESSION['uname'])){ ?><a id="reg-link" href="http://unps-gama.info/register.php">Register</a> <?php } ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Load the JS after the DOM so speed up load times -->
|
||||||
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
|
||||||
|
<script src="assets/js/jquery.countdown.js"></script>
|
||||||
|
<script src="assets/js/main.countdown.js"></script>
|
||||||
|
<script src="assets/bootstrap/js/bootstrap.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
jQuery(document).ready(function(){
|
||||||
|
// When the page loads, we're gonna want to hide the shorten-password and report-details elements
|
||||||
|
$("#shorten-password").slideUp("slow");
|
||||||
|
$("#report-details").slideUp("slow");
|
||||||
|
});
|
||||||
|
$(function() { // Fairly messy. Changes submit button based on radio button and shows/hides shorten-password and report-details elements
|
||||||
|
$("input[type=radio]").on('click', function(){
|
||||||
|
if($('#shorten').is(':checked')){
|
||||||
|
$("#short-button").html('Shorten');
|
||||||
|
$("#report").val('');
|
||||||
|
$("#pass").val('');
|
||||||
|
}
|
||||||
|
if ($('#dellink').is(':checked')){
|
||||||
|
$("#shorten-password").slideDown("slow");
|
||||||
|
$("#short-button").html('Delete');
|
||||||
|
$("#report").val('');
|
||||||
|
}else{
|
||||||
|
$("#shorten-password").slideUp("slow");
|
||||||
|
}
|
||||||
|
if($('#replink').is(':checked')){
|
||||||
|
$("#report-details").slideDown("slow");
|
||||||
|
$("#short-button").html('Report');
|
||||||
|
$("#pass").val('');
|
||||||
|
}else{
|
||||||
|
$("#report-details").slideUp("slow");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// This is our AJAX - Thank you Wizzy <3
|
||||||
|
$("#form-shorten").submit(function(event){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
$.post("process.php", $(this).serialize(), function(data){
|
||||||
|
$("#message").html(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
44
process.php
Normal file
44
process.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require('api/api.backend.php');
|
||||||
|
require('api/dbsettings.php');
|
||||||
|
|
||||||
|
$key = '9a211e90b0a0570ed33e47428231e702af47b6f54fb347960f661184e063a1d0'; // KEEP THIS PRIVATE! This is the only thing that authenticates the application
|
||||||
|
|
||||||
|
function sanitize($input){
|
||||||
|
if ($input == null) die("Sanatize() - No Input Provided, Aborting\r\n<br>");
|
||||||
|
include('api/dbsettings.php');
|
||||||
|
$output = strip_tags($input);
|
||||||
|
$output = stripslashes($output);
|
||||||
|
$output = $apidb->real_escape_string($output);
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
$unpsAPI = new api();
|
||||||
|
|
||||||
|
if(!empty($_POST['link']) && !empty($_POST['linkmod'])){
|
||||||
|
switch ($_POST['linkmod']){
|
||||||
|
case "shorten":
|
||||||
|
$short = sanitize($_POST['link']);
|
||||||
|
echo $unpsAPI->shorten($apidb, $key, $shortdb, $short);
|
||||||
|
break;
|
||||||
|
case "dellink":
|
||||||
|
if(empty($_POST['password'])) die("Something went wrong somewhere, but there's no password here");
|
||||||
|
$link = sanitize($_POST['link']);
|
||||||
|
$password = sanitize($_POST['password']);
|
||||||
|
$link = explode("=", $link);
|
||||||
|
$link = $link[1];
|
||||||
|
echo $unpsAPI->delShort($apidb, $key, $shortdb, $link, $password);
|
||||||
|
break;
|
||||||
|
case "replink":
|
||||||
|
if(empty($_POST['report-details'])) die("Something went wrong somewhere, but I can't find the reason for reporting this link");
|
||||||
|
$link = sanitize($_POST['link']);
|
||||||
|
$details = sanitize($_POST['report-details']);
|
||||||
|
echo $unpsAPI->reportLink($apidb, $key, $shortdb, $link, $details);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("I don't know what you want to do... [-Check linkmod-]");
|
||||||
|
}
|
||||||
|
}else{ die("I can't do my job if I'm not given a link to work on..."); }
|
||||||
|
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user