@flowerforce/flowerbase 1.6.3-beta.6 → 1.7.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 1.7.0 (2026-02-04)
2
+
3
+
4
+ ### 🚀 Features
5
+
6
+ - setup monit page ([7638e37](https://github.com/flowerforce/flowerbase/commit/7638e37))
7
+
8
+
9
+ ### 🩹 Fixes
10
+
11
+ - monit separate css js html ([e62feea](https://github.com/flowerforce/flowerbase/commit/e62feea))
12
+
13
+ - error monit ([68b4a56](https://github.com/flowerforce/flowerbase/commit/68b4a56))
14
+
15
+ - monit edit code function ([e25ef2b](https://github.com/flowerforce/flowerbase/commit/e25ef2b))
16
+
1
17
  ## 1.6.2 (2026-01-30)
2
18
 
3
19
 
package/README.md CHANGED
@@ -15,7 +15,7 @@ Monitor Key capabilities:
15
15
  - Functions panel: list functions, view code (if allowed), invoke functions with custom args, and review recent invocation history.
16
16
  - Endpoints panel: list HTTP endpoints and invoke them with custom method, headers, query, and payload.
17
17
  - Users panel: search auth/custom users, create users, reset passwords, and enable/disable accounts.
18
- - Collections panel: list collections, inspect rules snapshot for a given user/system context, and run query/aggregate with pagination + history.
18
+ - Collections panel: list collections, inspect rules snapshot for a given user/system context, and run queries/aggregations with pagination + history.
19
19
 
20
20
  #### 🧠 Features Summary
21
21
  | Feature | Status |
@@ -1,3 +1,7 @@
1
+ export declare const PASSWORD_RULES: {
2
+ readonly minLength: 6;
3
+ readonly maxLength: 128;
4
+ };
1
5
  export declare const LOGIN_SCHEMA: {
2
6
  tags: string[];
3
7
  body: {
@@ -10,9 +14,9 @@ export declare const LOGIN_SCHEMA: {
10
14
  maxLength: number;
11
15
  };
12
16
  password: {
17
+ minLength: 6;
18
+ maxLength: 128;
13
19
  type: string;
14
- minLength: number;
15
- maxLength: number;
16
20
  };
17
21
  };
18
22
  required: string[];
@@ -45,9 +49,9 @@ export declare const RESET_CALL_SCHEMA: {
45
49
  maxLength: number;
46
50
  };
47
51
  password: {
52
+ minLength: 6;
53
+ maxLength: 128;
48
54
  type: string;
49
- minLength: number;
50
- maxLength: number;
51
55
  };
52
56
  arguments: {
53
57
  type: string;
@@ -62,9 +66,9 @@ export declare const CONFIRM_RESET_SCHEMA: {
62
66
  type: string;
63
67
  properties: {
64
68
  password: {
69
+ minLength: 6;
70
+ maxLength: 128;
65
71
  type: string;
66
- minLength: number;
67
- maxLength: number;
68
72
  };
69
73
  token: {
70
74
  type: string;
@@ -118,9 +122,9 @@ export declare const REGISTRATION_SCHEMA: {
118
122
  maxLength: number;
119
123
  };
120
124
  password: {
125
+ minLength: 6;
126
+ maxLength: 128;
121
127
  type: string;
122
- minLength: number;
123
- maxLength: number;
124
128
  };
125
129
  };
126
130
  required: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;CAexB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;CAc7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;CAgB7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;CAWhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;CAU/B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;CAe/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;IAC/B,iBAAiB,EAAE,cAAc,CAAA;IACjC,WAAW,CAAC,EAAE,QAAQ,CAAA;CACvB;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B,EAAE,MAAM,CAAA;CACvC;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAuCjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAarC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc;;;CAA4C,CAAC;AACxE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;CAexB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;CAc7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;CAgB7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;CAWhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;CAU/B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;CAe/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;IAC/B,iBAAiB,EAAE,cAAc,CAAA;IACjC,WAAW,CAAC,EAAE,QAAQ,CAAA;CACvB;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B,EAAE,MAAM,CAAA;CACvC;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAuCjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAarC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generatePassword = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.RESET_SCHEMA = exports.CONFIRM_USER_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_CALL_SCHEMA = exports.RESET_SEND_SCHEMA = exports.LOGIN_SCHEMA = void 0;
6
+ exports.generatePassword = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.RESET_SCHEMA = exports.CONFIRM_USER_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_CALL_SCHEMA = exports.RESET_SEND_SCHEMA = exports.LOGIN_SCHEMA = exports.PASSWORD_RULES = void 0;
7
7
  const crypto_1 = __importDefault(require("crypto"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]{};:,.<>?";
11
+ exports.PASSWORD_RULES = { minLength: 6, maxLength: 128 };
11
12
  exports.LOGIN_SCHEMA = {
12
13
  tags: ['Auth'],
13
14
  body: {
@@ -19,7 +20,7 @@ exports.LOGIN_SCHEMA = {
19
20
  minLength: 5,
20
21
  maxLength: 254
21
22
  },
22
- password: { type: 'string', minLength: 6, maxLength: 128 }
23
+ password: Object.assign({ type: 'string' }, exports.PASSWORD_RULES)
23
24
  },
24
25
  required: ['username', 'password']
25
26
  }
@@ -50,7 +51,7 @@ exports.RESET_CALL_SCHEMA = {
50
51
  minLength: 5,
51
52
  maxLength: 254
52
53
  },
53
- password: { type: 'string', minLength: 6, maxLength: 128 },
54
+ password: Object.assign({ type: 'string' }, exports.PASSWORD_RULES),
54
55
  arguments: { type: 'array' }
55
56
  },
56
57
  required: ['email', 'password']
@@ -61,7 +62,7 @@ exports.CONFIRM_RESET_SCHEMA = {
61
62
  body: {
62
63
  type: 'object',
63
64
  properties: {
64
- password: { type: 'string', minLength: 6, maxLength: 128 },
65
+ password: Object.assign({ type: 'string' }, exports.PASSWORD_RULES),
65
66
  token: { type: 'string' },
66
67
  tokenId: { type: 'string' }
67
68
  },
@@ -91,7 +92,7 @@ exports.REGISTRATION_SCHEMA = {
91
92
  minLength: 5,
92
93
  maxLength: 254
93
94
  },
94
- password: { type: 'string', minLength: 6, maxLength: 128 }
95
+ password: Object.assign({ type: 'string' }, exports.PASSWORD_RULES)
95
96
  },
96
97
  required: ['email', 'password']
97
98
  }
@@ -1 +1 @@
1
- {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/monitoring/routes/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAK9C,OAAO,EAAiB,mBAAmB,EAAmB,YAAY,EAAgC,MAAM,UAAU,CAAA;AAE1H,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,OAAO,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,kBAAkB,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACxD,eAAe,EAAE,mBAAmB,EAAE,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,KAAK,eAAe,EAAE,MAAM,kBAAkB,SAyJpF,CAAA"}
1
+ {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/monitoring/routes/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAK9C,OAAO,EAAiB,mBAAmB,EAAmB,YAAY,EAAgC,MAAM,UAAU,CAAA;AAE1H,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,OAAO,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,kBAAkB,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACxD,eAAe,EAAE,mBAAmB,EAAE,CAAA;CACvC,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,KAAK,eAAe,EAAE,MAAM,kBAAkB,SA8JpF,CAAA"}
@@ -144,7 +144,12 @@ const registerFunctionRoutes = (app, deps) => {
144
144
  type: 'error',
145
145
  source: 'monit',
146
146
  message: `invoke ${name} failed`,
147
- data: (0, utils_1.sanitize)({ error })
147
+ data: (0, utils_1.sanitize)({
148
+ error,
149
+ user: userInfo,
150
+ invokedFrom: name,
151
+ runAsSystem: effectiveRunAsSystem
152
+ })
148
153
  });
149
154
  reply.code(500);
150
155
  const details = (0, utils_1.getErrorDetails)(error);
@@ -1 +1 @@
1
- {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../src/monitoring/routes/users.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAM9C,OAAO,EAAiB,YAAY,EAAY,MAAM,UAAU,CAAA;AAEhE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CACxC,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,KAAK,eAAe,EAAE,MAAM,cAAc,SAkO5E,CAAA"}
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../src/monitoring/routes/users.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAO9C,OAAO,EAAiB,YAAY,EAAY,MAAM,UAAU,CAAA;AAEhE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CACxC,CAAA;AAYD,eAAO,MAAM,kBAAkB,GAAI,KAAK,eAAe,EAAE,MAAM,cAAc,SAoP5E,CAAA"}
@@ -14,11 +14,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.registerUserRoutes = void 0;
16
16
  const mongodb_1 = require("mongodb");
17
+ const utils_1 = require("../../auth/utils");
17
18
  const constants_1 = require("../../constants");
18
19
  const handleUserRegistration_1 = __importDefault(require("../../shared/handleUserRegistration"));
19
20
  const handleUserRegistration_model_1 = require("../../shared/models/handleUserRegistration.model");
20
21
  const crypto_1 = require("../../utils/crypto");
21
- const utils_1 = require("../utils");
22
+ const utils_2 = require("../utils");
23
+ const validatePassword = (password) => {
24
+ if (password.length < utils_1.PASSWORD_RULES.minLength) {
25
+ return `Password must be at least ${utils_1.PASSWORD_RULES.minLength} characters`;
26
+ }
27
+ if (password.length > utils_1.PASSWORD_RULES.maxLength) {
28
+ return `Password must be at most ${utils_1.PASSWORD_RULES.maxLength} characters`;
29
+ }
30
+ return '';
31
+ };
22
32
  const registerUserRoutes = (app, deps) => {
23
33
  const { prefix, addEvent } = deps;
24
34
  app.get(`${prefix}/api/users`, (req) => __awaiter(void 0, void 0, void 0, function* () {
@@ -64,7 +74,7 @@ const registerUserRoutes = (app, deps) => {
64
74
  .toArray();
65
75
  response.auth = {
66
76
  collection: authCollection,
67
- items: authItems.map((doc) => (0, utils_1.sanitize)(doc))
77
+ items: authItems.map((doc) => (0, utils_2.sanitize)(doc))
68
78
  };
69
79
  }
70
80
  if ((scope === 'all' || scope === 'custom') && userCollection) {
@@ -93,7 +103,7 @@ const registerUserRoutes = (app, deps) => {
93
103
  .toArray();
94
104
  response.custom = {
95
105
  collection: userCollection,
96
- items: customItems.map((doc) => (0, utils_1.sanitize)(doc)),
106
+ items: customItems.map((doc) => (0, utils_2.sanitize)(doc)),
97
107
  pagination: {
98
108
  page,
99
109
  pages: totalPages,
@@ -104,6 +114,13 @@ const registerUserRoutes = (app, deps) => {
104
114
  }
105
115
  return response;
106
116
  }));
117
+ app.get(`${prefix}/api/users/config`, () => __awaiter(void 0, void 0, void 0, function* () {
118
+ return {
119
+ providers: (0, utils_1.loadAuthConfig)(),
120
+ customUserData: (0, utils_1.loadCustomUserData)(),
121
+ passwordRules: utils_1.PASSWORD_RULES
122
+ };
123
+ }));
107
124
  app.post(`${prefix}/api/users`, (req, reply) => __awaiter(void 0, void 0, void 0, function* () {
108
125
  var _a, _b, _c;
109
126
  const body = req.body;
@@ -113,6 +130,11 @@ const registerUserRoutes = (app, deps) => {
113
130
  reply.code(400);
114
131
  return { error: 'Missing email or password' };
115
132
  }
133
+ const passwordError = validatePassword(password);
134
+ if (passwordError) {
135
+ reply.code(400);
136
+ return { error: passwordError };
137
+ }
116
138
  const result = yield (0, handleUserRegistration_1.default)(app, {
117
139
  run_as_system: true,
118
140
  provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS
@@ -126,12 +148,12 @@ const registerUserRoutes = (app, deps) => {
126
148
  }, { upsert: true });
127
149
  }
128
150
  addEvent({
129
- id: (0, utils_1.createEventId)(),
151
+ id: (0, utils_2.createEventId)(),
130
152
  ts: Date.now(),
131
153
  type: 'auth',
132
154
  source: 'monit',
133
155
  message: 'user created',
134
- data: (0, utils_1.sanitize)({ email, userId })
156
+ data: (0, utils_2.sanitize)({ email, userId })
135
157
  });
136
158
  reply.code(201);
137
159
  return { userId };
@@ -145,6 +167,11 @@ const registerUserRoutes = (app, deps) => {
145
167
  reply.code(400);
146
168
  return { error: 'Missing password' };
147
169
  }
170
+ const passwordError = validatePassword(password);
171
+ if (passwordError) {
172
+ reply.code(400);
173
+ return { error: passwordError };
174
+ }
148
175
  const db = app.mongo.client.db(constants_1.DB_NAME);
149
176
  const authCollection = (_a = constants_1.AUTH_CONFIG.authCollection) !== null && _a !== void 0 ? _a : 'auth_users';
150
177
  const selector = {};
@@ -167,12 +194,12 @@ const registerUserRoutes = (app, deps) => {
167
194
  return { error: 'User not found' };
168
195
  }
169
196
  addEvent({
170
- id: (0, utils_1.createEventId)(),
197
+ id: (0, utils_2.createEventId)(),
171
198
  ts: Date.now(),
172
199
  type: 'auth',
173
200
  source: 'monit',
174
201
  message: 'password updated',
175
- data: (0, utils_1.sanitize)({ selector })
202
+ data: (0, utils_2.sanitize)({ selector })
176
203
  });
177
204
  return { status: 'ok' };
178
205
  }));
@@ -204,12 +231,12 @@ const registerUserRoutes = (app, deps) => {
204
231
  return { error: 'User not found' };
205
232
  }
206
233
  addEvent({
207
- id: (0, utils_1.createEventId)(),
234
+ id: (0, utils_2.createEventId)(),
208
235
  ts: Date.now(),
209
236
  type: 'auth',
210
237
  source: 'monit',
211
238
  message: `user status ${status}`,
212
- data: (0, utils_1.sanitize)({ selector, status })
239
+ data: (0, utils_2.sanitize)({ selector, status })
213
240
  });
214
241
  return { status: 'ok' };
215
242
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAs8BrF,QAAA,MAAM,YAAY,EAAE,oBAuBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;AA0+BrF,QAAA,MAAM,YAAY,EAAE,oBAuBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
@@ -15,9 +15,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const get_1 = __importDefault(require("lodash/get"));
16
16
  const isEqual_1 = __importDefault(require("lodash/isEqual"));
17
17
  const utils_1 = require("../../monitoring/utils");
18
- const monitoring_1 = require("../monitoring");
19
18
  const machines_1 = require("../../utils/roles/machines");
20
19
  const utils_2 = require("../../utils/roles/machines/utils");
20
+ const monitoring_1 = require("../monitoring");
21
21
  const model_1 = require("./model");
22
22
  const utils_3 = require("./utils");
23
23
  //TODO aggiungere no-sql inject security
@@ -80,11 +80,12 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
80
80
  collection: collName
81
81
  });
82
82
  const emitMongoEvent = (operation, meta, error) => {
83
+ const userId = getUserId(user);
83
84
  (0, monitoring_1.emitServiceEvent)({
84
85
  type: 'mongo',
85
86
  source: 'service:mongodb-atlas',
86
87
  message: error ? `mongo ${operation} failed` : `mongo ${operation}`,
87
- data: Object.assign({ operation, collection: collName, runAsSystem: !!run_as_system, rules: rulesMeta }, (meta !== null && meta !== void 0 ? meta : {})),
88
+ data: Object.assign(Object.assign(Object.assign({ operation, collection: collName, runAsSystem: !!run_as_system }, (userId ? { userId } : {})), { rules: rulesMeta }), (meta !== null && meta !== void 0 ? meta : {})),
88
89
  error,
89
90
  origin: monitoringOrigin
90
91
  });
@@ -109,7 +110,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
109
110
  */
110
111
  findOne: (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (query = {}, projection, options) {
111
112
  var _a;
112
- emitMongoEvent('findOne');
113
113
  try {
114
114
  const resolvedOptions = projection || options
115
115
  ? Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), (projection ? { projection } : {})) : undefined;
@@ -153,10 +153,14 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
153
153
  }, user)
154
154
  : fallbackAccess(result);
155
155
  // Return validated document or empty object if not permitted
156
- return Promise.resolve(status ? document : {});
156
+ const response = status ? document : {};
157
+ emitMongoEvent('findOne');
158
+ return Promise.resolve(response);
157
159
  }
158
160
  // System mode: no validation applied
159
- return collection.findOne(resolvedQuery, resolvedOptions);
161
+ const response = yield collection.findOne(resolvedQuery, resolvedOptions);
162
+ emitMongoEvent('findOne');
163
+ return response;
160
164
  }
161
165
  catch (error) {
162
166
  emitMongoEvent('findOne', undefined, error);
@@ -183,7 +187,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
183
187
  */
184
188
  deleteOne: (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (query = {}, options) {
185
189
  var _a;
186
- emitMongoEvent('deleteOne');
187
190
  try {
188
191
  if (!run_as_system) {
189
192
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.DELETE);
@@ -208,10 +211,14 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
208
211
  if (!status) {
209
212
  throw new Error('Delete not permitted');
210
213
  }
211
- return collection.deleteOne({ $and: formattedQuery }, options);
214
+ const res = yield collection.deleteOne({ $and: formattedQuery }, options);
215
+ emitMongoEvent('deleteOne');
216
+ return res;
212
217
  }
213
218
  // System mode: bypass access control
214
- return collection.deleteOne(query, options);
219
+ const result = yield collection.deleteOne(query, options);
220
+ emitMongoEvent('deleteOne');
221
+ return result;
215
222
  }
216
223
  catch (error) {
217
224
  emitMongoEvent('deleteOne', undefined, error);
@@ -238,7 +245,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
238
245
  * This ensures that only users with the correct permissions can insert data into the collection.
239
246
  */
240
247
  insertOne: (data, options) => __awaiter(void 0, void 0, void 0, function* () {
241
- emitMongoEvent('insertOne');
242
248
  try {
243
249
  if (!run_as_system) {
244
250
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.CREATE);
@@ -261,10 +267,13 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
261
267
  insertedId: insertResult.insertedId.toString(),
262
268
  document: data
263
269
  });
270
+ emitMongoEvent('insertOne');
264
271
  return insertResult;
265
272
  }
266
273
  // System mode: insert without validation
267
- return collection.insertOne(data, options);
274
+ const insertResult = yield collection.insertOne(data, options);
275
+ emitMongoEvent('insertOne');
276
+ return insertResult;
268
277
  }
269
278
  catch (error) {
270
279
  emitMongoEvent('insertOne', undefined, error);
@@ -293,7 +302,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
293
302
  * - If validation fails, throws an error; otherwise, updates the document.
294
303
  */
295
304
  updateOne: (query, data, options) => __awaiter(void 0, void 0, void 0, function* () {
296
- emitMongoEvent('updateOne');
297
305
  try {
298
306
  if (!run_as_system) {
299
307
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.UPDATE);
@@ -341,9 +349,13 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
341
349
  if (!status || !areDocumentsEqual) {
342
350
  throw new Error('Update not permitted');
343
351
  }
344
- return collection.updateOne({ $and: safeQuery }, data, options);
352
+ const res = yield collection.updateOne({ $and: safeQuery }, data, options);
353
+ emitMongoEvent('updateOne');
354
+ return res;
345
355
  }
346
- return collection.updateOne(query, data, options);
356
+ const result = yield collection.updateOne(query, data, options);
357
+ emitMongoEvent('updateOne');
358
+ return result;
347
359
  }
348
360
  catch (error) {
349
361
  emitMongoEvent('updateOne', undefined, error);
@@ -362,7 +374,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
362
374
  */
363
375
  findOneAndUpdate: (query, data, options) => __awaiter(void 0, void 0, void 0, function* () {
364
376
  var _a;
365
- emitMongoEvent('findOneAndUpdate');
366
377
  try {
367
378
  if (!run_as_system) {
368
379
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.UPDATE);
@@ -405,6 +416,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
405
416
  ? yield collection.findOneAndUpdate({ $and: safeQuery }, data, options)
406
417
  : yield collection.findOneAndUpdate({ $and: safeQuery }, data);
407
418
  if (!updateResult) {
419
+ emitMongoEvent('findOneAndUpdate');
408
420
  return updateResult;
409
421
  }
410
422
  const readRole = (0, utils_2.getWinningRole)(updateResult, user, roles);
@@ -417,11 +429,14 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
417
429
  }, user)
418
430
  : fallbackAccess(updateResult);
419
431
  const sanitizedDoc = readResult.status ? ((_a = readResult.document) !== null && _a !== void 0 ? _a : updateResult) : {};
432
+ emitMongoEvent('findOneAndUpdate');
420
433
  return sanitizedDoc;
421
434
  }
422
- return options
423
- ? collection.findOneAndUpdate(query, data, options)
424
- : collection.findOneAndUpdate(query, data);
435
+ const updateResult = options
436
+ ? yield collection.findOneAndUpdate(query, data, options)
437
+ : yield collection.findOneAndUpdate(query, data);
438
+ emitMongoEvent('findOneAndUpdate');
439
+ return updateResult;
425
440
  }
426
441
  catch (error) {
427
442
  emitMongoEvent('findOneAndUpdate', undefined, error);
@@ -449,7 +464,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
449
464
  * This ensures that both pre-query filtering and post-query validation are applied consistently.
450
465
  */
451
466
  find: (query = {}, projection, options) => {
452
- emitMongoEvent('find');
453
467
  try {
454
468
  const resolvedOptions = projection || options
455
469
  ? Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), (projection ? { projection } : {})) : undefined;
@@ -489,33 +503,39 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
489
503
  })));
490
504
  return filteredResponse.filter(Boolean);
491
505
  });
506
+ emitMongoEvent('find');
492
507
  return cursor;
493
508
  }
494
509
  // System mode: return original unfiltered cursor
495
- return collection.find(query, resolvedOptions);
510
+ const cursor = collection.find(query, resolvedOptions);
511
+ emitMongoEvent('find');
512
+ return cursor;
496
513
  }
497
514
  catch (error) {
498
515
  emitMongoEvent('find', undefined, error);
499
516
  throw error;
500
517
  }
501
518
  },
502
- count: (query, options) => {
503
- emitMongoEvent('count');
519
+ count: (query, options) => __awaiter(void 0, void 0, void 0, function* () {
504
520
  try {
505
521
  if (!run_as_system) {
506
522
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.READ);
507
523
  const formattedQuery = (0, utils_3.getFormattedQuery)(filters, query, user);
508
524
  const currentQuery = formattedQuery.length ? { $and: formattedQuery } : {};
509
525
  logService('count query', { collName, currentQuery });
510
- return collection.countDocuments(currentQuery, options);
526
+ const result = yield collection.countDocuments(currentQuery, options);
527
+ emitMongoEvent('count');
528
+ return result;
511
529
  }
512
- return collection.countDocuments(query, options);
530
+ const result = yield collection.countDocuments(query, options);
531
+ emitMongoEvent('count');
532
+ return result;
513
533
  }
514
534
  catch (error) {
515
535
  emitMongoEvent('count', undefined, error);
516
536
  throw error;
517
537
  }
518
- },
538
+ }),
519
539
  /**
520
540
  * Watches changes on a MongoDB collection with optional role-based filtering of change events.
521
541
  *
@@ -536,7 +556,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
536
556
  * This allows fine-grained control over what change events a user can observe, based on roles and filters.
537
557
  */
538
558
  watch: (pipeline = [], options) => {
539
- emitMongoEvent('watch');
540
559
  try {
541
560
  if (!run_as_system) {
542
561
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.READ);
@@ -589,10 +608,13 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
589
608
  listener(filteredChange);
590
609
  }));
591
610
  };
611
+ emitMongoEvent('watch');
592
612
  return result;
593
613
  }
594
614
  // System mode: no filtering applied
595
- return collection.watch(pipeline, options);
615
+ const result = collection.watch(pipeline, options);
616
+ emitMongoEvent('watch');
617
+ return result;
596
618
  }
597
619
  catch (error) {
598
620
  emitMongoEvent('watch', undefined, error);
@@ -601,10 +623,11 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
601
623
  },
602
624
  //TODO -> add filter & rules in aggregate
603
625
  aggregate: (pipeline = [], options, isClient) => {
604
- emitMongoEvent('aggregate');
605
626
  try {
606
627
  if (run_as_system || !isClient) {
607
- return collection.aggregate(pipeline, options);
628
+ const cursor = collection.aggregate(pipeline, options);
629
+ emitMongoEvent('aggregate');
630
+ return cursor;
608
631
  }
609
632
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.READ);
610
633
  const rulesConfig = collectionRules !== null && collectionRules !== void 0 ? collectionRules : { filters, roles };
@@ -631,6 +654,7 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
631
654
  const originalCursor = collection.aggregate(guardedPipeline, options);
632
655
  const newCursor = Object.create(originalCursor);
633
656
  newCursor.toArray = () => __awaiter(void 0, void 0, void 0, function* () { return originalCursor.toArray(); });
657
+ emitMongoEvent('aggregate');
634
658
  return newCursor;
635
659
  }
636
660
  catch (error) {
@@ -656,7 +680,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
656
680
  * Only documents passing validation will be inserted.
657
681
  */
658
682
  insertMany: (documents, options) => __awaiter(void 0, void 0, void 0, function* () {
659
- emitMongoEvent('insertMany');
660
683
  try {
661
684
  if (!run_as_system) {
662
685
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.CREATE);
@@ -677,10 +700,14 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
677
700
  if (!canInsert) {
678
701
  throw new Error('Insert not permitted');
679
702
  }
680
- return collection.insertMany(documents, options);
703
+ const result = yield collection.insertMany(documents, options);
704
+ emitMongoEvent('insertMany');
705
+ return result;
681
706
  }
682
707
  // If system mode is active, insert all documents without validation
683
- return collection.insertMany(documents, options);
708
+ const result = yield collection.insertMany(documents, options);
709
+ emitMongoEvent('insertMany');
710
+ return result;
684
711
  }
685
712
  catch (error) {
686
713
  emitMongoEvent('insertMany', undefined, error);
@@ -688,7 +715,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
688
715
  }
689
716
  }),
690
717
  updateMany: (query, data, options) => __awaiter(void 0, void 0, void 0, function* () {
691
- emitMongoEvent('updateMany');
692
718
  try {
693
719
  if (!run_as_system) {
694
720
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.UPDATE);
@@ -734,9 +760,13 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
734
760
  console.log('check1 In updateMany --> (!areDocumentsEqual)');
735
761
  throw new Error('Update not permitted');
736
762
  }
737
- return collection.updateMany({ $and: formattedQuery }, data, options);
763
+ const res = yield collection.updateMany({ $and: formattedQuery }, data, options);
764
+ emitMongoEvent('updateMany');
765
+ return res;
738
766
  }
739
- return collection.updateMany(query, data, options);
767
+ const result = yield collection.updateMany(query, data, options);
768
+ emitMongoEvent('updateMany');
769
+ return result;
740
770
  }
741
771
  catch (error) {
742
772
  emitMongoEvent('updateMany', undefined, error);
@@ -759,7 +789,6 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
759
789
  * - Deletes only the documents that the current user has permission to delete.
760
790
  */
761
791
  deleteMany: (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (query = {}, options) {
762
- emitMongoEvent('deleteMany');
763
792
  try {
764
793
  if (!run_as_system) {
765
794
  (0, utils_3.checkDenyOperation)(normalizedRules, collection.collectionName, model_1.CRUD_OPERATIONS.DELETE);
@@ -783,19 +812,25 @@ const getOperators = (collection, { rules, collName, user, run_as_system, monito
783
812
  // Extract IDs of documents that passed validation
784
813
  const elementsToDelete = filteredItems.filter(Boolean).map(({ _id }) => _id);
785
814
  if (!elementsToDelete.length) {
786
- return Promise.resolve({
815
+ const result = {
787
816
  acknowledged: true,
788
817
  deletedCount: 0
789
- });
818
+ };
819
+ emitMongoEvent('deleteMany');
820
+ return Promise.resolve(result);
790
821
  }
791
822
  // Build final delete query with access control and ID filter
792
823
  const deleteQuery = {
793
824
  $and: [...formattedQuery, { _id: { $in: elementsToDelete } }]
794
825
  };
795
- return collection.deleteMany(deleteQuery, options);
826
+ const result = yield collection.deleteMany(deleteQuery, options);
827
+ emitMongoEvent('deleteMany');
828
+ return result;
796
829
  }
797
830
  // If running as system, bypass access control and delete directly
798
- return collection.deleteMany(query, options);
831
+ const result = yield collection.deleteMany(query, options);
832
+ emitMongoEvent('deleteMany');
833
+ return result;
799
834
  }
800
835
  catch (error) {
801
836
  emitMongoEvent('deleteMany', undefined, error);