adminizer 4.1.0-build.2 → 4.1.0-build.20
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/Readme.md +11 -1
- package/assets/{VanillaJSONEditor-FUe77pIA.js → VanillaJSONEditor-D-Lx670g.js} +1 -1
- package/assets/add-BP_u3Tjl.js +1 -0
- package/assets/add-form-nffmiYTh.js +1 -0
- package/assets/add-group-D4vcHlm-.js +1 -0
- package/assets/{add-group-form-dzadPSfL.js → add-group-form-gNJW11-q.js} +1 -1
- package/assets/add-user-DWh3Nas0.js +1 -0
- package/assets/add-user-form-BJ0FsZYJ.js +1 -0
- package/assets/{app-DMmad2-f.css → app-C3OdwOHy.css} +1 -1
- package/assets/{app-layout-D1m9Kvxq.js → app-layout-DYsRFUuP.js} +1 -1
- package/assets/{app-shell-BWMRMkHM.js → app-shell-Dd9Eknik.js} +1 -1
- package/assets/app-sidebar-BOmu6-Sl.js +1 -0
- package/assets/{app-sidebar-header-DLAFi13E.js → app-sidebar-header-CoXSzWxk.js} +1 -1
- package/assets/app.js +2 -2
- package/assets/{breadcrumbs-CQNon4Vl.js → breadcrumbs-BmAq4fHT.js} +1 -1
- package/assets/{button-CQ9t1kLz.js → button-C9B_5Jf_.js} +1 -1
- package/assets/{checkbox-W0nGAXIj.js → checkbox-Fg27sL_1.js} +1 -1
- package/assets/{compiler-runtime-tM4jBQ-T.js → compiler-runtime-hB6dAw2d.js} +1 -1
- package/assets/dashboard-BOltB2Hq.css +1 -0
- package/assets/dashboard-Ddh74NBQ.js +3 -0
- package/assets/{date-picker-B__dVVqj.js → date-picker-DI1cCO7K.js} +1 -1
- package/assets/{dropdown-menu-SEBnEIiL.js → dropdown-menu-Bhj17ENm.js} +1 -1
- package/assets/{field-renderer-CapylJU9.js → field-renderer-DVHZF6HS.js} +3 -3
- package/assets/form-BgWdwvz1.js +1 -0
- package/assets/form-DgtErfln.js +1 -0
- package/assets/{geo-json-CwteYDGB.js → geo-json-BjiyTtMu.js} +1 -1
- package/assets/{handsontable-BCnjOpBr.js → handsontable-4mjU_b0n.js} +1 -1
- package/assets/home-CHntBHJa.js +2 -0
- package/assets/{icon-Bz9BMaD0.js → icon-Dt0vBgDO.js} +1 -1
- package/assets/index-B8BS9wMC.js +1 -0
- package/assets/{index-DEk3sC8d.js → index-BKCgnGj_.js} +1 -1
- package/assets/{index-C0SL3SHw.js → index-BykbU6Ee.js} +1 -1
- package/assets/index-CaJgc5EZ.js +1 -0
- package/assets/{index-BcE9FUM6.js → index-Cgp8OfuI.js} +1 -1
- package/assets/{index-DTRTjOmh.js → index-Cw5o84pO.js} +1 -1
- package/assets/{init-user-D9mW-g14.js → init-user-JfCKJ5Ce.js} +1 -1
- package/assets/{input-DF7Ue23C.js → input-CvRbIbk4.js} +1 -1
- package/assets/{input-error-BBygona6.js → input-error-DMK7cAt7.js} +1 -1
- package/assets/{label-Z506NKsW.js → label-CSLFe9Bz.js} +1 -1
- package/assets/list-B2Oa5O_Q.js +1 -0
- package/assets/{list-table-DB1sEQLF.js → list-table-DA9MhywL.js} +5 -5
- package/assets/{login-DrGaTWhY.js → login-DQwGtdis.js} +1 -1
- package/assets/manifest.json +491 -470
- package/assets/{material-icon-CItZiB53.js → material-icon-BJg8o_fs.js} +1 -1
- package/assets/module-DWXp59Vg.js +1 -0
- package/assets/{monaco-editor-DqAqwxw4.js → monaco-editor-CJs0_GlD.js} +1 -1
- package/assets/{multi-select-oabtVhUP.js → multi-select-BvRpAW8r.js} +1 -1
- package/assets/{nav-footer-CM-yHiRs.js → nav-footer-Bs4dmN1d.js} +1 -1
- package/assets/{nav-main-Q3xofGRT.js → nav-main-Bq3IMk4C.js} +1 -1
- package/assets/{nav-user-Ds8i0Pa2.js → nav-user-CbB22J5O.js} +1 -1
- package/assets/{pagination-render-B57pOpFy.js → pagination-render-DuXDDbC_.js} +1 -1
- package/assets/{popover-I249Gg2O.js → popover-DtoGI2b1.js} +1 -1
- package/assets/{register-C9FQIDtS.js → register-BSogVF0h.js} +1 -1
- package/assets/{select-D1N8zRPY.js → select-BWepUw-9.js} +1 -1
- package/assets/{sidebar-4D-sX2l4.js → sidebar-CAHsHdjM.js} +2 -2
- package/assets/skeleton-COOcAA8f.js +1 -0
- package/assets/{sonner-Dzckw3U3.js → sonner-BI0IFOQN.js} +1 -1
- package/assets/{toast-editor-FbrFd1ft.js → toast-editor-CMK7QtF1.js} +1 -1
- package/assets/{tooltip-D2ehgLlB.js → tooltip-DHwpLKOI.js} +1 -1
- package/assets/{use-appearance-Co6mO0dV.js → use-appearance-DRfIqTgw.js} +1 -1
- package/assets/{use-window-size-B8l6Bpkf.js → use-window-size-h0Sh_NvX.js} +1 -1
- package/assets/{user-info-DBYoAJYJ.js → user-info-DFrmpJ4y.js} +1 -1
- package/assets/{user-menu-content-qkvdkUVd.js → user-menu-content-DPXQdERj.js} +1 -1
- package/assets/welcome-B4WCIXKf.js +1 -0
- package/controllers/add.js +3 -3
- package/controllers/addGroup.js +2 -4
- package/controllers/addUser.js +4 -6
- package/controllers/catalog/Catalog.js +2 -2
- package/controllers/catalog/FrontentCatalogAdapter.js +1 -2
- package/controllers/ckeditorUpload.js +2 -3
- package/controllers/dashboard.js +16 -2
- package/controllers/edit.js +3 -4
- package/controllers/editGroup.js +2 -4
- package/controllers/editUser.js +3 -5
- package/controllers/form.js +2 -3
- package/controllers/getAllWidgets.js +3 -3
- package/controllers/initUser.js +1 -2
- package/controllers/list.js +5 -5
- package/controllers/login.js +31 -15
- package/controllers/media-manager/mediaManagerAdapter.js +1 -2
- package/controllers/media-manager/mediaManagerApi.js +2 -2
- package/controllers/navigation/edit.js +2 -2
- package/controllers/register.js +1 -4
- package/controllers/remove.js +3 -3
- package/controllers/timezones.js +1 -1
- package/controllers/view.js +3 -3
- package/controllers/welcome.js +1 -1
- package/controllers/widgets/Action.js +2 -2
- package/controllers/widgets/Custom.js +2 -2
- package/controllers/widgets/Info.js +2 -2
- package/controllers/widgets/switch.js +2 -2
- package/controllers/widgetsDB.js +5 -5
- package/helpers/accessRightsHelper.d.ts +3 -2
- package/helpers/accessRightsHelper.js +9 -3
- package/helpers/configHelper.js +2 -1
- package/helpers/controllerHelper.js +1 -1
- package/helpers/fieldsHelper.d.ts +1 -1
- package/helpers/fieldsHelper.js +1 -1
- package/helpers/inertiaActionsHelper.js +1 -1
- package/helpers/inertiaAddHelper.d.ts +1 -1
- package/helpers/inertiaAddHelper.js +2 -0
- package/helpers/inertiaFromHelper.js +2 -0
- package/helpers/inertiaGroupHelper.d.ts +4 -2
- package/helpers/inertiaGroupHelper.js +1 -1
- package/helpers/inertiaListHelper.js +5 -5
- package/helpers/inertiaMenuHelper.js +1 -1
- package/helpers/inertiaUserHelper.d.ts +7 -1
- package/helpers/inertiaUserHelper.js +5 -1
- package/index.d.ts +4 -1
- package/index.js +7 -1
- package/interfaces/adminpanelConfig.d.ts +8 -21
- package/interfaces/global.d.ts +8 -26
- package/interfaces/types.d.ts +1 -1
- package/lib/Adminizer.d.ts +2 -0
- package/lib/Adminizer.js +26 -6
- package/lib/catalog/AbstractCatalog.js +0 -1
- package/lib/catalog/Navigation.js +6 -7
- package/lib/datatable/NodeTable.js +2 -5
- package/lib/inertia/inertiaAdapter.js +0 -1
- package/lib/media-manager/AbstractMediaManager.d.ts +2 -2
- package/lib/media-manager/AbstractMediaManager.js +1 -1
- package/lib/media-manager/Items.js +0 -3
- package/lib/v4/DataAccessor.d.ts +5 -2
- package/lib/v4/DataAccessor.js +30 -14
- package/lib/v4/I18n.js +2 -0
- package/lib/v4/POWCaptcha.js +0 -1
- package/lib/v4/PolicyManager.js +0 -1
- package/lib/v4/helper/jwt.d.ts +10 -0
- package/lib/v4/helper/jwt.js +18 -0
- package/lib/v4/model/AbstractModel.d.ts +5 -1
- package/lib/v4/model/AbstractModel.js +2 -3
- package/lib/v4/model/ModelHandler.js +0 -1
- package/lib/v4/model/adapter/sequelize.d.ts +11 -2
- package/lib/v4/model/adapter/sequelize.js +451 -118
- package/lib/v4/model/adapter/waterline.js +5 -3
- package/lib/widgets/abstractAction.d.ts +1 -1
- package/lib/widgets/abstractCustom.d.ts +27 -12
- package/lib/widgets/abstractCustom.js +8 -2
- package/lib/widgets/abstractInfo.d.ts +1 -1
- package/lib/widgets/abstractInfo.js +1 -1
- package/lib/widgets/abstractLink.d.ts +1 -0
- package/lib/widgets/abstractSwitch.d.ts +1 -1
- package/lib/widgets/abstractWidgetBase.d.ts +1 -1
- package/lib/widgets/widgetHandler.d.ts +27 -3
- package/lib/widgets/widgetHandler.js +25 -25
- package/models/GroupAP.d.ts +8 -0
- package/models/NavigationAP.d.ts +5 -0
- package/models/UserAP.d.ts +24 -2
- package/models/UserAP.js +2 -2
- package/package.json +23 -11
- package/policies/checkAuth.js +4 -3
- package/policies/setLocale.js +2 -2
- package/system/Router.js +6 -14
- package/system/bindAccessRights.js +0 -4
- package/system/bindAuthorization.js +4 -5
- package/system/bindDev.js +1 -0
- package/system/bindInertia.js +9 -9
- package/system/bindMediaManager.js +0 -1
- package/system/bindModels.js +7 -2
- package/system/bindNavigation.js +0 -1
- package/system/bindReqFunctions.js +15 -0
- package/translations/ru.json +17 -8
- package/assets/add-ZITr43GJ.js +0 -1
- package/assets/add-form-CYOfr0Ef.js +0 -1
- package/assets/add-group-B332wN8K.js +0 -1
- package/assets/add-user-TC-mYdsB.js +0 -1
- package/assets/add-user-form-y2f_1_lM.js +0 -1
- package/assets/app-sidebar-BCtaEFGb.js +0 -1
- package/assets/dashboard-BR602KhL.js +0 -1
- package/assets/form-DOUNk3o2.js +0 -1
- package/assets/form-lOKv4Qbw.js +0 -1
- package/assets/home-Ch6QfTIt.js +0 -2
- package/assets/index-Cdb9ACvz.js +0 -1
- package/assets/index-K81GbF6O.js +0 -1
- package/assets/list-Qyd7ecQH.js +0 -1
- package/assets/module-DBaykv8l.js +0 -1
- package/assets/welcome-D2adQ8EU.js +0 -1
- package/controllers/processInstallFinalize.d.ts +0 -1
- package/controllers/processInstallFinalize.js +0 -16
- package/controllers/processInstallStep.d.ts +0 -1
- package/controllers/processInstallStep.js +0 -132
- package/lib/installStepper/InstallStepAbstract.d.ts +0 -52
- package/lib/installStepper/InstallStepAbstract.js +0 -69
- package/lib/installStepper/finalizeStep.d.ts +0 -21
- package/lib/installStepper/finalizeStep.js +0 -48
- package/lib/installStepper/installStepper.d.ts +0 -40
- package/lib/installStepper/installStepper.js +0 -195
- package/models/MediaManagerAP.d.ts +0 -46
- package/models/MediaManagerAP.js +0 -45
- package/models/MediaManagerAssociationsAP.d.ts +0 -28
- package/models/MediaManagerAssociationsAP.js +0 -27
- package/models/MediaManagerMetaAP.d.ts +0 -22
- package/models/MediaManagerMetaAP.js +0 -21
- package/system/bindInstallStepper.d.ts +0 -2
- package/system/bindInstallStepper.js +0 -23
package/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from "./helpers/configHelper";
|
|
2
2
|
export * from "./helpers/accessRightsHelper";
|
|
3
|
-
export * from "./lib/installStepper/installStepper";
|
|
4
3
|
export * from "./lib/widgets/widgetHandler";
|
|
5
4
|
export * from "./lib/catalog/CatalogHandler";
|
|
6
5
|
export * from "./lib/media-manager/MediaManagerHandler";
|
|
@@ -8,4 +7,8 @@ export * from "./interfaces/adminpanelConfig";
|
|
|
8
7
|
export * from "./lib/v4/model/AbstractModel";
|
|
9
8
|
export * from "./lib/v4/model/adapter/waterline";
|
|
10
9
|
export * from "./lib/v4/model/adapter/typeorm";
|
|
10
|
+
export * from "./lib/v4/model/adapter/sequelize";
|
|
11
11
|
export * from "./lib/Adminizer";
|
|
12
|
+
export * from "./models/GroupAP";
|
|
13
|
+
export * from "./models/UserAP";
|
|
14
|
+
export * from "./models/NavigationAP";
|
package/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from "./helpers/configHelper";
|
|
2
2
|
export * from "./helpers/accessRightsHelper";
|
|
3
|
-
export * from "./lib/installStepper/installStepper";
|
|
4
3
|
export * from "./lib/widgets/widgetHandler";
|
|
5
4
|
export * from "./lib/catalog/CatalogHandler";
|
|
6
5
|
export * from "./lib/media-manager/MediaManagerHandler";
|
|
@@ -8,4 +7,11 @@ export * from "./interfaces/adminpanelConfig";
|
|
|
8
7
|
export * from "./lib/v4/model/AbstractModel";
|
|
9
8
|
export * from "./lib/v4/model/adapter/waterline";
|
|
10
9
|
export * from "./lib/v4/model/adapter/typeorm";
|
|
10
|
+
export * from "./lib/v4/model/adapter/sequelize";
|
|
11
11
|
export * from "./lib/Adminizer";
|
|
12
|
+
export * from "./models/GroupAP";
|
|
13
|
+
export * from "./models/UserAP";
|
|
14
|
+
// export * from "./models/MediaManagerAP"
|
|
15
|
+
// export * from "./models/MediaManagerAssociationsAP"
|
|
16
|
+
// export * from "./models/MediaManagerMetaAP"
|
|
17
|
+
export * from "./models/NavigationAP";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { MaterialIcon } from "./MaaterialIcons";
|
|
2
2
|
import { EditorOptions } from "@toast-ui/editor/types/editor";
|
|
3
3
|
import { GridSettings as HandsontableSettings } from "handsontable/settings";
|
|
4
|
+
import { GroupAP } from "models/GroupAP";
|
|
5
|
+
import { UserAP } from "models/UserAP";
|
|
4
6
|
export type AdminpanelIcon = MaterialIcon;
|
|
5
7
|
export type FieldsTypes = "string" | "password" | "date" | "datetime" | "time" | "integer" | "number" | "float" | "color" | "email" | "month" | "week" | "range" | "boolean" | "binary" | "text" | "longtext" | "mediumtext" | "ckeditor" | "wysiwyg" | "texteditor" | "word" | 'tui' | 'tuieditor' | 'toast-ui' | "jsoneditor" | "json" | "array" | "object" | "ace" | "code" | "html" | "xml" | "aceeditor" | "menu" | "schedule" | "worktime" | "association" | "association-many" | "select" | "select-many" | "table" | "geojson" | "mediamanager" |
|
|
6
8
|
/**
|
|
@@ -121,23 +123,6 @@ export interface AdminpanelConfig {
|
|
|
121
123
|
* */
|
|
122
124
|
set?: SetFunction;
|
|
123
125
|
};
|
|
124
|
-
/**
|
|
125
|
-
* Wizards
|
|
126
|
-
* */
|
|
127
|
-
installStepper?: {
|
|
128
|
-
path: string;
|
|
129
|
-
data: {
|
|
130
|
-
[key: string]: FieldsModels;
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* Custom getter
|
|
134
|
-
* */
|
|
135
|
-
get?: GetFunction;
|
|
136
|
-
/**
|
|
137
|
-
* Custom setter
|
|
138
|
-
* */
|
|
139
|
-
set?: SetFunction;
|
|
140
|
-
};
|
|
141
126
|
/**
|
|
142
127
|
* Prime administrator login credentials
|
|
143
128
|
* */
|
|
@@ -264,12 +249,12 @@ export interface ModelConfig {
|
|
|
264
249
|
* May be association or association-many to UserAP or GroupAP */
|
|
265
250
|
userAccessRelation?: {
|
|
266
251
|
field: string;
|
|
267
|
-
via
|
|
252
|
+
via?: string;
|
|
268
253
|
} | string;
|
|
269
254
|
userAccessRelationCallback?: (userWithGroups: UserWithGroups, record: any) => boolean;
|
|
270
255
|
}
|
|
271
|
-
type UserWithGroups =
|
|
272
|
-
groups:
|
|
256
|
+
type UserWithGroups = UserAP & {
|
|
257
|
+
groups: GroupAP[];
|
|
273
258
|
};
|
|
274
259
|
export interface FieldsForms {
|
|
275
260
|
[key: string]: FormFieldConfig;
|
|
@@ -316,6 +301,8 @@ export interface BaseFieldConfig {
|
|
|
316
301
|
disabled?: boolean;
|
|
317
302
|
/** Show as required element HTML */
|
|
318
303
|
required?: boolean;
|
|
304
|
+
/** show or hode element, default `true` */
|
|
305
|
+
visible?: boolean;
|
|
319
306
|
}
|
|
320
307
|
export interface TuiEditorFieldConfig extends BaseFieldConfig {
|
|
321
308
|
type: 'tui' | 'tuieditor' | 'toast-ui';
|
|
@@ -403,7 +390,7 @@ export interface HrefConfig {
|
|
|
403
390
|
/**
|
|
404
391
|
* Only for view, controller still uses his own access rights token
|
|
405
392
|
* */
|
|
406
|
-
accessRightsToken?: string;
|
|
393
|
+
accessRightsToken?: string | undefined;
|
|
407
394
|
/**
|
|
408
395
|
* For menu items only
|
|
409
396
|
* */
|
package/interfaces/global.d.ts
CHANGED
|
@@ -4,15 +4,10 @@ import multer from "multer";
|
|
|
4
4
|
import { I18n } from "../lib/v4/I18n";
|
|
5
5
|
import { Inertia } from "../lib/inertia/inertiaAdapter";
|
|
6
6
|
import { Flash } from "../lib/inertia/flash";
|
|
7
|
+
import { UserAP } from "models/UserAP";
|
|
7
8
|
declare global {
|
|
9
|
+
/** @deprecated use import from TS model decalration */
|
|
8
10
|
type ModelsAP = {
|
|
9
|
-
GroupAP: {
|
|
10
|
-
id?: number;
|
|
11
|
-
name: string;
|
|
12
|
-
description?: string;
|
|
13
|
-
tokens?: string[];
|
|
14
|
-
users?: ModelsAP["UserAP"][];
|
|
15
|
-
};
|
|
16
11
|
MediaManagerAP: {
|
|
17
12
|
id?: string;
|
|
18
13
|
parent?: ModelsAP["MediaManagerAP"];
|
|
@@ -48,36 +43,20 @@ declare global {
|
|
|
48
43
|
label: string;
|
|
49
44
|
tree: any;
|
|
50
45
|
};
|
|
51
|
-
UserAP: {
|
|
52
|
-
id?: number;
|
|
53
|
-
login?: string;
|
|
54
|
-
fullName?: string;
|
|
55
|
-
email?: string;
|
|
56
|
-
passwordHashed?: string;
|
|
57
|
-
password?: string;
|
|
58
|
-
timezone?: string;
|
|
59
|
-
expires?: string;
|
|
60
|
-
locale?: string;
|
|
61
|
-
isDeleted?: boolean;
|
|
62
|
-
isActive?: boolean;
|
|
63
|
-
isAdministrator?: boolean;
|
|
64
|
-
groups?: ModelsAP["GroupAP"][];
|
|
65
|
-
widgets?: any;
|
|
66
|
-
isConfirmed?: boolean;
|
|
67
|
-
};
|
|
68
46
|
};
|
|
69
47
|
type reqSession = {
|
|
70
48
|
flashMessages: Record<string, string[]>;
|
|
71
49
|
xInertiaCurrentComponent: string | undefined;
|
|
72
|
-
UserAP:
|
|
50
|
+
UserAP: UserAP;
|
|
73
51
|
messages: {
|
|
74
52
|
adminError: string[];
|
|
75
53
|
adminSuccess: string[];
|
|
76
54
|
};
|
|
77
|
-
|
|
55
|
+
userPretended?: UserAP;
|
|
78
56
|
};
|
|
79
57
|
type FlashMessages = 'info' | 'error' | 'success' | string;
|
|
80
58
|
type ReqType = Request & {
|
|
59
|
+
user: UserAP;
|
|
81
60
|
Inertia: Inertia;
|
|
82
61
|
flash: Flash<FlashMessages>;
|
|
83
62
|
session: reqSession;
|
|
@@ -96,6 +75,9 @@ declare global {
|
|
|
96
75
|
i18n: I18n;
|
|
97
76
|
};
|
|
98
77
|
type ResType = Response & {
|
|
78
|
+
/**
|
|
79
|
+
* @deprecated // TODO delete after finish catalog
|
|
80
|
+
*/
|
|
99
81
|
viewAdmin(specifiedPath: string, locals?: any, cb_view?: Function): void;
|
|
100
82
|
};
|
|
101
83
|
type MiddlewareType = (req: ReqType, res: ResType, next: NextFunction) => void;
|
package/interfaces/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbstractModel } from "../lib/v4/model/AbstractModel";
|
|
2
2
|
import { ModelConfig } from "./adminpanelConfig";
|
|
3
|
-
export type EntityType = "form" | "model"
|
|
3
|
+
export type EntityType = "form" | "model";
|
|
4
4
|
export interface Entity {
|
|
5
5
|
name: string;
|
|
6
6
|
config?: ModelConfig;
|
package/lib/Adminizer.d.ts
CHANGED
|
@@ -24,8 +24,10 @@ export declare class Adminizer {
|
|
|
24
24
|
widgetHandler: WidgetHandler;
|
|
25
25
|
vite: ViteDevServer;
|
|
26
26
|
controlsHandler: ControlsHandler;
|
|
27
|
+
jwtSecret: string;
|
|
27
28
|
static logger: winston.Logger;
|
|
28
29
|
constructor(ormAdapters: AbstractAdapter[]);
|
|
30
|
+
getMiddleware(): (req: any, res: any) => void;
|
|
29
31
|
/**
|
|
30
32
|
* Vite middleware
|
|
31
33
|
* @protected
|
package/lib/Adminizer.js
CHANGED
|
@@ -29,6 +29,7 @@ import { bindInertia } from "../system/bindInertia";
|
|
|
29
29
|
import { MenuHelper } from "../helpers/menuHelper";
|
|
30
30
|
import { bindControls } from "../system/bindControls";
|
|
31
31
|
import { ControlsHandler } from "./controls/ControlsHandler";
|
|
32
|
+
import { v4 as uuid } from "uuid";
|
|
32
33
|
export class Adminizer {
|
|
33
34
|
app;
|
|
34
35
|
config;
|
|
@@ -42,8 +43,9 @@ export class Adminizer {
|
|
|
42
43
|
widgetHandler;
|
|
43
44
|
vite;
|
|
44
45
|
controlsHandler;
|
|
46
|
+
jwtSecret = process.env.JWT_SECRET ?? uuid();
|
|
45
47
|
static logger = winston.createLogger({
|
|
46
|
-
level: "
|
|
48
|
+
level: process.env.LOG_LEVEL ?? "debug",
|
|
47
49
|
format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ timestamp, level, message, ...meta }) => {
|
|
48
50
|
const metaString = Object.keys(meta).length ? JSON.stringify(meta) : "";
|
|
49
51
|
return `[${timestamp}] ${level.toUpperCase()}: ${message} ${metaString}`;
|
|
@@ -58,6 +60,21 @@ export class Adminizer {
|
|
|
58
60
|
this._emitter = new EventEmitter();
|
|
59
61
|
this.ormAdapters = ormAdapters;
|
|
60
62
|
}
|
|
63
|
+
getMiddleware() {
|
|
64
|
+
return (req, res) => {
|
|
65
|
+
this.app(req, res, (err) => {
|
|
66
|
+
if (err) {
|
|
67
|
+
console.error("Error in Adminizer", err);
|
|
68
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
69
|
+
res.end('Internal Server Error');
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
73
|
+
res.end('Route Not Found in Adminizer');
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
}
|
|
61
78
|
/**
|
|
62
79
|
* Vite middleware
|
|
63
80
|
* @protected
|
|
@@ -76,6 +93,9 @@ export class Adminizer {
|
|
|
76
93
|
async init(config) {
|
|
77
94
|
// set cookie parser
|
|
78
95
|
this.app.use(cookieParser());
|
|
96
|
+
if (!config || Object.keys(config).length === 0) {
|
|
97
|
+
Adminizer.log.warn(`Adminizer init > Adminizer config is emtpy`);
|
|
98
|
+
}
|
|
79
99
|
// Set vite middleware
|
|
80
100
|
const isViteDev = process.env.VITE_ENV === "dev";
|
|
81
101
|
if (isViteDev)
|
|
@@ -105,7 +125,6 @@ export class Adminizer {
|
|
|
105
125
|
set: configForms.set ?? defaultForms.set
|
|
106
126
|
}
|
|
107
127
|
};
|
|
108
|
-
// console.log("CONFIG", this.config)
|
|
109
128
|
this.modelHandler = new ModelHandler();
|
|
110
129
|
await bindModels(this);
|
|
111
130
|
await bindForms(this);
|
|
@@ -113,17 +132,18 @@ export class Adminizer {
|
|
|
113
132
|
this.policyManager = new PolicyManager(this);
|
|
114
133
|
await this.policyManager.loadPolicies();
|
|
115
134
|
this.accessRightsHelper = new AccessRightsHelper(this);
|
|
135
|
+
// Helpers go to construtor
|
|
116
136
|
this.configHelper = new ConfigHelper(this);
|
|
117
137
|
this.menuHelper = new MenuHelper(this.config);
|
|
118
138
|
this.widgetHandler = new WidgetHandler(this);
|
|
119
139
|
bindExpressUtils(this.app);
|
|
120
140
|
bindReqFunctions(this);
|
|
121
|
-
// add install stepper policy to check unfilled settings
|
|
122
|
-
// 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.
|
|
123
141
|
// Bind assets
|
|
124
142
|
bindAssets(this.app, this.config.routePrefix);
|
|
125
|
-
if (
|
|
126
|
-
|
|
143
|
+
if (!process.env.VITEST) {
|
|
144
|
+
if ((process.env.DEV && process.env.NODE_ENV !== 'production') || process.env.ADMINPANEL_FORCE_BIND_DEV === "TRUE") {
|
|
145
|
+
bindDev(this);
|
|
146
|
+
}
|
|
127
147
|
}
|
|
128
148
|
await bindDashboardWidgets(this);
|
|
129
149
|
// bindNavigation(this);
|
|
@@ -207,7 +207,6 @@ export class AbstractCatalog {
|
|
|
207
207
|
else {
|
|
208
208
|
action = this.actionHandlers.find((it) => it.id === actionId);
|
|
209
209
|
}
|
|
210
|
-
// console.log(this.actionHandlers)
|
|
211
210
|
if (!action)
|
|
212
211
|
throw `Action with id \`${actionId}\` not found`;
|
|
213
212
|
return await action.handler(items, config);
|
|
@@ -140,7 +140,6 @@
|
|
|
140
140
|
// {tree: tree}
|
|
141
141
|
// )
|
|
142
142
|
// } catch (e) {
|
|
143
|
-
// console.log(e)
|
|
144
143
|
// throw 'navigation model update error'
|
|
145
144
|
// }
|
|
146
145
|
// }
|
|
@@ -326,7 +325,7 @@
|
|
|
326
325
|
// let items = await this.adminizer.modelHandler.model.get(this.model)["_find"]({})
|
|
327
326
|
//
|
|
328
327
|
// // This dirty hack is here because the field of view is disappearing
|
|
329
|
-
// req.i18n.setLocale(req.
|
|
328
|
+
// req.i18n.setLocale(req.user.locale);
|
|
330
329
|
// const __ = (s: string) => {
|
|
331
330
|
// return req.i18n.__(s)
|
|
332
331
|
// }
|
|
@@ -354,7 +353,7 @@
|
|
|
354
353
|
// let type: 'html' = 'html'
|
|
355
354
|
//
|
|
356
355
|
// // This dirty hack is here because the field of view is disappearing
|
|
357
|
-
// req.i18n.setLocale(req.
|
|
356
|
+
// req.i18n.setLocale(req.user.locale);
|
|
358
357
|
// const __ = (s: string) => {
|
|
359
358
|
// return req.i18n.__(s)
|
|
360
359
|
// }
|
|
@@ -433,7 +432,7 @@
|
|
|
433
432
|
// let type: 'html' = 'html'
|
|
434
433
|
//
|
|
435
434
|
// // This dirty hack is here because the field of view is disappearing
|
|
436
|
-
// req.i18n.setLocale(req.
|
|
435
|
+
// req.i18n.setLocale(req.user.locale);
|
|
437
436
|
// const __ = (s: string) => {
|
|
438
437
|
// return req.i18n.__(s)
|
|
439
438
|
// }
|
|
@@ -460,7 +459,7 @@
|
|
|
460
459
|
// let item = await this.find(id, catalogId)
|
|
461
460
|
//
|
|
462
461
|
// // This dirty hack is here because the field of view is disappearing
|
|
463
|
-
// req.i18n.setLocale(req.
|
|
462
|
+
// req.i18n.setLocale(req.user.locale);
|
|
464
463
|
// const __ = (s: string) => {
|
|
465
464
|
// return req.i18n.__(s)
|
|
466
465
|
// }
|
|
@@ -496,7 +495,7 @@
|
|
|
496
495
|
//
|
|
497
496
|
// getAddHTML(req: ReqType): Promise<{ type: "link" | "html" | "jsonForm"; data: string }> {
|
|
498
497
|
// let type: 'html' = 'html'
|
|
499
|
-
// req.i18n.setLocale(req.
|
|
498
|
+
// req.i18n.setLocale(req.user.locale);
|
|
500
499
|
//
|
|
501
500
|
// const __ = (s: string) => {
|
|
502
501
|
// return req.i18n.__(s)
|
|
@@ -514,7 +513,7 @@
|
|
|
514
513
|
// let type: 'html' = 'html'
|
|
515
514
|
// let item = await this.find(id, catalogId)
|
|
516
515
|
//
|
|
517
|
-
// req.i18n.setLocale(req.
|
|
516
|
+
// req.i18n.setLocale(req.user.locale);
|
|
518
517
|
// const __ = (s: string) => {
|
|
519
518
|
// return req.i18n.__(s)
|
|
520
519
|
// }
|
|
@@ -98,7 +98,6 @@ export class NodeTable {
|
|
|
98
98
|
columnQuery = { [fieldsArray[parseInt(columnName)]]: { contains: searchStr } };
|
|
99
99
|
break;
|
|
100
100
|
default:
|
|
101
|
-
// Пропускаем json, ref и ассоциации
|
|
102
101
|
break;
|
|
103
102
|
}
|
|
104
103
|
}
|
|
@@ -132,10 +131,9 @@ export class NodeTable {
|
|
|
132
131
|
async output(callback, dataAccessor) {
|
|
133
132
|
try {
|
|
134
133
|
const queryOptions = await this.buildQuery();
|
|
135
|
-
const totalRecords = await this.model.count({});
|
|
136
|
-
const filteredRecords = await this.model.count(queryOptions.where);
|
|
134
|
+
const totalRecords = await this.model.count({}, dataAccessor);
|
|
135
|
+
const filteredRecords = await this.model.count(queryOptions.where, dataAccessor);
|
|
137
136
|
const data = await this.model.find(queryOptions, dataAccessor);
|
|
138
|
-
console.log(data, "data");
|
|
139
137
|
const output = {
|
|
140
138
|
draw: this.request.draw !== "" ? this.request.draw : 0,
|
|
141
139
|
recordsTotal: totalRecords,
|
|
@@ -201,7 +199,6 @@ export class NodeTable {
|
|
|
201
199
|
});
|
|
202
200
|
out.push(row);
|
|
203
201
|
});
|
|
204
|
-
console.log(out);
|
|
205
202
|
return out;
|
|
206
203
|
}
|
|
207
204
|
}
|
|
@@ -21,7 +21,6 @@ const inertiaExpressAdapter = function ({ version, html, flashMessages, enableRe
|
|
|
21
21
|
if (!['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
|
|
22
22
|
const csrfCookie = req.cookies['XSRF-TOKEN'];
|
|
23
23
|
const csrfHeader = req.headers[csrf.headerName || 'x-xsrf-token'];
|
|
24
|
-
// console.log('headers:', req.headers['x-xsrf-token']);
|
|
25
24
|
if (!csrfCookie || !csrfHeader || csrfCookie !== csrfHeader) {
|
|
26
25
|
res.status(403).send({ message: 'Invalid CSRF token' });
|
|
27
26
|
return;
|
|
@@ -143,10 +143,10 @@ export declare abstract class AbstractMediaManager {
|
|
|
143
143
|
uloadAllowedTypes: string[];
|
|
144
144
|
dir: string;
|
|
145
145
|
/**
|
|
146
|
-
|
|
146
|
+
|
|
147
147
|
*/
|
|
148
148
|
allowSearch: boolean;
|
|
149
|
-
|
|
149
|
+
/**⚠️ above the settings that need to be implemented*/
|
|
150
150
|
/**
|
|
151
151
|
* id for mediamanager instance
|
|
152
152
|
*/
|
|
@@ -324,12 +324,9 @@
|
|
|
324
324
|
// try {
|
|
325
325
|
// await fs.promises.access(file);
|
|
326
326
|
// await fs.promises.unlink(file);
|
|
327
|
-
// console.log('The file was successfully deleted');
|
|
328
327
|
// } catch (err) {
|
|
329
328
|
// if (err.code === 'ENOENT') {
|
|
330
|
-
// console.log('The file does not exist');
|
|
331
329
|
// } else if (err.code === 'EPERM') {
|
|
332
|
-
// console.log('You do not have permission to delete this file');
|
|
333
330
|
// } else {
|
|
334
331
|
// console.error(`An error occurred: ${err}`);
|
|
335
332
|
// }
|
package/lib/v4/DataAccessor.d.ts
CHANGED
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
import { Entity } from "../../interfaces/types";
|
|
5
5
|
import { ActionType } from "../../interfaces/adminpanelConfig";
|
|
6
6
|
import { Fields } from "../../helpers/fieldsHelper";
|
|
7
|
+
import { Adminizer } from "../Adminizer";
|
|
8
|
+
import { UserAP } from "models/UserAP";
|
|
7
9
|
export declare class DataAccessor {
|
|
8
10
|
private readonly adminizer;
|
|
9
|
-
user:
|
|
11
|
+
user: UserAP;
|
|
10
12
|
entity: Entity;
|
|
11
13
|
action: ActionType;
|
|
12
14
|
private fields;
|
|
13
|
-
|
|
15
|
+
private actionVerb;
|
|
16
|
+
constructor(adminizer: Adminizer, user: UserAP, entity: Entity, action: ActionType);
|
|
14
17
|
/**
|
|
15
18
|
* Retrieves the fields for the given entity based on action type,
|
|
16
19
|
* taking into account access rights and configuration settings.
|
package/lib/v4/DataAccessor.js
CHANGED
|
@@ -6,11 +6,13 @@ export class DataAccessor {
|
|
|
6
6
|
entity;
|
|
7
7
|
action;
|
|
8
8
|
fields = null;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
this.
|
|
9
|
+
actionVerb;
|
|
10
|
+
constructor(adminizer, user, entity, action) {
|
|
11
|
+
this.adminizer = adminizer;
|
|
12
|
+
this.user = user;
|
|
12
13
|
this.entity = entity;
|
|
13
14
|
this.action = action;
|
|
15
|
+
this.actionVerb = getTokenAction(this.action);
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* Retrieves the fields for the given entity based on action type,
|
|
@@ -26,10 +28,19 @@ export class DataAccessor {
|
|
|
26
28
|
}
|
|
27
29
|
// get action and field configs
|
|
28
30
|
const actionConfig = ControllerHelper.findActionConfig(this.entity, this.action);
|
|
29
|
-
const fieldsConfig = this.entity.config
|
|
31
|
+
const fieldsConfig = this.entity.config?.fields || {};
|
|
30
32
|
const modelAttributes = this.entity.model.attributes;
|
|
33
|
+
const tokenId = `${this.actionVerb}-${this.entity.model.modelname}-${this.entity.type}`;
|
|
34
|
+
if (!this.adminizer.accessRightsHelper.hasPermission(tokenId, this.user)) {
|
|
35
|
+
Adminizer.log.debug(`No access rights to ${this.entity.type}: ${this.entity.model.modelname}`);
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
31
38
|
const result = {};
|
|
32
39
|
Object.entries(modelAttributes).forEach(([key, modelField]) => {
|
|
40
|
+
// The fields that are recorded separately from the connection in some ORMs, because they are processed at the level above them.
|
|
41
|
+
if (modelAttributes[key].primaryKeyForAssociation === true) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
33
44
|
// Checks for short type in Waterline: fieldName: 'string'
|
|
34
45
|
if (typeof modelField === "string") {
|
|
35
46
|
modelField = { type: modelField };
|
|
@@ -66,13 +77,18 @@ export class DataAccessor {
|
|
|
66
77
|
let populatedModelFieldsConfig = {};
|
|
67
78
|
if (modelField.type === "association" || modelField.type === "association-many") {
|
|
68
79
|
const modelName = modelField.model || modelField.collection;
|
|
80
|
+
const tokenId = `${this.actionVerb}-${modelName}-${this.entity.type}`;
|
|
81
|
+
if (!this.adminizer.accessRightsHelper.hasPermission(tokenId, this.user)) {
|
|
82
|
+
Adminizer.log.silly(`No access rights to ${this.entity.type}: ${this.entity.model.modelname}`);
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
69
85
|
if (modelName) {
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
86
|
+
const model = this.adminizer.modelHandler.model.get(modelName);
|
|
87
|
+
if (model) {
|
|
72
88
|
populatedModelFieldsConfig = this.getAssociatedFieldsConfig(modelName);
|
|
73
89
|
}
|
|
74
90
|
else {
|
|
75
|
-
Adminizer.log.error(`Model not found: ${modelName}`);
|
|
91
|
+
Adminizer.log.error(`DataAccessor > getFieldsConfig > Model not found: ${modelName} when ${key}`);
|
|
76
92
|
}
|
|
77
93
|
}
|
|
78
94
|
}
|
|
@@ -94,10 +110,9 @@ export class DataAccessor {
|
|
|
94
110
|
return undefined;
|
|
95
111
|
}
|
|
96
112
|
// Check if user has access to the associated model
|
|
97
|
-
const
|
|
98
|
-
const tokenId = `${actionVerb}-${modelName}-${this.entity.type}`;
|
|
113
|
+
const tokenId = `${this.actionVerb}-${modelName}-${this.entity.type}`;
|
|
99
114
|
if (!this.adminizer.accessRightsHelper.hasPermission(tokenId, this.user)) {
|
|
100
|
-
Adminizer.log.
|
|
115
|
+
Adminizer.log.debug(`No access rights to ${this.entity.type}: ${modelName}`);
|
|
101
116
|
return undefined;
|
|
102
117
|
}
|
|
103
118
|
const associatedFields = {};
|
|
@@ -327,7 +342,7 @@ export class DataAccessor {
|
|
|
327
342
|
throw new Error(`No intermediate record found in model "${intermediateRelation.model}" associated with user ID "${this.user.id}"`);
|
|
328
343
|
}
|
|
329
344
|
// Ensure there is only one associated intermediate record
|
|
330
|
-
const intermediateRecordCount = await intermediateModel.count({ [via]: this.user.id });
|
|
345
|
+
const intermediateRecordCount = await intermediateModel.count({ [via]: this.user.id }, this);
|
|
331
346
|
if (intermediateRecordCount > 1) {
|
|
332
347
|
throw new Error(`Multiple intermediate records found in model "${intermediateRelation.model}" associated with user ID "${this.user.id}". ` +
|
|
333
348
|
`Expected only one`);
|
|
@@ -363,10 +378,11 @@ export class DataAccessor {
|
|
|
363
378
|
const relation = modelAttributes[accessField];
|
|
364
379
|
if (relation && ['userap', 'groupap'].includes(relation.model.toLowerCase())) {
|
|
365
380
|
if (relation.model.toLowerCase() === 'userap') {
|
|
366
|
-
|
|
381
|
+
if (!this.user.isAdministrator) {
|
|
382
|
+
updatedRecord[accessField] = this.user.id;
|
|
383
|
+
}
|
|
367
384
|
}
|
|
368
385
|
else if (relation.model.toLowerCase() === 'groupap') {
|
|
369
|
-
// Works only for users with only one group, later it can be resolved with group weight
|
|
370
386
|
const userGroups = this.user.groups || [];
|
|
371
387
|
if (userGroups.length === 1) {
|
|
372
388
|
updatedRecord[accessField] = userGroups[0].id;
|
|
@@ -409,7 +425,7 @@ export class DataAccessor {
|
|
|
409
425
|
throw new Error(`No intermediate record found in model "${intermediateRelation.model}" linking user "${this.user.id}" to the main record`);
|
|
410
426
|
}
|
|
411
427
|
// Ensure there is only one associated intermediate record
|
|
412
|
-
const intermediateRecordCount = await intermediateModel.count({ [via]: this.user.id });
|
|
428
|
+
const intermediateRecordCount = await intermediateModel.count({ [via]: this.user.id }, this);
|
|
413
429
|
if (intermediateRecordCount > 1) {
|
|
414
430
|
throw new Error(`Multiple intermediate records found in model "${intermediateRelation.model}" associated with user ID "${this.user.id}". ` +
|
|
415
431
|
`Expected only one`);
|
package/lib/v4/I18n.js
CHANGED
|
@@ -104,7 +104,9 @@ export class I18n {
|
|
|
104
104
|
return;
|
|
105
105
|
const file = this.locateFile(locale);
|
|
106
106
|
const tmpFile = `${file}.tmp`;
|
|
107
|
+
const dir = path.dirname(file);
|
|
107
108
|
try {
|
|
109
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
108
110
|
fs.writeFileSync(tmpFile, JSON.stringify(I18n.locales[locale], null, this.indent), "utf8");
|
|
109
111
|
fs.renameSync(tmpFile, file);
|
|
110
112
|
}
|
package/lib/v4/POWCaptcha.js
CHANGED
|
@@ -54,7 +54,6 @@ export class POWCaptcha {
|
|
|
54
54
|
if (!task || task.label !== label)
|
|
55
55
|
return false;
|
|
56
56
|
// Verify the solution (should be equal to puzzleOptions.message)
|
|
57
|
-
// console.log("QUESTION", `${taskId}:${label}`)
|
|
58
57
|
if (`${taskId}:${label}` === captchaSolution) {
|
|
59
58
|
this.deleteTask(taskId);
|
|
60
59
|
return true;
|
package/lib/v4/PolicyManager.js
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function signUser(user: JwtPayload, JWT_SECRET: string): string;
|
|
2
|
+
interface JwtPayload {
|
|
3
|
+
id: number;
|
|
4
|
+
login: string;
|
|
5
|
+
isAdministrator?: boolean;
|
|
6
|
+
iat?: number;
|
|
7
|
+
exp?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function verifyUser(token: string, JWT_SECRET: string): JwtPayload | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import jwt from 'jsonwebtoken';
|
|
2
|
+
export function signUser(user, JWT_SECRET) {
|
|
3
|
+
return jwt.sign(user, JWT_SECRET, {
|
|
4
|
+
expiresIn: '15d',
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
export function verifyUser(token, JWT_SECRET) {
|
|
8
|
+
try {
|
|
9
|
+
const decoded = jwt.verify(token, JWT_SECRET);
|
|
10
|
+
if (typeof decoded === 'object' && decoded !== null && 'id' in decoded && 'login' in decoded) {
|
|
11
|
+
return decoded;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -10,6 +10,10 @@ export interface Attribute {
|
|
|
10
10
|
collection?: string;
|
|
11
11
|
via?: string;
|
|
12
12
|
allowNull?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* This is a field that indicates that it refers to keep the bond key 1: 1
|
|
15
|
+
*/
|
|
16
|
+
primaryKeyForAssociation?: boolean;
|
|
13
17
|
}
|
|
14
18
|
export interface ModelAttributes {
|
|
15
19
|
[key: string]: Attribute;
|
|
@@ -49,7 +53,7 @@ export declare abstract class AbstractModel<T> {
|
|
|
49
53
|
update(criteria: Partial<T>, data: Partial<T>, dataAccessor: DataAccessor): Promise<Partial<T>[]>;
|
|
50
54
|
destroyOne(criteria: Partial<T>, dataAccessor: DataAccessor): Promise<Partial<T> | null>;
|
|
51
55
|
destroy(criteria: Partial<T>, dataAccessor: DataAccessor): Promise<Partial<T>[]>;
|
|
52
|
-
count(criteria: Partial<T> | undefined): Promise<number>;
|
|
56
|
+
count(criteria: Partial<T> | undefined, dataAccessor: DataAccessor): Promise<number>;
|
|
53
57
|
}
|
|
54
58
|
export declare abstract class AbstractAdapter {
|
|
55
59
|
abstract Model: any;
|
|
@@ -17,13 +17,11 @@ export class AbstractModel {
|
|
|
17
17
|
async findOne(criteria, dataAccessor) {
|
|
18
18
|
criteria = await dataAccessor.sanitizeUserRelationAccess(criteria);
|
|
19
19
|
let record = await this._findOne(criteria);
|
|
20
|
-
console.log(record, "record");
|
|
21
20
|
return record ? dataAccessor.process(record) : null;
|
|
22
21
|
}
|
|
23
22
|
async find(criteria, dataAccessor) {
|
|
24
23
|
criteria = await dataAccessor.sanitizeUserRelationAccess(criteria);
|
|
25
24
|
let records = await this._find(criteria);
|
|
26
|
-
console.log(records, "records");
|
|
27
25
|
return records.map(record => dataAccessor.process(record));
|
|
28
26
|
}
|
|
29
27
|
async updateOne(criteria, data, dataAccessor) {
|
|
@@ -48,7 +46,8 @@ export class AbstractModel {
|
|
|
48
46
|
let records = await this._destroy(criteria);
|
|
49
47
|
return records.map(record => dataAccessor.process(record));
|
|
50
48
|
}
|
|
51
|
-
async count(criteria) {
|
|
49
|
+
async count(criteria, dataAccessor) {
|
|
50
|
+
criteria = await dataAccessor.sanitizeUserRelationAccess(criteria);
|
|
52
51
|
return this._count(criteria);
|
|
53
52
|
}
|
|
54
53
|
}
|
|
@@ -8,7 +8,6 @@ export class ModelHandler {
|
|
|
8
8
|
}
|
|
9
9
|
this.models.set(modelname, modelInstance);
|
|
10
10
|
Adminizer.log.debug(`Model with name [${modelname}] was registered`);
|
|
11
|
-
console.log(`Model with name [${modelname}] was registered`);
|
|
12
11
|
}
|
|
13
12
|
/** Improved model getter, so you can write both model.get("UserAP") and model.get("userap") */
|
|
14
13
|
get model() {
|