Created
March 29, 2025 11:49
-
-
Save AliAryanTech/a8073fa8163740405e3763dde03048f1 to your computer and use it in GitHub Desktop.
Umm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const cors = require('cors') | |
const fs = require('fs-extra') | |
const crypto = require('crypto') | |
const { join } = require('path') | |
const verification = new Map() | |
const FILE = 'sessions.json' | |
const sessions = fs.existsSync(FILE) ? fs.readJsonSync(FILE) : {} | |
module.exports = class Server { | |
constructor(client) { | |
this.client = client | |
this.app.use(cors({ | |
origin: "*", | |
credentials: true | |
}), express.json()) | |
this.app.use((req, res, next) => { | |
res.set('Access-Control-Allow-Origin', '*') | |
res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization') | |
res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') | |
next() | |
}) | |
this.app.use('/', express.static(this.path)) | |
this.app.get('/wa/qr', async (req, res) => { | |
const { session } = req.query | |
if (!session || !this.client || this.client.config.session !== req.query.session) | |
return void res.status(404).setHeader('Content-Type', 'text/plain').send('Invalid Session').end() | |
if (!this.client || !this.client.QR) | |
return void res | |
.status(404) | |
.setHeader('Content-Type', 'text/plain') | |
.send( | |
this.client.condition === 'connected' | |
? 'You are already connected to WhatsApp' | |
: 'QR not generated' | |
) | |
.end() | |
res.status(200).contentType('image/png').send(this.client.QR) | |
}) | |
this.app.all('/request', async (req, res) => { | |
const { phone } = req.method === 'GET' ? req.query : req.body | |
if (!phone) return res.json({ success: false, message: 'No phone' }) | |
const jid = await this.client.isOnWhatsApp(phone) | |
if (!jid) return res.status(404).json({ success: false, message: 'Not on WhatsApp' }) | |
if (verification.has(jid)) return res.json({ success: false, message: `Wait ${((verification.get(jid).expiration - Date.now()) / 1000).toFixed(0)}s` }) | |
const code = Math.floor(100000 + Math.random() * 900000) | |
verification.set(jid, { code, expiration: Date.now() + 120000 }) | |
await this.client.sendMessage(jid, { text: `Your OTP is ${code}` }) | |
console.log(code) | |
setTimeout(() => verification.delete(jid), 120000) | |
res.json({ success: true, message: 'Check WhatsApp!' }) | |
}) | |
this.app.all('/verify', async (req, res) => { | |
const { phone, code } = req.method === 'GET' ? req.query : req.body | |
if (!phone || !code) return res.json({ success: false, message: 'Missing data' }) | |
const jid = await this.client.isOnWhatsApp(phone) | |
if (!jid) return res.status(404).json({ success: false, message: 'Not on WhatsApp' }) | |
const stored = verification.get(jid) | |
if (!stored || Date.now() > stored.expiration || parseInt(code) !== stored.code) | |
return res.status(400).json({ success: false, message: 'Invalid/Expired Code' }) | |
verification.delete(jid) | |
const token = crypto.randomBytes(32).toString('base64') | |
this.addAuth(token, { jid, expiration: Date.now() + 604800000, token }) | |
await this.client.sendMessage(this.client.config.adminsGroup, { text: `@${jid.split('@')[0]} Logged in Website.`, mentions: [jid] }) | |
res.json(sessions[token]) | |
}) | |
this.app.all(['/getUser', '/get-status', '/cards', '/profile'], async (req, res) => { | |
const { phone } = req.method === 'GET' ? req.query : req.body | |
if (!phone) return res.json({ success: false, message: 'No phone' }) | |
const jid = await this.client.isOnWhatsApp(phone) | |
const user = jid && await this.client.DB.user.get(jid) && await this.client.DB.getUser(jid) | |
if (!user) return res.status(404).json({ success: false, message: 'User not found' }) | |
const path = req.path.slice(1) | |
const { id, name, username, about, pfp, reaction, exp, level, wallet, bank, clan, gems, quizWins, moonstone, popularity, vault, ban, deck, coll, party, pc, afk, premium, status_updates = {} } = user | |
if (path === 'get-status') | |
return res.json({ success: true, status_updates: Object.fromEntries(Object.entries(status_updates || {}).filter(([k]) => /^\d/.test(k))) }) | |
if (path === 'cards') return res.json({ success: true, deck, coll }) | |
const bio = await this.client.fetchStatus(jid).then(res => res?.status).catch(() => null) | |
const pfpUrl = await this.client | |
.profilePictureUrl(jid, 'image') | |
.catch(() => 'https://upload.wikimedia.org/wikipedia/commons/a/ac/Default_pfp.jpg') | |
const cards = coll.concat(deck) | |
res.json({ | |
id, name, username, bio, about, reaction, exp, level, wallet, bank, clan, gems, | |
quizWins, moonstone, vault, ban, afk, premium, popularity: popularity?.count ?? 0, | |
pfp: pfp?.custom ? pfp?.url : pfpUrl, | |
pokemon: party.length + pc.length, | |
cards: cards.length, | |
frame: 1 | |
}) | |
}) | |
this.app.all('/updateUser', async (req, res) => { | |
const [session, error] = this.authCheck(req, res) | |
if (error) return error | |
const { jid, field, method, update } = req.method === 'GET' ? req.query : req.body | |
if (!field || !method || !update) return res.status(400).json({ success: false, message: 'Missing fields' }) | |
if (!['inc', 'set'].includes(method)) return res.status(400).json({ success: false, message: 'Invalid method' }) | |
if (!jid.includes(session.jid.split('@')[0])) return res.json({ success: false, message: 'Not authorized' }) | |
await this.client.DB.updateUser(jid, field, method, update) | |
res.json({ success: true, message: 'Updated' }) | |
}) | |
this.app.all('/transfer-card', async (req, res) => { | |
const [session, error] = this.authCheck(req, res) | |
if (error) return error | |
const { jid, type, index } = req.method === 'GET' ? req.query : req.body | |
if (!['deck', 'coll'].includes(type) || !Number.isInteger(Number(index)) || index < 0) | |
return res.status(400).json({ success: false, message: 'Invalid input' }) | |
if (!jid.includes(session.jid.split('@')[0])) return res.json({ success: false, message: 'Not authorized' }) | |
const user = await this.client.DB.getUser(jid) | |
const source = type === 'deck' ? user.deck : user.coll; | |
if (index >= source.length) | |
return res.status(400).json({ success: false, message: 'Index out of bounds' }) | |
if (type === 'coll' && user.deck.length >= 12) | |
return res.status(400).json({ success: false, message: 'Deck full' }) | |
const card = source.splice(index, 1)[0]; | |
(type === 'deck' ? user.coll : user.deck).push(card) | |
await this.client.DB.updateUser(jid, 'deck', 'set', user.deck) | |
await this.client.DB.updateUser(jid, 'coll', 'set', user.coll) | |
res.json({ | |
success: true, | |
deck: user.deck, | |
coll: user.coll | |
}) | |
}) | |
this.app.all('/top-lb', async (req, res) => { | |
const { category = 'exp' } = req.method === 'GET' ? req.query : req.body | |
const sort = { | |
exp: (a, b) => b.exp - a.exp, | |
moonstone: (a, b) => (b.moonstone || 0) + (b.vault || 0) - (a.moonstone || 0) - (a.vault || 0), | |
auction: (a, b) => b.auctionsWon - a.auctionsWon, | |
wallet: (a, b) => b.wallet - a.wallet, | |
bank: (a, b) => b.bank - a.bank, | |
pokemon: (a, b) => (b.party?.length || 0) + (b.pc?.length || 0) - (a.party?.length || 0) - (a.pc?.length || 0), | |
cards: (a, b) => (b.deck?.length || 0) + (b.coll?.length || 0) - (a.deck?.length || 0) - (a.coll?.length || 0), | |
quiz: (a, b) => b.quizWins - a.quizWins, | |
clanpoints: (a, b) => (b.clan?.clanpoints || 0) - (a.clan?.clanpoints || 0), | |
popularity: (a, b) => (b.popularity?.count || 0) - (a.popularity?.count || 0) | |
}[category] || ((a, b) => b.exp - a.exp) | |
const users = (await this.client.DB.user.all()) | |
.map(x => x.value?.whatsapp?.net) | |
.filter(u => u && u.id) | |
.sort(sort) | |
.slice(0, 10); | |
res.json(await Promise.all(users.map(async u => ({ | |
id: u.id, | |
name: u.name, | |
phone: u.id ? u.id.split('@')[0] : null, | |
pfp: u.custom ? u.url : await this.client.profilePictureUrl(u.id, 'image').catch(() => null), | |
exp: u.exp, | |
popularity: u.popularity?.count || 0, | |
clan: u.clan?.clanpoints || 0, | |
level: u.level, | |
pokemon: (u.party?.length || 0) + (u.pc?.length || 0), | |
cards: (u.deck?.length || 0) + (u.coll?.length || 0), | |
quizWins: u.quizWins | |
})))) | |
}) | |
this.app.all('/set-status', async (req, res) => { | |
const [session, error] = this.authCheck(req, res) | |
if (error) return error | |
const { jid, type, update } = req.method === 'GET' ? req.query : req.body | |
if (!jid || !type || !update) return res.status(400).json({ success: false, message: 'Missing fields' }) | |
if (!jid.includes(session.jid.split('@')[0]) && type === 'post') return res.json({ success: false, message: 'Unauthorized post' }) | |
await this.client.DB.statusUpdate(jid, type, update) | |
if (type === 'post') await this.client.sendMessage('[email protected]', { text: `@${jid.split('@')[0]} Posted a Status.\n\nLink: https://eclipsebot.net/status/${jid.split('@')[0]}`, mentions: [jid] }) | |
res.json({ success: true, message: 'Updated' }) | |
}) | |
this.app.all('*', (req, res) => res.sendStatus(404)) | |
const port = client.config.session === 'ASUNA' ? 53579 : client.config.PORT; | |
this.app.listen(port, () => console.log(`Server started on PORT: ${port}`)); | |
} | |
path = join(__dirname, '..', '..', 'public') | |
app = express() | |
addAuth = (token, data) => { | |
const existing = Object.keys(sessions).filter(t => sessions[t].jid === data.jid) | |
if (existing.length >= 3) delete sessions[existing[0]] | |
sessions[token] = data | |
fs.writeJsonSync(FILE, sessions, { spaces: 4 }) | |
} | |
authCheck = (req, res) => { | |
const token = req.headers.authorization?.replace('Bearer ', '') | |
if (!token || !sessions[token]) | |
return [null, res.status(401).json({ success: false, message: 'Invalid Token' })] | |
const session = sessions[token] | |
if (Date.now() > session.expiration) { | |
delete sessions[token] | |
fs.writeJsonSync(FILE, sessions, { spaces: 4 }) | |
return [null, res.status(401).json({ success: false, message: 'Session Expired' })] | |
} | |
return [session, null] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment