Initial prototype

This commit is contained in:
Maximilian Giller 2021-02-18 14:03:59 +01:00
parent 1d33b4b03d
commit 17be6ea3fd
8 changed files with 869 additions and 0 deletions

1
.gitignore vendored
View file

@ -29,3 +29,4 @@ graphics
.vscode
juggl-vue/package-lock.json
package-lock.json
public/api/vendor/

5
public/api/composer.json Normal file
View file

@ -0,0 +1,5 @@
{
"require": {
"tonyhhyip/sse": "^2.1"
}
}

678
public/api/composer.lock generated Normal file
View file

@ -0,0 +1,678 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "361f9482844d6c22d6efec567d317681",
"packages": [
{
"name": "symfony/deprecation-contracts",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665",
"reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-09-07T11:33:47+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v4.4.19",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "8888741b633f6c3d1e572b7735ad2cae3e03f9c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/8888741b633f6c3d1e572b7735ad2cae3e03f9c5",
"reference": "8888741b633f6c3d1e572b7735ad2cae3e03f9c5",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"symfony/mime": "^4.3|^5.0",
"symfony/polyfill-mbstring": "~1.1",
"symfony/polyfill-php80": "^1.15"
},
"require-dev": {
"predis/predis": "~1.0",
"symfony/expression-language": "^3.4|^4.0|^5.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-27T09:09:26+00:00"
},
{
"name": "symfony/mime",
"version": "v5.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "7dee6a43493f39b51ff6c5bb2bd576fe40a76c86"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/7dee6a43493f39b51ff6c5bb2bd576fe40a76c86",
"reference": "7dee6a43493f39b51ff6c5bb2bd576fe40a76c86",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0",
"symfony/polyfill-php80": "^1.15"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.2.2",
"phpdocumentor/type-resolver": "<1.4.0",
"symfony/mailer": "<4.4"
},
"require-dev": {
"egulias/email-validator": "^2.1.10",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/property-access": "^4.4|^5.1",
"symfony/property-info": "^4.4|^5.1",
"symfony/serializer": "^5.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Mime\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Allows manipulating MIME messages",
"homepage": "https://symfony.com",
"keywords": [
"mime",
"mime-type"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-02-02T06:10:15+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "2d63434d922daf7da8dd863e7907e67ee3031483"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483",
"reference": "2d63434d922daf7da8dd863e7907e67ee3031483",
"shasum": ""
},
"require": {
"php": ">=7.1",
"symfony/polyfill-intl-normalizer": "^1.10",
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Idn\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
{
"name": "Trevor Rowbotham",
"email": "trevor.rowbotham@pm.me"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"idn",
"intl",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
"reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"intl",
"normalizer",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
"reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "tonyhhyip/sse",
"version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/tonyhhyip/libSSE-php.git",
"reference": "804af074e46247b5d9290b509c5cab8de523c93a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tonyhhyip/libSSE-php/zipball/804af074e46247b5d9290b509c5cab8de523c93a",
"reference": "804af074e46247b5d9290b509c5cab8de523c93a",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/http-foundation": "~2.7 | ~3.0 | ~4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.2 | ~5.0"
},
"suggest": {
"predis/predis": "For using RedisMechnism",
"symfony/polyfill-apcu": "For APCMecnism on PHP < 7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Sse\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Licson Lee",
"email": "licson0729@gmail.com",
"homepage": "https://licson.net/",
"role": "Owner"
},
{
"name": "Tony Yip",
"email": "tony@opensource.hk",
"homepage": "https://github.com/tonyhhyip",
"role": "Developer"
}
],
"description": "An easy-to-use, object-oriented library for Server-Sent Events",
"homepage": "https://github.com/licson0729/libSSE-php",
"keywords": [
"sse"
],
"time": "2018-03-08T02:55:29+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "1.1.0"
}

44
public/api/events.php Normal file
View file

@ -0,0 +1,44 @@
<?php
require_once(__DIR__.'/vendor/autoload.php');
require_once(__DIR__."/services/authenticator.inc.php");
require_once(__DIR__."/services/responses.inc.php");
use Sse\Event;
use Sse\SSE;
//create the event handler
class YourEventHandler implements Event {
public function update(){
//Here's the place to send data
return 'Hello, world!';
}
public function check(){
//Here's the place to check when the data needs update
return true;
}
}
$SSE_KEY_KEY = "sse_key";
$auth = new Authenticator();
if (!isset($_GET["user_id"]) || !isset($_GET[$SSE_KEY_KEY]) || !$auth->isSseAuthenticated($_GET["user_id"], $_GET[$SSE_KEY_KEY])) {
respondStatus(403);
}
$sse = new SSE(); //create a libSSE instance
$sse->exec_limit = 600; //the execution time of the loop in seconds. Default: 600. Set to 0 to allow the script to run as long as possible.
$sse->sleep_time = 5; //The time to sleep after the data has been sent in seconds. Default: 0.5.
$sse->client_reconnect = 10; //the time for the client to reconnect after the connection has lost in seconds. Default: 1.
$sse->use_chunked_encoding = false; //Use chunked encoding. Some server may get problems with this and it defaults to false
$sse->keep_alive_time = 600; //The interval of sending a signal to keep the connection alive. Default: 300 seconds.
$sse->allow_cors = true; //Allow cross-domain access? Default: false. If you want others to access this must set to true.
$sse->addEventListener('change', new YourEventHandler());//register your event handler
$sse->start();//start the event loop
?>

View file

@ -1,5 +1,7 @@
<?php
require_once(__DIR__."/dbOperations.inc.php");
require_once(__DIR__."/paramCleaner.inc.php");
require_once(__DIR__."/jugglDbApi.inc.php");
class Authenticator {
function isApiKeyAuthenticated($api_key, $user_id) {
@ -16,5 +18,10 @@ class Authenticator {
function isAuthenticated($params) {
return $this->isApiKeyAuthenticated($params->get('api_key'), $params->get('user_id'));
}
function isSseAuthenticated($user_id, $sse_key) {
$params = new ParamCleaner(["sse_key" => $sse_key]);
return validatedSseKey($user_id, $params);
}
}
?>

View file

@ -78,6 +78,24 @@ class JsonBuilder
return $this;
}
function addSseKey(array $sse)
{
if ($sse === null) return;
$columns = array(
"sse_key_id" => "",
"sse_key" => "",
"user_id" => "",
"created" => ""
);
$this->jsonData['sse'] = array();
foreach ($sse as $sse) {
$this->jsonData['sse'][] = $this->createJsonArray($sse, $columns);
}
return $this;
}
function addRecordTags(array $record_tags)
{
if ($record_tags === null) return;

View file

@ -286,6 +286,108 @@ function removeProject($user_id, $params)
removeRecordsOfProject($user_id, $project_id);
}
function secureRandomBytes ()
{
$pr_bits = '';
// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
$pr_bits .= @fread($fp,16);
@fclose($fp);
}
// MS-Windows platform?
if (@class_exists('COM')) {
// http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
try {
$CAPI_Util = new COM('CAPICOM.Utilities.1');
$pr_bits .= $CAPI_Util->GetRandom(16,0);
// if we ask for binary data PHP munges it, so we
// request base64 return value. We squeeze out the
// redundancy and useless ==CRLF by hashing...
if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
} catch (Exception $ex) {
// echo 'Exception: ' . $ex->getMessage();
}
}
return $pr_bits;
}
function createSseKey($user_id)
{
// Generate random key
$sse_key = secureRandomBytes();
$data = [
"user_id" => $user_id,
"sse_key" => $sse_key
];
$db = new DbOperations();
$db->insert("sse_keys", $data);
$db->execute();
return $sse_key;
}
function deleteSseKey($user_id, $params)
{
$sse_key_id = $params->get("sse_key_id");
$sse_key = $params->get("sse_key");
$db = new DbOperations();
$db->delete("sse_keys");
$db->where("user_id", Comparison::EQUAL, $user_id);
if ($sse_key_id != null) {
$db->where("sse_key_id", Comparison::EQUAL, $sse_key_id);
}
if ($sse_key != null) {
$db->where("sse_key", Comparison::EQUAL, $sse_key);
}
$db->execute();
}
function getSseKey($user_id, $params)
{
$sse_key_id = $params->get("sse_key_id");
$sse_key = $params->get("sse_key");
$db = new DbOperations();
$db->select("sse_keys");
$db->where("user_id", Comparison::EQUAL, $user_id);
if ($sse_key_id != null) {
$db->where("sse_key_id", Comparison::EQUAL, $sse_key_id);
}
if ($sse_key != null) {
$db->where("sse_key", Comparison::EQUAL, $sse_key);
}
$result = $db->execute();
if (count($result) <= 0) {
return null;
}
$result = $result[0];
return $result;
}
function getAllSseKeys($user_id)
{
$db = new DbOperations();
$db->select("sse_keys");
$db->where("user_id", Comparison::EQUAL, $user_id);
return $db->execute();
}
function validatedSseKey($user_id, $params)
{
$key_entry = getSseKey($user_id, $params);
return $key_entry != null;
}
function removeRecordsOfProject($user_id, $project_id)
{
$db = new DbOperations();

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
var source = new EventSource('https://juggl.giller.dev/api/events.php?sse_key=9f8u592845vn982z4&user_id=1');
source.onmessage = function(e) {
document.body.innerHTML += e.data + '<br>';
};
</script>
</body>
</html>