inital commit

This commit is contained in:
2023-07-09 02:03:41 +02:00
commit 069a211528
9 changed files with 301 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
# ignore accidentally generated vendor directory and composer.lock file, just in case...
/vendor/
/composer.lock
# Ignore personal config file
config.php

17
composer.json Normal file
View File

@@ -0,0 +1,17 @@
{
"name": "brammp/basic-external-unifi-portal",
"description": "Basic Unifi Portal",
"type": "project",
"require": {
"art-of-wifi/unifi-api-client": "^1.1"
},
"license": [
"Unlicense"
],
"authors": [
{
"name": "brammp",
"email": "bram@bprieshof.nl"
}
]
}

8
config.example.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
//Unifi Config
define('controllerUser','UserName');
define('controllerPassword','Password');
define('controllerUrl','https://<unifiIP>:8443');
define('controllerValidateSSL',false);
define('siteId','default');
define('controllerVersion','7.4.156');

57
public/auth.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
//Load Post data in to variables
$accesCode = htmlspecialchars(trim($_POST['accesCode']));
$clientMac = htmlspecialchars(trim($_POST['clientMac']));
$apMac = htmlspecialchars(trim($_POST['apMac']));
//Check if request is (Prevent direct acces)
if ($_SERVER['REQUEST_METHOD'] !== 'POST' ) {
http_response_code(405);
return;
}
//Check if all neded data is present (Prevent direct acces)
if ( empty($accesCode) || empty($clientMac) || empty($apMac)) {
http_response_code(400);
return;
}
//Dummy sleep for testing loader
//sleep(5);
//LoadConfig
require_once __DIR__ . '/../config.php';
//Check acces code
if ($accesCode == 'ABC') {
$downloadSpeed = 5000;
$uploadSpeed = 5000;
}elseif ($accesCode == '123') {
$downloadSpeed = null;
$uploadSpeed = null;
}else{
echo 'Incorrect accesCode';
http_response_code(403);
return;
}
//load the class using the composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
//Initialize the UniFi API connection class and log in
$unifi_connection = new UniFi_API\Client(controllerUser, controllerPassword, controllerUrl, siteId, controllerVersion, controllerValidateSSL);
$login = $unifi_connection->login();
// authorize_guest Params: DeviceMac ExpireTime(Minutes) UploadSpeedLimit DownloadSpeedLimit DataCap ApMac
//Send AuthRequest
$auth_result = $unifi_connection->authorize_guest($clientMac, '2000', $uploadSpeed, $downloadSpeed, null, $apMac);
//Check if unsucsessfull
if ($auth_result == false) {
http_response_code(500);
}
//provide feedback in json format
//error_log (json_encode($auth_result, JSON_PRETTY_PRINT));

110
public/css/style.css Normal file
View File

@@ -0,0 +1,110 @@
.loginPage {
padding: 8% 0 0;
margin: auto;
max-width: 600px
}
.form {
position: relative;
z-index: 1;
background: #FFFFFF;
margin: 0 auto 100px;
padding: 45px;
text-align: center;
border-radius: 20px;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
.form input {
border-radius: 5px;
outline: 0;
background: #f2f2f2;
width: 100%;
border: 0;
margin: 0 0 15px;
padding: 20px;
box-sizing: border-box;
font-size: 18px;
}
.button {
position: relative;
outline: 0;
background: #0081ff;
width: 100%;
border: 0;
padding: 15px;
color: #FFFFFF;
border-radius: 50px;
font-size: 20px;
-webkit-transition: all 0.3 ease;
transition: all 0.3 ease;
cursor: pointer;
}
.button:hover,.button:active,button:focus {
background: #0000ff;
}
.button:disabled {
background: gray;
}
.buttonText {
color: #ffffff;
transition: all 0.2s;
}
.buttonLoading .buttonText {
visibility: hidden;
opacity: 0;
}
.buttonLoading::after {
content: "";
position: absolute;
width: 20px;
height: 20px;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border: 4px solid transparent;
border-top-color: #ffffff;
border-radius: 50%;
animation: button-loading-spinner 1s linear infinite;
}
@keyframes button-loading-spinner {
from {
transform: rotate(0turn);
}
to {
transform: rotate(1turn);
}
}
#responseMessage {
color: red;
font-weight: bold;
}
body {
background: #090979; /* fallback for old browsers */
background: rgb(9,9,121);
background: linear-gradient(90deg, rgba(0,129,255,100) 0%, rgba(9,9,121,1) 50%);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
@media only screen and (max-width: 1000px), only screen and (max-device-width: 1000px){
.button {
font-size: 40px;
}
.form input, body {
font-size: 35px;
}
.buttonLoading::after {
width: 40px;
height: 40px;
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

35
public/index.php Normal file
View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<!--SRC: https://codepen.io/colorlib/pen/rxddKy-->
<html>
<head>
<title>Portal</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="loginPage">
<?php
if (array_key_exists('id', $_GET) && array_key_exists('ap', $_GET)) {
// URL parameter exists
echo "
<div class='form' onsubmit='submitFormAjax();return false'>
<h1>Welcome</h1>
<p>Connecting to:" . htmlspecialchars(trim($_GET['ssid'])) ."</p>
<p id='responseMessage'></p>
<form class='login-form' id='login-from' enctype='multipart/form-data'>
<input id='accesCode' type='password' placeholder='Acces code' onkeyup='inputEntry()'>
<input type='hidden' id='apMac' name='apmac' value='" . htmlspecialchars(trim($_GET['ap'])) . "' />
<input type='hidden' id='clientMac' name='clientmac' value='" . htmlspecialchars(trim($_GET['id'])) . "' />
<input type='hidden' id='redirectURL' name='redirecturl' value='" . htmlspecialchars(trim($_GET['url'])) . "' />
</form>
<button type='button' class='button' id='submitButton' onclick='submitFormAjax()' disabled='true'><span class='buttonText' id='buttonText'>Connect</span></button>
<script src='js/app.js'></script>
</div>";
} else {
// URL parameter does not exist
echo '<div class="form"><h1>Something went wrong</h1></div>';
http_response_code(400);
}
?>
</div>
</body>
</html>

69
public/js/app.js Normal file
View File

@@ -0,0 +1,69 @@
// Retrieving the form data
var accesCode = document.getElementById("accesCode");
var submitButton = document.getElementById("submitButton");
var responseMessage = document.getElementById("responseMessage")
var redirectURL = document.getElementById("redirectURL").value
//var redirectURL = "https://Domain.tld/page"
var buttonLocked = false
function submitFormAjax() {
if (buttonLocked === true){return};
buttonLocked = true
responseMessage.innerHTML = ""
submitButton.classList.add("buttonLoading");
if(accesCode == ""){
responseMessage.innerHTML = "<p>Please enter your accesCode.</p>";
return;
}
submitButton.disabled = true;
accesCode.disabled = true;
var xmlhttp = new XMLHttpRequest();
// Instantiating the request object
xmlhttp.open("POST", "auth.php", true);
// Defining event listener for readystatechange event
xmlhttp.onreadystatechange = function() {
console.log(this.readyState + " status:" + this.status)
if (this.readyState === 4 && this.status === 200) {
submitButton.classList.remove("buttonLoading");
submitButton.style.backgroundColor = "green";
document.getElementById("buttonText").innerHTML = "Connected"
accesCode.style.display = "none";
window.setTimeout(redirectUser, 1500);
}else {
if (this.readyState === 4 && this.status === 403) {
responseMessage.innerHTML = "Acces code incorrect";
enableButton()
} else if (this.readyState === 4) {
responseMessage.innerHTML = "Something went wrong";
enableButton()
}
}
}
//console.log (document.getElementById("accesCode").value);
var params = "accesCode=" + encodeURIComponent(accesCode.value) + "&apMac=" + encodeURIComponent(document.getElementById("apMac").value) + "&clientMac=" + encodeURIComponent(document.getElementById("clientMac").value);
//Setting headers
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Sending the request to the server
xmlhttp.send(params);
}
function enableButton(){
buttonLocked = false
submitButton.disabled = false;
accesCode.disabled = false;
submitButton.classList.remove("buttonLoading");
accesCode.focus();
}
function inputEntry(){
if(accesCode.value != "")
submitButton.disabled = false;
else
submitButton.disabled = true;
}
function redirectUser(){
window.location.href = redirectURL
}

BIN
public/js/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB