webfast 0.1.31 → 0.1.35

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.
@@ -1,4 +1,42 @@
1
1
  console.log(`WebFast!`);
2
2
  window.WebFast = {
3
3
  ts : Date.now()
4
- }
4
+ }
5
+ // Connect to the Socket.IO server
6
+ const telegram = window.Telegram.WebApp;
7
+ // Step 1: Parse the query string
8
+ if (webfastSocket == undefined) {
9
+ webfastSocket = window.location.host;
10
+ }
11
+
12
+ let setData;
13
+ if (telegram.initData == ``) {
14
+ setData = `hybrid.institute.anonymous`
15
+ } else {
16
+ setData = telegram.initData;
17
+ }
18
+
19
+ const socketURL = `wss://${webfastSocket.replace(`https://`,``)}socket.io/?qbt=${setData}`;
20
+
21
+ try {
22
+ new WebSocket(socketURL,`test`,{
23
+ timeout : 0
24
+ });
25
+
26
+ // Start the other things
27
+ //alert(telegram.initData);
28
+ } catch (err) {
29
+ alert(`Err`);
30
+ console.error(err);
31
+ }
32
+
33
+ // On Ready desable all forms with jquery
34
+ jQuery(document).ready(function() {
35
+ jQuery('form').submit(function(e) {
36
+ e.preventDefault(); // Prevent the default form submission
37
+
38
+ // Check what to do like socketpath
39
+ alert(`Form Submit`);
40
+ return false;
41
+ });
42
+ });
@@ -4,10 +4,10 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title><%= title %></title>
7
- <script src="<%= url %>/app/content/js/jquery-3.7.1.min.js"></script>
7
+ <script src="<%= url %>app/content/js/jquery-3.7.1.min.js"></script>
8
8
  <script src="https://telegram.org/js/telegram-web-app.js"></script>
9
9
  <script src="https://unpkg.com/@tonconnect/ui@latest/dist/tonconnect-ui.min.js"></script>
10
- <script src="<%= url %>/app/content/js/webfast.js"></script>
10
+ <script src="<%= url %>app/content/js/webfast.js"></script>
11
11
  </head>
12
12
  <body>
13
13
 
package/ejs/view/list.ejs CHANGED
@@ -3,7 +3,12 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title><%= title %></title>
6
+ <title><%= title %></title><!-- Include Socket.IO from CDN -->
7
+ <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
8
+ <script src="<%= url %>app/content/js/jquery-3.7.1.min.js"></script>
9
+ <script src="https://telegram.org/js/telegram-web-app.js"></script>
10
+ <script src="https://unpkg.com/@tonconnect/ui@latest/dist/tonconnect-ui.min.js"></script>
11
+ <script src="<%= url %>app/content/js/webfast.js"></script>
7
12
  </head>
8
13
  <body>
9
14
 
package/example.js ADDED
@@ -0,0 +1,5 @@
1
+ const path = require(`path`);
2
+ let program = require(path.join(__dirname,`index.js`))({
3
+ wget : '/usr/local/bin/wget'
4
+ });
5
+ console.log(`Required`);
package/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  module.exports = function (array) {
2
2
  const { readdirSync } = require("fs");
3
3
 
4
- // Need to walk through array for specific things
5
4
  console.log(`WebFast!! Program`);
6
5
  let program = {
7
6
  ts : Date.now(),
@@ -11,17 +10,18 @@ module.exports = function (array) {
11
10
  }
12
11
 
13
12
  for (let key in array) {
14
- program.set[key] = array[key];
13
+ program.set[key]=array[key]
15
14
  }
16
15
 
17
16
  // Setup The Requirements
18
- async function set(program) {
19
- program.path = await require(`path`);
20
- program.fs = await require(`fs`);
21
- program.uuid = require(`uuid`);
22
- program.fetch = require(`fetch`);
23
-
24
- return program;
17
+ program.path = require(`path`);
18
+ program.fs = require(`fs`);
19
+ program.uuid = require(`uuid`);
20
+ program.fetch = require(`fetch`);
21
+ program.util = require(`util`);
22
+ program.exec = program.util.promisify(require('child_process').exec);
23
+ program.image = {
24
+ size : require('image-size')
25
25
  }
26
26
 
27
27
  // Program Fetch
@@ -127,11 +127,8 @@ module.exports = function (array) {
127
127
  }
128
128
  }
129
129
 
130
- program.modules.fetch = async function(folder,program,fetch) {
130
+ program.modules.fetch = async function(folder,program) {
131
131
  // TO Fetch folder modules
132
- if (fetch == undefined) {
133
- program = await set(program);
134
- }
135
132
  try {
136
133
  // Loop through folder and run module if js
137
134
  const readPath = program.path.join(__dirname,folder);
@@ -252,5 +249,26 @@ module.exports = function (array) {
252
249
 
253
250
  // Run program fetch
254
251
  program.modules.fetch(`modules`,program);
252
+
253
+ // Check if program.set.path is set
254
+ if (program.set.path != undefined) {
255
+ // We have the path for normal path so check for the folder app
256
+ try {
257
+ const appFolder = program.path.join(program.set.path,`app`,`init.js`);
258
+ // Now include this appFolder // set app
259
+ program.app = require(appFolder)(program);
260
+ console.log(`Include App`);
261
+ } catch (err) {
262
+ console.error(err);
263
+ console.error(`Error with program set folder`);
264
+ }
265
+ }
255
266
  return program;
267
+ }
268
+
269
+ // to cut the log
270
+ if (process.env.log == undefined) {
271
+ console.log = function() {
272
+
273
+ }
256
274
  }
@@ -0,0 +1,124 @@
1
+ module.exports = {
2
+ UserProfilePhotos : async function(program,user,callback) {
3
+ console.log(`Get User Profile Photos`);
4
+ // Save user photo when first time
5
+ // Create call
6
+ const userPhotos = await program.modules.telegram.functions.get.request(`getUserProfilePhotos`,{
7
+ user_id : user.id
8
+ },program,callback);
9
+ console.log(`The User Photo`);
10
+ // convert base64 and save to database
11
+ const uuid = program.uuid.v4();
12
+ for (let userI in userPhotos.result.photos) {
13
+ // Make request for file
14
+ let profilePictures = userPhotos.result.photos[userI]
15
+ // Telegram will give back an array
16
+ for (let profileI in profilePictures) {
17
+ const profilePictureData = profilePictures[profileI];
18
+ const fileID = profilePictureData.file_id;
19
+ const fileUnique = profilePictureData.file_unique_id;
20
+
21
+ try {
22
+ const userPhotoURL = await program.modules.telegram.functions.get.file(program,fileID);
23
+
24
+ // create url
25
+ const photoURL = `https://api.telegram.org/file/bot${process.env.telegram}/${userPhotoURL.result.file_path}`;;
26
+
27
+ // Now do the fetch process thingy
28
+ await program.modules.telegram.functions.get.downloadAndConvertToBase64(program,photoURL,async function(program,response){
29
+ console.log(`We have now file data`);
30
+ // Create id for file that is unique uuid
31
+ const meta = {
32
+ user : response.data.user.id,
33
+ type : response.imageData.type,
34
+ size : {
35
+ width : response.imageData.width,
36
+ height : response.imageData.height
37
+ }
38
+ }
39
+ await program.modules.data.file.uploadBuffer(program,response.buffer,uuid,meta,async function(progam,upload,meta){
40
+ console.log(`Uploaded Buffer`);
41
+ // Save to membe
42
+ await program.modules.telegram.functions.set.profilePhoto(progam,upload,meta);
43
+ });
44
+
45
+ },{
46
+ user : user,
47
+ data : profilePictureData
48
+ });
49
+ } catch (err) {
50
+ console.error(`Error For Downloading file`);
51
+ }
52
+ }
53
+ }
54
+ },
55
+ file : async function(program,fileID,callback) {
56
+ // TO get the file from telegram
57
+ const getFile = await program.modules.telegram.functions.get.request(`getFile`,{
58
+ file_id : fileID
59
+ },program,callback);
60
+ return getFile;
61
+ },
62
+ downloadAndConvertToBase64 : async (program, photoURL, callback,data) => {
63
+ try {
64
+ // Use wget to download the image
65
+ const { stdout, stderr } = await program.exec(`${program.set.wget} -O - ${photoURL}`, { encoding: 'buffer' });
66
+
67
+ // Check if the download was successful
68
+ const errBuf = Buffer.from(stderr);
69
+ const errorText = errBuf.toString('utf-8');
70
+ // Check if the errorText contains "200 OK"
71
+ if (errorText.includes('200 OK')) {
72
+ // The request was successful
73
+ console.log('Download successful');
74
+ } else {
75
+ // The request encountered an error
76
+ console.error('Download failed:', errorText);
77
+ throw new Error(`Failed to download image. Error: ${stderr}`);
78
+ }
79
+
80
+ // Convert the downloaded buffer to base64
81
+ const buffer = Buffer.from(stdout);
82
+ const base64 = buffer.toString('base64');
83
+
84
+ // Determine the MIME type and dimensions of the image
85
+ const dimensions = program.image.size(buffer);
86
+ const { width, height, type } = dimensions;
87
+
88
+ // Log the details
89
+ console.log('MIME Type:', type);
90
+ console.log('Dimensions:', `${width}x${height}`);
91
+
92
+ // Now you can use the base64 encoded string
93
+ //console.log('Base64:', base64);
94
+
95
+ // Call the callback with the result
96
+ callback(program,{
97
+ base: base64,
98
+ imageData: dimensions,
99
+ type: type,
100
+ data : data,
101
+ buffer : buffer
102
+ });
103
+
104
+ return true;
105
+ } catch (error) {
106
+ console.error('Error:', error.message);
107
+ return false;
108
+ }
109
+ },
110
+ request : async function(path, body,program,callback) {
111
+ // Make request with url
112
+ console.log(`Make Telegram Get Request`);
113
+ let respData = {}
114
+ const url = `https://api.telegram.org/bot${process.env.telegram}/${path}`;
115
+ // We have url make request
116
+ respData = await program.modules.request.post(program,url,body)
117
+
118
+ if (callback != undefined) {
119
+ return callback(madeRequest);
120
+ } else {
121
+ return respData;
122
+ }
123
+ }
124
+ }
@@ -0,0 +1,59 @@
1
+ module.exports = async function(program,req,res,body,params,command,middleValue) {
2
+ console.log(`Location Telegram Function`);
3
+ // We have the start function
4
+ let locSendMessage = false;
5
+
6
+ // Now get the photos and save them in db files
7
+ // loop through photos
8
+ const user = middleValue.from.id;
9
+ const uuid = program.uuid.v4();
10
+ for (let photoI in middleValue.photo) {
11
+ let photo = middleValue.photo[photoI];
12
+ // photo url user
13
+ const userPhotoURL = await program.modules.telegram.functions.get.file(program,photo.file_id);
14
+ console.log(userPhotoURL);
15
+ // create url
16
+ const photoURL = `https://api.telegram.org/file/bot${process.env.telegram}/${userPhotoURL.result.file_path}`;;
17
+
18
+ //res.status(200);
19
+ // Now do the fetch process thingy
20
+ await program.modules.telegram.functions.get.downloadAndConvertToBase64(program,photoURL,async function(program,response){
21
+ console.log(`We have now file data`);
22
+ // Create id for file that is unique uuid
23
+ const meta = {
24
+ user : response.data.user,
25
+ type : response.imageData.type,
26
+ size : {
27
+ width : response.imageData.width,
28
+ height : response.imageData.height
29
+ }
30
+ }
31
+ await program.modules.data.file.uploadBuffer(program,response.buffer,uuid,meta,async function(progam,upload,meta){
32
+ console.log(`Uploaded Buffer`);
33
+ // Save to membe
34
+ // Now we have received so we can add marker to the receive message
35
+ });
36
+
37
+ },{
38
+ user : user,
39
+ data : middleValue
40
+ });
41
+
42
+ }
43
+
44
+ res.status(200);
45
+
46
+ locSendMessage = `Image succesfull received`;
47
+
48
+ const scripting = await program.modules.telegram.script.function.check(program,command,middleValue.chat.id,middleValue,body);
49
+ console.log(scripting);
50
+
51
+ // Send back
52
+ return {
53
+ message : locSendMessage,
54
+ response : {
55
+ message : locSendMessage,
56
+ uuid : uuid
57
+ }
58
+ }
59
+ }
@@ -76,7 +76,27 @@ module.exports = {
76
76
  }
77
77
  }
78
78
  } else {
79
- console.error(`Need to set anwser data`);
79
+ // Check if something with type:
80
+ for (let li in question.match.data) {
81
+ let matchCheck = question.match.data[li];
82
+ if (typeof matchCheck.anwser == `object`) {
83
+ // Grab type if it's there
84
+ switch (matchCheck.anwser.type) {
85
+ case command:
86
+ console.log(`It's the dynamic thing`);
87
+ matched = matchCheck;
88
+ let variable = data.message[command]
89
+ anwserData = {
90
+ type : command,
91
+ data : variable
92
+ };
93
+ break;
94
+ default:
95
+ console.log(`No matching type found`);
96
+ }
97
+ }
98
+ }
99
+
80
100
  }
81
101
 
82
102
  // End of match process fo matched checking
@@ -132,6 +152,7 @@ module.exports = {
132
152
  // Create replacelist
133
153
  let replace = {
134
154
  "{{URL}}" : process.env.url,
155
+ "{{WEBURL}}" : process.env.webURL,
135
156
  "{{TEST}}" : "TEST REPLACED"
136
157
  }
137
158
 
@@ -15,7 +15,9 @@
15
15
  "function" : "program.modules.bots.scripts.function.response",
16
16
  "next" : "nextFunc"
17
17
  },{
18
- "anwser" : "hi",
18
+ "anwser" : {
19
+ "type" : "photo"
20
+ },
19
21
  "function" : "program.modules.bots.scripts.function.response",
20
22
  "next" : "nextFunc"
21
23
  }]
@@ -31,7 +33,7 @@
31
33
  "text" : "Testing Title : {{START}}",
32
34
  "buttons" : [
33
35
  [
34
- { "text": "EventGO!", "web_app" : { "url" : "{{URL}}events/list"}},
36
+ { "text": "EventGO!", "web_app" : { "url" : "{{WEBURL}}concepts/eventgo/events-list"}},
35
37
  { "text": "Create Event", "callback_data": "create_event" }
36
38
  ]
37
39
  ]
@@ -0,0 +1,38 @@
1
+ const { MongoClient } = require('mongodb');
2
+ const uri = process.env.mongo;
3
+ const client = new MongoClient(uri);
4
+
5
+ module.exports = {
6
+ profilePhoto : async function(program,content,meta) {
7
+ console.log(`Set User Profile Pic`);
8
+ const added = await program.modules.telegram.functions.set.addToCollection(program,`telegram`, `profileImage`, meta.name,{
9
+ id : meta.user
10
+ });
11
+ console.log(`Added`);
12
+ },
13
+ addToCollection : async function (program,collectionName, fieldName, data,search) {
14
+ try {
15
+ await client.connect();
16
+ const db = client.db('eventgo');
17
+ const collection = db.collection(collectionName);
18
+
19
+ // Check if the field is an array in the existing document
20
+ const existingDocument = await collection.findOne(search);
21
+ const isFieldArray = Array.isArray(existingDocument[fieldName]);
22
+
23
+ if (isFieldArray) {
24
+ // Field is an array, push the data
25
+ await collection.updateOne({}, { $addToSet: { [fieldName]: { $each: data } } });
26
+ } else {
27
+ // Field is not an array, save the array
28
+ await collection.updateOne({}, { $set: { [fieldName]: data } }, { upsert: true });
29
+ }
30
+
31
+ console.log('Data added to the collection successfully.');
32
+ } catch (error) {
33
+ console.error('Error:', error.message);
34
+ } finally {
35
+ await client.close();
36
+ }
37
+ }
38
+ }
@@ -48,8 +48,13 @@ module.exports = async function(program,folder) {
48
48
  id : middleValue.chat.id
49
49
  },middleValue.chat);
50
50
  let typeOFF = typeof user;
51
- if (middleValue.chat.uuid == user.uuid) {
51
+ if (middleValue.chat.uuid == user.uuid || user.profileImage == undefined) {
52
52
  user.new = true;
53
+
54
+ // do the process for downloading the users profile image
55
+ console.log(`Process Image`);
56
+ //getUserProfilePhotos
57
+ program.modules.telegram.functions.get.UserProfilePhotos(program,user);
53
58
  }
54
59
 
55
60
  middleValue.chat.uuid = user.uuid;
@@ -202,7 +207,7 @@ module.exports = async function(program,folder) {
202
207
  } catch (message) {
203
208
  // Process as other
204
209
  console.log(`Process Different`);
205
- let checkArray = [`location`];
210
+ let checkArray = [`location`,`photo`];
206
211
  // Loop through checkArray
207
212
  for (let c in checkArray) {
208
213
  const command = checkArray[c];
@@ -210,7 +215,7 @@ module.exports = async function(program,folder) {
210
215
  if (indexCheck != -1) {
211
216
  console.log(`Run this as middleware`);
212
217
  try {
213
- const runFunc = await program.modules.telegram.middleware[key][command](req,res,body,params,command,middleValue);
218
+ const runFunc = await program.modules.telegram.middleware[key][command](program,req,res,body,params,command,middleValue);
214
219
  const respFunc = runFunc;
215
220
  // PRocess response for object
216
221
  if (respFunc == undefined) {
@@ -351,7 +356,7 @@ module.exports = async function(program,folder) {
351
356
  int : {}
352
357
  }
353
358
  for (let scriptIndex in scriptsData) {
354
- let script = [scriptIndex];
359
+ let script = scriptsData[scriptIndex];
355
360
  // We now have the specific script check if folder
356
361
  if (!script.extension) {
357
362
  // It's folder create the function and read folder
@@ -0,0 +1,60 @@
1
+ const { MongoClient, GridFSBucket } = require('mongodb');
2
+ const fs = require('fs');
3
+
4
+ // Define the MongoDB URI
5
+ const uri = process.env.mongo;
6
+ const client = new MongoClient(uri);
7
+
8
+ module.exports = {
9
+ uploadBuffer: async function (progam,buffer, filename, metadata = {}, callback) {
10
+ const dbName = 'eventgo';
11
+ await client.connect();
12
+
13
+ const db = client.db(dbName);
14
+ const bucket = new GridFSBucket(db);
15
+
16
+ const uploadStream = bucket.openUploadStream(filename, { metadata });
17
+
18
+ uploadStream.end(buffer); // Write the buffer directly to the upload stream
19
+
20
+ new Promise((resolve, reject) => {
21
+ uploadStream.on('finish', () => {
22
+ // Access the ObjectId assigned to the stored file
23
+ const fileId = uploadStream.id;
24
+ let objectID = resolve(fileId);
25
+ console.log(`File ID hing`);
26
+ metadata.name = filename;
27
+ callback(progam,uploadStream,metadata);
28
+ });
29
+
30
+ uploadStream.on('error', reject);
31
+ });
32
+ },
33
+
34
+ downloadBuffer: async function (filename, dbName = 'media') {
35
+ await client.connect();
36
+
37
+ const db = client.db(dbName);
38
+ const bucket = new GridFSBucket(db);
39
+
40
+ const downloadStream = bucket.openDownloadStreamByName(filename);
41
+
42
+ return new Promise((resolve, reject) => {
43
+ const chunks = [];
44
+
45
+ // Accumulate chunks as they arrive
46
+ downloadStream.on('data', (chunk) => {
47
+ chunks.push(chunk);
48
+ });
49
+
50
+ // Resolve with the concatenated buffer and metadata when the download is complete
51
+ downloadStream.on('end', () => {
52
+ const buffer = Buffer.concat(chunks);
53
+ const metadata = downloadStream.s.file.metadata;
54
+ resolve({ buffer, metadata });
55
+ });
56
+
57
+ downloadStream.on('error', reject);
58
+ });
59
+ }
60
+ };
@@ -18,7 +18,7 @@ module.exports = function(db,collection) {
18
18
 
19
19
  async function main() {
20
20
  // Create a new MongoClient
21
- const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
21
+ const client = new MongoClient(uri);
22
22
 
23
23
  try {
24
24
  // Connect to the MongoDB server
@@ -36,7 +36,7 @@ module.exports = function(db,collection) {
36
36
 
37
37
  // Process the result
38
38
  console.log('Query result:', result);
39
-
39
+ return result;
40
40
  } finally {
41
41
  // Close the MongoClient
42
42
  await client.close();
@@ -0,0 +1,57 @@
1
+ const { MongoClient } = require('mongodb');
2
+
3
+ module.exports = async function (db, collection, condition, dataToUpdate) {
4
+ // Ensure the MongoDB connection string is provided
5
+ if (!process.env.mongo) {
6
+ console.error('MongoDB connection string not provided. Set process.env.mongo.');
7
+ process.exit(1);
8
+ }
9
+
10
+ // Define the MongoDB URI
11
+ const uri = process.env.mongo;
12
+
13
+ // Define the database and collection name
14
+ const dbName = db;
15
+ const collectionName = collection;
16
+
17
+ async function main() {
18
+ // Create a new MongoClient
19
+ const client = new MongoClient(uri);
20
+
21
+ try {
22
+ // Connect to the MongoDB server
23
+ await client.connect();
24
+ console.log('Connected to the MongoDB server');
25
+
26
+ // Select the database
27
+ const database = client.db(dbName);
28
+
29
+ // Select the collection
30
+ const collection = database.collection(collectionName);
31
+
32
+ // Perform the update or create operation
33
+ const result = await collection.updateOne(condition, { $set: dataToUpdate }, { upsert: true });
34
+
35
+ // If a document was upserted, retrieve the upserted document
36
+ const upsertedDocument = result.upsertedId
37
+ ? await collection.findOne({ _id: result.upsertedId })
38
+ : null;
39
+
40
+ // Process the result
41
+ if (upsertedDocument) {
42
+ console.log('Document upserted:', upsertedDocument);
43
+ return upsertedDocument;
44
+ } else {
45
+ console.log('Document updated.');
46
+ return dataToUpdate;
47
+ }
48
+ } finally {
49
+ // Close the MongoClient
50
+ await client.close();
51
+ console.log('Connection closed.');
52
+ }
53
+ }
54
+
55
+ // Execute the main function
56
+ return main().catch(console.error);
57
+ };
@@ -1,178 +1,285 @@
1
1
  module.exports = async function (program) {
2
- console.log(`Starting UP Express`);
3
- program.express = {
2
+ console.log(`Starting UP Express`);
3
+ program.express = {
4
4
  ts: Date.now(),
5
- };
6
-
7
- const express = require('express');
8
- const cors = require('cors');
9
- const bodyParser = require('body-parser');
10
- const port = 1221;
11
- const basePath = `/api`;
12
-
13
- const app = express();
14
-
15
- const corsOptions = {
5
+ };
6
+
7
+ const express = require('express');
8
+ const cors = require('cors');
9
+ const bodyParser = require('body-parser');
10
+ const WebSocket = require('ws');
11
+ const crypto = require(`crypto`)
12
+ const port = 1221;
13
+ const basePath = `/api`;
14
+
15
+ const app = express();
16
+
17
+ const corsOptions = {
16
18
  origin: '*',
17
19
  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
18
20
  credentials: true,
19
21
  optionsSuccessStatus: 204,
20
- };
21
-
22
- app.use(cors(corsOptions));
23
- app.use(bodyParser.json());
24
- app.use(bodyParser.urlencoded({ extended: true }));
25
- app.set('view engine', 'ejs');
26
-
27
- let routesPath = program.path.join(__dirname, `routes`);
28
- // Check if custom routes path
29
- if (program.set.path != undefined) {
30
- routesPath = program.path.join(program.set.path,`routes`);
31
- }
22
+ };
32
23
 
33
- let exprs = {};
34
-
35
- try {
24
+ app.use(cors(corsOptions));
25
+ app.use(bodyParser.json());
26
+ app.use(bodyParser.urlencoded({ extended: true }));
27
+ app.set('view engine', 'ejs');
28
+
29
+ let routesPath = program.path.join(__dirname, `routes`);
30
+ // Check if custom routes path
31
+ if (program.set.path != undefined) {
32
+ routesPath = program.path.join(program.set.path, `routes`);
33
+ }
34
+
35
+ let exprs = {};
36
+
37
+ try {
36
38
  let routesData = await program.modules.walkDirectory(routesPath);
37
-
39
+
38
40
  for (let routeData of routesData) {
39
- let routePath = `${basePath}/${routeData.name}`;
40
-
41
- const split = routeData.name.split('.');
42
- routeData.type = split.length > 1 ? split[split.length - 1] : 'get';
43
- routeData.name = split.length > 1 ? split[0] : routeData.name;
44
-
45
- const routeID = program.uuid.v4();
46
- routeData.tempID = routeID;
47
-
48
- try {
49
- const stats = await program.fs.statSync(routeData.path);
50
- const isDirectory = stats.isDirectory();
51
-
52
- if (isDirectory) {
53
- for (let subData of routeData.sub) {
54
- if (subData !== undefined) {
55
- const routeName = subData.name.replace('.get', '').replace('.post', '');
56
- const subDataSplit = subData.path.split('.');
57
- const type = subDataSplit[subDataSplit.length - 2];
58
-
59
- subData.name = routeName;
60
- delete subData.sub;
61
- subData.type = type;
62
-
63
- subData.func = require(subData.path);
64
- exprs[routePath + '/' + routeName] = subData;
41
+ let routePath = `${basePath}/${routeData.name}`;
42
+
43
+ const split = routeData.name.split('.');
44
+ routeData.type = split.length > 1 ? split[split.length - 1] : 'get';
45
+ routeData.name = split.length > 1 ? split[0] : routeData.name;
46
+
47
+ const routeID = program.uuid.v4();
48
+ routeData.tempID = routeID;
49
+
50
+ try {
51
+ const stats = await program.fs.statSync(routeData.path);
52
+ const isDirectory = stats.isDirectory();
53
+
54
+ if (isDirectory) {
55
+ for (let subData of routeData.sub) {
56
+ if (subData !== undefined) {
57
+ const routeName = subData.name.replace('.get', '').replace('.post', '');
58
+ const subDataSplit = subData.path.split('.');
59
+ const type = subDataSplit[subDataSplit.length - 2];
60
+
61
+ subData.name = routeName;
62
+ delete subData.sub;
63
+ subData.type = type;
64
+
65
+ subData.func = require(subData.path);
66
+ exprs[routePath + '/' + routeName] = subData;
67
+ }
68
+ }
69
+ } else {
70
+ routeData.func = require(routeData.path);
71
+ exprs[routePath] = routeData;
65
72
  }
66
- }
67
- } else {
68
- routeData.func = require(routeData.path);
69
- exprs[routePath] = routeData;
73
+ } catch (err) {
74
+ console.error(`Error Route Func`, routePath);
75
+ console.error(err);
70
76
  }
71
- } catch (err) {
72
- console.error(`Error Route Func`, routePath);
73
- console.error(err);
74
- }
75
-
76
- routeData.webwalk = 0;
77
+
78
+ routeData.webwalk = 0;
77
79
  }
78
-
80
+
79
81
  program.express.routes = exprs;
80
-
82
+
81
83
  for (let route in exprs) {
82
- let routeData = exprs[route];
83
- let state = false;
84
-
85
- try {
86
- app[routeData.type](route, async (req, res) => {
87
- try {
88
- exprs[route].webwalk++;
84
+ let routeData = exprs[route];
85
+ let state = false;
86
+
87
+ try {
88
+ app[routeData.type](route, async (req, res) => {
89
+ try {
90
+ exprs[route].webwalk++;
89
91
 
90
- // Get body
91
- const requestBody = req.body;
92
- const reqParams = req.params;
92
+ // Get body
93
+ const requestBody = req.body;
94
+ const reqParams = req.params;
93
95
 
94
- await routeData.func(program, req, res, route,requestBody,reqParams);
95
- } catch (err) {
96
- console.error(`Error With Route:`, route);
96
+ await routeData.func(program, req, res, route, requestBody, reqParams);
97
+ } catch (err) {
98
+ console.error(`Error With Route:`, route);
99
+ console.error(err);
100
+ }
101
+ });
102
+ state = true;
103
+ } catch (err) {
97
104
  console.error(err);
98
- }
99
- });
100
- state = true;
101
- } catch (err) {
102
- console.error(err);
103
- console.error(`Error Setting Up Route`);
104
- }
105
-
106
- exprs[route].state = state;
105
+ console.error(`Error Setting Up Route`);
106
+ }
107
+
108
+ exprs[route].state = state;
107
109
  }
108
-
110
+
109
111
  console.log(`Routes are set up successfully`);
110
- } catch (err) {
112
+ } catch (err) {
111
113
  console.error(err);
112
114
  console.error(`Error Setting Up Routes`);
113
- }
114
-
115
- program.express.app = app;
115
+ }
116
116
 
117
- // Let app listen for content
118
- app.get(`/app/content/ton/manifest.json`,async (req,res) => {
117
+ program.express.app = app;
118
+
119
+ // Let app listen for content
120
+ app.get(`/app/content/ton/manifest.json`, async (req, res) => {
119
121
  // Let's create a json
120
122
  const manifest = {
121
- url: process.env.url,
122
- name: process.env.name,
123
- iconUrl: process.env.image
123
+ url: process.env.url,
124
+ name: process.env.name,
125
+ iconUrl: process.env.image
124
126
  };
125
-
127
+
126
128
  res.setHeader('Content-Type', 'application/json');
127
129
  res.json(manifest);
128
- });
130
+ });
129
131
 
130
- app.get(`/app/content/:type/:file`,async (req,res) => {
131
- console.log(`Content Get`);
132
- // Try To get file from content folder
133
- try {
134
- const filePath = program.path.join(__dirname,`..`,`..`,`app`,`content`,req.params.type,req.params.file);
135
- let contentFolder = filePath;
136
-
137
- // Check if minify at the end
138
- const fileName = req.params.file;
139
- const isMinified = /-min\.js$/.test(fileName);
140
-
141
- if (isMinified) {
142
- console.log(`${fileName} ends with -min.js`);
143
- const toRequestFile = req.params.file.replace(`-min.js`,`.js`);
144
- contentFolder = program.path.join(__dirname,`..`,`..`,`app`,`content`,req.params.type,toRequestFile);
145
- } else {
146
- console.log(`${fileName} does not end with -min.js`);
147
- }
132
+ app.get(`/app/content/:type/:file`, async (req, res) => {
133
+ console.log(`Content Get`);
134
+ // Try To get file from content folder
135
+ try {
136
+ const filePath = program.path.join(__dirname, `..`, `..`, `app`, `content`, req.params.type, req.params.file);
137
+ let contentFolder = filePath;
148
138
 
149
- res.sendFile(contentFolder);
150
- } catch (err) {
151
- console.error(err);
152
- console.error(`Error Getting : ${req.params.type}`,req.params.file);
153
- }
154
- })
139
+ // Check if minify at the end
140
+ const fileName = req.params.file;
141
+ const isMinified = /-min\.js$/.test(fileName);
155
142
 
156
- app.listen(port, () => {
143
+ if (isMinified) {
144
+ console.log(`${fileName} ends with -min.js`);
145
+ const toRequestFile = req.params.file.replace(`-min.js`, `.js`);
146
+ contentFolder = program.path.join(__dirname, `..`, `..`, `app`, `content`, req.params.type, toRequestFile);
147
+ } else {
148
+ console.log(`${fileName} does not end with -min.js`);
149
+ }
150
+
151
+ res.sendFile(contentFolder);
152
+ } catch (err) {
153
+ console.error(err);
154
+ console.error(`Error Getting : ${req.params.type}`, req.params.file);
155
+ }
156
+ })
157
+
158
+ app.listen(port, () => {
157
159
  console.log(`Server Listening`, port, basePath);
158
- });
159
-
160
- program.express.url = {
160
+ });
161
+
162
+ program.express.url = {
161
163
  adaptive: {
162
- get: [],
163
- post: [],
164
+ get: [],
165
+ post: [],
164
166
  },
165
167
  set: function (requestPath, actionType, callback) {
166
- program.express.url.adaptive[actionType] = app[actionType](requestPath, async (req, res) => {
167
- let run = await callback(req, res, req.body, req.params);
168
- return run;
169
- });
170
- return true;
168
+ program.express.url.adaptive[actionType] = app[actionType](requestPath, async (req, res) => {
169
+ let run = await callback(req, res, req.body, req.params);
170
+ return run;
171
+ });
172
+ return true;
171
173
  },
172
- };
173
-
174
- program.express.setted = true;
175
-
176
- return program;
177
174
  };
178
-
175
+
176
+ program.express.setted = true;
177
+
178
+ let clients = new Map();
179
+ // Start socket thingy
180
+ const PORT = process.env.socket || 3000;
181
+ const wss = new WebSocket.Server({ port: PORT });
182
+
183
+
184
+ wss.on('connection', (ws, req) => {
185
+ console.log(`Socket Connected`);
186
+
187
+ // Generate a unique ID for the WebSocket connection
188
+ const clientId = program.uuid.v4();
189
+ const reqURL = req.url;
190
+ console.log(`We have some data`, reqURL);
191
+ const queryStringWithoutQBT = reqURL.replace('/socket.io/?qbt=', '');
192
+ const queryParamsArray = queryStringWithoutQBT.split('&');
193
+
194
+ const parsedQuery = queryParamsArray.reduce((acc, param) => {
195
+ const [key, value] = param.split('=');
196
+ acc[key] = decodeURIComponent(value);
197
+ return acc;
198
+ }, {});
199
+
200
+ // Extract data from the parsed query
201
+ const { auth_date, query_id, user, hash } = parsedQuery;
202
+
203
+ // Stringify the 'user' field if it contains JSON data
204
+ if (user != undefined) {
205
+ try {
206
+ parsedQuery.user = JSON.stringify(parsedQuery.user);
207
+ } catch (error) {
208
+ console.error('Error parsing JSON in user field:', error);
209
+ }
210
+ }
211
+
212
+ // Construct the data check string
213
+ const sortedKeys = Object.keys(parsedQuery).sort();
214
+ const data_check_string = sortedKeys.map(key => `${key}=${String(parsedQuery[key])}`).join('\n');
215
+
216
+ function HMAC_SHA256(data, key) {
217
+ const hmac = crypto.createHmac('sha256', key);
218
+ hmac.update(data);
219
+ return hmac.digest('hex');
220
+ }
221
+
222
+ const bot_token = process.env.telegram; // replace with your actual bot token
223
+ const secret_key = HMAC_SHA256(bot_token, 'WebAppData');
224
+ const calculated_hash = HMAC_SHA256(data_check_string, secret_key);
225
+
226
+ const received_hash = hash; // replace with the actual received hash
227
+
228
+ if (calculated_hash === received_hash) {
229
+ // Data is from Telegram and has not been tampered with
230
+ // Additional check for auth_date if needed
231
+ const currentUnixTimestamp = Math.floor(new Date().getTime() / 1000);
232
+ if (parseInt(auth_date, 10) <= currentUnixTimestamp) {
233
+ // Data is not outdated
234
+ // Use the validated data as needed
235
+ console.log('Data from Telegram is valid');
236
+ } else {
237
+ console.error('Received data is outdated');
238
+ }
239
+ } else {
240
+ console.error('Received data has been tampered with');
241
+ }
242
+
243
+ console.log(parsedQuery);
244
+
245
+ // Store the WebSocket connection with its ID in the map
246
+ clients.set(clientId, ws);
247
+
248
+ // Send the client ID to the connected client
249
+ ws.send(JSON.stringify({ type: 'clientId', id: clientId, params: parsedQuery }));
250
+
251
+ // Set up a ping interval to keep the connection alive
252
+ const pingInterval = setInterval(() => {
253
+ if (ws.readyState === WebSocket.OPEN) {
254
+ ws.ping();
255
+ } else {
256
+ // If the connection is closed, remove it from the map
257
+ clearInterval(pingInterval);
258
+ clients.delete(clientId);
259
+ console.log(`Removed disconnected socket with ID: ${clientId}`);
260
+ }
261
+ }, 5000); // Adjust the interval as needed
262
+
263
+ ws.on('close', () => {
264
+ console.log(`Socket Disconnected`);
265
+ clearInterval(pingInterval);
266
+ clients.delete(clientId);
267
+ });
268
+
269
+ // WebSocket on message event
270
+ ws.on('message', (message) => {
271
+ console.log(`Received message from ${clientId}: ${message}`);
272
+
273
+ // Add your custom on message logic here
274
+ // For example, you can broadcast the message to all connected clients
275
+ clients.forEach((client, id) => {
276
+ if (client.readyState === WebSocket.OPEN && id !== clientId) {
277
+ client.send(`Broadcast from ${clientId}: ${message}`);
278
+ }
279
+ });
280
+ });
281
+ });
282
+
283
+
284
+ return program;
285
+ };
@@ -1,12 +1,13 @@
1
1
  module.exports = async function(program,req,res,route) {
2
2
  console.log(`Create`);
3
- const fullPath = program.path.join(__dirname, `..`,`..`,`..`,`..`,`ejs`,`example`,`list.ejs`);
3
+ const fullPath = program.path.join(__dirname, `..`,`..`,`..`,`..`,`ejs`,`view`,`list.ejs`);
4
4
 
5
5
  // Render the EJS template
6
6
  res.render(fullPath, {
7
7
  title: 'EJS Example',
8
8
  name: 'John Doe',
9
9
  isAdmin: true,
10
- fruits: ['Apple', 'Banana', 'Orange']
10
+ fruits: ['Apple', 'Banana', 'Orange'],
11
+ url : process.env.url
11
12
  });
12
13
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "webfast",
3
- "version": "0.1.31",
4
- "description": "WebFast! Bot Application, including TON mini-apps",
3
+ "version": "0.1.35",
4
+ "description": "WebFast! Bot Application, including TON mini-apps for makign it easy and fast to build ini-apps",
5
5
  "main": "index.js",
6
6
  "repository": {
7
7
  "type": "git",
@@ -39,15 +39,18 @@
39
39
  "dependencies": {
40
40
  "body-parser": "^1.20.2",
41
41
  "cors": "^2.8.5",
42
+ "crypto": "^1.0.1",
42
43
  "dotenv": "^16.0.3",
43
44
  "ejs": "^3.1.9",
44
45
  "express": "^4.18.2",
45
46
  "fetch": "^1.1.0",
46
47
  "fs": "^0.0.1-security",
48
+ "image-size": "^1.1.1",
47
49
  "js": "^0.1.0",
48
50
  "mongodb": "^6.3.0",
49
51
  "node-fetch": "^3.3.2",
50
52
  "path": "^0.12.7",
51
- "uuid": "^9.0.1"
53
+ "uuid": "^9.0.1",
54
+ "ws": "^8.16.0"
52
55
  }
53
56
  }