data-primals-engine 1.0.2-s → 1.0.4

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/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "data-primals-engine",
3
- "version": "1.0.2s",
4
-
3
+ "version": "1.0.4",
5
4
  "description": "data-primals-engine is the package responsible from handling large amount of data in a practical and performant way. It can handle large amount of data in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation.",
6
5
  "main": "src/engine.js",
7
6
  "type": "module",
8
7
  "scripts": {
8
+ "preinstall": "npx force-resolutions",
9
9
  "devserver": "cross-env NODE_ENV=development node server.js",
10
10
  "server": "cross-env NODE_ENV=production node server.js",
11
11
  "migrate:create": "node src/migrate.js create",
@@ -14,6 +14,11 @@
14
14
  "migrate:revert": "node src/migrate.js revert",
15
15
  "migrate:status": "node src/migrate.js status"
16
16
  },
17
+ "resolutions": {
18
+ "tar-fs": "3.0.9",
19
+ "on-headers": "1.1.0",
20
+ "brace-expansion": "2.0.2"
21
+ },
17
22
  "repository": {
18
23
  "type": "git",
19
24
  "url": "https://github.com/anonympins/data-primals-engine.git"
@@ -34,11 +39,14 @@
34
39
  "check-disk-space": "^3.4.0",
35
40
  "compression": "^1.8.0",
36
41
  "connect-mongo": "^5.1.0",
42
+ "connect-multiparty": "^2.2.0",
37
43
  "cookie-parser": "^1.4.7",
44
+ "cronstrue": "^3.1.0",
38
45
  "csv-parse": "^5.6.0",
39
46
  "csv-parser": "^3.2.0",
40
47
  "express": "^4.21.2",
41
48
  "express-csrf-double-submit-cookie": "^1.2.1",
49
+ "express-rate-limit": "^8.0.1",
42
50
  "express-session": "^1.18.1",
43
51
  "express-sitemap-xml": "^3.1.0",
44
52
  "juice": "^11.0.1",
@@ -46,13 +54,27 @@
46
54
  "mongodb": "^6.12.0",
47
55
  "node-schedule": "^2.1.1",
48
56
  "nodemailer": "^6.10.0",
57
+ "randomcolor": "^0.6.2",
49
58
  "rate-limiter-flexible": "^5.0.5",
50
- "swagger-ui-express": "^5.0.1",
59
+ "request-ip": "^3.3.0",
60
+ "sanitize-html": "^2.17.0",
51
61
  "sirv": "^3.0.1",
62
+ "swagger-ui-express": "^5.0.1",
52
63
  "tar": "^7.4.3",
53
64
  "tar-fs": "^3.0.8",
54
65
  "uniqid": "^5.4.0",
55
- "yaml": "^2.8.0"
66
+ "yaml": "^2.8.0",
67
+ "bcrypt": "^5.1.1",
68
+ "date-fns": "^4.1.0",
69
+ "express-mongo-sanitize": "^2.2.0",
70
+ "i18next": "^24.2.2",
71
+ "i18next-browser-languagedetector": "^8.0.4",
72
+ "node-cache": "^5.1.2",
73
+ "openai": "^5.8.2",
74
+ "react-helmet": "^6.1.0",
75
+ "react-i18next": "^15.4.1",
76
+ "react-markdown": "^10.1.0",
77
+ "zlib": "^1.0.5"
56
78
  },
57
79
  "devDependencies": {
58
80
  "@eslint/js": "^9.17.0",
@@ -67,7 +89,8 @@
67
89
  "primals",
68
90
  "automation",
69
91
  "aws",
70
- "bucket", "S3"
92
+ "bucket",
93
+ "S3"
71
94
  ],
72
95
  "author": "anonympins",
73
96
  "license": "MIT",
package/server.js CHANGED
@@ -32,54 +32,18 @@ import path from "node:path";
32
32
  import { getAllPacks} from "../data-primals-engine/src/packs.js";
33
33
  import {middlewareAuthenticator, userInitiator} from "../data-primals-engine/src/modules/user.js";
34
34
  import {defaultModels} from "../data-primals-engine/src/defaultModels.js";
35
- Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant"])
35
+ Config.Set("modules", ["mongodb", "data", "file", "bucket", "workflow","user", "assistant", "swagger"])
36
36
  Config.Set("middlewares", []);
37
37
 
38
38
  const bench = GameObject.Create("Benchmark");
39
39
  const timer = bench.addComponent(BenchmarkTool);
40
40
  timer.start();
41
41
 
42
- const swaggerDocument = YAML.parse(fs.readFileSync(process.cwd()+'/swagger-en.yml', 'utf8'));
43
-
44
42
  const engine = Engine.Create();
45
43
 
46
- const models = defaultModels;
47
-
48
44
  const port = process.env.PORT || 7633;
49
45
  engine.start(port, async (r) => {
50
46
  const logger = engine.getComponent(Logger);
51
- logger.info("Loading and validating models...");
52
- const ms = Object.values(models);
53
-
54
- let dbModels = await getModels();
55
-
56
- for(let i = 0; i < ms.length; ++i){
57
- const model = ms[i];
58
- validateModelStructure(model);
59
- // Création des modèles
60
- if( !dbModels.find(m =>m.name === model.name) )
61
- {
62
- model.locked = true;
63
- const r = await createModel(model);
64
- dbModels.push({...model, _id: r.insertedId });
65
- }
66
- else
67
- logger.info('Model loaded (' + model.name + ')', {});
68
- }
69
-
70
- engine.use('/doc', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
71
-
72
- if( install )
73
- await installAllPacks();
74
47
 
75
48
  timer.stop();
76
49
  });
77
-
78
- const installAllPacks = async () => {
79
-
80
- const packs = await getAllPacks();
81
-
82
- console.log(util.inspect(packs, false, 20, true));
83
- await packsCollection.deleteMany({ _user: { $exists : false }});
84
- await packsCollection.insertMany(packs);
85
- }
package/src/constants.js CHANGED
@@ -40,6 +40,10 @@ export const awsDefaultConfig = {
40
40
  region: 'eu-north-1',
41
41
  }
42
42
 
43
+ export const emailDefaultConfig = {
44
+ from: "Support - data@primals.net <data@primals.net>"
45
+ }
46
+
43
47
  // 10000 tiny users
44
48
  // 1000 modern users
45
49
  // 100 mega utilisateurs potentiality
package/src/email.js CHANGED
@@ -44,14 +44,14 @@ const createTransporter = (smtpConfig) => {
44
44
  * @param {string|null} tpl - Le template HTML à utiliser.
45
45
  */
46
46
  export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl = null) => {
47
- const contactEmail = smtpConfig ? (smtpConfig.from || "Our company <noreply@ourdomain.tld>") : "Support - data@primals.net <data@primals.net>";
47
+ const contactEmail = smtpConfig ? (smtpConfig.from || emailDefaultConfig.from) :"Our company <noreply@ourdomain.tld>";
48
48
  const emails = Array.isArray(email) ? email : [email];
49
49
  if (emails.length === 0) return;
50
50
 
51
51
  // Choisir le transporteur à utiliser
52
52
  const transporter = smtpConfig ? createTransporter(smtpConfig) : defaultTransporter;
53
53
 
54
- if (tpl === null) tpl = etemplate1(data, lang);
54
+ if (tpl === null) tpl = event_trigger("sendEmail:template",data, lang);
55
55
  let html = tpl;
56
56
  try {
57
57
  html = juice(tpl);
@@ -80,205 +80,6 @@ export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl =
80
80
  }
81
81
  };
82
82
 
83
- export const etemplate1 = (data, lang = "de", font = "Roboto") => {
84
- const { title, content } = data;
85
- // S'assurer que les traductions existent pour la langue demandée
86
- const trs = translations[lang]?.translation || translations['en']['translation'];
87
- return (
88
- `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
89
- <html xmlns="http://www.w3.org/1999/xhtml">
90
- <head>
91
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
92
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
93
- <title>Newsletter web.primals.net</title>
94
- <script type="application/ld+json">
95
- {
96
- "@context": "http://schema.org",
97
- "@type": "EmailMessage",
98
- "potentialAction": {
99
- "@type": "ViewAction",
100
- "url": "https://web.primals.net",
101
- "name": "web.primals.net"
102
- }
103
- }
104
- </script>
105
- <style type="text/css">
106
- /* Based on The MailChimp Reset INLINE: Yes. */
107
- /* Client-specific Styles */
108
- #outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
109
- body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0; color:black}
110
- /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
111
- .ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
112
- .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
113
- /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
114
- #backgroundTable {margin:0; padding:0; width:100% !important; line-height: 100% !important;}
115
- /* End reset */
116
-
117
- /* Some sensible defaults for images
118
- Bring inline: Yes. */
119
- img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
120
- a img {border:none;}
121
- .image_fix {display:block;}
122
-
123
- /* Yahoo paragraph fix
124
- Bring inline: Yes. */
125
- p {margin: 0;}
126
-
127
- /* Hotmail header color reset
128
- Bring inline: Yes. */
129
- h1, h2, h3, h4, h5, h6 {color: black !important;}
130
-
131
- h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color: blue !important;}
132
-
133
- h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {
134
- color: red !important; /* Preferably not the same color as the normal header link color. There is limited support for psuedo classes in email clients, this was added just for good measure. */
135
- }
136
-
137
- h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
138
- color: purple !important; /* Preferably not the same color as the normal header link color. There is limited support for psuedo classes in email clients, this was added just for good measure. */
139
- }
140
-
141
- /* Outlook 07, 10 Padding issue fix
142
- Bring inline: No.*/
143
- table td {border-collapse: collapse; }
144
-
145
- /* Remove spacing around Outlook 07, 10 tables
146
- Bring inline: Yes */
147
-
148
- /* Styling your links has become much simpler with the new Yahoo. In fact, it falls in line with the main credo of styling in email and make sure to bring your styles inline. Your link colors will be uniform across clients when brought inline.
149
- Bring inline: Yes. */
150
- a {color: #1381b1;}
151
- p { color:black; }
152
-
153
- h2 {
154
- padding: 20px 0;
155
- }
156
-
157
-
158
- /***************************************************
159
- ****************************************************
160
- MOBILE TARGETING
161
- ****************************************************
162
- ***************************************************/
163
- @media only screen and (max-device-width: 480px) {
164
- /* Part one of controlling phone number linking for mobile. */
165
- a[href^="tel"], a[href^="sms"] {
166
- text-decoration: none;
167
- color: blue; /* or whatever your want */
168
- pointer-events: none;
169
- cursor: default;
170
- }
171
-
172
- .mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
173
- text-decoration: default;
174
- color: orange !important;
175
- pointer-events: auto;
176
- cursor: default;
177
- }
178
-
179
- }
180
-
181
- /* More Specific Targeting */
182
-
183
- @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {
184
- /* You guessed it, ipad (tablets, smaller screens, etc) */
185
- /* repeating for the ipad */
186
- a[href^="tel"], a[href^="sms"] {
187
- text-decoration: none;
188
- color: blue; /* or whatever your want */
189
- pointer-events: none;
190
- cursor: default;
191
- }
192
-
193
- .mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
194
- text-decoration: default;
195
- color: orange !important;
196
- pointer-events: auto;
197
- cursor: default;
198
- }
199
- }
200
-
201
- @media only screen and (-webkit-min-device-pixel-ratio: 2) {
202
- /* Put your iPhone 4g styles in here */
203
- }
204
-
205
- /* Android targeting */
206
- @media only screen and (-webkit-device-pixel-ratio:.75){
207
- /* Put CSS for low density (ldpi) Android layouts in here */
208
- }
209
- @media only screen and (-webkit-device-pixel-ratio:1){
210
- /* Put CSS for medium density (mdpi) Android layouts in here */
211
- }
212
- @media only screen and (-webkit-device-pixel-ratio:1.5){
213
- /* Put CSS for high density (hdpi) Android layouts in here */
214
- }
215
- /* end Android targeting */
216
-
217
- </style>
218
-
219
- <!-- Targeting Windows Mobile -->
220
- <!--[if IEMobile 7]>
221
- <style type="text/css">
222
-
223
- </style>
224
- <![endif]-->
225
-
226
- <!-- ***********************************************
227
- ****************************************************
228
- END MOBILE TARGETING
229
- ****************************************************
230
- ************************************************ -->
231
-
232
- <!--[if gte mso 9]>
233
- <style>
234
- /* Target Outlook 2007 and 2010 */
235
- </style>
236
- <![endif]-->
237
- </head>
238
- <body><style>
239
- @import url(https://fonts.googleapis.com/css?family=${font});
240
-
241
- /* Type styles for all clients */
242
- h1,h2,h3 {
243
- font-family: Helvetica, Arial, serif;
244
- text-align: center;
245
- }
246
- h3 {
247
- margin: 0;
248
- }
249
- p{
250
- font-family: Helvetica, Arial, serif;
251
- }
252
- /* Type styles for WebKit clients */
253
- @media screen and (-webkit-min-device-pixel-ratio:0) {
254
- h1,h2,h3 {
255
- font-family: ${font}, Helvetica, Arial, serif !important;
256
- }
257
- }
258
- </style>` +
259
- etable(
260
- etable(
261
- erow(
262
- etag("h2", {'text-align': 'left'}, title) +
263
- etable(
264
- erow(etag('p', {}, trs[content] || content || ''), { 'text-align': 'left' })+
265
- erow(etag('p', {}, trs['email.defaultSignature'] ||'')),
266
- { 'text-align': 'left' }),
267
- { 'text-align': 'left' }
268
- )+
269
- erow(
270
- etag('hr', {}, '')+
271
- etag('a', { href: "https://data.primals.net"}, 'https://data.primals.net')+
272
- etag('div', {}, 'Service gratuit de base de donnée en ligne')+
273
- etag("div", {}, 'Support: '+etag('a', { href:'mailto:data@primals.net'}, 'data@primals.net')),
274
- { 'text-align': 'left' }
275
- )
276
- ),
277
- { width: "1024px", 'text-align': "left" },
278
- )
279
- );
280
- };
281
-
282
83
  export const etag = (name, attrs, content = "") => {
283
84
  return (
284
85
  "<" +
@@ -292,5 +292,5 @@ export async function onInit(engine) {
292
292
  res.status(500).json({success: false, message: "Une erreur interne est survenue."});
293
293
  }
294
294
  });
295
- logger.info("Module 'assistant' initialisé et endpoint '/api/assistant/chat' enregistré.");
295
+ logger.info("Module 'assistant' loaded and endpoint '/api/assistant/chat' registered.");
296
296
  }
@@ -188,9 +188,6 @@ export async function onInit(defaultEngine) {
188
188
  // Autres validations possibles (longueur, format de la région, etc.)
189
189
 
190
190
  try {
191
- const primalsDb = MongoClient.db("primals"); // Assure-toi que MongoClient est bien ton client MongoDB connecté
192
- const usersCollection = primalsDb.collection("users");
193
-
194
191
  const updateData = {
195
192
  's3Config.bucketName': bucketName,
196
193
  's3Config.accessKeyId': accessKeyId, // Stocké en clair (généralement acceptable)
@@ -207,18 +204,15 @@ export async function onInit(defaultEngine) {
207
204
  // Pour l'instant, on ne touche pas à s3Config.secretAccessKey si req.body.secretAccessKey est vide.
208
205
  }
209
206
 
210
- const result = await usersCollection.updateOne(
207
+ const result = await engine.userProvider.updateUser(
211
208
  { username: user.username }, // ou user._id si c'est ce que tu utilises comme identifiant unique
212
- { $set: updateData }
209
+ updateData
213
210
  );
214
211
 
215
- if (result.modifiedCount > 0 || result.matchedCount > 0) { // Succès même si rien n'a été modifié (déjà les bonnes valeurs)
216
- logger.info(`S3 configuration updated for user ${user.username}`);
212
+ if (result) { // Succès même si rien n'a été modifié (déjà les bonnes valeurs)
217
213
  res.json({ success: true, message: "S3 configuration updated successfully." });
218
214
  } else {
219
- logger.warn(`S3 configuration update: User ${user.username} not found or no changes made.`);
220
- // Si l'utilisateur n'est pas trouvé, c'est une erreur 404
221
- const userExists = await usersCollection.findOne({ username: user.username });
215
+ const userExists = engine.userProvider.findUserByUsername(user.username);
222
216
  if (!userExists) {
223
217
  return res.status(404).json({ success: false, error: "User not found." });
224
218
  }
@@ -1397,7 +1397,7 @@ export async function onInit(defaultEngine) {
1397
1397
  // Créer une représentation de l'utilisateur mis à jour pour la réponse
1398
1398
  const updatedData = { activeTutorial: tutorialState };
1399
1399
 
1400
- await saveUser(user, updatedData);
1400
+ await engine.userProvider.updateUser(user, updatedData);
1401
1401
 
1402
1402
  // --- MODIFICATION ---
1403
1403
  res.json({
@@ -14,6 +14,9 @@ import crypto from "node:crypto";
14
14
  import * as tar from "tar";
15
15
  import {promisify} from "node:util";
16
16
  import {calculateTotalUserStorageUsage, hasPermission} from "./user.js";
17
+ import {Logger} from "../gameObject.js";
18
+ import YAML from "yaml";
19
+ import swaggerUi from "swagger-ui-express";
17
20
 
18
21
  const pbkdf2Async = promisify(crypto.pbkdf2);
19
22
 
@@ -190,3 +193,7 @@ export async function decryptFile(filePath, password) {
190
193
  throw new Error(`Decryption failed: ${error.message}`);
191
194
  }
192
195
  }
196
+
197
+ export async function onInit(defaultEngine) {
198
+
199
+ }
package/src/providers.js CHANGED
@@ -13,6 +13,15 @@ export class UserProvider {
13
13
  this.engine = engine;
14
14
  }
15
15
 
16
+ /**
17
+ * Met à jour un nouvel utilisateur.
18
+ * @param user
19
+ * @returns {Promise<void>}
20
+ */
21
+ async updateUser(user, data) {
22
+
23
+ }
24
+
16
25
  /**
17
26
  * Trouve un utilisateur par son nom d'utilisateur.
18
27
  * @param {string} username - Le nom d'utilisateur à rechercher.
@@ -54,8 +63,11 @@ export class DefaultUserProvider extends UserProvider {
54
63
  }
55
64
 
56
65
  async validatePassword(user, password) {
57
- if (!user || !user.password || !password) return false;
58
- return await compare(password, user.password);
66
+ return true;
67
+ }
68
+
69
+ async updateUser(user, data) {
70
+ this.users = this.users.map(user => user.username === user.username ? {...user, ...data} : user);
59
71
  }
60
72
 
61
73
  async initiateUser(req) {