From 872ef4099aebc9f7eda8e012bd079a55f1106cfb Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 21 Feb 2022 14:04:49 +0100 Subject: [PATCH] Cleanup + Login View --- cli.php | 20 +++- core/Configuration/CreateDatabase.class.php | 1 + core/Documents/Account.class.php | 3 + core/Documents/Files.class.php | 65 ------------ core/Elements/TemplateDocument.class.php | 1 + core/Objects/KeyBasedTwoFactorToken.class.php | 13 --- .../Objects/TimeBasedTwoFactorToken.class.php | 52 ---------- core/Objects/TwoFactorToken.class.php | 63 ------------ core/Templates/account/account.twig | 16 --- core/Templates/account/login.twig | 31 ++++++ core/Templates/mail/register.twig | 8 -- core/Views/Account/AcceptInvite.class.php | 89 ----------------- core/Views/Account/AccountView.class.php | 61 ------------ core/Views/Account/ConfirmEmail.class.php | 55 ----------- core/Views/Account/Register.class.php | 70 ------------- .../Account/ResendConfirmEmail.class.php | 39 -------- core/Views/Account/ResetPassword.class.php | 99 ------------------- core/Views/Admin/AdminDashboardBody.class.php | 20 ---- core/Views/Admin/LoginBody.class.php | 72 -------------- core/Views/LanguageFlags.class.php | 62 ------------ core/Views/View404.class.php | 13 --- 21 files changed, 54 insertions(+), 799 deletions(-) delete mode 100644 core/Documents/Files.class.php delete mode 100644 core/Objects/KeyBasedTwoFactorToken.class.php delete mode 100644 core/Objects/TimeBasedTwoFactorToken.class.php delete mode 100644 core/Objects/TwoFactorToken.class.php delete mode 100644 core/Templates/account/account.twig create mode 100644 core/Templates/account/login.twig delete mode 100644 core/Templates/mail/register.twig delete mode 100644 core/Views/Account/AcceptInvite.class.php delete mode 100644 core/Views/Account/AccountView.class.php delete mode 100644 core/Views/Account/ConfirmEmail.class.php delete mode 100644 core/Views/Account/Register.class.php delete mode 100644 core/Views/Account/ResendConfirmEmail.class.php delete mode 100644 core/Views/Account/ResetPassword.class.php delete mode 100644 core/Views/Admin/AdminDashboardBody.class.php delete mode 100644 core/Views/Admin/LoginBody.class.php delete mode 100644 core/Views/LanguageFlags.class.php delete mode 100644 core/Views/View404.class.php diff --git a/cli.php b/cli.php index 064d2a4..6004a8c 100644 --- a/cli.php +++ b/cli.php @@ -621,13 +621,29 @@ function onMail($argv) { function onImpersonate($argv) { if (count($argv) < 3) { - _exit("Usage: cli.php impersonate "); + _exit("Usage: cli.php impersonate "); } $user = getUser() or exit; - $user->createSession(intval($argv[2])); + + $userId = $argv[2]; + if (!is_numeric($userId)) { + $sql = $user->getSQL(); + $res = $sql->select("uid") + ->from("User") + ->where(new Compare("name", $userId)) + ->execute(); + if ($res === false) { + _exit("SQL error: " . $sql->getLastError()); + } else { + $userId = $res[0]["uid"]; + } + } + + $user->createSession(intval($userId)); $session = $user->getSession(); $session->setData(["2faAuthenticated" => true]); + $session->update(false); echo "session=" . $session->getCookie() . PHP_EOL; } diff --git a/core/Configuration/CreateDatabase.class.php b/core/Configuration/CreateDatabase.class.php index de7a0e1..2944ee5 100644 --- a/core/Configuration/CreateDatabase.class.php +++ b/core/Configuration/CreateDatabase.class.php @@ -160,6 +160,7 @@ class CreateDatabase extends DatabaseScript { ->addRow("^/confirmEmail/?$", "dynamic", "\\Documents\\Account", "account/confirm_email.twig") ->addRow("^/acceptInvite/?$", "dynamic", "\\Documents\\Account", "account/accept_invite.twig") ->addRow("^/resetPassword/?$", "dynamic", "\\Documents\\Account", "account/reset_password.twig") + ->addRow("^/login/?$", "dynamic", "\\Documents\\Account", "account/login.twig") ->addRow("^/resendConfirmEmail/?$", "dynamic", "\\Documents\\Account", "account/resend_confirm_email.twig") ->addRow("^/$", "static", "/static/welcome.html", NULL); diff --git a/core/Documents/Account.class.php b/core/Documents/Account.class.php index 70d35d2..1b60cf7 100644 --- a/core/Documents/Account.class.php +++ b/core/Documents/Account.class.php @@ -40,6 +40,9 @@ class Account extends TemplateDocument { } else if (!$settings->isRegistrationAllowed()) { $this->createError("Registration is not enabled on this website."); } + } else if ($this->getTemplateName() === "account/login.twig" && $this->user->isLoggedIn()) { + header("Location: /admin"); + exit(); } else if ($this->getTemplateName() === "account/accept_invite.twig") { if (isset($_GET["token"]) && is_string($_GET["token"]) && !empty($_GET["token"])) { $this->parameters["view"]["token"] = $_GET["token"]; diff --git a/core/Documents/Files.class.php b/core/Documents/Files.class.php deleted file mode 100644 index 37db052..0000000 --- a/core/Documents/Files.class.php +++ /dev/null @@ -1,65 +0,0 @@ -addCSS(Link::BOOTSTRAP); - $this->loadFontawesome(); - } - - protected function initMetas(): array { - return array( - array('name' => 'viewport', 'content' => 'width=device-width, initial-scale=1.0'), - array('name' => 'format-detection', 'content' => 'telephone=yes'), - array('charset' => 'utf-8'), - array('http-equiv' => 'expires', 'content' => '0'), - array('name' => 'robots', 'content' => 'noarchive'), - array('name' => 'referrer', 'content' => 'origin') - ); - } - - protected function initRawFields(): array { - return array(); - } - - protected function initTitle(): string { - return "File Control Panel"; - } - } - - class FilesBody extends SimpleBody { - - public function __construct($document) { - parent::__construct($document); - } - - protected function getContent(): string { - $html = ""; - $html .= "
"; - $html .= new Script(Script::MIME_TEXT_JAVASCRIPT, Script::FILES); - return $html; - } - } - -} diff --git a/core/Elements/TemplateDocument.class.php b/core/Elements/TemplateDocument.class.php index b2aa8bf..dfa23fb 100644 --- a/core/Elements/TemplateDocument.class.php +++ b/core/Elements/TemplateDocument.class.php @@ -58,6 +58,7 @@ class TemplateDocument extends Document { $params["site"] = [ "name" => $settings->getSiteName(), "baseUrl" => $settings->getBaseUrl(), + "registrationEnabled" => $settings->isRegistrationAllowed(), "title" => $this->title, "recaptcha" => [ "key" => $settings->isRecaptchaEnabled() ? $settings->getRecaptchaSiteKey() : null, diff --git a/core/Objects/KeyBasedTwoFactorToken.class.php b/core/Objects/KeyBasedTwoFactorToken.class.php deleted file mode 100644 index e657559..0000000 --- a/core/Objects/KeyBasedTwoFactorToken.class.php +++ /dev/null @@ -1,13 +0,0 @@ -getUsername()); - $settings = $user->getConfiguration()->getSettings(); - $urlArgs = [ - "secret" => $this->getSecret(), - "issuer" => $settings->getSiteName(), - ]; - - $urlArgs = http_build_query($urlArgs); - return "otpauth://$otpType/$name?$urlArgs"; - } - - public function generateQRCode(User $user) { - $options = new QROptions(['outputType' => QRCode::OUTPUT_IMAGE_PNG, "imageBase64" => false]); - $qrcode = new QRCode($options); - return $qrcode->render($this->getUrl($user)); - } - - public function generate(?int $at = null, int $length = 6, int $period = 30): string { - if ($at === null) { - $at = time(); - } - - $seed = intval($at / $period); - $secret = Base32::decode($this->getSecret()); - $hmac = hash_hmac('sha1', pack("J", $seed), $secret, true); - $offset = ord($hmac[-1]) & 0xF; - $code = (unpack("N", substr($hmac, $offset, 4))[1] & 0x7fffffff) % intval(pow(10, $length)); - return substr(str_pad(strval($code), $length, "0", STR_PAD_LEFT), -1 * $length); - } - - public function verify(string $code): bool { - return $this->generate() === $code; - } -} \ No newline at end of file diff --git a/core/Objects/TwoFactorToken.class.php b/core/Objects/TwoFactorToken.class.php deleted file mode 100644 index a903049..0000000 --- a/core/Objects/TwoFactorToken.class.php +++ /dev/null @@ -1,63 +0,0 @@ -id = $id; - $this->type = $type; - $this->secret = $secret; - $this->confirmed = $confirmed; - $this->authenticated = $_SESSION["2faAuthenticated"] ?? false; - } - - public function jsonSerialize(): array { - return [ - "id" => $this->id, - "type" => $this->type, - "confirmed" => $this->confirmed, - "authenticated" => $this->authenticated, - ]; - } - - public function authenticate() { - $this->authenticated = true; - $_SESSION["2faAuthenticated"] = true; - } - - public function getType(): string { - return $this->type; - } - - public function getSecret(): string { - return $this->secret; - } - - public function isConfirmed(): bool { - return $this->confirmed; - } - - public function getId(): int { - return $this->id; - } - - public static function newInstance(string $type, string $secret, ?int $id = null, bool $confirmed = false) { - if ($type === TimeBasedTwoFactorToken::TYPE) { - return new TimeBasedTwoFactorToken($secret, $id, $confirmed); - } else { - // TODO: error message - return null; - } - } - - public function isAuthenticated(): bool { - return $this->authenticated; - } -} \ No newline at end of file diff --git a/core/Templates/account/account.twig b/core/Templates/account/account.twig deleted file mode 100644 index c1de5e5..0000000 --- a/core/Templates/account/account.twig +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "base.twig" %} - -{% block head %} - - - - - - - - Account - {{ title }} -{% endblock %} - -{% block body %} - -{% endblock %} diff --git a/core/Templates/account/login.twig b/core/Templates/account/login.twig new file mode 100644 index 0000000..a7f3a17 --- /dev/null +++ b/core/Templates/account/login.twig @@ -0,0 +1,31 @@ +{% extends "account.twig" %} + +{% set view_title = 'Sign In' %} +{% set view_icon = 'user-lock' %} +{% set view_description = 'Sign In into your account' %} + +{% block view_content %} + +

Please fill with your details

+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ + {% if site.registrationEnabled %} +
Don't have an account yet? Click here to register.
+ {% endif %} +
+
+ +{% endblock %} \ No newline at end of file diff --git a/core/Templates/mail/register.twig b/core/Templates/mail/register.twig deleted file mode 100644 index 4eb546f..0000000 --- a/core/Templates/mail/register.twig +++ /dev/null @@ -1,8 +0,0 @@ -Hello {{ username }},

-You recently created an account on {{ site_name }}. Please click on the following link to confirm your email address and complete your registration.
-If you haven't registered an account, you can simply ignore this email. The link is valid for the next 48 hours:

- -{{ link }}

- -Best Regards
-{{ site_name }} Administration \ No newline at end of file diff --git a/core/Views/Account/AcceptInvite.class.php b/core/Views/Account/AcceptInvite.class.php deleted file mode 100644 index 8dc47c9..0000000 --- a/core/Views/Account/AcceptInvite.class.php +++ /dev/null @@ -1,89 +0,0 @@ -title = "Invitation"; - $this->description = "Finnish your account registration by choosing a password."; - $this->icon = "user-check"; - $this->success = false; - $this->message = "No content"; - $this->invitedUser = array(); - } - - public function loadView() { - parent::loadView(); - - if (isset($_GET["token"]) && is_string($_GET["token"]) && !empty($_GET["token"])) { - $req = new \Api\User\CheckToken($this->getDocument()->getUser()); - $this->success = $req->execute(array("token" => $_GET["token"])); - if ($this->success) { - if (strcmp($req->getResult()["token"]["type"], "invite") !== 0) { - $this->success = false; - $this->message = "The given token has a wrong type."; - } else { - $this->invitedUser = $req->getResult()["user"]; - } - } else { - $this->message = "Error confirming e-mail address: " . $req->getLastError(); - } - } else { - $this->success = false; - $this->message = "The link you visited is no longer valid"; - } - } - - protected function getAccountContent() { - if (!$this->success) { - return $this->createErrorText($this->message); - } - - $token = htmlspecialchars($_GET["token"], ENT_QUOTES); - $username = $this->invitedUser["name"]; - $emailAddress = $this->invitedUser["email"]; - - return "

Please fill with your details

-
- -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
- -
-
"; - } -} \ No newline at end of file diff --git a/core/Views/Account/AccountView.class.php b/core/Views/Account/AccountView.class.php deleted file mode 100644 index f14e033..0000000 --- a/core/Views/Account/AccountView.class.php +++ /dev/null @@ -1,61 +0,0 @@ -description = ""; - $this->icon = "image"; - } - - public function loadView() { - parent::loadView(); - - $document = $this->getDocument(); - $settings = $document->getUser()->getConfiguration()->getSettings(); - if ($settings->isRecaptchaEnabled()) { - $document->getHead()->loadGoogleRecaptcha($settings->getRecaptchaSiteKey()); - } - } - - public function getCode(): string { - $html = parent::getCode(); - - $content = $this->getAccountContent(); - $icon = $this->createIcon($this->icon, "fas", "fa-3x"); - - $html .= "
-
-
-
- $icon -

$this->title

-

$this->description

-
-
-
- $content - -
-
-
"; - - $settings = $this->getDocument()->getUser()->getConfiguration()->getSettings(); - if ($settings->isRecaptchaEnabled()) { - $siteKey = $settings->getRecaptchaSiteKey(); - $html .= ""; - } - - return $html; - } - - protected abstract function getAccountContent(); -} \ No newline at end of file diff --git a/core/Views/Account/ConfirmEmail.class.php b/core/Views/Account/ConfirmEmail.class.php deleted file mode 100644 index 8f77287..0000000 --- a/core/Views/Account/ConfirmEmail.class.php +++ /dev/null @@ -1,55 +0,0 @@ -title = "Confirm Email"; - $this->description = "Request a password reset, once you got the e-mail address, you can choose a new password"; - $this->icon = "user-check"; - } - - public function loadView() { - parent::loadView(); - $this->getDocument()->getHead()->addScript(Script::MIME_TEXT_JAVASCRIPT, "", ' - $(document).ready(function() { - var token = jsCore.getParameter("token"); - if (token) { - jsCore.apiCall("/user/confirmEmail", { token: token }, (res) => { - $("#confirm-status").removeClass("alert-info"); - if (!res.success) { - $("#confirm-status").addClass("alert-danger"); - $("#confirm-status").text("Error confirming e-mail address: " + res.msg); - } else { - $("#confirm-status").addClass("alert-success"); - $("#confirm-status").text("Your e-mail address was successfully confirmed, you may now log in."); - } - }); - } else { - $("#confirm-status").removeClass("alert-info"); - $("#confirm-status").addClass("alert-danger"); - $("#confirm-status").text("The link you visited is no longer valid"); - } - });' - ); - } - - protected function getAccountContent() { - - $spinner = $this->createIcon("spinner"); - $html = " -
- Confirming email… $spinner -
"; - - $html .= ""; - return $html; - } -} \ No newline at end of file diff --git a/core/Views/Account/Register.class.php b/core/Views/Account/Register.class.php deleted file mode 100644 index 2a7108e..0000000 --- a/core/Views/Account/Register.class.php +++ /dev/null @@ -1,70 +0,0 @@ -title = "Registration"; - $this->description = "Create a new account"; - $this->icon = "user-plus"; - } - - public function getAccountContent() { - - $user = $this->getDocument()->getUser(); - if ($user->isLoggedIn()) { - header(302); - header("Location: /"); - die("You are already logged in."); - } - - $settings = $user->getConfiguration()->getSettings(); - if (!$settings->isRegistrationAllowed()) { - return $this->createErrorText( - "Registration is not enabled on this website. If you are an administrator, - goto /admin/settings, to enable the user registration" - ); - } - - return "

Please fill with your details

-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
- -
"; - } -} \ No newline at end of file diff --git a/core/Views/Account/ResendConfirmEmail.class.php b/core/Views/Account/ResendConfirmEmail.class.php deleted file mode 100644 index 30cad73..0000000 --- a/core/Views/Account/ResendConfirmEmail.class.php +++ /dev/null @@ -1,39 +0,0 @@ -title = "Resend Confirm Email"; - $this->description = "Request a new confirmation email to finalize the account creation"; - $this->icon = "envelope"; - } - - protected function getAccountContent() { - return "

Enter your E-Mail address, to receive a new e-mail to confirm your registration.

-
-
-
- -
- -
-
- - - - -
- "; - } -} \ No newline at end of file diff --git a/core/Views/Account/ResetPassword.class.php b/core/Views/Account/ResetPassword.class.php deleted file mode 100644 index 040fa23..0000000 --- a/core/Views/Account/ResetPassword.class.php +++ /dev/null @@ -1,99 +0,0 @@ -title = "Reset Password"; - $this->description = "Request a password reset, once you got the e-mail address, you can choose a new password"; - $this->icon = "user-lock"; - $this->success = true; - $this->message = ""; - $this->token = NULL; - } - - public function loadView() { - parent::loadView(); - - if (isset($_GET["token"]) && is_string($_GET["token"]) && !empty($_GET["token"])) { - $this->token = $_GET["token"]; - $req = new \Api\User\CheckToken($this->getDocument()->getUser()); - $this->success = $req->execute(array("token" => $_GET["token"])); - if ($this->success) { - if (strcmp($req->getResult()["token"]["type"], "password_reset") !== 0) { - $this->success = false; - $this->message = "The given token has a wrong type."; - } - } else { - $this->message = "Error requesting password reset: " . $req->getLastError(); - } - } - } - - protected function getAccountContent() { - if (!$this->success) { - $html = $this->createErrorText($this->message); - if ($this->token !== null) { - $html .= "Go back"; - } - return $html; - } - - if ($this->token === null) { - return "

Enter your E-Mail address, to receive a password reset token.

- -
-
- -
- -
-
- - - - -
- "; - } else { - return "

Choose a new password

- - -
-
- -
- -
-
-
- -
- -
- -
"; - } - } -} \ No newline at end of file diff --git a/core/Views/Admin/AdminDashboardBody.class.php b/core/Views/Admin/AdminDashboardBody.class.php deleted file mode 100644 index a74452e..0000000 --- a/core/Views/Admin/AdminDashboardBody.class.php +++ /dev/null @@ -1,20 +0,0 @@ -getDocument()->createScript(Script::MIME_TEXT_JAVASCRIPT, "/js/admin.min.js"); - $html .= "
$script
"; - return $html; - } -} diff --git a/core/Views/Admin/LoginBody.class.php b/core/Views/Admin/LoginBody.class.php deleted file mode 100644 index b40285a..0000000 --- a/core/Views/Admin/LoginBody.class.php +++ /dev/null @@ -1,72 +0,0 @@ -getDocument()->getHead(); - $head->loadJQuery(); - $head->loadBootstrap(); - $head->addJS(Script::CORE); - $head->addCSS(Link::CORE); - $head->addJS(Script::ACCOUNT); - $head->addCSS(Link::ACCOUNT); - } - - public function getCode(): string { - $html = parent::getCode(); - - $username = L("Username"); - $password = L("Password"); - $login = L("Login"); - $backToStartPage = L("Back to Start Page"); - $stayLoggedIn = L("Stay logged in"); - - $flags = $this->load(LanguageFlags::class); - $iconBack = $this->createIcon("arrow-circle-left"); - $domain = $_SERVER['HTTP_HOST']; - $protocol = getProtocol(); - - $html .= " - -
-
-

Admin Control Panel

-
-
-
-
- - - - -
- - -
- - - $flags -
- -
-
-
- "; - - return $html; - } -} diff --git a/core/Views/LanguageFlags.class.php b/core/Views/LanguageFlags.class.php deleted file mode 100644 index b7e4187..0000000 --- a/core/Views/LanguageFlags.class.php +++ /dev/null @@ -1,62 +0,0 @@ -languageFlags = array(); - $this->searchable = false; - } - - public function loadView() { - parent::loadView(); - - $request = new \Api\Language\Get($this->getDocument()->getUser()); - if ($request->execute()) { - - $requestUri = $_SERVER["REQUEST_URI"]; - $queryString = $_SERVER['QUERY_STRING']; - - $params = explode("&", $queryString); - $query = array(); - foreach ($params as $param) { - $aParam = explode("=", $param); - $key = $aParam[0]; - - if ($key === "site" && - (!startsWith($_SERVER["REQUEST_URI"], "/index.php") || $_SERVER["REQUEST_URI"] === "/")) { - continue; - } - - $val = (isset($aParam[1]) ? $aParam[1] : ""); - if (!empty($key)) { - $query[$key] = $val; - } - } - - $url = parse_url($requestUri, PHP_URL_PATH) . "?"; - - foreach ($request->getResult()['languages'] as $lang) { - $langCode = $lang['code']; - $langName = $lang['name']; - $query['lang'] = $langCode; - $queryString = http_build_query($query); - - $this->languageFlags[] = $this->createLink( - "$url$queryString", - "\"$langName\"" - ); - } - } - } - - public function getCode(): string { - return implode('', $this->languageFlags); - } -} \ No newline at end of file diff --git a/core/Views/View404.class.php b/core/Views/View404.class.php deleted file mode 100644 index d3ebe0f..0000000 --- a/core/Views/View404.class.php +++ /dev/null @@ -1,13 +0,0 @@ -Not found"; - } - -}; \ No newline at end of file