-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathesurfing.js
240 lines (212 loc) · 6.08 KB
/
esurfing.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
const utils = require("./utils")
const axios = require("axios")
const configure = new utils.Config("./config.json")
let portal = {
address: null
}
const codesName = [
'networkStatus_OK',
'networkStatus_offline',
'networkStatus_portal',
'networkStatus_disconnect',
'networkStatus_unknownEnvironment'
]
const codes = {}
codesName.forEach(name =>{
!codes[name] && (codes[name] = Symbol(name))
})
/**
* async getVerifyCode
* @param {*} formData
* (require: username, clientip, nasip, mac, iswifi, timestamp, authKey)
* @returns String verifyCode
*/
async function getVerifyCode(formData){
const url = "http://enet.10000.gd.cn:10001/client/challenge"
const d = await axios.post(url, formData)
return d.data.challenge
}
/**
* async login
* do login with user info
* @param {*} username (student id)
* @param {*} password (the end 8 numbers of id)
* @param {*} config (object, nasip, clientip and mac is required)
* @returns Object, login result
*/
async function login(username, password, config = null){
let formData = {
username,
password,
iswifi: "4060",
clientip: null, //wlanip
nasip: null, //nasip
authenticator: null,
mac: null,
verificationcode: "",
timestamp: 0
}
if (!config){
throw new Error("config not specify")
}
formData = {
...formData,
...config
}
formData.timestamp = new Date().getTime() + ''
// no need to add secret
let { clientip, nasip, mac, timestamp } = formData
formData.authenticator = utils.getHash([clientip, nasip, mac, timestamp])
const verifyCode = await getVerifyCode(formData)
// update and calc
formData.timestamp = new Date().getTime() + ''
timestamp = formData.timestamp
formData.authenticator = utils.getHash([clientip, nasip, mac, timestamp, verifyCode])
const url = "http://enet.10000.gd.cn:10001/client/login"
const d = (await axios.post(url, formData)).data
const code = d.rescode
// login success
if (code && ~~code === 0){
configure.get().record = {
username,
mac: formData.mac,
nasip: formData.nasip,
wlanip: formData.clientip
}
configure.write()
}
return d
}
/**
* async logout
* do logout
* @returns Boolean, logout result
*/
async function logout(){
const { wlanip, nasip, mac } = configure.get().record
if (!(wlanip && nasip && mac)){
console.log('no record found, cannot disconnect');
return;
}
const url = "http://enet.10000.gd.cn:10001/client/logout"
let formData = {
clientip: wlanip, //wlanip
nasip: nasip, //nasip
authenticator: null,
mac: mac,
timestamp: new Date().getTime()
}
const timestamp = formData.timestamp
formData.authenticator = utils.getHash([wlanip, nasip, mac, timestamp])
const code = (await axios.post(url, formData)).data.rescode
return (code && ~~code === 0)
}
/**
* async active
* keep connection, call automatically by interval
* @returns Number, actice status
* (0: ok, 1: offine (needs relogin), 2: auth failed.)
*/
async function active(){
const url = "http://enet.10000.gd.cn:8001/hbservice/client/active"
const t = new Date().getTime()
const { username, wlanip, nasip, mac } = configure.get().record
const params = {
username,
clientip: wlanip,
nasip,
mac,
timestamp: t,
authenticator: utils.getHash([wlanip, nasip, mac, t])
}
const code = (await axios.get(url, { params })).data.rescode
// 0 -- online
// 1 -- offline
// 2 -- auth failed
return code
}
/**
* async networkCheck
* check network environment, return the network status
* @returns Symbol, status
* (0: ok, 1: offine (needs relogin), 2: portal needed., 3: network disconnect)
*/
async function networkCheck(){
/**
* 1.获取网卡地址,判断是否连接
* 2.访问百度,判断是否正常连接(超时限制)
* 3.若跳转,则进行普通登录; 否则访问2.2.2.2获取跳转
* 4.若2.2.2.2无跳转,程序结束
* 5.访问获得跳转的地址,再次跳转
* 6.进行登录,等待10秒,进行正常登录
*/
/**
* 新检测流程:
* 1.访问2.2.2.2
* 2.根据重定向的地址确定状态
*/
let ret = await utils.getNetworkInfo()
// 获取网卡信息
if (!ret){
return codes.networkStatus_disconnect
}
// 判断是否正常联网
ret = (await axios.get("http://www.baidu.com", { retry: 3, timeout: 10000 })).data
if (ret.indexOf("百度一下") !== -1){
return codes.networkStatus_OK
}
let redirect = await utils.getRedirectUrl("http://2.2.2.2")
// console.log('re >>> ', redirect);
// 如果未重定向, 则网络环境未知
if (!redirect){
return codes.networkStatus_unknownEnvironment
}
// 被重定向到portal页面,需要portal登录
if (redirect.host.indexOf("portal") !== -1){
// 如果需要,获取登录连接
redirect = await utils.getRedirectUrl(redirect.host)
if (!redirect){
throw new Error("unknown error")
}
if (redirect && redirect.host.indexOf("login") !== -1){
portal.address = redirect.host
return codes.networkStatus_portal
}
// 重定向的页面未包含login字段
return codes.networkStatus_unknownEnvironment
}
// 被重定向到gd10000,则需要正常登录
if (redirect.host.indexOf("enet.10000.gd") !== -1){
return codes.networkStatus_offline
}
// 完美避开所有正确答案
return codes.networkStatus_unknownEnvironment
}
/**
* async portalLogin
* do portal login, may cause a short network disconnecion
* @param {*} username
* @param {*} password
* @returns Object, login result
*/
async function portalLogin(username, password){
if (!portal.address){
throw new Error("no portal address found!")
}
const url = `http://${portal.address}:8080/portal/pws?t=li&ifEmailAuth=false`
const formData = utils.constructLoginForm(username, password, portal.address)
let ret = (await axios.post(url, formData, { retry: 3 })).data
const data = utils.responseToJSON(ret)
return data
}
async function portalLogout(username, password){
}
module.exports = {
login,
logout,
active,
portalLogin,
portalLogout,
networkCheck,
codes
}