adminizer 4.0.0-commit.a0ff2f0 → 4.0.0-commit.d27d87e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/{app-B3KHqZ_H.css → app-C4A2HUBD.css} +1 -1
- package/assets/app.js +2 -2
- package/assets/field-renderer-CvC9UdC0.js +1 -1
- package/assets/home-CmIZ3AL2.js +1 -1
- package/assets/login-Bg7ZQrZc.js +6 -0
- package/assets/manifest.json +2 -2
- package/controllers/add.d.ts +1 -1
- package/controllers/add.js +7 -17
- package/controllers/addGroup.js +1 -4
- package/controllers/addUser.js +1 -4
- package/controllers/catalog/Catalog.js +1 -1
- package/controllers/ckeditorUpload.js +1 -1
- package/controllers/dashboard.d.ts +1 -1
- package/controllers/dashboard.js +2 -4
- package/controllers/edit.js +7 -13
- package/controllers/editGroup.js +1 -3
- package/controllers/editUser.js +1 -3
- package/controllers/form.js +1 -2
- package/controllers/getAllWidgets.js +1 -1
- package/controllers/initUser.js +1 -1
- package/controllers/list.js +1 -1
- package/controllers/login.js +3 -4
- package/controllers/media-manager/mediaManagerApi.js +1 -1
- package/controllers/navigation/edit.js +1 -1
- package/controllers/processInstallFinalize.js +1 -1
- package/controllers/processInstallStep.js +1 -1
- package/controllers/register.js +1 -5
- package/controllers/remove.js +1 -4
- package/controllers/timezones.js +1 -1
- package/controllers/view.js +1 -6
- package/controllers/welcome.js +1 -1
- package/controllers/widgets/Action.js +1 -1
- package/controllers/widgets/Custom.js +1 -1
- package/controllers/widgets/Info.js +1 -1
- package/controllers/widgets/switch.js +1 -1
- package/controllers/widgetsDB.js +1 -1
- package/helpers/accessRightsHelper.js +1 -1
- package/helpers/inertiaAddHelper.d.ts +5 -5
- package/interfaces/adminpanelConfig.d.ts +6 -1
- package/lib/Adminizer.js +1 -5
- package/lib/controls/ControlsHandler.d.ts +1 -1
- package/lib/controls/ControlsHandler.js +1 -1
- package/lib/datatable/NodeTable.js +0 -42
- package/lib/inertia/inertiaAdapter.js +1 -1
- package/package.json +3 -3
- package/policies/checkAuth.js +1 -1
- package/system/Router.js +0 -2
- package/system/bindAuthorization.js +17 -2
- package/system/bindInertia.js +2 -2
- package/system/defaults.js +3 -0
- package/assets/login-B7INjWDi.js +0 -6
- package/controllers/listJson.d.ts +0 -1
- package/controllers/listJson.js +0 -35
- package/helpers/viewsHelper.d.ts +0 -44
- package/helpers/viewsHelper.js +0 -82
- package/system/bindResFunctions.d.ts +0 -2
- package/system/bindResFunctions.js +0 -52
- package/system/bindViewsLocals.d.ts +0 -2
- package/system/bindViewsLocals.js +0 -19
package/controllers/widgetsDB.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default async function widgetsDB(req, res) {
|
|
2
2
|
let id = 0;
|
|
3
|
-
let auth = req.adminizer.config.auth;
|
|
3
|
+
let auth = req.adminizer.config.auth.enable;
|
|
4
4
|
if (auth) {
|
|
5
5
|
if (!req.session.UserAP) {
|
|
6
6
|
return res.redirect(`${req.adminizer.config.routePrefix}/model/userap/login`);
|
|
@@ -42,7 +42,7 @@ export class AccessRightsHelper {
|
|
|
42
42
|
return tokens.some((token) => this.hasPermission(token, user));
|
|
43
43
|
}
|
|
44
44
|
hasPermission(tokenId, user) {
|
|
45
|
-
if (!this.adminizer.config.auth) {
|
|
45
|
+
if (!this.adminizer.config.auth.enable) {
|
|
46
46
|
return true;
|
|
47
47
|
}
|
|
48
48
|
if (user.isAdministrator) {
|
|
@@ -51,6 +51,10 @@ export declare function getControlsOptions(fieldConfig: BaseFieldConfig, req: Re
|
|
|
51
51
|
theme?: string;
|
|
52
52
|
autofocus?: boolean;
|
|
53
53
|
viewer?: boolean;
|
|
54
|
+
} | {
|
|
55
|
+
items: string[];
|
|
56
|
+
} | {
|
|
57
|
+
[x: string]: string | number | boolean | object | string[] | Record<string, unknown>;
|
|
54
58
|
} | {
|
|
55
59
|
activeHeaderClassName?: string;
|
|
56
60
|
allowEmpty?: boolean;
|
|
@@ -428,14 +432,10 @@ export declare function getControlsOptions(fieldConfig: BaseFieldConfig, req: Re
|
|
|
428
432
|
}) => void;
|
|
429
433
|
persistentStateReset?: (key: string) => void;
|
|
430
434
|
persistentStateSave?: (key: string, value: any) => void;
|
|
431
|
-
} | {
|
|
432
|
-
items: string[];
|
|
433
|
-
} | {
|
|
434
|
-
[x: string]: string | number | boolean | object | string[] | Record<string, unknown>;
|
|
435
435
|
};
|
|
436
436
|
path: {};
|
|
437
437
|
};
|
|
438
|
-
export declare function inputText(type: string, isIn: string[]): "email" | "password" | "
|
|
438
|
+
export declare function inputText(type: string, isIn: string[]): "email" | "password" | "number" | "date" | "time" | "color" | "month" | "week" | "range" | "text" | "select" | "datetime-local";
|
|
439
439
|
export declare function getControl(req: ReqType, type: ControlType, name: string | undefined, defaultControlName: string): AbstractControls;
|
|
440
440
|
export declare function setSelectMany(isIn: string[], value: string[] | undefined): {
|
|
441
441
|
initOptions: {
|
|
@@ -25,8 +25,12 @@ export interface AdminpanelConfig {
|
|
|
25
25
|
theme?: string;
|
|
26
26
|
/**
|
|
27
27
|
* Enable or disable auth for adminpanel
|
|
28
|
+
* by default is false
|
|
28
29
|
*/
|
|
29
|
-
auth?:
|
|
30
|
+
auth?: {
|
|
31
|
+
enable: boolean;
|
|
32
|
+
description?: string;
|
|
33
|
+
};
|
|
30
34
|
/**
|
|
31
35
|
* @alpha
|
|
32
36
|
* Models configuration
|
|
@@ -430,4 +434,5 @@ export interface MediaManagerConfig {
|
|
|
430
434
|
};
|
|
431
435
|
};
|
|
432
436
|
}
|
|
437
|
+
export type AdminizerConfig = AdminpanelConfig;
|
|
433
438
|
export {};
|
package/lib/Adminizer.js
CHANGED
|
@@ -6,7 +6,6 @@ import EventEmitter from 'events';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import PolicyManager from "./v4/PolicyManager";
|
|
8
8
|
import Router from "./../system/Router";
|
|
9
|
-
import { ViewsHelper } from "../helpers/viewsHelper";
|
|
10
9
|
import bindAssets from "../system/bindAssets";
|
|
11
10
|
import bindDev from "../system/bindDev";
|
|
12
11
|
import bindDashboardWidgets from "../system/bindDashboardWidgets";
|
|
@@ -99,7 +98,6 @@ export class Adminizer {
|
|
|
99
98
|
this.modelHandler = new ModelHandler();
|
|
100
99
|
await bindModels(this);
|
|
101
100
|
await bindForms(this);
|
|
102
|
-
this.config.templateRootPath = ViewsHelper.BASE_VIEWS_PATH;
|
|
103
101
|
this.config.rootPath = path.resolve(import.meta.dirname + "/..");
|
|
104
102
|
this.policyManager = new PolicyManager(this);
|
|
105
103
|
await this.policyManager.loadPolicies();
|
|
@@ -108,10 +106,9 @@ export class Adminizer {
|
|
|
108
106
|
this.menuHelper = new MenuHelper(this.config);
|
|
109
107
|
this.widgetHandler = new WidgetHandler(this);
|
|
110
108
|
bindExpressUtils(this.app);
|
|
111
|
-
// bindResFunctions(this);
|
|
112
109
|
bindReqFunctions(this);
|
|
113
110
|
// add install stepper policy to check unfilled settings
|
|
114
|
-
// bindInstallStepper(this);
|
|
111
|
+
// bindInstallStepper(this); // TODO It is necessary to provide an opportunity to be inserted by an intermediary after authorization, but before the admin panel, in order to block the user from managing the Installstepper's admin panel.
|
|
115
112
|
// Bind assets
|
|
116
113
|
bindAssets(this.app, this.config.routePrefix);
|
|
117
114
|
if ((process.env.DEV && process.env.NODE_ENV !== 'production') || process.env.ADMINPANEL_FORCE_BIND_DEV === "TRUE") {
|
|
@@ -121,7 +118,6 @@ export class Adminizer {
|
|
|
121
118
|
// bindNavigation(this);
|
|
122
119
|
// bindMediaManager(this);
|
|
123
120
|
await bindAccessRights(this);
|
|
124
|
-
// bindViewsLocals(this); // must be after setting all helpers that binds in here
|
|
125
121
|
if (I18n.appendLocale) {
|
|
126
122
|
bindTranslations(this);
|
|
127
123
|
}
|
|
@@ -6,5 +6,5 @@ export declare class ControlsHandler {
|
|
|
6
6
|
getByType<T extends ControlType>(type: T): AbstractControls[];
|
|
7
7
|
remove(type: ControlType, name: string): boolean;
|
|
8
8
|
getAll(): Record<ControlType, AbstractControls[]>;
|
|
9
|
-
collectAndGenerateStyleLinks(
|
|
9
|
+
collectAndGenerateStyleLinks(): string[];
|
|
10
10
|
}
|
|
@@ -33,7 +33,7 @@ export class ControlsHandler {
|
|
|
33
33
|
Array.from(group.values())
|
|
34
34
|
]));
|
|
35
35
|
}
|
|
36
|
-
collectAndGenerateStyleLinks(
|
|
36
|
+
collectAndGenerateStyleLinks() {
|
|
37
37
|
const stylesheets = [];
|
|
38
38
|
const allControls = this.getAll();
|
|
39
39
|
Object.values(allControls).forEach(controls => {
|
|
@@ -152,48 +152,6 @@ export class NodeTable {
|
|
|
152
152
|
callback(error, null);
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
-
// mapData(data: { [key: string]: any }): object[] {
|
|
156
|
-
// let out: object[] = [];
|
|
157
|
-
// data.forEach((elem: any) => {
|
|
158
|
-
// let row: any = [elem[this.model.primaryKey ?? 'id']];
|
|
159
|
-
// Object.keys(this.fields).forEach((key: string) => {
|
|
160
|
-
// let fieldConfigConfig = this.fields[key].config as BaseFieldConfig;
|
|
161
|
-
// if (fieldConfigConfig.displayModifier) {
|
|
162
|
-
// row.push(fieldConfigConfig.displayModifier(elem[key]));
|
|
163
|
-
// } else if (this.fields[key].model && this.fields[key].model.model) {
|
|
164
|
-
// // Обработка связей типа "belongsTo"
|
|
165
|
-
// if (!elem[key]) {
|
|
166
|
-
// row.push(null);
|
|
167
|
-
// } else {
|
|
168
|
-
// row.push(elem[key][fieldConfigConfig.displayField]);
|
|
169
|
-
// }
|
|
170
|
-
// } else if (this.fields[key].model.type === "association-many" || this.fields[key].model.type === "association") {
|
|
171
|
-
// if (!elem[key] || elem[key].length === 0) {
|
|
172
|
-
// row.push(null);
|
|
173
|
-
// } else {
|
|
174
|
-
// let displayValues: string[] = [];
|
|
175
|
-
// elem[key].forEach((item: any) => {
|
|
176
|
-
// if (item[fieldConfigConfig.displayField]) {
|
|
177
|
-
// displayValues.push(item[fieldConfigConfig.displayField]);
|
|
178
|
-
// } else {
|
|
179
|
-
// displayValues.push(item[fieldConfigConfig.identifierField]);
|
|
180
|
-
// }
|
|
181
|
-
// });
|
|
182
|
-
// row.push(displayValues.join(', '));
|
|
183
|
-
// }
|
|
184
|
-
//
|
|
185
|
-
// } else if (this.fields[key].model.type === "json") {
|
|
186
|
-
// let str = JSON.stringify(elem[key]);
|
|
187
|
-
// row.push(str === "{}" ? "" : str);
|
|
188
|
-
// } else {
|
|
189
|
-
// row.push(elem[key]);
|
|
190
|
-
// }
|
|
191
|
-
// });
|
|
192
|
-
// out.push(row);
|
|
193
|
-
// });
|
|
194
|
-
//
|
|
195
|
-
// return out;
|
|
196
|
-
// }
|
|
197
155
|
mapData(data) {
|
|
198
156
|
let out = [];
|
|
199
157
|
data.forEach((elem) => {
|
|
@@ -23,7 +23,7 @@ const inertiaExpressAdapter = function ({ version, html, flashMessages, enableRe
|
|
|
23
23
|
const csrfHeader = req.headers[csrf.headerName || 'x-xsrf-token'];
|
|
24
24
|
// console.log('headers:', req.headers['x-xsrf-token']);
|
|
25
25
|
if (!csrfCookie || !csrfHeader || csrfCookie !== csrfHeader) {
|
|
26
|
-
res.status(403).
|
|
26
|
+
res.status(403).send({ message: 'Invalid CSRF token' });
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adminizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.0-commit.
|
|
4
|
+
"version": "4.0.0-commit.d27d87e",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"build:react-quill": "vite build --config modules/controls/wysiwyg/vite.config.react-quill.ts",
|
|
18
18
|
"copy:modules": "node copy-modules.js",
|
|
19
19
|
"build:assets:modules": "npm run build:assets && npm run copy:modules",
|
|
20
|
-
"start:seed": "cross-env SEED_DATA=true tsx --tsconfig ./waterlineFixture/tsconfig.json ./waterlineFixture/index.ts",
|
|
20
|
+
"start:seed": "cross-env SEED_DATA=true DEMO=true tsx --tsconfig ./waterlineFixture/tsconfig.json ./waterlineFixture/index.ts",
|
|
21
21
|
"demo:build": "npm run copy:backend && npm run compile:backend && npm run build:assets && npm run copy:modules",
|
|
22
22
|
"demo": "npm run start:seed"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [],
|
|
25
25
|
"author": "",
|
|
26
|
-
"license": "
|
|
26
|
+
"license": "MIT",
|
|
27
27
|
"description": "",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@radix-ui/react-menubar": "^1.1.12",
|
package/policies/checkAuth.js
CHANGED
|
@@ -3,7 +3,7 @@ export default async function checkAuth(req, res, proceed) {
|
|
|
3
3
|
if (typeof req.adminizer.config.translation !== 'boolean') {
|
|
4
4
|
locale = req.adminizer.config.translation.defaultLocale;
|
|
5
5
|
}
|
|
6
|
-
if (!req.adminizer.config.auth) {
|
|
6
|
+
if (!req.adminizer.config.auth.enable) {
|
|
7
7
|
if (req.session.UserAP) {
|
|
8
8
|
req.session.UserAP.isAdministrator = true;
|
|
9
9
|
}
|
package/system/Router.js
CHANGED
|
@@ -3,7 +3,6 @@ import _processInstallFinalize from "../controllers/processInstallFinalize";
|
|
|
3
3
|
import _dashboard from "../controllers/dashboard";
|
|
4
4
|
import _welcome from "../controllers/welcome";
|
|
5
5
|
import _list from "../controllers/list";
|
|
6
|
-
import _listJson from "../controllers/listJson";
|
|
7
6
|
import _edit from "../controllers/edit";
|
|
8
7
|
import _add from "../controllers/add";
|
|
9
8
|
import _view from "../controllers/view";
|
|
@@ -143,7 +142,6 @@ export default class Router {
|
|
|
143
142
|
* View record details
|
|
144
143
|
*/
|
|
145
144
|
adminizer.app.all(baseRoute + "/view/:id", adminizer.policyManager.bindPolicies(policies, _view));
|
|
146
|
-
adminizer.app.all(baseRoute + "/json", adminizer.policyManager.bindPolicies(policies, _listJson));
|
|
147
145
|
/**
|
|
148
146
|
* Remove record
|
|
149
147
|
*/
|
|
@@ -60,15 +60,30 @@ export default async function bindAuthorization(adminizer) {
|
|
|
60
60
|
console.table(adminsCredentials);
|
|
61
61
|
console.groupEnd();
|
|
62
62
|
}
|
|
63
|
+
else if (process.env.ADMINPANEL_DEMO_ADMIN_ENABLE !== undefined) {
|
|
64
|
+
try {
|
|
65
|
+
let passwordHashed = generate("demodemo");
|
|
66
|
+
let password = 'masked';
|
|
67
|
+
// TODO refactor CRUD functions for DataAccessor usage
|
|
68
|
+
await adminizer.modelHandler.model.get("UserAP")?.["_create"]({
|
|
69
|
+
login: 'demo', password: 'demo', passwordHashed: passwordHashed, fullName: "Administrator",
|
|
70
|
+
isActive: true, isAdministrator: true
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
Adminizer.log.error("Could not create demo administrator profile", e);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
63
78
|
else { // try to create one if we don't
|
|
64
|
-
if (adminizer.config.auth) {
|
|
79
|
+
if (adminizer.config.auth.enable) {
|
|
65
80
|
Adminizer.log.debug(`Adminpanel does not have an administrator`);
|
|
66
81
|
adminizer.config.policies.push(initUserPolicy);
|
|
67
82
|
//@ts-ignore
|
|
68
83
|
adminizer.app.use(`${adminizer.config.routePrefix}/init_user`, _initUser);
|
|
69
84
|
}
|
|
70
85
|
}
|
|
71
|
-
if (adminizer.config.auth) {
|
|
86
|
+
if (adminizer.config.auth.enable) {
|
|
72
87
|
adminizer.app.use(baseRoute + '/login', adminizer.policyManager.bindPolicies(policies, _login));
|
|
73
88
|
adminizer.app.use(baseRoute + '/logout', adminizer.policyManager.bindPolicies(policies, _login));
|
|
74
89
|
adminizer.app.use(baseRoute + '/register', adminizer.policyManager.bindPolicies(policies, _register));
|
package/system/bindInertia.js
CHANGED
|
@@ -50,7 +50,7 @@ export function bindInertia(adminizer) {
|
|
|
50
50
|
scripts.push(`<script type="module" src="${href}"></script>`);
|
|
51
51
|
}
|
|
52
52
|
// Load modules CSS
|
|
53
|
-
const modulesCss = adminizer.controlsHandler.collectAndGenerateStyleLinks(
|
|
53
|
+
const modulesCss = adminizer.controlsHandler.collectAndGenerateStyleLinks();
|
|
54
54
|
modulesCss.forEach(cssPath => {
|
|
55
55
|
preloadLinks.push(`<link rel="preload" href="${cssPath}" as="style">`);
|
|
56
56
|
stylesheets.push(`<link rel="stylesheet" href="${cssPath}">`);
|
|
@@ -132,7 +132,7 @@ function checkAuth(req, adminizer) {
|
|
|
132
132
|
if (typeof adminizer.config.translation !== 'boolean') {
|
|
133
133
|
locale = adminizer.config.translation.defaultLocale;
|
|
134
134
|
}
|
|
135
|
-
if (!adminizer.config.auth) {
|
|
135
|
+
if (!adminizer.config.auth.enable) {
|
|
136
136
|
if (req.session.UserAP) {
|
|
137
137
|
req.session.UserAP.isAdministrator = true;
|
|
138
138
|
}
|
package/system/defaults.js
CHANGED
package/assets/login-B7INjWDi.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{r as ie,K as Ge,m as Ke,j as l,$ as qe}from"./app.js";import{c as Ve}from"./compiler-runtime-tM4jBQ-T.js";import{L as je}from"./label-BH_NLtVH.js";import{I as Be}from"./input-coEb8Hta.js";import{Icon as ye}from"./icon-CgDnRol2.js";import{B as Ce}from"./button-CcO4Q6h6.js";import{T as We,t as Xe}from"./sonner-Dzckw3U3.js";import we from"./input-error-Dt30bqav.js";import{i as Ye}from"./use-appearance-CL_TqHcP.js";import{c as Je}from"./createLucideIcon-BFG25zNo.js";import{L as Qe}from"./loader-circle-Utah5tGx.js";import"./index-Dv6YbCDH.js";import"./utils-jAU0Cazi.js";import"./index-CNFwBlc7.js";/**
|
|
2
|
-
* @license lucide-react v0.485.0 - ISC
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the ISC license.
|
|
5
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const Ze=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],Ae=Je("user",Ze),Ee=(e,n,s)=>{let r=1n,t=e%s;for(;n;)n&1n&&(r=r*t%s),t=t*t%s,n=n>>1n;return r};function ae(e,n,s){return typeof e=="bigint"&&typeof n=="bigint"&&typeof s=="bigint"?Ee(e,n,s):Number(Ee(BigInt(e),BigInt(n),BigInt(s)))}const S=crypto,en=new TextEncoder,nn=new TextDecoder("utf-8",{ignoreBOM:!0}),ee={encode:e=>en.encode(e),decode:e=>nn.decode(e)},Me=(()=>{const n=[..."0123456789abcdef"],s=new Array(256);for(let r=0;r<256;r++)s[r]=`${n[r>>>4&15]}${n[r&15]}`;return s})(),tn=(()=>{const e={};for(let n=0;n<256;n++){const s=Me[n],r=s[0],t=r.toUpperCase(),c=s[1],o=c.toUpperCase();e[s]=n,e[`${r}${o}`]=n,e[`${t}${c}`]=n,e[`${t}${o}`]=n}return e})(),sn=e=>!(e.length%2||!/^[a-fA-F0-9]*$/.test(e)),xe={encode:e=>{let n="";for(let s=0,r=e.length;s<r;s++)n+=Me[e[s]];return n},encodeStr:e=>xe.encode(ee.encode(e)),decode:e=>{const n=e.length/2,s=new Uint8Array(n);for(let r=0;r<n;r++)s[r]=tn[e.slice(r*2,r*2+2)];return s},decodeStr:e=>ee.decode(xe.decode(e)),is:sn},Pe=e=>xe.encode(e),Ne=new TextEncoder,le=e=>{const n=async o=>o instanceof Uint8Array?S.subtle.importKey("raw",o,{name:"PBKDF2"},!1,["deriveBits"]):typeof o=="string"?n(Ne.encode(o.normalize())):o,s=(o,i,a,d)=>(i=typeof i=="string"?Ne.encode(i):i,S.subtle.deriveBits({name:"PBKDF2",salt:i,iterations:a,hash:{name:e}},o,d)),r=async(o,i,a,d)=>{const f=await n(o);return await s(f,i,a,d*8)},t=async(o,i,a,d)=>new Uint8Array(await r(o,i,a,d)),c=async(o,i,a,d)=>Pe(await t(o,i,a,d));return c.buffer=r,c.hex=c,c.uint8=t,c},$e={sha1:le("SHA-1"),sha256:le("SHA-256"),sha384:le("SHA-384"),sha512:le("SHA-512")},be=e=>{const n=new Uint8Array(e);return S.getRandomValues(n),n},rn=new TextEncoder,de=e=>{const n=t=>(t=typeof t=="string"?rn.encode(t):t,S.subtle.digest(e,t)),s=async t=>new Uint8Array(await n(t)),r=async t=>Pe(await s(t));return r.buffer=n,r.hex=r,r.uint8=s,r};de("SHA-1");const Re=de("SHA-256");de("SHA-384");de("SHA-512");const b={encode:e=>{if(e!==e>>0)throw new Error("Invalid 32-bit integer");const n=e>>24&255,s=e>>16&255,r=e>>8&255,t=e>>0&255;return new Uint8Array([n,s,r,t])},decode:e=>{if(e.length!==4)throw new Error("Invalid 32-bit integer");const n=e[0],s=e[1],r=e[2],t=e[3];return(n<<24)+(s<<16)+(r<<8)+(t<<0)}},Fe=e=>{const n=e.reduce((r,t)=>r+t.byteLength,0),s=new Uint8Array(n);for(let r=0,t=0,c=e.length;t<c;t++)s.set(e[t],r),r+=e[t].byteLength;return s},on=async(e,n,s,r)=>{e=typeof e=="string"?ee.encode(e):e,s=typeof s=="string"?ee.encode(s):s||be(32),s=s.length===32?s:await Re.uint8(s);const t=new Uint8Array([1]),c=Math.max(1,r||0),o=await $e.sha256.uint8(n,s,c,32),i=await S.subtle.importKey("raw",o,"AES-GCM",!1,["encrypt"]),a=be(16),d=await S.subtle.encrypt({name:"AES-GCM",iv:a,length:256,tagLength:128},i,e),f=new Uint8Array(d);return Fe([t,s,b.encode(c),a,f])},cn=async(e,n)=>{if(e[0]!==1)throw new Error("Unsupported encrypted archive version");const r=e.subarray(1,33),t=b.decode(e.subarray(33,37)),c=e.subarray(37,53),o=e.subarray(53),i=await $e.sha256.uint8(n,r,t,32),a=await S.subtle.importKey("raw",i,"AES-GCM",!1,["decrypt"]),d=await S.subtle.decrypt({name:"AES-GCM",iv:c,length:256,tagLength:128},a,o);return new Uint8Array(d)},Ie=Object.freeze(Object.defineProperty({__proto__:null,decrypt:cn,encrypt:on},Symbol.toStringTag,{value:"Module"}));function Z(e){let n,s=0;return()=>((!n||s===n.length)&&(n=new e(65536/(e.BYTES_PER_ELEMENT*8)),s=0,S.getRandomValues(n)),n[s++])}function ln(e,n){let s=0,r=n;return()=>(r===n&&(s=e(),r=0),s&1<<r++?1:0)}const ne={get1:ln(Z(Uint8Array),8),get8:Z(Uint8Array),get16:Z(Uint16Array),get32:Z(Uint32Array),get64:Z(BigUint64Array)},an=Object.assign(()=>BigInt(ne.get1()),{BITS:1}),dn=Object.assign(()=>BigInt(ne.get8()),{BITS:8}),un=Object.assign(()=>BigInt(ne.get16()),{BITS:16}),fn=Object.assign(()=>BigInt(ne.get32()),{BITS:32}),pn=Object.assign(()=>ne.get64(),{BITS:64}),u=e=>{const n=e<=1?an:e<=8?dn:e<=16?un:e<=32?fn:pn,s=n.BITS;if(e===s)return n();if(e===128)return n()<<64n|n();if(e===160)return u(128)<<32n|u(32);if(e===192)return u(128)<<64n|u(64);if(e===224)return u(160)<<64n|u(64);if(e===256)return u(128)<<128n|u(128);if(e===384)return u(256)<<128n|u(128);if(e===512)return u(256)<<256n|u(256);if(e===1024)return u(512)<<512n|u(512);if(e===2048)return u(1024)<<1024n|u(1024);let r=0,t=0n;for(;r<e;){const c=Math.min(s,e-r),o=2n**BigInt(c)-1n,a=n()&o;if(e===c)return a;t=r?t|a<<BigInt(r):a,r+=c}return t},He=(e,n)=>{if(e=BigInt(e),n=BigInt(n),e<0n||n<0n)throw new Error("Negative ranges are not supported");if(n<=e)throw new Error('"max" must be at least equal to "min" plus 1');const s=n-e-1n,r=s.toString(2).length;for(;;){const t=u(r);if(!(t>s))return t+e}},Le=[2n,3n,5n,7n,11n,13n,17n,19n,23n,29n,31n,37n,41n,43n,47n,53n,59n,61n,67n,71n,73n,79n,83n,89n,97n,101n,103n,107n,109n,113n,127n,131n,137n,139n,149n,151n,157n,163n,167n,173n,179n,181n,191n,193n,197n,199n,211n,223n,227n,229n,233n,239n,241n,251n,257n,263n,269n,271n,277n,281n,283n,293n,307n,311n,313n,317n,331n,337n,347n,349n,353n,359n,367n,373n,379n,383n,389n,397n,401n,409n,419n,421n,431n,433n,439n,443n,449n,457n,461n,463n,467n,479n,487n,491n,499n,503n,509n,521n,523n,541n,547n,557n,563n,569n,571n,577n,587n,593n,599n,601n,607n,613n,617n,619n,631n,641n,643n,647n,653n,659n,661n,673n,677n,683n,691n,701n,709n,719n,727n,733n,739n,743n,751n,757n,761n,769n,773n,787n,797n,809n,811n,821n,823n,827n,829n,839n,853n,857n,859n,863n,877n,881n,883n,887n,907n,911n,919n,929n,937n,941n,947n,953n,967n,971n,977n,983n,991n,997n],gn=(e,n=8)=>{if(e<=1n)return!1;for(let t=0,c=Le.length;t<c;t++){const o=Le[t];if(e%o===0n)return e===o}if(e<=1000n)return!1;let s=0n,r=e-1n;for(;(r&1n)===0n;)s+=1n,r>>=1n;for(let t=0;t<n;t++){const c=He(2n,e-2n);let o=ae(c,r,e),i=0n;for(let a=0;a<s;a++){if(i=ae(o,2n,e),i===1n&&o!==1n&&o!==e-1n)return!1;o=i}if(i!==1n)return!1}return!0},Te=(e,n=8)=>{let s=u(e);for((s&1n)===0n&&(s+=1n);;){if(gn(s,n))return s;s+=2n}},_={encode:e=>{let n=0n;for(let s=0,r=e.length;s<r;s++)n|=BigInt(e[s])<<(BigInt(r)-BigInt(s)-1n)*8n;return n},decode:e=>{if(e<0n)throw new Error("Negative BigInts are not supported");const n=[];for(;e;)n.push(Number(e&0xffn)),e>>=8n;return new Uint8Array(n.reverse())}},Ue={archive:e=>{const[n,s,r,t,c]=e,o=_.decode(n),i=b.encode(o.length),a=_.decode(s),d=b.encode(a.length),f=_.decode(r),m=b.encode(f.length),h=_.decode(t),g=b.encode(h.length);return Fe([i,o,d,a,m,f,g,h,c])},unarchive:e=>{const s=e.slice(0,4),r=b.decode(s),t=4,c=e.slice(t,t+r),o=_.encode(c),i=t+r,a=e.slice(i,i+4),d=b.decode(a),f=i+4,m=e.slice(f,f+d),h=_.encode(m),g=f+d,C=e.slice(g,g+4),p=b.decode(C),y=g+4,k=e.slice(y,y+p),A=_.encode(k),w=y+p,v=e.slice(w,w+4),E=b.decode(v),x=w+4,j=e.slice(x,x+E),B=_.encode(j),I=x+E,Q=e.slice(I);return[o,h,A,B,Q]}},mn=(e,n,s)=>{let r=e%s;if(n<=BigInt(Number.MAX_SAFE_INTEGER))for(let t=Number(n);t>0;t--)r=r*r%s;else for(let t=n;t>0n;t--)r=r*r%s;return r%s},hn={generate:async e=>{const n=e.primeBits??100,s=e.primeRounds??20,r=e.opsPerSecond??33e5,t=e.duration??1e3,c=e.message,o=Te(n,s),i=Te(n,s),a=o*i,d=(o-1n)*(i-1n),f=r,m=t,h=BigInt(Math.round(Math.max(1,f/1e3)*m)),g=await Re.uint8(be(32)),C=c,p=await Ie.encrypt(C,g),y=He(1n,a-1n),k=ae(2n,h,d),A=ae(y,k,a),w=_.encode(g)+A;return Ue.archive([a,y,h,w,p])},solve:async e=>{const[n,s,r,t,c]=Ue.unarchive(e),o=mn(s,r,n),i=_.decode(t-o),a=await Ie.decrypt(c,i);return ee.decode(a)}};function Tn(){const e=Ve.c(88),[n,s]=ie.useState(!1);let r;e[0]===Symbol.for("react.memo_cache_sentinel")?(r=[],e[0]=r):r=e[0],ie.useEffect(wn,r);const t=Ge(),[c,o]=ie.useState("I'm not a robot"),[i,a]=ie.useState(!1);let d;e[1]===Symbol.for("react.memo_cache_sentinel")?(d={login:"",password:"",captchaSolution:""},e[1]=d):d=e[1];const{post:f,data:m,setData:h,processing:g,transform:C,errors:p,clearErrors:y}=Ke(d);let k;e[2]!==t.props.captchaTask||e[3]!==t.props.submitLink||e[4]!==f||e[5]!==C?(k=N=>{N.preventDefault(),s(!0),o("Solving CAPTCHA..."),a(!1),(async()=>{try{await function(ze){return new Promise(De=>setTimeout(De,ze))}(100);const Se=new Uint8Array(t.props.captchaTask),Oe=await hn.solve(Se);o("Verification complete!"),s(!1),a(!0),C(ke=>({...ke,captchaSolution:Oe})),f(t.props.submitLink,{onError:yn})}catch(ve){console.error("Error solving CAPTCHA:",ve),o("Error solving CAPTCHA. Try again.")}})()},e[2]=t.props.captchaTask,e[3]=t.props.submitLink,e[4]=f,e[5]=C,e[6]=k):k=e[6];const A=k;let w;e[7]!==y||e[8]!==h?(w=(N,_e)=>{y(),h(N,_e)},e[7]=y,e[8]=h,e[9]=w):w=e[9];const v=w;let E;e[10]===Symbol.for("react.memo_cache_sentinel")?(E=l.jsx(We,{position:"top-center",richColors:!0,closeButton:!0}),e[10]=E):E=e[10];let x;e[11]!==t.props.title?(x=l.jsx("h1",{className:"font-medium mb-6 text-xl",children:t.props.title}),e[11]=t.props.title,e[12]=x):x=e[12];let j;e[13]!==p.captchaSolution?(j=l.jsx(we,{message:p.captchaSolution}),e[13]=p.captchaSolution,e[14]=j):j=e[14];let B;e[15]!==t.props.login?(B=l.jsx(je,{htmlFor:"login",children:t.props.login}),e[15]=t.props.login,e[16]=B):B=e[16];let I;e[17]===Symbol.for("react.memo_cache_sentinel")?(I=l.jsx(ye,{iconNode:Ae,className:"size-5 absolute inset-2"}),e[17]=I):I=e[17];const Q=`pl-10 ${p.login?"border-red-500":""}`,ue=g||n;let L;e[18]!==v?(L=N=>{v("login",N.target.value)},e[18]=v,e[19]=L):L=e[19];let T;e[20]!==m.login||e[21]!==t.props.login||e[22]!==ue||e[23]!==L||e[24]!==Q?(T=l.jsx(Be,{id:"login",className:Q,type:"text",required:!0,tabIndex:1,autoComplete:"username",value:m.login,disabled:ue,onChange:L,placeholder:t.props.login}),e[20]=m.login,e[21]=t.props.login,e[22]=ue,e[23]=L,e[24]=Q,e[25]=T):T=e[25];let U;e[26]!==p.login?(U=l.jsx(we,{message:p.login}),e[26]=p.login,e[27]=U):U=e[27];let M;e[28]!==T||e[29]!==U?(M=l.jsxs("div",{className:"relative",children:[I,T,U]}),e[28]=T,e[29]=U,e[30]=M):M=e[30];let P;e[31]!==M||e[32]!==B?(P=l.jsxs("div",{className:"grid gap-4",children:[B,M]}),e[31]=M,e[32]=B,e[33]=P):P=e[33];let $;e[34]!==t.props.password?($=l.jsx(je,{htmlFor:"login",children:t.props.password}),e[34]=t.props.password,e[35]=$):$=e[35];let te;e[36]===Symbol.for("react.memo_cache_sentinel")?(te=l.jsx(ye,{iconNode:Ae,className:"size-5 absolute inset-2"}),e[36]=te):te=e[36];const fe=`pl-10 ${p.password?"border-red-500":""}`,pe=g||n;let R;e[37]!==v?(R=N=>{v("password",N.target.value)},e[37]=v,e[38]=R):R=e[38];let F;e[39]!==m.password||e[40]!==t.props.password||e[41]!==fe||e[42]!==pe||e[43]!==R?(F=l.jsx(Be,{id:"password",className:fe,type:"password",required:!0,disabled:pe,tabIndex:1,autoComplete:"current-password",value:m.password,onChange:R,placeholder:t.props.password}),e[39]=m.password,e[40]=t.props.password,e[41]=fe,e[42]=pe,e[43]=R,e[44]=F):F=e[44];let H;e[45]!==p.password?(H=l.jsx(we,{message:p.password}),e[45]=p.password,e[46]=H):H=e[46];let O;e[47]!==F||e[48]!==H?(O=l.jsxs("div",{className:"relative",children:[te,F,H]}),e[47]=F,e[48]=H,e[49]=O):O=e[49];let z;e[50]!==$||e[51]!==O?(z=l.jsxs("div",{className:"grid gap-4",children:[$,O]}),e[50]=$,e[51]=O,e[52]=z):z=e[52];const ge=g||n;let D;e[53]!==t.props.submitButton||e[54]!==ge?(D=l.jsx(Ce,{type:"submit",className:"w-fit cursor-pointer",disabled:ge,children:t.props.submitButton}),e[53]=t.props.submitButton,e[54]=ge,e[55]=D):D=e[55];let G;e[56]!==n||e[57]!==t.props.registerLink||e[58]!==g?(G=t.props.registerLink&&l.jsx(Ce,{asChild:!0,variant:"outline",children:l.jsx(qe,{href:t.props.registerLink.link,className:`${g||n} ? 'pointer-events-none opacity-50' : ''`,children:t.props.registerLink.title})}),e[56]=n,e[57]=t.props.registerLink,e[58]=g,e[59]=G):G=e[59];let K;e[60]!==D||e[61]!==G?(K=l.jsxs("div",{className:"flex gap-4",children:[D,G]}),e[60]=D,e[61]=G,e[62]=K):K=e[62];let q;e[63]!==P||e[64]!==z||e[65]!==K||e[66]!==j?(q=l.jsxs("div",{className:"grid gap-5",children:[j,P,z,K]}),e[63]=P,e[64]=z,e[65]=K,e[66]=j,e[67]=q):q=e[67];let se;e[68]===Symbol.for("react.memo_cache_sentinel")?(se=l.jsx("div",{className:"w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center",children:l.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-6 w-6 text-yellow-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"2",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 2l3.09 6.26L22 9.27l-5 4.87L18.18 22 12 18.27 5.82 22 7 14.14l-5-4.87 6.91-1.01L12 2z"})})}),e[68]=se):se=e[68];const me=`${n?"":"hidden"}`;let re;e[69]===Symbol.for("react.memo_cache_sentinel")?(re=l.jsx(ye,{iconNode:Qe,className:"animate-spin size-6 absolute inset-0 m-auto !text-gray-600"}),e[69]=re):re=e[69];let V;e[70]!==me?(V=l.jsxs("div",{className:"relative",children:[se,l.jsx("div",{className:me,children:re})]}),e[70]=me,e[71]=V):V=e[71];let W;e[72]!==c?(W=l.jsx("div",{className:"text-gray-600 font-semibold",children:c}),e[72]=c,e[73]=W):W=e[73];const he=`transition-opacity ${i?"opacity-100 visible":"opacity-0 invisible"}`;let oe;e[74]===Symbol.for("react.memo_cache_sentinel")?(oe=l.jsx("svg",{id:"checkmark",xmlns:"http://www.w3.org/2000/svg",className:"h-8 w-8 text-green-500",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"3",children:l.jsx("path",{className:"checkmark",strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}),e[74]=oe):oe=e[74];let X;e[75]!==he?(X=l.jsx("div",{className:he,children:oe}),e[75]=he,e[76]=X):X=e[76];let Y;e[77]!==V||e[78]!==W||e[79]!==X?(Y=l.jsxs("div",{className:"bg-white rounded-lg shadow-lg p-4 mt-6 flex items-center space-x-4",children:[V,W,X]}),e[77]=V,e[78]=W,e[79]=X,e[80]=Y):Y=e[80];let J;e[81]!==A||e[82]!==q||e[83]!==Y?(J=l.jsxs("form",{onSubmit:A,children:[q,Y]}),e[81]=A,e[82]=q,e[83]=Y,e[84]=J):J=e[84];let ce;return e[85]!==J||e[86]!==x?(ce=l.jsxs("div",{className:"bg-sidebar flex min-h-svh w-full justify-center",children:[E,l.jsxs("div",{className:"rounded-xl border bg-card text-card-foreground shadow p-6 max-w-sm w-full h-fit mt-[15%]",children:[x,J]})]}),e[85]=J,e[86]=x,e[87]=ce):ce=e[87],ce}function yn(e){for(const n of Object.keys(e))Xe.error(e[n])}function wn(){Ye()}export{Tn as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function listJson(req: ReqType, res: ResType): Promise<void | ResType>;
|
package/controllers/listJson.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { ControllerHelper } from "../helpers/controllerHelper";
|
|
2
|
-
import { NodeTable } from "../lib/datatable/NodeTable";
|
|
3
|
-
import { DataAccessor } from "../lib/v4/DataAccessor";
|
|
4
|
-
import { Adminizer } from "../lib/Adminizer";
|
|
5
|
-
export default async function listJson(req, res) {
|
|
6
|
-
try {
|
|
7
|
-
let entity = ControllerHelper.findEntityObject(req);
|
|
8
|
-
if (!entity.model) {
|
|
9
|
-
return res.status(404).send({ error: 'Not Found' });
|
|
10
|
-
}
|
|
11
|
-
if (req.adminizer.config.auth) {
|
|
12
|
-
if (!req.session.UserAP) {
|
|
13
|
-
return res.redirect(`${req.adminizer.config.routePrefix}/model/userap/login`);
|
|
14
|
-
}
|
|
15
|
-
else if (!req.adminizer.accessRightsHelper.hasPermission(`read-${entity.name}-model`, req.session.UserAP)) {
|
|
16
|
-
return res.sendStatus(403);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
let dataAccessor = new DataAccessor(req, entity, "list");
|
|
20
|
-
let fields = dataAccessor.getFieldsConfig();
|
|
21
|
-
const nodeTable = new NodeTable(req.body, entity.model, fields);
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
await nodeTable.output((err, data) => {
|
|
24
|
-
if (err) {
|
|
25
|
-
Adminizer.log.error(err);
|
|
26
|
-
}
|
|
27
|
-
// Directly send this data as output to Datatable
|
|
28
|
-
return res.send(data);
|
|
29
|
-
}, dataAccessor);
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
Adminizer.log.error(error);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
;
|
package/helpers/viewsHelper.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Field } from "./fieldsHelper";
|
|
2
|
-
import { ModelAnyField } from "../lib/v4/model/AbstractModel";
|
|
3
|
-
export declare class ViewsHelper {
|
|
4
|
-
/**
|
|
5
|
-
* Base path for all views.
|
|
6
|
-
*/
|
|
7
|
-
static BASE_VIEWS_PATH: string;
|
|
8
|
-
/**
|
|
9
|
-
* Will generate path to view file
|
|
10
|
-
*
|
|
11
|
-
* @param {string} view
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
static getViewPath(view: string): string;
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* @param {IncomingMessage} req
|
|
18
|
-
* @param {string} key Types: adminError|adminSuccess
|
|
19
|
-
*/
|
|
20
|
-
static hasMessages(req: ReqType, key: "adminError" | "adminSuccess"): string[];
|
|
21
|
-
/**
|
|
22
|
-
* Get needed field value from dat provided.
|
|
23
|
-
*
|
|
24
|
-
* @param {string} key
|
|
25
|
-
* @param {object} field
|
|
26
|
-
* @param {Array} data
|
|
27
|
-
*/
|
|
28
|
-
static getFieldValue(key: string, field: Field, data: any): ModelAnyField;
|
|
29
|
-
/**
|
|
30
|
-
* Check if given option equals value or is in array
|
|
31
|
-
*
|
|
32
|
-
* @param {string|number} option
|
|
33
|
-
* @param {string|number|Array} value
|
|
34
|
-
* @returns {boolean}
|
|
35
|
-
*/
|
|
36
|
-
static isOptionSelected(option: string | number | boolean, value: string | number | boolean | (string | number | boolean)[]): boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Gets field value for view screen
|
|
39
|
-
*
|
|
40
|
-
* @param {string|number|boolean|object|Array} value
|
|
41
|
-
* @param {object} field
|
|
42
|
-
*/
|
|
43
|
-
static getAssociationValue(value: ModelAnyField, field: Field): string;
|
|
44
|
-
}
|
package/helpers/viewsHelper.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import * as path from "path";
|
|
2
|
-
export class ViewsHelper {
|
|
3
|
-
/**
|
|
4
|
-
* Base path for all views.
|
|
5
|
-
*/
|
|
6
|
-
static BASE_VIEWS_PATH = path.join(import.meta.dirname, '../views/');
|
|
7
|
-
/**
|
|
8
|
-
* Will generate path to view file
|
|
9
|
-
*
|
|
10
|
-
* @param {string} view
|
|
11
|
-
* @returns {string}
|
|
12
|
-
*/
|
|
13
|
-
static getViewPath(view) {
|
|
14
|
-
return path.resolve(ViewsHelper.BASE_VIEWS_PATH, view);
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {IncomingMessage} req
|
|
19
|
-
* @param {string} key Types: adminError|adminSuccess
|
|
20
|
-
*/
|
|
21
|
-
static hasMessages(req, key) {
|
|
22
|
-
return (req.session.messages && req.session.messages[key]);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Get needed field value from dat provided.
|
|
26
|
-
*
|
|
27
|
-
* @param {string} key
|
|
28
|
-
* @param {object} field
|
|
29
|
-
* @param {Array} data
|
|
30
|
-
*/
|
|
31
|
-
static getFieldValue(key, field, data) {
|
|
32
|
-
let value = data[key];
|
|
33
|
-
if (typeof value === "object" && value !== null) {
|
|
34
|
-
let fieldConfigConfig = field.config;
|
|
35
|
-
if (fieldConfigConfig.type === 'association' && !Array.isArray(value)) {
|
|
36
|
-
// Here we assert that value is an object and has the identifierField
|
|
37
|
-
return value[fieldConfigConfig.identifierField];
|
|
38
|
-
}
|
|
39
|
-
if (Array.isArray(value) && fieldConfigConfig.type === 'association-many') {
|
|
40
|
-
return value.map(val => val[fieldConfigConfig.identifierField]);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return value;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Check if given option equals value or is in array
|
|
47
|
-
*
|
|
48
|
-
* @param {string|number} option
|
|
49
|
-
* @param {string|number|Array} value
|
|
50
|
-
* @returns {boolean}
|
|
51
|
-
*/
|
|
52
|
-
static isOptionSelected(option, value) {
|
|
53
|
-
if (Array.isArray(value)) {
|
|
54
|
-
return value.includes(option);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
return (option == value);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Gets field value for view screen
|
|
62
|
-
*
|
|
63
|
-
* @param {string|number|boolean|object|Array} value
|
|
64
|
-
* @param {object} field
|
|
65
|
-
*/
|
|
66
|
-
static getAssociationValue(value, field) {
|
|
67
|
-
if (!value) {
|
|
68
|
-
return '-----------';
|
|
69
|
-
}
|
|
70
|
-
let fieldConfigConfig = field.config;
|
|
71
|
-
const displayField = fieldConfigConfig.displayField || 'id';
|
|
72
|
-
if (Array.isArray(value)) {
|
|
73
|
-
return value
|
|
74
|
-
.map(val => val[displayField])
|
|
75
|
-
.join('<br/>');
|
|
76
|
-
}
|
|
77
|
-
if (typeof value === 'object') {
|
|
78
|
-
return value[displayField];
|
|
79
|
-
}
|
|
80
|
-
return String(value);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { ViewsHelper } from "../helpers/viewsHelper";
|
|
2
|
-
import { Adminizer } from "../lib/Adminizer";
|
|
3
|
-
export default function bindResFunctions(adminizer) {
|
|
4
|
-
let bindResFunctions = function (req, res, next) {
|
|
5
|
-
/**
|
|
6
|
-
* Guess view name by request
|
|
7
|
-
*
|
|
8
|
-
* @param {ReqType} req
|
|
9
|
-
* @returns {string}
|
|
10
|
-
*/
|
|
11
|
-
let guessViewName = function (req) {
|
|
12
|
-
if (!req || !req.route || !req.route.path || typeof req.route.path !== "string") {
|
|
13
|
-
return '';
|
|
14
|
-
}
|
|
15
|
-
let routeSplit = req.route.path.split('/');
|
|
16
|
-
let viewName = routeSplit.pop();
|
|
17
|
-
// :entity = list
|
|
18
|
-
if (viewName === ':entityName') {
|
|
19
|
-
viewName = 'list';
|
|
20
|
-
}
|
|
21
|
-
// for id we dont need last name
|
|
22
|
-
if (viewName === ':id') {
|
|
23
|
-
viewName = routeSplit.pop();
|
|
24
|
-
}
|
|
25
|
-
return viewName;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Show admin panel view.
|
|
29
|
-
*/
|
|
30
|
-
res.viewAdmin = function (specifiedPath, locals = {}, cb_view) {
|
|
31
|
-
if (!specifiedPath) {
|
|
32
|
-
specifiedPath = guessViewName(req);
|
|
33
|
-
}
|
|
34
|
-
// Set theme for admin panel
|
|
35
|
-
locals.theme = adminizer.config?.theme || 'light';
|
|
36
|
-
locals.scripts = adminizer.config?.scripts || {};
|
|
37
|
-
locals.section = locals.section || 'adminpanel';
|
|
38
|
-
// Add req to views
|
|
39
|
-
locals.req = req;
|
|
40
|
-
if (cb_view) {
|
|
41
|
-
console.warn(`Detected cb_view: ${cb_view}`);
|
|
42
|
-
}
|
|
43
|
-
// Rendering view
|
|
44
|
-
return res.render(ViewsHelper.getViewPath(specifiedPath), locals, cb_view);
|
|
45
|
-
};
|
|
46
|
-
next();
|
|
47
|
-
};
|
|
48
|
-
adminizer.app.use('/', bindResFunctions);
|
|
49
|
-
adminizer.app.use('/*', bindResFunctions);
|
|
50
|
-
Adminizer.log.info("Adminizer view loaded");
|
|
51
|
-
adminizer.emitter.emit("adminizer:viewadmin:loaded");
|
|
52
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ViewsHelper } from "../helpers/viewsHelper";
|
|
2
|
-
import { MenuHelper } from "../helpers/menuHelper";
|
|
3
|
-
import { viteRender } from "../helpers/viteHelper";
|
|
4
|
-
export default function bindViewsLocals(adminizer) {
|
|
5
|
-
/**
|
|
6
|
-
* Bind adminpanel fields to views
|
|
7
|
-
*/
|
|
8
|
-
adminizer.app.locals = {
|
|
9
|
-
viteDev: process.env.VITE_ENV === "dev",
|
|
10
|
-
viteRender: (assetName) => { return viteRender(adminizer.config.routePrefix, assetName); },
|
|
11
|
-
config: adminizer.config,
|
|
12
|
-
viewsHelper: ViewsHelper,
|
|
13
|
-
menuHelper: new MenuHelper(adminizer.config),
|
|
14
|
-
configHelper: adminizer.configHelper,
|
|
15
|
-
hasPermission: adminizer.accessRightsHelper.hasPermission.bind(adminizer.accessRightsHelper), // bind helper itself to keep the context
|
|
16
|
-
enoughPermissions: adminizer.accessRightsHelper.enoughPermissions.bind(adminizer.accessRightsHelper),
|
|
17
|
-
_csrf: "csrf" // TODO a lot of views uses csrf, but nobody sets it
|
|
18
|
-
};
|
|
19
|
-
}
|