From fe81e0f6fac833743b2713465267545789973ae6 Mon Sep 17 00:00:00 2001 From: Roman Date: Sat, 6 Apr 2024 11:52:22 +0200 Subject: [PATCH] Session handling bugfix, profile frontend WIP --- Core/API/PermissionAPI.class.php | 4 + Core/API/Request.class.php | 5 + Core/API/UserAPI.class.php | 4 + Core/Objects/Context.class.php | 8 +- Core/Objects/Router/Router.class.php | 2 +- index.php | 5 +- react/admin-panel/src/AdminDashboard.jsx | 4 +- react/admin-panel/src/elements/sidebar.js | 24 +- react/admin-panel/src/res/select2.min.css | 1 - .../admin-panel/src/views/profile/profile.js | 141 ++++++ react/admin-panel/src/views/settings.js | 8 +- react/shared/api.js | 3 +- react/yarn.lock | 470 +++++++++--------- yarn.lock | 213 -------- 14 files changed, 422 insertions(+), 470 deletions(-) delete mode 100644 react/admin-panel/src/res/select2.min.css create mode 100644 react/admin-panel/src/views/profile/profile.js delete mode 100644 yarn.lock diff --git a/Core/API/PermissionAPI.class.php b/Core/API/PermissionAPI.class.php index cb10e8d..ef3d625 100644 --- a/Core/API/PermissionAPI.class.php +++ b/Core/API/PermissionAPI.class.php @@ -76,6 +76,10 @@ namespace Core\API\Permission { $currentUser = $this->context->getUser(); $userGroups = $currentUser ? $currentUser->getGroups() : []; if (empty($userGroups) || empty(array_intersect($groups, array_keys($userGroups)))) { + if (!$currentUser) { + $this->result["loggedIn"] = false; + } + http_response_code(401); return $this->createError("Permission denied."); } diff --git a/Core/API/Request.class.php b/Core/API/Request.class.php index 3a1aaed..ed90c21 100644 --- a/Core/API/Request.class.php +++ b/Core/API/Request.class.php @@ -9,6 +9,7 @@ use Core\Objects\DatabaseEntity\TwoFactorToken; use Core\Objects\TwoFactor\KeyBasedTwoFactorToken; use PhpMqtt\Client\MqttClient; +// TODO: many things are only checked for external calls, e.g. loginRequired. If we call the API internally, we might get null-pointers for $context->user abstract class Request { protected Context $context; @@ -228,6 +229,7 @@ abstract class Request { if ($this->loginRequired) { if (!$session && !$apiKeyAuthorized) { $this->lastError = 'You are not logged in.'; + $this->result["loggedIn"] = false; http_response_code(401); return false; } else if ($session && !$this->check2FA()) { @@ -253,6 +255,9 @@ abstract class Request { $this->success = $req->execute(["method" => self::getEndpoint()]); $this->lastError = $req->getLastError(); if (!$this->success) { + if (!$this->context->getUser()) { + $this->result["loggedIn"] = false; + } return false; } } diff --git a/Core/API/UserAPI.class.php b/Core/API/UserAPI.class.php index cb7cd3e..e12e6d4 100644 --- a/Core/API/UserAPI.class.php +++ b/Core/API/UserAPI.class.php @@ -1231,6 +1231,10 @@ namespace Core\API\User { } return $this->success; } + + public static function getDefaultACL(Insert $insert): void { + $insert->addRow(self::getEndpoint(), [], "Allows users to update their profiles.", true); + } } class ImportGPG extends UserAPI { diff --git a/Core/Objects/Context.class.php b/Core/Objects/Context.class.php index 94778cf..52f7287 100644 --- a/Core/Objects/Context.class.php +++ b/Core/Objects/Context.class.php @@ -53,7 +53,7 @@ class Context { } } - public function setLanguage(Language $language) { + public function setLanguage(Language $language): void { $this->language = $language; $this->language->activate(); @@ -90,7 +90,7 @@ class Context { return $this->user; } - public function sendCookies() { + public function sendCookies(): void { $domain = $this->getSettings()->getDomain(); $this->language->sendCookie($domain); $this->session?->sendCookie($domain); @@ -139,7 +139,7 @@ class Context { return false; } - public function processVisit() { + public function processVisit(): void { if (isset($_COOKIE["PHPSESSID"]) && !empty($_COOKIE["PHPSESSID"])) { if ($this->isBot()) { return; @@ -206,7 +206,7 @@ class Context { ->set("active", false) ->whereEq("user_id", $this->user->getId()); - if (!$keepCurrent && $this->session !== null) { + if ($keepCurrent && $this->session !== null) { $query->whereNeq("id", $this->session->getId()); } diff --git a/Core/Objects/Router/Router.class.php b/Core/Objects/Router/Router.class.php index 24bde34..e31f1fe 100644 --- a/Core/Objects/Router/Router.class.php +++ b/Core/Objects/Router/Router.class.php @@ -76,7 +76,7 @@ class Router { } } - public function addRoute(Route $route) { + public function addRoute(Route $route): void { if (preg_match("/^\/(\d+)$/", $route->getPattern(), $re)) { $this->statusCodeRoutes[$re[1]] = $route; } diff --git a/index.php b/index.php index 170e37d..a185703 100644 --- a/index.php +++ b/index.php @@ -70,9 +70,12 @@ if ($installation) { } catch (\Error $e) { http_response_code(500); $router->getLogger()->error($e->getMessage()); - $router->returnStatusCode(500); + $response = $router->returnStatusCode(500); } } + } else { + http_response_code(500); + $response = "Router could not be instantiated."; } $context->processVisit(); diff --git a/react/admin-panel/src/AdminDashboard.jsx b/react/admin-panel/src/AdminDashboard.jsx index af40a31..49f5533 100644 --- a/react/admin-panel/src/AdminDashboard.jsx +++ b/react/admin-panel/src/AdminDashboard.jsx @@ -1,6 +1,5 @@ import React, {lazy, Suspense, useCallback, useState} from "react"; import {BrowserRouter, Route, Routes} from "react-router-dom"; -import Header from "./elements/header"; import Sidebar from "./elements/sidebar"; import Dialog from "./elements/dialog"; import Footer from "./elements/footer"; @@ -23,6 +22,7 @@ const AccessControlList = lazy(() => import("./views/access-control-list")); const RouteListView = lazy(() => import("./views/route/route-list")); const RouteEditView = lazy(() => import("./views/route/route-edit")); const SettingsView = lazy(() => import("./views/settings")); +const ProfileView = lazy(() => import("./views/profile/profile")); export default function AdminDashboard(props) { @@ -67,7 +67,6 @@ export default function AdminDashboard(props) { } return -
@@ -85,6 +84,7 @@ export default function AdminDashboard(props) { }/> }/> }/> + }/> } /> diff --git a/react/admin-panel/src/elements/sidebar.js b/react/admin-panel/src/elements/sidebar.js index 6830439..e9ca413 100644 --- a/react/admin-panel/src/elements/sidebar.js +++ b/react/admin-panel/src/elements/sidebar.js @@ -2,6 +2,22 @@ import React, {useCallback, useContext} from 'react'; import {Link, NavLink} from "react-router-dom"; import Icon from "shared/elements/icon"; import {LocaleContext} from "shared/locale"; +import {Avatar, styled} from "@mui/material"; + +const ProfileLink = styled(Link)((props) => ({ + "& > div": { + padding: 3, + width: 30, + height: 30, + }, + marginLeft: props.theme.spacing(1), + marginTop: props.theme.spacing(1), + display: "grid", + gridTemplateColumns: "45px auto", + "& > span": { + alignSelf: "center" + } +})); export default function Sidebar(props) { @@ -100,9 +116,11 @@ export default function Sidebar(props) {
- {L("account.logged_in_as")}:  - {api.user.name} - +
{L("account.logged_in_as")}:
+ + + {api.user?.name || L("account.not_logged_in")} +