101 lines
2.9 KiB
JavaScript
101 lines
2.9 KiB
JavaScript
const http = require('http')
|
|
const express = require('express')
|
|
const WebSocket = require('ws')
|
|
const bodyParser = require('body-parser')
|
|
const cookieParser = require('cookie-parser')
|
|
const cookie = require('cookie')
|
|
const crypto = require('crypto')
|
|
const bot = require('./apps/bot')
|
|
const log = require('./include/log')
|
|
|
|
const adminapp = require('./apps/admin')
|
|
const miniapp = require('./apps/miniapp')
|
|
|
|
BigInt.prototype.toJSON = function () {
|
|
return Number(this)
|
|
}
|
|
|
|
const app = express()
|
|
const server = http.createServer(app)
|
|
const wss = new WebSocket.Server({ server })
|
|
|
|
app.use(bodyParser.json({limit: '10mb'}))
|
|
app.use(cookieParser())
|
|
|
|
app.use((req, res, next) => {
|
|
const start = Date.now()
|
|
|
|
const end = res.end
|
|
res.end = function (chunk, encoding) {
|
|
log.http (req, res, Date.now() - start)
|
|
end.apply (res, arguments)
|
|
}
|
|
|
|
next()
|
|
})
|
|
|
|
app.use((req, res, next) => {
|
|
if(!(req.body instanceof Object))
|
|
return next()
|
|
|
|
const escapeHtml = str => str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''')
|
|
Object
|
|
.keys(req.body || {})
|
|
.filter(key => typeof(req.body[key]) == 'string' && key != 'password')
|
|
.map(key => req.body[key] = escapeHtml(req.body[key]))
|
|
|
|
next()
|
|
})
|
|
|
|
app.post('(/api/admin/auth/telegram|/api/miniapp/auth)', (req, res, next) => {
|
|
const data = Object.assign({}, req.query)
|
|
delete data.hash
|
|
|
|
const BOT_TOKEN = process.env.BOT_TOKEN || '7236504417:AAGVaodw3cRwGlf-jAhwnYb51OHaXcgpW8k'
|
|
const dataCheckString = Object.keys(data).sort().map((key) => `${key}=${data[key]}`).join('\n')
|
|
const secretKey = crypto.createHmac('sha256', 'WebAppData').update(BOT_TOKEN).digest()
|
|
const hmac = crypto.createHmac('sha256', secretKey).update(dataCheckString).digest('hex')
|
|
|
|
const timeDiff = Date.now() / 1000 - data.auth_date
|
|
|
|
if (hmac !== req.query?.hash) // || timeDiff > 10)
|
|
throw Error('ACCESS_DENIED::401')
|
|
|
|
const user = JSON.parse(req.query.user)
|
|
res.locals.telegram_id = user.id
|
|
res.locals.start_param = req.query.start_param
|
|
|
|
if (!res.locals.telegram_id)
|
|
throw Error('ACCESS_DENIED::500')
|
|
|
|
next()
|
|
})
|
|
|
|
app.use('/api/admin', adminapp.router)
|
|
app.use('/api/miniapp', miniapp.router)
|
|
|
|
app.use((err, req, res, next) => {
|
|
console.error(`Error for ${req.path}: ${err}`)
|
|
log.error(err)
|
|
|
|
let message, code
|
|
[message, code = 500] = err.message.split('::')
|
|
res.status(+code).json({success: false, error: { message, code}})
|
|
})
|
|
|
|
wss.on('connection', (ws, req) => {
|
|
const sid = cookie.parse(req.headers.cookie || '')?.sid
|
|
if (!miniapp.registerWS(sid, ws) && !adminapp.registerWS(sid, ws))
|
|
return ws.close(1008, 'Unauthorized')
|
|
})
|
|
|
|
const PORT = process.env.PORT || 3000
|
|
server.listen(PORT, async () => {
|
|
console.log(`Listening at port ${PORT}`)
|
|
bot.start(
|
|
+(process.env.API_ID || 26746106),
|
|
process.env.API_HASH || '29e5f83c04e635fa583721473a6003b5',
|
|
process.env.BOT_TOKEN || '7236504417:AAGVaodw3cRwGlf-jAhwnYb51OHaXcgpW8k',
|
|
process.env.BOT_SID || ''
|
|
)
|
|
}) |