Raybilhelp commited on
Commit
6249eb8
·
verified ·
1 Parent(s): c0fe8c3

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +102 -118
app.js CHANGED
@@ -1,126 +1,110 @@
1
- const express = require('express');
2
- const admin = require('firebase-admin');
3
-
4
- const app = express();
5
- app.use(express.json());
6
-
7
- // ==========================================
8
- // ১. য়ারবেজ সেটআপ (Environment Variable থেকে)
9
- // ==========================================
10
- // Hugging Face-এর Secrets FIREBASE_ADMIN JSON স্ট্রিং হিসেবে সেভ করা থাকতে হবে
11
- // এবং FIREBASE_DB_URL নামে ডাটাবেজ লিংকটি রাখতে হবে।
12
- const serviceAccount = JSON.parse(process.env.FIREBASE_ADMIN);
13
-
14
- admin.initializeApp({
15
- credential: admin.credential.cert(serviceAccount),
16
- databaseURL: process.env.FIREBASE_DB_URL // উদাহরণ: "https://your-project.firebaseio.com"
17
- });
18
- const db = admin.database();
19
-
20
- // ==========================================
21
- // ২. হেলথ চেক রাউটস (যেকোনো রিকোয়েস্ট)
22
- // ==========================================
23
- const healthHandler = (req, res) => {
24
- res.send('Ok yes done');
25
- };
26
- app.all('/health', healthHandler);
27
- app.all('/check', healthHandler);
28
- app.all('/unps', healthHandler);
29
-
30
- // ==========================================
31
- // ৩. মূল কাজের পাথগুলো
32
- // ==========================================
33
- const pathGroup1 = ['/link-visit'];
34
- const pathGroup2 = ['/adsgram-1', '/adsgram-2', '/gigapub-1', '/gigapub-2', '/monetag-1', '/monetag-2', '/add-account'];
35
- const allActionPaths = [...pathGroup1, ...pathGroup2];
36
-
37
- // শুধুমাত্র POST রিকোয়েস্ট পারমিট করার মিডলওয়্যার
38
- app.use(allActionPaths, (req, res, next) => {
39
- if (req.method !== 'POST') {
40
- return res.status(405).json({ error: 'Method Not Allowed. Only POST is accepted.' });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
- next();
43
- });
44
 
45
- // ==========================================
46
- // ৪. Cloudflare Turnstile ভ্যালিডেশন মিডলওয়্যার
47
- // ==========================================
48
- const verifyCloudflare = async (req, res, next) => {
49
- // ক্লায়েন্ট থেকে আসা টোকেন (ধরে নিচ্ছি বডিতে 'cf_token' নামে আসবে)
50
- const token = req.body.cf_token;
51
- if (!token) return res.status(403).json({ error: 'Cloudflare token is missing' });
52
 
53
  try {
54
- const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
55
- method: 'POST',
56
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
57
- body: `secret=${process.env.CLOUDFLIRE_CHECK}&response=${token}`
58
- });
59
-
60
- const data = await response.json();
61
- if (data.success) {
62
- next(); // ভ্যালিশন সফল, ের পে
63
- } else {
64
- return res.status(403).json({ error: 'Cloudflare verification failed' });
65
- }
66
- } catch (error) {
67
- return res.status(500).json({ error: 'Server error during Cloudflare verification' });
68
- }
69
- };
70
-
71
- // ==========================================
72
- // ৫. ডাটা প্রসেসিং এবং ফায়ারবেজে সেভ করা
73
- // ==========================================
74
- app.post(allActionPaths, verifyCloudflare, async (req, res) => {
75
- const { user_id, action, 'action_type-1': balance, 'action_type-2': stock } = req.body;
76
-
77
- // ভ্যালিডেশন: ইউজার আইডি এবং অ্যাকশন চেক
78
- if (!user_id || !action) {
79
- return res.status(400).json({ error: 'Missing user_id or action' });
80
- }
81
 
82
- // ভ্যালিডেশন: ডাটা ডিলিট করার রিকোয়েস্ট বাতিল
83
- if (action.toLowerCase().includes('delete') || action.toLowerCase() !== 'add') {
84
- return res.status(400).json({ error: 'Invalid action. Only "add" is allowed.' });
85
- }
86
-
87
- const currentPath = req.path; // যেমন: '/link-visit'
88
-
89
- // ভ্যালিডেশন: ফিক্সড ব্যালেন্স এবং স্টক চেক
90
- if (pathGroup1.includes(currentPath)) {
91
- if (Number(balance) !== 0.05 || stock !== '+1') {
92
- return res.status(400).json({ error: 'Invalid balance or stock for this path. Expected 0.05 and +1.' });
93
- }
94
- } else if (pathGroup2.includes(currentPath)) {
95
- if (Number(balance) !== 0.06 || stock !== '+1') {
96
- return res.status(400).json({ error: 'Invalid balance or stock for this path. Expected 0.06 and +1.' });
97
- }
98
- }
99
-
100
- // ফায়ারবেজে ডাটা সেভ করা
101
- try {
102
- // ফায়ারবেজে রিকোয়েস্টের পাথের নামেই ডাটা সেভ হবে (যেমন: /link-visit/user_id/...)
103
- const dbRef = db.ref(currentPath).child(user_id);
104
-
105
- const newData = {
106
- action: action,
107
- balance: Number(balance),
108
- stock: stock,
109
- timestamp: admin.database.ServerValue.TIMESTAMP
110
- };
111
-
112
- // ইউজারের নোডের আন্ডারে নতুন ডাটা পুশ করা হলো
113
- await dbRef.push(newData);
114
-
115
- res.status(200).json({ message: 'Success! Data saved to Firebase.', path: currentPath });
116
  } catch (error) {
117
- console.error('Firebase Error:', error);
118
- res.status(500).json({ error: 'Failed to save data to Firebase' });
 
 
119
  }
120
- });
121
 
122
- // সার্ভার স্টার্ট
123
- const PORT = process.env.PORT || 7860; // Hugging Face Space ডিফল্টভাবে 7860 পোর্ট ব্যবহার করে
124
- app.listen(PORT, () => {
125
- console.log(`Server is running on port ${PORT}`);
126
- });
 
1
+ import express from 'express';
2
+ import admin from 'firebase-admin';
3
+ import cluster from 'cluster';
4
+ import os from 'os';
5
+
6
+ const totalCpus = os.cpus().length;
7
+
8
+ // --- ল্টি-কোর ক্লস্টার সেটআপ ---
9
+ if (cluster.isPrimary) {
10
+ console.log(`Primary Master Process ${process.pid} is running`);
11
+
12
+ // প্রতিটি CPU কোরের জন্য একটি করে ওয়ার্কার প্রসেস তৈরি হবে
13
+ for (let i = 0; i < totalCpus; i++) {
14
+ cluster.fork();
15
+ }
16
+
17
+ cluster.on('exit', (worker) => {
18
+ console.log(`Worker ${worker.process.pid} died. Forking a new one...`);
19
+ cluster.fork();
20
+ });
21
+
22
+ } else {
23
+ // ওয়ার্কার প্রসেস - যা মূল API হ্যান্ডেল করবে
24
+ const app = express();
25
+ app.use(express.json());
26
+
27
+ const PORT = process.env.PORT || 7860;
28
+ const BOT_TOKEN = process.env.BOT_TOKEN;
29
+
30
+ // --- ফায়ারবেস এডমিন ১ ও ২ ইনিশিয়ালাইজেশন ---
31
+ let app1, app2;
32
+ try {
33
+ const firebaseAdmin1 = JSON.parse(process.env.FIREBASE_ADMIN_1 || '{}');
34
+ const firebaseAdmin2 = JSON.parse(process.env.FIREBASE_ADMIN_2 || '{}');
35
+
36
+ app1 = admin.initializeApp({
37
+ credential: admin.credential.cert(firebaseAdmin1),
38
+ databaseURL: process.env.FB_DB_1
39
+ }, 'app1');
40
+
41
+ app2 = admin.initializeApp({
42
+ credential: admin.credential.cert(firebaseAdmin2),
43
+ databaseURL: process.env.FB_DB_2
44
+ }, 'app2');
45
+
46
+ console.log(`Worker ${process.pid} connected to Firebase.`);
47
+ } catch (error) {
48
+ console.error('Firebase initialization error:', error.message);
49
+ }
50
+
51
+ // --- ডাটা ভ্যালিডেশন ফাংশন (একই ফাইলে) ---
52
+ function verifyIntegrity(intdata, uid, fullName) {
53
+ if (!intdata || !uid || !fullName) return false;
54
+
55
+ // আপনার আইডিয়া অনুযায়ী BOT_TOKEN এবং intdata ম্যাচিং বা ডিক্রিপশন লজিক এখানে হবে
56
+ // সাময়িকভাবে ভ্যালিডেশন পাস করানোর জন্য true দেওয়া হলো
57
+ return true;
58
+ }
59
+
60
+ // --- এপিআই এন্ডপয়েন্ট সমূহ ---
61
+
62
+ // ১. /health এন্ডপয়েন্ট (যেকোনো মেথড আসলে জাস্ট ওকে ব্যাক করবে)
63
+ app.all('/health', (req, res) => {
64
+ res.status(200).json({ status: "OK", message: "Server is healthy" });
65
+ });
66
+
67
+ // ২. /profile পোস্ট রিকোয়েস্ট এন্ডপয়েন্ট
68
+ app.post('/profile', async (req, res) => {
69
+ const { intdata, uid, full_name } = req.body;
70
+
71
+ // টোকেন ও ডাটা ভ্যালিডেশন চেক
72
+ if (!verifyIntegrity(intdata, uid, full_name)) {
73
+ return res.status(400).json({ error: "Bad Request: Integrity check failed" });
74
  }
 
 
75
 
76
+ let responseData = {};
 
 
 
 
 
 
77
 
78
  try {
79
+ // লজিক ১: FIREBASE_ADMIN_1 থেকে database/withdraw/{uid} আনা
80
+ const db1 = admin.database(app1);
81
+ const snapshot1 = await db1.ref(`database/withdraw/${uid}`).once('value');
82
+
83
+ if (snapshot1.exists()) {
84
+ responseData.withdraw = snapshot1.val();
85
+ }
86
+
87
+ // িক ২: FIREBASE_ADMIN_2 থকে user/{uid} সব ডটা আন
88
+ const db2 = admin.database(app2);
89
+ const snapshot2 = await db2.ref(`user/${uid}`).once('value');
90
+
91
+ responseData.user_info = snapshot2.exists() ? snapshot2.val() : {};
92
+
93
+ // ফাইনাল রেসপন্স পাঠানো
94
+ return res.status(200).json({
95
+ status: "success",
96
+ data: responseData
97
+ });
 
 
 
 
 
 
 
 
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  } catch (error) {
100
+ return res.status(500).json({
101
+ error: "Internal Server Error",
102
+ details: error.message
103
+ });
104
  }
105
+ });
106
 
107
+ app.listen(PORT, () => {
108
+ console.log(`Worker ${process.pid} listening on port ${PORT}`);
109
+ });
110
+ }