@triophore/falconjs 1.0.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.
Files changed (53) hide show
  1. package/FalconAuthPlugin.js +473 -0
  2. package/LICENSE +21 -0
  3. package/README.md +2 -0
  4. package/core/auth.js +200 -0
  5. package/core/cache/redis_cacher.js +7 -0
  6. package/core/check_collection.js +9 -0
  7. package/core/crypto/encrypt_decrypt.js +19 -0
  8. package/core/errors.js +48 -0
  9. package/core/logger/log4js.js +89 -0
  10. package/core/logo.js +3 -0
  11. package/core/mongo/generateModelfromJsonFile.js +128 -0
  12. package/core/mongo/mongoSchmeFromJson.js +90 -0
  13. package/core/parse_num.js +8 -0
  14. package/core/rannum.js +33 -0
  15. package/core/ranstring.js +33 -0
  16. package/core/recursive-require-call.js +121 -0
  17. package/core/uitls/mongoose_to_joi.js +72 -0
  18. package/core/uitls/return.js +7 -0
  19. package/falcon.js +1644 -0
  20. package/falconAuthPlugin.js +17 -0
  21. package/falconBaseService.js +532 -0
  22. package/falconBaseWorker.js +540 -0
  23. package/index.js +4 -0
  24. package/out/Falcon.html +777 -0
  25. package/out/falcon.js.html +525 -0
  26. package/out/fonts/OpenSans-Bold-webfont.eot +0 -0
  27. package/out/fonts/OpenSans-Bold-webfont.svg +1830 -0
  28. package/out/fonts/OpenSans-Bold-webfont.woff +0 -0
  29. package/out/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  30. package/out/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
  31. package/out/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  32. package/out/fonts/OpenSans-Italic-webfont.eot +0 -0
  33. package/out/fonts/OpenSans-Italic-webfont.svg +1830 -0
  34. package/out/fonts/OpenSans-Italic-webfont.woff +0 -0
  35. package/out/fonts/OpenSans-Light-webfont.eot +0 -0
  36. package/out/fonts/OpenSans-Light-webfont.svg +1831 -0
  37. package/out/fonts/OpenSans-Light-webfont.woff +0 -0
  38. package/out/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  39. package/out/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
  40. package/out/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  41. package/out/fonts/OpenSans-Regular-webfont.eot +0 -0
  42. package/out/fonts/OpenSans-Regular-webfont.svg +1831 -0
  43. package/out/fonts/OpenSans-Regular-webfont.woff +0 -0
  44. package/out/index.html +65 -0
  45. package/out/scripts/linenumber.js +25 -0
  46. package/out/scripts/prettify/Apache-License-2.0.txt +202 -0
  47. package/out/scripts/prettify/lang-css.js +2 -0
  48. package/out/scripts/prettify/prettify.js +28 -0
  49. package/out/styles/jsdoc-default.css +358 -0
  50. package/out/styles/prettify-jsdoc.css +111 -0
  51. package/out/styles/prettify-tomorrow.css +132 -0
  52. package/package.json +106 -0
  53. package/settings.js +1 -0
@@ -0,0 +1,525 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>JSDoc: Source: falcon.js</title>
6
+
7
+ <script src="scripts/prettify/prettify.js"> </script>
8
+ <script src="scripts/prettify/lang-css.js"> </script>
9
+ <!--[if lt IE 9]>
10
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11
+ <![endif]-->
12
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
13
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
14
+ </head>
15
+
16
+ <body>
17
+
18
+ <div id="main">
19
+
20
+ <h1 class="page-title">Source: falcon.js</h1>
21
+
22
+
23
+
24
+
25
+
26
+
27
+ <section>
28
+ <article>
29
+ <pre class="prettyprint source linenums"><code>require("dotenv").config({ quiet: true, debug: false });
30
+ const config = process.env;
31
+ const crypto = require("crypto");
32
+ const mongoose = require("mongoose");
33
+ const bcrypt = require("bcrypt");
34
+ // const mongoosePaginate = require('mongoose-paginate-v2');
35
+ const Hapi = require("@hapi/hapi");
36
+ const Blipp = require("blipp");
37
+ const Inert = require("@hapi/inert");
38
+ const path = require("path");
39
+ const fs = require("fs");
40
+ const fsp = require("fs/promises");
41
+ const Crumb = require("@hapi/crumb");
42
+ const JWT = require("jsonwebtoken");
43
+ const { v4: uuidv4 } = require("uuid");
44
+ const { Server } = require("socket.io");
45
+ const redis = require("redis");
46
+ const axios = require("axios");
47
+ const spawn = require("child_process").spawn;
48
+ const customParser = require("socket.io-msgpack-parser");
49
+ const encrypt = require("./core/crypto/encrypt_decrypt").encrypt;
50
+ const decrypt = require("./core/crypto/encrypt_decrypt").decrypt;
51
+ const mqtt = require("mqtt");
52
+ const logger = require("./core/logger/log4js").getlogger();
53
+ const Scooter = require("@hapi/scooter");
54
+ const { createServer } = require("node:http");
55
+ const logo = require("./core/logo").logo;
56
+
57
+
58
+ /**
59
+ * Represents a Falcon Server.
60
+ * @constructor
61
+ */
62
+ class Falcon {
63
+ // #models = {}
64
+
65
+ constructor() {
66
+ //check if settings files in the directory
67
+ if (!fs.existsSync(path.join(__dirname, "settings.js"))) {
68
+ throw "Settings file not found !";
69
+ }
70
+ this.SETTINGS = require("./settings.js").settings;
71
+ this.db = null;
72
+ this.redis_client = null;
73
+ this.http_server = null;
74
+ this._socket_io_config = {};
75
+ this.models = {};
76
+ this.CONTEXT = {};
77
+ this.CONTEXT["models"] = {};
78
+ this.CONTEXT["env"] = config;
79
+ this.CONTEXT["services"] = [];
80
+ this.CONTEXT["workers"] = {};
81
+ this.aedes = require("aedes")();
82
+ this.mqtt_client = false;
83
+ this.mqtt_server = require("net").createServer(this.aedes.handle);
84
+ this.mqtt_port = process.env.MQTT_PORT;
85
+ this.mqtt_server.listen(this.mqtt_port, function () {
86
+ logger.info("MQTT server started and listening on port ", this.mqtt_port);
87
+ });
88
+ this.CONTEXT["mqtt"] = this.mqtt_server;
89
+ this.CONTEXT["settings"] = this.SETTINGS;
90
+ this.CONTEXT["logger"] = logger;
91
+ this.config = config;
92
+ }
93
+
94
+ #isDev() {
95
+ return process.env.MODE == "DEV" ? true : false;
96
+ }
97
+
98
+ async #Prep() {
99
+ logger.info(
100
+ "......................................................................",
101
+ );
102
+ logger.info("TRIOPHORE SERVER");
103
+ logger.info("Developed and maintained by");
104
+ logger.info(logo);
105
+ logger.info("Triophore");
106
+ logger.info("visit us on : https://triophore.com");
107
+ logger.info(
108
+ "......................................................................",
109
+ );
110
+ logger.info(
111
+ "......................................................................",
112
+ );
113
+ logger.info("Starting server");
114
+ logger.info("Date :: " + Date.now());
115
+ logger.info(
116
+ "......................................................................",
117
+ );
118
+ logger.info("");
119
+ logger.info(
120
+ "......................................................................",
121
+ );
122
+ logger.info("Starting bind for services");
123
+ logger.info("Date :: " + Date.now());
124
+ logger.info("Binding complete");
125
+ logger.info(
126
+ "......................................................................",
127
+ );
128
+ logger.info("");
129
+ logger.info("MQTT Service details");
130
+ logger.info("launching worker process....");
131
+ }
132
+
133
+ /**
134
+ * starts the initializing process
135
+ * @returns context
136
+ */
137
+ async init() {
138
+ await this.#Prep();
139
+ await this.#startService();
140
+ await this.#startMongoDB();
141
+ await this.#startRedis();
142
+ // this.CONTEXT["return"] = require("./core/uitls/return").return_obj;
143
+ await this.#loadModels();
144
+ await this.#startHttpServer();
145
+ await this.#startMqttClient();
146
+ await this.#startSocketIO();
147
+ await this.#Postinit();
148
+ return this;
149
+ }
150
+
151
+ async #startService() {
152
+ if (this.SETTINGS.hasOwnProperty("services")) {
153
+ if (this.SETTINGS.services.length > 0) {
154
+ logger.info("-----------------Spawning Services----------------");
155
+ logger.info(
156
+ "......................................................................",
157
+ );
158
+ this.#services(this.SETTINGS.services);
159
+ logger.info(
160
+ "......................................................................",
161
+ );
162
+ logger.info("-----------------Spawning Services----------------");
163
+ } else {
164
+ logger.info("-----------------Spawning Services----------------");
165
+ logger.info(
166
+ "......................................................................",
167
+ );
168
+ logger.info("No worker registered..");
169
+ logger.info(
170
+ "......................................................................",
171
+ );
172
+ logger.info("-----------------Spawning Services----------------");
173
+ }
174
+ }
175
+ }
176
+
177
+ async #Postinit() {
178
+ if (this.SETTINGS.postInit) {
179
+ var post_file_path = path.join(
180
+ __dirname,
181
+ "init",
182
+ this.SETTINGS.postInit + ".js",
183
+ );
184
+ if (fs.existsSync(post_file_path)) {
185
+ await require(post_file_path).run(this.CONTEXT);
186
+ }
187
+ }
188
+ }
189
+
190
+ async #startMongoDB() {
191
+ if (this.#isDev()) {
192
+ mongoose.set("debug", true);
193
+ logger.debug("Mongoose ODM is set in Debug Mode");
194
+ logger.info("Mongoose Log will be collected");
195
+ }
196
+ await mongoose.connect(config.MONGODB_URL, {}); //useNewUrlParser: true, useUnifiedTopology: true
197
+ mongoose.set("debug", (collectionName, method, query, doc) => {
198
+ logger.info(
199
+ `MONGOOSE ==> ${collectionName}.${method}`,
200
+ JSON.stringify(query),
201
+ doc,
202
+ );
203
+ });
204
+ this.db = mongoose.connection.db;
205
+ logger.info("MongoDB connected");
206
+ this.CONTEXT["db"] = this.db;
207
+ this.CONTEXT["mongoose"] = mongoose;
208
+ }
209
+
210
+ async #startRedis() {
211
+ if (this.config.REDIS_ENABLE === "true") {
212
+ logger.info("Redis enabled!");
213
+ this.redis_client = await redis
214
+ .createClient({
215
+ url: this.config.REDIS_URL,
216
+ })
217
+ .on("error", (err) => logger.error(`Error connecting to Redis ${err}`))
218
+ .on("ready", () =>
219
+ logger.info(`Connected to Redis ${config.REDIS_URL}`),
220
+ )
221
+ .connect();
222
+ this.CONTEXT["redis"] = this.redis_client;
223
+ } else {
224
+ logger.warn("Redis disabled");
225
+ this.CONTEXT["redis"] = false;
226
+ }
227
+ }
228
+
229
+ /**
230
+ *
231
+ * @param {*} route for connecting
232
+ * @returns context
233
+ */
234
+ async addRoute(route) {
235
+ await this.http_server.route(route);
236
+ return this;
237
+ }
238
+
239
+ async #loadModels() {
240
+ /*MODELS*/
241
+ logger.info("-----------------Registering Model----------------");
242
+ for (let mindex = 0; mindex &lt; this.SETTINGS.models.length; mindex++) {
243
+ const model = this.SETTINGS.models[mindex];
244
+ await this.#load_model_name(model);
245
+ }
246
+ logger.info("-----------------Registering Model----------------");
247
+ /*MODELS*/
248
+ // this.CONTEXT["models"] = models;
249
+ }
250
+
251
+ async #startHttpServer() {
252
+ //creating server object
253
+ this.http_server = null;
254
+ this.http_server = Hapi.server({
255
+ port: process.env.HTTP_PORT,
256
+ host: process.env.HTTP_HOST,
257
+ routes: {
258
+ cors: true,
259
+ },
260
+ });
261
+ this.http_server.events.on("log", (event, tags) => {
262
+ logger.error(
263
+ `Server error: ${event.error ? event.error.message : "unknown"} -- ${tags}`,
264
+ );
265
+ });
266
+ this.http_server.events.on("request", (request, event, tags) => {
267
+ logger.info(`Server request: ${request} ${event}`);
268
+ });
269
+ await this.http_server.register({
270
+ plugin: Blipp,
271
+ options: { showAuth: true },
272
+ });
273
+
274
+ await this.registerAuth();
275
+ await this.http_server.register(Scooter);
276
+ logger.info(await this.http_server.plugins.blipp.info());
277
+ if (this.#isDev()) {
278
+ logger.info("-----------------DEV MODE----------------");
279
+ logger.info("-----------------DEV MODE----------------");
280
+ logger.info("-----------------DEV MODE----------------");
281
+ }
282
+ this.CONTEXT["server"] = this.http_server;
283
+ /* ROUTES */
284
+ for (let rindex = 0; rindex &lt; this.SETTINGS.routes.length; rindex++) {
285
+ const route = this.SETTINGS.routes[rindex];
286
+ await require("./routes/" + route).route(this.CONTEXT);
287
+ }
288
+ this.http_server.events.on("response", function (request) {
289
+ logger.info(
290
+ request.info.remoteAddress +
291
+ ": " +
292
+ request.method.toUpperCase() +
293
+ " " +
294
+ request.path +
295
+ " --> " +
296
+ request.response.statusCode,
297
+ );
298
+ });
299
+ logger.info("-----------------Registered Routes----------------");
300
+ await this.http_server
301
+ .table()
302
+ .forEach((route) => logger.info(`${route.method}\t${route.path}`));
303
+ logger.info("-----------------Registered Routes----------------");
304
+ }
305
+
306
+ /**
307
+ * Starts the server
308
+ */
309
+ async runServer() {
310
+ await this.CONTEXT["server"].start();
311
+ }
312
+
313
+ async #startSocketIO() {
314
+ var io = new Server(this.http_server.listener, _socket_io_config);
315
+ }
316
+ async #startMqttClient() {
317
+ this.mqtt_client = mqtt.connect(`${config.MQTT_URL}`);
318
+ this.CONTEXT["mqtt_client"] = this.mqtt_client;
319
+ this.mqtt_client.on("connect", () => {
320
+ this.mqtt_client.subscribe("service_utils", (err) => {
321
+ logger.info("mqtt connected and subscribed to utility service");
322
+ });
323
+ this.mqtt_client.subscribe("websocket_broadcast", (err) => {
324
+ logger.info("mqtt connected and subscribed to utility service");
325
+ });
326
+ });
327
+ }
328
+
329
+ /**
330
+ *
331
+ * Get Socket IO middle ware
332
+ * @returns context
333
+ */
334
+ registerSocketIOMiddleware() {
335
+ return this;
336
+ }
337
+
338
+ /**
339
+ * Override this function to handle your own auth
340
+ */
341
+ async registerAuth() {
342
+ await this.http_server.register(require("hapi-auth-jwt2"));
343
+ this.http_server.auth.strategy("jwt", "jwt", {
344
+ key: config.JWT_SECRET, // Never Share your secret key
345
+ validate: this.#validate, // validate function defined above
346
+ });
347
+ this.http_server.auth.default("jwt");
348
+ return this;
349
+ }
350
+
351
+ async #validate(decoded, request, h) {
352
+ await this.validateAuth(decoded, request, h, this.CONTEXT)
353
+ }
354
+
355
+ /**
356
+ * Handler for auth validation
357
+ */
358
+ async validateAuth(decoded, request, h, context) {
359
+
360
+ logger.info("jwt_validate");
361
+ logger.info(request.path);
362
+ logger.info(decoded);
363
+ logger.info("jwt_validate");
364
+ if (decoded == null || decoded == undefined) {
365
+ return { isValid: false };
366
+ } else {
367
+ //JSON.parse(decrypt(decoded))
368
+ // return { isValid: true };
369
+ if (decoded.hasOwnProperty("token") &amp;&amp; decoded.hasOwnProperty("uid")) {
370
+ if (decoded.uid &amp;&amp; decoded.token) {
371
+ try {
372
+ var _temp = false;
373
+ var jwt_cache = await CONTEXT["redis"].get(
374
+ "login_" + decoded.token,
375
+ );
376
+ logger.info(`Redis data from cache ${jwt_cache}`);
377
+ if (jwt_cache) {
378
+ _temp = JSON.parse(jwt_cache);
379
+ } else {
380
+ _temp_db = await CONTEXT["models"]["user"].findById(
381
+ decoded.token,
382
+ );
383
+ if (_temp_db) {
384
+ await CONTEXT["redis"].set(
385
+ "login_" + decoded.token,
386
+ JSON.stringify(_temp_db),
387
+ { EX: 60 },
388
+ );
389
+ }
390
+ _temp = _temp_db;
391
+ }
392
+ if (_temp) {
393
+ return { isValid: true, credentials: _temp };
394
+ } else {
395
+ return { isValid: false };
396
+ }
397
+ } catch (error) {
398
+ return { isValid: false };
399
+ }
400
+ } else {
401
+ return { isValid: false };
402
+ }
403
+ } else {
404
+ return { isValid: false };
405
+ }
406
+ }
407
+
408
+
409
+ }
410
+
411
+ // --- LOADER FUNCTION --- //
412
+ async #load_model_name(name) {
413
+ var _temp = await require("./models/" + name)(mongoose);
414
+ this.models[name] = _temp;
415
+ this.CONTEXT["models"][name] = _temp;
416
+ logger.info(name + " model registered");
417
+ }
418
+ async #load_route_name(name, server) {
419
+ await require("./routes/" + name).route(server, models, logger);
420
+ logger.info(name + " route registered");
421
+ }
422
+ // --- LOADER FUNCTION --- //
423
+
424
+ #workers() {
425
+ this.CONTEXT.startWorker = async function (worker_name, args = {}) {
426
+ if (this.CONTEXT.workers.hasOwnProperty(worker_name)) {
427
+ const service_file = `./workers/${this.CONTEXT.workers[worker_name]}.js`;
428
+ const args_json = JSON.stringify(args);
429
+ const buffer = Buffer.from(jsonString, "utf8");
430
+ const base64String = buffer.toString("base64");
431
+ var service_worker = spawn('node', [service_file, base64String], { env: { ...process.env } });
432
+ service_worker.stdout.setEncoding('utf8');
433
+ service_worker.stderr.setEncoding('utf8');
434
+ logger.info("Settings EMAIL Worker")
435
+ service_worker.stdout.on('data', function (data) {
436
+ logger.info("-------EMAIL WORKER-------")
437
+ logger.info(data)
438
+ logger.info("-------EMAIL WORKER-------")
439
+ });
440
+ service_worker.stderr.on('data', function (data) {
441
+ logger.error("-------EMAIL WORKER ERROR-------")
442
+ logger.error(data)
443
+ logger.error("-------EMAIL WORKER ERROR-------")
444
+ });
445
+ service_worker.on('close', function (code) {
446
+ logger.info("-------EMAIL WORKER CLOSED-------")
447
+ logger.info(code)
448
+ logger.info("-------EMAIL WORKER CLOSED-------")
449
+ });
450
+ } else {
451
+
452
+ }
453
+ };
454
+ }
455
+
456
+ #services(filesToRun) {
457
+ filesToRun.forEach((file) => {
458
+ const spawnOptions = {
459
+ stdio: ["pipe", "pipe", "pipe"], // Pipe stdout and stderr to our custom logging function
460
+ env: { ...process.env, LOG4JS_LOGGER_LEVEL: "DEBUG" }, // Set the Log4js logger level for each process
461
+ };
462
+
463
+ const s_path = path.join(__dirname, "services", file + ".js");
464
+
465
+ console.log(s_path);
466
+
467
+ // Spawn a new process using childProcess.spawn()
468
+ const cprocess = spawn("node", [s_path], spawnOptions);
469
+
470
+ // Pipe stdout and stderr to our custom logging function
471
+ // process.stdout.pipe(process.stdout);
472
+ // process.stderr.pipe(process.stderr);
473
+
474
+ cprocess.stdout.on("data", (data) => {
475
+ logger.info(
476
+ `------------------------SERVICE - ${file}----------------`,
477
+ );
478
+ logger.info(data.toString());
479
+ logger.info(
480
+ `------------------------SERVICE - ${file}----------------`,
481
+ );
482
+ });
483
+ cprocess.stderr.on("data", (data) => {
484
+ logger.error(
485
+ `------------------------SERVICE - ${file}----------------`,
486
+ );
487
+ logger.error(data.toString());
488
+ logger.error(
489
+ `------------------------SERVICE - ${file}----------------`,
490
+ );
491
+ });
492
+
493
+ this.CONTEXT["services"].push({
494
+ pid: cprocess.pid,
495
+ stdout: cprocess.stdout,
496
+ stderr: cprocess.stderr,
497
+ });
498
+ });
499
+ }
500
+ }
501
+
502
+ module.exports = Falcon;
503
+ </code></pre>
504
+ </article>
505
+ </section>
506
+
507
+
508
+
509
+
510
+ </div>
511
+
512
+ <nav>
513
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Falcon.html">Falcon</a></li></ul>
514
+ </nav>
515
+
516
+ <br class="clear">
517
+
518
+ <footer>
519
+ Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Sun Oct 19 2025 12:00:49 GMT+0530 (India Standard Time)
520
+ </footer>
521
+
522
+ <script> prettyPrint(); </script>
523
+ <script src="scripts/linenumber.js"> </script>
524
+ </body>
525
+ </html>