Enhance API functionality: add token generation methods, implement entry management, and improve setup process with settings storage
This commit is contained in:
1 parent
8ef5f7a941
commit
9316818753
9 files changed
+248
-25
No files matched your search
+24
-4
@@ -28,7 +28,7 @@ class gbAPI {
|
|||||||
return parse_ini_file(APP_PATH . ".env");
|
return parse_ini_file(APP_PATH . ".env");
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateToken($username) {
|
function generateCookieToken($username) {
|
||||||
$config = $this->getConfig();
|
$config = $this->getConfig();
|
||||||
|
|
||||||
// Generate Token
|
// Generate Token
|
||||||
@@ -37,7 +37,21 @@ class gbAPI {
|
|||||||
"auth" => true
|
"auth" => true
|
||||||
];
|
];
|
||||||
$string = json_encode($payload);
|
$string = json_encode($payload);
|
||||||
$secret = $config["TOKEN_SIGNATURE"];
|
$secret = $config["COOKIE_TOKEN_SIGNATURE"];
|
||||||
|
|
||||||
|
return hash_hmac("sha256", $string, $secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateAPIToken($username) {
|
||||||
|
$config = $this->getConfig();
|
||||||
|
|
||||||
|
// Generate Token
|
||||||
|
$payload = [
|
||||||
|
"user" => $username,
|
||||||
|
"auth" => true
|
||||||
|
];
|
||||||
|
$string = json_encode($payload);
|
||||||
|
$secret = $config["API_TOKEN_SIGNATURE"];
|
||||||
|
|
||||||
return hash_hmac("sha256", $string, $secret);
|
return hash_hmac("sha256", $string, $secret);
|
||||||
}
|
}
|
||||||
@@ -83,9 +97,11 @@ class gbAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function dbCommand($command, $expectResult, $stmtArgsRequired = false, $stmtArgs = []) {
|
function dbCommand($command, $expectResult, $stmtArgsRequired = false, $stmtArgs = []) {
|
||||||
$db_path = APP_PATH . "database.db";
|
$config = $this->getConfig();
|
||||||
|
$db_name = $config["DB_NAME"];
|
||||||
|
$db_path = APP_PATH . $db_name;
|
||||||
|
|
||||||
$db = new PDO("sqlite: " . $db_path);
|
$db = new PDO("sqlite:" . $db_path);
|
||||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
$stmt = $db->prepare($command);
|
$stmt = $db->prepare($command);
|
||||||
@@ -97,4 +113,8 @@ class gbAPI {
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSetting() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
// Load Main Library
|
||||||
|
require "../api.php";
|
||||||
|
|
||||||
|
$api = new gbAPI(false);
|
||||||
|
|
||||||
|
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
|
||||||
|
$api->answer(400, [
|
||||||
|
"error" => "false_request_method",
|
||||||
|
"error_text" => "Only POST allowed"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = json_decode(file_get_contents("php://input"), true);
|
||||||
|
|
||||||
|
if (!isset($input["name"]) || !isset($input["text"])) {
|
||||||
|
$api->answer(400, [
|
||||||
|
"error" => "missing_fields",
|
||||||
|
"error_text" => "Some fields are missing"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$api->getSetting("");
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
// Load Main Library
|
||||||
|
require "../api.php";
|
||||||
|
|
||||||
|
$api = new gbAPI(false);
|
||||||
|
|
||||||
|
// Get Entrys
|
||||||
|
$command = "SELECT * FROM entrys WHERE status = :status";
|
||||||
|
$result = $api->dbCommand($command, true, true, [":status" => 1]);
|
||||||
|
|
||||||
|
$entrys = [];
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
$api->answer(200, [
|
||||||
|
"entrys" => [],
|
||||||
|
"empty" => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($result as $row) {
|
||||||
|
$entry_name = $row["name"];
|
||||||
|
$entry_text = $row["text"];
|
||||||
|
|
||||||
|
$entry = [
|
||||||
|
"name" => $entry_name,
|
||||||
|
"text" => $entry_text
|
||||||
|
];
|
||||||
|
|
||||||
|
$entrys[] = $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = json_encode($entrys);
|
||||||
|
|
||||||
|
$api->answer(200, [
|
||||||
|
"entrys" => $entrys,
|
||||||
|
"empty" => false
|
||||||
|
]);
|
||||||
+39
-1
@@ -21,6 +21,14 @@ if (!isset($input["username"]) || !isset($input["password"]) || !isset($input["p
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if application already configurated
|
||||||
|
if (is_file(APP_PATH . "database.db")) {
|
||||||
|
$api->answer(503, [
|
||||||
|
"error" => "already_configurated",
|
||||||
|
"error_text" => "The application is already configurated."
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$username = $input["username"];
|
$username = $input["username"];
|
||||||
$password = $input["password"];
|
$password = $input["password"];
|
||||||
$password_repeat = $input["password_repeat"];
|
$password_repeat = $input["password_repeat"];
|
||||||
@@ -56,5 +64,35 @@ $command = "INSERT INTO users (username, password, owner) VALUES (:username, :pa
|
|||||||
$stmt = $db->prepare($command);
|
$stmt = $db->prepare($command);
|
||||||
$stmt->execute([":username" => $username, ":password" => $hash, ":owner" => 1]);
|
$stmt->execute([":username" => $username, ":password" => $hash, ":owner" => 1]);
|
||||||
|
|
||||||
$api->answer(200);
|
|
||||||
|
|
||||||
|
// INSERT SETTINGS
|
||||||
|
$command = "INSERT INTO settings (name, value) VALUES (:name, :value)";
|
||||||
|
|
||||||
|
$settings = [
|
||||||
|
":application_name" => "",
|
||||||
|
":allow_html" => "false",
|
||||||
|
":approve_entrys" => "true",
|
||||||
|
":allow_new_entrys" => "true"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($settings as $key => $value) {
|
||||||
|
$stmt = $db->prepare($command);
|
||||||
|
$stmt->execute([$key => $value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WRITE .env AND GENERATE SECRETS
|
||||||
|
$env = "";
|
||||||
|
|
||||||
|
$cookie_token = bin2hex(random_bytes(32));
|
||||||
|
$env .= "COOKIE_TOKEN_SIGNATURE=" . $cookie_token;
|
||||||
|
|
||||||
|
$api_token = bin2hex(random_bytes(32));
|
||||||
|
$env .= "API_TOKEN_SIGNATURE=" . $api_token;
|
||||||
|
|
||||||
|
$env .= "DB_FILE=database.db";
|
||||||
|
|
||||||
|
file_put_contents(APP_PATH . ".env", $env);
|
||||||
|
|
||||||
|
|
||||||
|
// RETURN SUCCESS MESSAGE
|
||||||
|
$api->answer(200);
|
||||||
BIN
Binary file not shown.
@@ -12,3 +12,8 @@ CREATE TABLE IF NOT EXISTS "entrys" (
|
|||||||
"status" INTEGER NOT NULL DEFAULT 0
|
"status" INTEGER NOT NULL DEFAULT 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "settings" (
|
||||||
|
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"value" TEXT NOT NULL
|
||||||
|
);
|
||||||
+18
-12
@@ -18,20 +18,26 @@ $htmlLoader->setTemplate("entrys_frontend");
|
|||||||
$url = "http://" . APP_DOMAIN . "/api/entrys/get.php";
|
$url = "http://" . APP_DOMAIN . "/api/entrys/get.php";
|
||||||
$response = file_get_contents($url);
|
$response = file_get_contents($url);
|
||||||
|
|
||||||
$entrys = json_decode($response, true);
|
$response = json_decode($response, true);
|
||||||
$entrys = $entrys["entrys"];
|
if ($response["data"]["empty"]) {
|
||||||
|
$html_block = "<p>There aren'n any entrys yet. Be the first one!</p>";
|
||||||
|
}else{
|
||||||
|
$entrys = $response["data"]["entrys"];
|
||||||
|
|
||||||
$html_block = "";
|
$html_block = "";
|
||||||
foreach($entrys as $entry) {
|
foreach($entrys as $entry) {
|
||||||
$name = $entry["name"];
|
$name = $entry["name"];
|
||||||
$text = $entry["text"];
|
$text = $entry["text"];
|
||||||
|
$date = $entry["date"];
|
||||||
|
|
||||||
$html_block .= '
|
$html_block .= '
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h3>' . $name . '</h3>
|
<h3>' . $name . '</h3>
|
||||||
<p>' . $text . '</p>
|
<p id="date">' . $date . '</p>
|
||||||
</div>
|
<p>' . $text . '</p>
|
||||||
';
|
</div>
|
||||||
|
';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$htmlLoader->show(["%entrys%" => $html_block]);
|
$htmlLoader->show(["%entrys%" => $html_block]);
|
||||||
@@ -26,13 +26,86 @@
|
|||||||
p {
|
p {
|
||||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 1px solid rgb(211, 211, 211);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 class="md-typescale-display-large">%appname%</h1>
|
<h1 class="md-typescale-display-large">%appname%</h1>
|
||||||
<h3 class="md-typescale-display-medium">All Entrys</h3>
|
<md-filled-tonal-button id="entry_add">
|
||||||
<md-filled-tonal-button>
|
|
||||||
Add Entry
|
Add Entry
|
||||||
</md-filled-tonal-button>
|
</md-filled-tonal-button>
|
||||||
</body>
|
<h2 class="md-typescale-display-medium">All Entrys</h2>
|
||||||
|
%entrys%
|
||||||
|
<md-dialog id="add_entry_dialog">
|
||||||
|
<div slot="headline">
|
||||||
|
Add entry
|
||||||
|
</div>
|
||||||
|
<form slot="content" method="dialog">
|
||||||
|
<md-filled-text-field id="entry_name" label="Name"></md-filled-text-field><br><br>
|
||||||
|
<md-filled-text-field id="entry_text" label="Text" rows="5" style="resize: vertical;" type="textarea"></md-filled-text-field>
|
||||||
|
<div class="loader" id="loader" style="display: none;">
|
||||||
|
<md-circular-progress id="add_entry_load" indeterminate></md-circular-progress>
|
||||||
|
</div>
|
||||||
|
<p id="entry_return"></p>
|
||||||
|
</form>
|
||||||
|
<div slot="actions">
|
||||||
|
<md-filled-button id="entry_submit">Submit</md-filled-button>
|
||||||
|
<md-text-button id="entry_close">Close</md-text-button>
|
||||||
|
</div>
|
||||||
|
</md-dialog>
|
||||||
|
<script>
|
||||||
|
document.getElementById("entry_add").addEventListener("click", function() {
|
||||||
|
document.getElementById("add_entry_dialog").setAttribute("open", "");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("entry_close").addEventListener("click", function() {
|
||||||
|
document.getElementById("add_entry_dialog").removeAttribute("open");
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("entry_submit").addEventListener("click", function() {
|
||||||
|
document.getElementById("entry_name").style.display = "none";
|
||||||
|
document.getElementById("entry_text").style.display = "none";
|
||||||
|
document.getElementById("entry_submit").style.display = "none";
|
||||||
|
document.getElementById("entry_close").style.display = "none";
|
||||||
|
|
||||||
|
document.getElementById("loader").style.display = "flex";
|
||||||
|
|
||||||
|
name = document.getElementById("entry_name").value;
|
||||||
|
text = document.getElementById("entry_text").value;
|
||||||
|
|
||||||
|
fetch("/api/entrys/add.php", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name,
|
||||||
|
text: text
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
document.getElementById("loader").style.display = "none";
|
||||||
|
if (data.status !== 200) {
|
||||||
|
document.getElementById("entry_return").innerHTML = "API returned an error: " + data.error_text;
|
||||||
|
document.getElementById("entry_close").style.display = "block";
|
||||||
|
}else{
|
||||||
|
document.getElementById("entry_return").innerHTML = "Success! Maybe your entry must be aproved by the owner.";
|
||||||
|
document.getElementById("entry_close").style.display = "block";
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
document.getElementById("loader").style.display = "none";
|
||||||
|
document.getElementById("entry_return").innerHTML = "There was an error: " + error;
|
||||||
|
document.getElementById("entry_close").style.display = "block";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -66,6 +66,18 @@
|
|||||||
<md-filled-button id="close-button">Close</md-filled-button>
|
<md-filled-button id="close-button">Close</md-filled-button>
|
||||||
</div>
|
</div>
|
||||||
</md-dialog>
|
</md-dialog>
|
||||||
|
<md-dialog id="success-dialog">
|
||||||
|
<div slot="headline">
|
||||||
|
Success!
|
||||||
|
</div>
|
||||||
|
<form slot="content" method="dialog" id="error-dialog-text">
|
||||||
|
Your Guestbook is finaly configurated! You can find the admin Panel on <span id="success-admin-url"></span>.
|
||||||
|
</form>
|
||||||
|
<div slot="actions">
|
||||||
|
<md-filled-button id="success-dialog-home">Open Guestbook</md-filled-button>
|
||||||
|
<md-filled-button id="success-dialog-admin">Open Admin Panel</md-filled-button>
|
||||||
|
</div>
|
||||||
|
</md-dialog>
|
||||||
<script>
|
<script>
|
||||||
if (window.location.protocol == "http:") {
|
if (window.location.protocol == "http:") {
|
||||||
document.getElementById("http-dialog").setAttribute("open", "");
|
document.getElementById("http-dialog").setAttribute("open", "");
|
||||||
@@ -80,7 +92,15 @@
|
|||||||
|
|
||||||
document.getElementById("close-button").addEventListener("click", function() {
|
document.getElementById("close-button").addEventListener("click", function() {
|
||||||
document.getElementById("error-dialog").removeAttribute("open");
|
document.getElementById("error-dialog").removeAttribute("open");
|
||||||
})
|
});
|
||||||
|
|
||||||
|
document.getElementById("success-dialog-home").addEventListener("click", function() {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("success-dialog-admin").addEventListener("click", function() {
|
||||||
|
window.location.href = "/admin";
|
||||||
|
});
|
||||||
|
|
||||||
function checkSetup() {
|
function checkSetup() {
|
||||||
const username = document.getElementById("setup-username").value;
|
const username = document.getElementById("setup-username").value;
|
||||||
@@ -108,14 +128,15 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => function() {
|
.then(data => {
|
||||||
if (data.status !== 200) {
|
if (data.status == 200) {
|
||||||
|
document.getElementById("success-admin-url").innerHTML = window.location.href + "admin";
|
||||||
|
document.getElementById("success-dialog").setAttribute("open", "");
|
||||||
|
}else{
|
||||||
console.error("Server returned following message: " + data.error);
|
console.error("Server returned following message: " + data.error);
|
||||||
|
|
||||||
document.getElementById("error-dialog-text").innerHTML = data.display_error;
|
document.getElementById("error-dialog-text").innerHTML = data.display_error;
|
||||||
document.getElementById("error-dialog").setAttribute("open", "");
|
document.getElementById("error-dialog").setAttribute("open", "");
|
||||||
}else{
|
|
||||||
alert("Tres bien!");
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user