diff --git a/Core/API/RoutesAPI.class.php b/Core/API/RoutesAPI.class.php
index 2b5a0f3..8f6cb60 100644
--- a/Core/API/RoutesAPI.class.php
+++ b/Core/API/RoutesAPI.class.php
@@ -5,6 +5,7 @@ namespace Core\API {
use Core\API\Routes\GenerateCache;
use Core\Objects\Context;
use Core\Objects\DatabaseEntity\Route;
+ use Core\Objects\Router\ApiRoute;
abstract class RoutesAPI extends Request {
@@ -24,6 +25,8 @@ namespace Core\API {
return false;
} else if ($route === null) {
return $this->createError("Route not found");
+ } else if ($route instanceof ApiRoute) {
+ return $this->createError("This route cannot be modified");
}
$route->setActive($active);
@@ -71,6 +74,7 @@ namespace Core\API\Routes {
use Core\Objects\Context;
use Core\Objects\DatabaseEntity\Group;
use Core\Objects\DatabaseEntity\Route;
+ use Core\Objects\Router\ApiRoute;
use Core\Objects\Router\Router;
class Fetch extends RoutesAPI {
@@ -87,10 +91,7 @@ namespace Core\API\Routes {
$this->success = ($routes !== FALSE);
if ($this->success) {
- $this->result["routes"] = [];
- foreach ($routes as $route) {
- $this->result["routes"][$route->getId()] = $route->jsonSerialize();
- }
+ $this->result["routes"] = $routes;
}
return $this->success;
@@ -307,7 +308,6 @@ namespace Core\API\Routes {
parent::__construct($context, $externalCall, array(
"id" => new Parameter("id", Parameter::TYPE_INT)
));
- $this->isPublic = false;
}
public function _execute(): bool {
@@ -319,6 +319,8 @@ namespace Core\API\Routes {
return $this->createError("Error fetching route: " . $sql->getLastError());
} else if ($route === null) {
return $this->createError("Route not found");
+ } else if ($route instanceof ApiRoute) {
+ return $this->createError("This route cannot be deleted");
}
$this->success = $route->delete($sql) !== false;
@@ -336,7 +338,6 @@ namespace Core\API\Routes {
parent::__construct($context, $externalCall, array(
"id" => new Parameter("id", Parameter::TYPE_INT)
));
- $this->isPublic = false;
}
public function _execute(): bool {
@@ -354,7 +355,6 @@ namespace Core\API\Routes {
parent::__construct($context, $externalCall, array(
"id" => new Parameter("id", Parameter::TYPE_INT)
));
- $this->isPublic = false;
}
public function _execute(): bool {
@@ -373,7 +373,6 @@ namespace Core\API\Routes {
public function __construct(Context $context, bool $externalCall = false) {
parent::__construct($context, $externalCall, []);
- $this->isPublic = false;
$this->router = null;
}
@@ -408,7 +407,10 @@ namespace Core\API\Routes {
}
public static function getDefaultACL(Insert $insert): void {
- $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to regenerate the routing cache", true);
+ $insert->addRow(self::getEndpoint(),
+ [Group::ADMIN, Group::SUPPORT],
+ "Allows users to regenerate the routing cache", true
+ );
}
}
diff --git a/Core/Objects/Router/DocumentRoute.class.php b/Core/Objects/Router/DocumentRoute.class.php
index bb2b8c1..b00cdd8 100644
--- a/Core/Objects/Router/DocumentRoute.class.php
+++ b/Core/Objects/Router/DocumentRoute.class.php
@@ -5,6 +5,7 @@ namespace Core\Objects\Router;
use Core\Driver\SQL\SQL;
use Core\Elements\Document;
use Core\Objects\Context;
+use Core\Objects\DatabaseEntity\Attribute\Transient;
use Core\Objects\DatabaseEntity\Route;
use Core\Objects\Search\Searchable;
use Core\Objects\Search\SearchQuery;
@@ -15,7 +16,10 @@ class DocumentRoute extends Route {
use Searchable;
+ #[Transient]
private array $args;
+
+ #[Transient]
private ?\ReflectionClass $reflectionClass = null;
public function __construct(string $pattern, bool $exact, string $className, ...$args) {
diff --git a/Core/Objects/Router/RedirectRoute.class.php b/Core/Objects/Router/RedirectRoute.class.php
index cc2e880..1c0ea39 100644
--- a/Core/Objects/Router/RedirectRoute.class.php
+++ b/Core/Objects/Router/RedirectRoute.class.php
@@ -2,11 +2,13 @@
namespace Core\Objects\Router;
+use Core\Objects\DatabaseEntity\Attribute\Transient;
use Core\Objects\DatabaseEntity\Route;
use JetBrains\PhpStorm\Pure;
class RedirectRoute extends Route {
+ #[Transient]
private int $code;
public function __construct(string $type, string $pattern, bool $exact, string $destination, int $code = 307) {
diff --git a/Core/Objects/Router/StaticFileRoute.class.php b/Core/Objects/Router/StaticFileRoute.class.php
index 80c34e7..8671a4a 100644
--- a/Core/Objects/Router/StaticFileRoute.class.php
+++ b/Core/Objects/Router/StaticFileRoute.class.php
@@ -4,6 +4,7 @@ namespace Core\Objects\Router;
use Core\Driver\SQL\SQL;
use Core\Objects\Context;
+use Core\Objects\DatabaseEntity\Attribute\Transient;
use Core\Objects\DatabaseEntity\Route;
use Core\Objects\Search\Searchable;
use Core\Objects\Search\SearchQuery;
@@ -14,6 +15,7 @@ class StaticFileRoute extends Route {
use Searchable;
+ #[Transient]
private int $code;
public function __construct(string $pattern, bool $exact, string $path, int $code = 200) {
diff --git a/Core/Objects/Router/StaticRoute.class.php b/Core/Objects/Router/StaticRoute.class.php
index 6fa509d..553700f 100644
--- a/Core/Objects/Router/StaticRoute.class.php
+++ b/Core/Objects/Router/StaticRoute.class.php
@@ -2,11 +2,15 @@
namespace Core\Objects\Router;
+use Core\Objects\DatabaseEntity\Attribute\Transient;
use Core\Objects\DatabaseEntity\Route;
class StaticRoute extends Route {
+ #[Transient]
private string $data;
+
+ #[Transient]
private int $code;
public function __construct(string $pattern, bool $exact, string $data, int $code = 200) {
diff --git a/react/admin-panel/src/AdminDashboard.jsx b/react/admin-panel/src/AdminDashboard.jsx
index d846fab..1e0e14b 100644
--- a/react/admin-panel/src/AdminDashboard.jsx
+++ b/react/admin-panel/src/AdminDashboard.jsx
@@ -20,6 +20,7 @@ const GroupListView = lazy(() => import('./views/group/group-list'));
const EditGroupView = lazy(() => import('./views/group/group-edit'));
const LogView = lazy(() => import("./views/log-view"));
const AccessControlList = lazy(() => import("./views/access-control-list"));
+const RouteListView = lazy(() => import("./views/routes"));
export default function AdminDashboard(props) {
@@ -79,6 +80,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 658e3fb..da8b2aa 100644
--- a/react/admin-panel/src/elements/sidebar.js
+++ b/react/admin-panel/src/elements/sidebar.js
@@ -36,7 +36,7 @@ export default function Sidebar(props) {
"name": "admin.groups",
"icon": "users-cog"
},
- "pages": {
+ "routes": {
"name": "admin.page_routes",
"icon": "copy",
},
diff --git a/react/admin-panel/src/views/access-control-list.js b/react/admin-panel/src/views/access-control-list.js
index bf20f64..8b5aecc 100644
--- a/react/admin-panel/src/views/access-control-list.js
+++ b/react/admin-panel/src/views/access-control-list.js
@@ -12,12 +12,11 @@ import {
TableContainer,
TableHead,
TableRow,
- IconButton
+ IconButton, styled
} from "@material-ui/core";
import {Add, Delete, Edit, Refresh} from "@material-ui/icons";
import {USER_GROUP_ADMIN} from "shared/constants";
import Dialog from "shared/elements/dialog";
-import {TableFooter} from "@mui/material";
export default function AccessControlList(props) {
@@ -74,18 +73,22 @@ export default function AccessControlList(props) {
const onChangePermission = useCallback((methodIndex, groupId, selected) => {
let newGroups = null;
let currentGroups = acl[methodIndex].groups;
- let groupIndex = currentGroups.indexOf(groupId);
- if (!selected) {
- if (currentGroups.length === 0) {
- // it was an "everyone permission" before
- newGroups = groups.filter(group => group.id !== groupId).map(group => group.id);
- } else if (groupIndex !== -1 && currentGroups.length > 1) {
+ if (groupId === null) {
+ newGroups = [];
+ } else {
+ let groupIndex = currentGroups.indexOf(groupId);
+ if (!selected) {
+ if (currentGroups.length === 0) {
+ // it was an "everyone permission" before
+ newGroups = groups.filter(group => group.id !== groupId).map(group => group.id);
+ } else if (groupIndex !== -1) {
+ newGroups = [...currentGroups];
+ newGroups.splice(groupIndex, 1);
+ }
+ } else if (groupIndex === -1) {
newGroups = [...currentGroups];
- newGroups.splice(groupIndex, 1);
+ newGroups.push(groupId);
}
- } else if (groupIndex === -1) {
- newGroups = [...currentGroups];
- newGroups.push(groupId);
}
if (newGroups !== null) {
@@ -94,6 +97,7 @@ export default function AccessControlList(props) {
let newACL = [...acl];
newACL[methodIndex].groups = newGroups;
setACL(newACL);
+ props.api.fetchUser();
} else {
props.showDialog("Error updating permission: " + data.msg);
}
@@ -106,6 +110,7 @@ export default function AccessControlList(props) {
if (data.success) {
let newACL = acl.filter(acl => acl.method.toLowerCase() !== method.toLowerCase());
setACL(newACL);
+ props.api.fetchUser();
} else {
props.showDialog("Error deleting permission: " + data.msg);
}
@@ -119,6 +124,7 @@ export default function AccessControlList(props) {
newACL.push({method: inputData.method, groups: groups, description: inputData.description});
newACL = newACL.sort((a, b) => a.method.localeCompare(b.method))
setACL(newACL);
+ props.api.fetchUser();
} else {
props.showDialog("Error updating permission: " + data.msg);
}
@@ -180,8 +186,13 @@ export default function AccessControlList(props) {
+
+ onChangePermission(index, null, e.target.checked)}
+ disabled={isRestricted(permission.method)} />
+
{groups.map(group =>
- onChangePermission(index, group.id, e.target.checked)}
disabled={isRestricted(permission.method)} />
)}
@@ -192,6 +203,11 @@ export default function AccessControlList(props) {
return <>{rows}>
}
+ const BorderedColumn = styled(TableCell)({
+ borderLeft: "1px dotted #666",
+ borderRight: "1px dotted #666",
+ });
+
return <>
@@ -244,23 +260,22 @@ export default function AccessControlList(props) {
-
-
-
-
-
- {L("permission")}
- { groups.map(group =>
- {group.name}
- ) }
-
-
-
-
-
-
-
-
+
+
+
+
+ {L("permission")}
+ {L("everyone")}
+ { groups.map(group =>
+ {group.name}
+ ) }
+
+
+
+
+
+
+