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.
- package/app/content/js/webfast.js +39 -1
- package/ejs/collect/event.ejs +2 -2
- package/ejs/view/list.ejs +6 -1
- package/example.js +5 -0
- package/index.js +31 -13
- package/modules/bots/applications/telegram/get.js +124 -0
- package/modules/bots/applications/telegram/middleware/message/photo.js +59 -0
- package/modules/bots/applications/telegram/que.js +22 -1
- package/modules/bots/applications/telegram/scripts/test/script.json +4 -2
- package/modules/bots/applications/telegram/set.js +38 -0
- package/modules/bots/applications/telegram.js +9 -4
- package/modules/data/mongo/file.js +60 -0
- package/modules/data/mongo/find.js +2 -2
- package/modules/data/mongo/updateOrCreate.js +57 -0
- package/modules/express/init.js +249 -142
- package/modules/express/routes/view/list.get.js +3 -2
- package/package.json +6 -3
@@ -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
|
+
});
|
package/ejs/collect/event.ejs
CHANGED
@@ -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
|
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
|
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
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]
|
13
|
+
program.set[key]=array[key]
|
15
14
|
}
|
16
15
|
|
17
16
|
// Setup The Requirements
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
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
|
-
|
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" :
|
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" : "{{
|
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
|
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
|
+
};
|
package/modules/express/init.js
CHANGED
@@ -1,178 +1,285 @@
|
|
1
1
|
module.exports = async function (program) {
|
2
|
-
|
3
|
-
|
2
|
+
console.log(`Starting UP Express`);
|
3
|
+
program.express = {
|
4
4
|
ts: Date.now(),
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
68
|
-
|
69
|
-
exprs[routePath] = routeData;
|
73
|
+
} catch (err) {
|
74
|
+
console.error(`Error Route Func`, routePath);
|
75
|
+
console.error(err);
|
70
76
|
}
|
71
|
-
|
72
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
92
|
+
// Get body
|
93
|
+
const requestBody = req.body;
|
94
|
+
const reqParams = req.params;
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
101
|
-
|
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
|
-
|
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
|
-
|
118
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
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
|
-
|
160
|
+
});
|
161
|
+
|
162
|
+
program.express.url = {
|
161
163
|
adaptive: {
|
162
|
-
|
163
|
-
|
164
|
+
get: [],
|
165
|
+
post: [],
|
164
166
|
},
|
165
167
|
set: function (requestPath, actionType, callback) {
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
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`,`
|
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.
|
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
|
}
|