data-primals-engine 1.5.2 → 1.6.1

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 (70) hide show
  1. package/README.md +938 -915
  2. package/client/README.md +136 -136
  3. package/client/index.js +0 -1
  4. package/client/public/doc/API.postman_collection.json +213 -213
  5. package/client/public/react.svg +9 -9
  6. package/client/src/AddWidgetTypeModal.jsx +47 -47
  7. package/client/src/App.css +42 -42
  8. package/client/src/App.jsx +92 -150
  9. package/client/src/App.scss +6 -0
  10. package/client/src/AssistantChat.jsx +362 -363
  11. package/client/src/Button.jsx +12 -12
  12. package/client/src/Dashboard.jsx +480 -480
  13. package/client/src/DashboardHtmlViewItem.jsx +146 -146
  14. package/client/src/DashboardView.jsx +654 -654
  15. package/client/src/DataEditor.jsx +383 -383
  16. package/client/src/DataLayout.jsx +779 -808
  17. package/client/src/DataTable.jsx +782 -822
  18. package/client/src/DataTable.scss +186 -186
  19. package/client/src/GeolocationField.jsx +93 -93
  20. package/client/src/HistoryDialog.jsx +307 -307
  21. package/client/src/HistoryDialog.scss +319 -319
  22. package/client/src/HtmlViewBuilderModal.jsx +90 -90
  23. package/client/src/HtmlViewBuilderModal.scss +17 -17
  24. package/client/src/HtmlViewCard.jsx +43 -43
  25. package/client/src/ModelCreator.jsx +683 -686
  26. package/client/src/ModelCreator.scss +1 -1
  27. package/client/src/ModelCreatorField.jsx +950 -950
  28. package/client/src/ModelImporter.jsx +3 -0
  29. package/client/src/ModelList.jsx +280 -280
  30. package/client/src/Notification.jsx +136 -136
  31. package/client/src/PackGallery.jsx +391 -391
  32. package/client/src/PackGallery.scss +231 -231
  33. package/client/src/Pagination.jsx +143 -143
  34. package/client/src/RelationField.jsx +354 -354
  35. package/client/src/RelationSelectorWidget.jsx +172 -172
  36. package/client/src/RelationValue.jsx +2 -1
  37. package/client/src/contexts/CommandContext.jsx +260 -0
  38. package/client/src/contexts/ModelContext.jsx +4 -1
  39. package/client/src/contexts/UIContext.jsx +72 -72
  40. package/client/src/filter.js +263 -263
  41. package/client/src/index.css +90 -90
  42. package/package.json +6 -5
  43. package/perf/artillery-hooks.js +37 -37
  44. package/perf/setup.yml +25 -25
  45. package/src/constants.js +4 -0
  46. package/src/defaultModels.js +7 -0
  47. package/src/engine.js +335 -335
  48. package/src/events.js +232 -137
  49. package/src/filter.js +274 -274
  50. package/src/index.js +1 -0
  51. package/src/modules/assistant/assistant.js +225 -83
  52. package/src/modules/auth-google/index.js +50 -50
  53. package/src/modules/auth-microsoft/index.js +81 -81
  54. package/src/modules/data/data.core.js +118 -118
  55. package/src/modules/data/data.history.js +555 -555
  56. package/src/modules/data/data.operations.js +112 -9
  57. package/src/modules/data/data.relations.js +686 -686
  58. package/src/modules/data/data.routes.js +1879 -1879
  59. package/src/modules/data/data.validation.js +2 -2
  60. package/src/modules/file.js +247 -247
  61. package/src/modules/user.js +14 -9
  62. package/src/packs.js +2 -2
  63. package/src/providers.js +2 -2
  64. package/src/services/stripe.js +196 -196
  65. package/src/sso.js +193 -193
  66. package/test/data.history.integration.test.js +264 -264
  67. package/test/data.integration.test.js +1281 -1206
  68. package/test/events.test.js +108 -10
  69. package/test/model.integration.test.js +377 -377
  70. package/test/user.test.js +106 -1
package/test/user.test.js CHANGED
@@ -1,4 +1,4 @@
1
- import { expect, describe, it, beforeEach, beforeAll, afterAll } from 'vitest';
1
+ import { expect, describe, it, afterEach, beforeAll, afterAll } from 'vitest';
2
2
  import { hasPermission, getUserActivePermissions } from '../src/modules/user.js';
3
3
  import {initEngine} from "../src/setenv";
4
4
  import {generateUniqueName} from "../src/setenv.js";
@@ -207,4 +207,109 @@ describe('User Permission Logic', () => {
207
207
  await coll.drop();
208
208
  });
209
209
  });
210
+
211
+ describe('hasPermission() with environment context', () => {
212
+ let user, coll;
213
+ let permRead, permWrite;
214
+ let envProdId, envStagingId;
215
+
216
+ beforeAll(async () => {
217
+ // --- Setup ---
218
+ coll = await setupTestContext();
219
+ user = currentTestUser; // Récupère l'utilisateur du contexte
220
+
221
+ // 1. Créer les permissions
222
+ const perms = await coll.insertMany([
223
+ { _model: 'permission', name: 'env:read', _user: user.username },
224
+ { _model: 'permission', name: 'env:write', _user: user.username }
225
+ ]);
226
+ permRead = perms.insertedIds[0];
227
+ permWrite = perms.insertedIds[1];
228
+
229
+ // 2. Créer les environnements
230
+ const envs = await coll.insertMany([
231
+ { _model: 'env', name: 'prod', _user: user.username },
232
+ { _model: 'env', name: 'staging', _user: user.username }
233
+ ]);
234
+ envProdId = envs.insertedIds[0].toString();
235
+ envStagingId = envs.insertedIds[1].toString();
236
+
237
+ // 3. Créer un rôle de base et l'assigner à l'utilisateur
238
+ const role = await coll.insertOne({
239
+ _model: 'role',
240
+ name: 'EnvTester',
241
+ permissions: [permRead.toString()],
242
+ _user: user.username
243
+ });
244
+ await coll.updateOne(
245
+ { _id: user._id },
246
+ { $set: { roles: [role.insertedId.toString()] } }
247
+ );
248
+ // Mettre à jour l'objet utilisateur en mémoire
249
+ user.roles = [role.insertedId.toString()];
250
+ user.permissions = ['env:read'];
251
+ });
252
+
253
+ afterAll(async () => {
254
+ await coll.drop();
255
+ });
256
+
257
+ afterEach(async () => {
258
+ // Nettoyer les exceptions de permission après chaque test
259
+ await coll.deleteMany({ _model: 'userPermission', user: user._id });
260
+ });
261
+
262
+ it('should grant permission if exception is global (no env)', async () => {
263
+ await coll.insertOne({
264
+ _model: 'userPermission', user: user._id, permission: permWrite, isGranted: true
265
+ });
266
+ // L'utilisateur doit avoir la permission dans n'importe quel environnement
267
+ expect(await hasPermission(['env:write'], user, envProdId)).toBe(true);
268
+ expect(await hasPermission(['env:write'], user, envStagingId)).toBe(true);
269
+ expect(await hasPermission(['env:write'], user, null)).toBe(true); // Environnement par défaut
270
+ });
271
+
272
+ it('should grant permission only in the specified environment', async () => {
273
+ await coll.insertOne({
274
+ _model: 'userPermission', user: user._id, permission: permWrite, isGranted: true, env: envProdId
275
+ });
276
+ // L'utilisateur ne doit avoir la permission qu'en 'prod'
277
+ expect(await hasPermission(['env:write'], user, envProdId)).toBe(true);
278
+ expect(await hasPermission(['env:write'], user, envStagingId)).toBe(false);
279
+ expect(await hasPermission(['env:write'], user, null)).toBe(false);
280
+ });
281
+
282
+ it('should revoke a base permission globally if exception has no env', async () => {
283
+ await coll.insertOne({
284
+ _model: 'userPermission', user: user._id, permission: permRead, isGranted: false
285
+ });
286
+ // La permission de lecture (du rôle) doit être révoquée partout
287
+ expect(await hasPermission(['env:read'], user, envProdId)).toBe(false);
288
+ expect(await hasPermission(['env:read'], user, envStagingId)).toBe(false);
289
+ expect(await hasPermission(['env:read'], user, null)).toBe(false);
290
+ });
291
+
292
+ it('should revoke a base permission only in the specified environment', async () => {
293
+ await coll.insertOne({
294
+ _model: 'userPermission', user: user._id, permission: permRead, isGranted: false, env: envStagingId
295
+ });
296
+ // La permission de lecture ne doit être révoquée qu'en 'staging'
297
+ expect(await hasPermission(['env:read'], user, envProdId)).toBe(true);
298
+ expect(await hasPermission(['env:read'], user, envStagingId)).toBe(false);
299
+ expect(await hasPermission(['env:read'], user, null)).toBe(true);
300
+ });
301
+
302
+ it('should prioritize specific env revocation over a global grant', async () => {
303
+ await coll.insertMany([
304
+ // On accorde 'env:write' partout
305
+ { _model: 'userPermission', user: user._id, permission: permWrite, isGranted: true },
306
+ // Mais on le révoque spécifiquement pour 'staging'
307
+ { _model: 'userPermission', user: user._id, permission: permWrite, isGranted: false, env: envStagingId }
308
+ ]);
309
+
310
+ expect(await hasPermission(['env:write'], user, envProdId)).toBe(true);
311
+ expect(await hasPermission(['env:write'], user, envStagingId)).toBe(false);
312
+ expect(await hasPermission(['env:write'], user, null)).toBe(true);
313
+ });
314
+ });
210
315
  });