webfast 0.1.31 → 0.1.35

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }