Add telegram linking
- Add init script - Apply error toggle from config file
This commit is contained in:
parent
e8d9d89b7a
commit
33b13af1dc
28
README.md
28
README.md
|
@ -10,28 +10,24 @@ This project has two parts the web server which gives the UI to enter new users
|
|||
|
||||
Requires
|
||||
- php >= 7
|
||||
- php-sqlite3
|
||||
- curl
|
||||
- php-curl
|
||||
- mysql/postgres
|
||||
- web server (only needed in production)
|
||||
- mysql/postgres (recommended)
|
||||
|
||||
Run copy the configuration file from `web/php/config.sample.php` to `web/php/config.php` and change the values accordingly.
|
||||
```sh
|
||||
cp web/php/config.sample.json web/php/config.json
|
||||
```
|
||||
|
||||
Run the intialization script to check and initialize the configuration.
|
||||
```sh
|
||||
php web/php/init.php
|
||||
```
|
||||
|
||||
In production hide the folder `php` from the webserver. For development use,
|
||||
```sh
|
||||
php -S localhost:8001 -t web
|
||||
|
||||
```
|
||||
All is well.
|
||||
|
||||
#### More configuration
|
||||
|
||||
The default database is `sqlite`. If you are using any other database engine, specify the configuration in `web/php/config.json`. For a starting reference see `web/php/config.sample.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"DBPATH": "mysql:host=localhost;dbname=myDb",
|
||||
"DBUSERNAME": "user",
|
||||
"DBPASSWORD": "pass"
|
||||
}
|
||||
```
|
||||
|
||||
The configuration can also be read from enviroment variables but the `config.json` is given precedence.
|
|
@ -1,8 +1,4 @@
|
|||
<?php
|
||||
ini_set("display_errors", "1");
|
||||
ini_set("display_startup_errors", "1");
|
||||
error_reporting(E_ALL);
|
||||
|
||||
session_start();
|
||||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
|
@ -40,7 +40,7 @@
|
|||
<?php
|
||||
if ($user->active) {
|
||||
echo'
|
||||
<div id="indicator" class="inactive"></div>
|
||||
<div class="indicator inactive"></div>
|
||||
<div id="bro_activity" class="info_entry">
|
||||
Bro on Duty
|
||||
<span>Your attendance is being checked and marked</span>
|
||||
|
@ -48,7 +48,7 @@
|
|||
';
|
||||
} else {
|
||||
echo'
|
||||
<div id="indicator" class="active"></div>
|
||||
<div class="indicator active"></div>
|
||||
<div id="bro_activity" class="info_entry">
|
||||
Bro is chilling
|
||||
<span>Account is inactive</span>
|
||||
|
@ -61,18 +61,25 @@
|
|||
<?php
|
||||
if ($user->active) {
|
||||
echo '<a href="/toggle_activation.php">
|
||||
<div id="btn_acountstatus" class="active">
|
||||
<div id="btn_acountstatus" class="button small error">
|
||||
Deactivate
|
||||
</div>
|
||||
</a>';
|
||||
} else {
|
||||
echo '<a href="/toggle_activation.php">
|
||||
<div id="btn_acountstatus" class="inactive">
|
||||
<div id="btn_acountstatus" class="button small accent">
|
||||
Activate
|
||||
</div>
|
||||
</a>';
|
||||
}
|
||||
?>
|
||||
<a href="/notifications.php">
|
||||
<div class="button ic <?php echo ($user->telegramId) ? "accent" : "error"; ?>">
|
||||
<svg class="icon sm" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="schedule">
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
session_start();
|
||||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
add_dependancies();
|
||||
redirect_unauthenticated();
|
||||
|
||||
$db = connect_db();
|
||||
$user = get_user_from_session($db);
|
||||
|
||||
$error = "";
|
||||
|
||||
try {
|
||||
$user->telegramId = 0;
|
||||
$user->update($db);
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
} finally {
|
||||
if ($error !== "") {
|
||||
header("location: /notifications.php?deactivation_notification_error={$error}");
|
||||
}
|
||||
|
||||
header("location: /notifications.php");
|
||||
}
|
||||
|
||||
?>
|
|
@ -3,7 +3,8 @@
|
|||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
add_dependancies();
|
||||
redirect_authenticated();
|
||||
$redirect_url = $_GET["redirect"] ?? "/dashboard.php";
|
||||
redirect_authenticated($redirect_url);
|
||||
$db = connect_db();
|
||||
|
||||
$num_users = $db->getTotalCount("users");
|
||||
|
@ -12,7 +13,7 @@
|
|||
$error = $username = "";
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
|
||||
|
||||
$user = new User();
|
||||
$username = $_POST["username"] ?? "";
|
||||
$password = $_POST["password"] ?? "";
|
||||
|
@ -20,24 +21,24 @@
|
|||
try {
|
||||
$user->find($db, $username);
|
||||
try {
|
||||
$user->login($db, $username, $password);
|
||||
header("location: /dashboard.php");
|
||||
$user->login($db, $username, $password);
|
||||
header("location: {$redirect_url}");
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
try {
|
||||
|
||||
|
||||
$user->username = $username;
|
||||
$user->password = $password;
|
||||
|
||||
|
||||
$user->save($db);
|
||||
$_SESSION["username"] = $username;
|
||||
header("location: /dashboard.php");
|
||||
header("location: {$redirect_url}");
|
||||
} catch (Exception $e) {
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$isError = ($error !== "");
|
||||
|
@ -67,7 +68,7 @@
|
|||
<h2 class="heading">Signin or Signup</h2>
|
||||
<span class="sub">Please note that we will be storing this password in a database as plain text. So please don't use your master or important passwords.</span>
|
||||
</div>
|
||||
<form id="form" method="post" action="/index.php">
|
||||
<form id="form" method="post" action="/index.php?redirect=<?php echo $redirect_url; ?>">
|
||||
<input autofocus class="input <?php echo $isError ? "error" : ""; ?>" id="username" type="text" name="username" value="<?php echo $username; ?>"placeholder="eduserver username" />
|
||||
<input class="input <?php echo $isError ? "error" : ""; ?>" id="password" type="password" name="password" placeholder="eduserver password" />
|
||||
<div class="error"><?php echo $error; ?></div>
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
<?php
|
||||
ini_set("display_errors", "1");
|
||||
ini_set("display_startup_errors", "1");
|
||||
error_reporting(E_ALL);
|
||||
|
||||
session_start();
|
||||
|
||||
$_SESSION = [];
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
session_start();
|
||||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
add_dependancies();
|
||||
redirect_unauthenticated();
|
||||
|
||||
$db = connect_db();
|
||||
$user = get_user_from_session($db);
|
||||
?>
|
||||
|
||||
<?php
|
||||
require_once(__DIR__. "/php/components/html_head.php");
|
||||
html_head("Notifications");
|
||||
?>
|
||||
<body>
|
||||
<div class="container">
|
||||
<?php require(__DIR__."/php/components/header.php"); ?>
|
||||
|
||||
<main id="notifications">
|
||||
<h1 class="heading">Activate Notifications</h1>
|
||||
|
||||
<section id="telegram" class="channel">
|
||||
<div class="heading">
|
||||
<div class="<?php echo ($user->telegramId) ? "indicator inactive" : "indicator active"; ?>"></div>
|
||||
<h2>Telegram</h2>
|
||||
<?php
|
||||
if ($user->telegramId) {
|
||||
echo '<a id="deactivate-btn" href="/deactivate_notification.php">
|
||||
<div class="button xs error">Unlink</div>
|
||||
</a>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="steps">
|
||||
<ol type="1">
|
||||
<li>Send a <code>\start</code> message to the telegram bot <a href="https://t.me/proxybro_bot" target="_blank" rel="noopener">@proxybro_bot</a></li>
|
||||
<li>The bot will send back a verification link.</li>
|
||||
<li>Click on the link and login.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
|
||||
<?php require(__DIR__."/php/components/footer.php"); ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -22,6 +22,7 @@ class Database {
|
|||
username VARCHAR(10) NOT NULL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
telegramId VARCHAR(25) NULL DEFAULT NULL,
|
||||
active INTEGER NOT NULL DEFAULT 1
|
||||
)";
|
||||
$this->dbh->exec($users_table_query);
|
||||
|
@ -29,6 +30,19 @@ class Database {
|
|||
if ($this->isError() !== false) {
|
||||
throw new Exception("Couldn\"t create table: {$this->error}");
|
||||
}
|
||||
|
||||
$verify_query = "CREATE TABLE IF NOT EXISTS alert_verify (
|
||||
passkey VARCHAR(50) NOT NULL PRIMARY KEY,
|
||||
chatId VARCHAR(25) NOT NULL,
|
||||
channel VARCHAR(25) NOT NULL,
|
||||
status INT NOT NULL DEFAULT 0,
|
||||
time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)";
|
||||
$this->dbh->exec($verify_query);
|
||||
|
||||
if ($this->isError() !== false) {
|
||||
echo $this->error;
|
||||
throw new Exception("Couldn\"t create table: {$this->error}");
|
||||
}
|
||||
}
|
||||
|
||||
function isError() {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
class Telegram {
|
||||
function __construct($token, $commands = []) {
|
||||
$this->token = $token;
|
||||
$this->commands = $commands;
|
||||
}
|
||||
|
||||
function sendMessage($chatId, $text, $options = []) {
|
||||
|
||||
send_post("https://api.telegram.org/bot{$this->token}/sendMessage", [
|
||||
"chat_id" => $chatId,
|
||||
"text" => $text,
|
||||
"parse_mode" => isset($options["parse_mode"])? $options["parse_mode"] : "MarkdownV2",
|
||||
"disable_web_page_preview" => isset($options["disable_web_page_preview"])? $options["disable_web_page_preview"] : false,
|
||||
]);
|
||||
}
|
||||
|
||||
function setWebhook($url) {
|
||||
|
||||
send_post("https://api.telegram.org/bot{$this->token}/setWebhook", [
|
||||
"url" => $url
|
||||
]);
|
||||
}
|
||||
|
||||
function recieveAndHandleMessage() {
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
$input = json_decode($inputJSON);
|
||||
|
||||
$chatId = $input->message->chat->id;
|
||||
$chatText = $input->message->text;
|
||||
|
||||
if ($this->executeCommandIfExist($input->message, $chatId, $chatText) === false) {
|
||||
$this->sendGenericResponse($chatId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function executeCommandIfExist($message, $chatId, $text) {
|
||||
$isCommand = false;
|
||||
if (@isset($message->entities)) {
|
||||
foreach ($message->entities as $entity) {
|
||||
if ($entity->type === "bot_command") {
|
||||
$isCommand = true;
|
||||
$commandName = substr($text, $entity->offset, $entity->length);
|
||||
$arguments = explode(" ", substr($text, $entity->offset + $entity->length));
|
||||
if (array_key_exists($commandName, $this->commands)) {
|
||||
$commandFunction = $this->commands[$commandName]["function"];
|
||||
$commandFunction($chatId, $arguments, $this);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($isCommand) {
|
||||
$this->sendMessage($chatId, "Command not recognised");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function sendGenericResponse($chatId) {
|
||||
$helpString = "";
|
||||
foreach ($this->commands as $command=>$config) {
|
||||
$helpString .= "\n{$command} - {$config["description"]}";
|
||||
}
|
||||
$this->sendMessage($chatId, "Available commands are: ". $helpString);
|
||||
}
|
||||
|
||||
}
|
|
@ -24,11 +24,12 @@ class User {
|
|||
// update all other than username and password
|
||||
function update($db) {
|
||||
// Prepare UPDATE statement.
|
||||
$update = "UPDATE users SET active=:active WHERE username=:username";
|
||||
$update = "UPDATE users SET active=:active, telegram_id=:telegramId WHERE username=:username";
|
||||
$stmt = $db->dbh->prepare($update);
|
||||
|
||||
$stmt->bindParam(":username", $this->username, PDO::PARAM_STR);
|
||||
$stmt->bindParam(":active", $this->active, PDO::PARAM_STR);
|
||||
$stmt->bindParam(":telegramId", $this->telegramId, PDO::PARAM_STR);
|
||||
$result = $stmt->execute();
|
||||
|
||||
if ($result === false) {
|
||||
|
@ -41,7 +42,7 @@ class User {
|
|||
|
||||
function find($db, $username) {
|
||||
// Prepare SELECT statement.
|
||||
$select = "SELECT username, name, password, active FROM users WHERE username=?";
|
||||
$select = "SELECT username, name, password, active, telegram_id FROM users WHERE username=?";
|
||||
$stmt = $db->dbh->prepare($select);
|
||||
|
||||
if ($db->isError()) {
|
||||
|
@ -61,6 +62,7 @@ class User {
|
|||
$this->name = $results["name"];
|
||||
$this->password = $results["password"];
|
||||
$this->active = intval($results["active"]);
|
||||
$this->telegramId = intval($results["telegram_id"]) === 0 ? null : $results["telegram_id"];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{
|
||||
"DBPATH": "mysql:host=localhost;dbname=myDb",
|
||||
"DBUSERNAME": "user",
|
||||
"DBPASSWORD": "pass"
|
||||
"DBPASSWORD": "pass",
|
||||
"SHOW_ERROR": 1,
|
||||
"SERVER_URL": "https://myproxybro.com",
|
||||
"TELEGRAM_TOKEN": "telegram_bot_token",
|
||||
"TELEGRAM_USERNAME": "my_proxybro_bot",
|
||||
"TELEGRAM_ENDPOINT": "my_sample_endpoint"
|
||||
}
|
||||
|
|
|
@ -1,39 +1,57 @@
|
|||
<?php
|
||||
|
||||
function add_dependancies() {
|
||||
require_once(__DIR__ ."/Config.php");
|
||||
|
||||
$config = new Config();
|
||||
|
||||
if (!is_null($config->SHOW_ERROR) && $config->SHOW_ERROR === 1) {
|
||||
ini_set("display_errors", "1");
|
||||
ini_set("display_startup_errors", "1");
|
||||
error_reporting(E_ALL);
|
||||
}
|
||||
|
||||
require_once(__DIR__ ."/Telegram.php");
|
||||
require_once(__DIR__ ."/Database.php");
|
||||
require_once(__DIR__ ."/User.php");
|
||||
require_once(__DIR__ ."/Config.php");
|
||||
require_once(__DIR__ ."/Schedule.php");
|
||||
}
|
||||
|
||||
function redirect_authenticated() {
|
||||
function redirect_authenticated($redirect_url = null) {
|
||||
$redirect_url = $redirect_url ?? "/dashboard.php";
|
||||
if (isset($_SESSION["username"])) {
|
||||
header("location: /dashboard.php");
|
||||
header("location: {$redirect_url}");
|
||||
}
|
||||
}
|
||||
|
||||
function redirect_unauthenticated() {
|
||||
function redirect_unauthenticated($redirect_url = null) {
|
||||
$redirect_url = $redirect_url ?? "/";
|
||||
if (!isset($_SESSION["username"])) {
|
||||
header("location: /");
|
||||
header("location: {$redirect_url}");
|
||||
}
|
||||
}
|
||||
|
||||
function get_user_from_session($db, $show_error = true) {
|
||||
function get_user_from_session($db, $display_error = true) {
|
||||
try {
|
||||
$user = new User();
|
||||
$user->find($db, @$_SESSION["username"]);
|
||||
return $user;
|
||||
} catch (Exception $e) {
|
||||
if ($show_error) {
|
||||
if ($display_error) {
|
||||
echo "User not found";
|
||||
echo '<a href="logout.php">Logout</a>';
|
||||
exit;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function flog($message, $file, $level) {
|
||||
$message = is_string($message) ? $message : json_encode(($message));
|
||||
file_put_contents("web.log", strtoupper($level) . "|" . substr($file, -20) ."|" . date("Y-m-d h:m:s") . "|" . session_id() . "|" . $message . "\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
function connect_db() {
|
||||
try {
|
||||
$config = new Config();
|
||||
|
@ -44,7 +62,6 @@ function connect_db() {
|
|||
|
||||
$db = new Database($path);
|
||||
$db->connect($username, $password);
|
||||
$db->create_tables();
|
||||
return $db;
|
||||
} catch (Exception $e) {
|
||||
echo "Error with database <br/>";
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
require_once(__DIR__ . "/helpers.php");
|
||||
|
||||
add_dependancies();
|
||||
|
||||
$config = new Config();
|
||||
$BASE_URL = __DIR__ ."/..";
|
||||
|
||||
// check if the configuration variables exist
|
||||
show("\nChecking configuration variables");
|
||||
$config_keys = json_decode(file_get_contents("{$BASE_URL}/php/config.sample.json"), true);
|
||||
|
||||
$config_error_flag = false;
|
||||
foreach ($config_keys as $key => $value) {
|
||||
if (is_null($config->$key)) {
|
||||
show_error("Configuration variable '{$key}' was not found.");
|
||||
$config_error_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($config_error_flag) {
|
||||
show_error("Some configuration variables were not found.");
|
||||
exit;
|
||||
}
|
||||
|
||||
show_success("All configuration variables found.");
|
||||
|
||||
// check connection of mysql using configuration
|
||||
show("\nChecking mysql connection");
|
||||
try {
|
||||
$config = new Config();
|
||||
|
||||
$path = $config->DBPATH;
|
||||
$username = $config->DBUSERNAME;
|
||||
$password = $config->DBPASSWORD;
|
||||
|
||||
$db = new Database($path);
|
||||
$db->connect($username, $password);
|
||||
$db->create_tables();
|
||||
show_success("Connected to database and tables created.");
|
||||
} catch (Exception $e) {
|
||||
show_error("Couldn't connect to database.");
|
||||
}
|
||||
|
||||
// move the telegram endpoint to a secret location
|
||||
show("\nAdding telegram endpoint");
|
||||
$original_file = "php/telegram_recieve";
|
||||
|
||||
if ((copy("{$BASE_URL}/{$original_file}.php", "{$BASE_URL}/{$config->TELEGRAM_ENDPOINT}.php")) === false) {
|
||||
show_error("Couldn't move telegram recieving file");
|
||||
exit;
|
||||
} else {
|
||||
show_success("Added telegram recieving endpoint({$config->TELEGRAM_ENDPOINT})");
|
||||
}
|
||||
|
||||
|
||||
// add telegram webhook
|
||||
show("\nAdding telegram webhook");
|
||||
$telegram = new Telegram($config->TELEGRAM_TOKEN);
|
||||
try {
|
||||
$telegram->setWebhook("{$config->SERVER_URL}/{$config->TELEGRAM_ENDPOINT}.php");
|
||||
show_success("Webhook added");
|
||||
} catch (Exception $e) {
|
||||
show_success("Telegram webhook could not be added.");
|
||||
show("Notifications will not be sent to the user");
|
||||
}
|
||||
|
||||
|
||||
function show_error($msg) {
|
||||
show($msg, true, "ERROR");
|
||||
}
|
||||
|
||||
function show_success($msg) {
|
||||
show($msg, true, "INFO");
|
||||
}
|
||||
|
||||
function show($msg, $newline = true, $prefix = "") {
|
||||
$prefix = $prefix ? "{$prefix}: " : "";
|
||||
echo "{$prefix}{$msg}";
|
||||
if ($newline) {
|
||||
echo PHP_EOL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
session_start();
|
||||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
add_dependancies();
|
||||
|
||||
$config = new Config();
|
||||
|
||||
$startCommand = function ($chatId, $arguments, $telegram) {
|
||||
$config = new Config();
|
||||
$db = connect_db();
|
||||
|
||||
$message = "";
|
||||
|
||||
try {
|
||||
// check if chatId already exists in users table
|
||||
$query = "SELECT COUNT(*) as count FROM users WHERE telegram_id=?";
|
||||
$stmt = $db->dbh->prepare($query);
|
||||
$stmt->execute([$chatId]);
|
||||
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (intval($data["count"]) >= 1) {
|
||||
// already a telegramId exists
|
||||
$telegram->sendMessage($chatId, "A user with using this chat as notification already exists. Cannot duplicate notifications.");
|
||||
return;
|
||||
}
|
||||
|
||||
// check already active activation link exists
|
||||
$query = "SELECT passkey, chatId, channel FROM alert_verify WHERE chatId=? and status=0 and channel='telegram'";
|
||||
$stmt = $db->dbh->prepare($query);
|
||||
$stmt->execute([$chatId]);
|
||||
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (isset($data["chatId"])) {
|
||||
|
||||
// a link already exists
|
||||
$pass = $data["passkey"];
|
||||
|
||||
} else {
|
||||
// create a new activation link
|
||||
$query = "INSERT INTO alert_verify (passkey, chatId, channel) VALUES (?, ?, ?)";
|
||||
$stmt = $db->dbh->prepare($query);
|
||||
|
||||
if ($db->isError() !== false) {
|
||||
throw new Exception($db->error);
|
||||
}
|
||||
|
||||
$pass = bin2hex(random_bytes(12));
|
||||
|
||||
$stmt->execute([$pass, $chatId, "telegram"]);
|
||||
if ($db->isError() !== false) {
|
||||
throw new Exception("Couldn't create verification link");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$link = $config->SERVER_URL . "/verify_notification.php?key=". $pass;
|
||||
$telegram->sendMessage($chatId, "Click the link to activiate notifivation\n{$link}");
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
$telegram->sendMessage($chatId, "Something went wrong at out end (token: ". session_id() ."). Please [report this issue](https://git.disroot.org/sQr00t/ProxyBro/issues).", [
|
||||
"parse_mode" => "MarkdownV2",
|
||||
"disable_web_page_preview" => true,
|
||||
]);
|
||||
flog($e->getMessage(), __FILE__, "ERROR");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$commands = [
|
||||
"/start" => [
|
||||
"name" => "Start",
|
||||
"description" => "Start recieveing notifications from proxybro",
|
||||
"function" => $startCommand,
|
||||
]];
|
||||
|
||||
$telegram = new Telegram($config->TELEGRAM_TOKEN, $commands);
|
||||
|
||||
$telegram->recieveAndHandleMessage();
|
|
@ -16,8 +16,9 @@
|
|||
--color-primary: #131a26;
|
||||
--color-primary-dark: #0c1018;
|
||||
--color-accent: #3bd671;
|
||||
--color-accent-dark: #199b46;
|
||||
--color-accent-dark: #2abb5d;
|
||||
--color-accent-error: #DF484A;
|
||||
--color-accent-error-dark: #dd3b3e;
|
||||
--color-accent-error-border: #9b2222;
|
||||
--color-primary-light: #212937;
|
||||
--color-body: #687790;
|
||||
|
@ -34,6 +35,7 @@
|
|||
/* --font-medium: 1.2rem; */
|
||||
/* --font-large: 1.7rem; */
|
||||
/* --font-xl: 2.2rem; */
|
||||
--font-small: 16px;
|
||||
--font-normal: 16px;
|
||||
--font-medium: 18px;
|
||||
--font-large: 24px;
|
||||
|
@ -61,6 +63,10 @@ body {
|
|||
padding: 0 50px;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: var(--color-body);
|
||||
}
|
||||
|
||||
.heading {
|
||||
color: var(--color-heading);
|
||||
}
|
||||
|
@ -75,12 +81,21 @@ body {
|
|||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
h2,
|
||||
.h2 {
|
||||
font-size: var(--font-xl);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
/* margin: auto; */
|
||||
|
@ -217,12 +232,27 @@ main#homepage .part.right #form {
|
|||
}
|
||||
|
||||
.button {
|
||||
display: block;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
align-items: center;
|
||||
padding: 10px 25px;
|
||||
font-size: var(--font-medium);
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-weight: 500;
|
||||
border-radius: 3px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: background-color 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.button.small {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.button.xs {
|
||||
padding: 5px 5px;
|
||||
font-size: var(--font-small);
|
||||
}
|
||||
|
||||
.error {
|
||||
|
@ -232,13 +262,21 @@ main#homepage .part.right #form {
|
|||
.button.accent {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-heading);
|
||||
transition: background-color 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.button.accent:hover {
|
||||
background-color: var(--color-accent-dark);
|
||||
}
|
||||
|
||||
.button.error {
|
||||
color: var(--color-heading);
|
||||
background-color: var(--color-accent-error);
|
||||
}
|
||||
|
||||
.button.error:hover {
|
||||
background-color: var(--color-accent-error-dark);
|
||||
}
|
||||
|
||||
form .bottom-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
@ -278,26 +316,29 @@ main#dashboard #stats {
|
|||
background-color: var(--color-primary-light);
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px 30px;
|
||||
color: #fff;
|
||||
padding: 0 30px;
|
||||
color: var(--color-heading);
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1)
|
||||
}
|
||||
main#dashboard #stats > div {
|
||||
margin: 20px auto;
|
||||
}
|
||||
main#dashboard #stats_left {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
width: 50%;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
}
|
||||
main#dashboard #stats_left .seperator {
|
||||
min-width: 3px;
|
||||
height: 30px%;
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
main#dashboard #stats_right {
|
||||
width: 30%;
|
||||
width: 100%;
|
||||
margin: 0 20px;
|
||||
}
|
||||
main#dashboard .info_entry {
|
||||
|
@ -319,28 +360,48 @@ main#dashboard #summary {
|
|||
background-color: var(--color-primary-light);
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px 50px;
|
||||
color: #fff;
|
||||
padding: 0 50px;
|
||||
color: var(--color-heading);
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1)
|
||||
}
|
||||
main#dashboard #indicator {
|
||||
.indicator {
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
height: 20px;
|
||||
/* filter: drop-shadow(0px 0px 10px); */
|
||||
box-shadow: 0 0px 19px;
|
||||
}
|
||||
|
||||
main#dashboard .icon {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
main#dashboard .icon.sm {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
main#dashboard #summary > div {
|
||||
padding: 20px 0;
|
||||
}
|
||||
main#dashboard #summary_left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
main#dashboard #summary_right {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
main#dashboard #summary_right a {
|
||||
text-decoration: none;
|
||||
}
|
||||
main#dashboard #summary_right a:first-child {
|
||||
margin-right: 15px;
|
||||
}
|
||||
main#dashboard #bro_activity {
|
||||
text-align: left;
|
||||
margin-left: 35px;
|
||||
|
@ -348,13 +409,13 @@ main#dashboard #bro_activity {
|
|||
main#dashboard #btn_acountstatus {
|
||||
padding: 10px 15px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
main#dashboard .inactive {
|
||||
main .inactive {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
main#dashboard .active {
|
||||
main .active {
|
||||
background-color: var(--color-accent-error);
|
||||
color: var(--color-accent-error);
|
||||
}
|
||||
|
@ -363,26 +424,29 @@ main#dashboard .active {
|
|||
/* schedule styling */
|
||||
|
||||
main#dashboard #schedule {
|
||||
width: 95%;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
margin-top: 40px;
|
||||
overflow: auto;
|
||||
}
|
||||
main#dashboard #schedule h2 {
|
||||
color: #fff;
|
||||
color: var(--color-heading);
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
main#dashboard table {
|
||||
main#dashboard #schedule table {
|
||||
overflow: auto;
|
||||
background-color: var(--color-primary-light);
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: 5px;
|
||||
margin: 20px 0;
|
||||
width: 100%;
|
||||
/* filter: drop-shadow(10px 10px 30px var(--color-primary-dark)); */
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.2)
|
||||
}
|
||||
main#dashboard table thead {
|
||||
background-color: #181F2C;
|
||||
color: #fff;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
|
||||
main#dashboard table th,td {
|
||||
|
@ -395,7 +459,7 @@ main#dashboard table td {
|
|||
}
|
||||
main#dashboard table .course {
|
||||
text-align: left;
|
||||
color: #fff;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
main#dashboard table tbody>tr>:nth-child(4) {
|
||||
font-weight: 500;
|
||||
|
@ -409,3 +473,56 @@ main#dashboard table td.success {
|
|||
main#dashboard table td.pending {
|
||||
color: #F29030;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1000px) {
|
||||
main#dashboard #stats {
|
||||
flex-direction: row;
|
||||
}
|
||||
main#dashboard #stats_right {
|
||||
width: 30%;
|
||||
}
|
||||
main#dashboard #stats_left {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
main#dashboard #summary {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
/* Notifications page */
|
||||
main#notifications .channel .heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
||||
main#notifications .channel .heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
||||
main#notifications .channel .heading > *:not(:last-child) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
main#notifications .channel .steps {
|
||||
margin-top: 30px;
|
||||
}
|
||||
main#notifications .channel .steps li {
|
||||
font-size: var(--font-medium);
|
||||
margin: 15px 0;
|
||||
}
|
||||
main#notifications #deactivate-btn {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Verify Notifications Page */
|
||||
main#verify-notification {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
main#verify-notification .link {
|
||||
padding: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
<?php
|
||||
ini_set("display_errors", "1");
|
||||
ini_set("display_startup_errors", "1");
|
||||
error_reporting(E_ALL);
|
||||
|
||||
session_start();
|
||||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('display_startup_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
session_start();
|
||||
require_once(__DIR__ ."/php/helpers.php");
|
||||
|
||||
add_dependancies();
|
||||
|
||||
$config = new Config();
|
||||
$db = connect_db();
|
||||
$user = get_user_from_session($db, false);
|
||||
$current_route = $_SERVER["REQUEST_URI"];
|
||||
$key = $_GET["key"];
|
||||
$telegram = new Telegram($config->TELEGRAM_TOKEN);
|
||||
|
||||
$message = "";
|
||||
|
||||
if ($user && $key) {
|
||||
try {
|
||||
|
||||
// get telegram details from alert_verify
|
||||
$query = "SELECT chatId FROM alert_verify WHERE passkey=? AND channel=? AND status=0";
|
||||
$stmt = $db->dbh->prepare($query);
|
||||
$stmt->execute([$key, "telegram"]);
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($data === false) {
|
||||
throw new Exception("Invalid or expired link");
|
||||
}
|
||||
|
||||
$chatId = $data["chatId"];
|
||||
|
||||
// update telegramId in users table
|
||||
$query = "UPDATE users SET telegram_id=? WHERE username=? LIMIT 1";
|
||||
$stmt = $db->dbh->prepare($query);
|
||||
$stmt->execute([$chatId, $user->username]);
|
||||
|
||||
// and change status to 1 in alert_verify
|
||||
$query = "UPDATE alert_verify SET status=1 WHERE chatId=?";
|
||||
$stmt = $db->dbh->prepare($query);
|
||||
$stmt->execute([$chatId]);
|
||||
|
||||
$message = "Verification complete. You will now recieve attendance updates.";
|
||||
|
||||
$telegram->sendMessage($chatId, $message);
|
||||
header("location: /dashboard.php");
|
||||
|
||||
} catch (Exception $e) {
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
|
||||
|
||||
} else if (isset($key)) {
|
||||
header("location: /index.php?redirect={$current_route}");
|
||||
} else {
|
||||
header("location: /");
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
require_once(__DIR__. "/php/components/html_head.php");
|
||||
html_head("Dashboard");
|
||||
?>
|
||||
<body>
|
||||
<div class="container">
|
||||
<?php require(__DIR__."/php/components/header.php"); ?>
|
||||
|
||||
<main id="verify-notification">
|
||||
<h2 class="heading"><?php echo $message; ?></h2>
|
||||
<div class="link">
|
||||
<a href="/">Go home</a>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<?php require(__DIR__."/php/components/footer.php"); ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue