|
|
import express from 'express' |
|
|
import template from 'express-art-template' |
|
|
import http from 'http' |
|
|
import lodash from 'lodash' |
|
|
import fs from 'node:fs' |
|
|
import { resolve } from 'node:path' |
|
|
import YAML from 'yaml' |
|
|
|
|
|
class example { |
|
|
constructor () { |
|
|
this.cfg = YAML.parse(fs.readFileSync('./config.yaml', 'utf8')) |
|
|
this.tmp = {} |
|
|
this.isRegister = {} |
|
|
this.result = {} |
|
|
this.load(express()) |
|
|
console.log(`Successfully started, port: \x1b[32m${this.cfg.Port}\x1b[0m`) |
|
|
console.log('\x1b[32m%s\x1b[0m', `[POST] ${this.address}/register${this.cfg.Key && `?key=${this.cfg.Key}`}`) |
|
|
} |
|
|
|
|
|
load(app) { |
|
|
|
|
|
http.createServer(app).listen(this.cfg.Port); |
|
|
this.route(app); |
|
|
} |
|
|
|
|
|
route (app) { |
|
|
app.use(express.static(resolve('public'))) |
|
|
app.use(express.urlencoded({ extended: false })) |
|
|
app.use(express.json()) |
|
|
app.engine('html', template) |
|
|
app.set('views', resolve('public')) |
|
|
app.set('view engine', 'html') |
|
|
app.get('/GTest/:key', this.self('index')) |
|
|
app.post('/GTest/register', this.self('register')) |
|
|
app.get('/GTest/register/:key', this.self('get_register')) |
|
|
app.post('/GTest/validate/:key', this.self('validate')) |
|
|
app.get('/GTest/validate/:key', this.self('get_validate')) |
|
|
app.use(this.invalid) |
|
|
app.use(this.error) |
|
|
} |
|
|
|
|
|
|
|
|
index (req, res, next) { |
|
|
let { key } = req.params |
|
|
if (!key || !this.isRegister[key]) return next('验证信息不存在或已失效。') |
|
|
res.render('GTest/main', { key, copyright: this.cfg.Copyright }) |
|
|
} |
|
|
|
|
|
|
|
|
register (req, res, next) { |
|
|
let { key } = req.query, { gt, challenge } = req.body || {} |
|
|
if (!gt || !challenge) return next('error') |
|
|
if (this.cfg.Key && key !== this.cfg.Key) return next('please enter the correct key') |
|
|
for (let i = 0; i < 99; i++) { |
|
|
key = lodash.sampleSize('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 6).join('') |
|
|
if (this.isRegister[key] || this.result[key]) continue |
|
|
break |
|
|
} |
|
|
this.tmp[key] = req.body |
|
|
this.isRegister[key] = 1 |
|
|
|
|
|
setTimeout(() => delete this.tmp[key] && delete this.isRegister[key], 120000) |
|
|
this.send(res, { |
|
|
link: `${this.address}/${key}`, |
|
|
result: `${this.address}/validate/${key}` |
|
|
}) |
|
|
} |
|
|
|
|
|
|
|
|
get_register (req, res, next) { |
|
|
let { key } = req.params |
|
|
if (!key || !this.tmp[key]) return next('该验证信息已被使用,若非本人操作请重新获取') |
|
|
res.send(this.tmp[key] || {}) |
|
|
delete this.tmp[key] |
|
|
} |
|
|
|
|
|
|
|
|
validate (req, res, next) { |
|
|
let { key } = req.params |
|
|
if (!key || !req.body) return next('error') |
|
|
this.result[key] = req.body |
|
|
setTimeout(() => delete this.result[key], 30000) |
|
|
this.send(res, {}) |
|
|
delete this.isRegister[key] |
|
|
console.log('[GeeTest] 验证成功, key:', key) |
|
|
} |
|
|
|
|
|
|
|
|
async get_validate (req, res, next) { |
|
|
let { key } = req.params, data = null |
|
|
if (!key) return next('error') |
|
|
|
|
|
if (this.isRegister[key] || this.result[key]) { |
|
|
for (let i = 0; i < 120; i++) { |
|
|
if (this.result[key]) { |
|
|
data = this.result[key] |
|
|
break |
|
|
} |
|
|
await new Promise((resolve) => setTimeout(resolve, 1000)) |
|
|
} |
|
|
if (!data) data = {} |
|
|
} |
|
|
this.send(res, data) |
|
|
} |
|
|
|
|
|
invalid (req, res) { |
|
|
if (!res.finished) res.status(404).end() |
|
|
} |
|
|
|
|
|
error (err, req, res, next) { |
|
|
let message = err?.message || (err !== 'error' && `${err}`) || 'Invalid request' |
|
|
if (!res.finished) res.send({ status: 1, message }) |
|
|
} |
|
|
|
|
|
send (res, data, message = 'OK') { |
|
|
res.send({ |
|
|
status: Number(!data), |
|
|
message, |
|
|
data |
|
|
}) |
|
|
} |
|
|
|
|
|
get address () { |
|
|
let { Host, Port, Https, Key } = this.cfg |
|
|
if (![80, 443,7860].includes(Port)) Host += `:${Port}` |
|
|
return `https://${Host}/GTest` |
|
|
} |
|
|
|
|
|
self (fn) { |
|
|
return (...args) => this[fn].call(this, ...args) |
|
|
} |
|
|
} |
|
|
|
|
|
process.on('unhandledRejection', (error, promise) => console.log(error)) |
|
|
new example() |