Skip to content

Commit 0d8399f

Browse files
Merge branch 'widgets' into demo
2 parents 97aeece + c05970b commit 0d8399f

File tree

125 files changed

+3556
-3869
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+3556
-3869
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"commentTranslate.source": "Google"
3+
}

Readme.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
<span class="badge-npmversion"><a href="https://npmjs.org/package/adminizer" title="View this project on NPM"><img src="https://img.shields.io/npm/v/adminizer.svg" alt="NPM version" /></a></span>
44

5-
65
Adminizer is a modern admin panel built as an independent module for Node.js.
76
The backend is written in TypeScript, and the frontend uses React, providing high modularity and flexibility.
87
The system is specifically designed to be **framework- and ORM-agnostic**, running directly inside the Node.js Runtime.
@@ -11,6 +10,17 @@ Thanks to this approach, Adminizer can be integrated into any server-side applic
1110
The project is **open-source**, **free to use**, and focused on building an **open community**.
1211
We would like to express special thanks to **Konstantin Zolotarev**, who laid the foundation with the **sails-adminpanel** project, which we later reworked and generalized.
1312

13+
---
14+
15+
Follow us for updates, tutorials, and community discussions:
16+
17+
[![Telegram](https://img.shields.io/badge/Telegram-Join%20Chat-blue?logo=telegram)](https://t.me/talks_adminizer)
18+
[![X / Twitter](https://img.shields.io/badge/X-%40admnzr-000000?logo=twitter)](https://x.com/admnzr)
19+
[![Facebook](https://img.shields.io/badge/Facebook-Adminizer-blue?logo=facebook)](https://www.facebook.com/profile.php?id=61575683442665)
20+
21+
---
22+
23+
1424
The core principle of Adminizer is **maximum extensibility**.
1525
The admin panel can be configured and expanded **at runtime** without requiring rebuilds or server restarts.
1626
We aimed to make the system as easy to integrate as possible: just install the package and immediately gain access to a powerful admin interface.

docs/AccessRightsModelFields.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
### `DataAccessor` — Data Layer Mediator with Access Control
2+
3+
The `DataAccessor` class is a central utility for handling the interaction between users and the system's data models, while enforcing access control and configuration constraints.
4+
5+
---
6+
7+
#### **Purpose**
8+
9+
This class:
10+
11+
* Retrieves and merges model field configurations based on the action type (e.g., `add`, `edit`, `list`, `view`, `remove`)
12+
* Applies user permission checks at both the model and field level
13+
* Filters records according to configured access rules
14+
* Dynamically includes associated models and their configurations
15+
* Automatically applies or restricts data access based on user roles and group membership
16+
* Helps populate or restrict relation fields (e.g., `UserAP`, `GroupAP`) depending on ownership and configuration
17+
* Provides unified methods for reading (`process`, `processMany`), sanitizing (`sanitizeUserRelationAccess`), and updating (`setUserRelationAccess`) data records with permission logic baked in
18+
19+
---
20+
21+
#### **Key Features**
22+
23+
* **Access-aware field resolution**: Only exposes fields the current user is allowed to see or edit.
24+
* **Dynamic config merging**: Combines global and action-specific model field configs, ensuring the right context is applied.
25+
* **Association support**: Handles both `BelongsTo` and `HasMany` style associations with optional population and recursive field filtering.
26+
* **Multi-level access logic**: Enforces both direct and intermediate relation-based access restrictions using the `userAccessRelation` model config key.
27+
* **CRUD-agnostic**: Designed to be used with various actions (`add`, `edit`, `view`, `list`) with unified processing logic.
28+
29+
---
30+
31+
#### **Typical Use Cases**
32+
33+
* Building an admin panel or API layer where user-specific permissions restrict what data can be read, written, or modified
34+
* Ensuring consistent permission logic across different parts of the system (e.g., listing vs viewing a single item)
35+
* Populating complex forms or detail views that include nested associations with restricted fields
36+
37+
---
38+
39+
#### **Permission Logic and Configuration**
40+
41+
The `DataAccessor` supports fine-grained access control at the field level using a combination of global configuration, action-specific overrides, and user role/group validation.
42+
43+
**How Permissions Are Checked**
44+
45+
Each field passes through the `checkFieldAccess()` method, which evaluates:
46+
47+
1. **Explicit Disabling**
48+
If a field is set to `false` in the config, it will be excluded:
49+
50+
```ts
51+
fields: { secretField: false }
52+
```
53+
54+
2. **Always Allowed:**
55+
56+
* Primary key field (`id`)
57+
* All fields for admin users (`isAdministrator === true`)
58+
* Fields without any config object
59+
60+
3. **Group-Based Restrictions**
61+
If a field defines `groupsAccessRights`, access is granted only if the user's group is listed:
62+
63+
```ts
64+
fields: {
65+
internalNotes: {
66+
type: "string",
67+
groupsAccessRights: ["manager", "admin"]
68+
}
69+
}
70+
```
71+
72+
4. **Default Denial for Default Group**
73+
If no access rights are defined, the field is denied **only** to users from the `defaultUserGroup` (defined in config):
74+
75+
```ts
76+
config: {
77+
registration: {
78+
defaultUserGroup: "users"
79+
}
80+
}
81+
```
82+
83+
**Where Permissions Are Applied**
84+
85+
* During field config loading (`getFieldsConfig`)
86+
* When preparing the output for individual records (`process`)
87+
* When preparing associated models (`getAssociatedFieldsConfig`)
88+
* During write-time operations that assign ownership/access (`sanitizeUserRelationAccess`, `setUserRelationAccess`)
89+
90+
---
91+
92+
#### **Config Example**
93+
94+
```ts
95+
models: {
96+
Task: {
97+
fields: {
98+
title: { type: "string" },
99+
internalStatus: {
100+
type: "string",
101+
groupsAccessRights: ["admin", "qa"]
102+
},
103+
createdAt: false // completely hidden
104+
},
105+
userAccessRelation: "owner"
106+
}
107+
}
108+
```
109+
110+
In this example:
111+
112+
* The `title` field is visible to everyone.
113+
* `internalStatus` is only shown to admins and QA team members.
114+
* `createdAt` is hidden entirely.
115+
* Only records where the current user is the `owner` are accessible to non-admins.
File renamed without changes.

docs/Configuration/General.md

Whitespace-only changes.

docs/Configuration/Models.md

Whitespace-only changes.
File renamed without changes.

docs/index.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
1-
# Adminizer Documentation
1+
# 📘 Adminizer Documentation
22

3-
1. [Installation](Install.md)
4-
2. [Configuration](Configuration.md)
3+
## 1. Getting Started
54

5+
* [Installation](Install.md)
66

7-
2. [Form Error Management](FormError.md)
8-
3. [Inertia Adapter & Flash](InertiaAdapter.md)
9-
4. [Admin Controls](Controls.md)
7+
## 2. Configuration
8+
9+
* [General Settings](Configuration/General.md)
10+
* [Model Definitions](Configuration/Models.md)
11+
* [Field Options](Configuration/Fields.md)
12+
* [Custom Components](Configuration/CustomComponents.md)
13+
14+
## Other
15+
16+
* [Localization](Configuration/Localization.md)
17+
## 3. Frontend Integration
18+
19+
* [Inertia Adapter & Flash](InertiaAdapter.md)
20+
* [Form Error Management](FormError.md)
21+
22+
## 4. Admin Panel Features
23+
24+
* [Admin Controls](Controls.md)
25+
26+
## 5. Access Control
27+
28+
* [Model-Level Permissions](AccessControl/ModelPermissions.md)
29+
* [Field-Level Restrictions](AccessControl/FieldRestrictions.md)
30+
* [Role & Group Management](AccessControl/RoleGroups.md)

fixture/adminizerConfig.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
11
import {AdminpanelConfig} from "../dist/interfaces/adminpanelConfig";
2+
import Example from "./models/Example";
23

34
const routePrefix = "/adminizer";
45

56
const models: AdminpanelConfig["models"] = {
67
test: {
78
title: 'Test model',
89
model: 'test',
10+
// userAccessRelation: 'owner',
911
fields: {
1012
createdAt: false,
1113
updatedAt: false,
1214
title: {
1315
title: 'Title',
1416
type: 'string',
1517
required: true
16-
},
17-
owner: false
18+
}
1819
},
1920
list: {
2021
fields: {
21-
owner: false
22+
owner: false,
23+
example: {
24+
// displayModifier(d) {
25+
// console.log("________________________________")
26+
// console.dir(d)
27+
// return d
28+
// }
29+
}
30+
}
31+
},
32+
add: {
33+
fields: {
34+
ownerId: false,
35+
exampleId: false
2236
}
2337
},
2438
icon: 'receipt'
@@ -362,17 +376,19 @@ const models: AdminpanelConfig["models"] = {
362376
const config: AdminpanelConfig = {
363377
routePrefix: routePrefix,
364378
// routePrefix: "/admin",
365-
// auth: true,
366-
// registration: {
367-
// enable: true,
368-
// defaultUserGroup: "test",
369-
// confirmationRequired: false
379+
// auth: {
380+
// enable: true
370381
// },
371-
auth: {
382+
registration: {
372383
enable: true,
373-
description: "Login `demo`, password `demo`"
384+
defaultUserGroup: "guest",
385+
confirmationRequired: false
374386
},
375-
dashboard: false,
387+
// auth: {
388+
// enable: true,
389+
// description: "Login `demo`, password `demo`"
390+
// },
391+
dashboard: true,
376392
forms: {
377393
data: {
378394
global: {
@@ -502,7 +518,7 @@ const config: AdminpanelConfig = {
502518
translation: {
503519
locales: ['en', 'ru', 'de', 'ua'],
504520
path: 'config/locales', // relative path to translations directory
505-
defaultLocale: 'en'
521+
defaultLocale: 'ru'
506522
},
507523
models: models,
508524
//@ts-ignore

0 commit comments

Comments
 (0)