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.
Files changed (59) hide show
  1. package/assets/{app-B3KHqZ_H.css → app-C4A2HUBD.css} +1 -1
  2. package/assets/app.js +2 -2
  3. package/assets/field-renderer-CvC9UdC0.js +1 -1
  4. package/assets/home-CmIZ3AL2.js +1 -1
  5. package/assets/login-Bg7ZQrZc.js +6 -0
  6. package/assets/manifest.json +2 -2
  7. package/controllers/add.d.ts +1 -1
  8. package/controllers/add.js +7 -17
  9. package/controllers/addGroup.js +1 -4
  10. package/controllers/addUser.js +1 -4
  11. package/controllers/catalog/Catalog.js +1 -1
  12. package/controllers/ckeditorUpload.js +1 -1
  13. package/controllers/dashboard.d.ts +1 -1
  14. package/controllers/dashboard.js +2 -4
  15. package/controllers/edit.js +7 -13
  16. package/controllers/editGroup.js +1 -3
  17. package/controllers/editUser.js +1 -3
  18. package/controllers/form.js +1 -2
  19. package/controllers/getAllWidgets.js +1 -1
  20. package/controllers/initUser.js +1 -1
  21. package/controllers/list.js +1 -1
  22. package/controllers/login.js +3 -4
  23. package/controllers/media-manager/mediaManagerApi.js +1 -1
  24. package/controllers/navigation/edit.js +1 -1
  25. package/controllers/processInstallFinalize.js +1 -1
  26. package/controllers/processInstallStep.js +1 -1
  27. package/controllers/register.js +1 -5
  28. package/controllers/remove.js +1 -4
  29. package/controllers/timezones.js +1 -1
  30. package/controllers/view.js +1 -6
  31. package/controllers/welcome.js +1 -1
  32. package/controllers/widgets/Action.js +1 -1
  33. package/controllers/widgets/Custom.js +1 -1
  34. package/controllers/widgets/Info.js +1 -1
  35. package/controllers/widgets/switch.js +1 -1
  36. package/controllers/widgetsDB.js +1 -1
  37. package/helpers/accessRightsHelper.js +1 -1
  38. package/helpers/inertiaAddHelper.d.ts +5 -5
  39. package/interfaces/adminpanelConfig.d.ts +6 -1
  40. package/lib/Adminizer.js +1 -5
  41. package/lib/controls/ControlsHandler.d.ts +1 -1
  42. package/lib/controls/ControlsHandler.js +1 -1
  43. package/lib/datatable/NodeTable.js +0 -42
  44. package/lib/inertia/inertiaAdapter.js +1 -1
  45. package/package.json +3 -3
  46. package/policies/checkAuth.js +1 -1
  47. package/system/Router.js +0 -2
  48. package/system/bindAuthorization.js +17 -2
  49. package/system/bindInertia.js +2 -2
  50. package/system/defaults.js +3 -0
  51. package/assets/login-B7INjWDi.js +0 -6
  52. package/controllers/listJson.d.ts +0 -1
  53. package/controllers/listJson.js +0 -35
  54. package/helpers/viewsHelper.d.ts +0 -44
  55. package/helpers/viewsHelper.js +0 -82
  56. package/system/bindResFunctions.d.ts +0 -2
  57. package/system/bindResFunctions.js +0 -52
  58. package/system/bindViewsLocals.d.ts +0 -2
  59. package/system/bindViewsLocals.js +0 -19
@@ -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" | "date" | "time" | "number" | "color" | "month" | "week" | "range" | "text" | "select" | "datetime-local";
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?: boolean;
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(routePrefix: string): string[];
9
+ collectAndGenerateStyleLinks(): string[];
10
10
  }
@@ -33,7 +33,7 @@ export class ControlsHandler {
33
33
  Array.from(group.values())
34
34
  ]));
35
35
  }
36
- collectAndGenerateStyleLinks(routePrefix) {
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).json({ message: 'Invalid CSRF token' });
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.a0ff2f0",
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": "ISC",
26
+ "license": "MIT",
27
27
  "description": "",
28
28
  "dependencies": {
29
29
  "@radix-ui/react-menubar": "^1.1.12",
@@ -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));
@@ -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(adminizer.config.routePrefix);
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
  }
@@ -107,6 +107,9 @@ var adminpanelConfig = {
107
107
  enable: false,
108
108
  defaultUserGroup: "guest",
109
109
  confirmationRequired: true
110
+ },
111
+ auth: {
112
+ enable: false
110
113
  }
111
114
  };
112
115
  export function setDefaultConfig(config) {
@@ -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>;
@@ -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
- ;
@@ -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
- }
@@ -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,2 +0,0 @@
1
- import { Adminizer } from "../lib/Adminizer";
2
- export default function bindResFunctions(adminizer: Adminizer): void;
@@ -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,2 +0,0 @@
1
- import { Adminizer } from "../lib/Adminizer";
2
- export default function bindViewsLocals(adminizer: Adminizer): void;
@@ -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
- }