adminizer 4.6.0 → 4.7.0-build.221

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.
Files changed (335) hide show
  1. package/Readme.md +12 -0
  2. package/assets/RelationDialogStack-CnHFOYyR.css +1 -0
  3. package/assets/RelationDialogStack-DI2bZxQX.js +20 -0
  4. package/assets/add-4213XScp.js +1 -0
  5. package/assets/add-group--F1XxfJ1.js +1 -0
  6. package/assets/add-group-form-DKRXC2n-.js +1 -0
  7. package/assets/add-user-b9HfMq7z.js +1 -0
  8. package/assets/add-user-form-UXAToWQd.js +1 -0
  9. package/assets/app-Clx8f5hd.css +1 -0
  10. package/assets/app-layout-C02ja4OI.js +1 -0
  11. package/assets/app-shell-D8wtkECO.js +1 -0
  12. package/assets/app-sidebar-BR5_zwxj.js +1 -0
  13. package/assets/app-sidebar-header-BZbIBQjq.js +1 -0
  14. package/assets/app.js +59 -7990
  15. package/assets/breadcrumbs-CODaqVkB.js +1 -0
  16. package/assets/catalog-6ZZjWdFs.js +6 -0
  17. package/assets/dashboard-CftAdKiH.js +3 -0
  18. package/assets/date-picker-DSOkNiNo.js +1 -0
  19. package/assets/del-modal-Cd4M7af8.js +1 -0
  20. package/assets/dynamic-controls-BsrJhPDY.js +1 -0
  21. package/assets/geo-json-CzR5JBXL.js +1 -0
  22. package/assets/handsontable-BI98OF5R.js +336 -0
  23. package/assets/history-DLHSU7Ak.js +1 -0
  24. package/assets/home-NcQ7nnU0.js +2 -0
  25. package/assets/icon-C2JNaLxH.js +1 -0
  26. package/assets/init-user-D2HSyXup.js +1 -0
  27. package/assets/input-error-CH2caTtO.js +1 -0
  28. package/assets/jsoneditor-DVNQmA6G.js +3869 -0
  29. package/assets/list-CFU0-TgN.js +4 -0
  30. package/assets/login-DFSLEO17.js +1 -0
  31. package/assets/manifest.json +246 -273
  32. package/assets/material-icon-Bx9pGQiQ.js +1 -0
  33. package/assets/media-manager-WcKe1EvD.js +6 -0
  34. package/assets/module-CT7PC6pc.js +1 -0
  35. package/assets/monaco-Bl4zdWCn.js +11 -0
  36. package/assets/nav-footer-BiSQkPt4.js +1 -0
  37. package/assets/nav-main-rTH0PfDw.js +1 -0
  38. package/assets/nav-user-Bj6cWs0a.js +1 -0
  39. package/assets/notification-Bi-PX87D.js +20 -0
  40. package/assets/pagination-render-AKJvTIRA.js +1 -0
  41. package/assets/register-BTP4uxsK.js +1 -0
  42. package/assets/ru-eW0WKkga.js +1 -0
  43. package/assets/theme-switcher-Dm8EOGzx.js +1 -0
  44. package/assets/toast-editor-DOg_gvSp.js +668 -0
  45. package/assets/user-filters-list-YUfR4XMI.js +1 -0
  46. package/assets/user-info-BgSbT02v.js +1 -0
  47. package/assets/user-menu-content-TQTXHIv6.js +1 -0
  48. package/assets/{vanilla-picker-l5rcX3cq.js → vanilla-picker-B3LgXoKV.js} +1 -7
  49. package/assets/welcome-vLwTu1R6.js +1 -0
  50. package/controllers/add.d.ts +1 -1
  51. package/controllers/add.js +20 -26
  52. package/controllers/addGroup.d.ts +1 -1
  53. package/controllers/addGroup.js +7 -15
  54. package/controllers/addUser.d.ts +1 -1
  55. package/controllers/addUser.js +10 -16
  56. package/controllers/catalog/Catalog.d.ts +1 -1
  57. package/controllers/catalog/Catalog.js +1 -10
  58. package/controllers/catalog/FrontendCatalogAdapter.d.ts +3 -3
  59. package/controllers/catalog/FrontendCatalogAdapter.js +0 -6
  60. package/controllers/catalog/FrontentCatalogAdapter.d.ts +3 -3
  61. package/controllers/catalog/FrontentCatalogAdapter.js +0 -4
  62. package/controllers/ckeditorUpload.js +2 -18
  63. package/controllers/dashboard.d.ts +1 -1
  64. package/controllers/dashboard.js +2 -5
  65. package/controllers/edit.js +24 -37
  66. package/controllers/editGroup.d.ts +1 -1
  67. package/controllers/editGroup.js +10 -21
  68. package/controllers/editUser.d.ts +1 -1
  69. package/controllers/editUser.js +11 -23
  70. package/controllers/exportData.d.ts +6 -0
  71. package/controllers/exportData.js +315 -0
  72. package/controllers/feed.d.ts +6 -0
  73. package/controllers/feed.js +73 -0
  74. package/controllers/feedback/feedbackController.d.ts +1 -1
  75. package/controllers/feedback/feedbackController.js +5 -7
  76. package/controllers/filter-fields/columns.d.ts +11 -0
  77. package/controllers/filter-fields/columns.js +106 -0
  78. package/controllers/filter-fields/filterFields.d.ts +10 -0
  79. package/controllers/filter-fields/filterFields.js +141 -0
  80. package/controllers/filter-fields/getAllUserFilters.d.ts +6 -0
  81. package/controllers/filter-fields/getAllUserFilters.js +115 -0
  82. package/controllers/filter-fields/groups.d.ts +5 -0
  83. package/controllers/filter-fields/groups.js +26 -0
  84. package/controllers/filter-fields/savedFilters.d.ts +25 -0
  85. package/controllers/filter-fields/savedFilters.js +317 -0
  86. package/controllers/getAllWidgets.d.ts +1 -1
  87. package/controllers/getAllWidgets.js +1 -9
  88. package/controllers/history-actions/HistoryController.js +6 -31
  89. package/controllers/initUser.js +6 -5
  90. package/controllers/inlineUpdate.d.ts +7 -0
  91. package/controllers/inlineUpdate.js +148 -0
  92. package/controllers/list.d.ts +1 -1
  93. package/controllers/list.js +383 -70
  94. package/controllers/listUserFilters.d.ts +5 -0
  95. package/controllers/listUserFilters.js +26 -0
  96. package/controllers/login.js +2 -2
  97. package/controllers/media-manager/mediaManagerApi.js +0 -9
  98. package/controllers/navigation/edit.js +3 -9
  99. package/controllers/notifications/NotificationController.d.ts +1 -1
  100. package/controllers/notifications/NotificationController.js +12 -36
  101. package/controllers/register.js +10 -9
  102. package/controllers/remove.js +10 -19
  103. package/controllers/timezones.d.ts +1 -1
  104. package/controllers/timezones.js +0 -6
  105. package/controllers/userApiKey.d.ts +7 -0
  106. package/controllers/userApiKey.js +36 -0
  107. package/controllers/view.js +14 -26
  108. package/controllers/welcome.d.ts +1 -1
  109. package/controllers/welcome.js +0 -4
  110. package/controllers/widgets/Action.d.ts +1 -1
  111. package/controllers/widgets/Action.js +1 -9
  112. package/controllers/widgets/Custom.d.ts +1 -1
  113. package/controllers/widgets/Custom.js +1 -9
  114. package/controllers/widgets/Info.d.ts +1 -1
  115. package/controllers/widgets/Info.js +1 -9
  116. package/controllers/widgets/filterInfo.d.ts +1 -0
  117. package/controllers/widgets/filterInfo.js +44 -0
  118. package/controllers/widgets/switch.d.ts +1 -1
  119. package/controllers/widgets/switch.js +1 -9
  120. package/controllers/widgetsDB.d.ts +1 -1
  121. package/controllers/widgetsDB.js +2 -8
  122. package/helpers/accessRightsHelper.d.ts +1 -1
  123. package/helpers/accessRightsHelper.js +5 -4
  124. package/helpers/apiKeyHelper.d.ts +5 -0
  125. package/helpers/apiKeyHelper.js +8 -0
  126. package/helpers/configHelper.js +12 -15
  127. package/helpers/controllerHelper.d.ts +14 -21
  128. package/helpers/controllerHelper.js +50 -83
  129. package/helpers/fieldsHelper.js +3 -3
  130. package/helpers/filterDatetimeHelper.d.ts +5 -0
  131. package/helpers/filterDatetimeHelper.js +84 -0
  132. package/helpers/inertiaActionsHelper.d.ts +2 -2
  133. package/helpers/inertiaActionsHelper.js +5 -4
  134. package/helpers/inertiaAddHelper.d.ts +3 -414
  135. package/helpers/inertiaAddHelper.js +39 -15
  136. package/helpers/inertiaGroupHelper.d.ts +2 -2
  137. package/helpers/inertiaGroupHelper.js +3 -3
  138. package/helpers/inertiaListHelper.d.ts +7 -3
  139. package/helpers/inertiaListHelper.js +26 -12
  140. package/helpers/inertiaMenuHelper.d.ts +1 -0
  141. package/helpers/inertiaMenuHelper.js +15 -3
  142. package/helpers/inertiaUserHelper.d.ts +3 -2
  143. package/helpers/inertiaUserHelper.js +7 -3
  144. package/helpers/menuHelper.d.ts +5 -2
  145. package/helpers/menuHelper.js +64 -12
  146. package/helpers/viteHelper.js +1 -2
  147. package/index.d.ts +6 -2
  148. package/index.js +6 -2
  149. package/interfaces/adminpanelConfig.d.ts +126 -39
  150. package/interfaces/internalModelAccess.d.ts +37 -0
  151. package/interfaces/internalModelAccess.js +1 -0
  152. package/interfaces/listQueryBuilder.d.ts +22 -0
  153. package/interfaces/listQueryBuilder.js +1 -0
  154. package/interfaces/queryCriteria.d.ts +54 -0
  155. package/interfaces/queryCriteria.js +1 -0
  156. package/interfaces/types.d.ts +1 -13
  157. package/lib/Adminizer.d.ts +4 -2
  158. package/lib/Adminizer.js +29 -10
  159. package/lib/DataAccessor.d.ts +8 -5
  160. package/lib/DataAccessor.js +89 -42
  161. package/lib/I18n.d.ts +5 -1
  162. package/lib/I18n.js +45 -19
  163. package/lib/MiddlewareManager.d.ts +8 -0
  164. package/lib/MiddlewareManager.js +53 -0
  165. package/lib/ai-assistant/OpenAiModelService.d.ts +3 -3
  166. package/lib/ai-assistant/OpenAiModelService.js +23 -24
  167. package/lib/catalog/Navigation.d.ts +1 -0
  168. package/lib/catalog/Navigation.js +12 -11
  169. package/lib/controls/jsoneditor/JsonEditor.d.ts +1 -2
  170. package/lib/controls/markdown/ToastUiEditor.d.ts +1 -2
  171. package/lib/feedback/FeedbackHandler.js +2 -2
  172. package/lib/filters/ConditionValidator.d.ts +107 -0
  173. package/lib/filters/ConditionValidator.js +483 -0
  174. package/lib/filters/CustomFilterHandler.d.ts +122 -0
  175. package/lib/filters/CustomFilterHandler.js +131 -0
  176. package/lib/filters/FilterCustomFieldHandler.d.ts +2 -0
  177. package/lib/filters/FilterCustomFieldHandler.js +2 -0
  178. package/lib/filters/FilterService.d.ts +82 -0
  179. package/lib/filters/FilterService.js +323 -0
  180. package/lib/filters/index.d.ts +6 -0
  181. package/lib/filters/index.js +4 -0
  182. package/lib/history-actions/AbstractHistoryAdapter.d.ts +5 -4
  183. package/lib/history-actions/AbstractHistoryAdapter.js +45 -30
  184. package/lib/history-actions/DefaultHistoryAdapter.d.ts +2 -0
  185. package/lib/history-actions/DefaultHistoryAdapter.js +12 -6
  186. package/lib/history-actions/HistoryHandler.js +1 -1
  187. package/lib/list-query-builder/ListQueryBuilder.d.ts +117 -0
  188. package/lib/list-query-builder/ListQueryBuilder.js +707 -0
  189. package/lib/media-manager/AbstractMediaManager.d.ts +9 -8
  190. package/lib/media-manager/DefaultMediaManager.d.ts +2 -0
  191. package/lib/media-manager/DefaultMediaManager.js +27 -15
  192. package/lib/media-manager/Items.d.ts +4 -1
  193. package/lib/media-manager/Items.js +62 -59
  194. package/lib/media-manager/MediaManagerHandler.js +1 -1
  195. package/lib/media-manager/helpers/MediaManagerHelper.d.ts +5 -1
  196. package/lib/media-manager/helpers/MediaManagerHelper.js +38 -4
  197. package/lib/model/AbstractModel.d.ts +33 -25
  198. package/lib/model/AbstractModel.js +54 -2
  199. package/lib/model/InternalModelAccessFactory.d.ts +18 -0
  200. package/lib/model/InternalModelAccessFactory.js +82 -0
  201. package/lib/model/ModelHandler.d.ts +6 -0
  202. package/lib/model/ModelHandler.js +14 -0
  203. package/lib/model/adapter/sequelize.d.ts +32 -10
  204. package/lib/model/adapter/sequelize.js +409 -62
  205. package/lib/model/adapter/typeorm.d.ts +62 -0
  206. package/lib/model/adapter/typeorm.js +777 -0
  207. package/lib/model/internalModelAccessToken.d.ts +1 -0
  208. package/lib/model/internalModelAccessToken.js +1 -0
  209. package/lib/model/internalModelRepository.d.ts +3 -0
  210. package/lib/model/internalModelRepository.js +4 -0
  211. package/lib/notifications/AbstractNotificationService.d.ts +3 -0
  212. package/lib/notifications/AbstractNotificationService.js +42 -36
  213. package/lib/notifications/GeneralNotificationService.js +37 -40
  214. package/lib/notifications/SystemNotificationService.js +33 -36
  215. package/lib/requestProcessor.js +0 -3
  216. package/lib/ui-i18n/getUiTranslations.d.ts +1 -0
  217. package/lib/ui-i18n/getUiTranslations.js +3 -0
  218. package/lib/ui-i18n/uiTranslationKeys.d.ts +6 -0
  219. package/lib/ui-i18n/uiTranslationKeys.js +268 -0
  220. package/lib/widgets/widgetHandler.d.ts +7 -2
  221. package/lib/widgets/widgetHandler.js +98 -18
  222. package/models/FilterAP.d.ts +116 -0
  223. package/models/FilterAP.js +68 -0
  224. package/models/FilterColumnAP.d.ts +32 -0
  225. package/models/FilterColumnAP.js +21 -0
  226. package/models/GroupAP.d.ts +1 -1
  227. package/models/HistoryActionsAP.d.ts +3 -3
  228. package/models/MediaManagerMetaAP.d.ts +1 -1
  229. package/models/NavigationAP.d.ts +1 -1
  230. package/models/UserAP.d.ts +6 -1
  231. package/models/UserAP.js +4 -0
  232. package/package.json +39 -32
  233. package/policies/authPolicies.d.ts +12 -0
  234. package/policies/authPolicies.js +104 -0
  235. package/policies/permissionResolvers.d.ts +12 -0
  236. package/policies/permissionResolvers.js +52 -0
  237. package/services/FeedService.d.ts +70 -0
  238. package/services/FeedService.js +334 -0
  239. package/system/Router.d.ts +1 -0
  240. package/system/Router.js +136 -59
  241. package/system/bindAccessRights.js +11 -30
  242. package/system/bindAuthorization.js +18 -18
  243. package/system/bindCors.js +16 -1
  244. package/system/bindCustomFilterHandlers.d.ts +2 -0
  245. package/system/bindCustomFilterHandlers.js +4 -0
  246. package/system/bindInertia.js +18 -61
  247. package/system/bindReqFunctions.js +10 -2
  248. package/system/bindTranslations.js +7 -3
  249. package/system/buildInternalModelAccess.d.ts +4 -0
  250. package/system/buildInternalModelAccess.js +59 -0
  251. package/system/defaults.js +18 -14
  252. package/system/routePolicies.d.ts +2 -0
  253. package/system/routePolicies.js +29 -0
  254. package/translations/en.json +151 -39
  255. package/translations/ru.json +211 -64
  256. package/ui/components/handsontable.js +13 -27
  257. package/ui/components/ui/dialog-stack.js +1 -3
  258. package/ui/components/ui/popover.js +1 -1
  259. package/ui/components/ui/sidebar.js +1 -1
  260. package/assets/RelationDialogStack-D9UVEF9s.js +0 -407
  261. package/assets/RelationDialogStack-DV8OITPR.css +0 -4
  262. package/assets/add-BlvzWQKF.js +0 -1
  263. package/assets/add-group-1Uoq9NWe.js +0 -1
  264. package/assets/add-group-form-B01gwDGu.js +0 -1
  265. package/assets/add-user-BQCAsaRy.js +0 -1
  266. package/assets/add-user-form-Cgwc9JkI.js +0 -1
  267. package/assets/app-DaOMy1nl.css +0 -72
  268. package/assets/app-layout-CAm60qoE.js +0 -1
  269. package/assets/app-shell-QWCtn9ye.js +0 -1
  270. package/assets/app-sidebar-CfaYbnSy.js +0 -1
  271. package/assets/app-sidebar-header-BsPFDhZ8.js +0 -1
  272. package/assets/breadcrumbs-CZZirDj8.js +0 -1
  273. package/assets/catalog-k5myk7fk.js +0 -6
  274. package/assets/dashboard-BkL9ybBw.js +0 -3
  275. package/assets/date-picker-B5AZ_7Q9.js +0 -1
  276. package/assets/del-modal-BoyXZloG.js +0 -1
  277. package/assets/dynamic-controls-k61T9W2P.js +0 -1
  278. package/assets/form-1WGY0YgG.js +0 -1
  279. package/assets/form-DJapG3qF.js +0 -1
  280. package/assets/geo-json-DsMUHo0l.js +0 -4
  281. package/assets/handsontable-PxYdjN8c.js +0 -298
  282. package/assets/history-CluyR-yJ.js +0 -1
  283. package/assets/home-Dug9zBzM.js +0 -2
  284. package/assets/icon-DfDLMG5f.js +0 -1
  285. package/assets/init-user-CF80MEnT.js +0 -1
  286. package/assets/input-error-DuuqFgZa.js +0 -1
  287. package/assets/jsoneditor-De1FvcYu.js +0 -3882
  288. package/assets/list-CuexshNt.js +0 -1
  289. package/assets/list-table-BsEWjTKY.js +0 -22
  290. package/assets/login-eDemYzN-.js +0 -1
  291. package/assets/material-icon-DMT8KdmE.js +0 -1
  292. package/assets/media-manager-DfYa_mT_.js +0 -14
  293. package/assets/module-Cd4Tm6uq.js +0 -1
  294. package/assets/monaco-BhBYtg3d.js +0 -11
  295. package/assets/nav-footer-D3olYxtz.js +0 -1
  296. package/assets/nav-main-BctqyzeV.js +0 -1
  297. package/assets/nav-user-Bn1Lt-BZ.js +0 -1
  298. package/assets/notification-D64qvni-.js +0 -27
  299. package/assets/pagination-render-DxD78ahJ.js +0 -1
  300. package/assets/register-349PwYbe.js +0 -1
  301. package/assets/theme-switcher-DfExsHW2.js +0 -1
  302. package/assets/toast-editor-ESK5iWPx.js +0 -845
  303. package/assets/user-info-DtBK5Kh8.js +0 -1
  304. package/assets/user-menu-content-0XYOCMaA.js +0 -1
  305. package/assets/welcome-PDp-gUei.js +0 -1
  306. package/controllers/form.d.ts +0 -1
  307. package/controllers/form.js +0 -86
  308. package/helpers/formHelper.d.ts +0 -6
  309. package/helpers/formHelper.js +0 -38
  310. package/helpers/inertiaFromHelper.d.ts +0 -11
  311. package/helpers/inertiaFromHelper.js +0 -98
  312. package/helpers/runtimeMode.d.ts +0 -1
  313. package/helpers/runtimeMode.js +0 -3
  314. package/lib/PolicyManager.d.ts +0 -8
  315. package/lib/PolicyManager.js +0 -53
  316. package/lib/datatable/NodeTable.d.ts +0 -49
  317. package/lib/datatable/NodeTable.js +0 -207
  318. package/lib/model/adapter/waterline.d.ts +0 -32
  319. package/lib/model/adapter/waterline.js +0 -180
  320. package/migrations/index.d.ts +0 -3
  321. package/migrations/index.js +0 -4
  322. package/migrations/knex/20250106000001_adminizer_init.d.ts +0 -8
  323. package/migrations/knex/20250106000001_adminizer_init.js +0 -164
  324. package/migrations/umzug/0001.d.ts +0 -7
  325. package/migrations/umzug/0001.js +0 -121
  326. package/migrations/umzugExports.d.ts +0 -2
  327. package/migrations/umzugExports.js +0 -9
  328. package/system/bindForms.d.ts +0 -2
  329. package/system/bindForms.js +0 -20
  330. /package/{policies → middlewares}/addMessages.d.ts +0 -0
  331. /package/{policies → middlewares}/addMessages.js +0 -0
  332. /package/{policies → middlewares}/checkAuth.d.ts +0 -0
  333. /package/{policies → middlewares}/checkAuth.js +0 -0
  334. /package/{policies → middlewares}/setLocale.d.ts +0 -0
  335. /package/{policies → middlewares}/setLocale.js +0 -0
package/system/Router.js CHANGED
@@ -5,14 +5,23 @@ import _edit from "../controllers/edit.js";
5
5
  import _add from "../controllers/add.js";
6
6
  import _view from "../controllers/view.js";
7
7
  import _remove from "../controllers/remove.js";
8
+ import _inlineUpdate from "../controllers/inlineUpdate.js";
9
+ import _filterFields from "../controllers/filter-fields/filterFields.js";
10
+ import { getSavedFilters, saveFilter, deleteFilter, applyTemporaryFilter, getTemporaryFilter } from "../controllers/filter-fields/savedFilters.js";
11
+ import { getAllUserFilters } from "../controllers/filter-fields/getAllUserFilters.js";
12
+ import { getModelColumns, updateFilterColumns } from "../controllers/filter-fields/columns.js";
13
+ import { getAllGroups } from "../controllers/filter-fields/groups.js";
8
14
  import { ckEditorUpload } from "../controllers/ckeditorUpload.js";
9
- import _form from "../controllers/form.js";
15
+ import _exportData from "../controllers/exportData.js";
16
+ import _feed from "../controllers/feed.js";
17
+ import { getUserApiKey, regenerateUserApiKey } from "../controllers/userApiKey.js";
10
18
  import { widgetSwitchController } from "../controllers/widgets/switch.js";
11
19
  import _getAllWidgets from "../controllers/getAllWidgets.js";
12
20
  import _widgetsDB from "../controllers/widgetsDB.js";
13
21
  import { widgetInfoController } from '../controllers/widgets/Info.js';
14
22
  import { widgetActionController } from '../controllers/widgets/Action.js';
15
23
  import { widgetCustomController } from "../controllers/widgets/Custom.js";
24
+ import { widgetFilterInfoController } from "../controllers/widgets/filterInfo.js";
16
25
  import { catalogController } from "../controllers/catalog/Catalog.js";
17
26
  import { mediaManagerController } from "../controllers/media-manager/mediaManagerApi.js";
18
27
  import { thumbController } from "../controllers/media-manager/ThumbController.js";
@@ -21,6 +30,10 @@ import timezones from "../controllers/timezones.js";
21
30
  import { NotificationController } from "../controllers/notifications/NotificationController.js";
22
31
  import { AiAssistantController } from "../controllers/ai/AiAssistantController.js";
23
32
  import { HistoryController } from "../controllers/history-actions/HistoryController.js";
33
+ import listUserFilters from "../controllers/listUserFilters.js";
34
+ import { requireAnyPermission, requireAuthAPI, requireAuthEnabled, requireAuthUI, requirePermission } from "../policies/authPolicies.js";
35
+ import { aiModelToken, catalogToken, groupFilterVisibilityToken, historyToken, mediaManagerToken, modelCreateToken, modelDeleteToken, modelReadToken, modelUpdateToken, widgetToken, widgetsToken } from "../policies/permissionResolvers.js";
36
+ import { bindWithMiddlewares } from "./routePolicies.js";
24
37
  export default class Router {
25
38
  adminizer;
26
39
  constructor(adminizer) {
@@ -47,7 +60,8 @@ export default class Router {
47
60
  * List or one policy that should be bound to actions
48
61
  * @type {MiddlewareType[]}
49
62
  */
50
- let policies = adminizer.config.policies;
63
+ let middlewares = adminizer.config.middlewares;
64
+ const withPolicies = (action, ...policies) => bindWithMiddlewares(adminizer, middlewares, action, policies);
51
65
  /**
52
66
  * Prevent stale/cached admin API responses.
53
67
  * This protects JSON endpoints from browser/proxy cache and avoids
@@ -80,138 +94,201 @@ export default class Router {
80
94
  /**
81
95
  * Widgets All
82
96
  */
83
- adminizer.app.all(`${adminizer.config.routePrefix}/widgets-get-all`, adminizer.policyManager.bindPolicies(policies, _getAllWidgets));
97
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-get-all`, withPolicies(_getAllWidgets, requireAuthUI(), requirePermission(widgetsToken, { mode: "ui" })));
84
98
  /**
85
99
  * Widgets All from DB
86
100
  */
87
- adminizer.app.all(`${adminizer.config.routePrefix}/widgets-get-all-db`, adminizer.policyManager.bindPolicies(policies, _widgetsDB));
101
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-get-all-db`, withPolicies(_widgetsDB, requireAuthUI(), requirePermission(widgetsToken, { mode: "ui" })));
88
102
  /**
89
103
  * Widgets Switch
90
104
  */
91
- adminizer.app.all(`${adminizer.config.routePrefix}/widgets-switch/:widgetId`, adminizer.policyManager.bindPolicies(policies, widgetSwitchController));
105
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-switch/:widgetId`, withPolicies(widgetSwitchController, requireAuthUI(), requirePermission(widgetToken, { mode: "ui" })));
92
106
  /**
93
107
  * Widgets Info
94
108
  */
95
- adminizer.app.all(`${adminizer.config.routePrefix}/widgets-info/:widgetId`, adminizer.policyManager.bindPolicies(policies, widgetInfoController));
109
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-info/:widgetId`, withPolicies(widgetInfoController, requireAuthUI(), requirePermission(widgetToken, { mode: "ui" })));
110
+ /**
111
+ * Widgets Filter Info (built-in filter widgets)
112
+ */
113
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-filter-info/:filterId`, withPolicies(widgetFilterInfoController, requireAuthUI(), requirePermission(widgetsToken, { mode: "ui" })));
96
114
  /**
97
115
  * Widgets Action
98
116
  */
99
- adminizer.app.all(`${adminizer.config.routePrefix}/widgets-action/:widgetId`, adminizer.policyManager.bindPolicies(policies, widgetActionController));
117
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-action/:widgetId`, withPolicies(widgetActionController, requireAuthUI(), requirePermission(widgetToken, { mode: "ui" })));
100
118
  /**
101
119
  * Widgets Custom
102
120
  */
103
- adminizer.app.all(`${adminizer.config.routePrefix}/widgets-action/:widgetId`, adminizer.policyManager.bindPolicies(policies, widgetCustomController));
104
- /**
105
- * Edit form
106
- * */
107
- adminizer.app.all(`${adminizer.config.routePrefix}/form/:slug`, adminizer.policyManager.bindPolicies(policies, _form));
121
+ adminizer.app.all(`${adminizer.config.routePrefix}/widgets-action/:widgetId`, withPolicies(widgetCustomController, requireAuthUI(), requirePermission(widgetToken, { mode: "ui" })));
108
122
  /**
109
- * Create a base entity route
123
+ * Create a base ModelResource route
110
124
  */
111
- let baseRoute = `${adminizer.config.routePrefix}/:entityType(form|model)/:entityName`;
125
+ const resourceRoute = (suffix = '') => `${adminizer.config.routePrefix}/model/:modelResourceName${suffix}`;
112
126
  /**
113
127
  * Catalog
114
128
  */
115
- adminizer.app.all(`${adminizer.config.routePrefix}/catalog/:slug/:id`, adminizer.policyManager.bindPolicies(policies, catalogController));
116
- adminizer.app.all(`${adminizer.config.routePrefix}/catalog/:slug`, adminizer.policyManager.bindPolicies(policies, catalogController));
129
+ adminizer.app.all(`${adminizer.config.routePrefix}/catalog/:slug/:id`, withPolicies(catalogController, requireAuthUI(), requirePermission(catalogToken, { mode: "ui" })));
130
+ adminizer.app.all(`${adminizer.config.routePrefix}/catalog/:slug`, withPolicies(catalogController, requireAuthUI(), requirePermission(catalogToken, { mode: "ui" })));
117
131
  /**
118
132
  * Media Manager
119
133
  */
120
- adminizer.app.post(`${adminizer.config.routePrefix}/media-manager-uploader/:id/upload`, adminizer.policyManager.bindPolicies(policies, mediaManagerController));
121
- adminizer.app.post(`${adminizer.config.routePrefix}/media-manager-uploader/:id/upload-variant`, adminizer.policyManager.bindPolicies(policies, mediaManagerController));
122
- adminizer.app.all(`${adminizer.config.routePrefix}/media-manager-uploader/:id`, adminizer.policyManager.bindPolicies(policies, mediaManagerController));
123
- adminizer.app.all(`${adminizer.config.routePrefix}/get-thumbs`, adminizer.policyManager.bindPolicies(policies, thumbController));
134
+ adminizer.app.post(`${adminizer.config.routePrefix}/media-manager-uploader/:id/upload`, withPolicies(mediaManagerController, requireAuthUI(), requirePermission(mediaManagerToken, { mode: "ui" })));
135
+ adminizer.app.post(`${adminizer.config.routePrefix}/media-manager-uploader/:id/upload-variant`, withPolicies(mediaManagerController, requireAuthUI(), requirePermission(mediaManagerToken, { mode: "ui" })));
136
+ adminizer.app.all(`${adminizer.config.routePrefix}/media-manager-uploader/:id`, withPolicies(mediaManagerController, requireAuthUI(), requirePermission(mediaManagerToken, { mode: "ui" })));
137
+ adminizer.app.all(`${adminizer.config.routePrefix}/get-thumbs`, adminizer.middlewareManager.bindMiddlewares(middlewares, thumbController));
124
138
  /**
125
139
  * Upload images CKeditor5
126
140
  */
127
- adminizer.app.post(`${baseRoute}/ckeditor5/upload`, adminizer.policyManager.bindPolicies(policies, ckEditorUpload));
141
+ adminizer.app.post(resourceRoute('/ckeditor5/upload'), withPolicies(ckEditorUpload, requireAuthUI(), requireAnyPermission([
142
+ modelUpdateToken,
143
+ modelCreateToken,
144
+ ], { mode: "ui" })));
128
145
  /**
129
146
  * Notifications
130
147
  */
131
148
  if (adminizer.config.notifications.enabled) {
132
- adminizer.app.get(`${adminizer.config.routePrefix}/notifications`, adminizer.policyManager.bindPolicies(policies, NotificationController.viewAll));
133
- adminizer.app.post(`${adminizer.config.routePrefix}/notifications`, adminizer.policyManager.bindPolicies(policies, NotificationController.viewAll));
134
- adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api/stream`, adminizer.policyManager.bindPolicies(policies, NotificationController.getNotificationsStream));
135
- adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api/get-classes`, adminizer.policyManager.bindPolicies(policies, NotificationController.getNotificationClasses));
136
- adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api/:notificationClass`, adminizer.policyManager.bindPolicies(policies, NotificationController.getNotificationsByClass));
137
- adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api`, adminizer.policyManager.bindPolicies(policies, NotificationController.getUserNotifications));
138
- adminizer.app.put(`${adminizer.config.routePrefix}/notifications/api/:notificationClass/:id/read`, adminizer.policyManager.bindPolicies(policies, NotificationController.markAsRead));
139
- adminizer.app.put(`${adminizer.config.routePrefix}/notifications/api/read-all`, adminizer.policyManager.bindPolicies(policies, NotificationController.markAllAsRead));
140
- adminizer.app.post(`${adminizer.config.routePrefix}/notifications/api/search`, adminizer.policyManager.bindPolicies(policies, NotificationController.search));
149
+ adminizer.app.get(`${adminizer.config.routePrefix}/notifications`, withPolicies(NotificationController.viewAll, requireAuthUI()));
150
+ adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api/stream`, withPolicies(NotificationController.getNotificationsStream, requireAuthAPI()));
151
+ adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api/get-classes`, withPolicies(NotificationController.getNotificationClasses, requireAuthAPI()));
152
+ adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api/:notificationClass`, withPolicies(NotificationController.getNotificationsByClass, requireAuthAPI()));
153
+ adminizer.app.get(`${adminizer.config.routePrefix}/notifications/api`, withPolicies(NotificationController.getUserNotifications, requireAuthAPI()));
154
+ adminizer.app.put(`${adminizer.config.routePrefix}/notifications/api/:notificationClass/:id/read`, withPolicies(NotificationController.markAsRead, requireAuthAPI()));
155
+ adminizer.app.put(`${adminizer.config.routePrefix}/notifications/api/read-all`, withPolicies(NotificationController.markAllAsRead, requireAuthAPI()));
156
+ adminizer.app.post(`${adminizer.config.routePrefix}/notifications/api/search`, withPolicies(NotificationController.search, requireAuthAPI()));
141
157
  }
142
158
  /**
143
159
  * History-actions
144
160
  */
145
161
  if (adminizer.config.history?.enabled) {
146
- adminizer.app.get(`${adminizer.config.routePrefix}/history/view-all`, adminizer.policyManager.bindPolicies(policies, HistoryController.index));
147
- adminizer.app.post(`${adminizer.config.routePrefix}/history/view-all`, adminizer.policyManager.bindPolicies(policies, HistoryController.index));
148
- adminizer.app.post(`${adminizer.config.routePrefix}/history/get-model-history`, adminizer.policyManager.bindPolicies(policies, HistoryController.getAllModelHistory));
149
- adminizer.app.post(`${adminizer.config.routePrefix}/history/get-model-fields`, adminizer.policyManager.bindPolicies(policies, HistoryController.getModelFieldsHistory));
162
+ adminizer.app.get(`${adminizer.config.routePrefix}/history/view-all`, withPolicies(HistoryController.index, requireAuthUI(), requirePermission(historyToken, { mode: "ui" })));
163
+ adminizer.app.post(`${adminizer.config.routePrefix}/history/view-all`, withPolicies(HistoryController.index, requireAuthAPI(), requirePermission(historyToken)));
164
+ adminizer.app.post(`${adminizer.config.routePrefix}/history/get-model-history`, withPolicies(HistoryController.getAllModelHistory, requireAuthAPI(), requirePermission(historyToken)));
165
+ adminizer.app.post(`${adminizer.config.routePrefix}/history/get-model-fields`, withPolicies(HistoryController.getModelFieldsHistory, requireAuthAPI(), requirePermission(historyToken)));
150
166
  }
151
167
  if (adminizer.config.aiAssistant?.enabled) {
152
- adminizer.app.get(`${adminizer.config.routePrefix}/api/ai-assistant/models`, adminizer.policyManager.bindPolicies(policies, AiAssistantController.getModels));
153
- adminizer.app.get(`${adminizer.config.routePrefix}/api/ai-assistant/history/:modelId`, adminizer.policyManager.bindPolicies(policies, AiAssistantController.getHistory));
154
- adminizer.app.post(`${adminizer.config.routePrefix}/api/ai-assistant/query`, adminizer.policyManager.bindPolicies(policies, AiAssistantController.sendMessage));
155
- adminizer.app.delete(`${adminizer.config.routePrefix}/api/ai-assistant/history/:modelId`, adminizer.policyManager.bindPolicies(policies, AiAssistantController.resetHistory));
168
+ adminizer.app.get(`${adminizer.config.routePrefix}/api/ai-assistant/models`, withPolicies(AiAssistantController.getModels, requireAuthAPI()));
169
+ adminizer.app.get(`${adminizer.config.routePrefix}/api/ai-assistant/history/:modelId`, withPolicies(AiAssistantController.getHistory, requireAuthAPI(), requirePermission(aiModelToken)));
170
+ adminizer.app.post(`${adminizer.config.routePrefix}/api/ai-assistant/query`, withPolicies(AiAssistantController.sendMessage, requireAuthAPI(), requirePermission(aiModelToken)));
171
+ adminizer.app.delete(`${adminizer.config.routePrefix}/api/ai-assistant/history/:modelId`, withPolicies(AiAssistantController.resetHistory, requireAuthAPI(), requirePermission(aiModelToken)));
156
172
  }
157
173
  /**
158
174
  * List of records
159
175
  */
160
- adminizer.app.all(baseRoute, adminizer.policyManager.bindPolicies(policies, _list));
161
- adminizer.app.get(`${adminizer.config.routePrefix}/get-timezones`, adminizer.policyManager.bindPolicies(policies, timezones));
176
+ adminizer.app.all(resourceRoute(), withPolicies(_list, requireAuthUI(), requirePermission(modelReadToken, { mode: "ui" })));
177
+ if (adminizer.config.filters?.enabled) {
178
+ /**
179
+ * Get filter fields for model
180
+ */
181
+ adminizer.app.get(resourceRoute('/filter-fields'), withPolicies(_filterFields, requireAuthAPI(), requirePermission(modelReadToken)));
182
+ /**
183
+ * Saved filters
184
+ */
185
+ adminizer.app.get(resourceRoute('/saved-filters'), withPolicies(getSavedFilters, requireAuthAPI(), requirePermission(modelReadToken)));
186
+ adminizer.app.get(resourceRoute('/filter/temporary'), withPolicies(getTemporaryFilter, requireAuthAPI(), requirePermission(modelReadToken)));
187
+ adminizer.app.post(resourceRoute('/filter'), withPolicies(saveFilter, requireAuthAPI(), requirePermission(modelReadToken)));
188
+ adminizer.app.post(resourceRoute('/filter/apply'), withPolicies(applyTemporaryFilter, requireAuthAPI(), requirePermission(modelReadToken)));
189
+ adminizer.app.delete(resourceRoute('/filter/:id'), withPolicies(deleteFilter, requireAuthAPI(), requirePermission(modelReadToken)));
190
+ /**
191
+ * Get all groups (for admin filter visibility settings)
192
+ */
193
+ adminizer.app.get(`${adminizer.config.routePrefix}/groups`, withPolicies(getAllGroups, requireAuthAPI(), requirePermission(groupFilterVisibilityToken)));
194
+ /**
195
+ * Export data (JSON, CSV, XLSX)
196
+ */
197
+ adminizer.app.post(resourceRoute('/export'), withPolicies(_exportData, requireAuthAPI(), requirePermission(modelReadToken)));
198
+ /**
199
+ * Public feed API — export by apiKey without auth
200
+ * GET /adminizer/api/feed/:apiKey.json
201
+ * GET /adminizer/api/feed/:apiKey.xml
202
+ */
203
+ adminizer.app.get(`${adminizer.config.routePrefix}/api/feed/:apiKey.:format`, _feed);
204
+ // Also support without extension (defaults to JSON)
205
+ adminizer.app.get(`${adminizer.config.routePrefix}/api/feed/:apiKey`, _feed);
206
+ /**
207
+ * User Filters — list all filters accessible to the current user across all models
208
+ */
209
+ adminizer.app.get(`${adminizer.config.routePrefix}/api/all-user-filters`, withPolicies(getAllUserFilters, requireAuthAPI()));
210
+ adminizer.app.all(`${adminizer.config.routePrefix}/user-filters`, withPolicies(listUserFilters, requireAuthUI()));
211
+ /**
212
+ * Get model columns (available columns for the model)
213
+ */
214
+ adminizer.app.get(resourceRoute('/columns'), withPolicies(getModelColumns, requireAuthAPI(), requirePermission(modelReadToken)));
215
+ /**
216
+ * Update filter columns configuration
217
+ */
218
+ adminizer.app.post(resourceRoute('/filter/:filterId/columns'), withPolicies(updateFilterColumns, requireAuthAPI(), requirePermission(modelReadToken)));
219
+ }
220
+ /**
221
+ * User API Key management
222
+ * GET /adminizer/api/user-key — returns current user's API key
223
+ * POST /adminizer/api/user-key/regenerate — regenerates the API key
224
+ */
225
+ adminizer.app.get(`${adminizer.config.routePrefix}/api/user-key`, withPolicies(getUserApiKey, requireAuthEnabled(), requireAuthAPI()));
226
+ adminizer.app.post(`${adminizer.config.routePrefix}/api/user-key/regenerate`, withPolicies(regenerateUserApiKey, requireAuthEnabled(), requireAuthAPI()));
227
+ adminizer.app.get(`${adminizer.config.routePrefix}/get-timezones`, withPolicies(timezones, requireAuthUI()));
162
228
  if (adminizer.config.models) {
163
229
  for (let model in adminizer.config.models) {
164
- await this.bindModelRoutes(model, policies);
230
+ await this.bindModelRoutes(model, middlewares);
165
231
  }
166
232
  }
233
+ /**
234
+ * Inline update field in list view
235
+ */
236
+ adminizer.app.patch(resourceRoute('/inline/:id'), withPolicies(_inlineUpdate, requireAuthAPI(), requirePermission(modelUpdateToken)));
167
237
  /**
168
238
  * View record details
169
239
  */
170
- adminizer.app.all(baseRoute + "/view/:id", adminizer.policyManager.bindPolicies(policies, _view));
240
+ adminizer.app.all(resourceRoute('/view/:id'), withPolicies(_view, requireAuthUI(), requirePermission(modelReadToken, { mode: "ui" })));
171
241
  /**
172
242
  * Remove record
173
243
  */
174
- adminizer.app.all(baseRoute + "/remove/:id", adminizer.policyManager.bindPolicies(policies, _remove));
244
+ adminizer.app.all(resourceRoute('/remove/:id'), withPolicies(_remove, requireAuthUI(), requirePermission(modelDeleteToken, { mode: "ui" })));
175
245
  /**
176
246
  * Create a default dashboard
177
247
  */
178
248
  if (adminizer.config.dashboard) {
179
- adminizer.app.all(adminizer.config.routePrefix, adminizer.policyManager.bindPolicies(policies, _dashboard));
249
+ adminizer.app.all(adminizer.config.routePrefix, withPolicies(_dashboard, requireAuthUI()));
180
250
  }
181
251
  else {
182
- adminizer.app.all(adminizer.config.routePrefix, adminizer.policyManager.bindPolicies(policies, _welcome));
252
+ adminizer.app.all(adminizer.config.routePrefix, withPolicies(_welcome, requireAuthUI()));
183
253
  }
184
254
  // TODO emit can be used in tests
185
255
  adminizer.emitter.emit("router:bound");
186
256
  }
187
257
  unbindModelRoutes(model) {
188
- if (!this.adminizer.app._router)
258
+ const routerStack = this.getRouterStack();
259
+ if (!routerStack)
189
260
  return;
190
261
  const patterns = this.modelRoutePatterns.get(model);
191
262
  if (!patterns?.length)
192
263
  return;
193
264
  const removedPaths = [];
194
- this.adminizer.app._router.stack = this.adminizer.app._router.stack.filter((layer) => {
265
+ const filteredStack = routerStack.filter((layer) => {
195
266
  if (layer.route && patterns.some((p) => p.test(layer.route.path))) {
196
267
  removedPaths.push(layer.route.path);
197
268
  return false;
198
269
  }
199
270
  return true;
200
271
  });
272
+ routerStack.splice(0, routerStack.length, ...filteredStack);
201
273
  this.modelRoutePatterns.delete(model);
202
274
  Adminizer.log.debug(`Adminpanel removed routes for model \`${model}\`: ${removedPaths.join(', ')}`);
203
275
  }
276
+ getRouterStack() {
277
+ const app = this.adminizer.app;
278
+ const router = app.router ?? app._router;
279
+ return Array.isArray(router?.stack) ? router.stack : null;
280
+ }
204
281
  async bindModelRoutes(model, policies) {
205
282
  if (!policies)
206
- policies = this.adminizer.config.policies;
283
+ policies = this.adminizer.config.middlewares;
207
284
  if (this.modelRoutePatterns.has(model)) {
208
285
  this.unbindModelRoutes(model);
209
286
  }
210
287
  const modelConfig = this.adminizer.config.models[model];
211
288
  const prefix = `${this.adminizer.config.routePrefix}/model/${model}`;
212
289
  const registeredPaths = [];
213
- const register = (path, handler) => {
214
- this.adminizer.app.all(path, this.adminizer.policyManager.bindPolicies(policies, handler));
290
+ const register = (path, handler, policies = []) => {
291
+ this.adminizer.app.all(path, bindWithMiddlewares(this.adminizer, policies, handler, policies));
215
292
  const patterns = this.modelRoutePatterns.get(model) ?? [];
216
293
  patterns.push(new RegExp(`^${path.replace(/:[^/]+/g, '[^/]+')}$`));
217
294
  this.modelRoutePatterns.set(model, patterns);
@@ -219,9 +296,9 @@ export default class Router {
219
296
  };
220
297
  if (typeof modelConfig === "boolean" && modelConfig === true) {
221
298
  Adminizer.log.debug(`Adminpanel create CRUD routes for \`${model}\` by boolean true`);
222
- register(`${prefix}/add`, _add);
223
- register(`${prefix}/edit/:id`, _edit);
224
- register(`${prefix}/remove/:id`, _remove);
299
+ register(`${prefix}/add`, _add, [requireAuthUI(), requirePermission(() => `create-${model}-model`, { mode: "ui" })]);
300
+ register(`${prefix}/edit/:id`, _edit, [requireAuthUI(), requirePermission(() => `update-${model}-model`, { mode: "ui" })]);
301
+ register(`${prefix}/remove/:id`, _remove, [requireAuthUI(), requirePermission(() => `delete-${model}-model`, { mode: "ui" })]);
225
302
  }
226
303
  else if (modelConfig !== undefined && typeof modelConfig !== "boolean") {
227
304
  Adminizer.log.debug(`Adminpanel create CRUD routes for \`${model}\` by ModelConfig`);
@@ -232,14 +309,14 @@ export default class Router {
232
309
  if (addHandler?.controller) {
233
310
  if (typeof addHandler.controller === 'string') {
234
311
  let controller = await import(addHandler.controller);
235
- register(`${prefix}/add`, controller.default);
312
+ register(`${prefix}/add`, controller.default, [requireAuthUI(), requirePermission(() => `create-${model}-model`, { mode: "ui" })]);
236
313
  }
237
314
  else {
238
- register(`${prefix}/add`, addHandler.controller);
315
+ register(`${prefix}/add`, addHandler.controller, [requireAuthUI(), requirePermission(() => `create-${model}-model`, { mode: "ui" })]);
239
316
  }
240
317
  }
241
318
  else {
242
- register(`${prefix}/add`, _add);
319
+ register(`${prefix}/add`, _add, [requireAuthUI(), requirePermission(() => `create-${model}-model`, { mode: "ui" })]);
243
320
  }
244
321
  /**
245
322
  * Edit existing record
@@ -248,14 +325,14 @@ export default class Router {
248
325
  if (editHandler?.controller) {
249
326
  if (typeof editHandler.controller === 'string') {
250
327
  let controller = await import(editHandler.controller);
251
- register(`${prefix}/edit/:id`, controller.default);
328
+ register(`${prefix}/edit/:id`, controller.default, [requireAuthUI(), requirePermission(() => `update-${model}-model`, { mode: "ui" })]);
252
329
  }
253
330
  else {
254
- register(`${prefix}/edit/:id`, editHandler.controller);
331
+ register(`${prefix}/edit/:id`, editHandler.controller, [requireAuthUI(), requirePermission(() => `update-${model}-model`, { mode: "ui" })]);
255
332
  }
256
333
  }
257
334
  else {
258
- register(`${prefix}/edit/:id`, _edit);
335
+ register(`${prefix}/edit/:id`, _edit, [requireAuthUI(), requirePermission(() => `update-${model}-model`, { mode: "ui" })]);
259
336
  }
260
337
  }
261
338
  else {
@@ -1,3 +1,4 @@
1
+ import { GROUP_FILTER_VISIBILITY_TOKEN } from "../policies/permissionResolvers.js";
1
2
  export default async function bindAccessRights(adminizer) {
2
3
  if (adminizer.config.models) {
3
4
  let models = adminizer.config.models;
@@ -8,32 +9,6 @@ export default async function bindAccessRights(adminizer) {
8
9
  }
9
10
  }
10
11
  }
11
- if (adminizer.config.forms && adminizer.config.forms.data) {
12
- let forms = adminizer.config.forms.data;
13
- for (let key of Object.keys(forms)) {
14
- let department = `Form ${key}`;
15
- // create
16
- adminizer.accessRightsHelper.registerToken({
17
- id: `create-${key}-form`, name: "Create",
18
- description: "Access to creating form in database", department: department
19
- });
20
- // read
21
- adminizer.accessRightsHelper.registerToken({
22
- id: `read-${key}-form`, name: "Read",
23
- description: "Access to reading form in database", department: department
24
- });
25
- // update
26
- adminizer.accessRightsHelper.registerToken({
27
- id: `update-${key}-form`, name: "Update",
28
- description: "Access to updating form in database", department: department
29
- });
30
- // delete
31
- adminizer.accessRightsHelper.registerToken({
32
- id: `delete-${key}-form`, name: "Delete",
33
- description: "Access to deleting form in database", department: department
34
- });
35
- }
36
- }
37
12
  // Widgets
38
13
  adminizer.accessRightsHelper.registerToken({
39
14
  id: `widgets`, name: "Widgets",
@@ -46,13 +21,19 @@ export default async function bindAccessRights(adminizer) {
46
21
  description: "Are users allowed to log in to the admin panel?",
47
22
  department: "Admin panel"
48
23
  });
24
+ // Filters
25
+ adminizer.accessRightsHelper.registerToken({
26
+ id: GROUP_FILTER_VISIBILITY_TOKEN,
27
+ name: "Manage group filter visibility",
28
+ description: "Allows setting saved filter visibility to selected groups",
29
+ department: "Filters"
30
+ });
49
31
  // Default user group
50
32
  if (adminizer.config.registration && adminizer.config.registration.enable) {
51
- // TODO refactor CRUD functions for DataAccessor usage
52
- let defaultUserGroupRecord = await adminizer.modelHandler.model.get("GroupAP")["_findOne"]({ name: adminizer.config.registration.defaultUserGroup });
33
+ const groupModel = adminizer.modelHandler.internal("access-rights").get("GroupAP");
34
+ let defaultUserGroupRecord = await groupModel.findOne({ where: { name: adminizer.config.registration.defaultUserGroup } });
53
35
  if (!defaultUserGroupRecord) {
54
- // TODO refactor CRUD functions for DataAccessor usage
55
- await adminizer.modelHandler.model.get("GroupAP")?.["_create"]({
36
+ await groupModel.create({
56
37
  name: adminizer.config.registration.defaultUserGroup,
57
38
  description: "Group for default users (guests) who dont have access to fields"
58
39
  });
@@ -3,11 +3,12 @@ import _register from "../controllers/register.js";
3
3
  import _initUser from "../controllers/initUser.js";
4
4
  import { Adminizer } from "../lib/Adminizer.js";
5
5
  import { generate } from "password-hash";
6
+ import { generateUserApiKey } from "../helpers/apiKeyHelper.js";
6
7
  export default async function bindAuthorization(adminizer) {
8
+ const userModel = adminizer.modelHandler.internal("auth").get("UserAP");
7
9
  let admins;
8
10
  try {
9
- // TODO refactor CRUD functions for DataAccessor usage
10
- admins = await adminizer.modelHandler.model.get("UserAP")?.["_find"]({ isAdministrator: true });
11
+ admins = await userModel.find({ where: { isAdministrator: true } });
11
12
  }
12
13
  catch (e) {
13
14
  Adminizer.log.error("Error trying to find administrator", e);
@@ -16,8 +17,8 @@ export default async function bindAuthorization(adminizer) {
16
17
  /**
17
18
  * Router
18
19
  */
19
- let policies = adminizer.config.policies;
20
- let baseRoute = `${adminizer.config.routePrefix}/model/:entity`;
20
+ let policies = adminizer.config.middlewares;
21
+ let baseRoute = `${adminizer.config.routePrefix}/model/:modelResourceName`;
21
22
  let adminsCredentials = [];
22
23
  // if we have administrator profiles
23
24
  let config = adminizer.config;
@@ -45,14 +46,14 @@ export default async function bindAuthorization(adminizer) {
45
46
  try {
46
47
  let passwordHashed = generate(adminData.login + adminData.password + process.env.AP_PASSWORD_SALT);
47
48
  let password = 'masked';
48
- // TODO refactor CRUD functions for DataAccessor usage
49
- await adminizer.modelHandler.model.get("UserAP")?.["_create"]({
49
+ await userModel.create({
50
50
  login: adminData.login, passwordHashed: passwordHashed, fullName: "Administrator",
51
- isActive: true, isAdministrator: true
51
+ isActive: true, isAdministrator: true,
52
+ apiKey: generateUserApiKey()
52
53
  });
53
54
  }
54
55
  catch (e) {
55
- Adminizer.log.error("Could not create administrator profile", e);
56
+ Adminizer.log.error("Error trying to create administrator", e);
56
57
  return;
57
58
  }
58
59
  console.group("Administrators credentials");
@@ -63,10 +64,10 @@ export default async function bindAuthorization(adminizer) {
63
64
  try {
64
65
  let passwordHashed = generate("demodemo" + process.env.AP_PASSWORD_SALT);
65
66
  let password = 'masked';
66
- // TODO refactor CRUD functions for DataAccessor usage
67
- await adminizer.modelHandler.model.get("UserAP")?.["_create"]({
68
- login: 'demo', password: 'demo', passwordHashed: passwordHashed, fullName: "Administrator",
69
- isActive: true, isAdministrator: true
67
+ await userModel.create({
68
+ login: 'demo', passwordHashed: passwordHashed, fullName: "Administrator",
69
+ isActive: true, isAdministrator: true,
70
+ apiKey: generateUserApiKey()
70
71
  });
71
72
  }
72
73
  catch (e) {
@@ -77,15 +78,15 @@ export default async function bindAuthorization(adminizer) {
77
78
  else { // try to create one if we don't
78
79
  if (adminizer.config.auth.enable) {
79
80
  Adminizer.log.debug(`Adminpanel does not have an administrator`);
80
- adminizer.config.policies.push(initUserPolicy);
81
+ adminizer.config.middlewares.push(initUserPolicy);
81
82
  //@ts-ignore
82
83
  adminizer.app.use(`${adminizer.config.routePrefix}/init_user`, _initUser);
83
84
  }
84
85
  }
85
86
  if (adminizer.config.auth.enable) {
86
- adminizer.app.use(baseRoute + '/login', adminizer.policyManager.bindPolicies(policies, _login));
87
- adminizer.app.use(baseRoute + '/logout', adminizer.policyManager.bindPolicies(policies, _login));
88
- adminizer.app.use(baseRoute + '/register', adminizer.policyManager.bindPolicies(policies, _register));
87
+ adminizer.app.use(baseRoute + '/login', adminizer.middlewareManager.bindMiddlewares(policies, _login));
88
+ adminizer.app.use(baseRoute + '/logout', adminizer.middlewareManager.bindMiddlewares(policies, _login));
89
+ adminizer.app.use(baseRoute + '/register', adminizer.middlewareManager.bindMiddlewares(policies, _register));
89
90
  }
90
91
  }
91
92
  ;
@@ -95,8 +96,7 @@ function getRandomInt(min, max) {
95
96
  return Math.floor(Math.random() * (max - min)) + min;
96
97
  }
97
98
  async function initUserPolicy(req, res, proceed) {
98
- // TODO refactor CRUD functions for DataAccessor usage
99
- let admins = await req.adminizer.modelHandler.model.get("UserAP")?.["_find"]({ isAdministrator: true });
99
+ let admins = await req.adminizer.modelHandler.internal("auth").get("UserAP").find({ where: { isAdministrator: true } });
100
100
  if (!admins || !admins.length) {
101
101
  return res.redirect(`${req.adminizer.config.routePrefix}/init_user`);
102
102
  }
@@ -5,7 +5,10 @@ export function bindCors(adminizer) {
5
5
  const allowedOrigins = Array.isArray(corsConfig.origin)
6
6
  ? corsConfig.origin
7
7
  : [corsConfig.origin];
8
- adminizer.app.all(`${adminizer.config.routePrefix}/${corsConfig.path}`, (req, res, next) => {
8
+ adminizer.app.use(adminizer.config.routePrefix, (req, res, next) => {
9
+ if (!matchesCorsPath(req.path, corsConfig.path)) {
10
+ return next();
11
+ }
9
12
  const requestOrigin = req.headers.origin;
10
13
  // Checking if origin is allowed
11
14
  const isOriginAllowed = !requestOrigin || allowedOrigins.includes(requestOrigin);
@@ -39,3 +42,15 @@ export function bindCors(adminizer) {
39
42
  console.log('✅ API CORS middleware enabled. Allowed origins:', allowedOrigins);
40
43
  }
41
44
  }
45
+ function matchesCorsPath(requestPath, configuredPath = '') {
46
+ const normalizedRequestPath = requestPath.replace(/^\/+/, '');
47
+ const normalizedConfiguredPath = configuredPath.replace(/^\/+/, '');
48
+ if (!normalizedConfiguredPath || normalizedConfiguredPath === '*') {
49
+ return true;
50
+ }
51
+ if (!normalizedConfiguredPath.includes('*')) {
52
+ return normalizedRequestPath === normalizedConfiguredPath;
53
+ }
54
+ const prefix = normalizedConfiguredPath.slice(0, normalizedConfiguredPath.indexOf('*'));
55
+ return normalizedRequestPath.startsWith(prefix);
56
+ }
@@ -0,0 +1,2 @@
1
+ import { Adminizer } from "../lib/Adminizer";
2
+ export default function bindCustomFilterHandlers(adminizer: Adminizer): void;
@@ -0,0 +1,4 @@
1
+ import { CustomFilterHandler } from "../lib/filters/CustomFilterHandler.js";
2
+ export default function bindCustomFilterHandlers(adminizer) {
3
+ adminizer.customFilterHandler = new CustomFilterHandler();
4
+ }