Hans-Tz commited on
Commit
8873b82
Β·
verified Β·
1 Parent(s): aacdb17

Upload server.js

Browse files
Files changed (1) hide show
  1. server.js +417 -0
server.js ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from "express";
2
+ import dotenv from "dotenv";
3
+ import axios from "axios";
4
+ import { Buffer } from "buffer";
5
+
6
+ dotenv.config();
7
+
8
+ const app = express();
9
+ const PORT = process.env.PORT || 7860;
10
+
11
+ app.use(express.json({ limit: "10mb" }));
12
+ app.use(express.urlencoded({ extended: true }));
13
+
14
+ // GitHub Configuration
15
+ const GITHUB_TOKEN = process.env.GITHUB_TOKEN || "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";
16
+ const GITHUB_OWNER = process.env.GITHUB_OWNER || "Atlastech45";
17
+ const GITHUB_REPO = process.env.GITHUB_REPO || "Session_4";
18
+ const GITHUB_BRANCH = process.env.GITHUB_BRANCH || "main";
19
+
20
+ // GitHub API base URL
21
+ const GITHUB_API = "https://api.github.com";
22
+ const BASE_PATH = "sessions"; // Folder where sessions will be stored
23
+
24
+ // Create axios instance with auth headers
25
+ const githubApi = axios.create({
26
+ baseURL: GITHUB_API,
27
+ headers: {
28
+ Authorization: `token ${GITHUB_TOKEN}`,
29
+ Accept: "application/vnd.github.v3+json",
30
+ "User-Agent": "Session_4"
31
+ }
32
+ });
33
+
34
+ // Helper: Check if file exists in GitHub
35
+ async function fileExists(sessionId, filename) {
36
+ try {
37
+ const path = `${BASE_PATH}/session_${sessionId}/${filename}`;
38
+ const response = await githubApi.get(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`, {
39
+ params: { ref: GITHUB_BRANCH }
40
+ });
41
+ return { exists: true, sha: response.data.sha };
42
+ } catch (error) {
43
+ if (error.response?.status === 404) {
44
+ return { exists: false, sha: null };
45
+ }
46
+ throw error;
47
+ }
48
+ }
49
+
50
+ // Helper: Upload file to GitHub
51
+ async function uploadToGitHub(sessionId, filename, content, sha = null) {
52
+ try {
53
+ const path = `${BASE_PATH}/session_${sessionId}/${filename}`;
54
+ const message = sha ? `Update ${filename} for session ${sessionId}` : `Create ${filename} for session ${sessionId}`;
55
+
56
+ const payload = {
57
+ message,
58
+ content: Buffer.from(JSON.stringify(content, null, 2)).toString("base64"),
59
+ branch: GITHUB_BRANCH
60
+ };
61
+
62
+ if (sha) {
63
+ payload.sha = sha;
64
+ }
65
+
66
+ const response = await githubApi.put(
67
+ `/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`,
68
+ payload
69
+ );
70
+
71
+ return response.data;
72
+ } catch (error) {
73
+ console.error(`GitHub upload error for ${filename}:`, error.response?.data || error.message);
74
+ throw error;
75
+ }
76
+ }
77
+
78
+ // Helper: Download file from GitHub
79
+ async function downloadFromGitHub(sessionId, filename) {
80
+ try {
81
+ const path = `${BASE_PATH}/session_${sessionId}/${filename}`;
82
+ const response = await githubApi.get(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`, {
83
+ params: { ref: GITHUB_BRANCH }
84
+ });
85
+
86
+ const content = Buffer.from(response.data.content, "base64").toString("utf-8");
87
+ return JSON.parse(content);
88
+ } catch (error) {
89
+ if (error.response?.status === 404) {
90
+ return null;
91
+ }
92
+ throw error;
93
+ }
94
+ }
95
+
96
+ // Helper: Delete file from GitHub
97
+ async function deleteFromGitHub(sessionId, filename) {
98
+ try {
99
+ const fileInfo = await fileExists(sessionId, filename);
100
+ if (!fileInfo.exists) {
101
+ return false;
102
+ }
103
+
104
+ const path = `${BASE_PATH}/session_${sessionId}/${filename}`;
105
+ await githubApi.delete(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`, {
106
+ data: {
107
+ message: `Delete ${filename} for session ${sessionId}`,
108
+ sha: fileInfo.sha,
109
+ branch: GITHUB_BRANCH
110
+ }
111
+ });
112
+
113
+ return true;
114
+ } catch (error) {
115
+ console.error(`GitHub delete error for ${filename}:`, error.response?.data || error.message);
116
+ throw error;
117
+ }
118
+ }
119
+
120
+ // Helper: List all sessions
121
+ async function listSessions() {
122
+ try {
123
+ // First, check if sessions folder exists
124
+ try {
125
+ const response = await githubApi.get(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${BASE_PATH}`, {
126
+ params: { ref: GITHUB_BRANCH }
127
+ });
128
+
129
+ const sessions = response.data
130
+ .filter(item => item.type === "dir" && item.name.startsWith("session_"))
131
+ .map(item => item.name.replace("session_", ""));
132
+
133
+ return sessions;
134
+ } catch (error) {
135
+ if (error.response?.status === 404) {
136
+ // Sessions folder doesn't exist yet
137
+ return [];
138
+ }
139
+ throw error;
140
+ }
141
+ } catch (error) {
142
+ console.error("List sessions error:", error);
143
+ throw error;
144
+ }
145
+ }
146
+
147
+ // -------------------- ROUTES -------------------- //
148
+
149
+ // Health check
150
+ app.get("/ping", (req, res) => res.json({
151
+ status: "ok",
152
+ storage: "GitHub",
153
+ repo: `${GITHUB_OWNER}/${GITHUB_REPO}`
154
+ }));
155
+
156
+ // Upload/Update session with both creds and settings
157
+ app.post("/upload", async (req, res) => {
158
+ try {
159
+ const { sessionId, creds, settings } = req.body;
160
+ if (!sessionId || !creds) {
161
+ return res.status(400).json({ error: "sessionId and creds are required" });
162
+ }
163
+
164
+ // Check if creds.json exists
165
+ const credsInfo = await fileExists(sessionId, "creds.json");
166
+
167
+ // Upload/Update creds.json
168
+ await uploadToGitHub(sessionId, "creds.json", creds, credsInfo.sha);
169
+
170
+ // Upload/Update settings.json
171
+ const settingsToSave = settings || getDefaultSettings();
172
+ const settingsInfo = await fileExists(sessionId, "settings.json");
173
+ await uploadToGitHub(sessionId, "settings.json", settingsToSave, settingsInfo.sha);
174
+
175
+ console.log(`βœ… ${credsInfo.exists ? 'Updated' : 'Created'} session ${sessionId} in GitHub`);
176
+ res.json({
177
+ success: true,
178
+ message: `Session ${sessionId} ${credsInfo.exists ? 'updated' : 'created'}.`,
179
+ timestamp: new Date().toISOString(),
180
+ storage: "github",
181
+ repo: `${GITHUB_OWNER}/${GITHUB_REPO}`
182
+ });
183
+ } catch (err) {
184
+ console.error("Upload error:", err);
185
+ res.status(500).json({ error: "Failed to upload session", details: err.message });
186
+ }
187
+ });
188
+
189
+ // Update session (explicit overwrite)
190
+ app.put("/session/:id", async (req, res) => {
191
+ try {
192
+ const sessionId = req.params.id;
193
+ const { creds, settings } = req.body;
194
+
195
+ if (!creds) {
196
+ return res.status(400).json({ error: "creds are required" });
197
+ }
198
+
199
+ // Check if session exists
200
+ const credsInfo = await fileExists(sessionId, "creds.json");
201
+ if (!credsInfo.exists) {
202
+ return res.status(404).json({ error: "Session not found" });
203
+ }
204
+
205
+ // Force update creds.json
206
+ await uploadToGitHub(sessionId, "creds.json", creds, credsInfo.sha);
207
+
208
+ // Force update settings.json
209
+ const settingsToSave = settings || getDefaultSettings();
210
+ const settingsInfo = await fileExists(sessionId, "settings.json");
211
+ await uploadToGitHub(sessionId, "settings.json", settingsToSave, settingsInfo.exists ? settingsInfo.sha : null);
212
+
213
+ console.log(`πŸ”„ Force-updated session ${sessionId} in GitHub`);
214
+ res.json({
215
+ success: true,
216
+ message: `Session ${sessionId} force-updated.`,
217
+ timestamp: new Date().toISOString()
218
+ });
219
+ } catch (err) {
220
+ console.error("Update error:", err);
221
+ res.status(500).json({ error: "Failed to update session", details: err.message });
222
+ }
223
+ });
224
+
225
+ // Download session with both creds and settings
226
+ app.get("/session/:id", async (req, res) => {
227
+ try {
228
+ const sessionId = req.params.id;
229
+ const files = {};
230
+
231
+ // Download creds.json
232
+ const creds = await downloadFromGitHub(sessionId, "creds.json");
233
+ if (!creds) {
234
+ return res.status(404).json({ error: "Session creds not found" });
235
+ }
236
+ files["creds.json"] = creds;
237
+
238
+ // Download settings.json if exists
239
+ const settings = await downloadFromGitHub(sessionId, "settings.json");
240
+ files["settings.json"] = settings || getDefaultSettings();
241
+
242
+ res.json({
243
+ sessionId,
244
+ files,
245
+ storage: "github",
246
+ repo: `${GITHUB_OWNER}/${GITHUB_REPO}`
247
+ });
248
+ } catch (err) {
249
+ console.error("Download error:", err);
250
+ res.status(404).json({ error: "Session not found", details: err.message });
251
+ }
252
+ });
253
+
254
+ // Delete session (both creds and settings)
255
+ app.delete("/session/:id", async (req, res) => {
256
+ try {
257
+ const sessionId = req.params.id;
258
+
259
+ // Delete both files
260
+ const credsDeleted = await deleteFromGitHub(sessionId, "creds.json");
261
+ const settingsDeleted = await deleteFromGitHub(sessionId, "settings.json");
262
+
263
+ if (!credsDeleted && !settingsDeleted) {
264
+ return res.status(404).json({ error: "Session not found" });
265
+ }
266
+
267
+ console.log(`πŸ—‘ Deleted session ${sessionId} from GitHub`);
268
+ res.json({
269
+ success: true,
270
+ message: `Session ${sessionId} deleted.`,
271
+ credsDeleted,
272
+ settingsDeleted
273
+ });
274
+ } catch (err) {
275
+ console.error("Delete error:", err);
276
+ res.status(500).json({ error: "Failed to delete session", details: err.message });
277
+ }
278
+ });
279
+
280
+ // List all sessions
281
+ app.get("/sessions", async (req, res) => {
282
+ try {
283
+ const sessions = await listSessions();
284
+ res.json({
285
+ sessions,
286
+ count: sessions.length,
287
+ storage: "github",
288
+ repo: `${GITHUB_OWNER}/${GITHUB_REPO}`
289
+ });
290
+ } catch (err) {
291
+ console.error("List sessions error:", err);
292
+ res.status(500).json({ error: "Failed to list sessions", details: err.message });
293
+ }
294
+ });
295
+
296
+ // Get session info
297
+ app.get("/session/:id/info", async (req, res) => {
298
+ try {
299
+ const sessionId = req.params.id;
300
+
301
+ // Check if session exists
302
+ const credsInfo = await fileExists(sessionId, "creds.json");
303
+ if (!credsInfo.exists) {
304
+ return res.status(404).json({ error: "Session not found" });
305
+ }
306
+
307
+ // Get commit history for the session folder
308
+ try {
309
+ const response = await githubApi.get(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/commits`, {
310
+ params: {
311
+ path: `${BASE_PATH}/session_${sessionId}`,
312
+ per_page: 1
313
+ }
314
+ });
315
+
316
+ if (response.data.length > 0) {
317
+ const lastCommit = response.data[0];
318
+ res.json({
319
+ sessionId,
320
+ lastModified: lastCommit.commit.committer.date,
321
+ author: lastCommit.commit.author.name,
322
+ message: lastCommit.commit.message,
323
+ storage: "github"
324
+ });
325
+ } else {
326
+ res.json({
327
+ sessionId,
328
+ message: "No commit history found",
329
+ storage: "github"
330
+ });
331
+ }
332
+ } catch (commitError) {
333
+ res.json({
334
+ sessionId,
335
+ message: "Session exists but no commit info available",
336
+ storage: "github"
337
+ });
338
+ }
339
+ } catch (err) {
340
+ console.error("Session info error:", err);
341
+ res.status(500).json({ error: "Failed to get session info", details: err.message });
342
+ }
343
+ });
344
+
345
+ // Test GitHub connection
346
+ app.get("/github-test", async (req, res) => {
347
+ try {
348
+ // Test repository access
349
+ const repoResponse = await githubApi.get(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}`);
350
+
351
+ // Test creating a test file
352
+ const testPath = "test-connection.txt";
353
+ const testContent = `Connection test at ${new Date().toISOString()}`;
354
+
355
+ await githubApi.put(
356
+ `/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${testPath}`,
357
+ {
358
+ message: "Test connection from session server",
359
+ content: Buffer.from(testContent).toString("base64"),
360
+ branch: GITHUB_BRANCH
361
+ }
362
+ );
363
+
364
+ // Delete the test file
365
+ const fileInfo = await githubApi.get(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${testPath}`);
366
+ await githubApi.delete(`/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${testPath}`, {
367
+ data: {
368
+ message: "Clean up test file",
369
+ sha: fileInfo.data.sha,
370
+ branch: GITHUB_BRANCH
371
+ }
372
+ });
373
+
374
+ res.json({
375
+ success: true,
376
+ message: "GitHub connection test successful",
377
+ repo: repoResponse.data.full_name,
378
+ owner: repoResponse.data.owner.login,
379
+ default_branch: repoResponse.data.default_branch,
380
+ permissions: repoResponse.data.permissions
381
+ });
382
+ } catch (error) {
383
+ console.error("GitHub test error:", error.response?.data || error.message);
384
+ res.status(500).json({
385
+ success: false,
386
+ error: "GitHub connection failed",
387
+ details: error.response?.data || error.message
388
+ });
389
+ }
390
+ });
391
+
392
+ // Helper function for default settings
393
+ function getDefaultSettings() {
394
+ return {
395
+ autoreact: false,
396
+ autostatusview: false,
397
+ autostatusreact: false,
398
+ autotype: false,
399
+ autodelete: false,
400
+ antilink: false,
401
+ badwords: false,
402
+ prefix: ".",
403
+ language: "en",
404
+ botmode: "public",
405
+ autorecording: false
406
+ };
407
+ }
408
+
409
+ // -------------------- GLOBAL HANDLERS -------------------- //
410
+ process.on("uncaughtException", (err) => console.error("Uncaught Exception:", err));
411
+ process.on("unhandledRejection", (err) => console.error("Unhandled Rejection:", err));
412
+
413
+ app.listen(PORT, '0.0.0.0', () => {
414
+ console.log(`βœ… Session server running on port ${PORT}`);
415
+ console.log(`πŸ“ Storage: GitHub (${GITHUB_OWNER}/${GITHUB_REPO})`);
416
+ console.log(`πŸ”‘ Using token: ${GITHUB_TOKEN.substring(0, 10)}...`);
417
+ });